From 5a4a63f8a93019119f81cbed3b466b16de338802 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Mon, 30 Jan 2023 18:52:35 -0500 Subject: [PATCH 001/739] Create IfStatementAdditionOverflow.ql --- .../CWE-190/IfStatementAdditionOverflow.ql | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql new file mode 100644 index 00000000000..4763504ca0d --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql @@ -0,0 +1,28 @@ +/** + * @name Integer addition may overflow inside if statement + * @description Detects "if (a+b>c) a=c-b", which is incorrect if a+b overflows. + * Should be replaced by "if (a>c-b) a=c-b", which correctly + * implements a = min(a,c-b)". This integer overflow is the root + * cause of the buffer overflow in the SHA-3 reference implementation + * (CVE-2022-37454). + * @kind problem + * @problem.severity warning + * @id cpp/if-statement-addition-overflow + * @tags: experimental + * correctness + * security + * external/cwe/cwe-190 + */ + +import cpp + +from IfStmt ifstmt, GTExpr gtexpr, ExprStmt exprstmt, AssignExpr assignexpr, AddExpr addexpr, SubExpr subexpr +where ifstmt.getCondition() = gtexpr and + gtexpr.getLeftOperand() = addexpr and + ifstmt.getThen() = exprstmt and + exprstmt.getExpr() = assignexpr and + assignexpr.getRValue() = subexpr and + addexpr.getLeftOperand().toString() = assignexpr.getLValue().toString() and + addexpr.getRightOperand().toString() = subexpr.getRightOperand().toString() and + gtexpr.getRightOperand().toString() = subexpr.getLeftOperand().toString() +select ifstmt, "Integer addition may overflow inside if statement." From f577a04eabd6f8a3f899647298534f445a4f2061 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Sat, 18 Feb 2023 21:34:03 -0500 Subject: [PATCH 002/739] Update IfStatementAdditionOverflow.ql --- .../CWE-190/IfStatementAdditionOverflow.ql | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql index 4763504ca0d..cbfc2fc7f90 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql @@ -1,10 +1,13 @@ /** - * @name Integer addition may overflow inside if statement - * @description Detects "if (a+b>c) a=c-b", which is incorrect if a+b overflows. - * Should be replaced by "if (a>c-b) a=c-b", which correctly - * implements a = min(a,c-b)". This integer overflow is the root - * cause of the buffer overflow in the SHA-3 reference implementation - * (CVE-2022-37454). + * @name Integer addition may overflow inside condition + * @description Detects "c-b" when the condition "a+b>c" has been imposed, + * which is not the same as the condition "a>b-c" if "a+b" + * overflows. Rewriting improves readability and optimizability + * (CSE elimination). Also detects "b+a>c" (swapped terms in + * addition), "c=", "<", + * "<=" instead of ">" (all operators). This integer overflow + * is the root cause of the buffer overflow in the SHA-3 + * reference implementation (CVE-2022-37454). * @kind problem * @problem.severity warning * @id cpp/if-statement-addition-overflow @@ -15,14 +18,19 @@ */ import cpp +import semmle.code.cpp.controlflow.Guards +import semmle.code.cpp.valuenumbering.GlobalValueNumbering +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis +import semmle.code.cpp.commons.Exclusions -from IfStmt ifstmt, GTExpr gtexpr, ExprStmt exprstmt, AssignExpr assignexpr, AddExpr addexpr, SubExpr subexpr -where ifstmt.getCondition() = gtexpr and - gtexpr.getLeftOperand() = addexpr and - ifstmt.getThen() = exprstmt and - exprstmt.getExpr() = assignexpr and - assignexpr.getRValue() = subexpr and - addexpr.getLeftOperand().toString() = assignexpr.getLValue().toString() and - addexpr.getRightOperand().toString() = subexpr.getRightOperand().toString() and - gtexpr.getRightOperand().toString() = subexpr.getLeftOperand().toString() -select ifstmt, "Integer addition may overflow inside if statement." +from GuardCondition guard, BasicBlock block, RelationalOperation relop, AddExpr addexpr, SubExpr subexpr +where guard.controls(block, _) and + guard.getAChild*() = relop and + pragma[only_bind_into](block) = subexpr.getBasicBlock() and + relop.getAnOperand() = addexpr and + addexpr.getUnspecifiedType() instanceof IntegralType and + not isFromMacroDefinition(relop) and + exprMightOverflowPositively(addexpr) and + globalValueNumber(addexpr.getAnOperand()) = globalValueNumber(subexpr.getRightOperand()) and + globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) +select guard, "Integer addition may overflow inside condition." From ed75172bdd555587fd9b74ebc812c1c347c51ec1 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Tue, 21 Feb 2023 18:11:22 -0500 Subject: [PATCH 003/739] Update IfStatementAdditionOverflow.ql --- .../CWE-190/IfStatementAdditionOverflow.ql | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql index cbfc2fc7f90..5bfa265fca5 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql @@ -1,13 +1,13 @@ /** - * @name Integer addition may overflow inside condition - * @description Detects "c-b" when the condition "a+b>c" has been imposed, - * which is not the same as the condition "a>b-c" if "a+b" - * overflows. Rewriting improves readability and optimizability - * (CSE elimination). Also detects "b+a>c" (swapped terms in - * addition), "c=", "<", - * "<=" instead of ">" (all operators). This integer overflow - * is the root cause of the buffer overflow in the SHA-3 - * reference implementation (CVE-2022-37454). + * @name Integer addition may overflow inside if statement + * @description Detects "if (a+b>c) a=c-b", which incorrectly implements + * a = min(a,c-b) if a+b overflows. Should be replaced by + * "if (a>c-b) a=c-b". Also detects "if (b+a>c) a=c-b" + * (swapped terms in addition), if (a+b>c) { a=c-b }" + * (assignment inside block), "c=", "<", "<=" instead of ">" (all operators). This + * integer overflow is the root cause of the buffer overflow + * in the SHA-3 reference implementation (CVE-2022-37454). * @kind problem * @problem.severity warning * @id cpp/if-statement-addition-overflow @@ -18,19 +18,27 @@ */ import cpp -import semmle.code.cpp.controlflow.Guards import semmle.code.cpp.valuenumbering.GlobalValueNumbering +import semmle.code.cpp.valuenumbering.HashCons import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis import semmle.code.cpp.commons.Exclusions -from GuardCondition guard, BasicBlock block, RelationalOperation relop, AddExpr addexpr, SubExpr subexpr -where guard.controls(block, _) and - guard.getAChild*() = relop and - pragma[only_bind_into](block) = subexpr.getBasicBlock() and +from IfStmt ifstmt, RelationalOperation relop, ExprStmt exprstmt, BlockStmt blockstmt, AssignExpr assignexpr, AddExpr addexpr, SubExpr subexpr +where ifstmt.getCondition() = relop and relop.getAnOperand() = addexpr and addexpr.getUnspecifiedType() instanceof IntegralType and + subexpr.getUnspecifiedType() instanceof IntegralType and not isFromMacroDefinition(relop) and exprMightOverflowPositively(addexpr) and - globalValueNumber(addexpr.getAnOperand()) = globalValueNumber(subexpr.getRightOperand()) and - globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) -select guard, "Integer addition may overflow inside condition." + (ifstmt.getThen() = exprstmt or + (ifstmt.getThen() = blockstmt and + blockstmt.getAStmt() = exprstmt)) and + exprstmt.getExpr() = assignexpr and + assignexpr.getRValue() = subexpr and + ((hashCons(addexpr.getLeftOperand()) = hashCons(assignexpr.getLValue()) and + globalValueNumber(addexpr.getRightOperand()) = globalValueNumber(subexpr.getRightOperand())) or + (hashCons(addexpr.getRightOperand()) = hashCons(assignexpr.getLValue()) and + globalValueNumber(addexpr.getLeftOperand()) = globalValueNumber(subexpr.getRightOperand()))) and + globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) and + not globalValueNumber(addexpr.getAnOperand()) = globalValueNumber(relop.getAnOperand()) +select ifstmt, "Integer addition may overflow inside if statement." From 08f04d53864d461155e536c5e86326864607eb43 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Thu, 23 Feb 2023 17:50:02 -0500 Subject: [PATCH 004/739] Update IfStatementAdditionOverflow.ql --- .../CWE/CWE-190/IfStatementAdditionOverflow.ql | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql index 5bfa265fca5..20e77bb5ec0 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql @@ -1,13 +1,8 @@ /** * @name Integer addition may overflow inside if statement - * @description Detects "if (a+b>c) a=c-b", which incorrectly implements - * a = min(a,c-b) if a+b overflows. Should be replaced by - * "if (a>c-b) a=c-b". Also detects "if (b+a>c) a=c-b" - * (swapped terms in addition), if (a+b>c) { a=c-b }" - * (assignment inside block), "c=", "<", "<=" instead of ">" (all operators). This - * integer overflow is the root cause of the buffer overflow - * in the SHA-3 reference implementation (CVE-2022-37454). + * @description "if (a+b>c) a=c-b" was detected where "a+b" may potentially + * produce an integer overflow (or wraparound). The code can be + * rewritten to "if (a>c-b) a=c-b" which avoids the overflow. * @kind problem * @problem.severity warning * @id cpp/if-statement-addition-overflow @@ -27,7 +22,6 @@ from IfStmt ifstmt, RelationalOperation relop, ExprStmt exprstmt, BlockStmt bloc where ifstmt.getCondition() = relop and relop.getAnOperand() = addexpr and addexpr.getUnspecifiedType() instanceof IntegralType and - subexpr.getUnspecifiedType() instanceof IntegralType and not isFromMacroDefinition(relop) and exprMightOverflowPositively(addexpr) and (ifstmt.getThen() = exprstmt or @@ -39,6 +33,5 @@ where ifstmt.getCondition() = relop and globalValueNumber(addexpr.getRightOperand()) = globalValueNumber(subexpr.getRightOperand())) or (hashCons(addexpr.getRightOperand()) = hashCons(assignexpr.getLValue()) and globalValueNumber(addexpr.getLeftOperand()) = globalValueNumber(subexpr.getRightOperand()))) and - globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) and - not globalValueNumber(addexpr.getAnOperand()) = globalValueNumber(relop.getAnOperand()) + globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) select ifstmt, "Integer addition may overflow inside if statement." From dc09c9218ebb4bcb3f84797239a4028023804b1e Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Sun, 12 Mar 2023 01:05:18 -0500 Subject: [PATCH 005/739] Update IfStatementAdditionOverflow.ql --- .../CWE/CWE-190/IfStatementAdditionOverflow.ql | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql index 20e77bb5ec0..a45ba737bab 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql @@ -1,8 +1,13 @@ /** * @name Integer addition may overflow inside if statement - * @description "if (a+b>c) a=c-b" was detected where "a+b" may potentially - * produce an integer overflow (or wraparound). The code can be - * rewritten to "if (a>c-b) a=c-b" which avoids the overflow. + * @description Detects "if (a+b>c) a=c-b", which incorrectly implements + * a = min(a,c-b) if a+b overflows. Should be replaced by + * "if (a>c-b) a=c-b". Also detects "if (b+a>c) a=c-b" + * (swapped terms in addition), if (a+b>c) { a=c-b }" + * (assignment inside block), "c=", "<", "<=" instead of ">" (all operators). This + * integer overflow is the root cause of the buffer overflow + * in the SHA-3 reference implementation (CVE-2022-37454). * @kind problem * @problem.severity warning * @id cpp/if-statement-addition-overflow @@ -34,4 +39,4 @@ where ifstmt.getCondition() = relop and (hashCons(addexpr.getRightOperand()) = hashCons(assignexpr.getLValue()) and globalValueNumber(addexpr.getLeftOperand()) = globalValueNumber(subexpr.getRightOperand()))) and globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) -select ifstmt, "Integer addition may overflow inside if statement." +select ifstmt, "\"if (a+b>c) a=c-b\" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as \"if (a>c-b) a=c-b\" which avoids the overflow.", addexpr, "addition" From 91a9a7eb32d3e4a0ea73eeb0d092861a4161f0c7 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Sun, 12 Mar 2023 01:13:32 -0500 Subject: [PATCH 006/739] Create test.cpp --- .../IfStatementAdditionOverflow/test.cpp | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp new file mode 100644 index 00000000000..ca67c5578c7 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp @@ -0,0 +1,59 @@ + +int getAnInt(); +double getADouble(); +unsigned short getAnUnsignedShort(); + +void test() +{ + int a = getAnInt(); + int b = getAnInt(); + int c = getAnInt(); + int x = getAnInt(); + int y = getAnInt(); + int d = getADouble(); + int a1 = getAnUnsignedShort(); + int b1 = getAnUnsignedShort(); + int c1 = getAnUnsignedShort(); + + if (a+b>c) a = c-b; // BAD + if (a+b>c) { a = c-b; } // BAD + if (b+a>c) a = c-b; // BAD + if (b+a>c) { a = c-b; } // BAD + if (c>a+b) a = c-b; // BAD + if (c>a+b) { a = c-b; } // BAD + if (c>b+a) a = c-b; // BAD + if (c>b+a) { a = c-b; } // BAD + + if (a+b>=c) a = c-b; // BAD + if (a+b>=c) { a = c-b; } // BAD + if (b+a>=c) a = c-b; // BAD + if (b+a>=c) { a = c-b; } // BAD + if (c>=a+b) a = c-b; // BAD + if (c>=a+b) { a = c-b; } // BAD + if (c>=b+a) a = c-b; // BAD + if (c>=b+a) { a = c-b; } // BAD + + if (a+bd) a = d-b; // GOOD + if (a+(-x)>c) a = c-(-y); // GOOD + if (a+b>c) { b++; a = c-b; } // GOOD + if (a+d>c) a = c-d; // GOOD + if (a1+b1>c1) a1 = c1-b1; // GOOD +} From 2477c3a1c26d86c3b6c30c45fe8735f264bb5426 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Sun, 12 Mar 2023 03:25:52 -0400 Subject: [PATCH 007/739] Update test.cpp --- .../CWE/CWE-190/IfStatementAdditionOverflow/test.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp index ca67c5578c7..47c077a3c9b 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp @@ -8,12 +8,12 @@ void test() int a = getAnInt(); int b = getAnInt(); int c = getAnInt(); - int x = getAnInt(); + int x = getAnInt(); int y = getAnInt(); - int d = getADouble(); - int a1 = getAnUnsignedShort(); - int b1 = getAnUnsignedShort(); - int c1 = getAnUnsignedShort(); + double d = getADouble(); + unsigned short a1 = getAnUnsignedShort(); + unsigned short b1 = getAnUnsignedShort(); + unsigned short c1 = getAnUnsignedShort(); if (a+b>c) a = c-b; // BAD if (a+b>c) { a = c-b; } // BAD @@ -51,7 +51,7 @@ void test() if (c<=b+a) a = c-b; // BAD if (c<=b+a) { a = c-b; } // BAD - if (a+b>d) a = d-b; // GOOD + if (a+b>d) a = d-b; // BAD if (a+(-x)>c) a = c-(-y); // GOOD if (a+b>c) { b++; a = c-b; } // GOOD if (a+d>c) a = c-d; // GOOD From 59c1ae7734bb18431006c40841904cf132c95815 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Sun, 12 Mar 2023 03:27:10 -0400 Subject: [PATCH 008/739] Update test.cpp --- .../Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp index 47c077a3c9b..5879a7ca2a3 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp @@ -8,7 +8,7 @@ void test() int a = getAnInt(); int b = getAnInt(); int c = getAnInt(); - int x = getAnInt(); + int x = getAnInt(); int y = getAnInt(); double d = getADouble(); unsigned short a1 = getAnUnsignedShort(); From 66710ad5a03fa6b1d60f08f6a90c297aa7835299 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Sun, 12 Mar 2023 03:30:26 -0400 Subject: [PATCH 009/739] Create IfStatementAdditionOverflow.qlref --- .../IfStatementAdditionOverflow.qlref | 1 + 1 file changed, 1 insertion(+) create mode 100644 cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.qlref diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.qlref new file mode 100644 index 00000000000..0873051581d --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql From a2b5fbf24c72f9b810f2ede79ba997c4b047aa17 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Sun, 12 Mar 2023 03:31:48 -0400 Subject: [PATCH 010/739] Create IfStatementAdditionOverflow.expected --- .../IfStatementAdditionOverflow.expected | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.expected diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.expected new file mode 100644 index 00000000000..12dbde04790 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.expected @@ -0,0 +1,33 @@ +| test.cpp:18:2:18:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:18:6:18:8 | ... + ... | addition | +| test.cpp:19:2:19:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:19:6:19:8 | ... + ... | addition | +| test.cpp:20:2:20:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:20:6:20:8 | ... + ... | addition | +| test.cpp:21:2:21:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:21:6:21:8 | ... + ... | addition | +| test.cpp:22:2:22:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:22:8:22:10 | ... + ... | addition | +| test.cpp:23:2:23:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:23:8:23:10 | ... + ... | addition | +| test.cpp:24:2:24:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:24:8:24:10 | ... + ... | addition | +| test.cpp:25:2:25:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:25:8:25:10 | ... + ... | addition | +| test.cpp:27:2:27:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:27:6:27:8 | ... + ... | addition | +| test.cpp:28:2:28:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:28:6:28:8 | ... + ... | addition | +| test.cpp:29:2:29:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:29:6:29:8 | ... + ... | addition | +| test.cpp:30:2:30:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:30:6:30:8 | ... + ... | addition | +| test.cpp:31:2:31:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:31:9:31:11 | ... + ... | addition | +| test.cpp:32:2:32:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:32:9:32:11 | ... + ... | addition | +| test.cpp:33:2:33:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:33:9:33:11 | ... + ... | addition | +| test.cpp:34:2:34:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:34:9:34:11 | ... + ... | addition | +| test.cpp:36:2:36:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:36:6:36:8 | ... + ... | addition | +| test.cpp:37:2:37:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:37:6:37:8 | ... + ... | addition | +| test.cpp:38:2:38:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:38:6:38:8 | ... + ... | addition | +| test.cpp:39:2:39:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:39:6:39:8 | ... + ... | addition | +| test.cpp:40:2:40:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:40:8:40:10 | ... + ... | addition | +| test.cpp:41:2:41:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:41:8:41:10 | ... + ... | addition | +| test.cpp:42:2:42:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:42:8:42:10 | ... + ... | addition | +| test.cpp:43:2:43:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:43:8:43:10 | ... + ... | addition | +| test.cpp:45:2:45:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:45:6:45:8 | ... + ... | addition | +| test.cpp:46:2:46:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:46:6:46:8 | ... + ... | addition | +| test.cpp:47:2:47:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:47:6:47:8 | ... + ... | addition | +| test.cpp:48:2:48:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:48:6:48:8 | ... + ... | addition | +| test.cpp:49:2:49:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:49:9:49:11 | ... + ... | addition | +| test.cpp:50:2:50:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:50:9:50:11 | ... + ... | addition | +| test.cpp:51:2:51:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:51:9:51:11 | ... + ... | addition | +| test.cpp:52:2:52:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:52:9:52:11 | ... + ... | addition | +| test.cpp:54:2:54:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:54:6:54:8 | ... + ... | addition | From 2de0e2209edde14d3fb930e44eb1d879e499fc80 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Thu, 16 Mar 2023 02:34:40 -0400 Subject: [PATCH 011/739] Update test.cpp --- .../Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp index 5879a7ca2a3..f1aac83122b 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp @@ -52,6 +52,7 @@ void test() if (c<=b+a) { a = c-b; } // BAD if (a+b>d) a = d-b; // BAD + if (a+(double)b>c) a = c-b; // GOOD if (a+(-x)>c) a = c-(-y); // GOOD if (a+b>c) { b++; a = c-b; } // GOOD if (a+d>c) a = c-d; // GOOD From 6a3d995b357ff0a39c65fd5c3b534dc0da268f89 Mon Sep 17 00:00:00 2001 From: Maiky <76447395+maikypedia@users.noreply.github.com> Date: Sat, 6 May 2023 12:25:25 +0200 Subject: [PATCH 012/739] Add Mysql2 as SQL Injection Sink --- ruby/ql/lib/change-notes/2023-05-06-mysql2.md | 4 ++ ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll | 49 +++++++++++++++++++ .../security/SqlInjectionCustomizations.qll | 22 ++++++++- .../frameworks/mysql2/Mysql2.expected | 5 ++ .../library-tests/frameworks/mysql2/Mysql2.ql | 5 ++ .../library-tests/frameworks/mysql2/Mysql2.rb | 30 ++++++++++++ 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 ruby/ql/lib/change-notes/2023-05-06-mysql2.md create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll create mode 100644 ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.expected create mode 100644 ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.ql create mode 100644 ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.rb diff --git a/ruby/ql/lib/change-notes/2023-05-06-mysql2.md b/ruby/ql/lib/change-notes/2023-05-06-mysql2.md new file mode 100644 index 00000000000..d8fa92dd394 --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-05-06-mysql2.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Support for the `mysql2` gem has been added. Method calls that execute queries against an MySQL database that may be vulnerable to injection attacks will now be recognized. \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll new file mode 100644 index 00000000000..efea7383a4c --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll @@ -0,0 +1,49 @@ +/** + * Provides modeling for mysql2, a Ruby library (gem) for interacting with MySql databases. + */ + +private import codeql.ruby.ApiGraphs +private import codeql.ruby.dataflow.FlowSummary +private import codeql.ruby.Concepts + +/** + * Provides modeling for mysql2, a Ruby library (gem) for interacting with MySql databases. + */ +module Mysql2 { + /** + * Flow summary for `Mysql2::Client.new()`. + */ + private class SqlSummary extends SummarizedCallable { + SqlSummary() { this = "Mysql2::Client.new()" } + + override MethodCall getACall() { result = any(Mysql2Connection c).asExpr().getExpr() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and output = "ReturnValue" and preservesValue = false + } + } + + /** A call to Mysql2::Client.new() is used to establish a connection to a MySql database. */ + private class Mysql2Connection extends DataFlow::CallNode { + Mysql2Connection() { + this = API::getTopLevelMember("Mysql2").getMember("Client").getAnInstantiation() + } + } + + /** A call that executes SQL statements against a MySQL database. */ + private class Mysql2Execution extends SqlExecution::Range, DataFlow::CallNode { + private DataFlow::Node query; + + Mysql2Execution() { + exists(Mysql2Connection mysql2Connection, DataFlow::CallNode prepareCall | + this = mysql2Connection.getAMethodCall("query") and query = this.getArgument(0) + or + prepareCall = mysql2Connection.getAMethodCall("prepare") and + query = prepareCall.getArgument(0) and + this = prepareCall.getAMethodCall("execute") + ) + } + + override DataFlow::Node getSql() { result = query } + } +} diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll index c82b44d4349..546e84e023b 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll @@ -7,6 +7,7 @@ private import codeql.ruby.Concepts private import codeql.ruby.DataFlow private import codeql.ruby.dataflow.BarrierGuards private import codeql.ruby.dataflow.RemoteFlowSources +private import codeql.ruby.ApiGraphs /** * Provides default sources, sinks and sanitizers for detecting SQL injection @@ -51,6 +52,23 @@ module SqlInjection { * sanitizer-guard. */ class StringConstArrayInclusionCallAsSanitizer extends Sanitizer, - StringConstArrayInclusionCallBarrier - { } + StringConstArrayInclusionCallBarrier { } + + /** + * A call to `Mysql2::Client.escape`, considered as a sanitizer. + */ + class Mysql2EscapeSanitization extends Sanitizer { + Mysql2EscapeSanitization() { + this = API::getTopLevelMember("Mysql2").getMember("Client").getAMethodCall("escape") + } + } + + /** + * A call to `SQLite3::Database.quote`, considered as a sanitizer. + */ + class SQLite3EscapeSanitization extends Sanitizer { + SQLite3EscapeSanitization() { + this = API::getTopLevelMember("SQLite3").getMember("Database").getAMethodCall("quote") + } + } } diff --git a/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.expected b/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.expected new file mode 100644 index 00000000000..cc87a7d3403 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.expected @@ -0,0 +1,5 @@ +| Mysql2.rb:10:16:10:48 | call to query | Mysql2.rb:10:27:10:47 | "SELECT * FROM users" | +| Mysql2.rb:13:16:13:73 | call to query | Mysql2.rb:13:27:13:72 | "SELECT * FROM users WHERE use..." | +| Mysql2.rb:17:16:17:76 | call to query | Mysql2.rb:17:27:17:75 | "SELECT * FROM users WHERE use..." | +| Mysql2.rb:21:16:21:57 | call to execute | Mysql2.rb:20:31:20:82 | "SELECT * FROM users WHERE id ..." | +| Mysql2.rb:25:16:25:60 | call to execute | Mysql2.rb:24:31:24:93 | "SELECT * FROM users WHERE use..." | diff --git a/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.ql b/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.ql new file mode 100644 index 00000000000..c019bf0751b --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.ql @@ -0,0 +1,5 @@ +private import codeql.ruby.DataFlow +private import codeql.ruby.Concepts +private import codeql.ruby.frameworks.Mysql2 + +query predicate mysql2SqlExecution(SqlExecution e, DataFlow::Node sql) { sql = e.getSql() } diff --git a/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.rb b/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.rb new file mode 100644 index 00000000000..b9b3b5a7b57 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/mysql2/Mysql2.rb @@ -0,0 +1,30 @@ +class UsersController < ActionController::Base + def mysql2_handler(event:, context:) + name = params[:user_name] + + conn = Mysql2::Client.new( + host: "127.0.0.1", + username: "root" + ) + # GOOD: SQL statement is not constructed from user input + results1 = conn.query("SELECT * FROM users") + + # BAD: SQL statement constructed from user input + results2 = conn.query("SELECT * FROM users WHERE username='#{name}'") + + # GOOD: user input is escaped + escaped = Mysql2::Client.escape(name) + results3 = conn.query("SELECT * FROM users WHERE username='#{escaped}'") + + # GOOD: user input is escaped + statement1 = conn.prepare("SELECT * FROM users WHERE id >= ? AND username = ?") + results4 = statement1.execute(1, name, :as => :array) + + # BAD: SQL statement constructed from user input + statement2 = conn.prepare("SELECT * FROM users WHERE username='#{name}' AND password = ?") + results4 = statement2.execute("password", :as => :array) + + # NOT EXECUTED + statement3 = conn.prepare("SELECT * FROM users WHERE username = ?") + end +end \ No newline at end of file From 3960853af0962bf8512d0465bcdae0bdfa3ee4f4 Mon Sep 17 00:00:00 2001 From: Maiky <76447395+maikypedia@users.noreply.github.com> Date: Sun, 7 May 2023 23:56:56 +0200 Subject: [PATCH 013/739] CWE-089 Add Sequel SQL Injection Sink --- ruby/ql/lib/change-notes/2023-05-07-sequel.md | 4 ++ ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/Sequel.qll | 71 +++++++++++++++++++ .../frameworks/sequel/Sequel.expected | 23 ++++++ .../library-tests/frameworks/sequel/Sequel.ql | 7 ++ .../library-tests/frameworks/sequel/sequel.rb | 67 +++++++++++++++++ 6 files changed, 173 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2023-05-07-sequel.md create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/Sequel.qll create mode 100644 ruby/ql/test/library-tests/frameworks/sequel/Sequel.expected create mode 100644 ruby/ql/test/library-tests/frameworks/sequel/Sequel.ql create mode 100644 ruby/ql/test/library-tests/frameworks/sequel/sequel.rb diff --git a/ruby/ql/lib/change-notes/2023-05-07-sequel.md b/ruby/ql/lib/change-notes/2023-05-07-sequel.md new file mode 100644 index 00000000000..3688f28db56 --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-05-07-sequel.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Support for the `sequel` gem has been added. Method calls that execute queries against a database that may be vulnerable to injection attacks will now be recognized. diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index e61ac723e7e..d7b76c090b2 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -32,3 +32,4 @@ private import codeql.ruby.frameworks.Slim private import codeql.ruby.frameworks.Sinatra private import codeql.ruby.frameworks.Twirp private import codeql.ruby.frameworks.Sqlite3 +private import codeql.ruby.frameworks.Sequel diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Sequel.qll b/ruby/ql/lib/codeql/ruby/frameworks/Sequel.qll new file mode 100644 index 00000000000..b9488a92016 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Sequel.qll @@ -0,0 +1,71 @@ +/** + * Provides modeling for `Sequel`, the database toolkit for Ruby. + * https://github.com/jeremyevans/sequel + */ + +private import ruby +private import codeql.ruby.ApiGraphs +private import codeql.ruby.dataflow.FlowSummary +private import codeql.ruby.Concepts + +/** + * Provides modeling for `Sequel`, the database toolkit for Ruby. + * https://github.com/jeremyevans/sequel + */ +module Sequel { + /** Flow Summary for `Sequel`. */ + private class SqlSummary extends SummarizedCallable { + SqlSummary() { this = "Sequel.connect" } + + override MethodCall getACall() { result = any(SequelConnection c).asExpr().getExpr() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and output = "ReturnValue" and preservesValue = false + } + } + + /** A call to establish a connection to a database */ + private class SequelConnection extends DataFlow::CallNode { + SequelConnection() { + this = + API::getTopLevelMember("Sequel").getAMethodCall(["connect", "sqlite", "mysql2", "jdbc"]) + } + } + + /** A call that constructs SQL statements */ + private class SequelConstruction extends SqlConstruction::Range, DataFlow::CallNode { + DataFlow::Node query; + + SequelConstruction() { + this = API::getTopLevelMember("Sequel").getAMethodCall("cast") and query = this.getArgument(1) + or + this = API::getTopLevelMember("Sequel").getAMethodCall("function") and + query = this.getArgument(0) + } + + override DataFlow::Node getSql() { result = query } + } + + /** A call that executes SQL statements against a database */ + private class SequelExecution extends SqlExecution::Range, DataFlow::CallNode { + SequelExecution() { + exists(SequelConnection sequelConnection | + this = + sequelConnection + .getAMethodCall([ + "execute", "execute_ddl", "execute_dui", "execute_insert", "run", "<<", "fetch", + "fetch_rows", "[]", "log_connection_yield" + ]) or + this = + sequelConnection + .getAMethodCall("dataset") + .getAMethodCall([ + "with_sql", "with_sql_all", "with_sql_delete", "with_sql_each", "with_sql_first", + "with_sql_insert", "with_sql_single_value", "with_sql_update" + ]) + ) + } + + override DataFlow::Node getSql() { result = this.getArgument(0) } + } +} diff --git a/ruby/ql/test/library-tests/frameworks/sequel/Sequel.expected b/ruby/ql/test/library-tests/frameworks/sequel/Sequel.expected new file mode 100644 index 00000000000..b44d06e6c19 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/sequel/Sequel.expected @@ -0,0 +1,23 @@ +sequelSqlConstruction +| sequel.rb:63:29:63:49 | call to cast | sequel.rb:63:45:63:48 | name | +| sequel.rb:66:29:66:49 | call to function | sequel.rb:66:45:66:48 | name | +sequelSqlExecution +| sequel.rb:10:9:10:60 | ...[...] | sequel.rb:10:14:10:59 | "SELECT * FROM users WHERE use..." | +| sequel.rb:13:9:13:64 | call to run | sequel.rb:13:18:13:63 | "SELECT * FROM users WHERE use..." | +| sequel.rb:16:9:18:11 | call to fetch | sequel.rb:16:20:16:65 | "SELECT * FROM users WHERE use..." | +| sequel.rb:21:9:21:65 | ...[...] | sequel.rb:21:14:21:64 | "SELECT * FROM users WHERE use..." | +| sequel.rb:24:9:24:65 | call to execute | sequel.rb:24:22:24:65 | "SELECT * FROM users WHERE use..." | +| sequel.rb:27:9:27:71 | call to execute_ddl | sequel.rb:27:26:27:71 | "SELECT * FROM users WHERE use..." | +| sequel.rb:30:9:30:71 | call to execute_dui | sequel.rb:30:26:30:71 | "SELECT * FROM users WHERE use..." | +| sequel.rb:33:9:33:74 | call to execute_insert | sequel.rb:33:29:33:74 | "SELECT * FROM users WHERE use..." | +| sequel.rb:36:9:36:62 | ... << ... | sequel.rb:36:17:36:62 | "SELECT * FROM users WHERE use..." | +| sequel.rb:39:9:39:79 | call to fetch_rows | sequel.rb:39:25:39:70 | "SELECT * FROM users WHERE use..." | +| sequel.rb:42:9:42:81 | call to with_sql_all | sequel.rb:42:35:42:80 | "SELECT * FROM users WHERE use..." | +| sequel.rb:45:9:45:84 | call to with_sql_delete | sequel.rb:45:38:45:83 | "SELECT * FROM users WHERE use..." | +| sequel.rb:48:9:48:90 | call to with_sql_each | sequel.rb:48:36:48:81 | "SELECT * FROM users WHERE use..." | +| sequel.rb:51:9:51:83 | call to with_sql_first | sequel.rb:51:37:51:82 | "SELECT * FROM users WHERE use..." | +| sequel.rb:54:9:54:84 | call to with_sql_insert | sequel.rb:54:38:54:83 | "SELECT * FROM users WHERE use..." | +| sequel.rb:57:9:57:90 | call to with_sql_single_value | sequel.rb:57:44:57:89 | "SELECT * FROM users WHERE use..." | +| sequel.rb:60:9:60:84 | call to with_sql_update | sequel.rb:60:38:60:83 | "SELECT * FROM users WHERE use..." | +| sequel.rb:63:9:63:20 | ...[...] | sequel.rb:63:14:63:19 | :table | +| sequel.rb:66:9:66:20 | ...[...] | sequel.rb:66:14:66:19 | :table | diff --git a/ruby/ql/test/library-tests/frameworks/sequel/Sequel.ql b/ruby/ql/test/library-tests/frameworks/sequel/Sequel.ql new file mode 100644 index 00000000000..9645c5d4f17 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/sequel/Sequel.ql @@ -0,0 +1,7 @@ +private import codeql.ruby.DataFlow +private import codeql.ruby.Concepts +private import codeql.ruby.frameworks.Sequel + +query predicate sequelSqlConstruction(SqlConstruction c, DataFlow::Node sql) { sql = c.getSql() } + +query predicate sequelSqlExecution(SqlExecution e, DataFlow::Node sql) { sql = e.getSql() } diff --git a/ruby/ql/test/library-tests/frameworks/sequel/sequel.rb b/ruby/ql/test/library-tests/frameworks/sequel/sequel.rb new file mode 100644 index 00000000000..d760f6c3d07 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/sequel/sequel.rb @@ -0,0 +1,67 @@ +require 'sequel' + +class UsersController < ActionController::Base + def sequel_handler(event:, context:) + name = params[:name] + conn = Sequel.sqlite("sqlite://example.db") + + # BAD: SQL statement constructed from user input + conn["SELECT * FROM users WHERE username='#{name}'"] + + # BAD: SQL statement constructed from user input + conn.run("SELECT * FROM users WHERE username='#{name}'") + + # BAD: SQL statement constructed from user input + conn.fetch("SELECT * FROM users WHERE username='#{name}'") do |row| + puts row[:name] + end + + # GOOD: SQL statement is not constructed from user input + conn["SELECT * FROM users WHERE username='im_not_input'"] + + # BAD: SQL statement constructed from user input + conn.execute "SELECT * FROM users WHERE username=#{name}" + + # BAD: SQL statement constructed from user input + conn.execute_ddl "SELECT * FROM users WHERE username='#{name}'" + + # BAD: SQL statement constructed from user input + conn.execute_dui "SELECT * FROM users WHERE username='#{name}'" + + # BAD: SQL statement constructed from user input + conn.execute_insert "SELECT * FROM users WHERE username='#{name}'" + + # BAD: SQL statement constructed from user input + conn << "SELECT * FROM users WHERE username='#{name}'" + + # BAD: SQL statement constructed from user input + conn.fetch_rows("SELECT * FROM users WHERE username='#{name}'"){|row| } + + # BAD: SQL statement constructed from user input + conn.dataset.with_sql_all("SELECT * FROM users WHERE username='#{name}'") + + # BAD: SQL statement constructed from user input + conn.dataset.with_sql_delete("SELECT * FROM users WHERE username='#{name}'") + + # BAD: SQL statement constructed from user input + conn.dataset.with_sql_each("SELECT * FROM users WHERE username='#{name}'"){|row| } + + # BAD: SQL statement constructed from user input + conn.dataset.with_sql_first("SELECT * FROM users WHERE username='#{name}'") + + # BAD: SQL statement constructed from user input + conn.dataset.with_sql_insert("SELECT * FROM users WHERE username='#{name}'") + + # BAD: SQL statement constructed from user input + conn.dataset.with_sql_single_value("SELECT * FROM users WHERE username='#{name}'") + + # BAD: SQL statement constructed from user input + conn.dataset.with_sql_update("SELECT * FROM users WHERE username='#{name}'") + + # BAD: SQL statement constructed from user input + conn[:table].select(Sequel.cast(:a, name)) + + # BAD: SQL statement constructed from user input + conn[:table].select(Sequel.function(name)) + end +end \ No newline at end of file From 8f39f028e654fd1ae85ed2c55d645b762a8a38b3 Mon Sep 17 00:00:00 2001 From: Mathew Payne Date: Tue, 9 May 2023 17:31:51 +0100 Subject: [PATCH 014/739] feat: Additional models as data extensions - `logging`, `ldap`, and `url-redirect` sinks --- csharp/ql/lib/change-notes/2023-05-09-models-as-data.md | 4 ++++ .../code/csharp/security/dataflow/LDAPInjectionQuery.qll | 6 ++++++ .../code/csharp/security/dataflow/LogForgingQuery.qll | 6 ++++++ .../code/csharp/security/dataflow/UrlRedirectQuery.qll | 6 ++++++ 4 files changed, 22 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2023-05-09-models-as-data.md diff --git a/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md b/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md new file mode 100644 index 00000000000..ef7e8a808b6 --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Additional support for `logging`, `ldap`, and `url-redirect` sink kinds for Models as Data. \ No newline at end of file diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll index 9171bae41b4..0e1afdbef7e 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll @@ -8,6 +8,7 @@ private import semmle.code.csharp.security.dataflow.flowsources.Remote private import semmle.code.csharp.frameworks.system.DirectoryServices private import semmle.code.csharp.frameworks.system.directoryservices.Protocols private import semmle.code.csharp.security.Sanitizers +private import semmle.code.csharp.dataflow.ExternalFlow /** * A data flow source for unvalidated user input that is used to construct LDAP queries. @@ -68,6 +69,11 @@ module LdapInjection = TaintTracking::Global; /** A source of remote user input. */ class RemoteSource extends Source instanceof RemoteFlowSource { } +/** LDAP sinks defined through Models as Data. */ +private class ExternalLDAPExprSink extends Sink { + ExternalLDAPExprSink() { sinkNode(this, "ldap") } +} + /** * An argument that sets the `Path` property of a `DirectoryEntry` object that is a sink for LDAP * injection. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll index f145b18dfeb..e304a7be1c5 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll @@ -8,6 +8,7 @@ private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.text.RegularExpressions private import semmle.code.csharp.security.Sanitizers private import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink +private import semmle.code.csharp.dataflow.ExternalFlow /** * A data flow source for untrusted user input used in log entries. @@ -72,6 +73,11 @@ private class LogForgingLogMessageSink extends Sink, LogMessageSink { } */ private class LogForgingTraceMessageSink extends Sink, TraceMessageSink { } +/** Log Forging sinks defined through Models as Data. */ +private class ExternalLDAPExprSink extends Sink { + ExternalLDAPExprSink() { sinkNode(this, "logging") } +} + /** * A call to String replace or remove that is considered to sanitize replaced string. */ diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll index 44b90cf3096..d6f32722792 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll @@ -9,6 +9,7 @@ private import semmle.code.csharp.frameworks.system.Web private import semmle.code.csharp.frameworks.system.web.Mvc private import semmle.code.csharp.security.Sanitizers private import semmle.code.csharp.frameworks.microsoft.AspNetCore +private import semmle.code.csharp.dataflow.ExternalFlow /** * A data flow source for unvalidated URL redirect vulnerabilities. @@ -70,6 +71,11 @@ module UrlRedirect = TaintTracking::Global; /** A source of remote user input. */ class RemoteSource extends Source instanceof RemoteFlowSource { } +/** URL Redirection sinks defined through Models as Data. */ +private class ExternalLDAPExprSink extends Sink { + ExternalLDAPExprSink() { sinkNode(this, "url-redirect") } +} + /** * A URL argument to a call to `HttpResponse.Redirect()` or `Controller.Redirect()`, that is a * sink for URL redirects. From 632e48745823ef8df32e9d2749c50cc4ca0dc3fb Mon Sep 17 00:00:00 2001 From: Mathew Payne Date: Tue, 9 May 2023 17:37:00 +0100 Subject: [PATCH 015/739] Add Command Injection support --- .../code/csharp/security/dataflow/CommandInjectionQuery.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll index 265cae5f08a..7572d696459 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll @@ -6,6 +6,7 @@ import csharp private import semmle.code.csharp.security.dataflow.flowsources.Remote private import semmle.code.csharp.frameworks.system.Diagnostics private import semmle.code.csharp.security.Sanitizers +private import semmle.code.csharp.dataflow.ExternalFlow /** * A source specific to command injection vulnerabilities. @@ -66,6 +67,11 @@ module CommandInjection = TaintTracking::Global; /** A source of remote user input. */ class RemoteSource extends Source instanceof RemoteFlowSource { } +/** Command Injection sinks defined through CSV models. */ +private class ExternalCommandInjectionExprSink extends Sink { + ExternalCommandInjectionExprSink() { sinkNode(this, "command-injection") } +} + /** * A sink in `System.Diagnostic.Process` or its related classes. */ From e84657242c106eabb3b91dc32ecff4806b41b780 Mon Sep 17 00:00:00 2001 From: Mathew Payne Date: Tue, 9 May 2023 17:38:15 +0100 Subject: [PATCH 016/739] Fix names --- .../semmle/code/csharp/security/dataflow/LogForgingQuery.qll | 4 ++-- .../semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll index e304a7be1c5..9b17342345c 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll @@ -74,8 +74,8 @@ private class LogForgingLogMessageSink extends Sink, LogMessageSink { } private class LogForgingTraceMessageSink extends Sink, TraceMessageSink { } /** Log Forging sinks defined through Models as Data. */ -private class ExternalLDAPExprSink extends Sink { - ExternalLDAPExprSink() { sinkNode(this, "logging") } +private class ExternalLoggingExprSink extends Sink { + ExternalLoggingExprSink() { sinkNode(this, "logging") } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll index d6f32722792..66cdee8f2cc 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll @@ -72,8 +72,8 @@ module UrlRedirect = TaintTracking::Global; class RemoteSource extends Source instanceof RemoteFlowSource { } /** URL Redirection sinks defined through Models as Data. */ -private class ExternalLDAPExprSink extends Sink { - ExternalLDAPExprSink() { sinkNode(this, "url-redirect") } +private class ExternalUrlRedirectExprSink extends Sink { + ExternalUrlRedirectExprSink() { sinkNode(this, "url-redirect") } } /** From 7b55955fac59fb3183f82f4145b533999f2b9e9d Mon Sep 17 00:00:00 2001 From: Mathew Payne Date: Tue, 9 May 2023 17:40:12 +0100 Subject: [PATCH 017/739] Update change notes --- csharp/ql/lib/change-notes/2023-05-09-models-as-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md b/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md index ef7e8a808b6..eec683c707c 100644 --- a/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md +++ b/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* Additional support for `logging`, `ldap`, and `url-redirect` sink kinds for Models as Data. \ No newline at end of file +* Additional support for `logging`, `ldap`, `command-injection`, and `url-redirect` sink kinds for Models as Data. \ No newline at end of file From 0e932574f45e51523fbf89898f7b3cc8fa6f8b66 Mon Sep 17 00:00:00 2001 From: Mathew Payne Date: Tue, 9 May 2023 17:42:17 +0100 Subject: [PATCH 018/739] Fix Ldap class name --- .../code/csharp/security/dataflow/LDAPInjectionQuery.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll index 0e1afdbef7e..ba18e27e33c 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll @@ -70,8 +70,8 @@ module LdapInjection = TaintTracking::Global; class RemoteSource extends Source instanceof RemoteFlowSource { } /** LDAP sinks defined through Models as Data. */ -private class ExternalLDAPExprSink extends Sink { - ExternalLDAPExprSink() { sinkNode(this, "ldap") } +private class ExternalLdapExprSink extends Sink { + ExternalLdapExprSink() { sinkNode(this, "ldap") } } /** From 0f85b98cc771d5da6c6c98622af7cd65c9a17d6c Mon Sep 17 00:00:00 2001 From: Mathew Payne Date: Wed, 10 May 2023 10:00:16 +0100 Subject: [PATCH 019/739] Update models to match new data extensions names --- .../semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll | 2 +- .../semmle/code/csharp/security/dataflow/LogForgingQuery.qll | 2 +- .../semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll index ba18e27e33c..838fb2f373b 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll @@ -71,7 +71,7 @@ class RemoteSource extends Source instanceof RemoteFlowSource { } /** LDAP sinks defined through Models as Data. */ private class ExternalLdapExprSink extends Sink { - ExternalLdapExprSink() { sinkNode(this, "ldap") } + ExternalLdapExprSink() { sinkNode(this, "ldap-injection") } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll index 9b17342345c..e219b5db589 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LogForgingQuery.qll @@ -75,7 +75,7 @@ private class LogForgingTraceMessageSink extends Sink, TraceMessageSink { } /** Log Forging sinks defined through Models as Data. */ private class ExternalLoggingExprSink extends Sink { - ExternalLoggingExprSink() { sinkNode(this, "logging") } + ExternalLoggingExprSink() { sinkNode(this, "log-injection") } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll index 66cdee8f2cc..56c409b38b5 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll @@ -73,7 +73,7 @@ class RemoteSource extends Source instanceof RemoteFlowSource { } /** URL Redirection sinks defined through Models as Data. */ private class ExternalUrlRedirectExprSink extends Sink { - ExternalUrlRedirectExprSink() { sinkNode(this, "url-redirect") } + ExternalUrlRedirectExprSink() { sinkNode(this, "url-redirection") } } /** From 681623d631f24726faa7a9e663fe921ee9a3d57c Mon Sep 17 00:00:00 2001 From: Mathew Payne Date: Wed, 10 May 2023 10:06:22 +0100 Subject: [PATCH 020/739] Update kind model validation --- csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 1f57626840b..0ce50e54a3a 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -211,7 +211,11 @@ module ModelValidation { ) or exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | - not kind = ["code", "sql", "xss", "remote", "html"] and + not kind = + [ + "code", "command-injection", "html", "ldap-injection", "log-injection", "remote", "sql", + "url-redirection", "xss", + ] and not kind.matches("encryption-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) From bffc233d865f38a0ce20ec163847f6206c60a32d Mon Sep 17 00:00:00 2001 From: Mathew Payne Date: Wed, 10 May 2023 10:09:19 +0100 Subject: [PATCH 021/739] Update release notes --- csharp/ql/lib/change-notes/2023-05-09-models-as-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md b/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md index eec683c707c..c0abd8f06c0 100644 --- a/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md +++ b/csharp/ql/lib/change-notes/2023-05-09-models-as-data.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* Additional support for `logging`, `ldap`, `command-injection`, and `url-redirect` sink kinds for Models as Data. \ No newline at end of file +* Additional support for `command-injection`, `ldap-injection`, `log-injection`, and `url-redirection` sink kinds for Models as Data. \ No newline at end of file From 3193b3b171c01bb7c49dc52452389ee3fe9f2ca7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 15 May 2023 10:51:21 +0100 Subject: [PATCH 022/739] Swift: Make the CleartextLogging.ql query ID consistent with the other swift/cleartext-* queries. --- swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql b/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql index 2d76f1d3e7e..d4314ab1631 100644 --- a/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql +++ b/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql @@ -6,7 +6,7 @@ * @problem.severity error * @security-severity 7.5 * @precision high - * @id swift/clear-text-logging + * @id swift/cleartext-logging * @tags security * external/cwe/cwe-312 * external/cwe/cwe-359 From 2a4d7cb642f5bd6c7121d9b3205f6d8e84812bc0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 15 May 2023 11:53:58 +0100 Subject: [PATCH 023/739] Swift: Make the result message consistent as well. --- .../src/queries/Security/CWE-312/CleartextLogging.ql | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql b/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql index d4314ab1631..764a4af3d94 100644 --- a/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql +++ b/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql @@ -18,7 +18,9 @@ import codeql.swift.dataflow.DataFlow import codeql.swift.security.CleartextLoggingQuery import CleartextLoggingFlow::PathGraph -from CleartextLoggingFlow::PathNode src, CleartextLoggingFlow::PathNode sink -where CleartextLoggingFlow::flowPath(src, sink) -select sink.getNode(), src, sink, "This $@ is written to a log file.", src.getNode(), - "potentially sensitive information" +from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink +where CleartextLoggingFlow::flowPath(source, sink) +select sink, source, sink, + "This operation writes '" + sink.toString() + + "' to a log file. It may contain unencrypted sensitive data from $@.", source, + source.getNode().toString() From f46620c455b76b49381fbde233c70431fafd8f8d Mon Sep 17 00:00:00 2001 From: Maiky <76447395+maikypedia@users.noreply.github.com> Date: Mon, 15 May 2023 15:09:44 +0200 Subject: [PATCH 024/739] Var only used in one side of disjunct --- ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll index efea7383a4c..c1c74813b75 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll @@ -35,12 +35,14 @@ module Mysql2 { private DataFlow::Node query; Mysql2Execution() { - exists(Mysql2Connection mysql2Connection, DataFlow::CallNode prepareCall | + exists(Mysql2Connection mysql2Connection | this = mysql2Connection.getAMethodCall("query") and query = this.getArgument(0) or - prepareCall = mysql2Connection.getAMethodCall("prepare") and - query = prepareCall.getArgument(0) and - this = prepareCall.getAMethodCall("execute") + exists(DataFlow::CallNode prepareCall | + prepareCall = mysql2Connection.getAMethodCall("prepare") and + query = prepareCall.getArgument(0) and + this = prepareCall.getAMethodCall("execute") + ) ) } From 3c002353755bb8af5d26770d6e01b07bd1d65020 Mon Sep 17 00:00:00 2001 From: Maiky <76447395+maikypedia@users.noreply.github.com> Date: Mon, 15 May 2023 15:56:52 +0200 Subject: [PATCH 025/739] Add SqlSanitization to `Concepts` and turn private --- ruby/ql/lib/codeql/ruby/Concepts.qll | 13 +++++++++++++ ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 + .../ruby/security/SqlInjectionCustomizations.qll | 4 ++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/Concepts.qll b/ruby/ql/lib/codeql/ruby/Concepts.qll index ec27694581f..0a403734512 100644 --- a/ruby/ql/lib/codeql/ruby/Concepts.qll +++ b/ruby/ql/lib/codeql/ruby/Concepts.qll @@ -78,6 +78,19 @@ module SqlExecution { } } + /** + * A data-flow node that performs SQL sanitization. + */ + class SqlSanitization extends DataFlow::Node instanceof SqlSanitization::Range { } + + /** Provides a class for modeling new SQL sanitization APIs. */ + module SqlSanitization { + /** + * A data-flow node that performs SQL sanitization. + */ + abstract class Range extends DataFlow::Node { } + } + /** * A data-flow node that executes a regular expression. * diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index e61ac723e7e..7da37077df9 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -32,3 +32,4 @@ private import codeql.ruby.frameworks.Slim private import codeql.ruby.frameworks.Sinatra private import codeql.ruby.frameworks.Twirp private import codeql.ruby.frameworks.Sqlite3 +private import codeql.ruby.frameworks.Mysql2 \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll index 546e84e023b..e1e1b630d9d 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll @@ -57,7 +57,7 @@ module SqlInjection { /** * A call to `Mysql2::Client.escape`, considered as a sanitizer. */ - class Mysql2EscapeSanitization extends Sanitizer { + private class Mysql2EscapeSanitization extends Sanitizer { Mysql2EscapeSanitization() { this = API::getTopLevelMember("Mysql2").getMember("Client").getAMethodCall("escape") } @@ -66,7 +66,7 @@ module SqlInjection { /** * A call to `SQLite3::Database.quote`, considered as a sanitizer. */ - class SQLite3EscapeSanitization extends Sanitizer { + private class SQLite3EscapeSanitization extends Sanitizer { SQLite3EscapeSanitization() { this = API::getTopLevelMember("SQLite3").getMember("Database").getAMethodCall("quote") } From cc72bfbbbb4e1738396350f8265cea0b0a4ba7c6 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 May 2023 13:52:54 +0100 Subject: [PATCH 026/739] Swift: Add the shared SensitiveDataHeuristics.qll to Swift. --- config/identical-files.json | 5 +- .../internal/SensitiveDataHeuristics.qll | 124 ++++++++++++++++++ 2 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll diff --git a/config/identical-files.json b/config/identical-files.json index 3a9ef5173aa..4991f92d93c 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -512,7 +512,8 @@ "SensitiveDataHeuristics Python/JS": [ "javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll", "python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll", - "ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll" + "ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll", + "swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll" ], "CFG": [ "csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll", @@ -599,4 +600,4 @@ "python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll", "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" ] -} \ No newline at end of file +} diff --git a/swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll b/swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll new file mode 100644 index 00000000000..7bc61ee2aee --- /dev/null +++ b/swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll @@ -0,0 +1,124 @@ +/** + * INTERNAL: Do not use. + * + * Provides classes and predicates for identifying strings that may indicate the presence of sensitive data. + * Such that we can share this logic across our CodeQL analysis of different languages. + * + * 'Sensitive' data in general is anything that should not be sent around in unencrypted form. + */ + +/** + * A classification of different kinds of sensitive data: + * + * - secret: generic secret or trusted data; + * - id: a user name or other account information; + * - password: a password or authorization key; + * - certificate: a certificate. + * + * While classifications are represented as strings, this should not be relied upon. + * Instead, use the predicates in `SensitiveDataClassification::` to work with + * classifications. + */ +class SensitiveDataClassification extends string { + SensitiveDataClassification() { this in ["secret", "id", "password", "certificate"] } +} + +/** + * Provides predicates to select the different kinds of sensitive data we support. + */ +module SensitiveDataClassification { + /** Gets the classification for secret or trusted data. */ + SensitiveDataClassification secret() { result = "secret" } + + /** Gets the classification for user names or other account information. */ + SensitiveDataClassification id() { result = "id" } + + /** Gets the classification for passwords or authorization keys. */ + SensitiveDataClassification password() { result = "password" } + + /** Gets the classification for certificates. */ + SensitiveDataClassification certificate() { result = "certificate" } +} + +/** + * INTERNAL: Do not use. + * + * Provides heuristics for identifying names related to sensitive information. + */ +module HeuristicNames { + /** + * Gets a regular expression that identifies strings that may indicate the presence of secret + * or trusted data. + */ + string maybeSecret() { result = "(?is).*((? Date: Thu, 11 May 2023 16:50:58 +0100 Subject: [PATCH 027/739] Swift: Use SensitiveDataHeuristics.qll in regexpProbablySafe. --- .../codeql/swift/security/SensitiveExprs.qll | 3 ++- .../CWE-311/CleartextStorageDatabase.expected | 17 +++++++++++++---- .../Security/CWE-311/SensitiveExprs.expected | 5 +++-- .../CWE-312/CleartextLoggingTest.expected | 1 + .../CleartextStoragePreferences.expected | 8 -------- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index 91f824aa5f2..8dd55d00259 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -5,6 +5,7 @@ */ import swift +import internal.SensitiveDataHeuristics private newtype TSensitiveDataType = TCredential() or @@ -69,7 +70,7 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo { * contain hashed or encrypted data, or are only a reference to data that is * actually stored elsewhere. */ -private string regexpProbablySafe() { result = ".*(hash|crypt|file|path|url|invalid).*" } +private string regexpProbablySafe() { result = HeuristicNames::notSensitiveRegexp() } /** * A `VarDecl` that might be used to contain sensitive data. diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index 320f4873d08..caad0df3190 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -110,11 +110,14 @@ edges | testCoreData.swift:18:19:18:26 | value | testCoreData.swift:19:12:19:12 | value | | testCoreData.swift:31:3:31:3 | newValue | testCoreData.swift:32:13:32:13 | newValue | | testCoreData.swift:61:25:61:25 | password | testCoreData.swift:18:19:18:26 | value | +| testCoreData.swift:62:25:62:25 | password_file | testCoreData.swift:18:19:18:26 | value | | testCoreData.swift:64:2:64:2 | [post] obj [myValue] | testCoreData.swift:64:2:64:2 | [post] obj | | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:31:3:31:3 | newValue | | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:64:2:64:2 | [post] obj [myValue] | +| testCoreData.swift:65:2:65:2 | [post] obj [myValue] | testCoreData.swift:65:2:65:2 | [post] obj | +| testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:31:3:31:3 | newValue | +| testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:65:2:65:2 | [post] obj [myValue] | | testCoreData.swift:77:24:77:24 | x | testCoreData.swift:78:15:78:15 | x | -| testCoreData.swift:80:10:80:22 | call to getPassword() | testCoreData.swift:81:15:81:15 | y | | testCoreData.swift:91:10:91:10 | passwd | testCoreData.swift:95:15:95:15 | x | | testCoreData.swift:92:10:92:10 | passwd | testCoreData.swift:96:15:96:15 | y | | testCoreData.swift:93:10:93:10 | passwd | testCoreData.swift:97:15:97:15 | z | @@ -311,14 +314,17 @@ nodes | testCoreData.swift:48:15:48:15 | password | semmle.label | password | | testCoreData.swift:51:24:51:24 | password | semmle.label | password | | testCoreData.swift:58:15:58:15 | password | semmle.label | password | +| testCoreData.swift:59:15:59:15 | password_file | semmle.label | password_file | | testCoreData.swift:61:25:61:25 | password | semmle.label | password | +| testCoreData.swift:62:25:62:25 | password_file | semmle.label | password_file | | testCoreData.swift:64:2:64:2 | [post] obj | semmle.label | [post] obj | | testCoreData.swift:64:2:64:2 | [post] obj [myValue] | semmle.label | [post] obj [myValue] | | testCoreData.swift:64:16:64:16 | password | semmle.label | password | +| testCoreData.swift:65:2:65:2 | [post] obj | semmle.label | [post] obj | +| testCoreData.swift:65:2:65:2 | [post] obj [myValue] | semmle.label | [post] obj [myValue] | +| testCoreData.swift:65:16:65:16 | password_file | semmle.label | password_file | | testCoreData.swift:77:24:77:24 | x | semmle.label | x | | testCoreData.swift:78:15:78:15 | x | semmle.label | x | -| testCoreData.swift:80:10:80:22 | call to getPassword() | semmle.label | call to getPassword() | -| testCoreData.swift:81:15:81:15 | y | semmle.label | y | | testCoreData.swift:85:15:85:17 | .password | semmle.label | .password | | testCoreData.swift:91:10:91:10 | passwd | semmle.label | passwd | | testCoreData.swift:92:10:92:10 | passwd | semmle.label | passwd | @@ -492,13 +498,16 @@ subpaths | testCoreData2.swift:104:2:104:2 | dbObj | testCoreData2.swift:101:10:101:10 | bankAccountNo | testCoreData2.swift:104:2:104:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:101:10:101:10 | bankAccountNo | bankAccountNo | | testCoreData2.swift:105:2:105:2 | dbObj | testCoreData2.swift:101:10:101:10 | bankAccountNo | testCoreData2.swift:105:2:105:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:101:10:101:10 | bankAccountNo | bankAccountNo | | testCoreData.swift:19:12:19:12 | value | testCoreData.swift:61:25:61:25 | password | testCoreData.swift:19:12:19:12 | value | This operation stores 'value' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:61:25:61:25 | password | password | +| testCoreData.swift:19:12:19:12 | value | testCoreData.swift:62:25:62:25 | password_file | testCoreData.swift:19:12:19:12 | value | This operation stores 'value' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:62:25:62:25 | password_file | password_file | | testCoreData.swift:32:13:32:13 | newValue | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:32:13:32:13 | newValue | This operation stores 'newValue' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password | password | +| testCoreData.swift:32:13:32:13 | newValue | testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:32:13:32:13 | newValue | This operation stores 'newValue' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:65:16:65:16 | password_file | password_file | | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:48:15:48:15 | password | password | | testCoreData.swift:51:24:51:24 | password | testCoreData.swift:51:24:51:24 | password | testCoreData.swift:51:24:51:24 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:51:24:51:24 | password | password | | testCoreData.swift:58:15:58:15 | password | testCoreData.swift:58:15:58:15 | password | testCoreData.swift:58:15:58:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:58:15:58:15 | password | password | +| testCoreData.swift:59:15:59:15 | password_file | testCoreData.swift:59:15:59:15 | password_file | testCoreData.swift:59:15:59:15 | password_file | This operation stores 'password_file' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:59:15:59:15 | password_file | password_file | | testCoreData.swift:64:2:64:2 | obj | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:64:2:64:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password | password | +| testCoreData.swift:65:2:65:2 | obj | testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:65:2:65:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:65:16:65:16 | password_file | password_file | | testCoreData.swift:78:15:78:15 | x | testCoreData.swift:77:24:77:24 | x | testCoreData.swift:78:15:78:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:77:24:77:24 | x | x | -| testCoreData.swift:81:15:81:15 | y | testCoreData.swift:80:10:80:22 | call to getPassword() | testCoreData.swift:81:15:81:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:80:10:80:22 | call to getPassword() | call to getPassword() | | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | This operation stores '.password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:85:15:85:17 | .password | .password | | testCoreData.swift:95:15:95:15 | x | testCoreData.swift:91:10:91:10 | passwd | testCoreData.swift:95:15:95:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:91:10:91:10 | passwd | passwd | | testCoreData.swift:96:15:96:15 | y | testCoreData.swift:92:10:92:10 | passwd | testCoreData.swift:96:15:96:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:92:10:92:10 | passwd | passwd | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 20e1757c132..0960d1983a1 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -51,11 +51,12 @@ | testCoreData.swift:48:15:48:15 | password | label:password, type:credential | | testCoreData.swift:51:24:51:24 | password | label:password, type:credential | | testCoreData.swift:58:15:58:15 | password | label:password, type:credential | +| testCoreData.swift:59:15:59:15 | password_file | label:password_file, type:credential | | testCoreData.swift:61:25:61:25 | password | label:password, type:credential | +| testCoreData.swift:62:25:62:25 | password_file | label:password_file, type:credential | | testCoreData.swift:64:16:64:16 | password | label:password, type:credential | -| testCoreData.swift:77:2:77:25 | call to doSomething(password:) | label:doSomething(password:), type:credential | +| testCoreData.swift:65:16:65:16 | password_file | label:password_file, type:credential | | testCoreData.swift:77:24:77:24 | x | label:password, type:credential | -| testCoreData.swift:80:10:80:22 | call to getPassword() | label:getPassword(), type:credential | | testCoreData.swift:85:15:85:17 | .password | label:password, type:credential | | testCoreData.swift:91:10:91:10 | passwd | label:passwd, type:credential | | testCoreData.swift:92:10:92:10 | passwd | label:passwd, type:credential | diff --git a/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected b/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected index e69de29bb2d..967f34d486e 100644 --- a/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected +++ b/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected @@ -0,0 +1 @@ +| cleartextLoggingTest.swift:153:11:154:1 | // $ hasCleartextLogging=152\n | Missing result:hasCleartextLogging=152 | diff --git a/swift/ql/test/query-tests/Security/CWE-312/CleartextStoragePreferences.expected b/swift/ql/test/query-tests/Security/CWE-312/CleartextStoragePreferences.expected index 823733bb3ab..72c382d2331 100644 --- a/swift/ql/test/query-tests/Security/CWE-312/CleartextStoragePreferences.expected +++ b/swift/ql/test/query-tests/Security/CWE-312/CleartextStoragePreferences.expected @@ -1,11 +1,9 @@ edges | testNSUbiquitousKeyValueStore.swift:41:24:41:24 | x | testNSUbiquitousKeyValueStore.swift:42:40:42:40 | x | -| testNSUbiquitousKeyValueStore.swift:44:10:44:22 | call to getPassword() | testNSUbiquitousKeyValueStore.swift:45:40:45:40 | y | | testNSUbiquitousKeyValueStore.swift:55:10:55:10 | passwd | testNSUbiquitousKeyValueStore.swift:59:40:59:40 | x | | testNSUbiquitousKeyValueStore.swift:56:10:56:10 | passwd | testNSUbiquitousKeyValueStore.swift:60:40:60:40 | y | | testNSUbiquitousKeyValueStore.swift:57:10:57:10 | passwd | testNSUbiquitousKeyValueStore.swift:61:40:61:40 | z | | testUserDefaults.swift:41:24:41:24 | x | testUserDefaults.swift:42:28:42:28 | x | -| testUserDefaults.swift:44:10:44:22 | call to getPassword() | testUserDefaults.swift:45:28:45:28 | y | | testUserDefaults.swift:55:10:55:10 | passwd | testUserDefaults.swift:59:28:59:28 | x | | testUserDefaults.swift:56:10:56:10 | passwd | testUserDefaults.swift:60:28:60:28 | y | | testUserDefaults.swift:57:10:57:10 | passwd | testUserDefaults.swift:61:28:61:28 | z | @@ -13,8 +11,6 @@ nodes | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | semmle.label | password | | testNSUbiquitousKeyValueStore.swift:41:24:41:24 | x | semmle.label | x | | testNSUbiquitousKeyValueStore.swift:42:40:42:40 | x | semmle.label | x | -| testNSUbiquitousKeyValueStore.swift:44:10:44:22 | call to getPassword() | semmle.label | call to getPassword() | -| testNSUbiquitousKeyValueStore.swift:45:40:45:40 | y | semmle.label | y | | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | semmle.label | .password | | testNSUbiquitousKeyValueStore.swift:55:10:55:10 | passwd | semmle.label | passwd | | testNSUbiquitousKeyValueStore.swift:56:10:56:10 | passwd | semmle.label | passwd | @@ -25,8 +21,6 @@ nodes | testUserDefaults.swift:28:15:28:15 | password | semmle.label | password | | testUserDefaults.swift:41:24:41:24 | x | semmle.label | x | | testUserDefaults.swift:42:28:42:28 | x | semmle.label | x | -| testUserDefaults.swift:44:10:44:22 | call to getPassword() | semmle.label | call to getPassword() | -| testUserDefaults.swift:45:28:45:28 | y | semmle.label | y | | testUserDefaults.swift:49:28:49:30 | .password | semmle.label | .password | | testUserDefaults.swift:55:10:55:10 | passwd | semmle.label | passwd | | testUserDefaults.swift:56:10:56:10 | passwd | semmle.label | passwd | @@ -38,14 +32,12 @@ subpaths #select | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | This operation stores 'password' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | password | | testNSUbiquitousKeyValueStore.swift:42:40:42:40 | x | testNSUbiquitousKeyValueStore.swift:41:24:41:24 | x | testNSUbiquitousKeyValueStore.swift:42:40:42:40 | x | This operation stores 'x' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:41:24:41:24 | x | x | -| testNSUbiquitousKeyValueStore.swift:45:40:45:40 | y | testNSUbiquitousKeyValueStore.swift:44:10:44:22 | call to getPassword() | testNSUbiquitousKeyValueStore.swift:45:40:45:40 | y | This operation stores 'y' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:44:10:44:22 | call to getPassword() | call to getPassword() | | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | This operation stores '.password' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | .password | | testNSUbiquitousKeyValueStore.swift:59:40:59:40 | x | testNSUbiquitousKeyValueStore.swift:55:10:55:10 | passwd | testNSUbiquitousKeyValueStore.swift:59:40:59:40 | x | This operation stores 'x' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:55:10:55:10 | passwd | passwd | | testNSUbiquitousKeyValueStore.swift:60:40:60:40 | y | testNSUbiquitousKeyValueStore.swift:56:10:56:10 | passwd | testNSUbiquitousKeyValueStore.swift:60:40:60:40 | y | This operation stores 'y' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:56:10:56:10 | passwd | passwd | | testNSUbiquitousKeyValueStore.swift:61:40:61:40 | z | testNSUbiquitousKeyValueStore.swift:57:10:57:10 | passwd | testNSUbiquitousKeyValueStore.swift:61:40:61:40 | z | This operation stores 'z' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:57:10:57:10 | passwd | passwd | | testUserDefaults.swift:28:15:28:15 | password | testUserDefaults.swift:28:15:28:15 | password | testUserDefaults.swift:28:15:28:15 | password | This operation stores 'password' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:28:15:28:15 | password | password | | testUserDefaults.swift:42:28:42:28 | x | testUserDefaults.swift:41:24:41:24 | x | testUserDefaults.swift:42:28:42:28 | x | This operation stores 'x' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:41:24:41:24 | x | x | -| testUserDefaults.swift:45:28:45:28 | y | testUserDefaults.swift:44:10:44:22 | call to getPassword() | testUserDefaults.swift:45:28:45:28 | y | This operation stores 'y' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:44:10:44:22 | call to getPassword() | call to getPassword() | | testUserDefaults.swift:49:28:49:30 | .password | testUserDefaults.swift:49:28:49:30 | .password | testUserDefaults.swift:49:28:49:30 | .password | This operation stores '.password' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:49:28:49:30 | .password | .password | | testUserDefaults.swift:59:28:59:28 | x | testUserDefaults.swift:55:10:55:10 | passwd | testUserDefaults.swift:59:28:59:28 | x | This operation stores 'x' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:55:10:55:10 | passwd | passwd | | testUserDefaults.swift:60:28:60:28 | y | testUserDefaults.swift:56:10:56:10 | passwd | testUserDefaults.swift:60:28:60:28 | y | This operation stores 'y' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:56:10:56:10 | passwd | passwd | From e2080c5d007a7e285c6d3de6191cdec8178fb4c5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 May 2023 17:52:47 +0100 Subject: [PATCH 028/739] Swift: SensitiveDataHeuristics.qll expects function names without an (argument:list:). --- swift/ql/lib/codeql/swift/security/SensitiveExprs.qll | 8 ++++++-- .../Security/CWE-311/CleartextStorageDatabase.expected | 4 ++++ .../query-tests/Security/CWE-311/SensitiveExprs.expected | 1 + .../Security/CWE-312/CleartextLoggingTest.expected | 1 - .../Security/CWE-312/CleartextStoragePreferences.expected | 8 ++++++++ 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index 8dd55d00259..ffb3796b9cf 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -91,11 +91,15 @@ private class SensitiveVarDecl extends VarDecl { */ private class SensitiveFunction extends Function { SensitiveDataType sensitiveType; + string name; // name of the function, not including the argument list. - SensitiveFunction() { this.getName().toLowerCase().regexpMatch(sensitiveType.getRegexp()) } + SensitiveFunction() { + name = this.getName().splitAt("(", 0) and + name.toLowerCase().regexpMatch(sensitiveType.getRegexp()) + } predicate hasInfo(string label, SensitiveDataType type) { - label = this.getName() and + label = name and sensitiveType = type } } diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index caad0df3190..9f0a34d5bb1 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -118,6 +118,7 @@ edges | testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:31:3:31:3 | newValue | | testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:65:2:65:2 | [post] obj [myValue] | | testCoreData.swift:77:24:77:24 | x | testCoreData.swift:78:15:78:15 | x | +| testCoreData.swift:80:10:80:22 | call to getPassword() | testCoreData.swift:81:15:81:15 | y | | testCoreData.swift:91:10:91:10 | passwd | testCoreData.swift:95:15:95:15 | x | | testCoreData.swift:92:10:92:10 | passwd | testCoreData.swift:96:15:96:15 | y | | testCoreData.swift:93:10:93:10 | passwd | testCoreData.swift:97:15:97:15 | z | @@ -325,6 +326,8 @@ nodes | testCoreData.swift:65:16:65:16 | password_file | semmle.label | password_file | | testCoreData.swift:77:24:77:24 | x | semmle.label | x | | testCoreData.swift:78:15:78:15 | x | semmle.label | x | +| testCoreData.swift:80:10:80:22 | call to getPassword() | semmle.label | call to getPassword() | +| testCoreData.swift:81:15:81:15 | y | semmle.label | y | | testCoreData.swift:85:15:85:17 | .password | semmle.label | .password | | testCoreData.swift:91:10:91:10 | passwd | semmle.label | passwd | | testCoreData.swift:92:10:92:10 | passwd | semmle.label | passwd | @@ -508,6 +511,7 @@ subpaths | testCoreData.swift:64:2:64:2 | obj | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:64:2:64:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password | password | | testCoreData.swift:65:2:65:2 | obj | testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:65:2:65:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:65:16:65:16 | password_file | password_file | | testCoreData.swift:78:15:78:15 | x | testCoreData.swift:77:24:77:24 | x | testCoreData.swift:78:15:78:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:77:24:77:24 | x | x | +| testCoreData.swift:81:15:81:15 | y | testCoreData.swift:80:10:80:22 | call to getPassword() | testCoreData.swift:81:15:81:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:80:10:80:22 | call to getPassword() | call to getPassword() | | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | This operation stores '.password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:85:15:85:17 | .password | .password | | testCoreData.swift:95:15:95:15 | x | testCoreData.swift:91:10:91:10 | passwd | testCoreData.swift:95:15:95:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:91:10:91:10 | passwd | passwd | | testCoreData.swift:96:15:96:15 | y | testCoreData.swift:92:10:92:10 | passwd | testCoreData.swift:96:15:96:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:92:10:92:10 | passwd | passwd | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 0960d1983a1..59bf4abeec3 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -57,6 +57,7 @@ | testCoreData.swift:64:16:64:16 | password | label:password, type:credential | | testCoreData.swift:65:16:65:16 | password_file | label:password_file, type:credential | | testCoreData.swift:77:24:77:24 | x | label:password, type:credential | +| testCoreData.swift:80:10:80:22 | call to getPassword() | label:getPassword, type:credential | | testCoreData.swift:85:15:85:17 | .password | label:password, type:credential | | testCoreData.swift:91:10:91:10 | passwd | label:passwd, type:credential | | testCoreData.swift:92:10:92:10 | passwd | label:passwd, type:credential | diff --git a/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected b/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected index 967f34d486e..e69de29bb2d 100644 --- a/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected +++ b/swift/ql/test/query-tests/Security/CWE-312/CleartextLoggingTest.expected @@ -1 +0,0 @@ -| cleartextLoggingTest.swift:153:11:154:1 | // $ hasCleartextLogging=152\n | Missing result:hasCleartextLogging=152 | diff --git a/swift/ql/test/query-tests/Security/CWE-312/CleartextStoragePreferences.expected b/swift/ql/test/query-tests/Security/CWE-312/CleartextStoragePreferences.expected index 72c382d2331..823733bb3ab 100644 --- a/swift/ql/test/query-tests/Security/CWE-312/CleartextStoragePreferences.expected +++ b/swift/ql/test/query-tests/Security/CWE-312/CleartextStoragePreferences.expected @@ -1,9 +1,11 @@ edges | testNSUbiquitousKeyValueStore.swift:41:24:41:24 | x | testNSUbiquitousKeyValueStore.swift:42:40:42:40 | x | +| testNSUbiquitousKeyValueStore.swift:44:10:44:22 | call to getPassword() | testNSUbiquitousKeyValueStore.swift:45:40:45:40 | y | | testNSUbiquitousKeyValueStore.swift:55:10:55:10 | passwd | testNSUbiquitousKeyValueStore.swift:59:40:59:40 | x | | testNSUbiquitousKeyValueStore.swift:56:10:56:10 | passwd | testNSUbiquitousKeyValueStore.swift:60:40:60:40 | y | | testNSUbiquitousKeyValueStore.swift:57:10:57:10 | passwd | testNSUbiquitousKeyValueStore.swift:61:40:61:40 | z | | testUserDefaults.swift:41:24:41:24 | x | testUserDefaults.swift:42:28:42:28 | x | +| testUserDefaults.swift:44:10:44:22 | call to getPassword() | testUserDefaults.swift:45:28:45:28 | y | | testUserDefaults.swift:55:10:55:10 | passwd | testUserDefaults.swift:59:28:59:28 | x | | testUserDefaults.swift:56:10:56:10 | passwd | testUserDefaults.swift:60:28:60:28 | y | | testUserDefaults.swift:57:10:57:10 | passwd | testUserDefaults.swift:61:28:61:28 | z | @@ -11,6 +13,8 @@ nodes | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | semmle.label | password | | testNSUbiquitousKeyValueStore.swift:41:24:41:24 | x | semmle.label | x | | testNSUbiquitousKeyValueStore.swift:42:40:42:40 | x | semmle.label | x | +| testNSUbiquitousKeyValueStore.swift:44:10:44:22 | call to getPassword() | semmle.label | call to getPassword() | +| testNSUbiquitousKeyValueStore.swift:45:40:45:40 | y | semmle.label | y | | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | semmle.label | .password | | testNSUbiquitousKeyValueStore.swift:55:10:55:10 | passwd | semmle.label | passwd | | testNSUbiquitousKeyValueStore.swift:56:10:56:10 | passwd | semmle.label | passwd | @@ -21,6 +25,8 @@ nodes | testUserDefaults.swift:28:15:28:15 | password | semmle.label | password | | testUserDefaults.swift:41:24:41:24 | x | semmle.label | x | | testUserDefaults.swift:42:28:42:28 | x | semmle.label | x | +| testUserDefaults.swift:44:10:44:22 | call to getPassword() | semmle.label | call to getPassword() | +| testUserDefaults.swift:45:28:45:28 | y | semmle.label | y | | testUserDefaults.swift:49:28:49:30 | .password | semmle.label | .password | | testUserDefaults.swift:55:10:55:10 | passwd | semmle.label | passwd | | testUserDefaults.swift:56:10:56:10 | passwd | semmle.label | passwd | @@ -32,12 +38,14 @@ subpaths #select | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | This operation stores 'password' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:28:12:28:12 | password | password | | testNSUbiquitousKeyValueStore.swift:42:40:42:40 | x | testNSUbiquitousKeyValueStore.swift:41:24:41:24 | x | testNSUbiquitousKeyValueStore.swift:42:40:42:40 | x | This operation stores 'x' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:41:24:41:24 | x | x | +| testNSUbiquitousKeyValueStore.swift:45:40:45:40 | y | testNSUbiquitousKeyValueStore.swift:44:10:44:22 | call to getPassword() | testNSUbiquitousKeyValueStore.swift:45:40:45:40 | y | This operation stores 'y' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:44:10:44:22 | call to getPassword() | call to getPassword() | | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | This operation stores '.password' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:49:40:49:42 | .password | .password | | testNSUbiquitousKeyValueStore.swift:59:40:59:40 | x | testNSUbiquitousKeyValueStore.swift:55:10:55:10 | passwd | testNSUbiquitousKeyValueStore.swift:59:40:59:40 | x | This operation stores 'x' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:55:10:55:10 | passwd | passwd | | testNSUbiquitousKeyValueStore.swift:60:40:60:40 | y | testNSUbiquitousKeyValueStore.swift:56:10:56:10 | passwd | testNSUbiquitousKeyValueStore.swift:60:40:60:40 | y | This operation stores 'y' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:56:10:56:10 | passwd | passwd | | testNSUbiquitousKeyValueStore.swift:61:40:61:40 | z | testNSUbiquitousKeyValueStore.swift:57:10:57:10 | passwd | testNSUbiquitousKeyValueStore.swift:61:40:61:40 | z | This operation stores 'z' in iCloud. It may contain unencrypted sensitive data from $@. | testNSUbiquitousKeyValueStore.swift:57:10:57:10 | passwd | passwd | | testUserDefaults.swift:28:15:28:15 | password | testUserDefaults.swift:28:15:28:15 | password | testUserDefaults.swift:28:15:28:15 | password | This operation stores 'password' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:28:15:28:15 | password | password | | testUserDefaults.swift:42:28:42:28 | x | testUserDefaults.swift:41:24:41:24 | x | testUserDefaults.swift:42:28:42:28 | x | This operation stores 'x' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:41:24:41:24 | x | x | +| testUserDefaults.swift:45:28:45:28 | y | testUserDefaults.swift:44:10:44:22 | call to getPassword() | testUserDefaults.swift:45:28:45:28 | y | This operation stores 'y' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:44:10:44:22 | call to getPassword() | call to getPassword() | | testUserDefaults.swift:49:28:49:30 | .password | testUserDefaults.swift:49:28:49:30 | .password | testUserDefaults.swift:49:28:49:30 | .password | This operation stores '.password' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:49:28:49:30 | .password | .password | | testUserDefaults.swift:59:28:59:28 | x | testUserDefaults.swift:55:10:55:10 | passwd | testUserDefaults.swift:59:28:59:28 | x | This operation stores 'x' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:55:10:55:10 | passwd | passwd | | testUserDefaults.swift:60:28:60:28 | y | testUserDefaults.swift:56:10:56:10 | passwd | testUserDefaults.swift:60:28:60:28 | y | This operation stores 'y' in the user defaults database. It may contain unencrypted sensitive data from $@. | testUserDefaults.swift:56:10:56:10 | passwd | passwd | From a91c45049e9b8a68b57c37cd6d83b9b337a66eca Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 12 May 2023 12:02:22 +0100 Subject: [PATCH 029/739] Swift: Add some special cases to preserve (for now) result quality. --- .../ql/lib/codeql/swift/security/SensitiveExprs.qll | 5 ++++- .../CWE-311/CleartextStorageDatabase.expected | 13 ------------- .../Security/CWE-311/SensitiveExprs.expected | 3 --- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index ffb3796b9cf..d644da9e776 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -70,7 +70,10 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo { * contain hashed or encrypted data, or are only a reference to data that is * actually stored elsewhere. */ -private string regexpProbablySafe() { result = HeuristicNames::notSensitiveRegexp() } +private string regexpProbablySafe() { + result = HeuristicNames::notSensitiveRegexp() or + result = "(?is).*(file|path|url|invalid).*" +} /** * A `VarDecl` that might be used to contain sensitive data. diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index 9f0a34d5bb1..320f4873d08 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -110,13 +110,9 @@ edges | testCoreData.swift:18:19:18:26 | value | testCoreData.swift:19:12:19:12 | value | | testCoreData.swift:31:3:31:3 | newValue | testCoreData.swift:32:13:32:13 | newValue | | testCoreData.swift:61:25:61:25 | password | testCoreData.swift:18:19:18:26 | value | -| testCoreData.swift:62:25:62:25 | password_file | testCoreData.swift:18:19:18:26 | value | | testCoreData.swift:64:2:64:2 | [post] obj [myValue] | testCoreData.swift:64:2:64:2 | [post] obj | | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:31:3:31:3 | newValue | | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:64:2:64:2 | [post] obj [myValue] | -| testCoreData.swift:65:2:65:2 | [post] obj [myValue] | testCoreData.swift:65:2:65:2 | [post] obj | -| testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:31:3:31:3 | newValue | -| testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:65:2:65:2 | [post] obj [myValue] | | testCoreData.swift:77:24:77:24 | x | testCoreData.swift:78:15:78:15 | x | | testCoreData.swift:80:10:80:22 | call to getPassword() | testCoreData.swift:81:15:81:15 | y | | testCoreData.swift:91:10:91:10 | passwd | testCoreData.swift:95:15:95:15 | x | @@ -315,15 +311,10 @@ nodes | testCoreData.swift:48:15:48:15 | password | semmle.label | password | | testCoreData.swift:51:24:51:24 | password | semmle.label | password | | testCoreData.swift:58:15:58:15 | password | semmle.label | password | -| testCoreData.swift:59:15:59:15 | password_file | semmle.label | password_file | | testCoreData.swift:61:25:61:25 | password | semmle.label | password | -| testCoreData.swift:62:25:62:25 | password_file | semmle.label | password_file | | testCoreData.swift:64:2:64:2 | [post] obj | semmle.label | [post] obj | | testCoreData.swift:64:2:64:2 | [post] obj [myValue] | semmle.label | [post] obj [myValue] | | testCoreData.swift:64:16:64:16 | password | semmle.label | password | -| testCoreData.swift:65:2:65:2 | [post] obj | semmle.label | [post] obj | -| testCoreData.swift:65:2:65:2 | [post] obj [myValue] | semmle.label | [post] obj [myValue] | -| testCoreData.swift:65:16:65:16 | password_file | semmle.label | password_file | | testCoreData.swift:77:24:77:24 | x | semmle.label | x | | testCoreData.swift:78:15:78:15 | x | semmle.label | x | | testCoreData.swift:80:10:80:22 | call to getPassword() | semmle.label | call to getPassword() | @@ -501,15 +492,11 @@ subpaths | testCoreData2.swift:104:2:104:2 | dbObj | testCoreData2.swift:101:10:101:10 | bankAccountNo | testCoreData2.swift:104:2:104:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:101:10:101:10 | bankAccountNo | bankAccountNo | | testCoreData2.swift:105:2:105:2 | dbObj | testCoreData2.swift:101:10:101:10 | bankAccountNo | testCoreData2.swift:105:2:105:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:101:10:101:10 | bankAccountNo | bankAccountNo | | testCoreData.swift:19:12:19:12 | value | testCoreData.swift:61:25:61:25 | password | testCoreData.swift:19:12:19:12 | value | This operation stores 'value' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:61:25:61:25 | password | password | -| testCoreData.swift:19:12:19:12 | value | testCoreData.swift:62:25:62:25 | password_file | testCoreData.swift:19:12:19:12 | value | This operation stores 'value' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:62:25:62:25 | password_file | password_file | | testCoreData.swift:32:13:32:13 | newValue | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:32:13:32:13 | newValue | This operation stores 'newValue' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password | password | -| testCoreData.swift:32:13:32:13 | newValue | testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:32:13:32:13 | newValue | This operation stores 'newValue' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:65:16:65:16 | password_file | password_file | | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:48:15:48:15 | password | password | | testCoreData.swift:51:24:51:24 | password | testCoreData.swift:51:24:51:24 | password | testCoreData.swift:51:24:51:24 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:51:24:51:24 | password | password | | testCoreData.swift:58:15:58:15 | password | testCoreData.swift:58:15:58:15 | password | testCoreData.swift:58:15:58:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:58:15:58:15 | password | password | -| testCoreData.swift:59:15:59:15 | password_file | testCoreData.swift:59:15:59:15 | password_file | testCoreData.swift:59:15:59:15 | password_file | This operation stores 'password_file' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:59:15:59:15 | password_file | password_file | | testCoreData.swift:64:2:64:2 | obj | testCoreData.swift:64:16:64:16 | password | testCoreData.swift:64:2:64:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password | password | -| testCoreData.swift:65:2:65:2 | obj | testCoreData.swift:65:16:65:16 | password_file | testCoreData.swift:65:2:65:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:65:16:65:16 | password_file | password_file | | testCoreData.swift:78:15:78:15 | x | testCoreData.swift:77:24:77:24 | x | testCoreData.swift:78:15:78:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:77:24:77:24 | x | x | | testCoreData.swift:81:15:81:15 | y | testCoreData.swift:80:10:80:22 | call to getPassword() | testCoreData.swift:81:15:81:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:80:10:80:22 | call to getPassword() | call to getPassword() | | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | This operation stores '.password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:85:15:85:17 | .password | .password | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 59bf4abeec3..89b8d36ccdf 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -51,11 +51,8 @@ | testCoreData.swift:48:15:48:15 | password | label:password, type:credential | | testCoreData.swift:51:24:51:24 | password | label:password, type:credential | | testCoreData.swift:58:15:58:15 | password | label:password, type:credential | -| testCoreData.swift:59:15:59:15 | password_file | label:password_file, type:credential | | testCoreData.swift:61:25:61:25 | password | label:password, type:credential | -| testCoreData.swift:62:25:62:25 | password_file | label:password_file, type:credential | | testCoreData.swift:64:16:64:16 | password | label:password, type:credential | -| testCoreData.swift:65:16:65:16 | password_file | label:password_file, type:credential | | testCoreData.swift:77:24:77:24 | x | label:password, type:credential | | testCoreData.swift:80:10:80:22 | call to getPassword() | label:getPassword, type:credential | | testCoreData.swift:85:15:85:17 | .password | label:password, type:credential | From 245e8fbc920155d0c3c45349b647eb0f578fbba4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 May 2023 22:22:01 +0100 Subject: [PATCH 030/739] Swift: Use SensitiveDataHeuristics.qll in SensitiveCredential. --- .../codeql/swift/security/SensitiveExprs.qll | 4 +- .../CWE-311/CleartextTransmission.expected | 6 +- .../Security/CWE-311/SensitiveExprs.expected | 86 ++++++++++--------- .../CWE-328/WeakSensitiveDataHashing.expected | 24 ++++++ 4 files changed, 74 insertions(+), 46 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index d644da9e776..093caaaa0cf 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -29,9 +29,7 @@ abstract class SensitiveDataType extends TSensitiveDataType { class SensitiveCredential extends SensitiveDataType, TCredential { override string toString() { result = "credential" } - override string getRegexp() { - result = ".*(password|passwd|accountid|account.?key|accnt.?key|license.?key|trusted).*" - } + override string getRegexp() { result = HeuristicNames::maybeSensitiveRegexp(_) } } /** diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected index 94272faf6d0..816ef16e076 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -13,6 +13,7 @@ edges | testSend.swift:54:17:54:17 | password | testSend.swift:41:10:41:18 | data | | testSend.swift:54:17:54:17 | password | testSend.swift:54:13:54:25 | call to pad(_:) | | testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | +| testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | nodes | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | @@ -36,10 +37,11 @@ nodes | testSend.swift:59:27:59:27 | str1 | semmle.label | str1 | | testSend.swift:60:27:60:27 | str2 | semmle.label | str2 | | testSend.swift:61:27:61:27 | str3 | semmle.label | str3 | -| testSend.swift:65:27:65:27 | license_key | semmle.label | license_key | | testSend.swift:66:27:66:30 | .mobileNumber | semmle.label | .mobileNumber | | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testURL.swift:13:54:13:54 | passwd | semmle.label | passwd | +| testURL.swift:15:22:15:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| testURL.swift:15:55:15:55 | account_no | semmle.label | account_no | | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no | semmle.label | credit_card_no | | testURL.swift:20:22:20:22 | passwd | semmle.label | passwd | @@ -55,8 +57,8 @@ subpaths | testSend.swift:59:27:59:27 | str1 | testSend.swift:52:13:52:13 | password | testSend.swift:59:27:59:27 | str1 | This operation transmits 'str1', which may contain unencrypted sensitive data from $@. | testSend.swift:52:13:52:13 | password | password | | testSend.swift:60:27:60:27 | str2 | testSend.swift:53:13:53:13 | password | testSend.swift:60:27:60:27 | str2 | This operation transmits 'str2', which may contain unencrypted sensitive data from $@. | testSend.swift:53:13:53:13 | password | password | | testSend.swift:61:27:61:27 | str3 | testSend.swift:54:17:54:17 | password | testSend.swift:61:27:61:27 | str3 | This operation transmits 'str3', which may contain unencrypted sensitive data from $@. | testSend.swift:54:17:54:17 | password | password | -| testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | This operation transmits 'license_key', which may contain unencrypted sensitive data from $@. | testSend.swift:65:27:65:27 | license_key | license_key | | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | This operation transmits '.mobileNumber', which may contain unencrypted sensitive data from $@. | testSend.swift:66:27:66:30 | .mobileNumber | .mobileNumber | | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:13:54:13:54 | passwd | passwd | +| testURL.swift:15:22:15:55 | ... .+(_:_:) ... | testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:15:55:15:55 | account_no | account_no | | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:16:55:16:55 | credit_card_no | credit_card_no | | testURL.swift:20:22:20:22 | passwd | testURL.swift:20:22:20:22 | passwd | testURL.swift:20:22:20:22 | passwd | This operation transmits 'passwd', which may contain unencrypted sensitive data from $@. | testURL.swift:20:22:20:22 | passwd | passwd | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 89b8d36ccdf..1c22f1e0bb9 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -4,50 +4,54 @@ | testAlamofire.swift:159:26:159:26 | email | label:email, type:private information | | testAlamofire.swift:171:35:171:35 | email | label:email, type:private information | | testAlamofire.swift:177:35:177:35 | email | label:email, type:private information | +| testAlamofire.swift:187:48:187:48 | username | label:username, type:credential | | testAlamofire.swift:187:65:187:65 | password | label:password, type:credential | +| testAlamofire.swift:195:47:195:47 | username | label:username, type:credential | | testAlamofire.swift:195:64:195:64 | password | label:password, type:credential | +| testAlamofire.swift:205:45:205:45 | username | label:username, type:credential | | testAlamofire.swift:205:62:205:62 | password | label:password, type:credential | +| testAlamofire.swift:213:48:213:48 | username | label:username, type:credential | | testAlamofire.swift:213:65:213:65 | password | label:password, type:credential | -| testCoreData2.swift:37:16:37:16 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:38:2:38:6 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | -| testCoreData2.swift:39:2:39:6 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | -| testCoreData2.swift:39:28:39:28 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:40:2:40:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:private information | -| testCoreData2.swift:41:2:41:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:private information | -| testCoreData2.swift:41:29:41:29 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:42:2:42:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:private information | -| testCoreData2.swift:43:2:43:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:private information | -| testCoreData2.swift:43:35:43:35 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:46:22:46:22 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:47:2:47:12 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | -| testCoreData2.swift:48:2:48:12 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | -| testCoreData2.swift:48:34:48:34 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:49:2:49:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:private information | -| testCoreData2.swift:50:2:50:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:private information | -| testCoreData2.swift:50:35:50:35 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:51:2:51:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:private information | -| testCoreData2.swift:52:2:52:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:private information | -| testCoreData2.swift:52:41:52:41 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:57:3:57:7 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | -| testCoreData2.swift:57:29:57:29 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:60:4:60:8 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | -| testCoreData2.swift:60:30:60:30 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:62:4:62:8 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | -| testCoreData2.swift:62:30:62:30 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:65:3:65:7 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | -| testCoreData2.swift:65:29:65:29 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:79:18:79:28 | .bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 | label:bankAccountNo2, type:private information | -| testCoreData2.swift:82:18:82:18 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:83:18:83:18 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:84:18:84:18 | bankAccountNo2 | label:bankAccountNo2, type:private information | -| testCoreData2.swift:85:18:85:18 | bankAccountNo2 | label:bankAccountNo2, type:private information | -| testCoreData2.swift:87:22:87:32 | .bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:88:22:88:22 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:89:22:89:22 | bankAccountNo2 | label:bankAccountNo2, type:private information | -| testCoreData2.swift:91:10:91:10 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:95:10:95:10 | bankAccountNo | label:bankAccountNo, type:private information | -| testCoreData2.swift:101:10:101:10 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:37:16:37:16 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:38:2:38:6 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:39:2:39:6 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:39:28:39:28 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:40:2:40:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential, type:private information | +| testCoreData2.swift:41:2:41:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential, type:private information | +| testCoreData2.swift:41:29:41:29 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:42:2:42:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:43:2:43:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:43:35:43:35 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:46:22:46:22 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:47:2:47:12 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:48:2:48:12 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:48:34:48:34 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:49:2:49:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential, type:private information | +| testCoreData2.swift:50:2:50:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential, type:private information | +| testCoreData2.swift:50:35:50:35 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:51:2:51:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:52:2:52:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:52:41:52:41 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:57:3:57:7 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:57:29:57:29 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:60:4:60:8 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:60:30:60:30 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:62:4:62:8 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:62:30:62:30 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:65:3:65:7 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | +| testCoreData2.swift:65:29:65:29 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:79:18:79:28 | .bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 | label:bankAccountNo2, type:credential, type:private information | +| testCoreData2.swift:82:18:82:18 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:83:18:83:18 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:84:18:84:18 | bankAccountNo2 | label:bankAccountNo2, type:credential, type:private information | +| testCoreData2.swift:85:18:85:18 | bankAccountNo2 | label:bankAccountNo2, type:credential, type:private information | +| testCoreData2.swift:87:22:87:32 | .bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:88:22:88:22 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:89:22:89:22 | bankAccountNo2 | label:bankAccountNo2, type:credential, type:private information | +| testCoreData2.swift:91:10:91:10 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:95:10:95:10 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:101:10:101:10 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | | testCoreData.swift:48:15:48:15 | password | label:password, type:credential | | testCoreData.swift:51:24:51:24 | password | label:password, type:credential | | testCoreData.swift:58:15:58:15 | password | label:password, type:credential | @@ -125,9 +129,9 @@ | testSend.swift:55:23:55:23 | password | label:password, type:credential | | testSend.swift:56:27:56:27 | password | label:password, type:credential | | testSend.swift:57:27:57:27 | password | label:password, type:credential | -| testSend.swift:65:27:65:27 | license_key | label:license_key, type:credential | | testSend.swift:66:27:66:30 | .mobileNumber | label:mobileNumber, type:private information | | testSend.swift:69:27:69:30 | .passwordFeatureEnabled | label:passwordFeatureEnabled, type:credential | | testURL.swift:13:54:13:54 | passwd | label:passwd, type:credential | +| testURL.swift:15:55:15:55 | account_no | label:account_no, type:credential | | testURL.swift:16:55:16:55 | credit_card_no | label:credit_card_no, type:private information | | testURL.swift:20:22:20:22 | passwd | label:passwd, type:credential | diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected index 1a3d8a15f8a..16fc67d4a6f 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -1,17 +1,29 @@ edges nodes | testCryptoKit.swift:56:47:56:47 | passwd | semmle.label | passwd | +| testCryptoKit.swift:57:43:57:43 | cert | semmle.label | cert | +| testCryptoKit.swift:59:43:59:43 | account_no | semmle.label | account_no | | testCryptoKit.swift:60:43:60:43 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:61:43:61:43 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:63:44:63:44 | passwd | semmle.label | passwd | +| testCryptoKit.swift:64:44:64:44 | cert | semmle.label | cert | +| testCryptoKit.swift:66:44:66:44 | account_no | semmle.label | account_no | | testCryptoKit.swift:67:44:67:44 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:90:23:90:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:91:23:91:23 | cert | semmle.label | cert | +| testCryptoKit.swift:93:23:93:23 | account_no | semmle.label | account_no | | testCryptoKit.swift:94:23:94:23 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:99:23:99:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:100:23:100:23 | cert | semmle.label | cert | +| testCryptoKit.swift:102:23:102:23 | account_no | semmle.label | account_no | | testCryptoKit.swift:103:23:103:23 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:132:32:132:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:133:32:133:32 | cert | semmle.label | cert | +| testCryptoKit.swift:135:32:135:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:136:32:136:32 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:141:32:141:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:142:32:142:32 | cert | semmle.label | cert | +| testCryptoKit.swift:144:32:144:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:145:32:145:32 | credit_card_no | semmle.label | credit_card_no | | testCryptoSwift.swift:113:30:113:30 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:115:31:115:31 | passwdArray | semmle.label | passwdArray | @@ -26,17 +38,29 @@ nodes subpaths #select | testCryptoKit.swift:56:47:56:47 | passwd | testCryptoKit.swift:56:47:56:47 | passwd | testCryptoKit.swift:56:47:56:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:56:47:56:47 | passwd | sensitive data (credential passwd) | +| testCryptoKit.swift:57:43:57:43 | cert | testCryptoKit.swift:57:43:57:43 | cert | testCryptoKit.swift:57:43:57:43 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:57:43:57:43 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:59:43:59:43 | account_no | testCryptoKit.swift:59:43:59:43 | account_no | testCryptoKit.swift:59:43:59:43 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:59:43:59:43 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:60:43:60:43 | credit_card_no | testCryptoKit.swift:60:43:60:43 | credit_card_no | testCryptoKit.swift:60:43:60:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:60:43:60:43 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:61:43:61:43 | credit_card_no | testCryptoKit.swift:61:43:61:43 | credit_card_no | testCryptoKit.swift:61:43:61:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:61:43:61:43 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:63:44:63:44 | passwd | testCryptoKit.swift:63:44:63:44 | passwd | testCryptoKit.swift:63:44:63:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:63:44:63:44 | passwd | sensitive data (credential passwd) | +| testCryptoKit.swift:64:44:64:44 | cert | testCryptoKit.swift:64:44:64:44 | cert | testCryptoKit.swift:64:44:64:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:64:44:64:44 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:66:44:66:44 | account_no | testCryptoKit.swift:66:44:66:44 | account_no | testCryptoKit.swift:66:44:66:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:66:44:66:44 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:67:44:67:44 | credit_card_no | testCryptoKit.swift:67:44:67:44 | credit_card_no | testCryptoKit.swift:67:44:67:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:67:44:67:44 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:90:23:90:23 | passwd | testCryptoKit.swift:90:23:90:23 | passwd | testCryptoKit.swift:90:23:90:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:90:23:90:23 | passwd | sensitive data (credential passwd) | +| testCryptoKit.swift:91:23:91:23 | cert | testCryptoKit.swift:91:23:91:23 | cert | testCryptoKit.swift:91:23:91:23 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:91:23:91:23 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:93:23:93:23 | account_no | testCryptoKit.swift:93:23:93:23 | account_no | testCryptoKit.swift:93:23:93:23 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:93:23:93:23 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:94:23:94:23 | credit_card_no | testCryptoKit.swift:94:23:94:23 | credit_card_no | testCryptoKit.swift:94:23:94:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:94:23:94:23 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:99:23:99:23 | passwd | testCryptoKit.swift:99:23:99:23 | passwd | testCryptoKit.swift:99:23:99:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:99:23:99:23 | passwd | sensitive data (credential passwd) | +| testCryptoKit.swift:100:23:100:23 | cert | testCryptoKit.swift:100:23:100:23 | cert | testCryptoKit.swift:100:23:100:23 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:100:23:100:23 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:102:23:102:23 | account_no | testCryptoKit.swift:102:23:102:23 | account_no | testCryptoKit.swift:102:23:102:23 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:102:23:102:23 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:103:23:103:23 | credit_card_no | testCryptoKit.swift:103:23:103:23 | credit_card_no | testCryptoKit.swift:103:23:103:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:103:23:103:23 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:132:32:132:32 | passwd | testCryptoKit.swift:132:32:132:32 | passwd | testCryptoKit.swift:132:32:132:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:132:32:132:32 | passwd | sensitive data (credential passwd) | +| testCryptoKit.swift:133:32:133:32 | cert | testCryptoKit.swift:133:32:133:32 | cert | testCryptoKit.swift:133:32:133:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:133:32:133:32 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:135:32:135:32 | account_no | testCryptoKit.swift:135:32:135:32 | account_no | testCryptoKit.swift:135:32:135:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:135:32:135:32 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:136:32:136:32 | credit_card_no | testCryptoKit.swift:136:32:136:32 | credit_card_no | testCryptoKit.swift:136:32:136:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:136:32:136:32 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:141:32:141:32 | passwd | testCryptoKit.swift:141:32:141:32 | passwd | testCryptoKit.swift:141:32:141:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:141:32:141:32 | passwd | sensitive data (credential passwd) | +| testCryptoKit.swift:142:32:142:32 | cert | testCryptoKit.swift:142:32:142:32 | cert | testCryptoKit.swift:142:32:142:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:142:32:142:32 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:144:32:144:32 | account_no | testCryptoKit.swift:144:32:144:32 | account_no | testCryptoKit.swift:144:32:144:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:144:32:144:32 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:145:32:145:32 | credit_card_no | testCryptoKit.swift:145:32:145:32 | credit_card_no | testCryptoKit.swift:145:32:145:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:145:32:145:32 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoSwift.swift:113:30:113:30 | passwdArray | testCryptoSwift.swift:113:30:113:30 | passwdArray | testCryptoSwift.swift:113:30:113:30 | passwdArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:113:30:113:30 | passwdArray | sensitive data (credential passwdArray) | | testCryptoSwift.swift:115:31:115:31 | passwdArray | testCryptoSwift.swift:115:31:115:31 | passwdArray | testCryptoSwift.swift:115:31:115:31 | passwdArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:115:31:115:31 | passwdArray | sensitive data (credential passwdArray) | From 252b72b5731be19f3c5c5ea97f3e9b8182622240 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 12 May 2023 12:18:32 +0100 Subject: [PATCH 031/739] Swift: Add some special cases to preserve (for now) result quality. --- swift/ql/lib/codeql/swift/security/SensitiveExprs.qll | 5 ++++- .../Security/CWE-311/CleartextTransmission.expected | 2 ++ .../query-tests/Security/CWE-311/SensitiveExprs.expected | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index 093caaaa0cf..a742974710d 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -29,7 +29,10 @@ abstract class SensitiveDataType extends TSensitiveDataType { class SensitiveCredential extends SensitiveDataType, TCredential { override string toString() { result = "credential" } - override string getRegexp() { result = HeuristicNames::maybeSensitiveRegexp(_) } + override string getRegexp() { + result = HeuristicNames::maybeSensitiveRegexp(_) or + result = "(?is).*(license.?key).*" + } } /** diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected index 816ef16e076..c832cf51a15 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -37,6 +37,7 @@ nodes | testSend.swift:59:27:59:27 | str1 | semmle.label | str1 | | testSend.swift:60:27:60:27 | str2 | semmle.label | str2 | | testSend.swift:61:27:61:27 | str3 | semmle.label | str3 | +| testSend.swift:65:27:65:27 | license_key | semmle.label | license_key | | testSend.swift:66:27:66:30 | .mobileNumber | semmle.label | .mobileNumber | | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testURL.swift:13:54:13:54 | passwd | semmle.label | passwd | @@ -57,6 +58,7 @@ subpaths | testSend.swift:59:27:59:27 | str1 | testSend.swift:52:13:52:13 | password | testSend.swift:59:27:59:27 | str1 | This operation transmits 'str1', which may contain unencrypted sensitive data from $@. | testSend.swift:52:13:52:13 | password | password | | testSend.swift:60:27:60:27 | str2 | testSend.swift:53:13:53:13 | password | testSend.swift:60:27:60:27 | str2 | This operation transmits 'str2', which may contain unencrypted sensitive data from $@. | testSend.swift:53:13:53:13 | password | password | | testSend.swift:61:27:61:27 | str3 | testSend.swift:54:17:54:17 | password | testSend.swift:61:27:61:27 | str3 | This operation transmits 'str3', which may contain unencrypted sensitive data from $@. | testSend.swift:54:17:54:17 | password | password | +| testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | This operation transmits 'license_key', which may contain unencrypted sensitive data from $@. | testSend.swift:65:27:65:27 | license_key | license_key | | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | This operation transmits '.mobileNumber', which may contain unencrypted sensitive data from $@. | testSend.swift:66:27:66:30 | .mobileNumber | .mobileNumber | | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:13:54:13:54 | passwd | passwd | | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:15:55:15:55 | account_no | account_no | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 1c22f1e0bb9..812581cfb87 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -129,6 +129,7 @@ | testSend.swift:55:23:55:23 | password | label:password, type:credential | | testSend.swift:56:27:56:27 | password | label:password, type:credential | | testSend.swift:57:27:57:27 | password | label:password, type:credential | +| testSend.swift:65:27:65:27 | license_key | label:license_key, type:credential | | testSend.swift:66:27:66:30 | .mobileNumber | label:mobileNumber, type:private information | | testSend.swift:69:27:69:30 | .passwordFeatureEnabled | label:passwordFeatureEnabled, type:credential | | testURL.swift:13:54:13:54 | passwd | label:passwd, type:credential | From 047494dc95b61d085583559e93a09c87d0c782cd Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 12 May 2023 15:38:17 +0100 Subject: [PATCH 032/739] Swift: Bank account numbers are a credential now, I guess they don't need to be private data as well. --- .../codeql/swift/security/SensitiveExprs.qll | 2 +- .../Security/CWE-311/SensitiveExprs.expected | 80 +++++++++---------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index a742974710d..3de43524294 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -54,7 +54,7 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo { // Geographic location - where the user is (or was) "latitude|longitude|" + // Financial data - such as credit card numbers, salary, bank accounts, and debts - "credit.?card|debit.?card|salary|bank.?account|" + + "credit.?card|debit.?card|salary|" + // Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc. "email|" + // Health - medical conditions, insurance status, prescription records diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 812581cfb87..708d68a05e9 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -12,46 +12,46 @@ | testAlamofire.swift:205:62:205:62 | password | label:password, type:credential | | testAlamofire.swift:213:48:213:48 | username | label:username, type:credential | | testAlamofire.swift:213:65:213:65 | password | label:password, type:credential | -| testCoreData2.swift:37:16:37:16 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:38:2:38:6 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:39:2:39:6 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:39:28:39:28 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:40:2:40:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential, type:private information | -| testCoreData2.swift:41:2:41:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential, type:private information | -| testCoreData2.swift:41:29:41:29 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:42:2:42:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:43:2:43:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:43:35:43:35 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:46:22:46:22 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:47:2:47:12 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:48:2:48:12 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:48:34:48:34 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:49:2:49:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential, type:private information | -| testCoreData2.swift:50:2:50:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential, type:private information | -| testCoreData2.swift:50:35:50:35 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:51:2:51:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:52:2:52:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:52:41:52:41 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:57:3:57:7 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:57:29:57:29 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:60:4:60:8 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:60:30:60:30 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:62:4:62:8 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:62:30:62:30 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:65:3:65:7 | .myBankAccountNumber | label:myBankAccountNumber, type:credential, type:private information | -| testCoreData2.swift:65:29:65:29 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:79:18:79:28 | .bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 | label:bankAccountNo2, type:credential, type:private information | -| testCoreData2.swift:82:18:82:18 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:83:18:83:18 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:84:18:84:18 | bankAccountNo2 | label:bankAccountNo2, type:credential, type:private information | -| testCoreData2.swift:85:18:85:18 | bankAccountNo2 | label:bankAccountNo2, type:credential, type:private information | -| testCoreData2.swift:87:22:87:32 | .bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:88:22:88:22 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:89:22:89:22 | bankAccountNo2 | label:bankAccountNo2, type:credential, type:private information | -| testCoreData2.swift:91:10:91:10 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:95:10:95:10 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | -| testCoreData2.swift:101:10:101:10 | bankAccountNo | label:bankAccountNo, type:credential, type:private information | +| testCoreData2.swift:37:16:37:16 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:38:2:38:6 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | +| testCoreData2.swift:39:2:39:6 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | +| testCoreData2.swift:39:28:39:28 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:40:2:40:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential | +| testCoreData2.swift:41:2:41:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential | +| testCoreData2.swift:41:29:41:29 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:42:2:42:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential | +| testCoreData2.swift:43:2:43:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential | +| testCoreData2.swift:43:35:43:35 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:46:22:46:22 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:47:2:47:12 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | +| testCoreData2.swift:48:2:48:12 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | +| testCoreData2.swift:48:34:48:34 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:49:2:49:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential | +| testCoreData2.swift:50:2:50:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential | +| testCoreData2.swift:50:35:50:35 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:51:2:51:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential | +| testCoreData2.swift:52:2:52:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential | +| testCoreData2.swift:52:41:52:41 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:57:3:57:7 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | +| testCoreData2.swift:57:29:57:29 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:60:4:60:8 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | +| testCoreData2.swift:60:30:60:30 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:62:4:62:8 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | +| testCoreData2.swift:62:30:62:30 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:65:3:65:7 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | +| testCoreData2.swift:65:29:65:29 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:79:18:79:28 | .bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 | label:bankAccountNo2, type:credential | +| testCoreData2.swift:82:18:82:18 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:83:18:83:18 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:84:18:84:18 | bankAccountNo2 | label:bankAccountNo2, type:credential | +| testCoreData2.swift:85:18:85:18 | bankAccountNo2 | label:bankAccountNo2, type:credential | +| testCoreData2.swift:87:22:87:32 | .bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:88:22:88:22 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:89:22:89:22 | bankAccountNo2 | label:bankAccountNo2, type:credential | +| testCoreData2.swift:91:10:91:10 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:95:10:95:10 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:101:10:101:10 | bankAccountNo | label:bankAccountNo, type:credential | | testCoreData.swift:48:15:48:15 | password | label:password, type:credential | | testCoreData.swift:51:24:51:24 | password | label:password, type:credential | | testCoreData.swift:58:15:58:15 | password | label:password, type:credential | From 3f206cce003095b4135d6f6601e1ca2ea78a926a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 12 May 2023 09:50:38 +0100 Subject: [PATCH 033/739] Swift: Simplify out toLowerCase(). --- .../ql/lib/codeql/swift/security/SensitiveExprs.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index 3de43524294..c3432fa58e4 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -43,7 +43,7 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo { override string getRegexp() { result = - ".*(" + + "(?is).*(" + // Inspired by the list on https://cwe.mitre.org/data/definitions/359.html // Government identifiers, such as Social Security Numbers "social.?security|national.?insurance|" + @@ -82,7 +82,7 @@ private string regexpProbablySafe() { private class SensitiveVarDecl extends VarDecl { SensitiveDataType sensitiveType; - SensitiveVarDecl() { this.getName().toLowerCase().regexpMatch(sensitiveType.getRegexp()) } + SensitiveVarDecl() { this.getName().regexpMatch(sensitiveType.getRegexp()) } predicate hasInfo(string label, SensitiveDataType type) { label = this.getName() and @@ -99,7 +99,7 @@ private class SensitiveFunction extends Function { SensitiveFunction() { name = this.getName().splitAt("(", 0) and - name.toLowerCase().regexpMatch(sensitiveType.getRegexp()) + name.regexpMatch(sensitiveType.getRegexp()) } predicate hasInfo(string label, SensitiveDataType type) { @@ -114,7 +114,7 @@ private class SensitiveFunction extends Function { private class SensitiveArgument extends Argument { SensitiveDataType sensitiveType; - SensitiveArgument() { this.getLabel().toLowerCase().regexpMatch(sensitiveType.getRegexp()) } + SensitiveArgument() { this.getLabel().regexpMatch(sensitiveType.getRegexp()) } predicate hasInfo(string label, SensitiveDataType type) { label = this.getLabel() and @@ -147,7 +147,7 @@ class SensitiveExpr extends Expr { ) ) and // do not mark as sensitive it if it is probably safe - not label.toLowerCase().regexpMatch(regexpProbablySafe()) + not label.regexpMatch(regexpProbablySafe()) } /** @@ -165,7 +165,7 @@ class SensitiveExpr extends Expr { * A function that is likely used to encrypt or hash data. */ private class EncryptionFunction extends Function { - EncryptionFunction() { this.getName().regexpMatch(".*(crypt|hash|encode|protect).*") } + EncryptionFunction() { this.getName().regexpMatch("(?is).*(crypt|hash|encode|protect).*") } } /** From 5019d3befa7963b9854b0be325849d95d2e1b0b8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 12 May 2023 15:30:14 +0100 Subject: [PATCH 034/739] Swift: Update test annotations. --- .../Security/CWE-311/testURL.swift | 2 +- .../Security/CWE-328/testCryptoKit.swift | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-311/testURL.swift b/swift/ql/test/query-tests/Security/CWE-311/testURL.swift index 48ae815232f..7f9b64ff4f6 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testURL.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testURL.swift @@ -12,7 +12,7 @@ struct URL func test1(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) { let a = URL(string: "http://example.com/login?p=" + passwd); // BAD let b = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive) - let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD [NOT DETECTED] + let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD let d = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD let base = URL(string: "http://example.com/"); // GOOD (not sensitive) diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index a97eab7501d..55fb9284fa6 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -54,16 +54,16 @@ enum Insecure { func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD - hash = Crypto.Insecure.MD5.hash(data: cert) // BAD [NOT DETECTED] + hash = Crypto.Insecure.MD5.hash(data: cert) // BAD hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD - hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD hash = Crypto.SHA256.hash(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash @@ -88,18 +88,18 @@ func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_pa func testMD5UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.MD5() hash.update(data: passwd) // BAD - hash.update(data: cert) // BAD [NOT DETECTED] + hash.update(data: cert) // BAD hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD [NOT DETECTED] + hash.update(data: account_no) // BAD hash.update(data: credit_card_no) // BAD } func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.SHA1() hash.update(data: passwd) // BAD - hash.update(data: cert) // BAD [NOT DETECTED] + hash.update(data: cert) // BAD hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD [NOT DETECTED] + hash.update(data: account_no) // BAD hash.update(data: credit_card_no) // BAD } @@ -130,18 +130,18 @@ func testSHA512UpdateWithData(passwd : String, cert: String, encrypted_passwd : func testMD5UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) { var hash = Crypto.Insecure.MD5() hash.update(bufferPointer: passwd) // BAD - hash.update(bufferPointer: cert) // BAD [NOT DETECTED] + hash.update(bufferPointer: cert) // BAD hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive) - hash.update(bufferPointer: account_no) // BAD [NOT DETECTED] + hash.update(bufferPointer: account_no) // BAD hash.update(bufferPointer: credit_card_no) // BAD } func testSHA1UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, cert: UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) { var hash = Crypto.Insecure.SHA1() hash.update(bufferPointer: passwd) // BAD - hash.update(bufferPointer: cert) // BAD [NOT DETECTED] + hash.update(bufferPointer: cert) // BAD hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive) - hash.update(bufferPointer: account_no) // BAD [NOT DETECTED] + hash.update(bufferPointer: account_no) // BAD hash.update(bufferPointer: credit_card_no) // BAD } From d17199a9e10f36817bdb9426b128c12b91aea299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Tue, 16 May 2023 15:00:26 +0200 Subject: [PATCH 035/739] add gson models --- java/ql/lib/ext/com.google.gson.model.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 java/ql/lib/ext/com.google.gson.model.yml diff --git a/java/ql/lib/ext/com.google.gson.model.yml b/java/ql/lib/ext/com.google.gson.model.yml new file mode 100644 index 00000000000..a35ff0f117e --- /dev/null +++ b/java/ql/lib/ext/com.google.gson.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.google.gson", "Gson", False, "toJson", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJsonTree", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "fromJson", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "newJsonReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "newJsonWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson.stream", "JsonReader", False, "nextName", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson.stream", "JsonReader", False, "nextString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] From 94b4ebe38b0628e957599e7daea8cfea919c0df2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 May 2023 14:16:30 +0100 Subject: [PATCH 036/739] Update swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql Co-authored-by: Mathias Vorreiter Pedersen --- swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql b/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql index 764a4af3d94..69601b3d931 100644 --- a/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql +++ b/swift/ql/src/queries/Security/CWE-312/CleartextLogging.ql @@ -20,7 +20,7 @@ import CleartextLoggingFlow::PathGraph from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink where CleartextLoggingFlow::flowPath(source, sink) -select sink, source, sink, +select sink.getNode(), source, sink, "This operation writes '" + sink.toString() + "' to a log file. It may contain unencrypted sensitive data from $@.", source, source.getNode().toString() From 7880e9e92c204137540560002bf74e5ee57b3627 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Fri, 12 May 2023 14:52:13 -0400 Subject: [PATCH 037/739] JS: update 'command-line-injection' sink kind to 'command-injection' --- .../customizing-library-models-for-javascript.rst | 6 +++--- .../security/dataflow/CommandInjectionCustomizations.qll | 2 +- .../ql/test/library-tests/DataExtensions/execa.model.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index d8a9e15faf5..d5cf4e0338e 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -53,7 +53,7 @@ Note that this sink is already recognized by the CodeQL JS analysis, but for thi pack: codeql/javascript-all extensible: sinkModel data: - - ["execa", "Member[shell].Argument[0]", "command-line-injection"] + - ["execa", "Member[shell].Argument[0]", "command-injection"] - Since we're adding a new sink, we add a tuple to the **sinkModel** extensible predicate. @@ -64,7 +64,7 @@ Note that this sink is already recognized by the CodeQL JS analysis, but for thi - **Member[shell]** selects accesses to the **shell** member of the **execa** package. - **Argument[0]** selects the first argument to calls to that member. -- **command-line-injection** indicates that this is considered a sink for the command injection query. +- **command-injection** indicates that this is considered a sink for the command injection query. Example: Taint sources from window 'message' events --------------------------------------------------- @@ -463,7 +463,7 @@ Sink kinds Unlike sources, sinks tend to be highly query-specific, rarely affecting more than one or two queries. Not every query supports customizable sinks. If the following sinks are not suitable for your use case, you should add a new query. - **code-injection**: A sink that can be used to inject code, such as in calls to **eval**. -- **command-line-injection**: A sink that can be used to inject shell commands, such as in calls to **child_process.spawn**. +- **command-injection**: A sink that can be used to inject shell commands, such as in calls to **child_process.spawn**. - **path-injection**: A sink that can be used for path injection in a file system access, such as in calls to **fs.readFile**. - **sql-injection**: A sink that can be used for SQL injection, such as in a MySQL **query** call. - **nosql-injection**: A sink that can be used for NoSQL injection, such as in a MongoDB **findOne** call. diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjectionCustomizations.qll index fee201c1d05..8581a5b0cb0 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CommandInjectionCustomizations.qll @@ -49,6 +49,6 @@ module CommandInjection { } private class SinkFromModel extends Sink { - SinkFromModel() { this = ModelOutput::getASinkNode("command-line-injection").asSink() } + SinkFromModel() { this = ModelOutput::getASinkNode("command-injection").asSink() } } } diff --git a/javascript/ql/test/library-tests/DataExtensions/execa.model.yml b/javascript/ql/test/library-tests/DataExtensions/execa.model.yml index 2516e1a7be8..f7e0f70c0bc 100644 --- a/javascript/ql/test/library-tests/DataExtensions/execa.model.yml +++ b/javascript/ql/test/library-tests/DataExtensions/execa.model.yml @@ -6,5 +6,5 @@ extensions: - [ "@example/execa", "Member[shell].Argument[0]", - "command-line-injection", + "command-injection", ] From 359f6ffd1ef86dea9f2354dd4204bae470596900 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Fri, 12 May 2023 15:12:53 -0400 Subject: [PATCH 038/739] JS: update 'credentials[%]' sink kind to 'credentials-%' --- .../semmle/javascript/frameworks/Credentials.qll | 2 +- .../javascript/frameworks/sequelize/model.json | 8 ++++---- .../javascript/frameworks/sequelize/model.yml | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Credentials.qll b/javascript/ql/lib/semmle/javascript/frameworks/Credentials.qll index 21ecbc6d001..c1685f11cf4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Credentials.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Credentials.qll @@ -46,7 +46,7 @@ module CredentialsExpr { private class CredentialsFromModel extends CredentialsNode { string kind; - CredentialsFromModel() { this = ModelOutput::getASinkNode("credentials[" + kind + "]").asSink() } + CredentialsFromModel() { this = ModelOutput::getASinkNode("credentials-" + kind).asSink() } override string getCredentialsKind() { result = CredentialsExpr::normalizeKind(kind) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.json b/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.json index 88568283605..62ad94b9ea0 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.json +++ b/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.json @@ -19,10 +19,10 @@ "sequelize.Sequelize;Member[query].Argument[0].Member[query];sql-injection", "sequelize.Sequelize;Member[query].Argument[0];sql-injection", "sequelize.SequelizeStaticAndInstance;Member[asIs,literal].Argument[0];sql-injection", - "sequelize;Argument[0..].Member[password];credentials[password]", - "sequelize;Argument[0..].Member[username];credentials[username]", - "sequelize;Argument[1];credentials[username]", - "sequelize;Argument[2];credentials[password]" + "sequelize;Argument[0..].Member[password];credentials-password", + "sequelize;Argument[0..].Member[username];credentials-username", + "sequelize;Argument[1];credentials-username", + "sequelize;Argument[2];credentials-password" ], "typeDefinitions": [ "sequelize.Sequelize;sequelize-typescript.Sequelize;" diff --git a/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.yml b/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.yml index 41a97e63a76..b25152b3764 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.yml +++ b/javascript/ql/lib/semmle/javascript/frameworks/sequelize/model.yml @@ -1,17 +1,17 @@ extensions: - - addsTo: + - addsTo: pack: codeql/javascript-all extensible: sinkModel data: - [sequelize.Sequelize, "Member[query].Argument[0].Member[query]", "sql-injection"] - [sequelize.Sequelize, "Member[query].Argument[0]", "sql-injection"] - [sequelize.SequelizeStaticAndInstance, "Member[asIs,literal].Argument[0]", "sql-injection"] - - [sequelize, "Argument[0..].Member[password]", "credentials[password]"] - - [sequelize, "Argument[0..].Member[username]", "credentials[username]"] - - [sequelize, "Argument[1]", "credentials[username]"] - - [sequelize, "Argument[2]", "credentials[password]"] + - [sequelize, "Argument[0..].Member[password]", "credentials-password"] + - [sequelize, "Argument[0..].Member[username]", "credentials-username"] + - [sequelize, "Argument[1]", "credentials-username"] + - [sequelize, "Argument[2]", "credentials-password"] - - addsTo: + - addsTo: pack: codeql/javascript-all extensible: typeModel data: @@ -264,7 +264,7 @@ extensions: - [sequelize.ThroughOptions, sequelize.AssociationOptionsBelongsToMany, "Member[through]"] - [sequelize.Utils, sequelize.SequelizeStaticAndInstance, "Member[Utils]"] - - addsTo: + - addsTo: pack: codeql/javascript-all extensible: summaryModel data: @@ -274,7 +274,7 @@ extensions: - [sequelize.Model, "", "", "Member[schema,scope,unscoped].ReturnValue", type] - [sequelize.Model, "", "", "Member[sync].ReturnValue.Awaited", type] - - addsTo: + - addsTo: pack: codeql/javascript-all extensible: typeVariableModel data: From 003bb2f6f50651cc5f8e8da28274b7a1310b3026 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Fri, 12 May 2023 15:20:03 -0400 Subject: [PATCH 039/739] JS: add change note --- .../ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md diff --git a/javascript/ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md b/javascript/ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md new file mode 100644 index 00000000000..9d215924623 --- /dev/null +++ b/javascript/ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Updated the following JavaScript sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. + * `command-line-injection` to `command-injection` + * `credentials[kind]` to `credentials-kind` From 9ec6c7daea8b267f5371ef1b3f5dc465d9f2e417 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 17 May 2023 10:47:25 +0200 Subject: [PATCH 040/739] JS: Avoid using global vars in documentation examples --- ...-labels-for-precise-data-flow-analysis.rst | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index 597ce491463..8625d637366 100644 --- a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -70,18 +70,22 @@ For example, we would like to flag this code: .. code-block:: javascript - var data = JSON.parse(str); - if (data.length > 0) { // problematic: `data` may be `null` - ... + function test(str) { + var data = JSON.parse(str); + if (data.length > 0) { // problematic: `data` may be `null` + ... + } } This code, on the other hand, should not be flagged: .. code-block:: javascript - var data = JSON.parse(str); - if (data && data.length > 0) { // unproblematic: `data` is first checked for nullness - ... + function test(str) { + var data = JSON.parse(str); + if (data && data.length > 0) { // unproblematic: `data` is first checked for nullness + ... + } } We will first try to write a query to find this kind of problem without flow labels, and use the @@ -168,11 +172,13 @@ checked for null-guardedness: .. code-block:: javascript - var root = JSON.parse(str); - if (root) { - var payload = root.data; // unproblematic: `root` cannot be `null` here - if (payload.length > 0) { // problematic: `payload` may be `null` here - ... + function test(str) { + var root = JSON.parse(str); + if (root) { + var payload = root.data; // unproblematic: `root` cannot be `null` here + if (payload.length > 0) { // problematic: `payload` may be `null` here + ... + } } } From 0f93f3a5ad134cc612a02df70db8e6ce14d09a73 Mon Sep 17 00:00:00 2001 From: Charis Kyriakou Date: Wed, 17 May 2023 12:34:47 +0100 Subject: [PATCH 041/739] Remove GITHUB_TOKEN permissions note since it's no longer required --- .../running-codeql-queries-at-scale-with-mrva.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index 656aec444de..83dc32edf76 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -23,7 +23,7 @@ If you want to run variant analysis on your repositories, you need to enable cod Setting a controller repository for variant analysis ---------------------------------------------------- -When you run variant analysis, the analysis is run entirely using GitHub Actions. You don't need to create any workflows, but you must specify which GitHub repository the CodeQL extension should use as the "controller repository." Controller repositories can be empty, but they must have at least one commit. The ``GITHUB_TOKEN`` must also have "Read and write permissions" to run workflows in that repository. For more information, see "`Managing GitHub Actions settings for a repository `__." +When you run variant analysis, the analysis is run entirely using GitHub Actions. You don't need to create any workflows, but you must specify which GitHub repository the CodeQL extension should use as the "controller repository." Controller repositories can be empty, but they must have at least one commit. .. pull-quote:: From 3b2c3f6f40ebb3aa7c8859f38a027c7c52688b56 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 May 2023 13:46:51 +0100 Subject: [PATCH 042/739] C++: Use an 'EquivalenceRelation' instead of the 'shortestDistances' HOP in 'getInstruction'. This reduces the memory pressure when generating the CFG for Wireshark. --- .../ir/implementation/aliased_ssa/IRBlock.qll | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll index 78008a6c69b..34a7abf7b5e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll @@ -255,14 +255,27 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | + block = MkIRBlock(first) and + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached From 771abf4f97c8c681ebf823ef2f717892901092ab Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 May 2023 13:47:01 +0100 Subject: [PATCH 043/739] C++/C#: Sync identical files. --- .../cpp/ir/implementation/raw/IRBlock.qll | 21 +++++++++++++++---- .../implementation/unaliased_ssa/IRBlock.qll | 21 +++++++++++++++---- .../ir/implementation/raw/IRBlock.qll | 21 +++++++++++++++---- .../implementation/unaliased_ssa/IRBlock.qll | 21 +++++++++++++++---- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll index 78008a6c69b..34a7abf7b5e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll @@ -255,14 +255,27 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | + block = MkIRBlock(first) and + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll index 78008a6c69b..34a7abf7b5e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll @@ -255,14 +255,27 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | + block = MkIRBlock(first) and + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll index 78008a6c69b..34a7abf7b5e 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll @@ -255,14 +255,27 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | + block = MkIRBlock(first) and + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll index 78008a6c69b..34a7abf7b5e 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll @@ -255,14 +255,27 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | + block = MkIRBlock(first) and + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached From 8cd85a5676abbd64e1d3f5dafee9647d63e2a90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Wed, 17 May 2023 16:16:30 +0200 Subject: [PATCH 044/739] add flow support for unmarshaled object fields --- .../lib/semmle/code/java/Serializability.qll | 1 + .../frameworks/google/GsonSerializability.qll | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll diff --git a/java/ql/lib/semmle/code/java/Serializability.qll b/java/ql/lib/semmle/code/java/Serializability.qll index fc8a19040f0..72490118020 100644 --- a/java/ql/lib/semmle/code/java/Serializability.qll +++ b/java/ql/lib/semmle/code/java/Serializability.qll @@ -4,6 +4,7 @@ import java private import frameworks.jackson.JacksonSerializability +private import frameworks.google.GsonSerializability private import frameworks.google.GoogleHttpClientApi /** diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll new file mode 100644 index 00000000000..1f887b2d44e --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -0,0 +1,71 @@ +/** + * Provides classes and predicates for working with Java Serialization in the context of + * the `com.google.gson` JSON processing framework. + */ + +import java +import semmle.code.java.Serializability +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSteps + +/** + * A method used for deserializing objects using Gson. The first parameter is the object to be + * deserialized. + */ +private class GsonReadValueMethod extends Method { + GsonReadValueMethod() { + this.getDeclaringType().hasQualifiedName("com.google.gson", "Gson") and + this.getName().matches("fromJson") + } +} + +/** A type whose values may be deserialized by the Gson JSON framework. */ +abstract class GsonDeserializableType extends Type { } + +/** A type whose values are explicitly deserialized in a call to a Gson method. */ +private class ExplicitlyReadGsonDeserializableType extends GsonDeserializableType { + ExplicitlyReadGsonDeserializableType() { + exists(MethodAccess ma | + // A call to a Gson read method... + ma.getMethod() instanceof GsonReadValueMethod and + // ...where `this` is used in the final argument, indicating that this type will be deserialized. + // TODO: find a way to get the type represented by java.lang.reflect.Type and com.google.gson.reflect.TypeToken + // fromJson​(String json, TypeToken typeOfT) + // fromJson​(String json, Type typeOfT) + usesType(ma.getArgument(1).getType(), this) and + not this instanceof TypeClass and + not this instanceof TypeObject + ) + } +} + +predicate test(MethodAccess ma) { + ma.getMethod() instanceof GsonReadValueMethod +} + +/** A type used in a `GsonDeserializableField` declaration. */ +private class FieldReferencedGsonDeserializableType extends GsonDeserializableType { + FieldReferencedGsonDeserializableType() { + exists(GsonDeserializableField f | usesType(f.getType(), this)) + } +} + +/** A field that may be deserialized using the Gson JSON framework. */ +class GsonDeserializableField extends DeserializableField { + pragma[assume_small_delta] + GsonDeserializableField() { + exists(GsonDeserializableType superType | + superType = this.getDeclaringType().getAnAncestor() and + not superType instanceof TypeObject and + // TODO: if we have the source, can we just track the flow through the backing fields? + //superType.fromSource() + not superType.(RefType).getPackage().getName().matches("java%") + ) + } +} + +private class GsonInheritTaint extends DataFlow::FieldContent, TaintInheritingContent { + GsonInheritTaint() { + this.getField() instanceof GsonDeserializableField + } +} From 7baf244ac69f27855cc5fc48b72c5171d925410f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Wed, 17 May 2023 16:18:46 +0200 Subject: [PATCH 045/739] remove test predicate --- .../java/frameworks/google/GsonSerializability.qll | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index 1f887b2d44e..cec369b14c2 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -39,10 +39,6 @@ private class ExplicitlyReadGsonDeserializableType extends GsonDeserializableTyp } } -predicate test(MethodAccess ma) { - ma.getMethod() instanceof GsonReadValueMethod -} - /** A type used in a `GsonDeserializableField` declaration. */ private class FieldReferencedGsonDeserializableType extends GsonDeserializableType { FieldReferencedGsonDeserializableType() { @@ -56,7 +52,7 @@ class GsonDeserializableField extends DeserializableField { GsonDeserializableField() { exists(GsonDeserializableType superType | superType = this.getDeclaringType().getAnAncestor() and - not superType instanceof TypeObject and + not superType instanceof TypeObject and // TODO: if we have the source, can we just track the flow through the backing fields? //superType.fromSource() not superType.(RefType).getPackage().getName().matches("java%") @@ -65,7 +61,5 @@ class GsonDeserializableField extends DeserializableField { } private class GsonInheritTaint extends DataFlow::FieldContent, TaintInheritingContent { - GsonInheritTaint() { - this.getField() instanceof GsonDeserializableField - } + GsonInheritTaint() { this.getField() instanceof GsonDeserializableField } } From b235b1cbb9e5d69e3b9fb9038c46bf830873623e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Wed, 17 May 2023 16:40:28 +0200 Subject: [PATCH 046/739] improve yaml models --- java/ql/lib/ext/com.google.gson.model.yml | 33 +++++++++++++++++-- .../frameworks/google/GsonSerializability.qll | 1 - 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/ext/com.google.gson.model.yml b/java/ql/lib/ext/com.google.gson.model.yml index a35ff0f117e..b867997c8df 100644 --- a/java/ql/lib/ext/com.google.gson.model.yml +++ b/java/ql/lib/ext/com.google.gson.model.yml @@ -3,11 +3,38 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["com.google.gson", "Gson", False, "toJson", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "Gson", False, "toJsonTree", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "Gson", False, "toString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["com.google.gson", "Gson", False, "fromJson", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJson", "(JsonElement)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJson", "(JsonElement,JsonWriter)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJson", "(JsonElement,Appendable)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJson", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJson", "(Object,Appendable)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJson", "(Object,Type)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJson", "(Object,Type,Appendable)", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJson", "(Object,Type,JsonWriter)", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJsonTree", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toJsonTree", "(Object,Type)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "Gson", False, "toString", "()", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["com.google.gson", "Gson", False, "newJsonReader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["com.google.gson", "Gson", False, "newJsonWriter", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["com.google.gson.stream", "JsonReader", False, "nextName", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["com.google.gson.stream", "JsonReader", False, "nextString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonElement", True, "getAsByte", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonElement", True, "getAsCharacter", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonElement", True, "getAsJsonArray", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonElement", True, "getAsJsonObject", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonElement", True, "getAsJsonPrimitive", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonElement", True, "getAsString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonElement", True, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "add", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "asList", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "set", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["com.google.gson", "JsonObject", True, "add", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["com.google.gson", "JsonObject", True, "addProperty", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["com.google.gson", "JsonObject", True, "asMap", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonObject", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonObject", True, "keySet", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonPrimitive", True, "JsonPrimitive", "(Character)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["com.google.gson", "JsonPrimitive", True, "JsonPrimitive", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index cec369b14c2..ec1dea15497 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -53,7 +53,6 @@ class GsonDeserializableField extends DeserializableField { exists(GsonDeserializableType superType | superType = this.getDeclaringType().getAnAncestor() and not superType instanceof TypeObject and - // TODO: if we have the source, can we just track the flow through the backing fields? //superType.fromSource() not superType.(RefType).getPackage().getName().matches("java%") ) From 57cc316ecdfd569a6f33cf1e90533dafe1fdb78d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 May 2023 15:42:38 +0100 Subject: [PATCH 047/739] C++: Fix bug for single-instruction basic blocks. --- .../code/cpp/ir/implementation/aliased_ssa/IRBlock.qll | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll index 34a7abf7b5e..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll @@ -271,8 +271,9 @@ private module Cached { /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | - block = MkIRBlock(first) and + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or index = getMemberIndex(result) and BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) ) From 9e05569121c7654f46f08c3f3ef53ea71613488b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 May 2023 15:42:44 +0100 Subject: [PATCH 048/739] C++/C#: Sync identical files. --- cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll | 5 +++-- .../code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll | 5 +++-- csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll | 5 +++-- .../experimental/ir/implementation/unaliased_ssa/IRBlock.qll | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll index 34a7abf7b5e..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll @@ -271,8 +271,9 @@ private module Cached { /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | - block = MkIRBlock(first) and + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or index = getMemberIndex(result) and BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) ) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll index 34a7abf7b5e..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll @@ -271,8 +271,9 @@ private module Cached { /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | - block = MkIRBlock(first) and + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or index = getMemberIndex(result) and BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) ) diff --git a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll index 34a7abf7b5e..4de4279b54c 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll @@ -271,8 +271,9 @@ private module Cached { /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | - block = MkIRBlock(first) and + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or index = getMemberIndex(result) and BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) ) diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll index 34a7abf7b5e..4de4279b54c 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll @@ -271,8 +271,9 @@ private module Cached { /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | - block = MkIRBlock(first) and + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or index = getMemberIndex(result) and BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) ) From 66b13e2294bb5baea9ec3d7d58aded8a1e4135ec Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 17 May 2023 17:08:14 +0100 Subject: [PATCH 049/739] Swift: Add a test of enum decls. --- .../elements/decl/enumdecl/enumdecl.expected | 27 +++++++++++++++++++ .../elements/decl/enumdecl/enumdecl.ql | 25 +++++++++++++++++ .../elements/decl/enumdecl/enumdecl.swift | 20 ++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected create mode 100644 swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql create mode 100644 swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.swift diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected new file mode 100644 index 00000000000..0f20f1f20f4 --- /dev/null +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected @@ -0,0 +1,27 @@ +| enumdecl.swift:2:1:6:1 | MyColours | (EnumDecl), .getMember(0) = case ..., .getMember(1) = red, .getMember(10) = hashValue, .getMember(2) = case ..., .getMember(3) = green, .getMember(4) = yellow, .getMember(5) = case ..., .getMember(6) = blue, .getMember(7) = __derived_enum_equals(_:_:), .getMember(8) = var ... = ..., .getMember(9) = hash(into:), .getType = MyColours | +| enumdecl.swift:3:2:3:7 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = red | +| enumdecl.swift:3:7:3:7 | red | (EnumElementDecl), .getDeclaringDecl = MyColours | +| enumdecl.swift:4:2:4:14 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = green, .getElement(1) = yellow | +| enumdecl.swift:4:7:4:7 | green | (EnumElementDecl), .getDeclaringDecl = MyColours | +| enumdecl.swift:4:14:4:14 | yellow | (EnumElementDecl), .getDeclaringDecl = MyColours | +| enumdecl.swift:5:2:5:7 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = blue | +| enumdecl.swift:5:7:5:7 | blue | (EnumElementDecl), .getDeclaringDecl = MyColours | +| enumdecl.swift:8:1:11:1 | MyContainer | (EnumDecl), .getMember(0) = case ..., .getMember(1) = str, .getMember(2) = case ..., .getMember(3) = pair, .getType = MyContainer | +| enumdecl.swift:9:2:9:17 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyContainer, .getElement(0) = str | +| enumdecl.swift:9:7:9:17 | str | (EnumElementDecl), .getDeclaringDecl = MyContainer, .getParam(0) = _ | +| enumdecl.swift:10:2:10:26 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyContainer, .getElement(0) = pair | +| enumdecl.swift:10:7:10:26 | pair | (EnumElementDecl), .getDeclaringDecl = MyContainer, .getParam(0) = x, .getParam(1) = y | +| enumdecl.swift:13:1:16:1 | MyNumbers | (EnumDecl), .getMember(0) = case ..., .getMember(1) = one, .getMember(2) = two, .getMember(3) = case ..., .getMember(4) = three, .getMember(5) = four, .getMember(6) = MyNumbers.init(rawValue:), .getMember(7) = var ... = ..., .getMember(8) = RawValue, .getMember(9) = rawValue, .getType = MyNumbers | +| enumdecl.swift:14:2:14:16 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyNumbers, .getElement(0) = one, .getElement(1) = two | +| enumdecl.swift:14:7:14:13 | one | (EnumElementDecl), .getDeclaringDecl = MyNumbers | +| enumdecl.swift:14:16:14:16 | two | (EnumElementDecl), .getDeclaringDecl = MyNumbers | +| enumdecl.swift:15:2:15:14 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyNumbers, .getElement(0) = three, .getElement(1) = four | +| enumdecl.swift:15:7:15:7 | three | (EnumElementDecl), .getDeclaringDecl = MyNumbers | +| enumdecl.swift:15:14:15:14 | four | (EnumElementDecl), .getDeclaringDecl = MyNumbers | +| enumdecl.swift:18:1:20:1 | MyGreek | (EnumDecl), .getMember(0) = case ..., .getMember(1) = alpha, .getMember(2) = beta, .getMember(3) = gamma, .getMember(4) = delta, .getMember(5) = epsilon, .getMember(6) = __derived_enum_equals(_:_:), .getMember(7) = var ... = ..., .getMember(8) = hash(into:), .getMember(9) = hashValue, .getType = MyGreek | +| enumdecl.swift:19:2:19:34 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyGreek, .getElement(0) = alpha, .getElement(1) = beta, .getElement(2) = gamma, .getElement(3) = delta, .getElement(4) = epsilon | +| enumdecl.swift:19:7:19:7 | alpha | (EnumElementDecl), .getDeclaringDecl = MyGreek | +| enumdecl.swift:19:14:19:14 | beta | (EnumElementDecl), .getDeclaringDecl = MyGreek | +| enumdecl.swift:19:20:19:20 | gamma | (EnumElementDecl), .getDeclaringDecl = MyGreek | +| enumdecl.swift:19:27:19:27 | delta | (EnumElementDecl), .getDeclaringDecl = MyGreek | +| enumdecl.swift:19:34:19:34 | epsilon | (EnumElementDecl), .getDeclaringDecl = MyGreek | diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql new file mode 100644 index 00000000000..18d07936f21 --- /dev/null +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql @@ -0,0 +1,25 @@ +import swift + +string describe(Decl d) { + (d instanceof EnumDecl and result = "(EnumDecl)") + or + (d instanceof EnumCaseDecl and result = "(EnumCaseDecl)") + or + (d instanceof EnumElementDecl and result = "(EnumElementDecl)") + or + result = ".getType = " + d.(EnumDecl).getType().toString() + or + result = ".getDeclaringDecl = " + d.getDeclaringDecl().toString() + or + exists(int i | + result = ".getMember(" + i.toString() + ") = " + d.getMember(i).toString() + or + result = ".getElement(" + i.toString() + ") = " + d.(EnumCaseDecl).getElement(i).toString() + or + result = ".getParam(" + i.toString() + ") = " + d.(EnumElementDecl).getParam(i).toString() + ) +} + +from Decl d +where d.getLocation().getFile().getName() != "" +select d, strictconcat(describe(d), ", ") diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.swift b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.swift new file mode 100644 index 00000000000..7a8b06b7d94 --- /dev/null +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.swift @@ -0,0 +1,20 @@ + +enum MyColours { + case red + case green, yellow + case blue +} + +enum MyContainer { + case str(String) + case pair(x: Int, y: Int) +} + +enum MyNumbers: Int { + case one = 1, two + case three, four +} + +enum MyGreek { + case alpha, beta, gamma, delta, epsilon +} From 95caaecd7158064f114dd8c0ce4e55b1a2775ab7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 17 May 2023 18:40:01 +0100 Subject: [PATCH 050/739] Swift: Add EnumDecl.getEnumElement(_). --- .../codeql/swift/elements/decl/EnumDecl.qll | 51 ++++++++++++++++++- .../elements/decl/enumdecl/enumdecl.expected | 8 +-- .../elements/decl/enumdecl/enumdecl.ql | 2 + 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll index f7c42dc9a2f..b1100cc9abe 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll @@ -1,4 +1,51 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.decl.EnumDecl +private import codeql.swift.elements.decl.EnumCaseDecl +private import codeql.swift.elements.decl.EnumElementDecl +private import codeql.swift.elements.decl.Decl -class EnumDecl extends Generated::EnumDecl { } +/** + * An enumeration declaration, for example: + * ``` + * enum MyColours { + * case red + * case green + * case blue + * } + * ``` + */ +class EnumDecl extends Generated::EnumDecl { + /** + * Gets the number of `EnumElementDecl`s in this enumeration before the `index`th member. Some + * of the members of an `EnumDecl` are `EnumCaseDecls` (representing the `case` lines), each of + * which holds one or more `EnumElementDecl`s. + */ + private int countEnumElementsTo(int memberIndex) { + memberIndex = 0 and result = 0 + or + exists(Decl prev | prev = this.getMember(memberIndex - 1) | + result = this.countEnumElementsTo(memberIndex - 1) + prev.(EnumCaseDecl).getNumberOfElements() + or + not prev instanceof EnumCaseDecl and + result = this.countEnumElementsTo(memberIndex - 1) + ) + } + + /** + * Gets the `index`th enumeration element of this enumeration (0-based). + */ + final EnumElementDecl getEnumElement(int index) { + exists(int memberIndex | + result = + this.getMember(memberIndex) + .(EnumCaseDecl) + .getElement(index - this.countEnumElementsTo(memberIndex)) + ) + } + + /** + * Gets an enumeration element of this enumeration. + */ + final EnumElementDecl getAnEnumElement() { + result = this.getMember(_).(EnumCaseDecl).getElement(_) + } +} diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected index 0f20f1f20f4..0494f6a9da8 100644 --- a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected @@ -1,4 +1,4 @@ -| enumdecl.swift:2:1:6:1 | MyColours | (EnumDecl), .getMember(0) = case ..., .getMember(1) = red, .getMember(10) = hashValue, .getMember(2) = case ..., .getMember(3) = green, .getMember(4) = yellow, .getMember(5) = case ..., .getMember(6) = blue, .getMember(7) = __derived_enum_equals(_:_:), .getMember(8) = var ... = ..., .getMember(9) = hash(into:), .getType = MyColours | +| enumdecl.swift:2:1:6:1 | MyColours | (EnumDecl), .getEnumElement(0) = red, .getEnumElement(1) = green, .getEnumElement(2) = yellow, .getEnumElement(3) = blue, .getMember(0) = case ..., .getMember(1) = red, .getMember(10) = hashValue, .getMember(2) = case ..., .getMember(3) = green, .getMember(4) = yellow, .getMember(5) = case ..., .getMember(6) = blue, .getMember(7) = __derived_enum_equals(_:_:), .getMember(8) = var ... = ..., .getMember(9) = hash(into:), .getType = MyColours | | enumdecl.swift:3:2:3:7 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = red | | enumdecl.swift:3:7:3:7 | red | (EnumElementDecl), .getDeclaringDecl = MyColours | | enumdecl.swift:4:2:4:14 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = green, .getElement(1) = yellow | @@ -6,19 +6,19 @@ | enumdecl.swift:4:14:4:14 | yellow | (EnumElementDecl), .getDeclaringDecl = MyColours | | enumdecl.swift:5:2:5:7 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = blue | | enumdecl.swift:5:7:5:7 | blue | (EnumElementDecl), .getDeclaringDecl = MyColours | -| enumdecl.swift:8:1:11:1 | MyContainer | (EnumDecl), .getMember(0) = case ..., .getMember(1) = str, .getMember(2) = case ..., .getMember(3) = pair, .getType = MyContainer | +| enumdecl.swift:8:1:11:1 | MyContainer | (EnumDecl), .getEnumElement(0) = str, .getEnumElement(1) = pair, .getMember(0) = case ..., .getMember(1) = str, .getMember(2) = case ..., .getMember(3) = pair, .getType = MyContainer | | enumdecl.swift:9:2:9:17 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyContainer, .getElement(0) = str | | enumdecl.swift:9:7:9:17 | str | (EnumElementDecl), .getDeclaringDecl = MyContainer, .getParam(0) = _ | | enumdecl.swift:10:2:10:26 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyContainer, .getElement(0) = pair | | enumdecl.swift:10:7:10:26 | pair | (EnumElementDecl), .getDeclaringDecl = MyContainer, .getParam(0) = x, .getParam(1) = y | -| enumdecl.swift:13:1:16:1 | MyNumbers | (EnumDecl), .getMember(0) = case ..., .getMember(1) = one, .getMember(2) = two, .getMember(3) = case ..., .getMember(4) = three, .getMember(5) = four, .getMember(6) = MyNumbers.init(rawValue:), .getMember(7) = var ... = ..., .getMember(8) = RawValue, .getMember(9) = rawValue, .getType = MyNumbers | +| enumdecl.swift:13:1:16:1 | MyNumbers | (EnumDecl), .getEnumElement(0) = one, .getEnumElement(1) = two, .getEnumElement(2) = three, .getEnumElement(3) = four, .getMember(0) = case ..., .getMember(1) = one, .getMember(2) = two, .getMember(3) = case ..., .getMember(4) = three, .getMember(5) = four, .getMember(6) = MyNumbers.init(rawValue:), .getMember(7) = var ... = ..., .getMember(8) = RawValue, .getMember(9) = rawValue, .getType = MyNumbers | | enumdecl.swift:14:2:14:16 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyNumbers, .getElement(0) = one, .getElement(1) = two | | enumdecl.swift:14:7:14:13 | one | (EnumElementDecl), .getDeclaringDecl = MyNumbers | | enumdecl.swift:14:16:14:16 | two | (EnumElementDecl), .getDeclaringDecl = MyNumbers | | enumdecl.swift:15:2:15:14 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyNumbers, .getElement(0) = three, .getElement(1) = four | | enumdecl.swift:15:7:15:7 | three | (EnumElementDecl), .getDeclaringDecl = MyNumbers | | enumdecl.swift:15:14:15:14 | four | (EnumElementDecl), .getDeclaringDecl = MyNumbers | -| enumdecl.swift:18:1:20:1 | MyGreek | (EnumDecl), .getMember(0) = case ..., .getMember(1) = alpha, .getMember(2) = beta, .getMember(3) = gamma, .getMember(4) = delta, .getMember(5) = epsilon, .getMember(6) = __derived_enum_equals(_:_:), .getMember(7) = var ... = ..., .getMember(8) = hash(into:), .getMember(9) = hashValue, .getType = MyGreek | +| enumdecl.swift:18:1:20:1 | MyGreek | (EnumDecl), .getEnumElement(0) = alpha, .getEnumElement(1) = beta, .getEnumElement(2) = gamma, .getEnumElement(3) = delta, .getEnumElement(4) = epsilon, .getMember(0) = case ..., .getMember(1) = alpha, .getMember(2) = beta, .getMember(3) = gamma, .getMember(4) = delta, .getMember(5) = epsilon, .getMember(6) = __derived_enum_equals(_:_:), .getMember(7) = var ... = ..., .getMember(8) = hash(into:), .getMember(9) = hashValue, .getType = MyGreek | | enumdecl.swift:19:2:19:34 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyGreek, .getElement(0) = alpha, .getElement(1) = beta, .getElement(2) = gamma, .getElement(3) = delta, .getElement(4) = epsilon | | enumdecl.swift:19:7:19:7 | alpha | (EnumElementDecl), .getDeclaringDecl = MyGreek | | enumdecl.swift:19:14:19:14 | beta | (EnumElementDecl), .getDeclaringDecl = MyGreek | diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql index 18d07936f21..a8e9b2e1f9f 100644 --- a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql @@ -17,6 +17,8 @@ string describe(Decl d) { result = ".getElement(" + i.toString() + ") = " + d.(EnumCaseDecl).getElement(i).toString() or result = ".getParam(" + i.toString() + ") = " + d.(EnumElementDecl).getParam(i).toString() + or + result = ".getEnumElement(" + i.toString() + ") = " + d.(EnumDecl).getEnumElement(i).toString() ) } From 6c35bbf5c2c3f0145603b7c6514e19c733d37b2e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 17 May 2023 18:45:19 +0100 Subject: [PATCH 051/739] Swift: Simplify / focus the test. --- .../elements/decl/enumdecl/enumdecl.expected | 8 ++++---- .../test/library-tests/elements/decl/enumdecl/enumdecl.ql | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected index 0494f6a9da8..5e0222c484c 100644 --- a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.expected @@ -1,4 +1,4 @@ -| enumdecl.swift:2:1:6:1 | MyColours | (EnumDecl), .getEnumElement(0) = red, .getEnumElement(1) = green, .getEnumElement(2) = yellow, .getEnumElement(3) = blue, .getMember(0) = case ..., .getMember(1) = red, .getMember(10) = hashValue, .getMember(2) = case ..., .getMember(3) = green, .getMember(4) = yellow, .getMember(5) = case ..., .getMember(6) = blue, .getMember(7) = __derived_enum_equals(_:_:), .getMember(8) = var ... = ..., .getMember(9) = hash(into:), .getType = MyColours | +| enumdecl.swift:2:1:6:1 | MyColours | (EnumDecl), .getEnumElement(0) = red, .getEnumElement(1) = green, .getEnumElement(2) = yellow, .getEnumElement(3) = blue, .getType = MyColours | | enumdecl.swift:3:2:3:7 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = red | | enumdecl.swift:3:7:3:7 | red | (EnumElementDecl), .getDeclaringDecl = MyColours | | enumdecl.swift:4:2:4:14 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = green, .getElement(1) = yellow | @@ -6,19 +6,19 @@ | enumdecl.swift:4:14:4:14 | yellow | (EnumElementDecl), .getDeclaringDecl = MyColours | | enumdecl.swift:5:2:5:7 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyColours, .getElement(0) = blue | | enumdecl.swift:5:7:5:7 | blue | (EnumElementDecl), .getDeclaringDecl = MyColours | -| enumdecl.swift:8:1:11:1 | MyContainer | (EnumDecl), .getEnumElement(0) = str, .getEnumElement(1) = pair, .getMember(0) = case ..., .getMember(1) = str, .getMember(2) = case ..., .getMember(3) = pair, .getType = MyContainer | +| enumdecl.swift:8:1:11:1 | MyContainer | (EnumDecl), .getEnumElement(0) = str, .getEnumElement(1) = pair, .getType = MyContainer | | enumdecl.swift:9:2:9:17 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyContainer, .getElement(0) = str | | enumdecl.swift:9:7:9:17 | str | (EnumElementDecl), .getDeclaringDecl = MyContainer, .getParam(0) = _ | | enumdecl.swift:10:2:10:26 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyContainer, .getElement(0) = pair | | enumdecl.swift:10:7:10:26 | pair | (EnumElementDecl), .getDeclaringDecl = MyContainer, .getParam(0) = x, .getParam(1) = y | -| enumdecl.swift:13:1:16:1 | MyNumbers | (EnumDecl), .getEnumElement(0) = one, .getEnumElement(1) = two, .getEnumElement(2) = three, .getEnumElement(3) = four, .getMember(0) = case ..., .getMember(1) = one, .getMember(2) = two, .getMember(3) = case ..., .getMember(4) = three, .getMember(5) = four, .getMember(6) = MyNumbers.init(rawValue:), .getMember(7) = var ... = ..., .getMember(8) = RawValue, .getMember(9) = rawValue, .getType = MyNumbers | +| enumdecl.swift:13:1:16:1 | MyNumbers | (EnumDecl), .getEnumElement(0) = one, .getEnumElement(1) = two, .getEnumElement(2) = three, .getEnumElement(3) = four, .getType = MyNumbers | | enumdecl.swift:14:2:14:16 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyNumbers, .getElement(0) = one, .getElement(1) = two | | enumdecl.swift:14:7:14:13 | one | (EnumElementDecl), .getDeclaringDecl = MyNumbers | | enumdecl.swift:14:16:14:16 | two | (EnumElementDecl), .getDeclaringDecl = MyNumbers | | enumdecl.swift:15:2:15:14 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyNumbers, .getElement(0) = three, .getElement(1) = four | | enumdecl.swift:15:7:15:7 | three | (EnumElementDecl), .getDeclaringDecl = MyNumbers | | enumdecl.swift:15:14:15:14 | four | (EnumElementDecl), .getDeclaringDecl = MyNumbers | -| enumdecl.swift:18:1:20:1 | MyGreek | (EnumDecl), .getEnumElement(0) = alpha, .getEnumElement(1) = beta, .getEnumElement(2) = gamma, .getEnumElement(3) = delta, .getEnumElement(4) = epsilon, .getMember(0) = case ..., .getMember(1) = alpha, .getMember(2) = beta, .getMember(3) = gamma, .getMember(4) = delta, .getMember(5) = epsilon, .getMember(6) = __derived_enum_equals(_:_:), .getMember(7) = var ... = ..., .getMember(8) = hash(into:), .getMember(9) = hashValue, .getType = MyGreek | +| enumdecl.swift:18:1:20:1 | MyGreek | (EnumDecl), .getEnumElement(0) = alpha, .getEnumElement(1) = beta, .getEnumElement(2) = gamma, .getEnumElement(3) = delta, .getEnumElement(4) = epsilon, .getType = MyGreek | | enumdecl.swift:19:2:19:34 | case ... | (EnumCaseDecl), .getDeclaringDecl = MyGreek, .getElement(0) = alpha, .getElement(1) = beta, .getElement(2) = gamma, .getElement(3) = delta, .getElement(4) = epsilon | | enumdecl.swift:19:7:19:7 | alpha | (EnumElementDecl), .getDeclaringDecl = MyGreek | | enumdecl.swift:19:14:19:14 | beta | (EnumElementDecl), .getDeclaringDecl = MyGreek | diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql index a8e9b2e1f9f..e2756b77a49 100644 --- a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql @@ -12,8 +12,6 @@ string describe(Decl d) { result = ".getDeclaringDecl = " + d.getDeclaringDecl().toString() or exists(int i | - result = ".getMember(" + i.toString() + ") = " + d.getMember(i).toString() - or result = ".getElement(" + i.toString() + ") = " + d.(EnumCaseDecl).getElement(i).toString() or result = ".getParam(" + i.toString() + ") = " + d.(EnumElementDecl).getParam(i).toString() From 3539e55bb2651a7b9b8b4b87d7e5059e843a191d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 17 May 2023 19:21:41 +0100 Subject: [PATCH 052/739] Swift: Autoformat. --- .../test/library-tests/elements/decl/enumdecl/enumdecl.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql index e2756b77a49..dba88e6009d 100644 --- a/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/enumdecl.ql @@ -1,11 +1,11 @@ import swift string describe(Decl d) { - (d instanceof EnumDecl and result = "(EnumDecl)") + d instanceof EnumDecl and result = "(EnumDecl)" or - (d instanceof EnumCaseDecl and result = "(EnumCaseDecl)") + d instanceof EnumCaseDecl and result = "(EnumCaseDecl)" or - (d instanceof EnumElementDecl and result = "(EnumElementDecl)") + d instanceof EnumElementDecl and result = "(EnumElementDecl)" or result = ".getType = " + d.(EnumDecl).getType().toString() or From 5c6fc2ff019a8da08d0b08afccb085ab19cc2851 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Wed, 17 May 2023 15:18:52 -0400 Subject: [PATCH 053/739] Update IfStatementAdditionOverflow.ql --- .../CWE-190/IfStatementAdditionOverflow.ql | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql index a45ba737bab..3667f068a25 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql @@ -1,12 +1,8 @@ /** * @name Integer addition may overflow inside if statement - * @description Detects "if (a+b>c) a=c-b", which incorrectly implements - * a = min(a,c-b) if a+b overflows. Should be replaced by - * "if (a>c-b) a=c-b". Also detects "if (b+a>c) a=c-b" - * (swapped terms in addition), if (a+b>c) { a=c-b }" - * (assignment inside block), "c=", "<", "<=" instead of ">" (all operators). This - * integer overflow is the root cause of the buffer overflow + * @description Writing 'if (a+b>c) a=c-b' incorrectly implements + * 'a = min(a,c-b)' if 'a+b' overflows. This integer + * overflow is the root cause of the buffer overflow * in the SHA-3 reference implementation (CVE-2022-37454). * @kind problem * @problem.severity warning @@ -21,22 +17,26 @@ import cpp import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.valuenumbering.HashCons import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis -import semmle.code.cpp.commons.Exclusions +import semmle.code.cpp.controlflow.Guards -from IfStmt ifstmt, RelationalOperation relop, ExprStmt exprstmt, BlockStmt blockstmt, AssignExpr assignexpr, AddExpr addexpr, SubExpr subexpr -where ifstmt.getCondition() = relop and - relop.getAnOperand() = addexpr and +from + GuardCondition guard, Expr expr, ExprStmt exprstmt, BasicBlock block, AssignExpr assignexpr, + AddExpr addexpr, SubExpr subexpr +where + (guard.ensuresLt(expr, addexpr, 0, block, _) or guard.ensuresLt(addexpr, expr, 0, block, _)) and addexpr.getUnspecifiedType() instanceof IntegralType and - not isFromMacroDefinition(relop) and exprMightOverflowPositively(addexpr) and - (ifstmt.getThen() = exprstmt or - (ifstmt.getThen() = blockstmt and - blockstmt.getAStmt() = exprstmt)) and + block.getANode() = exprstmt and exprstmt.getExpr() = assignexpr and assignexpr.getRValue() = subexpr and - ((hashCons(addexpr.getLeftOperand()) = hashCons(assignexpr.getLValue()) and - globalValueNumber(addexpr.getRightOperand()) = globalValueNumber(subexpr.getRightOperand())) or - (hashCons(addexpr.getRightOperand()) = hashCons(assignexpr.getLValue()) and - globalValueNumber(addexpr.getLeftOperand()) = globalValueNumber(subexpr.getRightOperand()))) and - globalValueNumber(relop.getAnOperand()) = globalValueNumber(subexpr.getLeftOperand()) -select ifstmt, "\"if (a+b>c) a=c-b\" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as \"if (a>c-b) a=c-b\" which avoids the overflow.", addexpr, "addition" + ( + hashCons(addexpr.getLeftOperand()) = hashCons(assignexpr.getLValue()) and + globalValueNumber(addexpr.getRightOperand()) = globalValueNumber(subexpr.getRightOperand()) + or + hashCons(addexpr.getRightOperand()) = hashCons(assignexpr.getLValue()) and + globalValueNumber(addexpr.getLeftOperand()) = globalValueNumber(subexpr.getRightOperand()) + ) and + globalValueNumber(expr) = globalValueNumber(subexpr.getLeftOperand()) +select guard, + "\"if (a+b>c) a=c-b\" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as \"if (a>c-b) a=c-b\" which avoids the overflow.", + addexpr, "addition" From ef578617892e241545db4e0298c3b148d1558e74 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Wed, 17 May 2023 15:19:52 -0400 Subject: [PATCH 054/739] Update IfStatementAdditionOverflow.expected --- .../IfStatementAdditionOverflow.expected | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.expected index 12dbde04790..2e31f173faa 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/IfStatementAdditionOverflow.expected @@ -1,33 +1,35 @@ -| test.cpp:18:2:18:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:18:6:18:8 | ... + ... | addition | -| test.cpp:19:2:19:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:19:6:19:8 | ... + ... | addition | -| test.cpp:20:2:20:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:20:6:20:8 | ... + ... | addition | -| test.cpp:21:2:21:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:21:6:21:8 | ... + ... | addition | -| test.cpp:22:2:22:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:22:8:22:10 | ... + ... | addition | -| test.cpp:23:2:23:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:23:8:23:10 | ... + ... | addition | -| test.cpp:24:2:24:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:24:8:24:10 | ... + ... | addition | -| test.cpp:25:2:25:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:25:8:25:10 | ... + ... | addition | -| test.cpp:27:2:27:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:27:6:27:8 | ... + ... | addition | -| test.cpp:28:2:28:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:28:6:28:8 | ... + ... | addition | -| test.cpp:29:2:29:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:29:6:29:8 | ... + ... | addition | -| test.cpp:30:2:30:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:30:6:30:8 | ... + ... | addition | -| test.cpp:31:2:31:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:31:9:31:11 | ... + ... | addition | -| test.cpp:32:2:32:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:32:9:32:11 | ... + ... | addition | -| test.cpp:33:2:33:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:33:9:33:11 | ... + ... | addition | -| test.cpp:34:2:34:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:34:9:34:11 | ... + ... | addition | -| test.cpp:36:2:36:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:36:6:36:8 | ... + ... | addition | -| test.cpp:37:2:37:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:37:6:37:8 | ... + ... | addition | -| test.cpp:38:2:38:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:38:6:38:8 | ... + ... | addition | -| test.cpp:39:2:39:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:39:6:39:8 | ... + ... | addition | -| test.cpp:40:2:40:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:40:8:40:10 | ... + ... | addition | -| test.cpp:41:2:41:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:41:8:41:10 | ... + ... | addition | -| test.cpp:42:2:42:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:42:8:42:10 | ... + ... | addition | -| test.cpp:43:2:43:24 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:43:8:43:10 | ... + ... | addition | -| test.cpp:45:2:45:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:45:6:45:8 | ... + ... | addition | -| test.cpp:46:2:46:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:46:6:46:8 | ... + ... | addition | -| test.cpp:47:2:47:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:47:6:47:8 | ... + ... | addition | -| test.cpp:48:2:48:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:48:6:48:8 | ... + ... | addition | -| test.cpp:49:2:49:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:49:9:49:11 | ... + ... | addition | -| test.cpp:50:2:50:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:50:9:50:11 | ... + ... | addition | -| test.cpp:51:2:51:21 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:51:9:51:11 | ... + ... | addition | -| test.cpp:52:2:52:25 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:52:9:52:11 | ... + ... | addition | -| test.cpp:54:2:54:20 | if (...) ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:54:6:54:8 | ... + ... | addition | +| test.cpp:18:6:18:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:18:6:18:8 | ... + ... | addition | +| test.cpp:19:6:19:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:19:6:19:8 | ... + ... | addition | +| test.cpp:20:6:20:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:20:6:20:8 | ... + ... | addition | +| test.cpp:21:6:21:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:21:6:21:8 | ... + ... | addition | +| test.cpp:22:6:22:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:22:8:22:10 | ... + ... | addition | +| test.cpp:23:6:23:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:23:8:23:10 | ... + ... | addition | +| test.cpp:24:6:24:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:24:8:24:10 | ... + ... | addition | +| test.cpp:25:6:25:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:25:8:25:10 | ... + ... | addition | +| test.cpp:27:6:27:11 | ... >= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:27:6:27:8 | ... + ... | addition | +| test.cpp:28:6:28:11 | ... >= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:28:6:28:8 | ... + ... | addition | +| test.cpp:29:6:29:11 | ... >= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:29:6:29:8 | ... + ... | addition | +| test.cpp:30:6:30:11 | ... >= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:30:6:30:8 | ... + ... | addition | +| test.cpp:31:6:31:11 | ... >= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:31:9:31:11 | ... + ... | addition | +| test.cpp:32:6:32:11 | ... >= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:32:9:32:11 | ... + ... | addition | +| test.cpp:33:6:33:11 | ... >= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:33:9:33:11 | ... + ... | addition | +| test.cpp:34:6:34:11 | ... >= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:34:9:34:11 | ... + ... | addition | +| test.cpp:36:6:36:10 | ... < ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:36:6:36:8 | ... + ... | addition | +| test.cpp:37:6:37:10 | ... < ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:37:6:37:8 | ... + ... | addition | +| test.cpp:38:6:38:10 | ... < ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:38:6:38:8 | ... + ... | addition | +| test.cpp:39:6:39:10 | ... < ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:39:6:39:8 | ... + ... | addition | +| test.cpp:40:6:40:10 | ... < ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:40:8:40:10 | ... + ... | addition | +| test.cpp:41:6:41:10 | ... < ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:41:8:41:10 | ... + ... | addition | +| test.cpp:42:6:42:10 | ... < ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:42:8:42:10 | ... + ... | addition | +| test.cpp:43:6:43:10 | ... < ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:43:8:43:10 | ... + ... | addition | +| test.cpp:45:6:45:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:45:6:45:8 | ... + ... | addition | +| test.cpp:46:6:46:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:46:6:46:8 | ... + ... | addition | +| test.cpp:47:6:47:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:47:6:47:8 | ... + ... | addition | +| test.cpp:48:6:48:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:48:6:48:8 | ... + ... | addition | +| test.cpp:49:6:49:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:49:9:49:11 | ... + ... | addition | +| test.cpp:50:6:50:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:50:9:50:11 | ... + ... | addition | +| test.cpp:51:6:51:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:51:9:51:11 | ... + ... | addition | +| test.cpp:52:6:52:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:52:9:52:11 | ... + ... | addition | +| test.cpp:54:6:54:10 | ... > ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:54:6:54:8 | ... + ... | addition | +| test.cpp:61:6:61:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:61:6:61:8 | ... + ... | addition | +| test.cpp:62:6:62:11 | ... <= ... | "if (a+b>c) a=c-b" was detected where the $@ may potentially overflow/wraparound. The code can be rewritten as "if (a>c-b) a=c-b" which avoids the overflow. | test.cpp:62:6:62:8 | ... + ... | addition | From 187299fcaf283f06e664d894f10cddea039483fe Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Wed, 17 May 2023 15:20:54 -0400 Subject: [PATCH 055/739] Update test.cpp --- .../Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp index f1aac83122b..7c5ab91832e 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/IfStatementAdditionOverflow/test.cpp @@ -57,4 +57,7 @@ void test() if (a+b>c) { b++; a = c-b; } // GOOD if (a+d>c) a = c-d; // GOOD if (a1+b1>c1) a1 = c1-b1; // GOOD + + if (a+b<=c) { /* ... */ } else { a = c-b; } // BAD + if (a+b<=c) { return; } a = c-b; // BAD } From 27519ce3ea4e4917e14ee5b917696400ab9370b8 Mon Sep 17 00:00:00 2001 From: Nicky Mouha Date: Wed, 17 May 2023 15:27:19 -0400 Subject: [PATCH 056/739] Create IfStatementAdditionOverflow.qhelp --- .../CWE-190/IfStatementAdditionOverflow.qhelp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.qhelp diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.qhelp new file mode 100644 index 00000000000..72491838fd2 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.qhelp @@ -0,0 +1,33 @@ + + + + +

+Detects if (a+b>c) a=c-b, which incorrectly implements +a = min(a,c-b) if a+b overflows. +

+

+Also detects variants such as if (b+a>c) a=c-b (swapped +terms in addition), if (a+b>c) { a=c-b } (assignment +inside block), c<a+b (swapped operands), and +>=, <, <= instead of +> (all operators). +

+

+This integer overflow is the root cause of the buffer overflow in +the SHA-3 reference implementation (CVE-2022-37454). +

+
+ +

+Replace by if (a>c-b) a=c-b. This avoids the overflow +and makes it easy to see that a = min(a,c-b). +

+
+ +
  • CVE-2022-37454: The Keccak XKCP SHA-3 reference implementation before fdc6fef has an integer overflow and resultant buffer overflow that allows attackers to execute arbitrary code or eliminate expected cryptographic properties. This occurs in the sponge function interface.
  • +
  • GitHub Advisory Database: CVE-2022-37454: Buffer overflow in sponge queue functions
  • +
    +
    From f0ce5b09c6b9e9d345d94376ff174502166ce90d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 18 May 2023 09:39:42 +0100 Subject: [PATCH 057/739] Swift: Address QL-for-QL warning. --- swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll index b1100cc9abe..6fb24f21ea0 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll @@ -15,7 +15,7 @@ private import codeql.swift.elements.decl.Decl */ class EnumDecl extends Generated::EnumDecl { /** - * Gets the number of `EnumElementDecl`s in this enumeration before the `index`th member. Some + * Gets the number of `EnumElementDecl`s in this enumeration before the `memberIndex`th member. Some * of the members of an `EnumDecl` are `EnumCaseDecls` (representing the `case` lines), each of * which holds one or more `EnumElementDecl`s. */ From d26a86185faec1057eca98940bc81e719715518f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 18 May 2023 09:42:32 +0100 Subject: [PATCH 058/739] Swift: Codegen. --- swift/ql/.generated.list | 1 - swift/ql/.gitattributes | 1 - 2 files changed, 2 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 2a56c1ba2ae..c3c0bfb69ec 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -24,7 +24,6 @@ lib/codeql/swift/elements/decl/ConcreteVarDecl.qll 94bcbdd91f461295c5b6b49fa597b lib/codeql/swift/elements/decl/ConcreteVarDeclConstructor.qll 4b6a9f458db5437f9351b14464b3809a78194029554ea818b3e18272c17afba3 a60d695b0d0ffa917ad01908bec2beaa663e644eddb00fb370fbc906623775d4 lib/codeql/swift/elements/decl/DeinitializerConstructor.qll 85f29a68ee5c0f2606c51e7a859f5f45fbc5f373e11b5e9c0762c9ba5cff51c4 6b28f69b8125d0393607dbad8e7a8aaa6469b9c671f67e8e825cc63964ed2f5d lib/codeql/swift/elements/decl/EnumCaseDeclConstructor.qll 8c907544170671f713a8665d294eeefdbe78a607c2f16e2c630ea9c33f484baf eec83efc930683628185dbdad8f73311aad510074d168a53d85ea09d13f1f7e1 -lib/codeql/swift/elements/decl/EnumDecl.qll 29f9d8cbfb19c174af9a666162fd918af7f962fa5d97756105e78d5eec38cb9e 779940ebdbd510eb651972c57eb84b04af39c44ef59a8c307a44549ab730febb lib/codeql/swift/elements/decl/EnumDeclConstructor.qll 642bbfb71e917d84695622f3b2c7b36bf5be4e185358609810267ab1fc4e221b f6e06d79e7ff65fbabf72c553508b67406fb59c577215d28cc47971d34b6af05 lib/codeql/swift/elements/decl/EnumElementDeclConstructor.qll 736074246a795c14a30a8ec7bb8da595a729983187887294e485487309919dc6 4614fb380fad7af1b5fb8afce920f3e7350378254ece60d19722046046672fbb lib/codeql/swift/elements/decl/ExtensionDeclConstructor.qll 4f811e3332720327d2b9019edbb2fa70fb24322e72881afc040e7927452409d6 554f9832311dfc30762507e0bd4b25c5b6fdb9d0c4e8252cc5a1ef1033fafacb diff --git a/swift/ql/.gitattributes b/swift/ql/.gitattributes index 71cc5c58ecf..a1bd08a0b69 100644 --- a/swift/ql/.gitattributes +++ b/swift/ql/.gitattributes @@ -26,7 +26,6 @@ /lib/codeql/swift/elements/decl/ConcreteVarDeclConstructor.qll linguist-generated /lib/codeql/swift/elements/decl/DeinitializerConstructor.qll linguist-generated /lib/codeql/swift/elements/decl/EnumCaseDeclConstructor.qll linguist-generated -/lib/codeql/swift/elements/decl/EnumDecl.qll linguist-generated /lib/codeql/swift/elements/decl/EnumDeclConstructor.qll linguist-generated /lib/codeql/swift/elements/decl/EnumElementDeclConstructor.qll linguist-generated /lib/codeql/swift/elements/decl/ExtensionDeclConstructor.qll linguist-generated From bf3fb09dfd330665d1f38b3c1437d5c4e63ac28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvaro=20Mu=C3=B1oz?= Date: Thu, 18 May 2023 12:39:41 +0200 Subject: [PATCH 059/739] Apply suggestions from code review Co-authored-by: Tony Torralba --- .../semmle/code/java/frameworks/google/GsonSerializability.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index ec1dea15497..34a333c8b11 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -14,8 +14,7 @@ import semmle.code.java.dataflow.FlowSteps */ private class GsonReadValueMethod extends Method { GsonReadValueMethod() { - this.getDeclaringType().hasQualifiedName("com.google.gson", "Gson") and - this.getName().matches("fromJson") + this.hasQualifiedName("com.google.gson", "Gson", "fromJson") } } From 5ffde7a7628cc8793ce279f3e64fcabeb40cb234 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 May 2023 14:55:39 +0100 Subject: [PATCH 060/739] Update swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll Co-authored-by: Mathias Vorreiter Pedersen --- .../codeql/swift/elements/decl/EnumDecl.qll | 29 +++++-------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll index 6fb24f21ea0..91f597c8d38 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/EnumDecl.qll @@ -14,32 +14,17 @@ private import codeql.swift.elements.decl.Decl * ``` */ class EnumDecl extends Generated::EnumDecl { - /** - * Gets the number of `EnumElementDecl`s in this enumeration before the `memberIndex`th member. Some - * of the members of an `EnumDecl` are `EnumCaseDecls` (representing the `case` lines), each of - * which holds one or more `EnumElementDecl`s. - */ - private int countEnumElementsTo(int memberIndex) { - memberIndex = 0 and result = 0 - or - exists(Decl prev | prev = this.getMember(memberIndex - 1) | - result = this.countEnumElementsTo(memberIndex - 1) + prev.(EnumCaseDecl).getNumberOfElements() - or - not prev instanceof EnumCaseDecl and - result = this.countEnumElementsTo(memberIndex - 1) - ) - } - /** * Gets the `index`th enumeration element of this enumeration (0-based). */ final EnumElementDecl getEnumElement(int index) { - exists(int memberIndex | - result = - this.getMember(memberIndex) - .(EnumCaseDecl) - .getElement(index - this.countEnumElementsTo(memberIndex)) - ) + result = + rank[index + 1](int memberIndex, Decl d | + d = this.getMember(memberIndex) and + d instanceof EnumElementDecl + | + d order by memberIndex + ) } /** From 881134a6f5776a7ef13017f52e8fc6ed7160e51b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 May 2023 15:29:49 +0100 Subject: [PATCH 061/739] Swift: Add warning note to Decl.getMember. --- swift/ql/.generated.list | 4 ++-- swift/ql/lib/codeql/swift/generated/Raw.qll | 4 ++++ swift/ql/lib/codeql/swift/generated/decl/Decl.qll | 4 ++++ swift/schema.py | 6 +++++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index c3c0bfb69ec..dcc8cd2a698 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -383,7 +383,7 @@ lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d lib/codeql/swift/generated/ParentChild.qll 7db14da89a0dc22ab41e654750f59d03085de8726ac358c458fccb0e0b75e193 e16991b33eb0ddea18c0699d7ea31710460ff8ada1f51d8e94f1100f6e18d1c8 lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 8d4880e5ee1fdd120adeb7bf0dfa1399e7b1a53b2cc7598aed8e15cbf996d1c0 da0d446347d29f5cd05281c17c24e87610f31c32adb7e05ab8f3a26bed55bd90 +lib/codeql/swift/generated/Raw.qll cc504ec0771dbb461367944a5c95186047bad59a087a9bda74ef346c7b89b0d3 0b5973d56edd8099b645ea1f7be2a4934e62d5fa165261c63299ac2cf634437d lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -397,7 +397,7 @@ lib/codeql/swift/generated/decl/AssociatedTypeDecl.qll 4169d083104f9c089223ed3c5 lib/codeql/swift/generated/decl/CapturedDecl.qll cbc416f48471f978d21f5f9ec02eb912692f9678ed154cb0b6d30df9de48e628 d9534cdf290ad48e285d27a520c0b1692afed14bbdd907430bcd46e7de2fbb31 lib/codeql/swift/generated/decl/ClassDecl.qll a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 lib/codeql/swift/generated/decl/ConcreteVarDecl.qll 4801ccc477480c4bc4fc117976fbab152e081064e064c97fbb0f37199cb1d0a8 4d7cfbf5b39b307dd673781adc220fdef04213f2e3d080004fa658ba6d3acb8d -lib/codeql/swift/generated/decl/Decl.qll 2cc8ad7e3a3b658d7b1b06d20bdaf7604de387045c33b0d64191b5ef998708c2 7ed3194e89f7ae37cf9c691e4666449e4f406f6c3ee6d35bbbda4e66cdd3ca5a +lib/codeql/swift/generated/decl/Decl.qll 4bb00d3c64f88f3c8e1bdc7aa9de93d2bef6477adf756d6f7e3897d2c5685726 36d805a6f2b0c2dd8bdfbd10de6978bd9344a025e71c938e58d0c3c0f9672247 lib/codeql/swift/generated/decl/Deinitializer.qll 816ecd92552915d06952517606a6e4c67bc53d7e7d9f5c09b7276e70612627fe 816ecd92552915d06952517606a6e4c67bc53d7e7d9f5c09b7276e70612627fe lib/codeql/swift/generated/decl/EnumCaseDecl.qll 7942eb77f91680c3553becb313f21723e0b437eadebc117f0690e5364705bef1 40eec2e74c514cecdfcdf6d7d5c8a033c717f69a38cfca834934fe3859c4e1ef lib/codeql/swift/generated/decl/EnumDecl.qll fa4490d511ee537751a4fab2478e65250ff3deba43c74db5341184c9ba25b534 fa4490d511ee537751a4fab2478e65250ff3deba43c74db5341184c9ba25b534 diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index dc5ddeed979..8989bc83905 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -310,6 +310,10 @@ module Raw { /** * Gets the `index`th member of this declaration (0-based). + * + * Prefer to use more specific methods (such as `EnumDecl.getEnumElement`) rather than relying + * on the order of members given by `getMember`. In some cases the order of members may not + * align with expectations, and could change in future releases. */ Decl getMember(int index) { decl_members(this, index, result) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/Decl.qll b/swift/ql/lib/codeql/swift/generated/decl/Decl.qll index 673de2cffee..136d28ea852 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/Decl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/Decl.qll @@ -34,6 +34,10 @@ module Generated { /** * Gets the `index`th member of this declaration (0-based). + * + * Prefer to use more specific methods (such as `EnumDecl.getEnumElement`) rather than relying + * on the order of members given by `getMember`. In some cases the order of members may not + * align with expectations, and could change in future releases. */ final Decl getMember(int index) { result = this.getImmediateMember(index).resolve() } diff --git a/swift/schema.py b/swift/schema.py index 8fc0941e171..ccb538769af 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -80,7 +80,11 @@ class Type(Element): @group("decl") class Decl(AstNode): module: "ModuleDecl" - members: list["Decl"] | child + members: list["Decl"] | child | desc(""" + Prefer to use more specific methods (such as `EnumDecl.getEnumElement`) rather than relying + on the order of members given by `getMember`. In some cases the order of members may not + align with expectations, and could change in future releases. + """) @group("expr") class Expr(AstNode): From 19080333b9c5b3165ef4233f5593557991816305 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 May 2023 16:50:49 +0100 Subject: [PATCH 062/739] Swift: Add a few test cases. --- .../CWE-135/StringLengthConflation.expected | 56 +++++++++++++++++++ .../CWE-135/StringLengthConflation.swift | 19 +++++++ 2 files changed, 75 insertions(+) diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index b0154ec15af..ffae88451e2 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -18,6 +18,18 @@ edges | StringLengthConflation.swift:137:34:137:36 | .count | StringLengthConflation.swift:137:34:137:44 | ... .-(_:_:) ... | | StringLengthConflation.swift:138:36:138:38 | .count | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | | StringLengthConflation.swift:144:28:144:30 | .count | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | +| StringLengthConflation.swift:168:29:168:36 | .count | StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | +| StringLengthConflation.swift:169:29:169:37 | .count | StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | +| StringLengthConflation.swift:170:29:170:46 | .count | StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | +| StringLengthConflation.swift:171:29:171:32 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | +| StringLengthConflation.swift:172:29:172:33 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | +| StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | +| StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | +| StringLengthConflation.swift:176:35:176:52 | .count | StringLengthConflation.swift:176:35:176:60 | ... .-(_:_:) ... | +| StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | +| StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | +| StringLengthConflation.swift:180:37:180:44 | .count | StringLengthConflation.swift:180:37:180:52 | ... .-(_:_:) ... | +| StringLengthConflation.swift:182:37:182:45 | .count | StringLengthConflation.swift:182:37:182:53 | ... .-(_:_:) ... | | file://:0:0:0:0 | .length | StringLengthConflation.swift:53:43:53:46 | .length | | file://:0:0:0:0 | .length | StringLengthConflation.swift:60:47:60:50 | .length | | file://:0:0:0:0 | .length | StringLengthConflation.swift:66:33:66:36 | .length | @@ -27,6 +39,10 @@ edges | file://:0:0:0:0 | .length | StringLengthConflation.swift:108:25:108:28 | .length | | file://:0:0:0:0 | .length | StringLengthConflation.swift:114:23:114:26 | .length | | file://:0:0:0:0 | .length | StringLengthConflation.swift:120:22:120:25 | .length | +| file://:0:0:0:0 | .length | StringLengthConflation.swift:171:29:171:32 | .length | +| file://:0:0:0:0 | .length | StringLengthConflation.swift:172:29:172:33 | .length | +| file://:0:0:0:0 | .length | StringLengthConflation.swift:177:35:177:38 | .length | +| file://:0:0:0:0 | .length | StringLengthConflation.swift:178:35:178:39 | .length | nodes | StringLengthConflation2.swift:35:36:35:38 | .count | semmle.label | .count | | StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | @@ -76,6 +92,30 @@ nodes | StringLengthConflation.swift:151:45:151:53 | .count | semmle.label | .count | | StringLengthConflation.swift:156:45:156:52 | .count | semmle.label | .count | | StringLengthConflation.swift:161:45:161:53 | .count | semmle.label | .count | +| StringLengthConflation.swift:168:29:168:36 | .count | semmle.label | .count | +| StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:169:29:169:37 | .count | semmle.label | .count | +| StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:170:29:170:46 | .count | semmle.label | .count | +| StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:171:29:171:32 | .length | semmle.label | .length | +| StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:172:29:172:33 | .length | semmle.label | .length | +| StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:174:35:174:42 | .count | semmle.label | .count | +| StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:175:35:175:43 | .count | semmle.label | .count | +| StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:176:35:176:52 | .count | semmle.label | .count | +| StringLengthConflation.swift:176:35:176:60 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:177:35:177:38 | .length | semmle.label | .length | +| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:178:35:178:39 | .length | semmle.label | .length | +| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:180:37:180:44 | .count | semmle.label | .count | +| StringLengthConflation.swift:180:37:180:52 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:182:37:182:45 | .count | semmle.label | .count | +| StringLengthConflation.swift:182:37:182:53 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | file://:0:0:0:0 | .length | semmle.label | .length | subpaths #select @@ -117,3 +157,19 @@ subpaths | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | This String.utf8 length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | This String.utf16 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | StringLengthConflation.swift:168:29:168:36 | .count | StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | This String.utf8 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | StringLengthConflation.swift:169:29:169:37 | .count | StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | This String.utf16 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | StringLengthConflation.swift:170:29:170:46 | .count | StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | This String.unicodeScalars length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | StringLengthConflation.swift:171:29:171:32 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | StringLengthConflation.swift:172:29:172:33 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | This String.utf8 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | This String.utf16 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:176:35:176:60 | ... .-(_:_:) ... | StringLengthConflation.swift:176:35:176:52 | .count | StringLengthConflation.swift:176:35:176:60 | ... .-(_:_:) ... | This String.unicodeScalars length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:180:37:180:52 | ... .-(_:_:) ... | StringLengthConflation.swift:180:37:180:44 | .count | StringLengthConflation.swift:180:37:180:52 | ... .-(_:_:) ... | This String.utf8 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:182:37:182:53 | ... .-(_:_:) ... | StringLengthConflation.swift:182:37:182:45 | .count | StringLengthConflation.swift:182:37:182:53 | ... .-(_:_:) ... | This String.utf16 length is used in a String, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index 67b8feb657f..4d858ee669f 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -161,6 +161,25 @@ func test(s: String) { let _ = s.index(s.startIndex, offsetBy: s_utf16.count) // BAD let _ = s_utf16.index(s_utf16.startIndex, offsetBy: scalars.count) // GOOD let _ = s_utf16.index(s_utf16.startIndex, offsetBy: s.count) // BAD [NOT DETECTED] + + // --- methods provided by Sequence, Collection etc --- + + let _ = String(s.prefix(s.count - 10)) // GOOD + let _ = String(s.prefix(s.utf8.count - 10)) // BAD + let _ = String(s.prefix(s.utf16.count - 10)) // BAD + let _ = String(s.prefix(s.unicodeScalars.count - 10)) // BAD + let _ = String(s.prefix(ns.length - 10)) // BAD + let _ = String(s.prefix(nms.length - 10)) // BAD + let _ = String(scalars.prefix(s.count - 10)) // BAD [NOT DETECTED] + let _ = String(scalars.prefix(s.utf8.count - 10)) // BAD + let _ = String(scalars.prefix(s.utf16.count - 10)) // BAD + let _ = String(scalars.prefix(s.unicodeScalars.count - 10)) // GOOD [FALSE POSITIVE] + let _ = String(scalars.prefix(ns.length - 10)) // BAD + let _ = String(scalars.prefix(nms.length - 10)) // BAD + let _ = String(s.utf8.dropFirst(s.count - 10)) // BAD [NOT DETECTED] + let _ = String(s.utf8.dropFirst(s.utf8.count - 10)) // GOOD [FALSE POSITIVE] + let _ = String(s.utf16.dropLast(s.count - 10)) // BAD [NOT DETECTED] + let _ = String(s.utf16.dropLast(s.utf16.count - 10)) // GOOD [FALSE POSITIVE] } // `begin :thumbsup: end`, with thumbs up emoji and skin tone modifier From 2028b5ef958cba55eafc831c1e4d54ca8f3c53e7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 May 2023 17:24:50 +0100 Subject: [PATCH 063/739] Swift: Fix imprecise sinks. --- .../StringLengthConflationExtensions.qll | 57 ++++++++++++++++--- .../CWE-135/StringLengthConflation.expected | 36 ++++++------ .../CWE-135/StringLengthConflation.swift | 12 ++-- 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll index 560a332fc76..59fbe38a867 100644 --- a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll @@ -180,14 +180,6 @@ private class StringLengthConflationSinks extends SinkModelCsv { override predicate row(string row) { row = [ - ";Sequence;true;dropFirst(_:);;;Argument[0];string-length", - ";Sequence;true;dropLast(_:);;;Argument[0];string-length", - ";Sequence;true;prefix(_:);;;Argument[0];string-length", - ";Sequence;true;suffix(_:);;;Argument[0];string-length", - ";Collection;true;formIndex(_:offsetBy:);;;Argument[0..1];string-length", - ";Collection;true;formIndex(_:offsetBy:limitBy:);;;Argument[0..1];string-length", - ";Collection;true;removeFirst(_:);;;Argument[0];string-length", - ";RangeReplaceableCollection;true;removeLast(_:);;;Argument[0];string-length", ";String;true;index(_:offsetBy:);;;Argument[0..1];string-length", ";String;true;index(_:offsetBy:limitBy:);;;Argument[0..1];string-length", ";String.Index;true;init(encodedOffset:);;;Argument[0];string-length", @@ -203,3 +195,52 @@ private class StringLengthConflationSinks extends SinkModelCsv { ] } } + +/** + * An extra sink that don't fit into the CSV scheme (because we care about the actual + * type the method is being called on, not just the type it's declared on). + */ +private class ExtraStringLengthConflationSink extends StringLengthConflationSink { + StringType stringType; + + ExtraStringLengthConflationSink() { + exists(CallExpr call, string typeName | + ( + // `String` + typeName = "String" and + stringType = TString() + or + // `String.utf8` + typeName = "String.UTF8View" and + stringType = TStringUtf8() + or + // `String.utf16` + typeName = "String.UTF16View" and + stringType = TStringUtf16() + or + // `String.unicodeScalars` + typeName = "String.UnicodeScalarView" and + stringType = TStringUnicodeScalars() + ) and + // sink is a length or offset argument to [type].[method] + ( + call.getQualifier().getType().(NominalType).getName() = typeName or + call.getQualifier().getType().(InOutType).getObjectType().(NominalType).getName() = typeName + ) and + ( + call.getStaticTarget().getName() = + [ + "dropFirst(_:)", "dropLast(_:)", "prefix(_:)", "suffix(_:)", "removeFirst(_:)", + "removeLast(_:)" + ] and + this.asExpr() = call.getArgument(0).getExpr() + or + call.getStaticTarget().getName() = + ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and + this.asExpr() = call.getArgument([0, 1]).getExpr() + ) + ) + } + + override StringType getCorrectStringType() { result = stringType } +} diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index ffae88451e2..69e72385ddb 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -23,13 +23,13 @@ edges | StringLengthConflation.swift:170:29:170:46 | .count | StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | | StringLengthConflation.swift:171:29:171:32 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | | StringLengthConflation.swift:172:29:172:33 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | +| StringLengthConflation.swift:173:35:173:37 | .count | StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | | StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | | StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | -| StringLengthConflation.swift:176:35:176:52 | .count | StringLengthConflation.swift:176:35:176:60 | ... .-(_:_:) ... | | StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | | StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | -| StringLengthConflation.swift:180:37:180:44 | .count | StringLengthConflation.swift:180:37:180:52 | ... .-(_:_:) ... | -| StringLengthConflation.swift:182:37:182:45 | .count | StringLengthConflation.swift:182:37:182:53 | ... .-(_:_:) ... | +| StringLengthConflation.swift:179:37:179:39 | .count | StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | +| StringLengthConflation.swift:181:37:181:39 | .count | StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | | file://:0:0:0:0 | .length | StringLengthConflation.swift:53:43:53:46 | .length | | file://:0:0:0:0 | .length | StringLengthConflation.swift:60:47:60:50 | .length | | file://:0:0:0:0 | .length | StringLengthConflation.swift:66:33:66:36 | .length | @@ -102,20 +102,20 @@ nodes | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:172:29:172:33 | .length | semmle.label | .length | | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:173:35:173:37 | .count | semmle.label | .count | +| StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:174:35:174:42 | .count | semmle.label | .count | | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:175:35:175:43 | .count | semmle.label | .count | | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | -| StringLengthConflation.swift:176:35:176:52 | .count | semmle.label | .count | -| StringLengthConflation.swift:176:35:176:60 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:177:35:177:38 | .length | semmle.label | .length | | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:178:35:178:39 | .length | semmle.label | .length | | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | -| StringLengthConflation.swift:180:37:180:44 | .count | semmle.label | .count | -| StringLengthConflation.swift:180:37:180:52 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | -| StringLengthConflation.swift:182:37:182:45 | .count | semmle.label | .count | -| StringLengthConflation.swift:182:37:182:53 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:179:37:179:39 | .count | semmle.label | .count | +| StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:181:37:181:39 | .count | semmle.label | .count | +| StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | file://:0:0:0:0 | .length | semmle.label | .length | subpaths #select @@ -164,12 +164,12 @@ subpaths | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | StringLengthConflation.swift:172:29:172:33 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | This String.utf8 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | This String.utf16 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:176:35:176:60 | ... .-(_:_:) ... | StringLengthConflation.swift:176:35:176:52 | .count | StringLengthConflation.swift:176:35:176:60 | ... .-(_:_:) ... | This String.unicodeScalars length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:180:37:180:52 | ... .-(_:_:) ... | StringLengthConflation.swift:180:37:180:44 | .count | StringLengthConflation.swift:180:37:180:52 | ... .-(_:_:) ... | This String.utf8 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:182:37:182:53 | ... .-(_:_:) ... | StringLengthConflation.swift:182:37:182:45 | .count | StringLengthConflation.swift:182:37:182:53 | ... .-(_:_:) ... | This String.utf16 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | StringLengthConflation.swift:173:35:173:37 | .count | StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | This String length is used in a String.unicodeScalars, but it may not be equivalent. | +| StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | This String.utf8 length is used in a String.unicodeScalars, but it may not be equivalent. | +| StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | This String.utf16 length is used in a String.unicodeScalars, but it may not be equivalent. | +| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String.unicodeScalars, but it may not be equivalent. | +| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String.unicodeScalars, but it may not be equivalent. | +| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String.unicodeScalars, but it may not be equivalent. | +| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String.unicodeScalars, but it may not be equivalent. | +| StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | StringLengthConflation.swift:179:37:179:39 | .count | StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | This String length is used in a String.utf8, but it may not be equivalent. | +| StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | StringLengthConflation.swift:181:37:181:39 | .count | StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | This String length is used in a String.utf16, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index 4d858ee669f..c707b81fe35 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -170,16 +170,16 @@ func test(s: String) { let _ = String(s.prefix(s.unicodeScalars.count - 10)) // BAD let _ = String(s.prefix(ns.length - 10)) // BAD let _ = String(s.prefix(nms.length - 10)) // BAD - let _ = String(scalars.prefix(s.count - 10)) // BAD [NOT DETECTED] + let _ = String(scalars.prefix(s.count - 10)) // BAD let _ = String(scalars.prefix(s.utf8.count - 10)) // BAD let _ = String(scalars.prefix(s.utf16.count - 10)) // BAD - let _ = String(scalars.prefix(s.unicodeScalars.count - 10)) // GOOD [FALSE POSITIVE] + let _ = String(scalars.prefix(s.unicodeScalars.count - 10)) // GOOD let _ = String(scalars.prefix(ns.length - 10)) // BAD let _ = String(scalars.prefix(nms.length - 10)) // BAD - let _ = String(s.utf8.dropFirst(s.count - 10)) // BAD [NOT DETECTED] - let _ = String(s.utf8.dropFirst(s.utf8.count - 10)) // GOOD [FALSE POSITIVE] - let _ = String(s.utf16.dropLast(s.count - 10)) // BAD [NOT DETECTED] - let _ = String(s.utf16.dropLast(s.utf16.count - 10)) // GOOD [FALSE POSITIVE] + let _ = String(s.utf8.dropFirst(s.count - 10)) // BAD + let _ = String(s.utf8.dropFirst(s.utf8.count - 10)) // GOOD + let _ = String(s.utf16.dropLast(s.count - 10)) // BAD + let _ = String(s.utf16.dropLast(s.utf16.count - 10)) // GOOD } // `begin :thumbsup: end`, with thumbs up emoji and skin tone modifier From b6122d01fcd8c770e7a924d08177ecdc6176f878 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 May 2023 22:30:38 +0100 Subject: [PATCH 064/739] Swift: Clean up the query somewhat. --- .../StringLengthConflationExtensions.qll | 49 +++++++++---------- .../CWE-135/StringLengthConflation.expected | 40 +++++++-------- 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll index 59fbe38a867..efc8eeefe35 100644 --- a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll @@ -38,27 +38,34 @@ class StringType extends TStringType { csvLabel = "nsstring-length" or this = TStringUtf8() and - name = "String.utf8" and - singular = "a String.utf8" and + name = "String.UTF8View" and + singular = "a String.UTF8View" and equivClass = this and csvLabel = "string-utf8-length" or this = TStringUtf16() and - name = "String.utf16" and - singular = "a String.utf16" and + name = "String.UTF16View" and + singular = "a String.UTF16View" and equivClass = TNsString() and csvLabel = "string-utf16-length" or this = TStringUnicodeScalars() and - name = "String.unicodeScalars" and - singular = "a String.unicodeScalars" and + name = "String.UnicodeScalarView" and + singular = "a String.UnicodeScalarView" and equivClass = this and csvLabel = "string-unicodescalars-length" } - /** Gets a textual representation of this string type. */ + /** + * Gets a textual representation of this string type. + */ string toString() { result = name } + /** + * Gets the name of this string type. + */ + string getName() { result = name } + /** * Gets the equivalence class for this string type. If these are equal, * they should be treated as equivalent. @@ -142,21 +149,16 @@ private class ExtraStringLengthConflationSource extends StringLengthConflationSo StringType stringType; ExtraStringLengthConflationSource() { - exists(MemberRefExpr memberRef, string typeName | + // source is the result of a call to `[stringType].count`. + exists(MemberRefExpr memberRef | ( - // result of a call to `String.utf8.count` - typeName = "String.UTF8View" and stringType = TStringUtf8() or - // result of a call to `String.utf16.count` - typeName = "String.UTF16View" and stringType = TStringUtf16() or - // result of a call to `String.unicodeScalars.count` - typeName = "String.UnicodeScalarView" and stringType = TStringUnicodeScalars() ) and - memberRef.getBase().getType().(NominalType).getName() = typeName and + memberRef.getBase().getType().(NominalType).getName() = stringType.getName() and memberRef.getMember().(VarDecl).getName() = "count" and this.asExpr() = memberRef ) @@ -204,28 +206,21 @@ private class ExtraStringLengthConflationSink extends StringLengthConflationSink StringType stringType; ExtraStringLengthConflationSink() { - exists(CallExpr call, string typeName | + // sink is a length or offset argument of a call to `[stringType].[method]`. + exists(CallExpr call | ( - // `String` - typeName = "String" and stringType = TString() or - // `String.utf8` - typeName = "String.UTF8View" and stringType = TStringUtf8() or - // `String.utf16` - typeName = "String.UTF16View" and stringType = TStringUtf16() or - // `String.unicodeScalars` - typeName = "String.UnicodeScalarView" and stringType = TStringUnicodeScalars() ) and - // sink is a length or offset argument to [type].[method] ( - call.getQualifier().getType().(NominalType).getName() = typeName or - call.getQualifier().getType().(InOutType).getObjectType().(NominalType).getName() = typeName + call.getQualifier().getType().(NominalType).getName() = stringType.getName() or + call.getQualifier().getType().(InOutType).getObjectType().(NominalType).getName() = + stringType.getName() ) and ( call.getStaticTarget().getName() = diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 69e72385ddb..909c6233ba5 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -124,17 +124,17 @@ subpaths | StringLengthConflation.swift:36:93:36:93 | len | StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:36:93:36:93 | len | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:53:43:53:46 | .length | file://:0:0:0:0 | .length | StringLengthConflation.swift:53:43:53:46 | .length | This NSString length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | This String.utf8 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | This String.utf16 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | This String.UTF8View length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | This String.UTF16View length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | This String.UnicodeScalarView length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | StringLengthConflation.swift:60:47:60:50 | .length | StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:66:33:66:45 | ... ./(_:_:) ... | StringLengthConflation.swift:66:33:66:36 | .length | StringLengthConflation.swift:66:33:66:45 | ... ./(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:66:33:66:45 | ... ./(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:66:33:66:45 | ... ./(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:72:33:72:35 | .count | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:78:47:78:49 | .count | StringLengthConflation.swift:78:47:78:49 | .count | StringLengthConflation.swift:78:47:78:49 | .count | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | This String.utf8 length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | This String.unicodeScalars length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | This String.UTF8View length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | This String.UnicodeScalarView length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:96:28:96:40 | ... .-(_:_:) ... | StringLengthConflation.swift:96:28:96:31 | .length | StringLengthConflation.swift:96:28:96:40 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:96:28:96:40 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:96:28:96:40 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:100:27:100:39 | ... .-(_:_:) ... | StringLengthConflation.swift:100:27:100:30 | .length | StringLengthConflation.swift:100:27:100:39 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | @@ -154,22 +154,22 @@ subpaths | StringLengthConflation.swift:137:34:137:44 | ... .-(_:_:) ... | StringLengthConflation.swift:137:34:137:36 | .count | StringLengthConflation.swift:137:34:137:44 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | StringLengthConflation.swift:138:36:138:38 | .count | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | StringLengthConflation.swift:144:28:144:30 | .count | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | This String.utf8 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | This String.utf16 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | StringLengthConflation.swift:168:29:168:36 | .count | StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | This String.utf8 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | StringLengthConflation.swift:169:29:169:37 | .count | StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | This String.utf16 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | StringLengthConflation.swift:170:29:170:46 | .count | StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | This String.unicodeScalars length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | This String.UnicodeScalarView length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | This String.UTF8View length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | This String.UTF16View length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | StringLengthConflation.swift:168:29:168:36 | .count | StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | This String.UTF8View length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | StringLengthConflation.swift:169:29:169:37 | .count | StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | This String.UTF16View length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | StringLengthConflation.swift:170:29:170:46 | .count | StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | This String.UnicodeScalarView length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | StringLengthConflation.swift:171:29:171:32 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | StringLengthConflation.swift:172:29:172:33 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | StringLengthConflation.swift:173:35:173:37 | .count | StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | This String length is used in a String.unicodeScalars, but it may not be equivalent. | -| StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | This String.utf8 length is used in a String.unicodeScalars, but it may not be equivalent. | -| StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | This String.utf16 length is used in a String.unicodeScalars, but it may not be equivalent. | -| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String.unicodeScalars, but it may not be equivalent. | -| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String.unicodeScalars, but it may not be equivalent. | -| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String.unicodeScalars, but it may not be equivalent. | -| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String.unicodeScalars, but it may not be equivalent. | -| StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | StringLengthConflation.swift:179:37:179:39 | .count | StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | This String length is used in a String.utf8, but it may not be equivalent. | -| StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | StringLengthConflation.swift:181:37:181:39 | .count | StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | This String length is used in a String.utf16, but it may not be equivalent. | +| StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | StringLengthConflation.swift:173:35:173:37 | .count | StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | This String length is used in a String.UnicodeScalarView, but it may not be equivalent. | +| StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | This String.UTF8View length is used in a String.UnicodeScalarView, but it may not be equivalent. | +| StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | This String.UTF16View length is used in a String.UnicodeScalarView, but it may not be equivalent. | +| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String.UnicodeScalarView, but it may not be equivalent. | +| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String.UnicodeScalarView, but it may not be equivalent. | +| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String.UnicodeScalarView, but it may not be equivalent. | +| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String.UnicodeScalarView, but it may not be equivalent. | +| StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | StringLengthConflation.swift:179:37:179:39 | .count | StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | This String length is used in a String.UTF8View, but it may not be equivalent. | +| StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | StringLengthConflation.swift:181:37:181:39 | .count | StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | This String length is used in a String.UTF16View, but it may not be equivalent. | From 708a99528fcf41c2e4743b2e4fcbdc3f25c2308e Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 22 May 2023 10:11:32 +0200 Subject: [PATCH 065/739] initial implementation of TS 5.1 --- docs/codeql/reusables/supported-versions-compilers.rst | 2 +- javascript/extractor/lib/typescript/package.json | 2 +- javascript/extractor/lib/typescript/src/main.ts | 1 - javascript/extractor/lib/typescript/yarn.lock | 8 ++++---- .../extractor/src/com/semmle/js/extractor/Main.java | 2 +- .../ql/lib/change-notes/2023-04-19-typescript-5-1.md | 4 ++++ 6 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 javascript/ql/lib/change-notes/2023-04-19-typescript-5-1.md diff --git a/docs/codeql/reusables/supported-versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst index 93b826a94dd..1ac892c01c2 100644 --- a/docs/codeql/reusables/supported-versions-compilers.rst +++ b/docs/codeql/reusables/supported-versions-compilers.rst @@ -25,7 +25,7 @@ Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11",Not applicable,``.py`` Ruby [9]_,"up to 3.2",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``" Swift [10]_,"Swift 5.4-5.7","Swift compiler","``.swift``" - TypeScript [11]_,"2.6-5.0",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``" + TypeScript [11]_,"2.6-5.1",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``" .. container:: footnote-group diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index 0c8de4f1bbc..cb053bb0e6f 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "5.0.2" + "typescript": "5.1.1-rc" }, "scripts": { "build": "tsc --project tsconfig.json", diff --git a/javascript/extractor/lib/typescript/src/main.ts b/javascript/extractor/lib/typescript/src/main.ts index 2e9f26b6953..2594f4e35f5 100644 --- a/javascript/extractor/lib/typescript/src/main.ts +++ b/javascript/extractor/lib/typescript/src/main.ts @@ -579,7 +579,6 @@ function handleOpenProjectCommand(command: OpenProjectCommand) { // inverse mapping, nor a way to enumerate all known module names. So we discover all // modules on the type roots (usually "node_modules/@types" but this is configurable). let typeRoots = ts.getEffectiveTypeRoots(config.options, { - directoryExists: (path) => ts.sys.directoryExists(path), getCurrentDirectory: () => basePath, }); diff --git a/javascript/extractor/lib/typescript/yarn.lock b/javascript/extractor/lib/typescript/yarn.lock index 88d32ae6b3a..3b0a9476df6 100644 --- a/javascript/extractor/lib/typescript/yarn.lock +++ b/javascript/extractor/lib/typescript/yarn.lock @@ -7,7 +7,7 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.3.tgz#f0b991c32cfc6a4e7f3399d6cb4b8cf9a0315014" integrity sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw== -typescript@5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.2.tgz#891e1a90c5189d8506af64b9ef929fca99ba1ee5" - integrity sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw== +typescript@5.1.1-rc: + version "5.1.1-rc" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.1-rc.tgz#7be6e85bb4ad36e07e0125e501eb08ed3a6e3769" + integrity sha512-+yHTPe5QCxw5cgN+B81z+k65xTHcwNCRwJN7OGVUe3srPULTZHF7J9QCgrptL7F8mrO7gmsert7XrMksAjutRw== diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java index 4f8bb2c1ced..2a188676924 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/Main.java +++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java @@ -41,7 +41,7 @@ public class Main { * A version identifier that should be updated every time the extractor changes in such a way that * it may produce different tuples for the same file under the same {@link ExtractorConfig}. */ - public static final String EXTRACTOR_VERSION = "2023-03-16"; + public static final String EXTRACTOR_VERSION = "2023-04-19"; public static final Pattern NEWLINE = Pattern.compile("\n"); diff --git a/javascript/ql/lib/change-notes/2023-04-19-typescript-5-1.md b/javascript/ql/lib/change-notes/2023-04-19-typescript-5-1.md new file mode 100644 index 00000000000..7260bd3d389 --- /dev/null +++ b/javascript/ql/lib/change-notes/2023-04-19-typescript-5-1.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* Added support for TypeScript 5.1. \ No newline at end of file From 9a0f87434e30473d3d669833fc910c957d42db09 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 22 May 2023 15:10:51 +0200 Subject: [PATCH 066/739] Swift: remove unneeded properties from `InterpolatedStringLiteralExpr` These properties were unused in the QL library (hence the full upgrade/downgrade compatibility). --- .../old.dbscheme | 2618 ++++++++++++++++ .../swift.dbscheme | 2630 +++++++++++++++++ .../upgrade.properties | 2 + .../extractor/translators/ExprTranslator.cpp | 4 - swift/ql/.generated.list | 6 +- .../codeql/swift/generated/ParentChild.qll | 17 +- swift/ql/lib/codeql/swift/generated/Raw.qll | 14 - .../expr/InterpolatedStringLiteralExpr.qll | 57 - swift/ql/lib/swift.dbscheme | 12 - .../integer_literal_exprs.ql | 13 + .../old.dbscheme | 2630 +++++++++++++++++ .../swift.dbscheme | 2618 ++++++++++++++++ .../upgrade.properties | 5 + .../test/library-tests/ast/PrintAst.expected | 6 - swift/schema.py | 2 - 15 files changed, 10521 insertions(+), 113 deletions(-) create mode 100644 swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/old.dbscheme create mode 100644 swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/swift.dbscheme create mode 100644 swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties create mode 100644 swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/integer_literal_exprs.ql create mode 100644 swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/old.dbscheme create mode 100644 swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/swift.dbscheme create mode 100644 swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/upgrade.properties diff --git a/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/old.dbscheme b/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/old.dbscheme new file mode 100644 index 00000000000..44e36e15e90 --- /dev/null +++ b/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/old.dbscheme @@ -0,0 +1,2618 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @key_path_component +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +key_path_components( + unique int id: @key_path_component, + int kind: int ref, + int component_type: @type_or_none ref +); + +#keyset[id, index] +key_path_component_subscript_arguments( + int id: @key_path_component ref, + int index: int ref, + int subscript_argument: @argument_or_none ref +); + +#keyset[id] +key_path_component_tuple_indices( + int id: @key_path_component ref, + int tuple_index: int ref +); + +#keyset[id] +key_path_component_decl_refs( + int id: @key_path_component ref, + int decl_ref: @value_decl_or_none ref +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @extension_decl +| @function +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_storage_decl +| @enum_element_decl +| @function +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessors( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor: @accessor_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@function = + @accessor_or_named_function +| @deinitializer +| @initializer +; + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +@accessor_or_named_function = + @accessor +| @named_function +; + +deinitializers( //dir=decl + unique int id: @deinitializer +); + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +initializers( //dir=decl + unique int id: @initializer +); + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessors( //dir=decl + unique int id: @accessor +); + +#keyset[id] +accessor_is_getter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_setter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_will_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_did_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_read( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_modify( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_address( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_mutable_address( //dir=decl + int id: @accessor ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +named_functions( //dir=decl + unique int id: @named_function +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @closure_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initialization_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_initializer_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_initializer_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @explicit_closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@closure_expr = + @auto_closure_expr +| @explicit_closure_expr +; + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id, index] +key_path_expr_components( //dir=expr + int id: @key_path_expr ref, + int index: int ref, + int component: @key_path_component_or_none ref +); + +lazy_initialization_exprs( //dir=expr + unique int id: @lazy_initialization_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @function_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_initializer_ref_exprs( //dir=expr + unique int id: @other_initializer_ref_expr, + int initializer: @initializer_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_initializer_exprs( //dir=expr + unique int id: @rebind_self_in_initializer_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +explicit_closure_exprs( //dir=expr + unique int id: @explicit_closure_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @dot_syntax_call_expr +| @initializer_ref_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +initializer_ref_call_exprs( //dir=expr + unique int id: @initializer_ref_call_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@accessor_or_none = + @accessor +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@explicit_closure_expr_or_none = + @explicit_closure_expr +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@function_or_none = + @function +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@initializer_or_none = + @initializer +| @unspecified_element +; + +@key_path_component_or_none = + @key_path_component +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/swift.dbscheme b/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/swift.dbscheme new file mode 100644 index 00000000000..ba4171b90d0 --- /dev/null +++ b/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/swift.dbscheme @@ -0,0 +1,2630 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @key_path_component +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +key_path_components( + unique int id: @key_path_component, + int kind: int ref, + int component_type: @type_or_none ref +); + +#keyset[id, index] +key_path_component_subscript_arguments( + int id: @key_path_component ref, + int index: int ref, + int subscript_argument: @argument_or_none ref +); + +#keyset[id] +key_path_component_tuple_indices( + int id: @key_path_component ref, + int tuple_index: int ref +); + +#keyset[id] +key_path_component_decl_refs( + int id: @key_path_component ref, + int decl_ref: @value_decl_or_none ref +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @extension_decl +| @function +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_storage_decl +| @enum_element_decl +| @function +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessors( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor: @accessor_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@function = + @accessor_or_named_function +| @deinitializer +| @initializer +; + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +@accessor_or_named_function = + @accessor +| @named_function +; + +deinitializers( //dir=decl + unique int id: @deinitializer +); + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +initializers( //dir=decl + unique int id: @initializer +); + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessors( //dir=decl + unique int id: @accessor +); + +#keyset[id] +accessor_is_getter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_setter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_will_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_did_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_read( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_modify( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_address( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_mutable_address( //dir=decl + int id: @accessor ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +named_functions( //dir=decl + unique int id: @named_function +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @closure_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initialization_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_initializer_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_initializer_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @explicit_closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@closure_expr = + @auto_closure_expr +| @explicit_closure_expr +; + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id, index] +key_path_expr_components( //dir=expr + int id: @key_path_expr ref, + int index: int ref, + int component: @key_path_component_or_none ref +); + +lazy_initialization_exprs( //dir=expr + unique int id: @lazy_initialization_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @function_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_initializer_ref_exprs( //dir=expr + unique int id: @other_initializer_ref_expr, + int initializer: @initializer_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_initializer_exprs( //dir=expr + unique int id: @rebind_self_in_initializer_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +explicit_closure_exprs( //dir=expr + unique int id: @explicit_closure_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @dot_syntax_call_expr +| @initializer_ref_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +initializer_ref_call_exprs( //dir=expr + unique int id: @initializer_ref_call_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@accessor_or_none = + @accessor +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@explicit_closure_expr_or_none = + @explicit_closure_expr +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@function_or_none = + @function +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@initializer_or_none = + @initializer +| @unspecified_element +; + +@key_path_component_or_none = + @key_path_component +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties b/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties new file mode 100644 index 00000000000..2a0d022be0c --- /dev/null +++ b/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties @@ -0,0 +1,2 @@ +description: Revert removing `getInterpolationCountExpr` and `getLiteralCapacityExpr` from `InterpolatedStringLiteralExpr` +compatibility: full diff --git a/swift/extractor/translators/ExprTranslator.cpp b/swift/extractor/translators/ExprTranslator.cpp index 9c24dfb823b..6939415913b 100644 --- a/swift/extractor/translators/ExprTranslator.cpp +++ b/swift/extractor/translators/ExprTranslator.cpp @@ -61,10 +61,6 @@ codeql::InterpolatedStringLiteralExpr ExprTranslator::translateInterpolatedStrin const swift::InterpolatedStringLiteralExpr& expr) { auto entry = createExprEntry(expr); entry.interpolation_expr = dispatcher.fetchOptionalLabel(expr.getInterpolationExpr()); - // TODO we should be extracting getInterpolationCount and getLiteralCapacity directly to ints - // these expressions here are just an internal thing, the ints are actually directly available - entry.interpolation_count_expr = dispatcher.fetchOptionalLabel(expr.getInterpolationCountExpr()); - entry.literal_capacity_expr = dispatcher.fetchOptionalLabel(expr.getLiteralCapacityExpr()); entry.appending_expr = dispatcher.fetchOptionalLabel(expr.getAppendingExpr()); return entry; } diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index a28e6ba533b..d43696f7c23 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -381,10 +381,10 @@ lib/codeql/swift/generated/KeyPathComponent.qll 00b1e586b8532f0193b3f61111e70d4e lib/codeql/swift/generated/Locatable.qll bfdf2dafae2829cac8d1e863a93676228d131b5a7f3df87c40d2f3b1839962b8 af243098af0955a40862387edf7526826fde62a64e5e6ca28de9e9603a8622bf lib/codeql/swift/generated/Location.qll 921922352d39449067d9f2788309b5f3490091097ffe35e6aa98f9368626ce2c 0795c63565c4308e745400bc70ea73675160201590a95bb418de4e2ebca32764 lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 -lib/codeql/swift/generated/ParentChild.qll f490202e849b9cbd550ee9d758644b85d43e60d81413e6c28df2850fb1e9a2d6 6b95aeab6b53a880b230ad0c96b6deb519a7368898c844632ae96090de59df99 +lib/codeql/swift/generated/ParentChild.qll 3808a52565a4abb8ce878fb4aad09e8fb0e860d6379bb86897d0e0282389919c 408c7e6332dccfc98398f04ecbd54af8e0754d466ad7ca4d404b029c7f5bde49 lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 8d4880e5ee1fdd120adeb7bf0dfa1399e7b1a53b2cc7598aed8e15cbf996d1c0 da0d446347d29f5cd05281c17c24e87610f31c32adb7e05ab8f3a26bed55bd90 +lib/codeql/swift/generated/Raw.qll 062d062fada3e3f1b6af04cda724f8204de6b66bbca53d233e9b4d96df7a5c99 3c1e70b5ec4c576c92979b04d6d3ee59159b050c16c47f93463cba28f40ca906 lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -498,7 +498,7 @@ lib/codeql/swift/generated/expr/InOutToPointerExpr.qll 4b9ceffe43f192fac0c428d66 lib/codeql/swift/generated/expr/InitializerRefCallExpr.qll 4556d49d78566ad70a5e784a6db4897dc78ef1f30e67f0052dbb070eca8350f0 4556d49d78566ad70a5e784a6db4897dc78ef1f30e67f0052dbb070eca8350f0 lib/codeql/swift/generated/expr/InjectIntoOptionalExpr.qll b6fafb589901d73e94eb9bb0f5e87b54378d06ccc04c51a9f4c8003d1f23ead6 b6fafb589901d73e94eb9bb0f5e87b54378d06ccc04c51a9f4c8003d1f23ead6 lib/codeql/swift/generated/expr/IntegerLiteralExpr.qll aa54660c47169a35e396ea44430c3c4ec4353e33df1a00bd82aff7119f5af71b 7ba90cf17dd34080a9923253986b0f2680b44c4a4ba6e0fbad8b39d3b20c44b9 -lib/codeql/swift/generated/expr/InterpolatedStringLiteralExpr.qll e2c1aadf140c808a615bdc8732a154f6c1f8b79168779e1ba48753506fbd9516 5e9f20ee16b133269de6874c6776611b6f4eaec202a0e6a955a572c2a082ac40 +lib/codeql/swift/generated/expr/InterpolatedStringLiteralExpr.qll 8090616e43d79e03c2250352da722f577c4b6531befe40f2d2910db0db3895bc ba09ffbbe3557e6fc6a3219d656e5ce886d70117eea15334cf910825f2250e6e lib/codeql/swift/generated/expr/IsExpr.qll b5ca50490cae8ac590b68a1a51b7039a54280d606b42c444808a04fa26c7e1b6 b5ca50490cae8ac590b68a1a51b7039a54280d606b42c444808a04fa26c7e1b6 lib/codeql/swift/generated/expr/KeyPathApplicationExpr.qll 157a9c2fcf229b76d104abfa49f74337e20ac4d1fa1be2eaed1290cbd9bd1232 70ec0e7ee2e2c716ba510916fdf6d1d6dd6fd93b740a46c909ddb9e877427fe1 lib/codeql/swift/generated/expr/KeyPathDotExpr.qll ea73a462801fbe5e27b2f47bca4b39f6936d326d15d6de3f18b7afa6ace35878 ea73a462801fbe5e27b2f47bca4b39f6936d326d15d6de3f18b7afa6ace35878 diff --git a/swift/ql/lib/codeql/swift/generated/ParentChild.qll b/swift/ql/lib/codeql/swift/generated/ParentChild.qll index 09c48606353..7b8c9313e56 100644 --- a/swift/ql/lib/codeql/swift/generated/ParentChild.qll +++ b/swift/ql/lib/codeql/swift/generated/ParentChild.qll @@ -2515,31 +2515,18 @@ private module Impl { private Element getImmediateChildOfInterpolatedStringLiteralExpr( InterpolatedStringLiteralExpr e, int index, string partialPredicateCall ) { - exists( - int b, int bLiteralExpr, int n, int nInterpolationCountExpr, int nLiteralCapacityExpr, - int nAppendingExpr - | + exists(int b, int bLiteralExpr, int n, int nAppendingExpr | b = 0 and bLiteralExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLiteralExpr(e, i, _)) | i) and n = bLiteralExpr and - nInterpolationCountExpr = n + 1 and - nLiteralCapacityExpr = nInterpolationCountExpr + 1 and - nAppendingExpr = nLiteralCapacityExpr + 1 and + nAppendingExpr = n + 1 and ( none() or result = getImmediateChildOfLiteralExpr(e, index - b, partialPredicateCall) or index = n and - result = e.getImmediateInterpolationCountExpr() and - partialPredicateCall = "InterpolationCountExpr()" - or - index = nInterpolationCountExpr and - result = e.getImmediateLiteralCapacityExpr() and - partialPredicateCall = "LiteralCapacityExpr()" - or - index = nLiteralCapacityExpr and result = e.getImmediateAppendingExpr() and partialPredicateCall = "AppendingExpr()" ) diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index dc5ddeed979..f9a967867aa 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -1961,20 +1961,6 @@ module Raw { interpolated_string_literal_expr_interpolation_exprs(this, result) } - /** - * Gets the interpolation count expression of this interpolated string literal expression, if it exists. - */ - Expr getInterpolationCountExpr() { - interpolated_string_literal_expr_interpolation_count_exprs(this, result) - } - - /** - * Gets the literal capacity expression of this interpolated string literal expression, if it exists. - */ - Expr getLiteralCapacityExpr() { - interpolated_string_literal_expr_literal_capacity_exprs(this, result) - } - /** * Gets the appending expression of this interpolated string literal expression, if it exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/InterpolatedStringLiteralExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/InterpolatedStringLiteralExpr.qll index c7f67891199..abdcf4a1850 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/InterpolatedStringLiteralExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/InterpolatedStringLiteralExpr.qll @@ -1,7 +1,6 @@ // generated by codegen/codegen.py private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw -import codeql.swift.elements.expr.Expr import codeql.swift.elements.expr.LiteralExpr import codeql.swift.elements.expr.OpaqueValueExpr import codeql.swift.elements.expr.TapExpr @@ -38,62 +37,6 @@ module Generated { */ final predicate hasInterpolationExpr() { exists(this.getInterpolationExpr()) } - /** - * Gets the interpolation count expression of this interpolated string literal expression, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. - */ - Expr getImmediateInterpolationCountExpr() { - result = - Synth::convertExprFromRaw(Synth::convertInterpolatedStringLiteralExprToRaw(this) - .(Raw::InterpolatedStringLiteralExpr) - .getInterpolationCountExpr()) - } - - /** - * Gets the interpolation count expression of this interpolated string literal expression, if it exists. - */ - final Expr getInterpolationCountExpr() { - exists(Expr immediate | - immediate = this.getImmediateInterpolationCountExpr() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - - /** - * Holds if `getInterpolationCountExpr()` exists. - */ - final predicate hasInterpolationCountExpr() { exists(this.getInterpolationCountExpr()) } - - /** - * Gets the literal capacity expression of this interpolated string literal expression, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. - */ - Expr getImmediateLiteralCapacityExpr() { - result = - Synth::convertExprFromRaw(Synth::convertInterpolatedStringLiteralExprToRaw(this) - .(Raw::InterpolatedStringLiteralExpr) - .getLiteralCapacityExpr()) - } - - /** - * Gets the literal capacity expression of this interpolated string literal expression, if it exists. - */ - final Expr getLiteralCapacityExpr() { - exists(Expr immediate | - immediate = this.getImmediateLiteralCapacityExpr() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - - /** - * Holds if `getLiteralCapacityExpr()` exists. - */ - final predicate hasLiteralCapacityExpr() { exists(this.getLiteralCapacityExpr()) } - /** * Gets the appending expression of this interpolated string literal expression, if it exists. * diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index ba4171b90d0..44e36e15e90 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -1382,18 +1382,6 @@ interpolated_string_literal_expr_interpolation_exprs( //dir=expr int interpolation_expr: @opaque_value_expr_or_none ref ); -#keyset[id] -interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr - int id: @interpolated_string_literal_expr ref, - int interpolation_count_expr: @expr_or_none ref -); - -#keyset[id] -interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr - int id: @interpolated_string_literal_expr ref, - int literal_capacity_expr: @expr_or_none ref -); - #keyset[id] interpolated_string_literal_expr_appending_exprs( //dir=expr int id: @interpolated_string_literal_expr ref, diff --git a/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/integer_literal_exprs.ql b/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/integer_literal_exprs.ql new file mode 100644 index 00000000000..fc9d93c02b6 --- /dev/null +++ b/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/integer_literal_exprs.ql @@ -0,0 +1,13 @@ +class Element extends @element { + string toString() { none() } +} + +from Element i, string value +where + integer_literal_exprs(i, value) and + not exists(Element interpolated | + interpolated_string_literal_expr_interpolation_count_exprs(interpolated, i) + or + interpolated_string_literal_expr_literal_capacity_exprs(interpolated, i) + ) +select i, value diff --git a/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/old.dbscheme b/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/old.dbscheme new file mode 100644 index 00000000000..ba4171b90d0 --- /dev/null +++ b/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/old.dbscheme @@ -0,0 +1,2630 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @key_path_component +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +key_path_components( + unique int id: @key_path_component, + int kind: int ref, + int component_type: @type_or_none ref +); + +#keyset[id, index] +key_path_component_subscript_arguments( + int id: @key_path_component ref, + int index: int ref, + int subscript_argument: @argument_or_none ref +); + +#keyset[id] +key_path_component_tuple_indices( + int id: @key_path_component ref, + int tuple_index: int ref +); + +#keyset[id] +key_path_component_decl_refs( + int id: @key_path_component ref, + int decl_ref: @value_decl_or_none ref +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @extension_decl +| @function +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_storage_decl +| @enum_element_decl +| @function +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessors( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor: @accessor_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@function = + @accessor_or_named_function +| @deinitializer +| @initializer +; + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +@accessor_or_named_function = + @accessor +| @named_function +; + +deinitializers( //dir=decl + unique int id: @deinitializer +); + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +initializers( //dir=decl + unique int id: @initializer +); + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessors( //dir=decl + unique int id: @accessor +); + +#keyset[id] +accessor_is_getter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_setter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_will_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_did_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_read( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_modify( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_address( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_mutable_address( //dir=decl + int id: @accessor ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +named_functions( //dir=decl + unique int id: @named_function +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @closure_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initialization_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_initializer_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_initializer_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @explicit_closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@closure_expr = + @auto_closure_expr +| @explicit_closure_expr +; + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id, index] +key_path_expr_components( //dir=expr + int id: @key_path_expr ref, + int index: int ref, + int component: @key_path_component_or_none ref +); + +lazy_initialization_exprs( //dir=expr + unique int id: @lazy_initialization_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @function_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_initializer_ref_exprs( //dir=expr + unique int id: @other_initializer_ref_expr, + int initializer: @initializer_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_initializer_exprs( //dir=expr + unique int id: @rebind_self_in_initializer_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +explicit_closure_exprs( //dir=expr + unique int id: @explicit_closure_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_count_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_count_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_literal_capacity_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int literal_capacity_expr: @expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @dot_syntax_call_expr +| @initializer_ref_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +initializer_ref_call_exprs( //dir=expr + unique int id: @initializer_ref_call_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@accessor_or_none = + @accessor +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@explicit_closure_expr_or_none = + @explicit_closure_expr +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@function_or_none = + @function +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@initializer_or_none = + @initializer +| @unspecified_element +; + +@key_path_component_or_none = + @key_path_component +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/swift.dbscheme b/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/swift.dbscheme new file mode 100644 index 00000000000..44e36e15e90 --- /dev/null +++ b/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/swift.dbscheme @@ -0,0 +1,2618 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @key_path_component +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +key_path_components( + unique int id: @key_path_component, + int kind: int ref, + int component_type: @type_or_none ref +); + +#keyset[id, index] +key_path_component_subscript_arguments( + int id: @key_path_component ref, + int index: int ref, + int subscript_argument: @argument_or_none ref +); + +#keyset[id] +key_path_component_tuple_indices( + int id: @key_path_component ref, + int tuple_index: int ref +); + +#keyset[id] +key_path_component_decl_refs( + int id: @key_path_component ref, + int decl_ref: @value_decl_or_none ref +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @extension_decl +| @function +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_storage_decl +| @enum_element_decl +| @function +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessors( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor: @accessor_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@function = + @accessor_or_named_function +| @deinitializer +| @initializer +; + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +@accessor_or_named_function = + @accessor +| @named_function +; + +deinitializers( //dir=decl + unique int id: @deinitializer +); + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +initializers( //dir=decl + unique int id: @initializer +); + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessors( //dir=decl + unique int id: @accessor +); + +#keyset[id] +accessor_is_getter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_setter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_will_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_did_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_read( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_modify( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_address( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_mutable_address( //dir=decl + int id: @accessor ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +named_functions( //dir=decl + unique int id: @named_function +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @closure_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initialization_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_initializer_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_initializer_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @explicit_closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@closure_expr = + @auto_closure_expr +| @explicit_closure_expr +; + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id, index] +key_path_expr_components( //dir=expr + int id: @key_path_expr ref, + int index: int ref, + int component: @key_path_component_or_none ref +); + +lazy_initialization_exprs( //dir=expr + unique int id: @lazy_initialization_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @function_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_initializer_ref_exprs( //dir=expr + unique int id: @other_initializer_ref_expr, + int initializer: @initializer_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_initializer_exprs( //dir=expr + unique int id: @rebind_self_in_initializer_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +explicit_closure_exprs( //dir=expr + unique int id: @explicit_closure_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @dot_syntax_call_expr +| @initializer_ref_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +initializer_ref_call_exprs( //dir=expr + unique int id: @initializer_ref_call_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@accessor_or_none = + @accessor +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@explicit_closure_expr_or_none = + @explicit_closure_expr +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@function_or_none = + @function +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@initializer_or_none = + @initializer +| @unspecified_element +; + +@key_path_component_or_none = + @key_path_component +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/upgrade.properties b/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/upgrade.properties new file mode 100644 index 00000000000..fa6dbe30ef6 --- /dev/null +++ b/swift/ql/lib/upgrades/ba4171b90d0665b40e9e203bac9e3d4a0b2d03ec/upgrade.properties @@ -0,0 +1,5 @@ +description: Remove `getInterpolationCountExpr` and `getLiteralCapacityExpr` from `InterpolatedStringLiteralExpr` +compatibility: full +interpolated_string_literal_expr_interpolation_count_exprs.rel: delete +interpolated_string_literal_expr_literal_capacity_exprs.rel: delete +integer_literal_exprs.rel: run integer_literal_exprs.ql diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index b4665b644e8..f1fbb4f1544 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -206,8 +206,6 @@ cfg.swift: # 40| getExpr(): [VarargExpansionExpr] [...] # 40| getSubExpr(): [ArrayExpr] [...] # 40| getElement(0): [InterpolatedStringLiteralExpr] "..." -#-----| getInterpolationCountExpr(): [IntegerLiteralExpr] 1 -#-----| getLiteralCapacityExpr(): [IntegerLiteralExpr] 14 # 40| getAppendingExpr(): [TapExpr] TapExpr # 40| getSubExpr(): [OpaqueValueExpr] OpaqueValueExpr # 40| getBody(): [BraceStmt] { ... } @@ -1422,8 +1420,6 @@ cfg.swift: # 262| getBody(): [BraceStmt] { ... } # 263| getElement(0): [ReturnStmt] return ... # 263| getResult(): [InterpolatedStringLiteralExpr] "..." -#-----| getInterpolationCountExpr(): [IntegerLiteralExpr] 4 -#-----| getLiteralCapacityExpr(): [IntegerLiteralExpr] 37 # 263| getAppendingExpr(): [TapExpr] TapExpr # 263| getSubExpr(): [OpaqueValueExpr] OpaqueValueExpr # 263| getBody(): [BraceStmt] { ... } @@ -4293,8 +4289,6 @@ expressions.swift: # 7| getBody(): [BraceStmt] { ... } # 7| getElement(0): [PatternBindingDecl] var ... = ... # 7| getInit(0): [InterpolatedStringLiteralExpr] "..." -#-----| getInterpolationCountExpr(): [IntegerLiteralExpr] 1 -#-----| getLiteralCapacityExpr(): [IntegerLiteralExpr] 6 # 7| getAppendingExpr(): [TapExpr] TapExpr # 7| getSubExpr(): [OpaqueValueExpr] OpaqueValueExpr # 7| getBody(): [BraceStmt] { ... } diff --git a/swift/schema.py b/swift/schema.py index 8fc0941e171..c17cae57452 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -679,8 +679,6 @@ class InjectIntoOptionalExpr(ImplicitConversionExpr): class InterpolatedStringLiteralExpr(LiteralExpr): interpolation_expr: optional[OpaqueValueExpr] - interpolation_count_expr: optional[Expr] | child - literal_capacity_expr: optional[Expr] | child appending_expr: optional[TapExpr] | child class LinearFunctionExpr(ImplicitConversionExpr): From 3bcaff605914083b4f1f8cc550a41c025b3b61e1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 May 2023 16:37:03 +0100 Subject: [PATCH 067/739] Swift: re-run codegen. --- swift/ql/.generated.list | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index a28e6ba533b..e8993c8570d 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -24,7 +24,6 @@ lib/codeql/swift/elements/decl/ConcreteVarDecl.qll 94bcbdd91f461295c5b6b49fa597b lib/codeql/swift/elements/decl/ConcreteVarDeclConstructor.qll 4b6a9f458db5437f9351b14464b3809a78194029554ea818b3e18272c17afba3 a60d695b0d0ffa917ad01908bec2beaa663e644eddb00fb370fbc906623775d4 lib/codeql/swift/elements/decl/DeinitializerConstructor.qll 85f29a68ee5c0f2606c51e7a859f5f45fbc5f373e11b5e9c0762c9ba5cff51c4 6b28f69b8125d0393607dbad8e7a8aaa6469b9c671f67e8e825cc63964ed2f5d lib/codeql/swift/elements/decl/EnumCaseDeclConstructor.qll 8c907544170671f713a8665d294eeefdbe78a607c2f16e2c630ea9c33f484baf eec83efc930683628185dbdad8f73311aad510074d168a53d85ea09d13f1f7e1 -lib/codeql/swift/elements/decl/EnumDecl.qll 29f9d8cbfb19c174af9a666162fd918af7f962fa5d97756105e78d5eec38cb9e 779940ebdbd510eb651972c57eb84b04af39c44ef59a8c307a44549ab730febb lib/codeql/swift/elements/decl/EnumDeclConstructor.qll 642bbfb71e917d84695622f3b2c7b36bf5be4e185358609810267ab1fc4e221b f6e06d79e7ff65fbabf72c553508b67406fb59c577215d28cc47971d34b6af05 lib/codeql/swift/elements/decl/EnumElementDeclConstructor.qll 736074246a795c14a30a8ec7bb8da595a729983187887294e485487309919dc6 4614fb380fad7af1b5fb8afce920f3e7350378254ece60d19722046046672fbb lib/codeql/swift/elements/decl/ExtensionDeclConstructor.qll 4f811e3332720327d2b9019edbb2fa70fb24322e72881afc040e7927452409d6 554f9832311dfc30762507e0bd4b25c5b6fdb9d0c4e8252cc5a1ef1033fafacb @@ -384,7 +383,7 @@ lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d lib/codeql/swift/generated/ParentChild.qll f490202e849b9cbd550ee9d758644b85d43e60d81413e6c28df2850fb1e9a2d6 6b95aeab6b53a880b230ad0c96b6deb519a7368898c844632ae96090de59df99 lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 8d4880e5ee1fdd120adeb7bf0dfa1399e7b1a53b2cc7598aed8e15cbf996d1c0 da0d446347d29f5cd05281c17c24e87610f31c32adb7e05ab8f3a26bed55bd90 +lib/codeql/swift/generated/Raw.qll cc504ec0771dbb461367944a5c95186047bad59a087a9bda74ef346c7b89b0d3 0b5973d56edd8099b645ea1f7be2a4934e62d5fa165261c63299ac2cf634437d lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -398,7 +397,7 @@ lib/codeql/swift/generated/decl/AssociatedTypeDecl.qll 4169d083104f9c089223ed3c5 lib/codeql/swift/generated/decl/CapturedDecl.qll f8b69887acb35cc8de572984fef83eb08649845b49179b68d3afef36b526bddb 94ab461ef9ab5983dece5e2b1865b6056e381e5c06f2a3ec4dfde634a9368e59 lib/codeql/swift/generated/decl/ClassDecl.qll a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 lib/codeql/swift/generated/decl/ConcreteVarDecl.qll 4801ccc477480c4bc4fc117976fbab152e081064e064c97fbb0f37199cb1d0a8 4d7cfbf5b39b307dd673781adc220fdef04213f2e3d080004fa658ba6d3acb8d -lib/codeql/swift/generated/decl/Decl.qll 1d620c8e43df3cb46e5446dc9f6592205040c4d2b03c2ce1e491d7628f8904d0 b02514d7548a5a1dca39a148974a1b4dfeb681ebf81ad80f78d53ea48bab6133 +lib/codeql/swift/generated/decl/Decl.qll e9a27347096be6b0d1f9e555ba98867b4e3f1629bc4c24ed4c737921e416ef8c 5b9d839d3cce81a282fda869d83a33138c9587c76c1547692811aed05c44aa46 lib/codeql/swift/generated/decl/Deinitializer.qll 816ecd92552915d06952517606a6e4c67bc53d7e7d9f5c09b7276e70612627fe 816ecd92552915d06952517606a6e4c67bc53d7e7d9f5c09b7276e70612627fe lib/codeql/swift/generated/decl/EnumCaseDecl.qll 564718862a9fd5b99427591a83921bf57aac2074041b5b335577599e8eefda16 90899d7d7a9c695576ae4b24d19deb05e45e0e85c954ab41de154d5cc521019e lib/codeql/swift/generated/decl/EnumDecl.qll fa4490d511ee537751a4fab2478e65250ff3deba43c74db5341184c9ba25b534 fa4490d511ee537751a4fab2478e65250ff3deba43c74db5341184c9ba25b534 From 7aa23cf11db24341995b4252a64bc13d1b104bb2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 22 May 2023 20:47:00 +0000 Subject: [PATCH 068/739] Release preparation for version 2.13.3 --- cpp/ql/lib/CHANGELOG.md | 16 ++++++++ .../2023-04-28-indirect-barrier-node.md | 4 -- .../2023-04-28-static-local-dataflow.md | 4 -- .../2023-05-02-ir-noreturn-calls.md | 4 -- .../2023-05-02-range-analysis-wrapper.md | 4 -- .../2023-05-22-inline-in-std-namespace.md | 4 -- cpp/ql/lib/change-notes/released/0.7.2.md | 15 +++++++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 4 ++ cpp/ql/src/change-notes/released/0.6.2.md | 3 ++ cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++ .../lib/change-notes/released/1.5.2.md | 3 ++ .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++ .../src/change-notes/released/1.5.2.md | 3 ++ .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 7 ++++ .../2023-04-26-neutral-model-kinds.md | 4 -- .../0.6.2.md} | 8 ++-- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ++ csharp/ql/src/change-notes/released/0.6.2.md | 3 ++ csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 6 +++ .../0.5.2.md} | 9 ++-- go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++ go/ql/src/change-notes/released/0.5.2.md | 3 ++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 41 +++++++++++++++++++ ...-04-20-create-model-for-io-jsonwebtoken.md | 5 --- .../2023-04-26-neutral-model-kinds.md | 4 -- .../2023-05-02-apache-commons-net-models.md | 4 -- ...3-05-03-url-open-stream-as-experimental.md | 4 -- .../lib/change-notes/2023-05-11-new-models.md | 6 --- .../2023-05-12-spring-jdbc-sql-sinks.md | 4 -- .../0.6.2.md} | 17 ++++++-- java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 8 ++++ .../change-notes/2023-05-15-xpath-xxe-sink.md | 4 -- .../2023-05-19-groovy-injection-sink.md | 4 -- .../0.6.2.md} | 9 ++-- java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 6 +++ .../0.6.2.md} | 9 ++-- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 20 +++++++++ .../2023-04-13-Forge-truncated-sha512-hash.md | 5 --- .../2023-04-26-unsafe-yaml-deserialization.md | 5 --- .../2023-04-28-json-with-comments.md | 5 --- .../2023-05-02-github-actions-sources.md | 5 --- .../change-notes/2023-05-17-indirect-shell.md | 4 -- .../ql/src/change-notes/released/0.6.2.md | 19 +++++++++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++ .../change-notes/released/0.5.2.md | 3 ++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 7 ++++ ...16-typetracking-read-captured-variables.md | 4 -- .../0.9.2.md} | 8 ++-- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++ python/ql/src/change-notes/released/0.7.2.md | 3 ++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 6 +++ .../0.6.2.md} | 7 ++-- ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ++ ruby/ql/src/change-notes/released/0.6.2.md | 3 ++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++ shared/regex/change-notes/released/0.0.13.md | 3 ++ shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++ shared/ssa/change-notes/released/0.0.17.md | 3 ++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ++ .../tutorial/change-notes/released/0.0.10.md | 3 ++ shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++ .../change-notes/released/0.0.10.md | 3 ++ shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++ shared/typos/change-notes/released/0.0.17.md | 3 ++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 4 ++ shared/util/change-notes/released/0.0.10.md | 3 ++ shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ++ shared/yaml/change-notes/released/0.0.2.md | 3 ++ shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- 116 files changed, 347 insertions(+), 159 deletions(-) delete mode 100644 cpp/ql/lib/change-notes/2023-04-28-indirect-barrier-node.md delete mode 100644 cpp/ql/lib/change-notes/2023-04-28-static-local-dataflow.md delete mode 100644 cpp/ql/lib/change-notes/2023-05-02-ir-noreturn-calls.md delete mode 100644 cpp/ql/lib/change-notes/2023-05-02-range-analysis-wrapper.md delete mode 100644 cpp/ql/lib/change-notes/2023-05-22-inline-in-std-namespace.md create mode 100644 cpp/ql/lib/change-notes/released/0.7.2.md create mode 100644 cpp/ql/src/change-notes/released/0.6.2.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.2.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.2.md delete mode 100644 csharp/ql/lib/change-notes/2023-04-26-neutral-model-kinds.md rename csharp/ql/lib/change-notes/{2023-05-16-ilogger-extension-methods.md => released/0.6.2.md} (58%) create mode 100644 csharp/ql/src/change-notes/released/0.6.2.md rename go/ql/lib/change-notes/{2023-04-25-data-flow-varargs-parameters.md => released/0.5.2.md} (85%) create mode 100644 go/ql/src/change-notes/released/0.5.2.md delete mode 100644 java/ql/lib/change-notes/2023-04-20-create-model-for-io-jsonwebtoken.md delete mode 100644 java/ql/lib/change-notes/2023-04-26-neutral-model-kinds.md delete mode 100644 java/ql/lib/change-notes/2023-05-02-apache-commons-net-models.md delete mode 100644 java/ql/lib/change-notes/2023-05-03-url-open-stream-as-experimental.md delete mode 100644 java/ql/lib/change-notes/2023-05-11-new-models.md delete mode 100644 java/ql/lib/change-notes/2023-05-12-spring-jdbc-sql-sinks.md rename java/ql/lib/change-notes/{2023-05-04-add-libraries-for-query-configurations.md => released/0.6.2.md} (87%) delete mode 100644 java/ql/src/change-notes/2023-05-15-xpath-xxe-sink.md delete mode 100644 java/ql/src/change-notes/2023-05-19-groovy-injection-sink.md rename java/ql/src/change-notes/{2023-04-26-xxe-sinks-promotion.md => released/0.6.2.md} (50%) rename javascript/ql/lib/change-notes/{2023-04-03-gh-injection.md => released/0.6.2.md} (85%) delete mode 100644 javascript/ql/src/change-notes/2023-04-13-Forge-truncated-sha512-hash.md delete mode 100644 javascript/ql/src/change-notes/2023-04-26-unsafe-yaml-deserialization.md delete mode 100644 javascript/ql/src/change-notes/2023-04-28-json-with-comments.md delete mode 100644 javascript/ql/src/change-notes/2023-05-02-github-actions-sources.md delete mode 100644 javascript/ql/src/change-notes/2023-05-17-indirect-shell.md create mode 100644 javascript/ql/src/change-notes/released/0.6.2.md create mode 100644 misc/suite-helpers/change-notes/released/0.5.2.md delete mode 100644 python/ql/lib/change-notes/2023-03-16-typetracking-read-captured-variables.md rename python/ql/lib/change-notes/{2022-11-15-dictionary-read-store-steps.md => released/0.9.2.md} (51%) create mode 100644 python/ql/src/change-notes/released/0.7.2.md rename ruby/ql/lib/change-notes/{2023-05-03-sqlite3.md => released/0.6.2.md} (80%) create mode 100644 ruby/ql/src/change-notes/released/0.6.2.md create mode 100644 shared/regex/change-notes/released/0.0.13.md create mode 100644 shared/ssa/change-notes/released/0.0.17.md create mode 100644 shared/tutorial/change-notes/released/0.0.10.md create mode 100644 shared/typetracking/change-notes/released/0.0.10.md create mode 100644 shared/typos/change-notes/released/0.0.17.md create mode 100644 shared/util/change-notes/released/0.0.10.md create mode 100644 shared/yaml/change-notes/released/0.0.2.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index f77a14c328f..e5d2ae643bc 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.7.2 + +### New Features + +* Added an AST-based interface (`semmle.code.cpp.rangeanalysis.new.RangeAnalysis`) for the relative range analysis library. +* A new predicate `BarrierGuard::getAnIndirectBarrierNode` has been added to the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) to mark indirect expressions as barrier nodes using the `BarrierGuard` API. + +### Major Analysis Improvements + +* In the intermediate representation, handling of control flow after non-returning calls has been improved. This should remove false positives in queries that use the intermedite representation or libraries based on it, including the new data flow library. + +### Minor Analysis Improvements + +* The `StdNamespace` class now also includes all inline namespaces that are children of `std` namespace. +* The new dataflow (`semmle.code.cpp.dataflow.new.DataFlow`) and taint-tracking libraries (`semmle.code.cpp.dataflow.new.TaintTracking`) now support tracking flow through static local variables. + ## 0.7.1 No user-facing changes. diff --git a/cpp/ql/lib/change-notes/2023-04-28-indirect-barrier-node.md b/cpp/ql/lib/change-notes/2023-04-28-indirect-barrier-node.md deleted file mode 100644 index 68421139e7d..00000000000 --- a/cpp/ql/lib/change-notes/2023-04-28-indirect-barrier-node.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* A new predicate `BarrierGuard::getAnIndirectBarrierNode` has been added to the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) to mark indirect expressions as barrier nodes using the `BarrierGuard` API. diff --git a/cpp/ql/lib/change-notes/2023-04-28-static-local-dataflow.md b/cpp/ql/lib/change-notes/2023-04-28-static-local-dataflow.md deleted file mode 100644 index be4c4e73ed0..00000000000 --- a/cpp/ql/lib/change-notes/2023-04-28-static-local-dataflow.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The new dataflow (`semmle.code.cpp.dataflow.new.DataFlow`) and taint-tracking libraries (`semmle.code.cpp.dataflow.new.TaintTracking`) now support tracking flow through static local variables. diff --git a/cpp/ql/lib/change-notes/2023-05-02-ir-noreturn-calls.md b/cpp/ql/lib/change-notes/2023-05-02-ir-noreturn-calls.md deleted file mode 100644 index 5688945dc80..00000000000 --- a/cpp/ql/lib/change-notes/2023-05-02-ir-noreturn-calls.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* In the intermediate representation, handling of control flow after non-returning calls has been improved. This should remove false positives in queries that use the intermedite representation or libraries based on it, including the new data flow library. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2023-05-02-range-analysis-wrapper.md b/cpp/ql/lib/change-notes/2023-05-02-range-analysis-wrapper.md deleted file mode 100644 index b28167dc52d..00000000000 --- a/cpp/ql/lib/change-notes/2023-05-02-range-analysis-wrapper.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Added an AST-based interface (`semmle.code.cpp.rangeanalysis.new.RangeAnalysis`) for the relative range analysis library. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2023-05-22-inline-in-std-namespace.md b/cpp/ql/lib/change-notes/2023-05-22-inline-in-std-namespace.md deleted file mode 100644 index 8b562bd8357..00000000000 --- a/cpp/ql/lib/change-notes/2023-05-22-inline-in-std-namespace.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `StdNamespace` class now also includes all inline namespaces that are children of `std` namespace. diff --git a/cpp/ql/lib/change-notes/released/0.7.2.md b/cpp/ql/lib/change-notes/released/0.7.2.md new file mode 100644 index 00000000000..4decad06ae8 --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.7.2.md @@ -0,0 +1,15 @@ +## 0.7.2 + +### New Features + +* Added an AST-based interface (`semmle.code.cpp.rangeanalysis.new.RangeAnalysis`) for the relative range analysis library. +* A new predicate `BarrierGuard::getAnIndirectBarrierNode` has been added to the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) to mark indirect expressions as barrier nodes using the `BarrierGuard` API. + +### Major Analysis Improvements + +* In the intermediate representation, handling of control flow after non-returning calls has been improved. This should remove false positives in queries that use the intermedite representation or libraries based on it, including the new data flow library. + +### Minor Analysis Improvements + +* The `StdNamespace` class now also includes all inline namespaces that are children of `std` namespace. +* The new dataflow (`semmle.code.cpp.dataflow.new.DataFlow`) and taint-tracking libraries (`semmle.code.cpp.dataflow.new.TaintTracking`) now support tracking flow through static local variables. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index e007a9aec3e..fee171e9685 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.1 +lastReleaseVersion: 0.7.2 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 3f6482c1ebe..2008adee602 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.7.2-dev +version: 0.7.2 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 1314e6d7553..4991b66538f 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.2 + +No user-facing changes. + ## 0.6.1 ### New Queries diff --git a/cpp/ql/src/change-notes/released/0.6.2.md b/cpp/ql/src/change-notes/released/0.6.2.md new file mode 100644 index 00000000000..43f80640fc5 --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.6.2.md @@ -0,0 +1,3 @@ +## 0.6.2 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 4df58a2da69..8b2bb0ed100 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.6.2-dev +version: 0.6.2 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 56de88b8aa5..ad7a007007f 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.2 + +No user-facing changes. + ## 1.5.1 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.2.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.2.md new file mode 100644 index 00000000000..384c27833f1 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.2.md @@ -0,0 +1,3 @@ +## 1.5.2 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index c5775c46013..7eb901bae56 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.5.1 +lastReleaseVersion: 1.5.2 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index fb0859160cc..9c09d378a20 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.5.2-dev +version: 1.5.2 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 56de88b8aa5..ad7a007007f 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.2 + +No user-facing changes. + ## 1.5.1 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.2.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.2.md new file mode 100644 index 00000000000..384c27833f1 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.2.md @@ -0,0 +1,3 @@ +## 1.5.2 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index c5775c46013..7eb901bae56 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.5.1 +lastReleaseVersion: 1.5.2 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 4c9eeb60c87..241bb764b7c 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.5.2-dev +version: 1.5.2 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 4ebff5c86a7..435255a997a 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.6.2 + +### Minor Analysis Improvements + +* The `cs/log-forging`, `cs/cleartext-storage`, and `cs/exposure-of-sensitive-information` queries now correctly handle unsanitized arguments to `ILogger` extension methods. +* Updated the `neutralModel` extensible predicate to include a `kind` column. + ## 0.6.1 No user-facing changes. diff --git a/csharp/ql/lib/change-notes/2023-04-26-neutral-model-kinds.md b/csharp/ql/lib/change-notes/2023-04-26-neutral-model-kinds.md deleted file mode 100644 index ab19597224b..00000000000 --- a/csharp/ql/lib/change-notes/2023-04-26-neutral-model-kinds.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Updated the `neutralModel` extensible predicate to include a `kind` column. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2023-05-16-ilogger-extension-methods.md b/csharp/ql/lib/change-notes/released/0.6.2.md similarity index 58% rename from csharp/ql/lib/change-notes/2023-05-16-ilogger-extension-methods.md rename to csharp/ql/lib/change-notes/released/0.6.2.md index 4d4f0767238..c3829f2df86 100644 --- a/csharp/ql/lib/change-notes/2023-05-16-ilogger-extension-methods.md +++ b/csharp/ql/lib/change-notes/released/0.6.2.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.6.2 + +### Minor Analysis Improvements + * The `cs/log-forging`, `cs/cleartext-storage`, and `cs/exposure-of-sensitive-information` queries now correctly handle unsanitized arguments to `ILogger` extension methods. +* Updated the `neutralModel` extensible predicate to include a `kind` column. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index fdb710e9371..1e56c93103b 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.6.2-dev +version: 0.6.2 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index fb6006fc6f9..e214ec42a03 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.2 + +No user-facing changes. + ## 0.6.1 ### Minor Analysis Improvements diff --git a/csharp/ql/src/change-notes/released/0.6.2.md b/csharp/ql/src/change-notes/released/0.6.2.md new file mode 100644 index 00000000000..43f80640fc5 --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.6.2.md @@ -0,0 +1,3 @@ +## 0.6.2 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index d68e0a497c1..663ad9efee2 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.6.2-dev +version: 0.6.2 groups: - csharp - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index e144655e159..5f09272c19b 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.5.2 + +### Minor Analysis Improvements + +* Fixed data flow through variadic function parameters. The arguments corresponding to a variadic parameter are no longer returned by `CallNode.getArgument(int i)` and `CallNode.getAnArgument()`, and hence aren't `ArgumentNode`s. They now have one result, which is an `ImplicitVarargsSlice` node. For example, a call `f(a, b, c)` to a function `f(T...)` is treated like `f([]T{a, b, c})`. The old behaviour is preserved by `CallNode.getSyntacticArgument(int i)` and `CallNode.getASyntacticArgument()`. `CallExpr.getArgument(int i)` and `CallExpr.getAnArgument()` are unchanged, and will still have three results in the example given. + ## 0.5.1 ### Minor Analysis Improvements diff --git a/go/ql/lib/change-notes/2023-04-25-data-flow-varargs-parameters.md b/go/ql/lib/change-notes/released/0.5.2.md similarity index 85% rename from go/ql/lib/change-notes/2023-04-25-data-flow-varargs-parameters.md rename to go/ql/lib/change-notes/released/0.5.2.md index 881d570361e..ad1dea14924 100644 --- a/go/ql/lib/change-notes/2023-04-25-data-flow-varargs-parameters.md +++ b/go/ql/lib/change-notes/released/0.5.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* Fixed data flow through variadic function parameters. The arguments corresponding to a variadic parameter are no longer returned by `CallNode.getArgument(int i)` and `CallNode.getAnArgument()`, and hence aren't `ArgumentNode`s. They now have one result, which is an `ImplicitVarargsSlice` node. For example, a call `f(a, b, c)` to a function `f(T...)` is treated like `f([]T{a, b, c})`. The old behaviour is preserved by `CallNode.getSyntacticArgument(int i)` and `CallNode.getASyntacticArgument()`. `CallExpr.getArgument(int i)` and `CallExpr.getAnArgument()` are unchanged, and will still have three results in the example given. \ No newline at end of file +## 0.5.2 + +### Minor Analysis Improvements + +* Fixed data flow through variadic function parameters. The arguments corresponding to a variadic parameter are no longer returned by `CallNode.getArgument(int i)` and `CallNode.getAnArgument()`, and hence aren't `ArgumentNode`s. They now have one result, which is an `ImplicitVarargsSlice` node. For example, a call `f(a, b, c)` to a function `f(T...)` is treated like `f([]T{a, b, c})`. The old behaviour is preserved by `CallNode.getSyntacticArgument(int i)` and `CallNode.getASyntacticArgument()`. `CallExpr.getArgument(int i)` and `CallExpr.getAnArgument()` are unchanged, and will still have three results in the example given. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 0bf7024c337..2d9d3f587f8 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.1 +lastReleaseVersion: 0.5.2 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 346dc087db4..4da3e4ac60c 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.5.2-dev +version: 0.5.2 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 81ce4f00d02..8a1b8bcfebc 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.2 + +No user-facing changes. + ## 0.5.1 No user-facing changes. diff --git a/go/ql/src/change-notes/released/0.5.2.md b/go/ql/src/change-notes/released/0.5.2.md new file mode 100644 index 00000000000..e94d1f4ad5b --- /dev/null +++ b/go/ql/src/change-notes/released/0.5.2.md @@ -0,0 +1,3 @@ +## 0.5.2 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 0bf7024c337..2d9d3f587f8 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.1 +lastReleaseVersion: 0.5.2 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 64be9928c63..81410e8a0bc 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.5.2-dev +version: 0.5.2 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 03907f74b89..53fb1470bb9 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,44 @@ +## 0.6.2 + +### Minor Analysis Improvements + +* Added SQL injection sinks for Spring JDBC's `NamedParameterJdbcOperations`. +* Added models for the following packages: + + * org.apache.hadoop.fs +* Added the `ArithmeticCommon.qll` library to provide predicates for reasoning about arithmetic operations. +* Added the `ArithmeticTaintedLocalQuery.qll` library to provide the `ArithmeticTaintedLocalOverflowFlow` and `ArithmeticTaintedLocalUnderflowFlow` taint-tracking modules to reason about arithmetic with unvalidated user input. +* Added the `ArithmeticTaintedQuery.qll` library to provide the `RemoteUserInputOverflow` and `RemoteUserInputUnderflow` taint-tracking modules to reason about arithmetic with unvalidated user input. +* Added the `ArithmeticUncontrolledQuery.qll` library to provide the `ArithmeticUncontrolledOverflowFlow` and `ArithmeticUncontrolledUnderflowFlow` taint-tracking modules to reason about arithmetic with uncontrolled user input. +* Added the `ArithmeticWithExtremeValuesQuery.qll` library to provide the `MaxValueFlow` and `MinValueFlow` dataflow modules to reason about arithmetic with extreme values. +* Added the `BrokenCryptoAlgorithmQuery.qll` library to provide the `InsecureCryptoFlow` taint-tracking module to reason about broken cryptographic algorithm vulnerabilities. +* Added the `ExecTaintedLocalQuery.qll` library to provide the `LocalUserInputToArgumentToExecFlow` taint-tracking module to reason about command injection vulnerabilities caused by local data flow. +* Added the `ExternallyControlledFormatStringLocalQuery.qll` library to provide the `ExternallyControlledFormatStringLocalFlow` taint-tracking module to reason about format string vulnerabilities caused by local data flow. +* Added the `ImproperValidationOfArrayConstructionCodeSpecifiedQuery.qll` library to provide the `BoundedFlowSourceFlow` dataflow module to reason about improper validation of code-specified sizes used for array construction. +* Added the `ImproperValidationOfArrayConstructionLocalQuery.qll` library to provide the `ImproperValidationOfArrayConstructionLocalFlow` taint-tracking module to reason about improper validation of local user-provided sizes used for array construction caused by local data flow. +* Added the `ImproperValidationOfArrayConstructionQuery.qll` library to provide the `ImproperValidationOfArrayConstructionFlow` taint-tracking module to reason about improper validation of user-provided size used for array construction. +* Added the `ImproperValidationOfArrayIndexCodeSpecifiedQuery.qll` library to provide the `BoundedFlowSourceFlow` data flow module to reason about about improper validation of code-specified array index. +* Added the `ImproperValidationOfArrayIndexLocalQuery.qll` library to provide the `ImproperValidationOfArrayIndexLocalFlow` taint-tracking module to reason about improper validation of a local user-provided array index. +* Added the `ImproperValidationOfArrayIndexQuery.qll` library to provide the `ImproperValidationOfArrayIndexFlow` taint-tracking module to reason about improper validation of user-provided array index. +* Added the `InsecureCookieQuery.qll` library to provide the `SecureCookieFlow` taint-tracking module to reason about insecure cookie vulnerabilities. +* Added the `MaybeBrokenCryptoAlgorithmQuery.qll` library to provide the `InsecureCryptoFlow` taint-tracking module to reason about broken cryptographic algorithm vulnerabilities. +* Added the `NumericCastTaintedQuery.qll` library to provide the `NumericCastTaintedFlow` taint-tracking module to reason about numeric cast vulnerabilities. +* Added the `ResponseSplittingLocalQuery.qll` library to provide the `ResponseSplittingLocalFlow` taint-tracking module to reason about response splitting vulnerabilities caused by local data flow. +* Added the `SqlConcatenatedQuery.qll` library to provide the `UncontrolledStringBuilderSourceFlow` taint-tracking module to reason about SQL injection vulnerabilities caused by concatenating untrusted strings. +* Added the `SqlTaintedLocalQuery.qll` library to provide the `LocalUserInputToArgumentToSqlFlow` taint-tracking module to reason about SQL injection vulnerabilities caused by local data flow. +* Added the `StackTraceExposureQuery.qll` library to provide the `printsStackExternally`, `stringifiedStackFlowsExternally`, and `getMessageFlowsExternally` predicates to reason about stack trace exposure vulnerabilities. +* Added the `TaintedPermissionQuery.qll` library to provide the `TaintedPermissionFlow` taint-tracking module to reason about tainted permission vulnerabilities. +* Added the `TempDirLocalInformationDisclosureQuery.qll` library to provide the `TempDirSystemGetPropertyToCreate` taint-tracking module to reason about local information disclosure vulnerabilities caused by local data flow. +* Added the `UnsafeHostnameVerificationQuery.qll` library to provide the `TrustAllHostnameVerifierFlow` taint-tracking module to reason about insecure hostname verification vulnerabilities. +* Added the `UrlRedirectLocalQuery.qll` library to provide the `UrlRedirectLocalFlow` taint-tracking module to reason about URL redirection vulnerabilities caused by local data flow. +* Added the `UrlRedirectQuery.qll` library to provide the `UrlRedirectFlow` taint-tracking module to reason about URL redirection vulnerabilities. +* Added the `XPathInjectionQuery.qll` library to provide the `XPathInjectionFlow` taint-tracking module to reason about XPath injection vulnerabilities. +* Added the `XssLocalQuery.qll` library to provide the `XssLocalFlow` taint-tracking module to reason about XSS vulnerabilities caused by local data flow. +* Moved the `url-open-stream` sink models to experimental and removed `url-open-stream` as a sink option from the [Customizing Library Models for Java](https://github.com/github/codeql/blob/733a00039efdb39c3dd76ddffad5e6d6c85e6774/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst#customizing-library-models-for-java) documentation. +* Added models for the Apache Commons Net library. +* Updated the `neutralModel` extensible predicate to include a `kind` column. +* Added models for the `io.jsonwebtoken` library. + ## 0.6.1 ### Deprecated APIs diff --git a/java/ql/lib/change-notes/2023-04-20-create-model-for-io-jsonwebtoken.md b/java/ql/lib/change-notes/2023-04-20-create-model-for-io-jsonwebtoken.md deleted file mode 100644 index 3a037075967..00000000000 --- a/java/ql/lib/change-notes/2023-04-20-create-model-for-io-jsonwebtoken.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Added models for the `io.jsonwebtoken` library. - diff --git a/java/ql/lib/change-notes/2023-04-26-neutral-model-kinds.md b/java/ql/lib/change-notes/2023-04-26-neutral-model-kinds.md deleted file mode 100644 index ab19597224b..00000000000 --- a/java/ql/lib/change-notes/2023-04-26-neutral-model-kinds.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Updated the `neutralModel` extensible predicate to include a `kind` column. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2023-05-02-apache-commons-net-models.md b/java/ql/lib/change-notes/2023-05-02-apache-commons-net-models.md deleted file mode 100644 index a669c74d3e8..00000000000 --- a/java/ql/lib/change-notes/2023-05-02-apache-commons-net-models.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added models for the Apache Commons Net library. diff --git a/java/ql/lib/change-notes/2023-05-03-url-open-stream-as-experimental.md b/java/ql/lib/change-notes/2023-05-03-url-open-stream-as-experimental.md deleted file mode 100644 index 1d57d64973c..00000000000 --- a/java/ql/lib/change-notes/2023-05-03-url-open-stream-as-experimental.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Moved the `url-open-stream` sink models to experimental and removed `url-open-stream` as a sink option from the [Customizing Library Models for Java](https://github.com/github/codeql/blob/733a00039efdb39c3dd76ddffad5e6d6c85e6774/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst#customizing-library-models-for-java) documentation. diff --git a/java/ql/lib/change-notes/2023-05-11-new-models.md b/java/ql/lib/change-notes/2023-05-11-new-models.md deleted file mode 100644 index 067105b4aca..00000000000 --- a/java/ql/lib/change-notes/2023-05-11-new-models.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* Added models for the following packages: - - * org.apache.hadoop.fs diff --git a/java/ql/lib/change-notes/2023-05-12-spring-jdbc-sql-sinks.md b/java/ql/lib/change-notes/2023-05-12-spring-jdbc-sql-sinks.md deleted file mode 100644 index 68d6c2b45fe..00000000000 --- a/java/ql/lib/change-notes/2023-05-12-spring-jdbc-sql-sinks.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added SQL injection sinks for Spring JDBC's `NamedParameterJdbcOperations`. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2023-05-04-add-libraries-for-query-configurations.md b/java/ql/lib/change-notes/released/0.6.2.md similarity index 87% rename from java/ql/lib/change-notes/2023-05-04-add-libraries-for-query-configurations.md rename to java/ql/lib/change-notes/released/0.6.2.md index ead324ee5fb..f0bf9441a47 100644 --- a/java/ql/lib/change-notes/2023-05-04-add-libraries-for-query-configurations.md +++ b/java/ql/lib/change-notes/released/0.6.2.md @@ -1,6 +1,11 @@ ---- -category: minorAnalysis ---- +## 0.6.2 + +### Minor Analysis Improvements + +* Added SQL injection sinks for Spring JDBC's `NamedParameterJdbcOperations`. +* Added models for the following packages: + + * org.apache.hadoop.fs * Added the `ArithmeticCommon.qll` library to provide predicates for reasoning about arithmetic operations. * Added the `ArithmeticTaintedLocalQuery.qll` library to provide the `ArithmeticTaintedLocalOverflowFlow` and `ArithmeticTaintedLocalUnderflowFlow` taint-tracking modules to reason about arithmetic with unvalidated user input. * Added the `ArithmeticTaintedQuery.qll` library to provide the `RemoteUserInputOverflow` and `RemoteUserInputUnderflow` taint-tracking modules to reason about arithmetic with unvalidated user input. @@ -28,4 +33,8 @@ category: minorAnalysis * Added the `UrlRedirectLocalQuery.qll` library to provide the `UrlRedirectLocalFlow` taint-tracking module to reason about URL redirection vulnerabilities caused by local data flow. * Added the `UrlRedirectQuery.qll` library to provide the `UrlRedirectFlow` taint-tracking module to reason about URL redirection vulnerabilities. * Added the `XPathInjectionQuery.qll` library to provide the `XPathInjectionFlow` taint-tracking module to reason about XPath injection vulnerabilities. -* Added the `XssLocalQuery.qll` library to provide the `XssLocalFlow` taint-tracking module to reason about XSS vulnerabilities caused by local data flow. \ No newline at end of file +* Added the `XssLocalQuery.qll` library to provide the `XssLocalFlow` taint-tracking module to reason about XSS vulnerabilities caused by local data flow. +* Moved the `url-open-stream` sink models to experimental and removed `url-open-stream` as a sink option from the [Customizing Library Models for Java](https://github.com/github/codeql/blob/733a00039efdb39c3dd76ddffad5e6d6c85e6774/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst#customizing-library-models-for-java) documentation. +* Added models for the Apache Commons Net library. +* Updated the `neutralModel` extensible predicate to include a `kind` column. +* Added models for the `io.jsonwebtoken` library. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index c48db63b34d..94ec029ed07 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.6.2-dev +version: 0.6.2 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 744ac866083..1e7cebcfca1 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.6.2 + +### Minor Analysis Improvements + +* The query `java/groovy-injection` now recognizes `groovy.text.TemplateEngine.createTemplate` as a sink. +* The queries `java/xxe` and `java/xxe-local` now recognize the second argument of calls to `XPath.evaluate` as a sink. +* Experimental sinks for the query "Resolving XML external entity in user-controlled data" (`java/xxe`) have been promoted to the main query pack. These sinks were originally [submitted as part of an experimental query by @haby0](https://github.com/github/codeql/pull/6564). + ## 0.6.1 No user-facing changes. diff --git a/java/ql/src/change-notes/2023-05-15-xpath-xxe-sink.md b/java/ql/src/change-notes/2023-05-15-xpath-xxe-sink.md deleted file mode 100644 index 1696ffbd213..00000000000 --- a/java/ql/src/change-notes/2023-05-15-xpath-xxe-sink.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The queries `java/xxe` and `java/xxe-local` now recognize the second argument of calls to `XPath.evaluate` as a sink. diff --git a/java/ql/src/change-notes/2023-05-19-groovy-injection-sink.md b/java/ql/src/change-notes/2023-05-19-groovy-injection-sink.md deleted file mode 100644 index 7f668dd1b28..00000000000 --- a/java/ql/src/change-notes/2023-05-19-groovy-injection-sink.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The query `java/groovy-injection` now recognizes `groovy.text.TemplateEngine.createTemplate` as a sink. diff --git a/java/ql/src/change-notes/2023-04-26-xxe-sinks-promotion.md b/java/ql/src/change-notes/released/0.6.2.md similarity index 50% rename from java/ql/src/change-notes/2023-04-26-xxe-sinks-promotion.md rename to java/ql/src/change-notes/released/0.6.2.md index 01bbfe267bd..50a5ff81b8f 100644 --- a/java/ql/src/change-notes/2023-04-26-xxe-sinks-promotion.md +++ b/java/ql/src/change-notes/released/0.6.2.md @@ -1,4 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.6.2 + +### Minor Analysis Improvements + +* The query `java/groovy-injection` now recognizes `groovy.text.TemplateEngine.createTemplate` as a sink. +* The queries `java/xxe` and `java/xxe-local` now recognize the second argument of calls to `XPath.evaluate` as a sink. * Experimental sinks for the query "Resolving XML external entity in user-controlled data" (`java/xxe`) have been promoted to the main query pack. These sinks were originally [submitted as part of an experimental query by @haby0](https://github.com/github/codeql/pull/6564). diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 3e640f9376f..8936d5a4373 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.6.2-dev +version: 0.6.2 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 24e199a69d7..3ac3bc23481 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.6.2 + +### Minor Analysis Improvements + +* Improved the queries for injection vulnerabilities in GitHub Actions workflows (`js/actions/command-injection` and `js/actions/pull-request-target`) and the associated library `semmle.javascript.Actions`. These now support steps defined in composite actions, in addition to steps defined in Actions workflow files. It supports more potentially untrusted input values. Additionally to the shell injections it now also detects injections in `actions/github-script`. It also detects simple injections from user controlled `${{ env.name }}`. Additionally to the `yml` extension now it also supports workflows with the `yaml` extension. + ## 0.6.1 ### Major Analysis Improvements diff --git a/javascript/ql/lib/change-notes/2023-04-03-gh-injection.md b/javascript/ql/lib/change-notes/released/0.6.2.md similarity index 85% rename from javascript/ql/lib/change-notes/2023-04-03-gh-injection.md rename to javascript/ql/lib/change-notes/released/0.6.2.md index 63e913eb694..f97f6633c49 100644 --- a/javascript/ql/lib/change-notes/2023-04-03-gh-injection.md +++ b/javascript/ql/lib/change-notes/released/0.6.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* Improved the queries for injection vulnerabilities in GitHub Actions workflows (`js/actions/command-injection` and `js/actions/pull-request-target`) and the associated library `semmle.javascript.Actions`. These now support steps defined in composite actions, in addition to steps defined in Actions workflow files. It supports more potentially untrusted input values. Additionally to the shell injections it now also detects injections in `actions/github-script`. It also detects simple injections from user controlled `${{ env.name }}`. Additionally to the `yml` extension now it also supports workflows with the `yaml` extension. \ No newline at end of file +## 0.6.2 + +### Minor Analysis Improvements + +* Improved the queries for injection vulnerabilities in GitHub Actions workflows (`js/actions/command-injection` and `js/actions/pull-request-target`) and the associated library `semmle.javascript.Actions`. These now support steps defined in composite actions, in addition to steps defined in Actions workflow files. It supports more potentially untrusted input values. Additionally to the shell injections it now also detects injections in `actions/github-script`. It also detects simple injections from user controlled `${{ env.name }}`. Additionally to the `yml` extension now it also supports workflows with the `yaml` extension. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 4b0fa8d4ffb..c45ff2f4732 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.6.2-dev +version: 0.6.2 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index d0933ef06cf..eb914577876 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,23 @@ +## 0.6.2 + +### Major Analysis Improvements + +* Added taint sources from the `@actions/core` and `@actions/github` packages. +* Added command-injection sinks from the `@actions/exec` package. + +### Minor Analysis Improvements + +* The `js/indirect-command-line-injection` query no longer flags command arguments that cannot be interpreted as a shell string. +* The `js/unsafe-deserialization` query no longer flags deserialization through the `js-yaml` library, except + when it is used with an unsafe schema. +* The Forge module in `CryptoLibraries.qll` now correctly classifies SHA-512/224, + SHA-512/256, and SHA-512/384 hashes used in message digests as NonKeyCiphers. + +### Bug Fixes + +* Fixed a spurious diagnostic warning about comments in JSON files being illegal. + Comments in JSON files are in fact fully supported, and the diagnostic message was misleading. + ## 0.6.1 ### Minor Analysis Improvements diff --git a/javascript/ql/src/change-notes/2023-04-13-Forge-truncated-sha512-hash.md b/javascript/ql/src/change-notes/2023-04-13-Forge-truncated-sha512-hash.md deleted file mode 100644 index 1d2bfc9a8f9..00000000000 --- a/javascript/ql/src/change-notes/2023-04-13-Forge-truncated-sha512-hash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* The Forge module in `CryptoLibraries.qll` now correctly classifies SHA-512/224, - SHA-512/256, and SHA-512/384 hashes used in message digests as NonKeyCiphers. \ No newline at end of file diff --git a/javascript/ql/src/change-notes/2023-04-26-unsafe-yaml-deserialization.md b/javascript/ql/src/change-notes/2023-04-26-unsafe-yaml-deserialization.md deleted file mode 100644 index 02b044ee47a..00000000000 --- a/javascript/ql/src/change-notes/2023-04-26-unsafe-yaml-deserialization.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* The `js/unsafe-deserialization` query no longer flags deserialization through the `js-yaml` library, except - when it is used with an unsafe schema. diff --git a/javascript/ql/src/change-notes/2023-04-28-json-with-comments.md b/javascript/ql/src/change-notes/2023-04-28-json-with-comments.md deleted file mode 100644 index 3ce9949a39a..00000000000 --- a/javascript/ql/src/change-notes/2023-04-28-json-with-comments.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: fix ---- -* Fixed a spurious diagnostic warning about comments in JSON files being illegal. - Comments in JSON files are in fact fully supported, and the diagnostic message was misleading. diff --git a/javascript/ql/src/change-notes/2023-05-02-github-actions-sources.md b/javascript/ql/src/change-notes/2023-05-02-github-actions-sources.md deleted file mode 100644 index a9cf1339421..00000000000 --- a/javascript/ql/src/change-notes/2023-05-02-github-actions-sources.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: majorAnalysis ---- -* Added taint sources from the `@actions/core` and `@actions/github` packages. -* Added command-injection sinks from the `@actions/exec` package. diff --git a/javascript/ql/src/change-notes/2023-05-17-indirect-shell.md b/javascript/ql/src/change-notes/2023-05-17-indirect-shell.md deleted file mode 100644 index 556e9976152..00000000000 --- a/javascript/ql/src/change-notes/2023-05-17-indirect-shell.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `js/indirect-command-line-injection` query no longer flags command arguments that cannot be interpreted as a shell string. diff --git a/javascript/ql/src/change-notes/released/0.6.2.md b/javascript/ql/src/change-notes/released/0.6.2.md new file mode 100644 index 00000000000..777dd69688e --- /dev/null +++ b/javascript/ql/src/change-notes/released/0.6.2.md @@ -0,0 +1,19 @@ +## 0.6.2 + +### Major Analysis Improvements + +* Added taint sources from the `@actions/core` and `@actions/github` packages. +* Added command-injection sinks from the `@actions/exec` package. + +### Minor Analysis Improvements + +* The `js/indirect-command-line-injection` query no longer flags command arguments that cannot be interpreted as a shell string. +* The `js/unsafe-deserialization` query no longer flags deserialization through the `js-yaml` library, except + when it is used with an unsafe schema. +* The Forge module in `CryptoLibraries.qll` now correctly classifies SHA-512/224, + SHA-512/256, and SHA-512/384 hashes used in message digests as NonKeyCiphers. + +### Bug Fixes + +* Fixed a spurious diagnostic warning about comments in JSON files being illegal. + Comments in JSON files are in fact fully supported, and the diagnostic message was misleading. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 2c62c9e75d5..f64917ed51f 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.6.2-dev +version: 0.6.2 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 9621c2fa167..46787616efa 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.2 + +No user-facing changes. + ## 0.5.1 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.5.2.md b/misc/suite-helpers/change-notes/released/0.5.2.md new file mode 100644 index 00000000000..e94d1f4ad5b --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.5.2.md @@ -0,0 +1,3 @@ +## 0.5.2 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 0bf7024c337..2d9d3f587f8 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.1 +lastReleaseVersion: 0.5.2 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index c5cf2398633..a66a845730d 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.5.2-dev +version: 0.5.2 groups: shared diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index b00d10f98d9..91f53df486b 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.9.2 + +### Minor Analysis Improvements + +* Type tracking is now aware of reads of captured variables (variables defined in an outer scope). This leads to a richer API graph, and may lead to more results in some queries. +* Added more content-flow/field-flow for dictionaries, by adding support for reads through `mydict.get("key")` and `mydict.setdefault("key", value)`, and store steps through `dict["key"] = value` and `mydict.setdefault("key", value)`. + ## 0.9.1 ### Minor Analysis Improvements diff --git a/python/ql/lib/change-notes/2023-03-16-typetracking-read-captured-variables.md b/python/ql/lib/change-notes/2023-03-16-typetracking-read-captured-variables.md deleted file mode 100644 index 6905a03c8e8..00000000000 --- a/python/ql/lib/change-notes/2023-03-16-typetracking-read-captured-variables.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Type tracking is now aware of reads of captured variables (variables defined in an outer scope). This leads to a richer API graph, and may lead to more results in some queries. diff --git a/python/ql/lib/change-notes/2022-11-15-dictionary-read-store-steps.md b/python/ql/lib/change-notes/released/0.9.2.md similarity index 51% rename from python/ql/lib/change-notes/2022-11-15-dictionary-read-store-steps.md rename to python/ql/lib/change-notes/released/0.9.2.md index 45b225bbb26..06149b0aac9 100644 --- a/python/ql/lib/change-notes/2022-11-15-dictionary-read-store-steps.md +++ b/python/ql/lib/change-notes/released/0.9.2.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.9.2 + +### Minor Analysis Improvements + +* Type tracking is now aware of reads of captured variables (variables defined in an outer scope). This leads to a richer API graph, and may lead to more results in some queries. * Added more content-flow/field-flow for dictionaries, by adding support for reads through `mydict.get("key")` and `mydict.setdefault("key", value)`, and store steps through `dict["key"] = value` and `mydict.setdefault("key", value)`. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 6789dcd18b7..e1eda519435 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.1 +lastReleaseVersion: 0.9.2 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 9948ffa5d7f..be1ec0efa99 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.9.2-dev +version: 0.9.2 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 36f736322c9..712de670fdc 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.2 + +No user-facing changes. + ## 0.7.1 No user-facing changes. diff --git a/python/ql/src/change-notes/released/0.7.2.md b/python/ql/src/change-notes/released/0.7.2.md new file mode 100644 index 00000000000..8693d609ec7 --- /dev/null +++ b/python/ql/src/change-notes/released/0.7.2.md @@ -0,0 +1,3 @@ +## 0.7.2 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index e007a9aec3e..fee171e9685 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.1 +lastReleaseVersion: 0.7.2 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 0d2839ec410..d399ced2ccd 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.7.2-dev +version: 0.7.2 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 2071494bb54..65eba10cc10 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.6.2 + +### Minor Analysis Improvements + +* Support for the `sqlite3` gem has been added. Method calls that execute queries against an SQLite3 database that may be vulnerable to injection attacks will now be recognized. + ## 0.6.1 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/2023-05-03-sqlite3.md b/ruby/ql/lib/change-notes/released/0.6.2.md similarity index 80% rename from ruby/ql/lib/change-notes/2023-05-03-sqlite3.md rename to ruby/ql/lib/change-notes/released/0.6.2.md index 16af7f859e9..a1214bd6e68 100644 --- a/ruby/ql/lib/change-notes/2023-05-03-sqlite3.md +++ b/ruby/ql/lib/change-notes/released/0.6.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.6.2 + +### Minor Analysis Improvements + * Support for the `sqlite3` gem has been added. Method calls that execute queries against an SQLite3 database that may be vulnerable to injection attacks will now be recognized. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index f25ce14aa24..7d01fb676db 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.6.2-dev +version: 0.6.2 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 20ece6388aa..7e2e0df8b38 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.2 + +No user-facing changes. + ## 0.6.1 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/0.6.2.md b/ruby/ql/src/change-notes/released/0.6.2.md new file mode 100644 index 00000000000..43f80640fc5 --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.6.2.md @@ -0,0 +1,3 @@ +## 0.6.2 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 80fb0899f64..5501a2a1cc5 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.1 +lastReleaseVersion: 0.6.2 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index b85dc0f5e4f..2ba1f5ae58f 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.6.2-dev +version: 0.6.2 groups: - ruby - queries diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 64199d2b5ca..cc83ed1e68c 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.13 + +No user-facing changes. + ## 0.0.12 No user-facing changes. diff --git a/shared/regex/change-notes/released/0.0.13.md b/shared/regex/change-notes/released/0.0.13.md new file mode 100644 index 00000000000..f679eaf0313 --- /dev/null +++ b/shared/regex/change-notes/released/0.0.13.md @@ -0,0 +1,3 @@ +## 0.0.13 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index 997fb8da83c..044e54e4f7e 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.12 +lastReleaseVersion: 0.0.13 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index ef9519ead25..deb3ab1029b 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.13-dev +version: 0.0.13 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 52bdc7e1442..5e42000c1d1 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.17 + +No user-facing changes. + ## 0.0.16 No user-facing changes. diff --git a/shared/ssa/change-notes/released/0.0.17.md b/shared/ssa/change-notes/released/0.0.17.md new file mode 100644 index 00000000000..62cc89030a6 --- /dev/null +++ b/shared/ssa/change-notes/released/0.0.17.md @@ -0,0 +1,3 @@ +## 0.0.17 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index a49f7be4cff..cbc3d3cd493 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.16 +lastReleaseVersion: 0.0.17 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 4bb3d04e800..2200a923da4 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.0.17-dev +version: 0.0.17 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index 1e8bd30fccd..02876619527 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.10 + +No user-facing changes. + ## 0.0.9 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/0.0.10.md b/shared/tutorial/change-notes/released/0.0.10.md new file mode 100644 index 00000000000..22391080fd4 --- /dev/null +++ b/shared/tutorial/change-notes/released/0.0.10.md @@ -0,0 +1,3 @@ +## 0.0.10 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index ecdd64fbab8..b740014e5ae 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.9 +lastReleaseVersion: 0.0.10 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 37c2fca38b4..dafd176c023 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.0.10-dev +version: 0.0.10 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index 77af08547b4..c8729dc39f8 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.10 + +No user-facing changes. + ## 0.0.9 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/0.0.10.md b/shared/typetracking/change-notes/released/0.0.10.md new file mode 100644 index 00000000000..22391080fd4 --- /dev/null +++ b/shared/typetracking/change-notes/released/0.0.10.md @@ -0,0 +1,3 @@ +## 0.0.10 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index ecdd64fbab8..b740014e5ae 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.9 +lastReleaseVersion: 0.0.10 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 499f5cc4d34..697964c9078 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.0.10-dev +version: 0.0.10 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 600b6f93329..472d0ef41a5 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.17 + +No user-facing changes. + ## 0.0.16 No user-facing changes. diff --git a/shared/typos/change-notes/released/0.0.17.md b/shared/typos/change-notes/released/0.0.17.md new file mode 100644 index 00000000000..62cc89030a6 --- /dev/null +++ b/shared/typos/change-notes/released/0.0.17.md @@ -0,0 +1,3 @@ +## 0.0.17 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index a49f7be4cff..cbc3d3cd493 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.16 +lastReleaseVersion: 0.0.17 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 6d0b76e1ce5..41595203b56 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.0.17-dev +version: 0.0.17 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index aad25b929dc..99aa576343d 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.10 + +No user-facing changes. + ## 0.0.9 No user-facing changes. diff --git a/shared/util/change-notes/released/0.0.10.md b/shared/util/change-notes/released/0.0.10.md new file mode 100644 index 00000000000..22391080fd4 --- /dev/null +++ b/shared/util/change-notes/released/0.0.10.md @@ -0,0 +1,3 @@ +## 0.0.10 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index ecdd64fbab8..b740014e5ae 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.9 +lastReleaseVersion: 0.0.10 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 8ff9a0efdb6..b6a5d413250 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.0.10-dev +version: 0.0.10 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 9e8194d5e01..9119d5fc839 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 ### Minor Analysis Improvements diff --git a/shared/yaml/change-notes/released/0.0.2.md b/shared/yaml/change-notes/released/0.0.2.md new file mode 100644 index 00000000000..5ab250998ed --- /dev/null +++ b/shared/yaml/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index c6933410b71..55dc06fbd76 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 75a796f2ba3..5f61beb0f39 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.0.2-dev +version: 0.0.2 groups: shared library: true warnOnImplicitThis: true From c9c1f08de7601c00892ff865217fcca1a2729a61 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 23 May 2023 08:36:49 +0200 Subject: [PATCH 069/739] Swift: mark downgrade as backwards compatible --- .../44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties b/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties index 2a0d022be0c..24d1f9b8e02 100644 --- a/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties +++ b/swift/downgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties @@ -1,2 +1,2 @@ description: Revert removing `getInterpolationCountExpr` and `getLiteralCapacityExpr` from `InterpolatedStringLiteralExpr` -compatibility: full +compatibility: backwards From 36147e7afc27cf6cbfb72aa60a4fb62b90d036b8 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 11 May 2023 13:47:58 +0200 Subject: [PATCH 070/739] revert the better super-linear algorith, --- .../regex/nfa/SuperlinearBackTracking.qll | 407 +++++++----------- 1 file changed, 159 insertions(+), 248 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll index 3f16431e165..d06170502b4 100644 --- a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll +++ b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll @@ -9,16 +9,16 @@ * Theorem 3 from the paper describes the basic idea. * * The following explains the idea using variables and predicate names that are used in the implementation: - * We consider a pair of repetitions, which we will call `pivot` and `pumpEnd`. + * We consider a pair of repetitions, which we will call `pivot` and `succ`. * * We create a product automaton of 3-tuples of states (see `StateTuple`). * There exists a transition `(a,b,c) -> (d,e,f)` in the product automaton * iff there exists three transitions in the NFA `a->d, b->e, c->f` where those three * transitions all match a shared character `char`. (see `getAThreewayIntersect`) * - * We start a search in the product automaton at `(pivot, pivot, pumpEnd)`, + * We start a search in the product automaton at `(pivot, pivot, succ)`, * and search for a series of transitions (a `Trace`), such that we end - * at `(pivot, pumpEnd, pumpEnd)` (see `isReachableFromStartTuple`). + * at `(pivot, succ, succ)` (see `isReachableFromStartTuple`). * * For example, consider the regular expression `/^\d*5\w*$/`. * The search will start at the tuple `(\d*, \d*, \w*)` and search @@ -51,30 +51,20 @@ module Make { private State getRootState() { result = mkMatch(any(RegExpRoot r)) } private newtype TStateTuple = - /** - * A tuple of states `(q1, q2, q3)` in the product automaton that is reachable from `(pivot, pivot, pumpEnd)`. - */ - MkStateTuple(State pivot, State pumpEnd, State q1, State q2, State q3) { - // starts at (pivot, pivot, pumpEnd) - isStartLoops(q1, q3) and - q1 = q2 and - pivot = q1 and - pumpEnd = q3 + MkStateTuple(State q1, State q2, State q3) { + // starts at (pivot, pivot, succ) + isStartLoops(q1, q3) and q1 = q2 or - // recurse: any transition out where all 3 edges share a char (and the resulting tuple isn't obviously infeasible) - exists(StateTuple prev | - prev = MkStateTuple(pivot, pumpEnd, _, _, _) and - hasCommonStep(prev, _, _, _, q1, q2, q3) and - FeasibleTuple::isFeasibleTuple(pivot, pumpEnd, q1, q2, q3) - ) + step(_, _, _, _, q1, q2, q3) and FeasibleTuple::isFeasibleTuple(q1, q2, q3) } /** - * A state `(q1, q2, q3)` in the product automaton, that is reachable from `(pivot, pivot, pumpEnd)`. + * A state in the product automaton. + * The product automaton contains 3-tuples of states. * * We lazily only construct those states that we are actually * going to need. - * Either a start state `(pivot, pivot, pumpEnd)`, or a state + * Either a start state `(pivot, pivot, succ)`, or a state * where there exists a transition from an already existing state. * * The exponential variant of this query (`js/redos`) uses an optimization @@ -82,13 +72,11 @@ module Make { * of the elements matter. */ class StateTuple extends TStateTuple { - State pivot; - State pumpEnd; State q1; State q2; State q3; - StateTuple() { this = MkStateTuple(pivot, pumpEnd, q1, q2, q3) } + StateTuple() { this = MkStateTuple(q1, q2, q3) } /** * Gest a string representation of this tuple. @@ -100,39 +88,6 @@ module Make { */ pragma[noinline] predicate isTuple(State r1, State r2, State r3) { r1 = q1 and r2 = q2 and r3 = q3 } - - /** - * Gets the first state of the tuple. - */ - State getFirst() { result = q1 } - - /** - * Gets the second state of the tuple. - */ - State getSecond() { result = q2 } - - /** - * Gets the third state of the tuple. - */ - State getThird() { result = q3 } - - /** - * Gets the pivot state. - */ - State getPivot() { result = pivot } - - /** - * Gets the pumpEnd state. - */ - State getPumpEnd() { result = pumpEnd } - - /** - * Holds if the pivot state has the specified location. - * This location has been chosen arbitrarily, and is only useful for debugging. - */ - predicate hasLocationInfo(string file, int line, int column, int endLine, int endColumn) { - pivot.hasLocationInfo(file, line, column, endLine, endColumn) - } } /** @@ -142,36 +97,21 @@ module Make { */ private module FeasibleTuple { /** - * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state `(pivot, pivot, pumpEnd)` to an end-state `(pivot, pumpEnd, pumpEnd)` in the product automaton. + * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state to an end-state in the product automaton. */ - bindingset[pivot, pumpEnd, r1, r2, r3] - pragma[inline_late] - predicate isFeasibleTuple(State pivot, State pumpEnd, State r1, State r2, State r3) { - isStartLoops(pivot, pumpEnd) and - // r1 can reach the pivot state - reachesBeginning(r1, pivot) and - // r2 and r3 can reach the pumpEnd state - reachesEnd(r2, pumpEnd) and - reachesEnd(r3, pumpEnd) and + pragma[inline] + predicate isFeasibleTuple(State r1, State r2, State r3) { // The first element is either inside a repetition (or the start state itself) isRepetitionOrStart(r1) and // The last element is inside a repetition stateInsideRepetition(r3) and // The states are reachable in the NFA in the order r1 -> r2 -> r3 delta+(r1) = r2 and - delta+(r2) = r3 - } - - pragma[noinline] - private predicate reachesBeginning(State s, State pivot) { - isStartLoops(pivot, _) and - delta+(s) = pivot - } - - pragma[noinline] - private predicate reachesEnd(State s, State pumpEnd) { - isStartLoops(_, pumpEnd) and - delta+(s) = pumpEnd + delta+(r2) = r3 and + // The first element can reach a beginning (the "pivot" state in a `(pivot, succ)` pair). + canReachABeginning(r1) and + // The last element can reach a target (the "succ" state in a `(pivot, succ)` pair). + canReachATarget(r3) } /** @@ -189,18 +129,36 @@ module Make { private predicate stateInsideRepetition(State s) { s.getRepr().getParent*() instanceof InfiniteRepetitionQuantifier } + + /** + * Holds if there exists a path in the NFA from `s` to a "pivot" state + * (from a `(pivot, succ)` pair that starts the search). + */ + pragma[noinline] + private predicate canReachABeginning(State s) { + delta+(s) = any(State pivot | isStartLoops(pivot, _)) + } + + /** + * Holds if there exists a path in the NFA from `s` to a "succ" state + * (from a `(pivot, succ)` pair that starts the search). + */ + pragma[noinline] + private predicate canReachATarget(State s) { + delta+(s) = any(State succ | isStartLoops(_, succ)) + } } /** - * Holds if `pivot` and `pumpEnd` are a pair of loops that could be the beginning of a quadratic blowup. + * Holds if `pivot` and `succ` are a pair of loops that could be the beginning of a quadratic blowup. * - * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != pumpEnd`. - * The case where `pivot = pumpEnd` causes exponential backtracking and is handled by the `js/redos` query. + * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != succ`. + * The case where `pivot = succ` causes exponential backtracking and is handled by the `js/redos` query. */ - predicate isStartLoops(State pivot, State pumpEnd) { - pivot != pumpEnd and - pumpEnd.getRepr() instanceof InfiniteRepetitionQuantifier and - delta+(pivot) = pumpEnd and + predicate isStartLoops(State pivot, State succ) { + pivot != succ and + succ.getRepr() instanceof InfiniteRepetitionQuantifier and + delta+(pivot) = succ and ( pivot.getRepr() instanceof InfiniteRepetitionQuantifier or @@ -216,25 +174,62 @@ module Make { /** * Holds if there are transitions from the components of `q` to the corresponding * components of `r` labelled with `s1`, `s2`, and `s3`, respectively. - * Where the edges `s1`, `s2`, and `s3` all share at least one character. */ pragma[nomagic] - private predicate step(StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r) { + private predicate stepHelper( + StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r + ) { exists(State r1, State r2, State r3 | - hasCommonStep(q, s1, s2, s3, r1, r2, r3) and - r = - MkStateTuple(pragma[only_bind_out](q.getPivot()), pragma[only_bind_out](q.getPumpEnd()), - pragma[only_bind_out](r1), pragma[only_bind_out](r2), pragma[only_bind_out](r3)) + step(q, s1, s2, s3, r1, r2, r3) and r = MkStateTuple(r1, r2, r3) ) } + /** + * Holds if there are transitions from the components of `q` to the corresponding + * components of `r` labelled with `s1`, `s2`, and `s3`, respectively. + * + * Additionally, a heuristic is used to avoid blowups in the case of complex regexps. + * For regular expressions with more than 100 states, we only look at all the characters + * for the transitions out of `q` and only consider transitions that use the lexicographically + * smallest character. + */ + pragma[noinline] + predicate step(StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r) { + stepHelper(q, s1, s2, s3, r) and + ( + countStates(any(State s | q.isTuple(s, _, _)).getRepr().getRootTerm()) < 100 + or + // arbitrarily pick an edge out of `q` for complex regexps. This is a heuristic to avoid potential blowups. + exists(string char | + char = + min(string str, InputSymbol x1, InputSymbol x2, InputSymbol x3 | + stepHelper(q, x1, x2, x3, _) and str = getAStepChar(x1, x2, x3) + | + str + ) and + char = getAStepChar(s1, s2, s3) + ) + ) + } + + // specialized version of `getAThreewayIntersect` to be used in `step` above. + pragma[noinline] + private string getAStepChar(InputSymbol s1, InputSymbol s2, InputSymbol s3) { + stepHelper(_, s1, s2, s3, _) and result = getAThreewayIntersect(s1, s2, s3) + } + + /** Gets the number of states in the NFA for `root`. This is used to determine a complexity metric used in the `step` predicate above. */ + private int countStates(RegExpTerm root) { + root.isRootTerm() and + result = count(State s | s.getRepr().getRootTerm() = root) + } + /** * Holds if there are transitions from the components of `q` to `r1`, `r2`, and `r3 * labelled with `s1`, `s2`, and `s3`, respectively. - * Where `s1`, `s2`, and `s3` all share at least one character. */ pragma[noopt] - predicate hasCommonStep( + predicate step( StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, State r1, State r2, State r3 ) { exists(State q1, State q2, State q3 | q.isTuple(q1, q2, q3) | @@ -269,59 +264,41 @@ module Make { result = [min(intersect(a, b)), max(intersect(a, b))] } - /** Gets a tuple reachable in a forwards exploratory search from the start state `(pivot, pivot, pivot)`. */ - private StateTuple getReachableFromStartStateForwards(State pivot, State pumpEnd) { - // base case. - isStartLoops(pivot, pumpEnd) and - result = MkStateTuple(pivot, pumpEnd, pivot, pivot, pumpEnd) - or - // recursive case - exists(StateTuple p | - p = getReachableFromStartStateForwards(pivot, pumpEnd) and - step(p, _, _, _, result) - ) - } + private newtype TTrace = + Nil() or + Step(InputSymbol s1, InputSymbol s2, InputSymbol s3, TTrace t) { + isReachableFromStartTuple(_, _, t, s1, s2, s3, _, _) + } /** - * Gets a state tuple that can reach the end state `(pivot, pumpEnd, pumpEnd)`, found via a backwards exploratory search. - * Where the end state was reachable from a forwards search from the start state `(pivot, pivot, pumpEnd)`. - * The resulting tuples are exactly those that are on a path from the start state to the end state. + * A list of tuples of input symbols that describe a path in the product automaton + * starting from some start state. */ - private StateTuple getARelevantStateTuple(State pivot, State pumpEnd) { - // base case. - isStartLoops(pivot, pumpEnd) and - result = MkStateTuple(pivot, pumpEnd, pivot, pumpEnd, pumpEnd) and - result = getReachableFromStartStateForwards(pivot, pumpEnd) - or - // recursive case - exists(StateTuple p | - p = getARelevantStateTuple(pivot, pumpEnd) and - step(result, _, _, _, p) and - pragma[only_bind_out](result) = getReachableFromStartStateForwards(pivot, pumpEnd) // was reachable in the forwards pass. - ) + class Trace extends TTrace { + /** + * Gets a string representation of this Trace that can be used for debug purposes. + */ + string toString() { + this = Nil() and result = "Nil()" + or + exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace t | this = Step(s1, s2, s3, t) | + result = "Step(" + s1 + ", " + s2 + ", " + s3 + ", " + t + ")" + ) + } } /** - * Holds if there exists a transition from `src` to `dst` in the product automaton. - * Where `src` and `dst` are both on a path from a start state to an end state. + * Holds if there exists a transition from `r` to `q` in the product automaton. * Notice that the arguments are flipped, and thus the direction is backwards. */ pragma[noinline] - predicate tupleDeltaBackwards(StateTuple dst, StateTuple src) { - step(src, _, _, _, dst) and - // `step` ensures that `src` and `dst` have the same pivot and pumpEnd. - src = getARelevantStateTuple(_, _) and - dst = getARelevantStateTuple(_, _) - } + predicate tupleDeltaBackwards(StateTuple q, StateTuple r) { step(r, _, _, _, q) } /** - * Holds if `tuple` is an end state in our search, and `tuple` is on a path from a start state to an end state. - * That means there exists a pair of loops `(pivot, pumpEnd)` such that `tuple = (pivot, pumpEnd, pumpEnd)`. + * Holds if `tuple` is an end state in our search. + * That means there exists a pair of loops `(pivot, succ)` such that `tuple = (pivot, succ, succ)`. */ - predicate isEndTuple(StateTuple tuple) { - tuple = getEndTuple(_, _) and - tuple = getARelevantStateTuple(_, _) - } + predicate isEndTuple(StateTuple tuple) { tuple = getAnEndTuple(_, _) } /** * Gets the minimum length of a path from `r` to some an end state `end`. @@ -334,138 +311,72 @@ module Make { shortestDistances(isEndTuple/1, tupleDeltaBackwards/2)(end, r, result) /** - * Holds if there is a step from `q` to `r` in the product automaton labeled with `s1`, `s2`, and `s3`. - * Where the step is on a path from a start state to an end state. + * Holds if there exists a pair of repetitions `(pivot, succ)` in the regular expression such that: + * `tuple` is reachable from `(pivot, pivot, succ)` in the product automaton, + * and there is a distance of `dist` from `tuple` to the nearest end-tuple `(pivot, succ, succ)`, + * and a path from a start-state to `tuple` follows the transitions in `trace`. */ - private predicate isStepOnPath( - StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r + private predicate isReachableFromStartTuple( + State pivot, State succ, StateTuple tuple, Trace trace, int dist ) { - step(q, s1, s2, s3, r) and - exists(State pivot, State pumpEnd, StateTuple end | - end = MkStateTuple(pivot, pumpEnd, pivot, pumpEnd, pumpEnd) and - pragma[only_bind_out](distBackFromEnd(q, end)) = - pragma[only_bind_out](distBackFromEnd(r, end)) + 1 + exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace v | + isReachableFromStartTuple(pivot, succ, v, s1, s2, s3, tuple, dist) and + trace = Step(s1, s2, s3, v) + ) + } + + private predicate isReachableFromStartTuple( + State pivot, State succ, Trace trace, InputSymbol s1, InputSymbol s2, InputSymbol s3, + StateTuple tuple, int dist + ) { + // base case. + isStartLoops(pivot, succ) and + step(MkStateTuple(pivot, pivot, succ), s1, s2, s3, tuple) and + tuple = MkStateTuple(_, _, _) and + trace = Nil() and + dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) + or + // recursive case + exists(StateTuple p | + isReachableFromStartTuple(pivot, succ, p, trace, dist + 1) and + dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) and + step(p, s1, s2, s3, tuple) ) } /** - * Gets a unique number for a `state`. - * Is used to create an ordering of states and tuples of states. + * Gets the tuple `(pivot, succ, succ)` from the product automaton. */ - private int rankState(State state) { - state = - rank[result](State s, int startLine, int endLine, int startColumn, int endColumn | - exists(StateTuple tuple | tuple = getARelevantStateTuple(_, _) | - s = [tuple.getFirst(), tuple.getSecond(), tuple.getThird()] and - s.getRepr().hasLocationInfo(_, startLine, startColumn, endLine, endColumn) - ) - | - s order by startLine, startColumn, endLine, endColumn - ) - } - - /** - * Holds if there is a step from `q` to `r` in the product automaton labeled with `s1`, `s2`, and `s3`. - * Where the step is on a path from a start state to an end state. - * And the step is a uniquely chosen step from out of `q`. - */ - pragma[nomagic] - private predicate isUniqueMinStepOnPath( - StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r - ) { - isStepOnPath(q, s1, s2, s3, r) and - r = - min(StateTuple cand | - isStepOnPath(q, _, _, _, cand) - | - cand - order by - rankState(cand.getFirst()), rankState(cand.getSecond()), rankState(cand.getThird()) - ) - } - - private newtype TTrace = - Nil(State pivot, State pumpEnd) { - isStartLoops(pivot, pumpEnd) and - getStartTuple(pivot, pumpEnd) = getARelevantStateTuple(pivot, pumpEnd) - } or - Step(TTrace prev, StateTuple nextTuple) { - exists(StateTuple prevTuple | - exists(State pivot, State pumpEnd | - prev = Nil(pivot, pumpEnd) and - prevTuple = getStartTuple(pivot, pumpEnd) - ) - or - prev = Step(_, prevTuple) - | - isUniqueMinStepOnPath(prevTuple, _, _, _, nextTuple) - ) - } - - /** - * A list of tuples of input symbols that describe a path in the product automaton - * starting from a start state `(pivot, pivot, pumpEnd)`. - */ - class Trace extends TTrace { - /** - * Gets a string representation of this Trace that can be used for debug purposes. - */ - string toString() { result = "a trace" } - - /** Gets a trace where the head has been removed. */ - Trace getPrev() { this = Step(result, _) } - - /** Gets the tuple at the head of this trace. */ - StateTuple getTuple() { - this = Step(_, result) - or - exists(State prev, State pumpEnd | - this = Nil(prev, pumpEnd) and - result = getStartTuple(prev, pumpEnd) - ) - } - } - - /** - * Gets the tuple `(pivot, pumpEnd, pumpEnd)` from the product automaton. - */ - StateTuple getEndTuple(State pivot, State pumpEnd) { - isStartLoops(pivot, pumpEnd) and - result = MkStateTuple(pivot, pumpEnd, pivot, pumpEnd, pumpEnd) - } - - /** - * Gets the tuple `(pivot, pivot, pumpEnd)` from the product automaton. - */ - StateTuple getStartTuple(State pivot, State pumpEnd) { - isStartLoops(pivot, pumpEnd) and - result = MkStateTuple(pivot, pumpEnd, pivot, pivot, pumpEnd) + StateTuple getAnEndTuple(State pivot, State succ) { + isStartLoops(pivot, succ) and + result = MkStateTuple(pivot, succ, succ) } /** An implementation of a chain containing chars for use by `Concretizer`. */ private module CharTreeImpl implements CharTree { class CharNode = Trace; - CharNode getPrev(CharNode t) { result = t.getPrev() } + CharNode getPrev(CharNode t) { t = Step(_, _, _, result) } - predicate isARelevantEnd(CharNode n) { n.getTuple() = getEndTuple(_, _) } + /** Holds if `n` is used in `isPumpable`. */ + predicate isARelevantEnd(CharNode n) { + exists(State pivot, State succ | + isReachableFromStartTuple(pivot, succ, getAnEndTuple(pivot, succ), n, _) + ) + } string getChar(CharNode t) { - result = - min(string c, InputSymbol s1, InputSymbol s2, InputSymbol s3 | - isUniqueMinStepOnPath(t.getPrev().getTuple(), s1, s2, s3, t.getTuple()) and - c = getAThreewayIntersect(s1, s2, s3) - | - c - ) + exists(InputSymbol s1, InputSymbol s2, InputSymbol s3 | t = Step(s1, s2, s3, _) | + result = getAThreewayIntersect(s1, s2, s3) + ) } } /** * Holds if matching repetitions of `pump` can: * 1) Transition from `pivot` back to `pivot`. - * 2) Transition from `pivot` to `pumpEnd`. - * 3) Transition from `pumpEnd` to `pumpEnd`. + * 2) Transition from `pivot` to `succ`. + * 3) Transition from `succ` to `succ`. * * From theorem 3 in the paper linked in the top of this file we can therefore conclude that * the regular expression has polynomial backtracking - if a rejecting suffix exists. @@ -473,10 +384,10 @@ module Make { * This predicate is used by `SuperLinearReDoSConfiguration`, and the final results are * available in the `hasReDoSResult` predicate. */ - predicate isPumpable(State pivot, State pumpEnd, string pump) { + predicate isPumpable(State pivot, State succ, string pump) { exists(StateTuple q, Trace t | - q = getEndTuple(pivot, pumpEnd) and - q = t.getTuple() and + isReachableFromStartTuple(pivot, succ, q, t, _) and + q = getAnEndTuple(pivot, succ) and pump = Concretizer::concretize(t) ) } From efa53d21faaa54cb38217fe837826e79f467b4ba Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 11 May 2023 13:49:18 +0200 Subject: [PATCH 071/739] rename `succ` to `pumpEnd` --- .../regex/nfa/SuperlinearBackTracking.qll | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll index d06170502b4..43d8e8a73db 100644 --- a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll +++ b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll @@ -9,16 +9,16 @@ * Theorem 3 from the paper describes the basic idea. * * The following explains the idea using variables and predicate names that are used in the implementation: - * We consider a pair of repetitions, which we will call `pivot` and `succ`. + * We consider a pair of repetitions, which we will call `pivot` and `pumpEnd`. * * We create a product automaton of 3-tuples of states (see `StateTuple`). * There exists a transition `(a,b,c) -> (d,e,f)` in the product automaton * iff there exists three transitions in the NFA `a->d, b->e, c->f` where those three * transitions all match a shared character `char`. (see `getAThreewayIntersect`) * - * We start a search in the product automaton at `(pivot, pivot, succ)`, + * We start a search in the product automaton at `(pivot, pivot, pumpEnd)`, * and search for a series of transitions (a `Trace`), such that we end - * at `(pivot, succ, succ)` (see `isReachableFromStartTuple`). + * at `(pivot, pumpEnd, pumpEnd)` (see `isReachableFromStartTuple`). * * For example, consider the regular expression `/^\d*5\w*$/`. * The search will start at the tuple `(\d*, \d*, \w*)` and search @@ -52,7 +52,7 @@ module Make { private newtype TStateTuple = MkStateTuple(State q1, State q2, State q3) { - // starts at (pivot, pivot, succ) + // starts at (pivot, pivot, pumpEnd) isStartLoops(q1, q3) and q1 = q2 or step(_, _, _, _, q1, q2, q3) and FeasibleTuple::isFeasibleTuple(q1, q2, q3) @@ -64,7 +64,7 @@ module Make { * * We lazily only construct those states that we are actually * going to need. - * Either a start state `(pivot, pivot, succ)`, or a state + * Either a start state `(pivot, pivot, pumpEnd)`, or a state * where there exists a transition from an already existing state. * * The exponential variant of this query (`js/redos`) uses an optimization @@ -108,9 +108,9 @@ module Make { // The states are reachable in the NFA in the order r1 -> r2 -> r3 delta+(r1) = r2 and delta+(r2) = r3 and - // The first element can reach a beginning (the "pivot" state in a `(pivot, succ)` pair). + // The first element can reach a beginning (the "pivot" state in a `(pivot, pumpEnd)` pair). canReachABeginning(r1) and - // The last element can reach a target (the "succ" state in a `(pivot, succ)` pair). + // The last element can reach a target (the "pumpEnd" state in a `(pivot, pumpEnd)` pair). canReachATarget(r3) } @@ -132,7 +132,7 @@ module Make { /** * Holds if there exists a path in the NFA from `s` to a "pivot" state - * (from a `(pivot, succ)` pair that starts the search). + * (from a `(pivot, pumpEnd)` pair that starts the search). */ pragma[noinline] private predicate canReachABeginning(State s) { @@ -140,25 +140,25 @@ module Make { } /** - * Holds if there exists a path in the NFA from `s` to a "succ" state - * (from a `(pivot, succ)` pair that starts the search). + * Holds if there exists a path in the NFA from `s` to a "pumpEnd" state + * (from a `(pivot, pumpEnd)` pair that starts the search). */ pragma[noinline] private predicate canReachATarget(State s) { - delta+(s) = any(State succ | isStartLoops(_, succ)) + delta+(s) = any(State pumpEnd | isStartLoops(_, pumpEnd)) } } /** - * Holds if `pivot` and `succ` are a pair of loops that could be the beginning of a quadratic blowup. + * Holds if `pivot` and `pumpEnd` are a pair of loops that could be the beginning of a quadratic blowup. * - * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != succ`. - * The case where `pivot = succ` causes exponential backtracking and is handled by the `js/redos` query. + * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != pumpEnd`. + * The case where `pivot = pumpEnd` causes exponential backtracking and is handled by the `js/redos` query. */ - predicate isStartLoops(State pivot, State succ) { - pivot != succ and - succ.getRepr() instanceof InfiniteRepetitionQuantifier and - delta+(pivot) = succ and + predicate isStartLoops(State pivot, State pumpEnd) { + pivot != pumpEnd and + pumpEnd.getRepr() instanceof InfiniteRepetitionQuantifier and + delta+(pivot) = pumpEnd and ( pivot.getRepr() instanceof InfiniteRepetitionQuantifier or @@ -296,7 +296,7 @@ module Make { /** * Holds if `tuple` is an end state in our search. - * That means there exists a pair of loops `(pivot, succ)` such that `tuple = (pivot, succ, succ)`. + * That means there exists a pair of loops `(pivot, pumpEnd)` such that `tuple = (pivot, pumpEnd, pumpEnd)`. */ predicate isEndTuple(StateTuple tuple) { tuple = getAnEndTuple(_, _) } @@ -311,45 +311,45 @@ module Make { shortestDistances(isEndTuple/1, tupleDeltaBackwards/2)(end, r, result) /** - * Holds if there exists a pair of repetitions `(pivot, succ)` in the regular expression such that: - * `tuple` is reachable from `(pivot, pivot, succ)` in the product automaton, - * and there is a distance of `dist` from `tuple` to the nearest end-tuple `(pivot, succ, succ)`, + * Holds if there exists a pair of repetitions `(pivot, pumpEnd)` in the regular expression such that: + * `tuple` is reachable from `(pivot, pivot, pumpEnd)` in the product automaton, + * and there is a distance of `dist` from `tuple` to the nearest end-tuple `(pivot, pumpEnd, pumpEnd)`, * and a path from a start-state to `tuple` follows the transitions in `trace`. */ private predicate isReachableFromStartTuple( - State pivot, State succ, StateTuple tuple, Trace trace, int dist + State pivot, State pumpEnd, StateTuple tuple, Trace trace, int dist ) { exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace v | - isReachableFromStartTuple(pivot, succ, v, s1, s2, s3, tuple, dist) and + isReachableFromStartTuple(pivot, pumpEnd, v, s1, s2, s3, tuple, dist) and trace = Step(s1, s2, s3, v) ) } private predicate isReachableFromStartTuple( - State pivot, State succ, Trace trace, InputSymbol s1, InputSymbol s2, InputSymbol s3, + State pivot, State pumpEnd, Trace trace, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple tuple, int dist ) { // base case. - isStartLoops(pivot, succ) and - step(MkStateTuple(pivot, pivot, succ), s1, s2, s3, tuple) and + isStartLoops(pivot, pumpEnd) and + step(MkStateTuple(pivot, pivot, pumpEnd), s1, s2, s3, tuple) and tuple = MkStateTuple(_, _, _) and trace = Nil() and - dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) + dist = distBackFromEnd(tuple, MkStateTuple(pivot, pumpEnd, pumpEnd)) or // recursive case exists(StateTuple p | - isReachableFromStartTuple(pivot, succ, p, trace, dist + 1) and - dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) and + isReachableFromStartTuple(pivot, pumpEnd, p, trace, dist + 1) and + dist = distBackFromEnd(tuple, MkStateTuple(pivot, pumpEnd, pumpEnd)) and step(p, s1, s2, s3, tuple) ) } /** - * Gets the tuple `(pivot, succ, succ)` from the product automaton. + * Gets the tuple `(pivot, pumpEnd, pumpEnd)` from the product automaton. */ - StateTuple getAnEndTuple(State pivot, State succ) { - isStartLoops(pivot, succ) and - result = MkStateTuple(pivot, succ, succ) + StateTuple getAnEndTuple(State pivot, State pumpEnd) { + isStartLoops(pivot, pumpEnd) and + result = MkStateTuple(pivot, pumpEnd, pumpEnd) } /** An implementation of a chain containing chars for use by `Concretizer`. */ @@ -360,8 +360,8 @@ module Make { /** Holds if `n` is used in `isPumpable`. */ predicate isARelevantEnd(CharNode n) { - exists(State pivot, State succ | - isReachableFromStartTuple(pivot, succ, getAnEndTuple(pivot, succ), n, _) + exists(State pivot, State pumpEnd | + isReachableFromStartTuple(pivot, pumpEnd, getAnEndTuple(pivot, pumpEnd), n, _) ) } @@ -375,8 +375,8 @@ module Make { /** * Holds if matching repetitions of `pump` can: * 1) Transition from `pivot` back to `pivot`. - * 2) Transition from `pivot` to `succ`. - * 3) Transition from `succ` to `succ`. + * 2) Transition from `pivot` to `pumpEnd`. + * 3) Transition from `pumpEnd` to `pumpEnd`. * * From theorem 3 in the paper linked in the top of this file we can therefore conclude that * the regular expression has polynomial backtracking - if a rejecting suffix exists. @@ -384,10 +384,10 @@ module Make { * This predicate is used by `SuperLinearReDoSConfiguration`, and the final results are * available in the `hasReDoSResult` predicate. */ - predicate isPumpable(State pivot, State succ, string pump) { + predicate isPumpable(State pivot, State pumpEnd, string pump) { exists(StateTuple q, Trace t | - isReachableFromStartTuple(pivot, succ, q, t, _) and - q = getAnEndTuple(pivot, succ) and + isReachableFromStartTuple(pivot, pumpEnd, q, t, _) and + q = getAnEndTuple(pivot, pumpEnd) and pump = Concretizer::concretize(t) ) } @@ -439,8 +439,8 @@ module Make { * Holds if all non-empty successors to the polynomial backtracking term matches the end of the line. */ predicate isAtEndLine() { - forall(RegExpTerm succ | super.getSuccessor+() = succ and not matchesEpsilon(succ) | - succ instanceof RegExpDollar + forall(RegExpTerm pumpEnd | super.getSuccessor+() = pumpEnd and not matchesEpsilon(pumpEnd) | + pumpEnd instanceof RegExpDollar ) } From f85b3e13c2326fe515c71f9587bb38ff229f0ae4 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 11 May 2023 13:53:16 +0200 Subject: [PATCH 072/739] update expected output --- .../Security/CWE-400/ReDoS/PolynomialReDoS.expected | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected index 0ec4c40fd2c..4c534fffe13 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected @@ -163,6 +163,8 @@ nodes | polynomial-redos.js:65:24:65:30 | tainted | | polynomial-redos.js:66:19:66:25 | tainted | | polynomial-redos.js:66:19:66:25 | tainted | +| polynomial-redos.js:67:18:67:24 | tainted | +| polynomial-redos.js:67:18:67:24 | tainted | | polynomial-redos.js:68:18:68:24 | req.url | | polynomial-redos.js:68:18:68:24 | req.url | | polynomial-redos.js:68:18:68:24 | req.url | @@ -219,6 +221,8 @@ nodes | polynomial-redos.js:112:2:112:8 | tainted | | polynomial-redos.js:114:2:114:8 | tainted | | polynomial-redos.js:114:2:114:8 | tainted | +| polynomial-redos.js:116:2:116:8 | tainted | +| polynomial-redos.js:116:2:116:8 | tainted | | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:121:7:121:55 | replaced | @@ -403,6 +407,8 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:65:24:65:30 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:73:2:73:8 | tainted | @@ -453,6 +459,8 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:112:2:112:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:121:18:121:24 | tainted | @@ -547,6 +555,7 @@ edges | polynomial-redos.js:64:3:64:31 | /^foo(K ... ainted) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:64:24:64:30 | tainted | This $@ that depends on $@ may run slow on strings starting with 'fooY' and with many repetitions of 'Y'. | polynomial-redos.js:64:14:64:15 | Y* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:65:3:65:31 | /^foo(K ... ainted) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:65:24:65:30 | tainted | This $@ that depends on $@ may run slow on strings starting with 'fooY' and with many repetitions of 'K'. | polynomial-redos.js:65:14:65:15 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:66:3:66:26 | /(K\|Y). ... ainted) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:66:19:66:25 | tainted | This $@ that depends on $@ may run slow on strings starting with 'K' and with many repetitions of 'K'. | polynomial-redos.js:66:9:66:10 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:67:3:67:25 | /[^Y].* ... ainted) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:67:18:67:24 | tainted | This $@ that depends on $@ may run slow on strings starting with 'X' and with many repetitions of 'Z'. | polynomial-redos.js:67:8:67:9 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:69:3:69:26 | /[^Y].* ... q.body) | polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body | This $@ that depends on $@ may run slow on strings starting with 'X' and with many repetitions of 'X'. | polynomial-redos.js:69:8:69:9 | .* | regular expression | polynomial-redos.js:69:18:69:25 | req.body | a user-provided value | | polynomial-redos.js:71:2:71:67 | tainted ... E]*)$/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:71:2:71:8 | tainted | This $@ that depends on $@ may run slow on strings starting with ',-+' and with many repetitions of '++'. | polynomial-redos.js:71:51:71:63 | [?\\x21-\\x7E]* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:73:2:73:60 | tainted ... LWP7")) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:73:2:73:8 | tainted | This $@ that depends on $@ may run slow on strings starting with 'MSIE 0.0' and with many repetitions of '0'. | polynomial-redos.js:73:50:73:51 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | @@ -574,6 +583,7 @@ edges | polynomial-redos.js:111:2:111:22 | tainted ... /\\s*$/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:111:2:111:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of '\\t'. | polynomial-redos.js:111:17:111:19 | \\s* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:112:2:112:22 | tainted ... /\\s+$/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:112:2:112:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of '\\t'. | polynomial-redos.js:112:17:112:19 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:114:2:114:27 | tainted ... 5\\w*$/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:114:2:114:8 | tainted | This $@ that depends on $@ may run slow on strings starting with '5' and with many repetitions of '5'. | polynomial-redos.js:114:22:114:24 | \\w* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:116:2:116:35 | tainted ... \\*\\//g) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:116:2:116:8 | tainted | This $@ that depends on $@ may run slow on strings starting with '/*' and with many repetitions of 'a/*'. | polynomial-redos.js:116:21:116:28 | [\\d\\D]*? | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:118:2:118:25 | tainted ... \\d+)+/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:118:2:118:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of '0'. | polynomial-redos.js:118:17:118:23 | (#\\d+)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:124:12:124:43 | result. ... /g, '') | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:124:12:124:17 | result | This $@ that depends on $@ may run slow on strings with many repetitions of '\\t'. | polynomial-redos.js:124:33:124:35 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:130:2:130:31 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:130:2:130:9 | modified | This $@ that depends on $@ may run slow on strings starting with 'c' and with many repetitions of 'c'. | polynomial-redos.js:130:21:130:22 | c+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | From c7e21ee9aef8b90d723a1277df951775066f2c8e Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 11 May 2023 13:57:16 +0200 Subject: [PATCH 073/739] add really long regex as a test-case --- .../PolynomialReDoS.expected | 9 ++++++ .../PolynomialReDoS.rb | 28 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected index 97de9e92184..ec079020695 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected @@ -40,6 +40,9 @@ edges | PolynomialReDoS.rb:70:12:70:24 | ...[...] | PolynomialReDoS.rb:70:5:70:8 | name | | PolynomialReDoS.rb:73:32:73:35 | name | PolynomialReDoS.rb:76:35:76:39 | input | | PolynomialReDoS.rb:76:35:76:39 | input | PolynomialReDoS.rb:77:5:77:9 | input | +| PolynomialReDoS.rb:103:5:103:8 | name | PolynomialReDoS.rb:105:5:105:8 | name | +| PolynomialReDoS.rb:103:12:103:17 | call to params | PolynomialReDoS.rb:103:12:103:24 | ...[...] | +| PolynomialReDoS.rb:103:12:103:24 | ...[...] | PolynomialReDoS.rb:103:5:103:8 | name | | lib/index.rb:2:11:2:11 | x | lib/index.rb:4:13:4:13 | x | | lib/index.rb:8:13:8:13 | x | lib/index.rb:9:15:9:15 | x | | lib/index.rb:8:13:8:13 | x | lib/index.rb:11:16:11:16 | x | @@ -91,6 +94,10 @@ nodes | PolynomialReDoS.rb:73:32:73:35 | name | semmle.label | name | | PolynomialReDoS.rb:76:35:76:39 | input | semmle.label | input | | PolynomialReDoS.rb:77:5:77:9 | input | semmle.label | input | +| PolynomialReDoS.rb:103:5:103:8 | name | semmle.label | name | +| PolynomialReDoS.rb:103:12:103:17 | call to params | semmle.label | call to params | +| PolynomialReDoS.rb:103:12:103:24 | ...[...] | semmle.label | ...[...] | +| PolynomialReDoS.rb:105:5:105:8 | name | semmle.label | name | | lib/index.rb:2:11:2:11 | x | semmle.label | x | | lib/index.rb:4:13:4:13 | x | semmle.label | x | | lib/index.rb:8:13:8:13 | x | semmle.label | x | @@ -121,6 +128,8 @@ subpaths | PolynomialReDoS.rb:62:5:62:22 | call to gsub | PolynomialReDoS.rb:54:12:54:17 | call to params | PolynomialReDoS.rb:62:5:62:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:56:31:56:33 | \\s+ | regular expression | PolynomialReDoS.rb:54:12:54:17 | call to params | user-provided value | | PolynomialReDoS.rb:66:5:66:34 | call to match? | PolynomialReDoS.rb:54:12:54:17 | call to params | PolynomialReDoS.rb:66:5:66:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:58:30:58:32 | \\s+ | regular expression | PolynomialReDoS.rb:54:12:54:17 | call to params | user-provided value | | PolynomialReDoS.rb:77:5:77:22 | call to gsub | PolynomialReDoS.rb:70:12:70:17 | call to params | PolynomialReDoS.rb:77:5:77:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:72:28:72:30 | \\s+ | regular expression | PolynomialReDoS.rb:70:12:70:17 | call to params | user-provided value | +| PolynomialReDoS.rb:105:5:105:23 | ... =~ ... | PolynomialReDoS.rb:103:12:103:17 | call to params | PolynomialReDoS.rb:105:5:105:8 | name | This $@ that depends on a $@ may run slow on strings starting with '''' and with many repetitions of ' '. | PolynomialReDoS.rb:100:397:100:399 | \\s* | regular expression | PolynomialReDoS.rb:103:12:103:17 | call to params | user-provided value | +| PolynomialReDoS.rb:105:5:105:23 | ... =~ ... | PolynomialReDoS.rb:103:12:103:17 | call to params | PolynomialReDoS.rb:105:5:105:8 | name | This $@ that depends on a $@ may run slow on strings starting with '''' and with many repetitions of ' '. | PolynomialReDoS.rb:100:405:100:407 | \\s* | regular expression | PolynomialReDoS.rb:103:12:103:17 | call to params | user-provided value | | lib/index.rb:4:13:4:26 | call to match | lib/index.rb:2:11:2:11 | x | lib/index.rb:4:13:4:13 | x | This $@ that depends on a $@ may run slow on strings with many repetitions of 'a'. | lib/index.rb:4:22:4:23 | a+ | regular expression | lib/index.rb:2:11:2:11 | x | library input | | lib/index.rb:9:15:9:28 | call to match | lib/index.rb:8:13:8:13 | x | lib/index.rb:9:15:9:15 | x | This $@ that depends on a $@ may run slow on strings with many repetitions of 'a'. | lib/index.rb:9:24:9:25 | a+ | regular expression | lib/index.rb:8:13:8:13 | x | library input | | lib/index.rb:11:16:11:276 | call to match | lib/index.rb:8:13:8:13 | x | lib/index.rb:11:16:11:16 | x | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | lib/index.rb:11:271:11:272 | .* | regular expression | lib/index.rb:8:13:8:13 | x | library input | diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.rb b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.rb index d97f7413f82..2f73209321f 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.rb +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.rb @@ -76,4 +76,32 @@ class FooController < ActionController::Base def re_compile_indirect_2 (reg, input) input.gsub reg, '' # NOT GOOD end + + # See https://github.com/dependabot/dependabot-core/blob/37dc1767fde9b7184020763f4d0c1434f93d11d6/python/lib/dependabot/python/requirement_parser.rb#L6-L25 + NAME = /[a-zA-Z0-9](?:[a-zA-Z0-9\-_\.]*[a-zA-Z0-9])?/ + EXTRA = /[a-zA-Z0-9\-_\.]+/ + COMPARISON = /===|==|>=|<=|<|>|~=|!=/ + VERSION = /([1-9][0-9]*!)?[0-9]+[a-zA-Z0-9\-_.*]*(\+[0-9a-zA-Z]+(\.[0-9a-zA-Z]+)*)?/ + + REQUIREMENT = /(?#{COMPARISON})\s*\\?\s*(?#{VERSION})/ + HASH = /--hash=(?.*?):(?.*?)(?=\s|\\|$)/ + REQUIREMENTS = /#{REQUIREMENT}(\s*,\s*\\?\s*#{REQUIREMENT})*/ + HASHES = /#{HASH}(\s*\\?\s*#{HASH})*/ + MARKER_OP = /\s*(#{COMPARISON}|(\s*in)|(\s*not\s*in))/ + PYTHON_STR_C = %r{[a-zA-Z0-9\s\(\)\.\{\}\-_\*#:;/\?\[\]!~`@\$%\^&=\+\|<>]} + PYTHON_STR = /('(#{PYTHON_STR_C}|")*'|"(#{PYTHON_STR_C}|')*")/ + ENV_VAR = + /python_version|python_full_version|os_name|sys_platform| + platform_release|platform_system|platform_version|platform_machine| + platform_python_implementation|implementation_name| + implementation_version/ + MARKER_VAR = /\s*(#{ENV_VAR}|#{PYTHON_STR})/ + MARKER_EXPR_ONE = /#{MARKER_VAR}#{MARKER_OP}#{MARKER_VAR}/ + MARKER_EXPR = /(#{MARKER_EXPR_ONE}|\(\s*|\s*\)|\s+and\s+|\s+or\s+)+/ + + def use_marker_expr + name = params[:name] # source + + name =~ MARKER_EXPR + end end From f7419c92501593bc187fe56319a54efc62f9f0e6 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 12 May 2023 09:26:03 +0200 Subject: [PATCH 074/739] add expected output --- .../ReDoS/PolynomialBackTracking.expected | 73 ++++++++----------- 1 file changed, 30 insertions(+), 43 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected index db29a305639..d8bac89a913 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialBackTracking.expected @@ -1,5 +1,5 @@ -| highlight.js:2:26:2:979 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'ip\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | -| highlight.js:3:27:3:971 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'ip\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | +| highlight.js:2:26:2:979 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'aaa\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | +| highlight.js:3:27:3:971 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'aaa\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | | highlight.js:6:12:6:695 | (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|New\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+ | Strings with many repetitions of 'Add' can start matching anywhere after the start of the preceeding (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|New\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+(-)[\\w\\d]+ | | highlight.js:7:13:7:692 | (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+ | Strings with many repetitions of 'Add' can start matching anywhere after the start of the preceeding (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+(-)[\\w\\d]+ | | highlight.js:14:17:14:52 | [a-z0-9&#*=?@\\\\><:,()$[\\]_.{}!+%^-]+ | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding ([ ]*[a-z0-9&#*=?@\\\\><:,()$[\\]_.{}!+%^-]+)+ | @@ -7,8 +7,7 @@ | highlight.js:18:20:18:22 | .*? | Strings starting with '"' and with many repetitions of '"' can start matching anywhere after the start of the preceeding .*? | | highlight.js:18:27:18:29 | .*? | Strings starting with '[' and with many repetitions of '[' can start matching anywhere after the start of the preceeding .*? | | highlight.js:18:33:18:69 | [^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+ | Strings with many repetitions of '$' can start matching anywhere after the start of the preceeding .*? | -| highlight.js:19:56:19:61 | [^\\]]+ | Strings starting with '[' and with many repetitions of '[' can start matching anywhere after the start of the preceeding (\\.\|\\.\\/\|\\/)?(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+)((\\.\|\\/)(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+))* | -| highlight.js:19:141:19:146 | [^\\]]+ | Strings starting with '"".[' and with many repetitions of '$.[' can start matching anywhere after the start of the preceeding (\\.\|\\.\\/\|\\/)?(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+)((\\.\|\\/)(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+))* | +| highlight.js:19:56:19:61 | [^\\]]+ | Strings starting with '[' and with many repetitions of '.[' can start matching anywhere after the start of the preceeding (\\.\|\\.\\/\|\\/)?(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+)((\\.\|\\/)(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+))* | | highlight.js:22:12:22:82 | ((decltype\\(auto\\)\|(?:[a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(?:<.*?>)?)[\\*&\\s]+)+ | Strings with many repetitions of 'A\\t' can start matching anywhere after the start of the preceeding .*? | | highlight.js:22:43:22:45 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding .*? | | highlight.js:22:66:22:68 | .*? | Strings starting with 'A<' and with many repetitions of 'A<' can start matching anywhere after the start of the preceeding \\w* | @@ -17,8 +16,8 @@ | highlight.js:23:42:23:44 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding ((decltype\\(auto\\)\|([a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(<[^<>]+>)?)[\\*&\\s]+)+([a-zA-Z_]\\w*::)?[a-zA-Z]\\w*\\s*\\( | | highlight.js:23:63:23:68 | [^<>]+ | Strings starting with 'A<' and with many repetitions of ';>\\tA<' can start matching anywhere after the start of the preceeding ((decltype\\(auto\\)\|([a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(<[^<>]+>)?)[\\*&\\s]+)+([a-zA-Z_]\\w*::)?[a-zA-Z]\\w*\\s*\\( | | highlight.js:23:73:23:80 | [\\*&\\s]+ | Strings starting with 'A' and with many repetitions of '\\tA\\t' can start matching anywhere after the start of the preceeding ((decltype\\(auto\\)\|([a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(<[^<>]+>)?)[\\*&\\s]+)+([a-zA-Z_]\\w*::)?[a-zA-Z]\\w*\\s*\\( | -| highlight.js:26:14:26:34 | (([\\/.])[\\w\\-.\\/=]+)+ | Strings with many repetitions of '..' can start matching anywhere after the start of the preceeding [\\w\\-.\\/=]+ | -| highlight.js:26:22:26:32 | [\\w\\-.\\/=]+ | Strings with many repetitions of '..' can start matching anywhere after the start of the preceeding (([\\/.])[\\w\\-.\\/=]+)+ | +| highlight.js:26:14:26:34 | (([\\/.])[\\w\\-.\\/=]+)+ | Strings with many repetitions of '.-' can start matching anywhere after the start of the preceeding [\\w\\-.\\/=]+ | +| highlight.js:26:22:26:32 | [\\w\\-.\\/=]+ | Strings with many repetitions of '.-' can start matching anywhere after the start of the preceeding (([\\/.])[\\w\\-.\\/=]+)+ | | highlight.js:31:14:31:28 | (?:\\\\.\|[^`\\\\])+ | Strings starting with '`' and with many repetitions of '\\\\`' can start matching anywhere after the start of the preceeding `(?:\\\\.\|[^`\\\\])+` | | highlight.js:38:21:38:23 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding [a-zA-Z_]\\w*\\([^()]*(\\([^()]*(\\([^()]*\\))*[^()]*\\))*[^()]*\\)\\s*\\{ | | highlight.js:38:54:38:59 | [^()]* | Strings starting with 'A((' and with many repetitions of ''' can start matching anywhere after the start of the preceeding [^()]* | @@ -94,6 +93,7 @@ | polynomial-redos.js:64:14:64:15 | Y* | Strings starting with 'fooY' and with many repetitions of 'Y' can start matching anywhere after the start of the preceeding (K\|Y)+ | | polynomial-redos.js:65:14:65:15 | .* | Strings starting with 'fooY' and with many repetitions of 'K' can start matching anywhere after the start of the preceeding (K\|Y)+ | | polynomial-redos.js:66:9:66:10 | .* | Strings starting with 'K' and with many repetitions of 'K' can start matching anywhere after the start of the preceeding (K\|Y).*X | +| polynomial-redos.js:67:8:67:9 | .* | Strings starting with 'X' and with many repetitions of 'Z' can start matching anywhere after the start of the preceeding [^Y].*X | | polynomial-redos.js:68:8:68:9 | .* | Strings starting with 'X' and with many repetitions of 'X' can start matching anywhere after the start of the preceeding [^Y].*$ | | polynomial-redos.js:69:8:69:9 | .* | Strings starting with 'X' and with many repetitions of 'X' can start matching anywhere after the start of the preceeding [^Y].*$ | | polynomial-redos.js:71:51:71:63 | [?\\x21-\\x7E]* | Strings starting with ',-+' and with many repetitions of '++' can start matching anywhere after the start of the preceeding [A-Za-z0-9+/]+ | @@ -123,6 +123,7 @@ | polynomial-redos.js:111:17:111:19 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding \\s*$ | | polynomial-redos.js:112:17:112:19 | \\s+ | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding \\s+$ | | polynomial-redos.js:114:22:114:24 | \\w* | Strings starting with '5' and with many repetitions of '5' can start matching anywhere after the start of the preceeding \\d* | +| polynomial-redos.js:116:21:116:28 | [\\d\\D]*? | Strings starting with '/*' and with many repetitions of 'a/*' can start matching anywhere after the start of the preceeding \\/\\*[\\d\\D]*?\\*\\/ | | polynomial-redos.js:118:17:118:23 | (#\\d+)+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\d+ | | polynomial-redos.js:124:33:124:35 | \\s+ | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding \\s+$ | | polynomial-redos.js:130:21:130:22 | c+ | Strings starting with 'c' and with many repetitions of 'c' can start matching anywhere after the start of the preceeding cc+D | @@ -134,26 +135,22 @@ | 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*) | | regexplib/address.js:38:39:38:45 | [ 0-9]* | Strings starting with 'po' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding [ \|\\.]* | | regexplib/address.js:51:220:51:222 | \\w+ | Strings starting with 'C/O ' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:51:331:51:344 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0#' and with many repetitions of 'FL0' can start matching anywhere after the start of the preceeding \\w+ | -| regexplib/address.js:51:399:51:401 | \\s+ | Strings starting with 'C/O 0' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\x20* | +| regexplib/address.js:51:331:51:344 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0#' and with many repetitions of '0APT0' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:51:415:51:419 | \\x20+ | Strings starting with 'C/O 0\\t0' and with many repetitions of ' 0 ' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:51:420:51:422 | \\w+ | Strings starting with 'C/O 0\\t0 ' and with many repetitions of '0 0 ' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:51:616:51:618 | \\w+ | Strings starting with 'C/O 0\\tC/O ' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:51:727:51:740 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0\\t0 0#' and with many repetitions of 'FL0' can start matching anywhere after the start of the preceeding \\w+ | -| regexplib/address.js:51:796:51:798 | \\s+ | Strings starting with 'C/O 0\\t' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+ | +| regexplib/address.js:51:727:51:740 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0\\t0 0#' and with many repetitions of '0APT0' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/address.js:51:796:51:798 | \\s+ | Strings starting with 'C/O 0\\t' and with many repetitions of '\\t\\t' can start matching anywhere after the start of the preceeding \\s+ | | regexplib/address.js:51:803:51:811 | [A-Za-z]+ | Strings starting with 'C/O 0\\t\\t' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:67:379:67:755 | [a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\' ]+ | Strings starting with '#' and with many repetitions of '#' can start matching anywhere after the start of the preceeding [a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\']+ | | regexplib/address.js:69:3:69: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:69:48:69: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:69:93:69: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*) | | regexplib/address.js:75:220:75:222 | \\w+ | Strings starting with 'C/O ' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:75:331:75:344 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0#' and with many repetitions of 'FL0' can start matching anywhere after the start of the preceeding \\w+ | -| regexplib/address.js:75:399:75:401 | \\s+ | Strings starting with 'C/O 0' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\x20* | +| regexplib/address.js:75:331:75:344 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0#' and with many repetitions of '0APT0' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:75:415:75:419 | \\x20+ | Strings starting with 'C/O 0\\t0' and with many repetitions of ' 0 ' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:75:420:75:422 | \\w+ | Strings starting with 'C/O 0\\t0 ' and with many repetitions of '0 0 ' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:75:616:75:618 | \\w+ | Strings starting with 'C/O 0\\tC/O ' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:75:727:75:740 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0\\t0 0#' and with many repetitions of 'FL0' can start matching anywhere after the start of the preceeding \\w+ | -| regexplib/address.js:75:796:75:798 | \\s+ | Strings starting with 'C/O 0\\t' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+ | +| regexplib/address.js:75:727:75:740 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0\\t0 0#' and with many repetitions of '0APT0' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/address.js:75:796:75:798 | \\s+ | Strings starting with 'C/O 0\\t' and with many repetitions of '\\t\\t' can start matching anywhere after the start of the preceeding \\s+ | | regexplib/address.js:75:803:75:811 | [A-Za-z]+ | Strings starting with 'C/O 0\\t\\t' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:85:15:85:49 | ([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding (?([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+)([ ]\|[:]\|\\t\|[-])*(?Home\|Office\|Work\|Away\|Fax\|FAX\|Phone) | | regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | Strings starting with '0' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding ([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+ | @@ -167,10 +164,8 @@ | regexplib/email.js:5:24:5:35 | [a-zA-Z0-9]+ | Strings starting with '0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding ([_\\.\\-]?[a-zA-Z0-9]+)* | | regexplib/email.js:5:63:5:74 | [a-zA-Z0-9]+ | Strings starting with '0@0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [A-Za-z0-9]+ | | regexplib/email.js:8:16:8:49 | [^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+ | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | -| regexplib/email.js:8:57:8:84 | (?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))* | Strings starting with '"' and with many repetitions of '\\\\"' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:8:89:8:174 | (?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))* | Strings starting with '!' and with many repetitions of '.!' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:8:100:8:133 | [^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+ | Strings starting with '!.' and with many repetitions of '!.!' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | -| regexplib/email.js:8:141:8:168 | (?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))* | Strings starting with '!."' and with many repetitions of '".!."' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:12:2:12:4 | \\w+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | | regexplib/email.js:12:5:12:15 | ([-+.]\\w+)* | Strings starting with '0' and with many repetitions of '+0' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | | regexplib/email.js:12:11:12:13 | \\w+ | Strings starting with '0+' and with many repetitions of '0+' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | @@ -201,16 +196,12 @@ | regexplib/markup.js:2:3:2:7 | [^>]* | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]*> | | regexplib/markup.js:3:440:3:456 | (\\s(?.+?))* | Strings starting with '.+?))* | -| regexplib/markup.js:5:1525:5:1527 | \\s* | Strings starting with '?'DateLiteral' ?# Per the VB Spec : DateLiteral ::= '#' DateOrTime '#' # ?'DateOrTime' DateValue ?# TimeValue ::= HourValue : MinuteValue 10 ?# Hour 01 - 24 : 60 ?# Minute 01 - 60 : ?# Optional Minute :01 - :60 ' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s* | -| regexplib/markup.js:6:11:6:25 | [\\w\\*\\)\\(\\,\\s]+ | Strings starting with 'SELECT\\t' and with many repetitions of 'SELECT\\t' can start matching anywhere after the start of the preceeding (SELECT\\s[\\w\\*\\)\\(\\,\\s]+\\sFROM\\s[\\w]+) | | regexplib/markup.js:6:99:6:113 | [\\s\\w\\d\\)\\(\\,]* | Strings starting with ' INSERT\\tINTO\\t0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [\\d\\w]+ | | regexplib/markup.js:7:8:7:23 | (?:\\\\.\|[^\\\\"]*)* | Strings starting with '"!' and with many repetitions of '\\\\"!\\\\a' can start matching anywhere after the start of the preceeding "([^"](?:\\\\.\|[^\\\\"]*)*)" | | regexplib/markup.js:9:6:9:13 | [\\s\\S]*? | Strings starting with ' | | regexplib/markup.js:12:40:12:42 | .*? | Strings starting with ') | | regexplib/markup.js:12:117:12:121 | [^>]* | Strings starting with ']*>) | -| regexplib/markup.js:12:149:12:153 | [^>]* | Strings starting with 'font-family:' and with many repetitions of 'font-family:' can start matching anywhere after the start of the preceeding (font-family:[^>]*[;']) | -| regexplib/markup.js:12:171:12:175 | [^>]* | Strings starting with 'font-size:' and with many repetitions of 'font-size:' can start matching anywhere after the start of the preceeding (font-size:[^>]*[;'])(?-s) | | regexplib/markup.js:13:6:13:12 | [^"']+? | Strings starting with '<' and with many repetitions of '!' can start matching anywhere after the start of the preceeding .*? | | regexplib/markup.js:13:14:13:16 | .+? | Strings starting with '<' and with many repetitions of '!' can start matching anywhere after the start of the preceeding .*? | | regexplib/markup.js:14:13:14:14 | .* | Strings starting with '<' and with many repetitions of 'a' can start matching anywhere after the start of the preceeding .* | @@ -226,8 +217,7 @@ | regexplib/markup.js:20:52:20:53 | .* | Strings with many repetitions of '=color' can start matching anywhere after the start of the preceeding [^>]+ | | regexplib/markup.js:20:155:20:156 | '+ | Strings with many repetitions of '''' can start matching anywhere after the start of the preceeding '+ | | regexplib/markup.js:20:197:20:198 | "+ | Strings with many repetitions of '""' can start matching anywhere after the start of the preceeding "+ | -| regexplib/markup.js:20:245:20:247 | .*? | Strings with many repetitions of 'color: # IF found THEN move ahead "" # single or double # or no quotes\\t' can start matching anywhere after the start of the preceeding .*? | -| regexplib/markup.js:20:274:20:276 | .*? | Strings starting with ']+color.*>) #IF\\/THEN lookahead color in tag (.*?color\\s*?[=\|:]\\s*?) # IF found THEN move ahead ('+\\#*?[\\w\\s]*'+ # CAPTURE ColorName\\/Hex \|"+\\#*?[\\w\\s]*"+ # single or double \|\\#*\\w*\\b) # or no quotes\t.*?> # & move to end of tag \|.*?> # ELSE move to end of Tag ) # Close the If\\/Then lookahead # Use Multiline and IgnoreCase # Replace the matches from RE with MatchEvaluator below: # if m.Groups(1).Value<>"" then # Return "" # else # Return "" # end if | +| regexplib/markup.js:20:274:20:276 | .*? | Strings starting with ']+color.*>) #IF\\/THEN lookahead color in tag (.*?color\\s*?[=\|:]\\s*?) # IF found THEN move ahead ('+\\#*?[\\w\\s]*'+ # CAPTURE ColorName\\/Hex \|"+\\#*?[\\w\\s]*"+ # single or double \|\\#*\\w*\\b) # or no quotes\t.*?> # & move to end of tag \|.*?> # ELSE move to end of Tag ) # Close the If\\/Then lookahead # Use Multiline and IgnoreCase # Replace the matches from RE with MatchEvaluator below: # if m.Groups(1).Value<>"" then # Return "" # else # Return "" # end if | | regexplib/markup.js:24:39:24:41 | \\s+ | Strings starting with '<A' and with many repetitions of '\\t-\\t!=\\t' can start matching anywhere after the start of the preceeding \\s* | | regexplib/markup.js:24:43:24:45 | \\S+ | Strings starting with '<A\\t' and with many repetitions of '-\\t!=' can start matching anywhere after the start of the preceeding \\s* | | regexplib/markup.js:24:48:24:50 | \\s* | Strings starting with '<A\\t!' and with many repetitions of '\\t=-\\t!\\t' can start matching anywhere after the start of the preceeding \\s+ | @@ -236,6 +226,7 @@ | regexplib/markup.js:25:45:25:49 | [^>]* | Strings starting with ']* | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]*name[\\s]*=[\\s]*"?[^\\w_]*"?[^>]*> | | regexplib/markup.js:27:34:27:38 | [^>]* | Strings starting with ']* | Strings starting with '<' and with many repetitions of ']*)(\\s[^<]*)> | | regexplib/markup.js:37:15:37:19 | [\\w]* | Strings starting with '[0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\w+ | @@ -245,6 +236,7 @@ | regexplib/markup.js:43:45:43:49 | [^>]* | Strings starting with ']* | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]*name[\\s]*=[\\s]*"?[^\\w_]*"?[^>]*> | | regexplib/markup.js:44:34:44:38 | [^>]* | Strings starting with '' and with many repetitions of '' can start matching anywhere after the start of the preceeding [^']*? | | regexplib/markup.js:62:9:62:14 | [^>]*? | Strings starting with '' and with many repetitions of '>;' can start matching anywhere after the start of the preceeding .*? | | regexplib/markup.js:62:57:62:59 | .*? | Strings starting with '' and with many repetitions of '>a' can start matching anywhere after the start of the preceeding .*? | +| regexplib/markup.js:63:70:63:77 | [\\w\\W]*? | Strings with many repetitions of 'a/*' can start matching anywhere after the start of the preceeding (?((?m:^[\\t ]*\\/{2}[^\\n\\r\\v\\f]+[\\n\\r\\v\\f]*){2,})\|(\\/\\*[\\w\\W]*?\\*\\/)) | | regexplib/misc.js:4:36:4:44 | [a-zA-Z]* | Strings starting with 'A' and with many repetitions of 'AA' can start matching anywhere after the start of the preceeding [a-zA-Z]+ | | regexplib/misc.js:76:2:76:27 | (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+ | Strings with many repetitions of 'AUX' can start matching anywhere after the start of the preceeding (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+\\s*$ | | regexplib/misc.js:81:31:81:45 | [^a-z\\:\\,\\(\\)]* | Strings starting with '#' and with many repetitions of '#' can start matching anywhere after the start of the preceeding ([A-Zäöü0-9\\/][^a-z\\:\\,\\(\\)]*[A-Zäöü0-9])($\|[\\.\\:\\,\\;\\)\\-\\ \\+]\|s\\b) | @@ -279,7 +271,7 @@ | regexplib/misc.js:95:25:95:26 | .+ | Strings starting with 'at\\t' and with many repetitions of 'at\\ta' can start matching anywhere after the start of the preceeding (at\\s)(?.+)(\\.)(?[^\\.]*)(\\()(?[^\\)]*)(\\))((\\sin\\s)(?.+)(:line )(?[\\d]*))? | | regexplib/misc.js:95:71:95:76 | [^\\)]* | Strings starting with 'at\\ta.(' and with many repetitions of '((' can start matching anywhere after the start of the preceeding .+ | | regexplib/misc.js:95:103:95:104 | .+ | Strings starting with 'at\\ta.()\\tin\\t' and with many repetitions of '()\\tin\\t-' can start matching anywhere after the start of the preceeding .+ | -| regexplib/misc.js:101:52:101:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.htm' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | +| regexplib/misc.js:101:52:101:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.asp' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | | regexplib/misc.js:112:3:112:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?\\s*\\d{6}\\s*) | | regexplib/misc.js:112:32:112:34 | \\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/misc.js:114:6:114:8 | \\\|+ | Strings starting with 'a' and with many repetitions of '\|' can start matching anywhere after the start of the preceeding .+ | @@ -290,7 +282,7 @@ | regexplib/misc.js:123:36:123:38 | .*? | Strings starting with '?se[A' and with many repetitions of '?se[Aa' can start matching anywhere after the start of the preceeding (?s)(?:\\e\\[(?:(\\d+);?)*([A-Za-z])(.*?))(?=\\e\\[\|\\z) | | regexplib/misc.js:126:15:126:20 | [a-z]+ | Strings starting with 'a' and with many repetitions of 'aa' can start matching anywhere after the start of the preceeding [a-z]+ | | regexplib/misc.js:141:15:141:19 | [^;]+ | Strings starting with '{\\\\f\\\\' and with many repetitions of '{\\\\f\\\\:' can start matching anywhere after the start of the preceeding (\\{\\\\f\\d*)\\\\([^;]+;) | -| regexplib/misc.js:144:52:144:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.htm' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | +| regexplib/misc.js:144:52:144:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.asp' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | | regexplib/misc.js:148:12:148:18 | [^\\s>]+ | Strings starting with '<' and with many repetitions of ']+(\\s+[^"'=]+(=("[^"]*")\|('[^\\']*')\|([^\\s"'>]*))?)*\\s*\\/?> | | regexplib/misc.js:148:20:148:22 | \\s+ | Strings starting with '' and with many repetitions of 'href="">;' can start matching anywhere after the start of the preceeding href\\s*=\\s*(?:(?:\\"(?[^\\"]*)\\")\|(?[^\\s*] ))>(?[^<]+)<\\/\\w> | +| regexplib/uri.js:29:2:29:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | Strings with many repetitions of 'ftp://' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9%:/-_\\?\\.'~]*)? | +| regexplib/uri.js:31:65:31:69 | [^<]+ | Strings starting with 'href=! >' and with many repetitions of 'href=! >;' can start matching anywhere after the start of the preceeding href\\s*=\\s*(?:(?:\\"(?<url>[^\\"]*)\\")\|(?<url>[^\\s*] ))>(?<title>[^<]+)<\\/\\w> | | regexplib/uri.js:34:3:34:9 | [^\\=&]+ | Strings with many repetitions of '%' can start matching anywhere after the start of the preceeding ([^\\=&]+)(?<!param1\|param2\|param3)\\=([^\\=&]+)(&)? | | regexplib/uri.js:36:40:36:42 | \\d* | Strings starting with '$1' and with many repetitions of '1' can start matching anywhere after the start of the preceeding [1-9]+ | | regexplib/uri.js:38:20:38:28 | [a-z0-9]+ | Strings starting with 'a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-z]+ | @@ -406,8 +394,7 @@ | regexplib/uri.js:55:20:55:28 | [a-z0-9]+ | Strings starting with 'a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-z]+ | | regexplib/uri.js:55:35:55:40 | [a-z]+ | Strings starting with 'a.' and with many repetitions of 'aa' can start matching anywhere after the start of the preceeding [a-z0-9]+ | | regexplib/uri.js:55:52:55:60 | [a-z0-9]+ | Strings starting with 'a.a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-z]+ | -| regexplib/uri.js:58:2:58:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | Strings with many repetitions of 'wwwa' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9%:/-_\\?\\.'~]*)? | -| regexplib/uri.js:58:48:58:62 | [a-zA-Z0-9\\.-]+ | Strings starting with 'wwwa' and with many repetitions of 'www--' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | +| regexplib/uri.js:58:2:58:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | Strings with many repetitions of 'ftp://' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9%:/-_\\?\\.'~]*)? | | regexplib/uri.js:64:31:64:36 | [\\w-]+ | Strings with many repetitions of '-' can start matching anywhere after the start of the preceeding [\\w-\\s]* | | regexplib/uri.js:70:16:70:31 | [a-zA-Z0-9\\-\\.]+ | Strings starting with '0' and with many repetitions of '00' can start matching anywhere after the start of the preceeding [a-zA-Z0-9]+ | | regexplib/uri.js:71:75:71:89 | [^\\/\\\\:*?"<>\|]+ | Strings starting with 'A:\\\\!.' and with many repetitions of '!.' can start matching anywhere after the start of the preceeding [^\\/\\\\:*?"<>\|]+ | @@ -489,10 +476,10 @@ | tst.js:254:51:254:53 | \\w* | Strings starting with 'foobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbaz' can start matching anywhere after the start of the preceeding \\d* | | tst.js:254:63:254:65 | \\s* | Strings starting with 'foobarbazfoobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' can start matching anywhere after the start of the preceeding \\d* | | tst.js:254:75:254:77 | \\d* | Strings starting with 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' can start matching anywhere after the start of the preceeding \\s* | -| tst.js:257:14:257:116 | (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)* | Strings with many repetitions of 'athisisagoddamnlongstringforstresstestingthequery' can start matching anywhere after the start of the preceeding (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)*- | +| tst.js:257:14:257:116 | (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)* | Strings with many repetitions of '\\tthisisagoddamnlongstringforstresstestingthequery' can start matching anywhere after the start of the preceeding (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)*- | | tst.js:260:14:260:77 | (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)* | Strings with many repetitions of 'this0query' can start matching anywhere after the start of the preceeding \\w+ | | tst.js:260:68:260:70 | \\w+ | Strings starting with 'this' and with many repetitions of 'this' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)* | -| tst.js:263:15:263:117 | (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)* | Strings with many repetitions of 'thisisagoddamnlongstringforstresstestingthequery' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)*- | +| tst.js:263:15:263:117 | (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)* | Strings with many repetitions of 'imanotherbutunrelatedstringcomparedtotheotherstring' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)*- | | tst.js:272:21:272:22 | b+ | Strings with many repetitions of 'b' can start matching anywhere after the start of the preceeding (b+)+ | | tst.js:275:25:275:27 | \\s+ | Strings starting with '<0' and with many repetitions of '\\t0="\\t0="\\t' can start matching anywhere after the start of the preceeding [^"]* | | tst.js:275:28:275:30 | \\w+ | Strings starting with '<0\\t' and with many repetitions of '0="\\t0="\\t' can start matching anywhere after the start of the preceeding [^"]* | @@ -535,7 +522,7 @@ | tst.js:375:15:375:16 | x* | Strings with many repetitions of 'x' can start matching anywhere after the start of the preceeding (x*)+(?=$\|y) | | tst.js:378:16:378:22 | [\\s\\S]* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding ([\\s\\S]*)+(?=$) | | tst.js:379:16:379:22 | [\\s\\S]* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding ([\\s\\S]*)+(?=$\|y) | -| tst.js:381:15:381:24 | (foo\|FOO)* | Strings with many repetitions of 'foo' can start matching anywhere after the start of the preceeding (foo\|FOO)*bar | +| tst.js:381:15:381:24 | (foo\|FOO)* | Strings with many repetitions of 'FOO' can start matching anywhere after the start of the preceeding (foo\|FOO)*bar | | tst.js:382:14:382:23 | (foo\|FOO)* | Strings with many repetitions of 'foo' can start matching anywhere after the start of the preceeding (foo\|FOO)*bar | | tst.js:384:15:384:26 | ([AB]\|[ab])* | Strings with many repetitions of 'A' can start matching anywhere after the start of the preceeding ([AB]\|[ab])*C | | tst.js:385:14:385:25 | ([DE]\|[de])* | Strings with many repetitions of 'd' can start matching anywhere after the start of the preceeding ([DE]\|[de])*F | From d5d56cde5aac76d13baae120d0d1a2ce169694f5 Mon Sep 17 00:00:00 2001 From: Chris Smowton <smowton@github.com> Date: Tue, 23 May 2023 10:51:21 +0100 Subject: [PATCH 075/739] Dead store of field: count passing to a vararg function as escaping --- go/ql/src/RedundantCode/DeadStoreOfField.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/src/RedundantCode/DeadStoreOfField.ql b/go/ql/src/RedundantCode/DeadStoreOfField.ql index 2060ac1f734..9dd2c4de65c 100644 --- a/go/ql/src/RedundantCode/DeadStoreOfField.ql +++ b/go/ql/src/RedundantCode/DeadStoreOfField.ql @@ -36,7 +36,7 @@ predicate escapes(DataFlow::Node nd) { exists(SendStmt s | nd.asExpr() = s.getValue()) or // if `nd` is passed to a function, then it escapes - nd instanceof DataFlow::ArgumentNode + nd = any(DataFlow::CallNode c).getASyntacticArgument() or // if `nd` has its address taken, then it escapes exists(AddressExpr ae | nd.asExpr() = ae.getOperand()) From 0574f2784f2db7639bad37fba8871b71c99cb3d2 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 12:32:28 +0200 Subject: [PATCH 076/739] Swift: trigger workflow on `codeql-cli-*` --- .github/workflows/swift.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 806e04e6c68..075a5505f39 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -16,6 +16,7 @@ on: branches: - main - rc/* + - codeql-cli-* push: paths: - "swift/**" @@ -30,6 +31,7 @@ on: branches: - main - rc/* + - codeql-cli-* jobs: # not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks From 7dd18ff8010730866aedaec38ca3c1df24c412fd Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 09:02:44 +0200 Subject: [PATCH 077/739] Swift: add `@ql.hideable` to schema loading --- misc/codegen/lib/schema.py | 2 ++ misc/codegen/lib/schemadefs.py | 1 + misc/codegen/loaders/schemaloader.py | 2 ++ misc/codegen/test/test_schemaloader.py | 17 +++++++++++++++++ 4 files changed, 22 insertions(+) diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py index 64a4720093b..d72fa46adf4 100644 --- a/misc/codegen/lib/schema.py +++ b/misc/codegen/lib/schema.py @@ -91,6 +91,8 @@ class Class: """^^^ filled with `True` for non-final classes with only synthesized final descendants """ doc: List[str] = field(default_factory=list) default_doc_name: Optional[str] = None + hideable_root: bool = False + hideable: bool = False @property def final(self): diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index f3bfd9840dc..3235ace42e7 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -145,6 +145,7 @@ _Pragma("qltest_collapse_hierarchy") _Pragma("qltest_uncollapse_hierarchy") ql.default_doc_name = lambda doc: _annotate(doc_name=doc) +ql.hideable = _annotate(hideable=True) _Pragma("ql_internal") _Pragma("cpp_skip") diff --git a/misc/codegen/loaders/schemaloader.py b/misc/codegen/loaders/schemaloader.py index 5fd392b112d..0202c98f439 100644 --- a/misc/codegen/loaders/schemaloader.py +++ b/misc/codegen/loaders/schemaloader.py @@ -37,7 +37,9 @@ def _get_class(cls: type) -> schema.Class: derived={d.__name__ for d in cls.__subclasses__()}, # getattr to inherit from bases group=getattr(cls, "_group", ""), + hideable=getattr(cls, "_hideable", False), # in the following we don't use `getattr` to avoid inheriting + hideable_root=cls.__dict__.get("_hideable", False), pragmas=cls.__dict__.get("_pragmas", []), ipa=cls.__dict__.get("_ipa", None), properties=[ diff --git a/misc/codegen/test/test_schemaloader.py b/misc/codegen/test/test_schemaloader.py index 9c9750818ea..2479fc08500 100644 --- a/misc/codegen/test/test_schemaloader.py +++ b/misc/codegen/test/test_schemaloader.py @@ -688,5 +688,22 @@ def test_uppercase_acronyms_are_rejected(): pass +def test_hideable(): + @load + class data: + class Root: + pass + + @defs.ql.hideable + class A(Root): + pass + + class B(A): + pass + + assert data.classes["A"] == schema.Class("A", bases=["Root"], derived={"B"}, hideable_root=True, hideable=True) + assert data.classes["B"] == schema.Class("B", bases=["A"], hideable=True) + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) From a087fef33575aa7df945e93aebf6cee7d566f721 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 09:37:55 +0200 Subject: [PATCH 078/739] Swift: implement `@ql.hideable` --- misc/codegen/generators/qlgen.py | 15 +- misc/codegen/lib/ql.py | 3 + misc/codegen/templates/ql_class.mustache | 17 +-- misc/codegen/templates/ql_parent.mustache | 12 +- misc/codegen/test/test_qlgen.py | 128 ++++++++++-------- swift/ql/.generated.list | 4 +- .../codeql/swift/generated/ParentChild.qll | 6 +- swift/schema.py | 1 + 8 files changed, 112 insertions(+), 74 deletions(-) diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index 7affea51828..6e4017b81f6 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -102,7 +102,7 @@ def _get_doc(cls: schema.Class, prop: schema.Property, plural=None): return f"{prop_name} of this {class_name}" -def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str = "") -> ql.Property: +def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dict[str, schema.Class], prev_child: str = "") -> ql.Property: args = dict( type=prop.type if not prop.is_predicate else "predicate", qltest_skip="qltest_skip" in prop.pragmas, @@ -110,7 +110,8 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str = is_optional=prop.is_optional, is_predicate=prop.is_predicate, is_unordered=prop.is_unordered, - description=prop.description + description=prop.description, + type_is_hideable=lookup[prop.type].hideable if prop.type in lookup else False, ) if prop.is_single: args.update( @@ -147,12 +148,12 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str = return ql.Property(**args) -def get_ql_class(cls: schema.Class) -> ql.Class: +def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> ql.Class: pragmas = {k: True for k in cls.pragmas if k.startswith("ql")} prev_child = "" properties = [] for p in cls.properties: - prop = get_ql_property(cls, p, prev_child) + prop = get_ql_property(cls, p, lookup, prev_child) if prop.is_child: prev_child = prop.singular properties.append(prop) @@ -164,6 +165,8 @@ def get_ql_class(cls: schema.Class) -> ql.Class: dir=pathlib.Path(cls.group or ""), ipa=bool(cls.ipa), doc=cls.doc, + hideable=cls.hideable, + hideable_root=cls.hideable_root, **pragmas, ) @@ -254,7 +257,7 @@ def _get_all_properties_to_be_tested(cls: schema.Class, lookup: typing.Dict[str, for c, p in _get_all_properties(cls, lookup): if not ("qltest_skip" in c.pragmas or "qltest_skip" in p.pragmas): # TODO here operations are duplicated, but should be better if we split ql and qltest generation - p = get_ql_property(c, p) + p = get_ql_property(c, p, lookup) yield ql.PropertyForTest(p.getter, is_total=p.is_single or p.is_predicate, type=p.type if not p.is_predicate else None, is_indexed=p.is_indexed) if p.is_repeated and not p.is_optional: @@ -329,7 +332,7 @@ def generate(opts, renderer): data = schemaloader.load_file(input) - classes = {name: get_ql_class(cls) for name, cls in data.classes.items()} + classes = {name: get_ql_class(cls, data.classes) for name, cls in data.classes.items()} if not classes: raise NoClasses root = next(iter(classes.values())) diff --git a/misc/codegen/lib/ql.py b/misc/codegen/lib/ql.py index 97165053fd0..508db816beb 100644 --- a/misc/codegen/lib/ql.py +++ b/misc/codegen/lib/ql.py @@ -42,6 +42,7 @@ class Property: description: List[str] = field(default_factory=list) doc: Optional[str] = None doc_plural: Optional[str] = None + type_is_hideable: bool = False def __post_init__(self): if self.tableparams: @@ -113,6 +114,8 @@ class Class: ql_internal: bool = False ipa: bool = False doc: List[str] = field(default_factory=list) + hideable_root: bool = False + hideable: bool = False def __post_init__(self): self.bases = [Base(str(b), str(prev)) for b, prev in zip(self.bases, itertools.chain([""], self.bases))] diff --git a/misc/codegen/templates/ql_class.mustache b/misc/codegen/templates/ql_class.mustache index 9f72caef392..63e4f0088fe 100644 --- a/misc/codegen/templates/ql_class.mustache +++ b/misc/codegen/templates/ql_class.mustache @@ -37,7 +37,8 @@ module Generated { * Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs. */ final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") } - + {{/root}} + {{#hideable_root}} /** * Gets the most immediate element that should substitute this element in the explicit AST, if any. * Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved @@ -54,13 +55,13 @@ module Generated { or result = this.getResolveStep().resolve() } - {{/root}} + {{/hideable_root}} {{#final}} override string getAPrimaryQlClass() { result = "{{name}}" } {{/final}} {{#properties}} - {{#type_is_class}} + {{#type_is_hideable}} /** * {{>ql_property_doc}} * * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the @@ -85,11 +86,11 @@ module Generated { */ final {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { exists({{type}} immediate | immediate = this.get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}index{{/is_indexed}}) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve()) + {{#hideable}}if exists(this.getResolveStep()) then result = immediate else {{/hideable}}result = immediate.resolve()) } - {{/type_is_class}} - {{^type_is_class}} + {{/type_is_hideable}} + {{^type_is_hideable}} /** * {{>ql_property_doc}} * {{#has_description}} @@ -100,14 +101,14 @@ module Generated { */ {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { {{^ipa}} - {{^is_predicate}}result = {{/is_predicate}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}) + {{^is_predicate}}result = {{/is_predicate}}{{#type_is_class}}Synth::convert{{type}}FromRaw({{/type_is_class}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}){{#type_is_class}}){{/type_is_class}} {{/ipa}} {{#ipa}} none() {{/ipa}} } - {{/type_is_class}} + {{/type_is_hideable}} {{#is_optional}} /** * Holds if `{{getter}}({{#is_repeated}}index{{/is_repeated}})` exists. diff --git a/misc/codegen/templates/ql_parent.mustache b/misc/codegen/templates/ql_parent.mustache index 2c8d7dfc258..2dcac6c45dc 100644 --- a/misc/codegen/templates/ql_parent.mustache +++ b/misc/codegen/templates/ql_parent.mustache @@ -28,7 +28,7 @@ private module Impl { {{! for single and optional properties it adds 1 (regardless of whether the optional property exists) }} {{! for repeated it adds 1 + the maximum index (which works for repeated optional as well) }} and - n{{singular}} = n{{prev_child}} + 1{{#is_repeated}}+ max(int i | i = -1 or exists(e.getImmediate{{singular}}(i)) | i){{/is_repeated}} + n{{singular}} = n{{prev_child}} + 1{{#is_repeated}}+ max(int i | i = -1 or exists(e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}(i)) | i){{/is_repeated}} {{/is_child}} {{/properties}} and ( none() @@ -40,10 +40,10 @@ private module Impl { {{#is_child}} or {{#is_repeated}} - result = e.getImmediate{{singular}}(index - n{{prev_child}}) and partialPredicateCall = "{{singular}}(" + (index - n{{prev_child}}).toString() + ")" + result = e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}(index - n{{prev_child}}) and partialPredicateCall = "{{singular}}(" + (index - n{{prev_child}}).toString() + ")" {{/is_repeated}} {{^is_repeated}} - index = n{{prev_child}} and result = e.getImmediate{{singular}}() and partialPredicateCall = "{{singular}}()" + index = n{{prev_child}} and result = e.get{{#type_is_hideable}}Immediate{{/type_is_hideable}}{{singular}}() and partialPredicateCall = "{{singular}}()" {{/is_repeated}} {{/is_child}} {{/properties}} @@ -64,6 +64,10 @@ none() {{/final}} {{/classes}} } + +Element resolve(Element e) { + {{#classes}}{{#hideable_root}}if e instanceof {{name}} then result = e.({{name}}).resolve() else {{/hideable_root}}{{/classes}}result = e +} } /** @@ -87,5 +91,5 @@ exists(string partialAccessor | result = Impl::getImmediateChild(e, index, parti * Gets the child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child. */ Element getChildAndAccessor(Element e, int index, string accessor) { -exists(string partialAccessor | result = Impl::getImmediateChild(e, index, partialAccessor).resolve() and accessor = "get" + partialAccessor) +exists(string partialAccessor | result = Impl::resolve(Impl::getImmediateChild(e, index, partialAccessor)) and accessor = "get" + partialAccessor) } diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index 1cd85762315..32f65bbc851 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -139,15 +139,16 @@ def a_ql_class(**kwargs): return ql.Class(**kwargs, import_prefix=gen_import) -def a_ql_stub(**kwargs): - return ql.Stub(**kwargs, import_prefix=gen_import) +def a_ql_stub(*, name, import_prefix="", **kwargs): + return ql.Stub(name=name, **kwargs, import_prefix=gen_import, + base_import=f"{gen_import_prefix}{import_prefix}{name}") def test_one_empty_class(generate_classes): assert generate_classes([ schema.Class("A") ]) == { - "A.qll": (a_ql_stub(name="A", base_import=gen_import_prefix + "A"), + "A.qll": (a_ql_stub(name="A"), a_ql_class(name="A", final=True)), } @@ -159,15 +160,11 @@ def test_hierarchy(generate_classes): schema.Class("B", bases=["A"], derived={"D"}), schema.Class("A", derived={"B", "C"}), ]) == { - "A.qll": (a_ql_stub(name="A", base_import=gen_import_prefix + "A"), - a_ql_class(name="A")), - "B.qll": (a_ql_stub(name="B", base_import=gen_import_prefix + "B"), - a_ql_class(name="B", bases=["A"], imports=[stub_import_prefix + "A"])), - "C.qll": (a_ql_stub(name="C", base_import=gen_import_prefix + "C"), - a_ql_class(name="C", bases=["A"], imports=[stub_import_prefix + "A"])), - "D.qll": (a_ql_stub(name="D", base_import=gen_import_prefix + "D"), - a_ql_class(name="D", final=True, bases=["B", "C"], - imports=[stub_import_prefix + cls for cls in "BC"])), + "A.qll": (a_ql_stub(name="A"), a_ql_class(name="A")), + "B.qll": (a_ql_stub(name="B"), a_ql_class(name="B", bases=["A"], imports=[stub_import_prefix + "A"])), + "C.qll": (a_ql_stub(name="C"), a_ql_class(name="C", bases=["A"], imports=[stub_import_prefix + "A"])), + "D.qll": (a_ql_stub(name="D"), a_ql_class(name="D", final=True, bases=["B", "C"], + imports=[stub_import_prefix + cls for cls in "BC"])), } @@ -213,7 +210,7 @@ def test_single_property(generate_classes): schema.Class("MyObject", properties=[ schema.SingleProperty("foo", "bar")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_objects", @@ -236,9 +233,8 @@ def test_children(generate_classes): schema.RepeatedOptionalProperty("child_4", "int", is_child=True), ]), ]) == { - "FakeRoot.qll": (a_ql_stub(name="FakeRoot", base_import=gen_import_prefix + "FakeRoot"), - a_ql_class(name="FakeRoot", final=True)), - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "FakeRoot.qll": (a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True)), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="A", type="int", tablename="my_objects", @@ -286,7 +282,7 @@ def test_single_properties(generate_classes): schema.SingleProperty("three", "z"), ]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="One", type="x", tablename="my_objects", @@ -309,9 +305,8 @@ def test_optional_property(generate_classes, is_child, prev_child): schema.Class("MyObject", properties=[ schema.OptionalProperty("foo", "bar", is_child=is_child)]), ]) == { - "FakeRoot.qll": (a_ql_stub(name="FakeRoot", base_import=gen_import_prefix + "FakeRoot"), - a_ql_class(name="FakeRoot", final=True)), - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "FakeRoot.qll": (a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True)), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_object_foos", tableparams=["this", "result"], @@ -327,9 +322,8 @@ def test_repeated_property(generate_classes, is_child, prev_child): schema.Class("MyObject", properties=[ schema.RepeatedProperty("foo", "bar", is_child=is_child)]), ]) == { - "FakeRoot.qll": (a_ql_stub(name="FakeRoot", base_import=gen_import_prefix + "FakeRoot"), - a_ql_class(name="FakeRoot", final=True)), - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "FakeRoot.qll": (a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True)), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", plural="Foos", type="bar", tablename="my_object_foos", tableparams=["this", "index", "result"], prev_child=prev_child, @@ -344,9 +338,8 @@ def test_repeated_unordered_property(generate_classes): schema.Class("MyObject", properties=[ schema.RepeatedUnorderedProperty("foo", "bar")]), ]) == { - "FakeRoot.qll": (a_ql_stub(name="FakeRoot", base_import=gen_import_prefix + "FakeRoot"), - a_ql_class(name="FakeRoot", final=True)), - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "FakeRoot.qll": (a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True)), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", plural="Foos", type="bar", tablename="my_object_foos", tableparams=["this", "result"], is_unordered=True, @@ -363,9 +356,8 @@ def test_repeated_optional_property(generate_classes, is_child, prev_child): schema.RepeatedOptionalProperty("foo", "bar", is_child=is_child)]), ]) == { - "FakeRoot.qll": (a_ql_stub(name="FakeRoot", base_import=gen_import_prefix + "FakeRoot"), - a_ql_class(name="FakeRoot", final=True)), - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "FakeRoot.qll": (a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True)), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", plural="Foos", type="bar", tablename="my_object_foos", tableparams=["this", "index", "result"], is_optional=True, @@ -380,7 +372,7 @@ def test_predicate_property(generate_classes): schema.Class("MyObject", properties=[ schema.PredicateProperty("is_foo")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="isFoo", type="predicate", tablename="my_object_is_foo", tableparams=["this"], is_predicate=True, doc="this my object is foo"), @@ -395,7 +387,7 @@ def test_single_class_property(generate_classes, is_child, prev_child): schema.Class("MyObject", properties=[ schema.SingleProperty("foo", "Bar", is_child=is_child)]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class( name="MyObject", final=True, imports=[stub_import_prefix + "Bar"], properties=[ ql.Property(singular="Foo", type="Bar", tablename="my_objects", @@ -404,8 +396,7 @@ def test_single_class_property(generate_classes, is_child, prev_child): prev_child=prev_child, doc="foo of this my object"), ], )), - "Bar.qll": (a_ql_stub(name="Bar", base_import=gen_import_prefix + "Bar"), - a_ql_class(name="Bar", final=True)), + "Bar.qll": (a_ql_stub(name="Bar"), a_ql_class(name="Bar", final=True)), } @@ -414,8 +405,7 @@ def test_class_with_doc(generate_classes): assert generate_classes([ schema.Class("A", doc=doc), ]) == { - "A.qll": (a_ql_stub(name="A", base_import=gen_import_prefix + "A"), - a_ql_class(name="A", final=True, doc=doc)), + "A.qll": (a_ql_stub(name="A"), a_ql_class(name="A", final=True, doc=doc)), } @@ -425,9 +415,8 @@ def test_class_dir(generate_classes): schema.Class("A", derived={"B"}, group=dir), schema.Class("B", bases=["A"]), ]) == { - f"{dir}/A.qll": (a_ql_stub(name="A", base_import=gen_import_prefix + "another.rel.path.A"), - a_ql_class(name="A", dir=pathlib.Path(dir))), - "B.qll": (a_ql_stub(name="B", base_import=gen_import_prefix + "B"), + f"{dir}/A.qll": (a_ql_stub(name="A", import_prefix="another.rel.path."), a_ql_class(name="A", dir=pathlib.Path(dir))), + "B.qll": (a_ql_stub(name="B"), a_ql_class(name="B", final=True, bases=["A"], imports=[stub_import_prefix + "another.rel.path.A"])), } @@ -586,11 +575,11 @@ def test_test_partial_properties(opts, generate_tests): type="bool")), "B/B_getZ.ql": a_ql_property_tester(class_name="B", property=ql.PropertyForTest(getter="getZ", is_total=False, - is_indexed=True, - type="int")), + is_indexed=True, + type="int")), "B/B_getAW.ql": a_ql_property_tester(class_name="B", property=ql.PropertyForTest(getter="getAW", is_total=False, - type="string")), + type="string")), } @@ -611,7 +600,7 @@ def test_test_properties_deduplicated(opts, generate_tests): ]), "Final/Final_getY.ql": a_ql_property_tester(class_name="Final", property=ql.PropertyForTest(getter="getY", is_total=False, - is_indexed=True, + is_indexed=True, type="bool")), } @@ -706,7 +695,7 @@ def test_property_description(generate_classes): schema.SingleProperty("foo", "bar", description=description), ]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_objects", @@ -722,7 +711,7 @@ def test_property_doc_override(generate_classes): schema.Class("MyObject", properties=[ schema.SingleProperty("foo", "bar", doc="baz")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_objects", @@ -737,7 +726,7 @@ def test_repeated_property_doc_override(generate_classes): schema.RepeatedProperty("x", "int", doc="children of this"), schema.RepeatedOptionalProperty("y", "int", doc="child of this")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="X", plural="Xes", type="int", @@ -759,7 +748,7 @@ def test_property_doc_abbreviations(generate_classes, abbr, expected): schema.Class("Object", properties=[ schema.SingleProperty(f"foo_{abbr}_bar", "baz")]), ]) == { - "Object.qll": (a_ql_stub(name="Object", base_import=gen_import_prefix + "Object"), + "Object.qll": (a_ql_stub(name="Object"), a_ql_class(name="Object", final=True, properties=[ ql.Property(singular=f"Foo{abbr.capitalize()}Bar", type="baz", @@ -776,7 +765,7 @@ def test_property_doc_abbreviations_ignored_if_within_word(generate_classes, abb schema.Class("Object", properties=[ schema.SingleProperty(f"foo_{abbr}acadabra_bar", "baz")]), ]) == { - "Object.qll": (a_ql_stub(name="Object", base_import=gen_import_prefix + "Object"), + "Object.qll": (a_ql_stub(name="Object"), a_ql_class(name="Object", final=True, properties=[ ql.Property(singular=f"Foo{abbr.capitalize()}acadabraBar", type="baz", @@ -792,7 +781,7 @@ def test_repeated_property_doc_override_with_format(generate_classes): schema.RepeatedProperty("x", "int", doc="special {children} of this"), schema.RepeatedOptionalProperty("y", "int", doc="special {child} of this")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="X", plural="Xes", type="int", @@ -815,7 +804,7 @@ def test_repeated_property_doc_override_with_multiple_formats(generate_classes): schema.RepeatedProperty("x", "int", doc="{cat} or {dog}"), schema.RepeatedOptionalProperty("y", "int", doc="{cats} or {dogs}")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="X", plural="Xes", type="int", @@ -835,7 +824,7 @@ def test_property_doc_override_with_format(generate_classes): schema.Class("MyObject", properties=[ schema.SingleProperty("foo", "bar", doc="special {baz} of this")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_objects", @@ -850,7 +839,7 @@ def test_property_on_class_with_default_doc_name(generate_classes): schema.SingleProperty("foo", "bar")], default_doc_name="baz"), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_objects", @@ -863,7 +852,7 @@ def test_stub_on_class_with_ipa_from_class(generate_classes): assert generate_classes([ schema.Class("MyObject", ipa=schema.IpaInfo(from_class="A")), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject", ipa_accessors=[ + "MyObject.qll": (a_ql_stub(name="MyObject", ipa_accessors=[ ql.IpaUnderlyingAccessor(argument="Entity", type="Raw::A", constructorparams=["result"]), ]), a_ql_class(name="MyObject", final=True, ipa=True)), @@ -874,7 +863,7 @@ def test_stub_on_class_with_ipa_on_arguments(generate_classes): assert generate_classes([ schema.Class("MyObject", ipa=schema.IpaInfo(on_arguments={"base": "A", "index": "int", "label": "string"})), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject", ipa_accessors=[ + "MyObject.qll": (a_ql_stub(name="MyObject", ipa_accessors=[ ql.IpaUnderlyingAccessor(argument="Base", type="Raw::A", constructorparams=["result", "_", "_"]), ql.IpaUnderlyingAccessor(argument="Index", type="int", constructorparams=["_", "result", "_"]), ql.IpaUnderlyingAccessor(argument="Label", type="string", constructorparams=["_", "_", "result"]), @@ -883,5 +872,38 @@ def test_stub_on_class_with_ipa_on_arguments(generate_classes): } +def test_hideable_class(generate_classes): + assert generate_classes([ + schema.Class("MyObject", hideable=True), + ]) == { + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, hideable=True)), + } + + +def test_hideable_root_class(generate_classes): + assert generate_classes([ + schema.Class("MyObject", hideable_root=True), + ]) == { + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, hideable_root=True)), + } + + +def test_hideable_property(generate_classes): + assert generate_classes([ + schema.Class("MyObject", hideable=True), + schema.Class("Other", properties=[ + schema.SingleProperty("x", "MyObject"), + ]), + ]) == { + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, hideable=True)), + "Other.qll": (a_ql_stub(name="Other"), + a_ql_class(name="Other", imports=[stub_import_prefix + "MyObject"], + final=True, properties=[ + ql.Property(singular="X", type="MyObject", tablename="others", type_is_hideable=True, + tableparams=["this", "result"], doc="x of this other"), + ])), + } + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index a28e6ba533b..c6b98069ef7 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -374,14 +374,14 @@ lib/codeql/swift/generated/Comment.qll f58b49f6e68c21f87c51e2ff84c8a64b09286d733 lib/codeql/swift/generated/DbFile.qll a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc lib/codeql/swift/generated/DbLocation.qll b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 lib/codeql/swift/generated/Diagnostics.qll d2ee2db55e932dcaee95fcc1164a51ffbe1a78d86ee0f50aabb299b458462afe 566d554d579cadde26dc4d1d6b1750ca800511201b737b629f15b6f873af3733 -lib/codeql/swift/generated/Element.qll 81a01c1965cf8154596c753b20536ef8630b30567d8c077660ab2d11143f060b 74f5c76db5ec82a9c1675ec0282acd44f1a86ef447d1961c47aea3eed50f79cb +lib/codeql/swift/generated/Element.qll 5293995513d2461a0358ca73c723eddbe1c55c140531ba75d52b03b5e3137016 74f5c76db5ec82a9c1675ec0282acd44f1a86ef447d1961c47aea3eed50f79cb lib/codeql/swift/generated/ErrorElement.qll 4b032abe8ffb71376a29c63e470a52943ace2527bf7b433c97a8bf716f9ad102 4f2b1be162a5c275e3264dbc51bf98bce8846d251be8490a0d4b16cbc85f630f lib/codeql/swift/generated/File.qll f88c485883dd9b2b4a366080e098372912e03fb3177e5cae58aa4449c2b03399 0333c49e3a11c48e6146a7f492ee31ac022d80150fc3f8bfafc3c8f94d66ff76 lib/codeql/swift/generated/KeyPathComponent.qll 00b1e586b8532f0193b3f61111e70d4e595f3d45c7a25ff68114be1051882491 c556e85b21fc5a5aae12fb5599a96442431ef44ae92350eb7da9efe6a22efd53 lib/codeql/swift/generated/Locatable.qll bfdf2dafae2829cac8d1e863a93676228d131b5a7f3df87c40d2f3b1839962b8 af243098af0955a40862387edf7526826fde62a64e5e6ca28de9e9603a8622bf lib/codeql/swift/generated/Location.qll 921922352d39449067d9f2788309b5f3490091097ffe35e6aa98f9368626ce2c 0795c63565c4308e745400bc70ea73675160201590a95bb418de4e2ebca32764 lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 -lib/codeql/swift/generated/ParentChild.qll f490202e849b9cbd550ee9d758644b85d43e60d81413e6c28df2850fb1e9a2d6 6b95aeab6b53a880b230ad0c96b6deb519a7368898c844632ae96090de59df99 +lib/codeql/swift/generated/ParentChild.qll 727205c3f85c042a9a33c6a33da3843493ec7273c5cc07b92e82b90b140828c7 2d34bb73116390a1386b47443f7fe8b7f013078398e1f3387dba1c8522000aaa lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 lib/codeql/swift/generated/Raw.qll 8d4880e5ee1fdd120adeb7bf0dfa1399e7b1a53b2cc7598aed8e15cbf996d1c0 da0d446347d29f5cd05281c17c24e87610f31c32adb7e05ab8f3a26bed55bd90 diff --git a/swift/ql/lib/codeql/swift/generated/ParentChild.qll b/swift/ql/lib/codeql/swift/generated/ParentChild.qll index 09c48606353..958f4ec60a3 100644 --- a/swift/ql/lib/codeql/swift/generated/ParentChild.qll +++ b/swift/ql/lib/codeql/swift/generated/ParentChild.qll @@ -5299,6 +5299,10 @@ private module Impl { or result = getImmediateChildOfVariadicSequenceType(e, index, partialAccessor) } + + Element resolve(Element e) { + if e instanceof Element then result = e.(Element).resolve() else result = e + } } /** @@ -5326,7 +5330,7 @@ Element getImmediateChildAndAccessor(Element e, int index, string accessor) { */ Element getChildAndAccessor(Element e, int index, string accessor) { exists(string partialAccessor | - result = Impl::getImmediateChild(e, index, partialAccessor).resolve() and + result = Impl::resolve(Impl::getImmediateChild(e, index, partialAccessor)) and accessor = "get" + partialAccessor ) } diff --git a/swift/schema.py b/swift/schema.py index 8fc0941e171..f2d1283974f 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -14,6 +14,7 @@ from misc.codegen.lib.schemadefs import * include("prefix.dbscheme") @qltest.skip +@ql.hideable class Element: is_unknown: predicate | cpp.skip From b19194bd06794da7655f2e5eba032c8a14947ab1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 10:30:09 +0200 Subject: [PATCH 079/739] Swift: make only `Expr`, `Pattern` and `Type` hideable --- swift/ql/.generated.list | 173 ++++++++--------- swift/ql/.gitattributes | 1 + .../swift/controlflow/internal/Completion.qll | 6 +- .../internal/ControlFlowGraphImpl.qll | 46 +++-- swift/ql/lib/codeql/swift/elements.qll | 1 + .../ql/lib/codeql/swift/elements/Element.qll | 11 -- .../codeql/swift/elements/HideableElement.qll | 14 ++ .../lib/codeql/swift/elements/Locatable.qll | 6 +- .../codeql/swift/elements/UnknownLocation.qll | 2 +- .../swift/elements/UnspecifiedElement.qll | 2 +- .../swift/elements/expr/MethodLookupExpr.qll | 2 +- .../swift/generated/AvailabilityInfo.qll | 15 +- .../lib/codeql/swift/generated/Callable.qll | 64 +------ .../ql/lib/codeql/swift/generated/Element.qll | 17 -- .../swift/generated/HideableElement.qll | 25 +++ .../swift/generated/KeyPathComponent.qll | 32 +--- .../lib/codeql/swift/generated/Locatable.qll | 15 +- .../lib/codeql/swift/generated/Location.qll | 15 +- .../codeql/swift/generated/ParentChild.qll | 178 ++++++++++-------- swift/ql/lib/codeql/swift/generated/Raw.qll | 11 +- swift/ql/lib/codeql/swift/generated/Synth.qll | 39 +++- .../swift/generated/UnspecifiedElement.qll | 15 +- .../generated/decl/AbstractStorageDecl.qll | 15 +- .../swift/generated/decl/CapturedDecl.qll | 15 +- .../lib/codeql/swift/generated/decl/Decl.qll | 30 +-- .../swift/generated/decl/EnumCaseDecl.qll | 15 +- .../swift/generated/decl/EnumElementDecl.qll | 15 +- .../swift/generated/decl/ExtensionDecl.qll | 30 +-- .../swift/generated/decl/GenericContext.qll | 15 +- .../swift/generated/decl/IfConfigDecl.qll | 15 +- .../swift/generated/decl/ImportDecl.qll | 30 +-- .../generated/decl/InfixOperatorDecl.qll | 15 +- .../swift/generated/decl/ModuleDecl.qll | 32 +--- .../swift/generated/decl/NominalTypeDecl.qll | 2 +- .../swift/generated/decl/OpaqueTypeDecl.qll | 17 +- .../codeql/swift/generated/decl/ParamDecl.qll | 38 +--- .../generated/decl/PatternBindingDecl.qll | 4 +- .../generated/decl/PoundDiagnosticDecl.qll | 2 +- .../swift/generated/decl/SubscriptDecl.qll | 17 +- .../swift/generated/decl/TopLevelCodeDecl.qll | 15 +- .../swift/generated/decl/TypeAliasDecl.qll | 2 +- .../codeql/swift/generated/decl/TypeDecl.qll | 2 +- .../codeql/swift/generated/decl/ValueDecl.qll | 2 +- .../codeql/swift/generated/decl/VarDecl.qll | 92 ++------- .../expr/AppliedPropertyWrapperExpr.qll | 15 +- .../codeql/swift/generated/expr/ApplyExpr.qll | 15 +- .../codeql/swift/generated/expr/Argument.qll | 2 +- .../swift/generated/expr/CaptureListExpr.qll | 15 +- .../swift/generated/expr/DeclRefExpr.qll | 15 +- .../generated/expr/DefaultArgumentExpr.qll | 15 +- .../swift/generated/expr/EnumIsCaseExpr.qll | 15 +- .../lib/codeql/swift/generated/expr/Expr.qll | 3 +- .../swift/generated/expr/KeyPathExpr.qll | 30 +-- .../swift/generated/expr/LookupExpr.qll | 15 +- .../swift/generated/expr/ObjCSelectorExpr.qll | 15 +- .../generated/expr/ObjectLiteralExpr.qll | 15 +- .../expr/OtherInitializerRefExpr.qll | 15 +- .../generated/expr/OverloadedDeclRefExpr.qll | 15 +- .../expr/RebindSelfInInitializerExpr.qll | 15 +- .../swift/generated/expr/SubscriptExpr.qll | 15 +- .../swift/generated/expr/SuperRefExpr.qll | 15 +- .../codeql/swift/generated/expr/TapExpr.qll | 30 +-- .../codeql/swift/generated/expr/TypeExpr.qll | 15 +- .../generated/pattern/EnumElementPattern.qll | 15 +- .../swift/generated/pattern/IsPattern.qll | 15 +- .../swift/generated/pattern/Pattern.qll | 3 +- .../swift/generated/pattern/TypedPattern.qll | 15 +- .../codeql/swift/generated/stmt/BraceStmt.qll | 15 +- .../codeql/swift/generated/stmt/BreakStmt.qll | 15 +- .../swift/generated/stmt/CaseLabelItem.qll | 4 +- .../codeql/swift/generated/stmt/CaseStmt.qll | 45 +---- .../swift/generated/stmt/ConditionElement.qll | 21 +-- .../swift/generated/stmt/ContinueStmt.qll | 15 +- .../codeql/swift/generated/stmt/DeferStmt.qll | 15 +- .../swift/generated/stmt/DoCatchStmt.qll | 30 +-- .../codeql/swift/generated/stmt/DoStmt.qll | 15 +- .../swift/generated/stmt/FallthroughStmt.qll | 30 +-- .../swift/generated/stmt/ForEachStmt.qll | 21 +-- .../codeql/swift/generated/stmt/GuardStmt.qll | 15 +- .../codeql/swift/generated/stmt/IfStmt.qll | 30 +-- .../generated/stmt/LabeledConditionalStmt.qll | 15 +- .../swift/generated/stmt/PoundAssertStmt.qll | 2 +- .../swift/generated/stmt/RepeatWhileStmt.qll | 17 +- .../swift/generated/stmt/ReturnStmt.qll | 2 +- .../swift/generated/stmt/StmtCondition.qll | 15 +- .../swift/generated/stmt/SwitchStmt.qll | 17 +- .../codeql/swift/generated/stmt/ThrowStmt.qll | 2 +- .../codeql/swift/generated/stmt/WhileStmt.qll | 15 +- .../codeql/swift/generated/stmt/YieldStmt.qll | 2 +- .../swift/generated/type/AnyGenericType.qll | 15 +- .../swift/generated/type/ArchetypeType.qll | 15 +- .../generated/type/DependentMemberType.qll | 15 +- .../swift/generated/type/ModuleType.qll | 15 +- .../type/OpaqueTypeArchetypeType.qll | 15 +- .../lib/codeql/swift/generated/type/Type.qll | 4 +- .../swift/generated/type/TypeAliasType.qll | 15 +- .../codeql/swift/generated/type/TypeRepr.qll | 2 +- .../codeql/swift/printast/PrintAstNode.qll | 4 +- swift/ql/lib/swift.dbscheme | 8 +- swift/schema.py | 11 +- 100 files changed, 454 insertions(+), 1471 deletions(-) create mode 100644 swift/ql/lib/codeql/swift/elements/HideableElement.qll create mode 100644 swift/ql/lib/codeql/swift/generated/HideableElement.qll diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index c6b98069ef7..3de24cd5c71 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -365,80 +365,81 @@ lib/codeql/swift/elements/type/VariadicSequenceType.qll 325e4c4481e9ac07acdc6aeb lib/codeql/swift/elements/type/VariadicSequenceTypeConstructor.qll 0d1d2328a3b5e503a883e7e6d7efd0ca5e7f2633abead9e4c94a9f98ed3cb223 69bff81c1b9413949eacb9298d2efb718ea808e68364569a1090c9878c4af856 lib/codeql/swift/elements/type/WeakStorageType.qll 7c07739cfc1459f068f24fef74838428128054adf611504d22532e4a156073e7 9c968414d7cc8d672f3754bced5d4f83f43a6d7872d0d263d79ff60483e1f996 lib/codeql/swift/elements/type/WeakStorageTypeConstructor.qll d88b031ef44d6de14b3ddcff2eb47b53dbd11550c37250ff2edb42e5d21ec3e9 26d855c33492cf7a118e439f7baeed0e5425cfaf058b1dcc007eca7ed765c897 -lib/codeql/swift/elements.qll 3df0060edd2b2030f4e4d7d5518afe0073d798474d9b1d6185d833bec63ca8bd 3df0060edd2b2030f4e4d7d5518afe0073d798474d9b1d6185d833bec63ca8bd +lib/codeql/swift/elements.qll cba02ae777269061af0713f6b003c97679434ddc8b2e871fc00c5d17c5265d2a cba02ae777269061af0713f6b003c97679434ddc8b2e871fc00c5d17c5265d2a lib/codeql/swift/generated/AstNode.qll 02ca56d82801f942ae6265c6079d92ccafdf6b532f6bcebd98a04029ddf696e4 6216fda240e45bd4302fa0cf0f08f5f945418b144659264cdda84622b0420aa2 -lib/codeql/swift/generated/AvailabilityInfo.qll c648a66cf45414c85cf9cc69aa05b765a49d0c18cd9c101c34f99a9adc38a1ee 54ba7b07b4177d35e85d19363aa7adcda29cda185a5818e5fcb7c678c093e0ba +lib/codeql/swift/generated/AvailabilityInfo.qll 1e38e7f52ccbcecd4dd088eae15c482d87911682dabb426332cc0e207fc6bf2f 7c6640530cdbece90d4172e8d6cfd119656860da08bb61ed4ef3a6757723994f lib/codeql/swift/generated/AvailabilitySpec.qll fb1255f91bb5e41ad4e9c675a2efbc50d0fb366ea2de68ab7eebd177b0795309 144e0c2e7d6c62ecee43325f7f26dcf437881edf0b75cc1bc898c6c4b61fdeaf -lib/codeql/swift/generated/Callable.qll 9dcf09a2f227dd6f569f007a07fb368d6b928ffd002535bb97118361430d948c 5c203f5f6b4f8b6748e61e09bb46c55442a2fb36f2d1fa950e6f81bdda562709 +lib/codeql/swift/generated/Callable.qll c1f214f5ea4da567d3cf2ac4915630ae1e19c939d2aa64cdd5ab06e76de059dc c43fd17a89d016a31584de10e4d4988f3ea10dc26d6b59b3151bb3196e9f0689 lib/codeql/swift/generated/Comment.qll f58b49f6e68c21f87c51e2ff84c8a64b09286d733e86f70d67d3a98fe6260bd6 975bbb599a2a7adc35179f6ae06d9cbc56ea8a03b972ef2ee87604834bc6deb1 lib/codeql/swift/generated/DbFile.qll a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc lib/codeql/swift/generated/DbLocation.qll b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 lib/codeql/swift/generated/Diagnostics.qll d2ee2db55e932dcaee95fcc1164a51ffbe1a78d86ee0f50aabb299b458462afe 566d554d579cadde26dc4d1d6b1750ca800511201b737b629f15b6f873af3733 -lib/codeql/swift/generated/Element.qll 5293995513d2461a0358ca73c723eddbe1c55c140531ba75d52b03b5e3137016 74f5c76db5ec82a9c1675ec0282acd44f1a86ef447d1961c47aea3eed50f79cb +lib/codeql/swift/generated/Element.qll 1c6a757f3c1218b02a98f075b2cfb5bd0cc31dff31bd1d04acdf4d4f040dee45 a3221cd9250706e6313a82450466326e5a1e6ffa5ae0b308e943d0979d03919e lib/codeql/swift/generated/ErrorElement.qll 4b032abe8ffb71376a29c63e470a52943ace2527bf7b433c97a8bf716f9ad102 4f2b1be162a5c275e3264dbc51bf98bce8846d251be8490a0d4b16cbc85f630f lib/codeql/swift/generated/File.qll f88c485883dd9b2b4a366080e098372912e03fb3177e5cae58aa4449c2b03399 0333c49e3a11c48e6146a7f492ee31ac022d80150fc3f8bfafc3c8f94d66ff76 -lib/codeql/swift/generated/KeyPathComponent.qll 00b1e586b8532f0193b3f61111e70d4e595f3d45c7a25ff68114be1051882491 c556e85b21fc5a5aae12fb5599a96442431ef44ae92350eb7da9efe6a22efd53 -lib/codeql/swift/generated/Locatable.qll bfdf2dafae2829cac8d1e863a93676228d131b5a7f3df87c40d2f3b1839962b8 af243098af0955a40862387edf7526826fde62a64e5e6ca28de9e9603a8622bf -lib/codeql/swift/generated/Location.qll 921922352d39449067d9f2788309b5f3490091097ffe35e6aa98f9368626ce2c 0795c63565c4308e745400bc70ea73675160201590a95bb418de4e2ebca32764 +lib/codeql/swift/generated/HideableElement.qll 0eb3bb2fd9fb2b5ba444f4cd1aa4f91c87926618dcfa0051b048cf9d63f9602e 0eb3bb2fd9fb2b5ba444f4cd1aa4f91c87926618dcfa0051b048cf9d63f9602e +lib/codeql/swift/generated/KeyPathComponent.qll c79c7bc04fc1426992ab472eedc1a20a7aa496ff3f43305400022f1a02ba44f4 a9935b68b511329d157bcd7a7d27aa4803d2163306db8b41808a2b736f80f4d8 +lib/codeql/swift/generated/Locatable.qll be20967d48a34cdba126fe298606e0adc11697831f097acba9c52a0b7ce9983e 8aa01bc376614abbc3209e25785c72f86c9b4e94bb5f471a4a0677fedaec4f61 +lib/codeql/swift/generated/Location.qll c5793987e77812059a28254dadee29bfe9b38153c0399fbb1bf6a2f5c237fdab 6e6d8802b021e36bbaad81845657769dd48a798ea33080ada05e9818a20b38f7 lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 -lib/codeql/swift/generated/ParentChild.qll 727205c3f85c042a9a33c6a33da3843493ec7273c5cc07b92e82b90b140828c7 2d34bb73116390a1386b47443f7fe8b7f013078398e1f3387dba1c8522000aaa +lib/codeql/swift/generated/ParentChild.qll ffec94e3ee076ff73dd7b4e6561c8d8c1f9a198547085baa40a1e5e28adc5827 a28adf13137431f55ce218ade6848bf5b853d3f27315765e9e6c45032c02ddd3 lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 8d4880e5ee1fdd120adeb7bf0dfa1399e7b1a53b2cc7598aed8e15cbf996d1c0 da0d446347d29f5cd05281c17c24e87610f31c32adb7e05ab8f3a26bed55bd90 -lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 +lib/codeql/swift/generated/Raw.qll 56e12381886fe9eb6aef74968cb542e179116ad6722640a21bda37f1d9d26e77 ae93d0caebecf3ce593c95887b44cd1686b5c7e989d5cce4bb39d97312c3cb68 +lib/codeql/swift/generated/Synth.qll 14dbc93375bcde4d792c1ec6157ee9c825119dcc9de31bcfeea56b3636f32d27 e84970ed295aa0af59135ee09b9cddbd6a26dcbce3baaf0e2a958b0552aac6d1 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 lib/codeql/swift/generated/UnknownLocation.qll e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 -lib/codeql/swift/generated/UnspecifiedElement.qll e121c84a2990fe314ab0756832776fe98fbc41f295d532b6e154aca1c5513b13 ee70eedad752175dbeee83c07fdb2ae7f4fa080fec7ba2be408469dfa11a0b4a -lib/codeql/swift/generated/decl/AbstractStorageDecl.qll 8ed642e35b066cc65b3d8ad16cf6c726cf0b3802330b0c3d3ba87b34451005d1 3474ad1468f09bf63f3582468ed97e9ed3b3ee61db90a4d31966cc97d9ca1b18 +lib/codeql/swift/generated/UnspecifiedElement.qll 2b66070944ad36316476b6bf8a811131ca6d4232591353b2b23e881b547463cc c9bff46bcb6f6d106eb57ab8bb04584d9a0b2513abdc1be6e98c0bd227c5f1e0 +lib/codeql/swift/generated/decl/AbstractStorageDecl.qll 4e827d05b3b98c043f925a3bd9c00622da3dc6e3d3406f5a18b2c3a684e3774f 47e5767a6f9a87f848cccce651d8c40af8aa3e0e727fc147cbf4d5a2a3e483d9 lib/codeql/swift/generated/decl/AbstractTypeParamDecl.qll 1e268b00d0f2dbbd85aa70ac206c5e4a4612f06ba0091e5253483635f486ccf9 5479e13e99f68f1f347283535f8098964f7fd4a34326ff36ad5711b2de1ab0d0 lib/codeql/swift/generated/decl/Accessor.qll c93cdf7dbb87e6c9b09b5fcf469b952041f753914a892addeb24bb46eaa51d29 1e8104da2da146d3e4d8f5f96b87872e63162e53b46f9c7038c75db51a676599 lib/codeql/swift/generated/decl/AccessorOrNamedFunction.qll b78aaef06cdaa172dce3e1dcd6394566b10ce445906e3cf67f6bef951b1662a4 a30d9c2ff79a313c7d0209d72080fdc0fabf10379f8caed5ff2d72dc518f8ad3 lib/codeql/swift/generated/decl/AssociatedTypeDecl.qll 4169d083104f9c089223ed3c5968f757b8cd6c726887bbb6fbaf21f5ed7ee144 4169d083104f9c089223ed3c5968f757b8cd6c726887bbb6fbaf21f5ed7ee144 -lib/codeql/swift/generated/decl/CapturedDecl.qll f8b69887acb35cc8de572984fef83eb08649845b49179b68d3afef36b526bddb 94ab461ef9ab5983dece5e2b1865b6056e381e5c06f2a3ec4dfde634a9368e59 +lib/codeql/swift/generated/decl/CapturedDecl.qll bdc7479fd577a8830cf0672763656e0269f02681f40890c64ae3f413655589ef 4380339650dfbed9c4846691f0c4bc0aea51a8e11112add54e0add2222dff8a0 lib/codeql/swift/generated/decl/ClassDecl.qll a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 a60e8af2fdbcd20cfa2049660c8bcbbc00508fbd3dde72b4778317dfc23c5ae4 lib/codeql/swift/generated/decl/ConcreteVarDecl.qll 4801ccc477480c4bc4fc117976fbab152e081064e064c97fbb0f37199cb1d0a8 4d7cfbf5b39b307dd673781adc220fdef04213f2e3d080004fa658ba6d3acb8d -lib/codeql/swift/generated/decl/Decl.qll 1d620c8e43df3cb46e5446dc9f6592205040c4d2b03c2ce1e491d7628f8904d0 b02514d7548a5a1dca39a148974a1b4dfeb681ebf81ad80f78d53ea48bab6133 +lib/codeql/swift/generated/decl/Decl.qll f3ab9f78b789ad2b47c473e0c8949507841d4f0e675af5f361ec274ad5230be6 fed6509f9267cc7663b5a5ceb0f27e368c662b98a0367b2efdac20eef80cbc0a lib/codeql/swift/generated/decl/Deinitializer.qll 816ecd92552915d06952517606a6e4c67bc53d7e7d9f5c09b7276e70612627fe 816ecd92552915d06952517606a6e4c67bc53d7e7d9f5c09b7276e70612627fe -lib/codeql/swift/generated/decl/EnumCaseDecl.qll 564718862a9fd5b99427591a83921bf57aac2074041b5b335577599e8eefda16 90899d7d7a9c695576ae4b24d19deb05e45e0e85c954ab41de154d5cc521019e +lib/codeql/swift/generated/decl/EnumCaseDecl.qll 7370ff068f6650c74f324fbcad8782067fa42ff12d57cc5f6320df6d55357c97 9044207eb9592c68c8d36af570e45b7dbb5af00e00ded65793d08cea3ee6410b lib/codeql/swift/generated/decl/EnumDecl.qll fa4490d511ee537751a4fab2478e65250ff3deba43c74db5341184c9ba25b534 fa4490d511ee537751a4fab2478e65250ff3deba43c74db5341184c9ba25b534 -lib/codeql/swift/generated/decl/EnumElementDecl.qll 41cad9be29b7afd56ba312ce00650ed89bffec2e2aaeed7bf26cd3dc0edb502e 33ac9ee5b205d32e5cf6a31f3f4bfd0f60b49fb0265200fd9e4dbbd5426fff02 -lib/codeql/swift/generated/decl/ExtensionDecl.qll 5472aa7cea119b68571065143fb4b2e335df003184efe8b8f28a98fd3ca3691e f65c8b078d1c34047cc66f5eb75dae8243e7aa42a7f3f2c21ea1ccf76eb9e7b9 +lib/codeql/swift/generated/decl/EnumElementDecl.qll 53074d5ae6249ca07c44879f4662b4d0478418cd8bd60c5511db52cf00942cc2 c38469c60df7c14d9d9c426600d1648dc1db177bd27ba1116649c48337b95358 +lib/codeql/swift/generated/decl/ExtensionDecl.qll 51cdf6227526fc769d4361b821d01e20a2b508ad8289af1002a0a947d8df295f 6a13f93179222f8d0e7e6b5a08dd8583fa0381644847b56509a85e6f008936e6 lib/codeql/swift/generated/decl/Function.qll 92d1fbceb9e96afd00a1dfbfd15cec0063b3cba32be1c593702887acc00a388a 0cbae132d593b0313a2d75a4e428c7f1f07a88c1f0491a4b6fa237bb0da71df3 -lib/codeql/swift/generated/decl/GenericContext.qll 5bbed6687f985dc8e812e48ae6ac17ec98d6cfccc6a72bee82afde58ccad07f7 ef7a2fa2646dd619af8f49ed1a12ce880a345dfc36b44e67868d733fc3b309e6 +lib/codeql/swift/generated/decl/GenericContext.qll 9f7e17d11bf898429a921ba7726b07aab382c97f8326bd186f2bded3d090852c 14d558b6e498d49b850f862d85091a11954dad13f16c60f700cf2c66fa37c473 lib/codeql/swift/generated/decl/GenericTypeDecl.qll 71f5c9c6078567dda0a3ac17e2d2d590454776b2459267e31fed975724f84aec 669c5dbd8fad8daf007598e719ac0b2dbcb4f9fad698bffb6f1d0bcd2cee9102 lib/codeql/swift/generated/decl/GenericTypeParamDecl.qll bc41a9d854e65b1e0da86350870a8fe050eb1dc031cd17ded11c15b5ad8ad183 bc41a9d854e65b1e0da86350870a8fe050eb1dc031cd17ded11c15b5ad8ad183 -lib/codeql/swift/generated/decl/IfConfigDecl.qll 07ae599c23c75d4a1fc7f188dce70cf1ded749368274f071b5b9639b5e54f69a ef8dc3f91edf40b9f8e84672060cea0de1a9c6545fd7aadb80225d3ca8f883e9 -lib/codeql/swift/generated/decl/ImportDecl.qll 1adafa6660d0b3968d1ee8cbcb4632d3b3baaa8a72874d3c9c0f6185eac4bc3e 8e68a538da2bac088001427cbdf6234cfe33071f82193aa52dc99cb9be893f2d -lib/codeql/swift/generated/decl/InfixOperatorDecl.qll 3d94018c33422b6fbe18348d0d47c0747358777501155d49abd3c8f5012c8a5d 855b73306f510828ad30555d6bba98cd9eab918de9e78696921ccac584828fd6 +lib/codeql/swift/generated/decl/IfConfigDecl.qll 085e2c70d3e158b7f3d3d3ade94593f1331d681d07da8a968c537830a67a62fe 19bb842314e8edb6a8dce4d78ec8043a527f13569da8be4ad03ba876a09998a5 +lib/codeql/swift/generated/decl/ImportDecl.qll 542405d7a75659d048d1ff8894a0cc0d357802c2936407ec39b7e4f69d2dd864 41ee9a9f1fc8068db587ac786145cf50f74f74161555ca94b502a57cca23288a +lib/codeql/swift/generated/decl/InfixOperatorDecl.qll 3da133c325380fbc10448b731d5826959056ca861d3a0661e7c37694e5ccb208 bb81c8e1597a1fb7e791e3c4c4ed28a73c442591bff2b12d13a7a327a7b6db08 lib/codeql/swift/generated/decl/Initializer.qll a72005f0abebd31b7b91f496ddae8dff49a027ba01b5a827e9b8870ecf34de17 a72005f0abebd31b7b91f496ddae8dff49a027ba01b5a827e9b8870ecf34de17 lib/codeql/swift/generated/decl/MissingMemberDecl.qll eaf8989eda461ec886a2e25c1e5e80fc4a409f079c8d28671e6e2127e3167479 d74b31b5dfa54ca5411cd5d41c58f1f76cfccc1e12b4f1fdeed398b4faae5355 -lib/codeql/swift/generated/decl/ModuleDecl.qll dd7bef7f19a5d2f57f0168eda80796ed8a74c7a136b3dc0cb289c3f750ef9a25 652d44d1ac5e31e4ccf4c5d29f2c5b985c68c4254458c3bfce09c2a821631f8f +lib/codeql/swift/generated/decl/ModuleDecl.qll b080281f68ef9943f6b0a808a151375fa8bc7539baaa55689abc16aa9024ff13 f948fd2545b9535335f857d7303a0b7c77ccf62ec49ed066726c6a77b273e5f8 lib/codeql/swift/generated/decl/NamedFunction.qll e8c23d8344768fb7ffe31a6146952fb45f66e25c2dd32c91a6161aaa612e602f e8c23d8344768fb7ffe31a6146952fb45f66e25c2dd32c91a6161aaa612e602f -lib/codeql/swift/generated/decl/NominalTypeDecl.qll 64914282b062364d81b013922069404d49b8c8830cc23944281d023779a9925c 72d45c5b6073cb32e6df6b62c2c919be50314d9380b955035cfadf500b3dbccf -lib/codeql/swift/generated/decl/OpaqueTypeDecl.qll 4dc0fc09fe314cdc6788adb4a93e87a7c8121e3fecaada19a436321d248d377a 4e20e1820ddf7b23268707a2b98bbafc400219533f357189a267f8e35b89226e +lib/codeql/swift/generated/decl/NominalTypeDecl.qll 3c935fff267db6b6339cadfec9c28764db105a2f1391a28de3d95a3fd156b2ab 14cb4f115b4c09dcdb5d276be4b3b60406486e0acca9d11458d25d0f467ef0ed +lib/codeql/swift/generated/decl/OpaqueTypeDecl.qll b07bcb944d6adff06dad06f8b77729044399e9a2747354e71e55605fb850c705 7e415f4d88f313e52fe6fb908cfac39066ec1302bcbb4ae07ad05b46a86d6b91 lib/codeql/swift/generated/decl/OperatorDecl.qll 3ffdc7ab780ee94a975f0ce3ae4252b52762ca8dbea6f0eb95f951e404c36a5b 25e39ccd868fa2d1fbce0eb7cbf8e9c2aca67d6fd42f76e247fb0fa74a51b230 -lib/codeql/swift/generated/decl/ParamDecl.qll f5d2c9e40aa8a1a77793a6d66fc6b55ded11295ee996b883117ffd6ee2523441 e0137535d7eac959ed10b06ad769b8225c0fadeea03030c7b30191884234e9b9 -lib/codeql/swift/generated/decl/PatternBindingDecl.qll e598dc0ed9373b4ca9646cc7c408f65db6b40d4281c8cfcecd09524df81bfac8 2ff3fe7fd32004649a0d41a0bf6857ac48d3a7b2dd87f5c1ffd9d5eea0673551 +lib/codeql/swift/generated/decl/ParamDecl.qll 21c8c035eaaa0fccc184ac073cea09fb39ee6f72b7d69a7119e38fc88f7ed997 486c55bd555569bae1fb4869745e83910a9635b2ad7d62652889562fcf98a42b +lib/codeql/swift/generated/decl/PatternBindingDecl.qll d59f2b05bfd78faefeabf0ab63e135f74e9731f22dec8c9dd65beabf9bc0956b e453d5033a788781320d60eca09d4b044f505720cb23f12ba2ade59203d24f81 lib/codeql/swift/generated/decl/PostfixOperatorDecl.qll 5aa85fa325020b39769fdb18ef97ef63bd28e0d46f26c1383138221a63065083 5aa85fa325020b39769fdb18ef97ef63bd28e0d46f26c1383138221a63065083 -lib/codeql/swift/generated/decl/PoundDiagnosticDecl.qll dc867f12579cec4f9fe95b59dfc31ef0df60cccccaf41abc171a86b7fafaf3f2 4474a913c4bf4e8d60f100bf5a0d57cc042c1362b09dd3c9493cc23a75c32e84 +lib/codeql/swift/generated/decl/PoundDiagnosticDecl.qll 2cd5dbd6707fd3920d5f402a3b169c4eac4189f4bebb33eb279de6e038e7329b 183f41a3b5ef928ad733d19225c7212633a3ac4752976c19bd8f821ec8553c0e lib/codeql/swift/generated/decl/PrecedenceGroupDecl.qll d0918f238484052a0af902624b671c04eb8d018ee71ef4931c2fdbb74fa5c5d4 d0918f238484052a0af902624b671c04eb8d018ee71ef4931c2fdbb74fa5c5d4 lib/codeql/swift/generated/decl/PrefixOperatorDecl.qll 18f2a1f83ea880775344fbc57ed332e17edba97a56594da64580baeb45e95a5d 18f2a1f83ea880775344fbc57ed332e17edba97a56594da64580baeb45e95a5d lib/codeql/swift/generated/decl/ProtocolDecl.qll 4b03e3c2a7af66e66e8abc40bd2ea35e71959f471669e551f4c42af7f0fd4566 4b03e3c2a7af66e66e8abc40bd2ea35e71959f471669e551f4c42af7f0fd4566 lib/codeql/swift/generated/decl/StructDecl.qll 9343b001dfeec83a6b41e88dc1ec75744d39c397e8e48441aa4d01493f10026a 9343b001dfeec83a6b41e88dc1ec75744d39c397e8e48441aa4d01493f10026a -lib/codeql/swift/generated/decl/SubscriptDecl.qll d08d46ddff0816541b28e231ba83c41cb51b40d7ccf2e0e7465e62e17078c000 0a1f1741bea4d2a7ebde7cbaf1cd0f7730a9845a8fd45d3457dc1b2b63eab900 -lib/codeql/swift/generated/decl/TopLevelCodeDecl.qll e90cc73d62ad6037f1ec200bf8356292fa48b6890762b68e3fba6a129c888fcd d9152cbdfbc8cfb66695ed10a5729abca1b58275616d16d19aae27fb745bf3aa -lib/codeql/swift/generated/decl/TypeAliasDecl.qll 2058a0699ddffabd7d1d554615bd7e9ce26810ef1c6c68601df46e071eb9a10c 94ba93ef3cc1028a3018831e336316e566b6028eee1d81bf4d754dbdbd401ea8 -lib/codeql/swift/generated/decl/TypeDecl.qll cc40d3a105654461a60f982b6bdb21c7e689e695d314eead245bfeeda92a4572 03d89aa4c77dacdc57cd867b4869b26cdb55a06e2ba6faf3dbb9fce8f881786b -lib/codeql/swift/generated/decl/ValueDecl.qll 7b297ed98f5e985b93c9de6be000d67f71796892599ae8274048d8ad6b6183b9 462c983d4163011b2232b684c9a6c3f01114096c4bb7f862d950380f527e3926 -lib/codeql/swift/generated/decl/VarDecl.qll c648a5432d63a547cd381646f9586b4fc72edb2cff8462533449761b1ec57a56 7f2c157975bc1de7a8b6ff980bed790d864a08f1d6c0de39c106d84d2b49b883 +lib/codeql/swift/generated/decl/SubscriptDecl.qll c0bb8fd0d9d363c253251ea4b6cdceebd316708ce61f49e321318f7ce80ea153 dda76edc25ce4b3c31bcd7cc707143e22c3f887658e8071c646668f445b9f601 +lib/codeql/swift/generated/decl/TopLevelCodeDecl.qll f9b4f8b413e5fd3c0d48910013fe2443143d2ee237084cf3e4eb668d5bc8f460 5c85641375f5b9e658c9467f5c4913e50d4228718aad950e94f55a28edbe28c7 +lib/codeql/swift/generated/decl/TypeAliasDecl.qll b9c4baf4a2eb67d21535da5cbb9894945d66b8aecf8bd91cb8aa8c964188c82f a69db19c25da7232a9139400578cb7eda8b56eb55c7c45d38aa50cc0c063947f +lib/codeql/swift/generated/decl/TypeDecl.qll 21d075b1fb55ce2e89ad73e62edbe1ad3ca429ea5a1c6096ca7aca7eaeea9772 c099f32a24d1be26b7b6e7478b481f8086c74f67cc840a843466715afc069784 +lib/codeql/swift/generated/decl/ValueDecl.qll f34e3414f8700150ccd221aed26e58f64ed43d708a3ccb3c50eff5c12f083303 c2926bebba6bfb997f8a610f7bfd13114b21e92ba0243247543984d6ea71a33e +lib/codeql/swift/generated/decl/VarDecl.qll d326cd9d4e892e6ad2f02847e476218d0f1f1ca012c1bfeca7d656af34c870b4 a2cac56e67fdc32d6f33eac180ca4831cd355343280e2d69cd5a8e17a77a89ce lib/codeql/swift/generated/expr/AbiSafeConversionExpr.qll f4c913df3f1c139a0533f9a3a2f2e07aee96ab723c957fc7153d68564e4fdd6d f4c913df3f1c139a0533f9a3a2f2e07aee96ab723c957fc7153d68564e4fdd6d lib/codeql/swift/generated/expr/AnyHashableErasureExpr.qll f450ac8e316def1cd64dcb61411bae191144079df7f313a5973e59dc89fe367f f450ac8e316def1cd64dcb61411bae191144079df7f313a5973e59dc89fe367f lib/codeql/swift/generated/expr/AnyTryExpr.qll e4759465411c215262909d10d729642779340698165aff0a66986c7dfc822832 83ec7fb0f11e2ffe15f3a0c97318121443936733f1adef17e5baa020bca2de29 -lib/codeql/swift/generated/expr/AppliedPropertyWrapperExpr.qll de01c3b68c2a37e9f5dee0729838923cc615d436092e78b608b6f6c23e1b4965 612f72046aa2e49b9d494cad590bfae133bd5c00908ed4c8df82730294d21fb8 -lib/codeql/swift/generated/expr/ApplyExpr.qll 798b999f3da5d6b917ff57a0dc1fde149b906ffd72c6df5bc511f6e2d20a7e8b 8bce7f52c4bce1aad5c0b8a195dd1ab6f1d82289e5eb56fca4b7543be7943d15 +lib/codeql/swift/generated/expr/AppliedPropertyWrapperExpr.qll b441c3cad6d462ae0736d5e65742d49b280b907e8e250badb0248f501e1e9144 34a691143585fb9b9d7e3ef0b8d3c7250a73da0d323de6ac632472652bc86a1a +lib/codeql/swift/generated/expr/ApplyExpr.qll d97bce0ce47c42feda140c677c204f9d1c92fe1889760034fe8f1cb330f411d3 f7956f6bff4164adacce06ce2134bc6bf2d0e0261c9b5f7b882e04c0df5c8e0c lib/codeql/swift/generated/expr/ArchetypeToSuperExpr.qll e0b665b7389e5d0cb736426b9fd56abfec3b52f57178a12d55073f0776d8e5b7 e0b665b7389e5d0cb736426b9fd56abfec3b52f57178a12d55073f0776d8e5b7 -lib/codeql/swift/generated/expr/Argument.qll 97991761563d806ff0199e69f4c9eda93e324bb40bd41ddec98388c2146cbd6b c231f4e0320700fe64ce43123027516088b877fddde3be18565e01890f6b10ce +lib/codeql/swift/generated/expr/Argument.qll 441daab359d20018113344d026c1ace38a0acff35e68155a69a887a6fdb90684 43106272cfc5d19d60ca07b9bc4e22ff97b2b2451b67ec8884909c574634a337 lib/codeql/swift/generated/expr/ArrayExpr.qll 9894f7838b23c84c4c0ba442b790ada0231c2dc3508fd30735577397a87d9683 90ed566a71551f3549106bd60b972aca0ba52e8a2b787b58a3161634e26e773e lib/codeql/swift/generated/expr/ArrayToPointerExpr.qll afa9d62eb0f2044d8b2f5768c728558fe7d8f7be26de48261086752f57c70539 afa9d62eb0f2044d8b2f5768c728558fe7d8f7be26de48261086752f57c70539 lib/codeql/swift/generated/expr/AssignExpr.qll 97d41626dfe4e474c5e80aaee433641847a91f5c483f6da6cfc016b454545802 4ca02b4a878f0783f7d7788c85ffbb89c8ed6027c7e6d391ea9892256215358a @@ -451,7 +452,7 @@ lib/codeql/swift/generated/expr/BridgeFromObjCExpr.qll b9a6520d01613dfb8c7606177 lib/codeql/swift/generated/expr/BridgeToObjCExpr.qll 31ca13762aee9a6a17746f40ec4e1e929811c81fdadb27c48e0e7ce6a3a6222d 31ca13762aee9a6a17746f40ec4e1e929811c81fdadb27c48e0e7ce6a3a6222d lib/codeql/swift/generated/expr/BuiltinLiteralExpr.qll 052f8d0e9109a0d4496da1ae2b461417951614c88dbc9d80220908734b3f70c6 536fa290bb75deae0517d53528237eab74664958bf7fdbf8041283415dda2142 lib/codeql/swift/generated/expr/CallExpr.qll c7dc105fcb6c0956e20d40f736db35bd7f38f41c3d872858972c2ca120110d36 c7dc105fcb6c0956e20d40f736db35bd7f38f41c3d872858972c2ca120110d36 -lib/codeql/swift/generated/expr/CaptureListExpr.qll 4e94c2c66020f95af615d98756d7c1843c2744b3c1d83f73f24f6153d9d0592b e35e8190904415e2a1fe12857127c90cfaecde4f6f173d16399f45c0264d207c +lib/codeql/swift/generated/expr/CaptureListExpr.qll 671234408ead93c0d6abc453f774a88f0888956e6ad08d5a1c22aec72b2eec46 601e23e0356341fd6287fb9775f0e86bca6a0de46383e0912854e045e501d42c lib/codeql/swift/generated/expr/CheckedCastExpr.qll 146c24e72cda519676321d3bdb89d1953dfe1810d2710f04cfdc4210ace24c40 91093e0ba88ec3621b538d98454573b5eea6d43075a2ab0a08f80f9b9be336d3 lib/codeql/swift/generated/expr/ClassMetatypeToObjectExpr.qll 076c0f7369af3fffc8860429bd8e290962bf7fc8cf53bbba061de534e99cc8bf 076c0f7369af3fffc8860429bd8e290962bf7fc8cf53bbba061de534e99cc8bf lib/codeql/swift/generated/expr/ClosureExpr.qll f194fc8c5f67fcf0219e8e2de93ee2b820c27a609b2986b68d57a54445f66b61 3cae87f6c6eefb32195f06bc4c95ff6634446ecf346d3a3c94dc05c1539f3de2 @@ -462,8 +463,8 @@ lib/codeql/swift/generated/expr/ConditionalBridgeFromObjCExpr.qll 4a21e63cc54702 lib/codeql/swift/generated/expr/ConditionalCheckedCastExpr.qll 92a999dd1dcc1f498ed2e28b4d65ac697788960a66452a66b5281c287596d42b 92a999dd1dcc1f498ed2e28b4d65ac697788960a66452a66b5281c287596d42b lib/codeql/swift/generated/expr/CovariantFunctionConversionExpr.qll b749118590163eafbd538e71e4c903668451f52ae0dabbb13e504e7b1fefa9e1 abaf3f10d35bab1cf6ab44cb2e2eb1768938985ce00af4877d6043560a6b48ec lib/codeql/swift/generated/expr/CovariantReturnConversionExpr.qll f1b409f0bf54b149deb1a40fbe337579a0f6eb2498ef176ef5f64bc53e94e2fe 532d6cb2ebbb1e6da4b26df439214a5a64ec1eb8a222917ba2913f4ee8d73bd8 -lib/codeql/swift/generated/expr/DeclRefExpr.qll dda3034aba0170fb91ae62e5c8b02af27f3ac682c856af6eba2f8c57c186befe 338e7cfbea450e555191518dfa6b7b43cef3a0a029c4c0adb5101a2471c24c5e -lib/codeql/swift/generated/expr/DefaultArgumentExpr.qll ca9f228742acf990a81308f68a66dc55b35c75f23d5f0cabfdff30a1b99064d7 a97de64329149db8ca6d25635bdda63df0a2bdb600cfe0c71017e2eb3fdecb15 +lib/codeql/swift/generated/expr/DeclRefExpr.qll 06149b37933848032fb6cc4692ff63ee54347cccb79e1fa150129a081afbf5d2 580392ea470c21a58021245f1d7fa08232a2f5314786ba8476282a5fbe403ffe +lib/codeql/swift/generated/expr/DefaultArgumentExpr.qll 77468697fd5cafb05ca166a77e94ce9998c28624e235b626b9afbe1da9a93d4e d813ea7d5973945355a2941ccd3ca72e01745ab6320da429f3694e2465af96d3 lib/codeql/swift/generated/expr/DerivedToBaseExpr.qll 5f371b5b82262efb416af1a54073079dcf857f7a744010294f79a631c76c0e68 5f371b5b82262efb416af1a54073079dcf857f7a744010294f79a631c76c0e68 lib/codeql/swift/generated/expr/DestructureTupleExpr.qll 1214d25d0fa6a7c2f183d9b12c97c679e9b92420ca1970d802ea1fe84b42ccc8 1214d25d0fa6a7c2f183d9b12c97c679e9b92420ca1970d802ea1fe84b42ccc8 lib/codeql/swift/generated/expr/DictionaryExpr.qll f8bab2bdf683f4974be102faea2f8ff48ede5937a9112a1fa149180143052b0a 152ae4811c5282c68b9f2eb7b123631fbe461af7a7947434abf7e523b35b27e2 @@ -477,13 +478,13 @@ lib/codeql/swift/generated/expr/DynamicLookupExpr.qll 0f0d745085364bca3b67f67e34 lib/codeql/swift/generated/expr/DynamicMemberRefExpr.qll 2eab0e58a191624a9bf81a25f5ddad841f04001b7e9412a91e49b9d015259bbe 2eab0e58a191624a9bf81a25f5ddad841f04001b7e9412a91e49b9d015259bbe lib/codeql/swift/generated/expr/DynamicSubscriptExpr.qll f9d7d2fc89f1b724cab837be23188604cefa2c368fa07e942c7a408c9e824f3d f9d7d2fc89f1b724cab837be23188604cefa2c368fa07e942c7a408c9e824f3d lib/codeql/swift/generated/expr/DynamicTypeExpr.qll c29baea6ec5b0b7186b675e3322cd1cee9db8d647e16ac0f716990c22df17074 de9118fdb3778ef76de284992791d3f0f9978876f5799eda39da92c1242e603e -lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll edea1f464dc24ad8d300c547698699704cf7d9232782c2b6a536af6e058d440c 7d860abba668ac5fb078ac7b72d455824331d753751bbfbe7044a85a8365b6a7 +lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll 8df7cf11dff39ec1a8498d4df4cda2ab0fb49a88aaca671c8e4fd6d53bbf2af9 e5b064938c60634eb1060d39b435913286591e1e8d506bbb19ee8faace7105c5 lib/codeql/swift/generated/expr/ErasureExpr.qll c232bc7b612429b97dbd4bb2383c2601c7d12f63312f2c49e695c7a8a87fa72a c232bc7b612429b97dbd4bb2383c2601c7d12f63312f2c49e695c7a8a87fa72a lib/codeql/swift/generated/expr/ErrorExpr.qll 8e354eed5655e7261d939f3831eb6fa2961cdd2cebe41e3e3e7f54475e8a6083 8e354eed5655e7261d939f3831eb6fa2961cdd2cebe41e3e3e7f54475e8a6083 lib/codeql/swift/generated/expr/ExistentialMetatypeToObjectExpr.qll eb0d42aac3f6331011a0e26cf5581c5e0a1b5523d2da94672abdebe70000d65b efe2bc0424e551454acc919abe4dac7fd246b84f1ae0e5d2e31a49cbcf84ce40 lib/codeql/swift/generated/expr/ExplicitCastExpr.qll 162f94461d41cf10a81567e13d5141d7aca417cc92d4ef55de97c7909681882e c8e7d1f569265a9bc2ae6a82e33783ec3ac077c3ae6e582edcb49a4eb816f7b5 lib/codeql/swift/generated/expr/ExplicitClosureExpr.qll c5291fb91e04a99133d1b4caf25f8bd6e7f2e7b9d5d99558143899f4dc9a7861 c5291fb91e04a99133d1b4caf25f8bd6e7f2e7b9d5d99558143899f4dc9a7861 -lib/codeql/swift/generated/expr/Expr.qll b09ddd296693ad78a2b0e7dc17d2b746357ae88645b046a026861eafeba616cb 498c628f904fbf48be10f32b146168b71f8f7d9f829614e422020701ccc0f8e4 +lib/codeql/swift/generated/expr/Expr.qll 91b45df8d77ece59147e330b1a93515ad791e1da84128a079be2160ee5f87796 4a57263c533d9d5a9e1cacc997d09434fe7ebbabff9ac1a49602b618b828839b lib/codeql/swift/generated/expr/FloatLiteralExpr.qll ae851773886b3d33ab5535572a4d6f771d4b11d6c93e802f01348edb2d80c454 35f103436fc2d1b2cec67b5fbae07b28c054c9687d57cbd3245c38c55d8bde0b lib/codeql/swift/generated/expr/ForceTryExpr.qll 062997b5e9a9e993de703856ae6af60fe1950951cf77cdab11b972fb0a5a4ed3 062997b5e9a9e993de703856ae6af60fe1950951cf77cdab11b972fb0a5a4ed3 lib/codeql/swift/generated/expr/ForceValueExpr.qll cd7ee5fa4a6f7094c7fbb9c5831f60d5ce18b123fe7beea3dcb26ca78e387118 7cdef6e9b501f9e9cb0d48828e68b349b25e4e5f312e5bcee91868ae8b196e7d @@ -502,14 +503,14 @@ lib/codeql/swift/generated/expr/InterpolatedStringLiteralExpr.qll e2c1aadf140c80 lib/codeql/swift/generated/expr/IsExpr.qll b5ca50490cae8ac590b68a1a51b7039a54280d606b42c444808a04fa26c7e1b6 b5ca50490cae8ac590b68a1a51b7039a54280d606b42c444808a04fa26c7e1b6 lib/codeql/swift/generated/expr/KeyPathApplicationExpr.qll 157a9c2fcf229b76d104abfa49f74337e20ac4d1fa1be2eaed1290cbd9bd1232 70ec0e7ee2e2c716ba510916fdf6d1d6dd6fd93b740a46c909ddb9e877427fe1 lib/codeql/swift/generated/expr/KeyPathDotExpr.qll ea73a462801fbe5e27b2f47bca4b39f6936d326d15d6de3f18b7afa6ace35878 ea73a462801fbe5e27b2f47bca4b39f6936d326d15d6de3f18b7afa6ace35878 -lib/codeql/swift/generated/expr/KeyPathExpr.qll 654b32a92ff8015cb4b8d64c83abed601a884f4181613a7d428e975a945afff5 4c82c7b9d9232e84dd898cb7d3d79c1365481cd9d37444318a776ae509eb023a +lib/codeql/swift/generated/expr/KeyPathExpr.qll 7d088ae6d74193f06b2c121dfde182a228d5ab1498a70fd3ad7bc5cab8e76dcd 5596774318c8eed672ab360c0a1515493176d9edae64f09917ec789514928355 lib/codeql/swift/generated/expr/LazyInitializationExpr.qll b81b831893b0f1c2bcbf48a708267cd54a86dfc6af6dde8b8b57a03e045abff2 b28cf1f4017edee09278a23f403932f91fb1a21ea83778cccf7683b5a57f6480 lib/codeql/swift/generated/expr/LinearFunctionExpr.qll cd4c31bed9d0beb09fdfc57069d28adb3a661c064d9c6f52bb250011d8e212a7 cd4c31bed9d0beb09fdfc57069d28adb3a661c064d9c6f52bb250011d8e212a7 lib/codeql/swift/generated/expr/LinearFunctionExtractOriginalExpr.qll ee7d3e025815b5af392ffc006ec91e3150130f2bd708ab92dbe80f2efa9e6792 bcf9ed64cca2dcf5bb544f6347de3d6faa059a1900042a36555e11dfbe0a6013 lib/codeql/swift/generated/expr/LinearToDifferentiableFunctionExpr.qll f7aa178bff083d8e2822fda63de201d9d7f56f7f59f797ec92826001fca98143 c3ef32483f6da294c066c66b1d40159bc51366d817cf64a364f375f5e5dfa8b0 lib/codeql/swift/generated/expr/LiteralExpr.qll b501f426fa4e638b24d772c2ce4a4e0d40fce25b083a3eee361a66983683ee9d 068208879c86fbd5bed8290ce5962868af6c294a53ad1548cf89cf5a7f8e1781 lib/codeql/swift/generated/expr/LoadExpr.qll 90b9ba4c96c26c476c3692b1200c31071aa10199d3e21ef386ff48b9f0b6d33a 90b9ba4c96c26c476c3692b1200c31071aa10199d3e21ef386ff48b9f0b6d33a -lib/codeql/swift/generated/expr/LookupExpr.qll 12844a93ff8244c9a9c7091b32c56e80a1196dee5fbdd67dafa5329e8d424ed9 da9ba34043930d541751ba3bc828cfcf86cc0fcf3b58bf2a2a0b8d9ad7d73153 +lib/codeql/swift/generated/expr/LookupExpr.qll 612265f7ca68f1f62ea8ceaa74e1a876195c6c3062807b310f834aa04acfaa80 160fbb1efe0c1fb48698d786bb7f76be70b4cd96568557f90c062773fb0dff6e lib/codeql/swift/generated/expr/MagicIdentifierLiteralExpr.qll 16f0050128caf916506b1f7372dc225a12809a60b5b00f108705fcdfce3344a8 c064778526a5854bdf8cdbf4b64ad680b60df9fe71ec7a2d9aa6c36a7c4e5b31 lib/codeql/swift/generated/expr/MakeTemporarilyEscapableExpr.qll c63cd023a5c2662e2beee8dba5f9cb0012103424a245df5fde0d4a08a13a87ea 78729409bc0e387ad2ed7cd84b074dbf190f378a6c8794f4a6596ddfa1b1ad85 lib/codeql/swift/generated/expr/MemberRefExpr.qll e7db805b904d9b5d1e2bc2c171656e9da58f02a585127c45f52f7f8e691dc2e5 b44b5208e0b72060527a6fdb24b17b208f2263d78690d13548fba937fe0db3cd @@ -517,34 +518,34 @@ lib/codeql/swift/generated/expr/MetatypeConversionExpr.qll 714ecbc8ac51fdaaa4075 lib/codeql/swift/generated/expr/MethodLookupExpr.qll 526c9001c311a890db2409a46180a7fedbb11b6dcd8ee23dda4d4644e65bed3a 4b287235a19b85880136ac3485a85742aad7217021c9f6729bf2a39be5ebd1a1 lib/codeql/swift/generated/expr/NilLiteralExpr.qll 6f44106bc5396c87681676fc3e1239fe052d1a481d0a854afa8b66369668b058 6f44106bc5396c87681676fc3e1239fe052d1a481d0a854afa8b66369668b058 lib/codeql/swift/generated/expr/NumberLiteralExpr.qll 8acc7df8fe83b7d36d66b2feed0b8859bfde873c6a88dd676c9ebed32f39bd04 4bbafc8996b2e95522d8167417668b536b2651817f732554de3083c4857af96a -lib/codeql/swift/generated/expr/ObjCSelectorExpr.qll efc72580627467dce30ab784bfb963bd21297440bd6287600d0b3f2c5836c340 29a7974a65bde8f434de159e9a6ea0f6f48609d4d3332a216261f3c64cf3a070 -lib/codeql/swift/generated/expr/ObjectLiteralExpr.qll 199b3a5196bff35681ba2e4bdb546cfbe0a2e265f535d05cfdb89af9c382c1a6 7c6b962565841a634c850d088fd404a3e6f3045e05ff555e1cde0ec02ba8dc8d +lib/codeql/swift/generated/expr/ObjCSelectorExpr.qll 94a8344bff75033a3aae101c103419bd2201aa6992393d3450e4531ec33d4c83 78870c097692943f2eefb3ee86ccc86579411f35a4fa6e8753bf307009f85dba +lib/codeql/swift/generated/expr/ObjectLiteralExpr.qll f609e898670d4fc7937e9f5024dbf9d82c98bdfcef140cee6e13998046fbe044 cd8647e0b186ce74d27ac0fcfe037972f7e12a326a0ef53c51305cb7db783a0c lib/codeql/swift/generated/expr/OneWayExpr.qll 8464649694b671a8462476fcd3827b07f8448069c7caa9e9efce44d7ce87aee0 c3e143ecd28238342a1d911a468087cc58a751106385f01cbe5a44e19c862d0e lib/codeql/swift/generated/expr/OpaqueValueExpr.qll 354f23d00d5ea2e734fd192130620d26c76c14d5bb7b0a1aa69f17ffb5289793 354f23d00d5ea2e734fd192130620d26c76c14d5bb7b0a1aa69f17ffb5289793 lib/codeql/swift/generated/expr/OpenExistentialExpr.qll 55ff1b4fdf23b787538f8b8cdc5f382d874221cec230f8fa35189ebf6de09b58 8235fe3387753a0ac389e297bf67b416991117587a98a566620ac9b328887dd6 lib/codeql/swift/generated/expr/OptionalEvaluationExpr.qll 76a3a789b3a4f17dd494f973f099766aa1db97c38cbbd93542e664a7cd7e1680 f56ce693b59cee6713a7cfdb2937a8a4e791d6e80c241ecd333ab197482a2d1b lib/codeql/swift/generated/expr/OptionalTryExpr.qll f0c8dff90faee4fbf07772efda53afe1acc1fd148c16ee4d85a1502a36178e71 f0c8dff90faee4fbf07772efda53afe1acc1fd148c16ee4d85a1502a36178e71 -lib/codeql/swift/generated/expr/OtherInitializerRefExpr.qll 9e695cca00e162beadad513d6833f117cee0f364da6f16c7ed3809573c1fbfe2 ff29f1f265e22eefc9166f77fa8adca7f89d3f769591149e21c58c0789577a88 -lib/codeql/swift/generated/expr/OverloadedDeclRefExpr.qll fee0ef58103e48b9238f1dd94d530a54e8ffaea95924cdbb38057701360a849d 2e851c3aee89aa3cbc3b67846a723b98708233e74e872641988c3200476d2da2 +lib/codeql/swift/generated/expr/OtherInitializerRefExpr.qll 94b793be9a37626fe0b1b7c93ac37b2a00e4fb93ab96e4a230aaba66ef1721de 136ac6a349db23144fc71f3aa1383fb68370b13a8615eb6ad398b29a55f2cae3 +lib/codeql/swift/generated/expr/OverloadedDeclRefExpr.qll f2ef6518501e4bf7c51d009cb996dc88d56374a4dc572ce8514993591896deba e8519550ec34428715452f6716160e580cbbc894c2b78dd34c33835e11728f19 lib/codeql/swift/generated/expr/ParenExpr.qll f3fb35017423ee7360cab737249c01623cafc5affe8845f3898697d3bd2ef9d7 f3fb35017423ee7360cab737249c01623cafc5affe8845f3898697d3bd2ef9d7 lib/codeql/swift/generated/expr/PointerToPointerExpr.qll 7d6fa806bba09804705f9cef5be66e09cbbbbda9a4c5eae75d4380f1527bb1bd 7d6fa806bba09804705f9cef5be66e09cbbbbda9a4c5eae75d4380f1527bb1bd lib/codeql/swift/generated/expr/PostfixUnaryExpr.qll d1094c42aa03158bf89bace09b0a92b3056d560ebf69ddbf286accce7940d3ab d1094c42aa03158bf89bace09b0a92b3056d560ebf69ddbf286accce7940d3ab lib/codeql/swift/generated/expr/PrefixUnaryExpr.qll f66dee3c70ed257914de4dd4e8501bb49c9fe6c156ddad86cdcc636cf49b5f62 f66dee3c70ed257914de4dd4e8501bb49c9fe6c156ddad86cdcc636cf49b5f62 lib/codeql/swift/generated/expr/PropertyWrapperValuePlaceholderExpr.qll 0d604764ca2e77a51b7e7062a1f57c6f46dd007717bdebf765eb7b737ef5062d cff734718467dfd4abc12dcf7e72c5745fe4e917204cdd22e42973f30eb06df7 lib/codeql/swift/generated/expr/ProtocolMetatypeToObjectExpr.qll b692be6e5b249c095b77f4adcad5760f48bc07f6f53767ee3d236025ee4a2a51 efa47435cde494f3477164c540ac1ce0b036cb9c60f5f8ec7bfca82a88e208fb -lib/codeql/swift/generated/expr/RebindSelfInInitializerExpr.qll 87984796ee7bb5f8f474563d03e667b09ff36ccba5e084504e24ab3d9e90d4f2 b4885cb5a72edad07011e3e576ff3ce08ef6399320786ce1cf9d7a0a6350eb6f +lib/codeql/swift/generated/expr/RebindSelfInInitializerExpr.qll 66d4cbf211cae63a443d85f83a2799cb6ac66c061e691d0531ff5edeec9af6f3 7be66e5be4c6671abcb03af92d00ce5f5ba46797941ffbb98675f6cd15db59c7 lib/codeql/swift/generated/expr/RegexLiteralExpr.qll a11eb6f6ce7cebb35ab9ff51eae85f272980140814d7e6bded454069457a1312 bdb4bb65c9f4e187cf743ed13c0213bb7e55db9cc3adeae2169df5e32b003940 lib/codeql/swift/generated/expr/SelfApplyExpr.qll c0815a4d6d4f08bd0c7bc170fa817ebcb2328c937c8ef16391fb0da71aff17ae 0979f035e8d4b54e93f17163a4df3c2aa65f23d56c491fa72376887e3e5c10ac lib/codeql/swift/generated/expr/SequenceExpr.qll 62301b2e4c76de4820c6deef0ee95c8b328ed14ba8eac70aa10cc8fb0f3c5ace feb960c796ea517abc9587bd76f7ae9aabfd9a6b0984fe2d8380e803b002eede lib/codeql/swift/generated/expr/StringLiteralExpr.qll f420c5cd51a223b6f98177147967266e0094a5718ba2d57ae2d3acbb64bbb4b6 30d6dab2a93fd95e652a700902c4d106fecfce13880c2ece565de29f2504bedf lib/codeql/swift/generated/expr/StringToPointerExpr.qll ef69b570aa90697d438f5787a86797955b4b2f985960b5859a7bd13b9ecb9cd3 ef69b570aa90697d438f5787a86797955b4b2f985960b5859a7bd13b9ecb9cd3 -lib/codeql/swift/generated/expr/SubscriptExpr.qll 70ca2812ac4018c062fcb099e20433c7960325e68cfc544599d1860793b1464f d01d4b4ed833cb0390c3e96e75ef51150721245b0277946d75daca32d4085d9b -lib/codeql/swift/generated/expr/SuperRefExpr.qll f550961b912bdcaf159d4729b0a3f6911e97365e6d429717d4a9770a2a83a184 e5735644d755ac2ee56f6c3ab13ca6657c21cd00a366665ea858d405d32cb112 -lib/codeql/swift/generated/expr/TapExpr.qll 8556465559ed243c16396a1b426b666362c1bab1535a12faf9c1050e1b06c668 ea1c30b90d3620e580294d7d7010a720be688e10a9469405cd58b3da55070dc6 +lib/codeql/swift/generated/expr/SubscriptExpr.qll 8a2bf1f0ded1888546791e0e59b969267f0352223e2abeb38e91dfa2144a38ae 009566ef61689d14844730235b0e0c31ee01e95e2002cf7272cbabc97539dce9 +lib/codeql/swift/generated/expr/SuperRefExpr.qll 4fe3e827cff256d304bc73f0d44b6091dbea68d8176ff3af36dec80ab349f7dc 7e1c3975515db1aacdd8f5c90ff38cfc568e2c9e79495bb7832d72f856add2e8 +lib/codeql/swift/generated/expr/TapExpr.qll 6583473139cc6c93838e802d8e229ad90d90a2ef960600d95db6d12831402ff3 a7478c0c9e9a9899c1840838150e127e3bd192bb340249642efede3dd51d260a lib/codeql/swift/generated/expr/TryExpr.qll e6619905d9b2e06708c3bf41dace8c4e6332903f7111b3a59609d2bb7a6483ee e6619905d9b2e06708c3bf41dace8c4e6332903f7111b3a59609d2bb7a6483ee lib/codeql/swift/generated/expr/TupleElementExpr.qll e0050f30b31c58bcfbaaa61137484f9463aab435cbe1fd0dddd7a4b9d3a8ae46 0192eb79f1b1bff6185dddbc8ed37865cb669a670ffb9f5b63c34c1bf53a73c2 lib/codeql/swift/generated/expr/TupleExpr.qll b834c6347ec355f1135274f65bd7ca3768be42ea173225227a6b543c2fb2243b fddb421e1cdc8ae24afb6b72c0636b3341c5b039a4277fc99f00bbb077645cf8 -lib/codeql/swift/generated/expr/TypeExpr.qll accffc2dbe4a1f1ebdaeb4ca6a130faf139288a7470740213d5379ddc94dad18 e4595beff0e7b7cd698e2bb708ea10586cc2f2de5d6f9dcf3da3c3d9b43d33eb +lib/codeql/swift/generated/expr/TypeExpr.qll 0ebb5040199b71ea2f8922848b6d7ad2d4ac585b763485195e4180a118839dfa fb991cb078cecdfd0ec0d19d896635e7b834481c30970bd83fdd4e9792548416 lib/codeql/swift/generated/expr/UnderlyingToOpaqueExpr.qll 13d6c7a16ec0c4c92d12e052437dfa84274394ee8a4ca9b2c9e59514564dc683 13d6c7a16ec0c4c92d12e052437dfa84274394ee8a4ca9b2c9e59514564dc683 lib/codeql/swift/generated/expr/UnevaluatedInstanceExpr.qll 21dedc617838eed25a8d3a011296fda78f99aee0e8ae2c06789484da6886cfea 21dedc617838eed25a8d3a011296fda78f99aee0e8ae2c06789484da6886cfea lib/codeql/swift/generated/expr/UnresolvedDeclRefExpr.qll 17e83f6418f39cfd3b7768ba694dafce2807f97239d3ac0939fc0c3761ae3571 910e9440cae403b13b6dd501a3dbbda564a1d7d61a532e99a1825590c2d9a4ab @@ -558,45 +559,45 @@ lib/codeql/swift/generated/expr/VarargExpansionExpr.qll ac50264811fc0303220f7825 lib/codeql/swift/generated/pattern/AnyPattern.qll ce091e368da281381539d17e3bac59497ad51bb9c167d8991b661db11c482775 ce091e368da281381539d17e3bac59497ad51bb9c167d8991b661db11c482775 lib/codeql/swift/generated/pattern/BindingPattern.qll 61ae8b380b43c80710cf7d33c718c45b06cfa3680990e38e4191b3732236595c 1ff0450958cce5a5bfd00942d4846e3b2652499c738bd2790255632c883af0dd lib/codeql/swift/generated/pattern/BoolPattern.qll 118300aa665defa688a7c28f82deb73fa76adce1429d19aa082c71cfcbeb0903 0cd6db87e925e89f8ad6d464762d01d63ddfd34b05a31d5e80eb41aec37480b4 -lib/codeql/swift/generated/pattern/EnumElementPattern.qll 4aad6e1db45b8d39f61827e44335b2d7c1b9346538933bea82e4cec4b0993e3a 645edf97eb83f077f82c5f08cec912b845c826c2067f38f050b6e78031fe3a2e +lib/codeql/swift/generated/pattern/EnumElementPattern.qll 2d92a861316d46190e11880b0c383651e4ea15ea8fb81f55c08c4ce733bee2c7 c5915d7a3b62f7c009daac2e7d87c7d435a81a128bdfcc1db9ad281600acfb67 lib/codeql/swift/generated/pattern/ExprPattern.qll 169cef487e499a21d0d2cc4eda7268eb29cb6b1081fa6a0bc4e8571677f063f3 b7f3160f0812cf565873b607a247e184f17cc0289758f9a46748e90e783abd4f -lib/codeql/swift/generated/pattern/IsPattern.qll 864c38251026a523f91f0c097899cbc0c281f29d5c11142d5434cd182e8d70b8 be03f3a3aacbd44dc8e6a03f88d241d1247a3686c0d7d8eb4b50fa57c675aac9 +lib/codeql/swift/generated/pattern/IsPattern.qll c809159dff26b86d44f560742d66e75b3cf143cdfc0f3933b959864412770248 7375cb8140da3c1531b55b084c4b6aa8009495dd40697a13f05b258d3f5677cc lib/codeql/swift/generated/pattern/NamedPattern.qll 5d25e51eb83e86363b95a6531ffb164e5a6070b4a577f3900140edbef0e83c71 9e88b2b2b90a547b402d4782e8d494bc555d4200763c094dd985fe3b7ebc1ec8 lib/codeql/swift/generated/pattern/OptionalSomePattern.qll 5b9c7032584619d4921d1a1324e3ce4bd7207f0d4daa703e1e059f983bf1b132 e6d44514cd123a7ad27f657a2b83d46277a961a849139380ece886430a862920 lib/codeql/swift/generated/pattern/ParenPattern.qll 337cb03dcb7384f7ef13e35d843b3498c0ae391374f5e870d1e52c2d1baacd95 cba288ee99726f5bbf15cf61971e000a835cf6e8b7507dcf6f6c6dea91ec287a -lib/codeql/swift/generated/pattern/Pattern.qll 0e96528a8dd87185f4fb23ba33ea418932762127e99739d7e56e5c8988e024d1 ba1e010c9f7f891048fb8c4ff8ea5a6c664c09e43d74b860d559f6459f82554a +lib/codeql/swift/generated/pattern/Pattern.qll abdb00ae9ee55061de85fa77ecff6f3df9ddf395f45a38dde94983ac423d861a 67ffece7bd83150bb0981b2fda86468c2df7c4d2015526b90ca40c71eec6b542 lib/codeql/swift/generated/pattern/TuplePattern.qll b3a138b0942f7e3eecb52ad2f095584a6cd5f555e9487c6eaad6a5527ae99f0c d6ff67ecc7395571acef4b82da514cb737c72d97ea557d89da534469feda340c -lib/codeql/swift/generated/pattern/TypedPattern.qll 95185ae7acddb74ac68f2d2e31d83e64e3bac3fdbd7a8301a6dc8bb1d89d7918 5d6edf73b4ac2f81843fda26894f5dbf8aa2a7c129af5e1a3256370683fa619c -lib/codeql/swift/generated/stmt/BraceStmt.qll 15461198f638b8995687ad8a20ef47c8fac24445a8c28ea5113bbaabe43e4be3 72fa14dbb9cd31032a5f35754991beb6183c2ef37f942707dbfc8911687d8c6e -lib/codeql/swift/generated/stmt/BreakStmt.qll 7dca1ed723117cc245636c7ec5f31a69dbbb228eae2f6423ffa1f327f964d1c8 43052e648b31c6edf88c28fc8aa0ec440601c06776d5a32e7ef1efbb59f64cf2 -lib/codeql/swift/generated/stmt/CaseLabelItem.qll d04772471f1651c0f3c15cb7fa003431b2a51bbffa945a14ae85bb3e58015249 406b2d411a1aa3a513f93e9602ce34138bd47d84a8c5b9fc226ed3e0c972ae08 -lib/codeql/swift/generated/stmt/CaseStmt.qll 01b7cb7fe5839c02fec5af4ddc9d6c7646583305e17543f1e5a6993b8467c3cd 62ab05c856c1a567aa7aaa04390fee9cd65d44ad3e244a1f781e97710b89653d -lib/codeql/swift/generated/stmt/ConditionElement.qll 2f60c9326681613939b411d9c5e53e0e0e5cf756b551af4e150b8be964d8e05d 4155edf57ccc61b87f5d51684e57c06cd0bc6733579275f089de51975546eab1 -lib/codeql/swift/generated/stmt/ContinueStmt.qll 572747312c2a7c4e6ad1c82c58f8ac55ce05d5e1f828160fe139c3d2c100eb61 a54d57cc434f7d04412bf130391e9c571f8f11f90be501d736e96f341b0c1de9 -lib/codeql/swift/generated/stmt/DeferStmt.qll 099b98183d770608f63ee09b290e71042e4cbbbc6a83b0f0fa10614af418c712 d5504347c08ab2b4764d5cb03a3b590a97144240d68f626db0778697ef9638c1 -lib/codeql/swift/generated/stmt/DoCatchStmt.qll 4a05ba358b289c052f1e7d6b86dae206e91a8033687c3fabddac1556173a8140 8743746aeb98f28e7786233db4a9eacfcf73aea3f602be9e1f8c0d956d22aeb1 -lib/codeql/swift/generated/stmt/DoStmt.qll b22efabd7431e703ae33dd1df69a9e3ceb49f512ab2c46be9c7eba2d53a1e37f 8d7796e2b4676da59aa8425014a16b82ef47d4ac22af60a10c5076a691af17d1 +lib/codeql/swift/generated/pattern/TypedPattern.qll 6a9fd2815755eddc6918d6be8221c7afb90e4fba4fcb8eb54ff42754269bb481 f198c3b09553a5f5f3d97f8088ef82c00552b9635560750c56d801b09dbd9e26 +lib/codeql/swift/generated/stmt/BraceStmt.qll 72557bdbde907042a936b55039e6032afd5eb92b21a6bb3d669437f3141a7e76 a2fb52f3d77444880edcafec6d107f27cf8c528c21241b1222823136fd4cfbb9 +lib/codeql/swift/generated/stmt/BreakStmt.qll 879cf66911cc7f53e7e8f4ae8244681018fb17d6501b269fb7cf9d8481f0b539 c78fc1b0e3e76321fc1653aa8b0aabaaacf082e01a003b78f693b106cc05faa0 +lib/codeql/swift/generated/stmt/CaseLabelItem.qll 9536d2909a274c3a969eec25f8e5966adfaa9b0d6451ea6319d9f7bb2fd6fe07 02e25f036db50e9a6e9a7ceab6002dd605b73afb55fa1dee6f22e7af33a40913 +lib/codeql/swift/generated/stmt/CaseStmt.qll c180478c6161439bc76bd39edfab343faba7450900ffedcadd3ccea12dc3a08c b537eb517db76113cfbc91c59e6bdfbf16ff83d639dfe6fd6892171f71a97090 +lib/codeql/swift/generated/stmt/ConditionElement.qll 29c1f9ab045cceac466836c8c6b9b158395351a76d4c4f8725d98663ea75b9de 09342a6d9632a1af973ef21fd03d30ca85b94ebb7d51991b4b573ce9096f97f4 +lib/codeql/swift/generated/stmt/ContinueStmt.qll bf300c9655f750db8e71eb530d8972eca1ac9bf022023c8d99e299de8f5b3a44 746a2432752743e18e2b5fa4b46407e5d4c0e6ee38635c6de0846452cbc5eec5 +lib/codeql/swift/generated/stmt/DeferStmt.qll 230f8c8f53c86afd3169b36214c03c54ac3e5240b1c1c1ade4446b45c4c3c32a d0d9e728be7506aa07904c53087eb1273a82762139866767abb0b851f3e559ee +lib/codeql/swift/generated/stmt/DoCatchStmt.qll b418fdb6d48c2c0d30d11c0b256692af879846113c89ccdd21a84cd27ccfddec 5aea94c795e300ee1d99119c86d201228537b24a1e281abb79a14b2edbb498af +lib/codeql/swift/generated/stmt/DoStmt.qll 582f56113ecc384ee80610ae80e2a040fbe58c56b72c76b6c7da3daaeee739bd 3778445dc2f6173d4182cbda47ca0d0e066d931379ed7da89bb3afd1fda1e81b lib/codeql/swift/generated/stmt/FailStmt.qll d8f5816c51c5027fd6dacc8d9f5ddd21f691c138dfc80c6c79e250402a1fe165 d8f5816c51c5027fd6dacc8d9f5ddd21f691c138dfc80c6c79e250402a1fe165 -lib/codeql/swift/generated/stmt/FallthroughStmt.qll 0f5caceabd3f683914cd598c60e78f0c225a06b017784182e9bf1525ebf4eff8 fe328559e580ebcd38aac3b6402f1a40cd1c922e92b52456b18e79e6e241d7b4 -lib/codeql/swift/generated/stmt/ForEachStmt.qll 105f4905d2c9b832b01dabfc87a90294886ed867be119c83b1af779b61cca8c3 8aeae81570d9444f16e0335ac2d1b8645dc37e2b6b30ccdfeeda77b0d3c8af14 -lib/codeql/swift/generated/stmt/GuardStmt.qll 135faa385310d9398db6630c799ee57da6e5546e8ae09190b0aab8397c330c57 eb98434209466449d82dd75049850aa3d550f2c0d2b6e0a70f2ee8d2dae4d830 -lib/codeql/swift/generated/stmt/IfStmt.qll a01212a13060f36b0c5ff29a18aa64a450662b284d37d8cff10ce648507684b2 05e9617901b871d59fa9f08f3397aac7ebe7026ae482e316e591c2622ba64a2f -lib/codeql/swift/generated/stmt/LabeledConditionalStmt.qll 2865e39a960ec4f610cccc6cb93ecf2b3ef457fb4c3acb961ffcf84ed9c1f33e cb8b7f16520ead1299d898ccd22efb89a74e9b3d658fdb613af0797b60d80bb7 +lib/codeql/swift/generated/stmt/FallthroughStmt.qll aa400a95593395d97b196a78462fb5ab7cad0497b395cdd98885e1593271614d 4df6bfa7d2f4e2b5e5155351e445bb6c710e7c20c82fa3321564b11ef60b086a +lib/codeql/swift/generated/stmt/ForEachStmt.qll 0c4b3c9540aaf89c135de6618dc7f07680a44bb6e874d8b12b2457ecad7d766d 52fbec89382d3b207f379e126654008393be560c8efe4a490fda1e2c48914235 +lib/codeql/swift/generated/stmt/GuardStmt.qll f31660bbe32231e310ff3d33dfece761ee7ec888fe74683359f86a3766e7c378 ce1f8279839e0b6311107ea9473871cbcfdc7c12d2368ac55b989f9bff2c5e7c +lib/codeql/swift/generated/stmt/IfStmt.qll 80f1caba3a477e589b6aa3543ec1787005ab1ffab91a77832512c79dffce48c7 2126cf386e917a230175ba7e07450e390b4bd65da6fce1af8395e5ffd3f79dca +lib/codeql/swift/generated/stmt/LabeledConditionalStmt.qll 057c6c556ecd836ca7f40d208c04e43039dde53e41eb27cc27f5f502a38a86fa 2ee979a35e0e9fa72253ab21d57c18b7268b7acc1edb4ec514b73b99b0aa2c6c lib/codeql/swift/generated/stmt/LabeledStmt.qll 734f0bb5b40d72c3c949a08af15c01b3ae3a3e315f3196f75da27e03a2635d63 f1fbea28c7eef71135e60e144714b1027d71f07ccfabbb65d6a98aa89523720e -lib/codeql/swift/generated/stmt/PoundAssertStmt.qll d672d599679838fb9fcc7e9e3b4641a7d514ee35d94f9eaa9d56f1e893d57863 7ca6f2571015c105887b4c045c2305a05ad86813cf5fcf28b577efcc3d483717 -lib/codeql/swift/generated/stmt/RepeatWhileStmt.qll e9a4ac23dafb18a2bc23a045eb7ed8a96193600071d46351474ae899f7e24f7d 8bdfd1e1c75b95ba156dc0c90b5fcc185b0bee84feb144c7dc1b5f159703c79a -lib/codeql/swift/generated/stmt/ReturnStmt.qll c27a59f427f39d6eaebc96c6d975480be535945572e5a88ab961c34ef166df1a 269912d84e69f97348ea2cf46ab38d08cf92b7fc6bf6255e649a64580bf171ad +lib/codeql/swift/generated/stmt/PoundAssertStmt.qll c7a2effdfde66cf6308815affa966d63a9a251ddc27d492320733f1b2398ecdb 83b886c58dbdd845e4be08309c2be1e8954cd0aa1a8ce079d429f96beaef02bf +lib/codeql/swift/generated/stmt/RepeatWhileStmt.qll 5edf21c6f6a9ec95f1f4ada10a47f46e38550c307cae8b74dad4c26275e24ace 6a2c1cdc99ef31c9a8f49cc4cb207b832bb90d55f69ef3196948105daeaf8d45 +lib/codeql/swift/generated/stmt/ReturnStmt.qll bed521194ae4f9a60d3ea0a9ea46dd7dbbc62799272d752871524a8eedbefc46 eb28b591ad77d842211a0df931fd693581c0e792b93421679b64a38de637d836 lib/codeql/swift/generated/stmt/Stmt.qll b2a4f3712e3575321a4bc65d31b9eb8ddcd2d20af9863f3b9240e78e4b32ccff e0fc13b3af867aa53b21f58a5be1b7d1333b3e8543a4d214a346468f783dbf40 -lib/codeql/swift/generated/stmt/StmtCondition.qll 3a9b82fc0776c1693c620fd96b3dbf94052ca0a2134ea4c9c83e51a1df6accad d2f809dd6820aa05c1630cd09ca12f22f94698155661aecd5d3837e340354ff2 -lib/codeql/swift/generated/stmt/SwitchStmt.qll 2e43f3eb536bb8924311d2fe84b2b21f712875caeaa8c4b13047b782c06ae453 ff72f4a01c3d7d227a28481d5a95b0858c15619067dd159332693af05fd0f146 -lib/codeql/swift/generated/stmt/ThrowStmt.qll c6f419f7d7021061a913fd70e64e43d55efe4350f73a21921cbd0654fabfa928 b76d221ad122710050651a62efb92b318d48109ec5326971c66cf9876dde9e14 -lib/codeql/swift/generated/stmt/WhileStmt.qll 550fef68aa3e81fcc615a296fabeacacef7648fe8e0316daef8a2767654f3020 5a60c959f042ebd9142b26432ad905cc2079664568d1b0bdf22085d4a24a92b9 -lib/codeql/swift/generated/stmt/YieldStmt.qll 5b0a6e0a656f9db4095d128c3e7d6bf1265ff218045ad91bd0699097c6c3cce7 45f54dbd94af7c2ab7e53858a7c3389636726d3d5fb45b876b5daad1896d1305 +lib/codeql/swift/generated/stmt/StmtCondition.qll b8dabf10de10f7c21abe0c7911084a41beb6e7125016a9bc2e15a6ace6d31837 d3ad8923495c273b83d80c4c9f64665798273c843f4cd1862b0300a93c2ac2d6 +lib/codeql/swift/generated/stmt/SwitchStmt.qll e303f93ba166044326071368b8c3ef74c2a87c1c586b1d05cf645150f8958b1a 4a8e919ba35423b49d4400d0d0730a0372d5f75a741f49776654bae773250561 +lib/codeql/swift/generated/stmt/ThrowStmt.qll d486c63f0f224e088cd67deb296d47266c8cfa2212853f950f6d0457941a0ca2 c4315440944ccb312af7ee8ee18b5eb2b98909ba9655e4729ea0e0d6a87ff014 +lib/codeql/swift/generated/stmt/WhileStmt.qll ee2661a76fdb516095bfcfb3210b4e24fc0f9619e985c9916fc0f5150736dbb1 b6c95a8e410f79c8d0a7bc994f92bf34b51400a2ba49b67af28a5256687855a9 +lib/codeql/swift/generated/stmt/YieldStmt.qll 81e2e31455da36b08f21f905d3e5b87e9f5c10ba50990fa5722a2d9488378da4 21d9e9523ba28bd291753b331379945c621241ccadb0cb444755ee5947cb24d1 lib/codeql/swift/generated/type/AnyBuiltinIntegerType.qll a263451163e027c4c4223ec288e090b7e0d399cc46eb962013342bfeac5f6b86 d850ec1ee1902945b172ddd0ecd8884e399e963f939c04bc8bfaadacebdf55a9 lib/codeql/swift/generated/type/AnyFunctionType.qll ecd701702fc4f5a2205208faad7598f3083028914e72aacdaa6311f522468352 342e2265f0593c3f388a7f293b589f332c977d7863d697901445d68f0b93a222 -lib/codeql/swift/generated/type/AnyGenericType.qll a6da9ae1024bdafa244f3f5843fe16efe06f5d8e7305c5712f6b9ff409347427 11694abc90753c3f1a27e4745919f851334e0b79eb576831403c7866014b64aa +lib/codeql/swift/generated/type/AnyGenericType.qll 8b64a517c57c6c7e46eca923a5611c28c626c920818b5b9060f1772c10d1a636 151ce25c5b86e51d4e0f4a11c058eb1555a8d3f286029b37732b47b3b23e3667 lib/codeql/swift/generated/type/AnyMetatypeType.qll 6805a6895e748e02502105d844b66fab5111dbb0d727534d305a0396dacc9465 58e0794b8d6dccd9809f5b83bf64b162e69f3f84b5f3161b88aed10f16a8ede8 -lib/codeql/swift/generated/type/ArchetypeType.qll 2642f841dac57a4c2447ceb5c3a42bf9e59bdb426556307dae863bd4009950e0 e7136d1929951d7dc928d0ebab99aca84eee8bf71aad86f480c4820da26adec0 +lib/codeql/swift/generated/type/ArchetypeType.qll 49560392daec2e41846dba8254a1ce420ca17a0e6d45c6a6b670f3f9e44e2c18 6865b7359c413602d7de11aec850811a012cad846a5839817c4d5644c6138d8a lib/codeql/swift/generated/type/ArraySliceType.qll 72d0409e2704e89ebca364ae28d55c874152f55dd1deaac6c954617f6566f3c2 72d0409e2704e89ebca364ae28d55c874152f55dd1deaac6c954617f6566f3c2 lib/codeql/swift/generated/type/BoundGenericClassType.qll c82971dcd306a4cbc6bb885ae300556717eb2d068066b7752a36480e5eb14b5f c82971dcd306a4cbc6bb885ae300556717eb2d068066b7752a36480e5eb14b5f lib/codeql/swift/generated/type/BoundGenericEnumType.qll 89fcee52adbe6c9b130eae45cf43b2a2c302e8812f8519ea885e5d41dec3ec56 89fcee52adbe6c9b130eae45cf43b2a2c302e8812f8519ea885e5d41dec3ec56 @@ -616,7 +617,7 @@ lib/codeql/swift/generated/type/BuiltinType.qll 0f90f2fd18b67edf20712ff51484afd5 lib/codeql/swift/generated/type/BuiltinUnsafeValueBufferType.qll d569e7c255de5e87bb0eb68ae5e7fea011121e01b2868007485af91da7417cd6 d569e7c255de5e87bb0eb68ae5e7fea011121e01b2868007485af91da7417cd6 lib/codeql/swift/generated/type/BuiltinVectorType.qll f51ce577abec2a1de3ae77a5cd9719aa4a1a6f3f5ec492c7444e410fb1de802a f51ce577abec2a1de3ae77a5cd9719aa4a1a6f3f5ec492c7444e410fb1de802a lib/codeql/swift/generated/type/ClassType.qll b52f0383d3dcbf7cf56d0b143cbb63783cb5fa319bcbfc4754e362d935e0fb53 b52f0383d3dcbf7cf56d0b143cbb63783cb5fa319bcbfc4754e362d935e0fb53 -lib/codeql/swift/generated/type/DependentMemberType.qll 0596086099ef55db0647b436e4d4ad6482496e8d491b6497e31b6f4ecdafe5d0 2de600fd4ac4739afdf4cd84822da467d195c7cc6d7099fe7ac446eae147979d +lib/codeql/swift/generated/type/DependentMemberType.qll 348f4b1eb1ed6e311212c1565716c814f9f4198ec4be7e748fbd10cef1f98ce4 a17c65acda68c87b7148047372a9779ce9eda53dbaa81208f0b9b57262001791 lib/codeql/swift/generated/type/DictionaryType.qll 1a30cd9815e9162cbf07d193a35d834837f8b8aa8ab936ea8c4400ea66181937 d4100b99422db8b81632cd86144c316ed8504616df742223cb6cde1211704d14 lib/codeql/swift/generated/type/DynamicSelfType.qll 331e731ce6ebf8e4b152efcbfbebe35d506c03633dab75483ae660f967259c58 4066ab0cd3c768fe25aba0d2ddaa4e394070f97dbe77b375c6fd39447eef8fd9 lib/codeql/swift/generated/type/EnumType.qll dcf653c7ee2e76882d9f415fbbc208905b8d8ed68cc32e36c0439a9205e65b35 dcf653c7ee2e76882d9f415fbbc208905b8d8ed68cc32e36c0439a9205e65b35 @@ -629,10 +630,10 @@ lib/codeql/swift/generated/type/GenericTypeParamType.qll f515debe8b21f3ea6551e4f lib/codeql/swift/generated/type/InOutType.qll 93906f54e2e109a8e83bf10665a9cfb518b96c6f8d8ea50e8d994a2802082e61 1cdf37ee0a2785e1a3298022f0d9aa8e9bce38e8d7268d631bb6544bdf07e636 lib/codeql/swift/generated/type/LValueType.qll ed2c9347139582c311b6ae58a26fd4462cdcd4ec1f1d0ea3c9967d0bec54683c d027432cc73850731f33b1aaf7e2aa57d97ed7e3171de3dc53902e6ed7e38b46 lib/codeql/swift/generated/type/MetatypeType.qll cd752f81257820f74c1f5c016e19bdc9b0f8ff8ddcc231daa68061a85c4b38e2 cd752f81257820f74c1f5c016e19bdc9b0f8ff8ddcc231daa68061a85c4b38e2 -lib/codeql/swift/generated/type/ModuleType.qll 46178692ceeda03ded0af1ab96af9e3ef4ba426e7345a0e2abfc6b35eebd9fc1 135549ca669d27c737159cc8327963879c11e32177a3b72d2076decb0927c475 +lib/codeql/swift/generated/type/ModuleType.qll 77fc9ea296b5be29aa8eded4cdfdbc7ca09a4c443f6720f31f9728a6e5bf115d c551af9fa41b1da433f52c89e3d126ac11caad8ab6a59baeda7bdbd7b11487cf lib/codeql/swift/generated/type/NominalOrBoundGenericNominalType.qll 27d87dc4792b7f46fa1b708aadecef742ab2a78b23d4eb28ce392da49766122f 380b827d026202cbfcd825e975ebbdf8f53784a0426ce5454cb1b43cc42dfe16 lib/codeql/swift/generated/type/NominalType.qll f7e85d544eaaa259c727b8b4ba691578861d15612a134d19936a20943270b629 87472017a129921d2af9d380f69c293f4deba788e7660b0fe085a455e76562e8 -lib/codeql/swift/generated/type/OpaqueTypeArchetypeType.qll 2126dd1e66b3b8fb4a2ac1808674f1c502cabe7cce11ecde407e78bbb1a1546e e78d3b63cc551a0dd284969c8ba6294466b1ddbcd17a0fdb745237a3793313ac +lib/codeql/swift/generated/type/OpaqueTypeArchetypeType.qll 54f267ce066c2bc3c1a4ef93154a2b99c1c6a7253c9d75f5d215a4e8fe036c1d f2d397bc48875d7c47e239d859a40ee191dad8340c7f2861d461c8a4f339fa49 lib/codeql/swift/generated/type/OpenedArchetypeType.qll ed97d3fb8810424643953a0d5ebd93e58d1b2e397ea01ccde0dcd8e68c41adb2 ed97d3fb8810424643953a0d5ebd93e58d1b2e397ea01ccde0dcd8e68c41adb2 lib/codeql/swift/generated/type/OptionalType.qll d99dd5ec5636cc6c3e0e52bf27d0d8bf8dfcff25739cd7e1b845f5d96b1a5ac9 d99dd5ec5636cc6c3e0e52bf27d0d8bf8dfcff25739cd7e1b845f5d96b1a5ac9 lib/codeql/swift/generated/type/ParameterizedProtocolType.qll 5ec7f5d9412f071099a75e920dce686e3a3b3697d94f2b03d4456858060d31d1 9d8f3ae67ebe290102f6c3fc4bda14d66865b13a782fe9e80e3e2464da14f18e @@ -646,9 +647,9 @@ lib/codeql/swift/generated/type/SubstitutableType.qll 9e74ec2d281cd3dedbc5791d66 lib/codeql/swift/generated/type/SugarType.qll 4ea82201ae20e769c0c3e6e158bae86493e1b16bbd3ef6495e2a3760baa1fc6b 6c78df86db6f9c70398484819a9b9ecc8ee337b0a4ac2d84e17294951a6fd788 lib/codeql/swift/generated/type/SyntaxSugarType.qll 253e036452e0ba8ae3bb60d6ed22f4efb8436f4ef19f158f1114a6f9a14df42c 743fe4dede40ca173b19d5757d14e0f606fe36f51119445503e8eea7cf6df3b0 lib/codeql/swift/generated/type/TupleType.qll af224031c3bea6dfca6138903cca940a4f00ba6494ad7b591b9f017d69ee9a6c f59ad1bb4994196ec49836ae169e550a70dbb25a359ff889ed6456882fe2d9a0 -lib/codeql/swift/generated/type/Type.qll c08acc943c9b52662a465d77fcd39d12f869c42b24a3755225b3bddbb1cf72f5 6d82c5bddded75fd5598bb559ecfa07360ad802d5e9541af2c334dc9d0159335 -lib/codeql/swift/generated/type/TypeAliasType.qll 1c7b7d66f277907d04462712ff5271b84987656351da8e486d718b8d138ef545 2dc20e1fd98bee6a8e5b35cf7a048716b2b6d2e5ba6610ecc4f7f667da930885 -lib/codeql/swift/generated/type/TypeRepr.qll bb78cc2265734d8ecbd32ca85e38c853e9f35569aaf4dc8353d20471b3559c3d c2abc1d161590cbdc4cac7e147e114f8a28ba5f6405dba7ead51abe85991505d +lib/codeql/swift/generated/type/Type.qll ada3973ed840643fa9f015d721d1f3c58994cda46b169e875b77473281d9122f 6a43dc43be0ac6f315b58ca4dc9b015769281eb5011220f28b5e9b6ed9436207 +lib/codeql/swift/generated/type/TypeAliasType.qll 7c1397c4a145d3265e8d1b4dac4ae6a58a2c4026145cfb2d8d28c01309b0ea26 0e3c3a2c166285f4ac1b417b8cc74a5095c8a8e1a102d7b5ca2829a06b61de23 +lib/codeql/swift/generated/type/TypeRepr.qll 25a412f029bf2d4b283ea07f0f0ff5713b1b4f369f8cb06991328fdee030e14a 2a39717f2e023c96015b797b59812b0e0bef1ea2780ee83869b68da549abbf2f lib/codeql/swift/generated/type/UnarySyntaxSugarType.qll 6f3822691d04531cc1dd6a78fb184f3e18d42ee324123dc4338fdd368fbd0bd6 d489aac77955de0d71fd5c271fddccd40050db4ef8ce8d817320ca9554057c3a lib/codeql/swift/generated/type/UnboundGenericType.qll 43549cbdaaa05c3c6e3d6757aca7c549b67f3c1f7d7f0a987121de0c80567a78 43549cbdaaa05c3c6e3d6757aca7c549b67f3c1f7d7f0a987121de0c80567a78 lib/codeql/swift/generated/type/UnmanagedStorageType.qll 198727a7c9557a0a92c6d833768086f0a0a18c546b4bfd486d7ff7ad5677a6aa 198727a7c9557a0a92c6d833768086f0a0a18c546b4bfd486d7ff7ad5677a6aa diff --git a/swift/ql/.gitattributes b/swift/ql/.gitattributes index 71cc5c58ecf..c1bcfc90e69 100644 --- a/swift/ql/.gitattributes +++ b/swift/ql/.gitattributes @@ -379,6 +379,7 @@ /lib/codeql/swift/generated/Element.qll linguist-generated /lib/codeql/swift/generated/ErrorElement.qll linguist-generated /lib/codeql/swift/generated/File.qll linguist-generated +/lib/codeql/swift/generated/HideableElement.qll linguist-generated /lib/codeql/swift/generated/KeyPathComponent.qll linguist-generated /lib/codeql/swift/generated/Locatable.qll linguist-generated /lib/codeql/swift/generated/Location.qll linguist-generated diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll index 9e7975890e6..ad96fcb12de 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll @@ -98,7 +98,7 @@ private predicate isBooleanConstant(ControlFlowElement n, boolean value) { // Boolean constants hidden inside conversions are also // constants that resolve to the same value. exists(ControlFlowElement parent | - parent.asAstNode() = n.asAstNode().getResolveStep() and + parent.asAstNode() = n.asAstNode().(HideableElement).getResolveStep() and isBooleanConstant(parent, value) ) } @@ -122,9 +122,9 @@ private predicate inBooleanContext(ControlFlowElement n) { private predicate astInBooleanContext(AstNode n) { n = any(ConditionElement condElem).getBoolean().getFullyUnresolved() or - n = any(ConditionElement condElem).getAvailability().getFullyUnresolved() + n = any(ConditionElement condElem).getAvailability() or - n = any(StmtCondition stmtCond).getFullyUnresolved() + n = any(StmtCondition stmtCond) or exists(RepeatWhileStmt repeat | n = repeat.getCondition().getFullyConverted()) or diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll index d3eb3aaa244..3efa0dd8bc3 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll @@ -264,7 +264,7 @@ module Stmts { or child.asAstNode() = ast.getAnElement().getBoolean().getFullyConverted() or - child.asAstNode() = ast.getAnElement().getAvailability().getFullyUnresolved() + child.asAstNode() = ast.getAnElement().getAvailability() } predicate firstElement(int i, ControlFlowElement first) { @@ -278,7 +278,7 @@ module Stmts { astFirst(ast.getElement(i).getBoolean().getFullyConverted(), first) or // ... or an availability check. - astFirst(ast.getElement(i).getAvailability().getFullyUnresolved(), first) + astFirst(ast.getElement(i).getAvailability(), first) ) } @@ -296,7 +296,7 @@ module Stmts { astLast(ast.getElement(i).getBoolean().getFullyConverted(), pred, c) or // ... or the availability check ... - astLast(ast.getElement(i).getAvailability().getFullyUnresolved(), pred, c) + astLast(ast.getElement(i).getAvailability(), pred, c) ) and // We evaluate the next element c instanceof NormalCompletion and @@ -313,7 +313,7 @@ module Stmts { not c.(MatchingCompletion).isMatch() or // Stop if an availability check failed - astLast(ast.getAnElement().getAvailability().getFullyUnresolved(), last, c) and + astLast(ast.getAnElement().getAvailability(), last, c) and c instanceof FalseCompletion or // Stop if we successfully evaluated all the conditionals @@ -322,7 +322,7 @@ module Stmts { or astLast(ast.getLastElement().getPattern().getFullyUnresolved(), last, c) or - astLast(ast.getLastElement().getAvailability().getFullyUnresolved(), last, c) + astLast(ast.getLastElement().getAvailability(), last, c) ) and c instanceof NormalCompletion } @@ -342,14 +342,14 @@ module Stmts { override IfStmt ast; final override predicate propagatesAbnormal(ControlFlowElement child) { - child.asAstNode() = ast.getCondition().getFullyUnresolved() or + child.asAstNode() = ast.getCondition() or child.asAstNode() = ast.getThen() or child.asAstNode() = ast.getElse() } final override predicate last(ControlFlowElement last, Completion c) { // Condition exits with a false completion and there is no `else` branch - astLast(ast.getCondition().getFullyUnresolved(), last, c) and + astLast(ast.getCondition(), last, c) and c instanceof FalseOrNonMatchCompletion and not exists(ast.getElse()) or @@ -360,10 +360,10 @@ module Stmts { final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Pre-order: flow from statement itself to first element of condition pred.asAstNode() = ast and - astFirst(ast.getCondition().getFullyUnresolved(), succ) and + astFirst(ast.getCondition(), succ) and c instanceof SimpleCompletion or - astLast(ast.getCondition().getFullyUnresolved(), pred, c) and + astLast(ast.getCondition(), pred, c) and ( // Flow from last element of condition to first element of then branch c instanceof TrueOrMatchCompletion and @@ -380,7 +380,7 @@ module Stmts { override GuardStmt ast; final override predicate propagatesAbnormal(ControlFlowElement child) { - child.asAstNode() = ast.getCondition().getFullyUnresolved() or + child.asAstNode() = ast.getCondition() or child.asAstNode() = ast.getBody() } @@ -390,18 +390,18 @@ module Stmts { c instanceof NormalCompletion or // Exit when a condition is true - astLast(ast.getCondition().getFullyUnresolved(), last, c) and + astLast(ast.getCondition(), last, c) and c instanceof TrueOrMatchCompletion } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Pre-order: flow from statement itself to first element of condition pred.asAstNode() = ast and - astFirst(ast.getCondition().getFullyUnresolved(), succ) and + astFirst(ast.getCondition(), succ) and c instanceof SimpleCompletion or // Flow to the body when the condition is false - astLast(ast.getCondition().getFullyUnresolved(), pred, c) and + astLast(ast.getCondition(), pred, c) and c instanceof FalseOrNonMatchCompletion and astFirst(ast.getBody(), succ) } @@ -458,9 +458,7 @@ module Stmts { private class WhileTree extends LoopTree { override WhileStmt ast; - final override ControlFlowElement getCondition() { - result.asAstNode() = ast.getCondition().getFullyUnresolved() - } + final override ControlFlowElement getCondition() { result.asAstNode() = ast.getCondition() } final override ControlFlowElement getBody() { result.asAstNode() = ast.getBody() } @@ -674,7 +672,7 @@ module Stmts { final override predicate last(ControlFlowElement last, Completion c) { // Case pattern exits with a non-match - astLast(ast.getLastLabel().getFullyUnresolved(), last, c) and + astLast(ast.getLastLabel(), last, c) and not c.(MatchingCompletion).isMatch() or // Case body exits with any completion @@ -684,18 +682,18 @@ module Stmts { override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Pre-order: Flow from the case statement itself to the first label pred.asAstNode() = ast and - astFirst(ast.getFirstLabel().getFullyUnresolved(), succ) and + astFirst(ast.getFirstLabel(), succ) and c instanceof SimpleCompletion or // Left-to-right evaluation of labels until we find a match exists(int i | - astLast(ast.getLabel(i).getFullyUnresolved(), pred, c) and - astFirst(ast.getLabel(i + 1).getFullyUnresolved(), succ) and + astLast(ast.getLabel(i), pred, c) and + astFirst(ast.getLabel(i + 1), succ) and c.(MatchingCompletion).isNonMatch() ) or // Flow from last element of pattern to first element of body - astLast(ast.getALabel().getFullyUnresolved(), pred, c) and + astLast(ast.getALabel(), pred, c) and astFirst(ast.getBody(), succ) and c.(MatchingCompletion).isMatch() } @@ -1164,7 +1162,7 @@ module Exprs { override CaptureListExpr ast; final override ControlFlowElement getChildElement(int i) { - result.asAstNode() = ast.getBindingDecl(i).getFullyUnresolved() + result.asAstNode() = ast.getBindingDecl(i) or i = ast.getNumberOfBindingDecls() and result.asAstNode() = ast.getClosureBody().getFullyConverted() @@ -1796,9 +1794,7 @@ module AvailabilityInfo { private class AvailabilityInfoTree extends AstStandardPostOrderTree { override AvailabilityInfo ast; - final override ControlFlowElement getChildElement(int i) { - result.asAstNode() = ast.getSpec(i).getFullyUnresolved() - } + final override ControlFlowElement getChildElement(int i) { result.asAstNode() = ast.getSpec(i) } } private class AvailabilitySpecTree extends AstLeafTree { diff --git a/swift/ql/lib/codeql/swift/elements.qll b/swift/ql/lib/codeql/swift/elements.qll index 7c75c11c976..486b2aa6cd0 100644 --- a/swift/ql/lib/codeql/swift/elements.qll +++ b/swift/ql/lib/codeql/swift/elements.qll @@ -10,6 +10,7 @@ import codeql.swift.elements.Diagnostics import codeql.swift.elements.Element import codeql.swift.elements.ErrorElement import codeql.swift.elements.File +import codeql.swift.elements.HideableElement import codeql.swift.elements.KeyPathComponent import codeql.swift.elements.Locatable import codeql.swift.elements.Location diff --git a/swift/ql/lib/codeql/swift/elements/Element.qll b/swift/ql/lib/codeql/swift/elements/Element.qll index 394d1caab3b..b7bdd621eaf 100644 --- a/swift/ql/lib/codeql/swift/elements/Element.qll +++ b/swift/ql/lib/codeql/swift/elements/Element.qll @@ -1,18 +1,7 @@ private import codeql.swift.generated.Element class Element extends Generated::Element { - private predicate resolvesFrom(Element e) { e.getResolveStep() = this } - override string toString() { result = this.getPrimaryQlClasses() } - - Element getFullyUnresolved() { - not this.resolvesFrom(_) and result = this - or - exists(Element e | - this.resolvesFrom(e) and - result = e.getFullyUnresolved() - ) - } } class UnknownElement extends Element { diff --git a/swift/ql/lib/codeql/swift/elements/HideableElement.qll b/swift/ql/lib/codeql/swift/elements/HideableElement.qll new file mode 100644 index 00000000000..fdc392817dd --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/HideableElement.qll @@ -0,0 +1,14 @@ +private import codeql.swift.generated.HideableElement + +class HideableElement extends Generated::HideableElement { + private predicate resolvesFrom(HideableElement e) { e.getResolveStep() = this } + + HideableElement getFullyUnresolved() { + not this.resolvesFrom(_) and result = this + or + exists(HideableElement e | + this.resolvesFrom(e) and + result = e.getFullyUnresolved() + ) + } +} diff --git a/swift/ql/lib/codeql/swift/elements/Locatable.qll b/swift/ql/lib/codeql/swift/elements/Locatable.qll index 80afa75c1de..25877d7f074 100644 --- a/swift/ql/lib/codeql/swift/elements/Locatable.qll +++ b/swift/ql/lib/codeql/swift/elements/Locatable.qll @@ -4,10 +4,10 @@ private import codeql.swift.elements.UnknownLocation class Locatable extends Generated::Locatable { pragma[nomagic] - override Location getImmediateLocation() { - result = Generated::Locatable.super.getImmediateLocation() + override Location getLocation() { + result = Generated::Locatable.super.getLocation() or - not exists(Generated::Locatable.super.getImmediateLocation()) and + not exists(Generated::Locatable.super.getLocation()) and result instanceof UnknownLocation } diff --git a/swift/ql/lib/codeql/swift/elements/UnknownLocation.qll b/swift/ql/lib/codeql/swift/elements/UnknownLocation.qll index b97ef6e4e8f..df8823fe028 100644 --- a/swift/ql/lib/codeql/swift/elements/UnknownLocation.qll +++ b/swift/ql/lib/codeql/swift/elements/UnknownLocation.qll @@ -6,7 +6,7 @@ private import codeql.swift.elements.File * A `Location` that is given to something that is not associated with any position in the source code. */ class UnknownLocation extends Generated::UnknownLocation { - override File getImmediateFile() { result instanceof UnknownFile } + override File getFile() { result instanceof UnknownFile } override int getStartLine() { result = 0 } diff --git a/swift/ql/lib/codeql/swift/elements/UnspecifiedElement.qll b/swift/ql/lib/codeql/swift/elements/UnspecifiedElement.qll index cbafea24532..b062beeb197 100644 --- a/swift/ql/lib/codeql/swift/elements/UnspecifiedElement.qll +++ b/swift/ql/lib/codeql/swift/elements/UnspecifiedElement.qll @@ -19,5 +19,5 @@ class UnspecifiedElement extends Generated::UnspecifiedElement { ) } - override Location getImmediateLocation() { result = this.getParent().(Locatable).getLocation() } + override Location getLocation() { result = this.getParent().(Locatable).getLocation() } } diff --git a/swift/ql/lib/codeql/swift/elements/expr/MethodLookupExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/MethodLookupExpr.qll index 4dbdff505b4..ba036ddafcf 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/MethodLookupExpr.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/MethodLookupExpr.qll @@ -14,7 +14,7 @@ class MethodLookupExpr extends Generated::MethodLookupExpr { result = Synth::convertExprFromRaw(this.getUnderlying().getBase()) } - override Decl getImmediateMember() { + override Decl getMember() { result = this.getMethodRef().(DeclRefExpr).getDecl() or result = this.getMethodRef().(OtherInitializerRefExpr).getInitializer() diff --git a/swift/ql/lib/codeql/swift/generated/AvailabilityInfo.qll b/swift/ql/lib/codeql/swift/generated/AvailabilityInfo.qll index c0c7ec1ad00..3659bf7f16f 100644 --- a/swift/ql/lib/codeql/swift/generated/AvailabilityInfo.qll +++ b/swift/ql/lib/codeql/swift/generated/AvailabilityInfo.qll @@ -32,27 +32,14 @@ module Generated { /** * Gets the `index`th spec of this availability info (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - AvailabilitySpec getImmediateSpec(int index) { + AvailabilitySpec getSpec(int index) { result = Synth::convertAvailabilitySpecFromRaw(Synth::convertAvailabilityInfoToRaw(this) .(Raw::AvailabilityInfo) .getSpec(index)) } - /** - * Gets the `index`th spec of this availability info (0-based). - */ - final AvailabilitySpec getSpec(int index) { - exists(AvailabilitySpec immediate | - immediate = this.getImmediateSpec(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the specs of this availability info. */ diff --git a/swift/ql/lib/codeql/swift/generated/Callable.qll b/swift/ql/lib/codeql/swift/generated/Callable.qll index db03af1dbd0..124828a8e0d 100644 --- a/swift/ql/lib/codeql/swift/generated/Callable.qll +++ b/swift/ql/lib/codeql/swift/generated/Callable.qll @@ -20,27 +20,14 @@ module Generated { /** * Gets the self parameter of this callable, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ParamDecl getImmediateSelfParam() { + ParamDecl getSelfParam() { result = Synth::convertParamDeclFromRaw(Synth::convertCallableToRaw(this) .(Raw::Callable) .getSelfParam()) } - /** - * Gets the self parameter of this callable, if it exists. - */ - final ParamDecl getSelfParam() { - exists(ParamDecl immediate | - immediate = this.getImmediateSelfParam() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getSelfParam()` exists. */ @@ -48,27 +35,14 @@ module Generated { /** * Gets the `index`th parameter of this callable (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ParamDecl getImmediateParam(int index) { + ParamDecl getParam(int index) { result = Synth::convertParamDeclFromRaw(Synth::convertCallableToRaw(this) .(Raw::Callable) .getParam(index)) } - /** - * Gets the `index`th parameter of this callable (0-based). - */ - final ParamDecl getParam(int index) { - exists(ParamDecl immediate | - immediate = this.getImmediateParam(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the parameters of this callable. */ @@ -79,27 +53,14 @@ module Generated { */ final int getNumberOfParams() { result = count(int i | exists(this.getParam(i))) } - /** - * Gets the body of this callable, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. - */ - BraceStmt getImmediateBody() { - result = - Synth::convertBraceStmtFromRaw(Synth::convertCallableToRaw(this).(Raw::Callable).getBody()) - } - /** * Gets the body of this callable, if it exists. * * The body is absent within protocol declarations. */ - final BraceStmt getBody() { - exists(BraceStmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) + BraceStmt getBody() { + result = + Synth::convertBraceStmtFromRaw(Synth::convertCallableToRaw(this).(Raw::Callable).getBody()) } /** @@ -109,27 +70,14 @@ module Generated { /** * Gets the `index`th capture of this callable (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - CapturedDecl getImmediateCapture(int index) { + CapturedDecl getCapture(int index) { result = Synth::convertCapturedDeclFromRaw(Synth::convertCallableToRaw(this) .(Raw::Callable) .getCapture(index)) } - /** - * Gets the `index`th capture of this callable (0-based). - */ - final CapturedDecl getCapture(int index) { - exists(CapturedDecl immediate | - immediate = this.getImmediateCapture(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the captures of this callable. */ diff --git a/swift/ql/lib/codeql/swift/generated/Element.qll b/swift/ql/lib/codeql/swift/generated/Element.qll index 0fa588e0667..88e9b4cdd34 100644 --- a/swift/ql/lib/codeql/swift/generated/Element.qll +++ b/swift/ql/lib/codeql/swift/generated/Element.qll @@ -24,23 +24,6 @@ module Generated { */ final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") } - /** - * Gets the most immediate element that should substitute this element in the explicit AST, if any. - * Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved - * for conversions and syntactic sugar nodes like parentheses. - */ - Element getResolveStep() { none() } // overridden by subclasses - - /** - * Gets the element that should substitute this element in the explicit AST, applying `getResolveStep` - * transitively. - */ - final Element resolve() { - not exists(this.getResolveStep()) and result = this - or - result = this.getResolveStep().resolve() - } - /** * Holds if this element is unknown. */ diff --git a/swift/ql/lib/codeql/swift/generated/HideableElement.qll b/swift/ql/lib/codeql/swift/generated/HideableElement.qll new file mode 100644 index 00000000000..9d8b323313c --- /dev/null +++ b/swift/ql/lib/codeql/swift/generated/HideableElement.qll @@ -0,0 +1,25 @@ +// generated by codegen/codegen.py +private import codeql.swift.generated.Synth +private import codeql.swift.generated.Raw +import codeql.swift.elements.Element + +module Generated { + class HideableElement extends Synth::THideableElement, Element { + /** + * Gets the most immediate element that should substitute this element in the explicit AST, if any. + * Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved + * for conversions and syntactic sugar nodes like parentheses. + */ + HideableElement getResolveStep() { none() } // overridden by subclasses + + /** + * Gets the element that should substitute this element in the explicit AST, applying `getResolveStep` + * transitively. + */ + final HideableElement resolve() { + not exists(this.getResolveStep()) and result = this + or + result = this.getResolveStep().resolve() + } + } +} diff --git a/swift/ql/lib/codeql/swift/generated/KeyPathComponent.qll b/swift/ql/lib/codeql/swift/generated/KeyPathComponent.qll index a6b48cc2e0c..564e0397357 100644 --- a/swift/ql/lib/codeql/swift/generated/KeyPathComponent.qll +++ b/swift/ql/lib/codeql/swift/generated/KeyPathComponent.qll @@ -32,27 +32,14 @@ module Generated { /** * Gets the `index`th argument to an array or dictionary subscript expression (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Argument getImmediateSubscriptArgument(int index) { + Argument getSubscriptArgument(int index) { result = Synth::convertArgumentFromRaw(Synth::convertKeyPathComponentToRaw(this) .(Raw::KeyPathComponent) .getSubscriptArgument(index)) } - /** - * Gets the `index`th argument to an array or dictionary subscript expression (0-based). - */ - final Argument getSubscriptArgument(int index) { - exists(Argument immediate | - immediate = this.getImmediateSubscriptArgument(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the arguments to an array or dictionary subscript expression. */ @@ -79,27 +66,14 @@ module Generated { /** * Gets the property or subscript operator, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ValueDecl getImmediateDeclRef() { + ValueDecl getDeclRef() { result = Synth::convertValueDeclFromRaw(Synth::convertKeyPathComponentToRaw(this) .(Raw::KeyPathComponent) .getDeclRef()) } - /** - * Gets the property or subscript operator, if it exists. - */ - final ValueDecl getDeclRef() { - exists(ValueDecl immediate | - immediate = this.getImmediateDeclRef() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getDeclRef()` exists. */ @@ -128,7 +102,7 @@ module Generated { final Type getComponentType() { exists(Type immediate | immediate = this.getImmediateComponentType() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/generated/Locatable.qll b/swift/ql/lib/codeql/swift/generated/Locatable.qll index bb8b832a6af..9696d5d23ad 100644 --- a/swift/ql/lib/codeql/swift/generated/Locatable.qll +++ b/swift/ql/lib/codeql/swift/generated/Locatable.qll @@ -8,27 +8,14 @@ module Generated { class Locatable extends Synth::TLocatable, Element { /** * Gets the location associated with this element in the code, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Location getImmediateLocation() { + Location getLocation() { result = Synth::convertLocationFromRaw(Synth::convertLocatableToRaw(this) .(Raw::Locatable) .getLocation()) } - /** - * Gets the location associated with this element in the code, if it exists. - */ - final Location getLocation() { - exists(Location immediate | - immediate = this.getImmediateLocation() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getLocation()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/Location.qll b/swift/ql/lib/codeql/swift/generated/Location.qll index 9cdbd95fe8d..a95b34a9afa 100644 --- a/swift/ql/lib/codeql/swift/generated/Location.qll +++ b/swift/ql/lib/codeql/swift/generated/Location.qll @@ -8,25 +8,12 @@ module Generated { class Location extends Synth::TLocation, Element { /** * Gets the file of this location. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - File getImmediateFile() { + File getFile() { result = Synth::convertFileFromRaw(Synth::convertLocationToRaw(this).(Raw::Location).getFile()) } - /** - * Gets the file of this location. - */ - final File getFile() { - exists(File immediate | - immediate = this.getImmediateFile() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the start line of this location. */ diff --git a/swift/ql/lib/codeql/swift/generated/ParentChild.qll b/swift/ql/lib/codeql/swift/generated/ParentChild.qll index 958f4ec60a3..61b61ab0459 100644 --- a/swift/ql/lib/codeql/swift/generated/ParentChild.qll +++ b/swift/ql/lib/codeql/swift/generated/ParentChild.qll @@ -16,22 +16,22 @@ private module Impl { bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and n = bElement and nSelfParam = n + 1 and - nParam = nSelfParam + 1 + max(int i | i = -1 or exists(e.getImmediateParam(i)) | i) and + nParam = nSelfParam + 1 + max(int i | i = -1 or exists(e.getParam(i)) | i) and nBody = nParam + 1 and - nCapture = nBody + 1 + max(int i | i = -1 or exists(e.getImmediateCapture(i)) | i) and + nCapture = nBody + 1 + max(int i | i = -1 or exists(e.getCapture(i)) | i) and ( none() or result = getImmediateChildOfElement(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateSelfParam() and partialPredicateCall = "SelfParam()" + index = n and result = e.getSelfParam() and partialPredicateCall = "SelfParam()" or - result = e.getImmediateParam(index - nSelfParam) and + result = e.getParam(index - nSelfParam) and partialPredicateCall = "Param(" + (index - nSelfParam).toString() + ")" or - index = nParam and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = nParam and result = e.getBody() and partialPredicateCall = "Body()" or - result = e.getImmediateCapture(index - nBody) and + result = e.getCapture(index - nBody) and partialPredicateCall = "Capture(" + (index - nBody).toString() + ")" ) ) @@ -50,6 +50,21 @@ private module Impl { ) } + private Element getImmediateChildOfHideableElement( + HideableElement e, int index, string partialPredicateCall + ) { + exists(int b, int bElement, int n | + b = 0 and + bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and + n = bElement and + ( + none() + or + result = getImmediateChildOfElement(e, index - b, partialPredicateCall) + ) + ) + } + private Element getImmediateChildOfLocatable(Locatable e, int index, string partialPredicateCall) { exists(int b, int bElement, int n | b = 0 and @@ -195,13 +210,13 @@ private module Impl { b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and n = bAstNode and - nSpec = n + 1 + max(int i | i = -1 or exists(e.getImmediateSpec(i)) | i) and + nSpec = n + 1 + max(int i | i = -1 or exists(e.getSpec(i)) | i) and ( none() or result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) or - result = e.getImmediateSpec(index - n) and + result = e.getSpec(index - n) and partialPredicateCall = "Spec(" + (index - n).toString() + ")" ) ) @@ -229,14 +244,13 @@ private module Impl { b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and n = bAstNode and - nSubscriptArgument = - n + 1 + max(int i | i = -1 or exists(e.getImmediateSubscriptArgument(i)) | i) and + nSubscriptArgument = n + 1 + max(int i | i = -1 or exists(e.getSubscriptArgument(i)) | i) and ( none() or result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) or - result = e.getImmediateSubscriptArgument(index - n) and + result = e.getSubscriptArgument(index - n) and partialPredicateCall = "SubscriptArgument(" + (index - n).toString() + ")" ) ) @@ -295,13 +309,13 @@ private module Impl { b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and n = bAstNode and - nMember = n + 1 + max(int i | i = -1 or exists(e.getImmediateMember(i)) | i) and + nMember = n + 1 + max(int i | i = -1 or exists(e.getMember(i)) | i) and ( none() or result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) or - result = e.getImmediateMember(index - n) and + result = e.getMember(index - n) and partialPredicateCall = "Member(" + (index - n).toString() + ")" ) ) @@ -314,14 +328,13 @@ private module Impl { b = 0 and bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and n = bElement and - nGenericTypeParam = - n + 1 + max(int i | i = -1 or exists(e.getImmediateGenericTypeParam(i)) | i) and + nGenericTypeParam = n + 1 + max(int i | i = -1 or exists(e.getGenericTypeParam(i)) | i) and ( none() or result = getImmediateChildOfElement(e, index - b, partialPredicateCall) or - result = e.getImmediateGenericTypeParam(index - n) and + result = e.getGenericTypeParam(index - n) and partialPredicateCall = "GenericTypeParam(" + (index - n).toString() + ")" ) ) @@ -504,7 +517,7 @@ private module Impl { or result = getImmediateChildOfDecl(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = n and result = e.getBody() and partialPredicateCall = "Body()" ) ) } @@ -529,13 +542,13 @@ private module Impl { b = 0 and bValueDecl = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfValueDecl(e, i, _)) | i) and n = bValueDecl and - nAccessor = n + 1 + max(int i | i = -1 or exists(e.getImmediateAccessor(i)) | i) and + nAccessor = n + 1 + max(int i | i = -1 or exists(e.getAccessor(i)) | i) and ( none() or result = getImmediateChildOfValueDecl(e, index - b, partialPredicateCall) or - result = e.getImmediateAccessor(index - n) and + result = e.getAccessor(index - n) and partialPredicateCall = "Accessor(" + (index - n).toString() + ")" ) ) @@ -548,13 +561,13 @@ private module Impl { b = 0 and bValueDecl = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfValueDecl(e, i, _)) | i) and n = bValueDecl and - nParam = n + 1 + max(int i | i = -1 or exists(e.getImmediateParam(i)) | i) and + nParam = n + 1 + max(int i | i = -1 or exists(e.getParam(i)) | i) and ( none() or result = getImmediateChildOfValueDecl(e, index - b, partialPredicateCall) or - result = e.getImmediateParam(index - n) and + result = e.getParam(index - n) and partialPredicateCall = "Param(" + (index - n).toString() + ")" ) ) @@ -749,7 +762,7 @@ private module Impl { bAbstractStorageDecl + 1 + max(int i | i = -1 or exists(getImmediateChildOfGenericContext(e, i, _)) | i) and n = bGenericContext and - nParam = n + 1 + max(int i | i = -1 or exists(e.getImmediateParam(i)) | i) and + nParam = n + 1 + max(int i | i = -1 or exists(e.getParam(i)) | i) and ( none() or @@ -758,7 +771,7 @@ private module Impl { result = getImmediateChildOfGenericContext(e, index - bAbstractStorageDecl, partialPredicateCall) or - result = e.getImmediateParam(index - n) and + result = e.getParam(index - n) and partialPredicateCall = "Param(" + (index - n).toString() + ")" ) ) @@ -784,19 +797,19 @@ private module Impl { result = getImmediateChildOfAbstractStorageDecl(e, index - b, partialPredicateCall) or index = n and - result = e.getImmediatePropertyWrapperBackingVarBinding() and + result = e.getPropertyWrapperBackingVarBinding() and partialPredicateCall = "PropertyWrapperBackingVarBinding()" or index = nPropertyWrapperBackingVarBinding and - result = e.getImmediatePropertyWrapperBackingVar() and + result = e.getPropertyWrapperBackingVar() and partialPredicateCall = "PropertyWrapperBackingVar()" or index = nPropertyWrapperBackingVar and - result = e.getImmediatePropertyWrapperProjectionVarBinding() and + result = e.getPropertyWrapperProjectionVarBinding() and partialPredicateCall = "PropertyWrapperProjectionVarBinding()" or index = nPropertyWrapperProjectionVarBinding and - result = e.getImmediatePropertyWrapperProjectionVar() and + result = e.getPropertyWrapperProjectionVar() and partialPredicateCall = "PropertyWrapperProjectionVar()" ) ) @@ -929,11 +942,11 @@ private module Impl { result = getImmediateChildOfVarDecl(e, index - b, partialPredicateCall) or index = n and - result = e.getImmediatePropertyWrapperLocalWrappedVarBinding() and + result = e.getPropertyWrapperLocalWrappedVarBinding() and partialPredicateCall = "PropertyWrapperLocalWrappedVarBinding()" or index = nPropertyWrapperLocalWrappedVarBinding and - result = e.getImmediatePropertyWrapperLocalWrappedVar() and + result = e.getPropertyWrapperLocalWrappedVar() and partialPredicateCall = "PropertyWrapperLocalWrappedVar()" ) ) @@ -1030,14 +1043,19 @@ private module Impl { } private Element getImmediateChildOfExpr(Expr e, int index, string partialPredicateCall) { - exists(int b, int bAstNode, int n | + exists(int b, int bAstNode, int bHideableElement, int n | b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and - n = bAstNode and + bHideableElement = + bAstNode + 1 + + max(int i | i = -1 or exists(getImmediateChildOfHideableElement(e, i, _)) | i) and + n = bHideableElement and ( none() or result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) + or + result = getImmediateChildOfHideableElement(e, index - bAstNode, partialPredicateCall) ) ) } @@ -1082,7 +1100,7 @@ private module Impl { bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and n = bExpr and nFunction = n + 1 and - nArgument = nFunction + 1 + max(int i | i = -1 or exists(e.getImmediateArgument(i)) | i) and + nArgument = nFunction + 1 + max(int i | i = -1 or exists(e.getArgument(i)) | i) and ( none() or @@ -1090,7 +1108,7 @@ private module Impl { or index = n and result = e.getImmediateFunction() and partialPredicateCall = "Function()" or - result = e.getImmediateArgument(index - nFunction) and + result = e.getArgument(index - nFunction) and partialPredicateCall = "Argument(" + (index - nFunction).toString() + ")" ) ) @@ -1140,14 +1158,14 @@ private module Impl { b = 0 and bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and n = bExpr and - nBindingDecl = n + 1 + max(int i | i = -1 or exists(e.getImmediateBindingDecl(i)) | i) and + nBindingDecl = n + 1 + max(int i | i = -1 or exists(e.getBindingDecl(i)) | i) and nClosureBody = nBindingDecl + 1 and ( none() or result = getImmediateChildOfExpr(e, index - b, partialPredicateCall) or - result = e.getImmediateBindingDecl(index - n) and + result = e.getBindingDecl(index - n) and partialPredicateCall = "BindingDecl(" + (index - n).toString() + ")" or index = nBindingDecl and @@ -1470,15 +1488,15 @@ private module Impl { bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and n = bExpr and nRoot = n + 1 and - nComponent = nRoot + 1 + max(int i | i = -1 or exists(e.getImmediateComponent(i)) | i) and + nComponent = nRoot + 1 + max(int i | i = -1 or exists(e.getComponent(i)) | i) and ( none() or result = getImmediateChildOfExpr(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateRoot() and partialPredicateCall = "Root()" + index = n and result = e.getRoot() and partialPredicateCall = "Root()" or - result = e.getImmediateComponent(index - nRoot) and + result = e.getComponent(index - nRoot) and partialPredicateCall = "Component(" + (index - nRoot).toString() + ")" ) ) @@ -1773,7 +1791,7 @@ private module Impl { or index = n and result = e.getImmediateSubExpr() and partialPredicateCall = "SubExpr()" or - index = nSubExpr and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = nSubExpr and result = e.getBody() and partialPredicateCall = "Body()" ) ) } @@ -1824,7 +1842,7 @@ private module Impl { or result = getImmediateChildOfExpr(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateTypeRepr() and partialPredicateCall = "TypeRepr()" + index = n and result = e.getTypeRepr() and partialPredicateCall = "TypeRepr()" ) ) } @@ -2688,13 +2706,13 @@ private module Impl { bLiteralExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLiteralExpr(e, i, _)) | i) and n = bLiteralExpr and - nArgument = n + 1 + max(int i | i = -1 or exists(e.getImmediateArgument(i)) | i) and + nArgument = n + 1 + max(int i | i = -1 or exists(e.getArgument(i)) | i) and ( none() or result = getImmediateChildOfLiteralExpr(e, index - b, partialPredicateCall) or - result = e.getImmediateArgument(index - n) and + result = e.getArgument(index - n) and partialPredicateCall = "Argument(" + (index - n).toString() + ")" ) ) @@ -2850,13 +2868,13 @@ private module Impl { bLookupExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLookupExpr(e, i, _)) | i) and n = bLookupExpr and - nArgument = n + 1 + max(int i | i = -1 or exists(e.getImmediateArgument(i)) | i) and + nArgument = n + 1 + max(int i | i = -1 or exists(e.getArgument(i)) | i) and ( none() or result = getImmediateChildOfLookupExpr(e, index - b, partialPredicateCall) or - result = e.getImmediateArgument(index - n) and + result = e.getArgument(index - n) and partialPredicateCall = "Argument(" + (index - n).toString() + ")" ) ) @@ -3161,14 +3179,19 @@ private module Impl { } private Element getImmediateChildOfPattern(Pattern e, int index, string partialPredicateCall) { - exists(int b, int bAstNode, int n | + exists(int b, int bAstNode, int bHideableElement, int n | b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and - n = bAstNode and + bHideableElement = + bAstNode + 1 + + max(int i | i = -1 or exists(getImmediateChildOfHideableElement(e, i, _)) | i) and + n = bHideableElement and ( none() or result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) + or + result = getImmediateChildOfHideableElement(e, index - bAstNode, partialPredicateCall) ) ) } @@ -3267,9 +3290,7 @@ private module Impl { or result = getImmediateChildOfPattern(e, index - b, partialPredicateCall) or - index = n and - result = e.getImmediateCastTypeRepr() and - partialPredicateCall = "CastTypeRepr()" + index = n and result = e.getCastTypeRepr() and partialPredicateCall = "CastTypeRepr()" or index = nCastTypeRepr and result = e.getImmediateSubPattern() and @@ -3364,9 +3385,7 @@ private module Impl { or index = n and result = e.getImmediateSubPattern() and partialPredicateCall = "SubPattern()" or - index = nSubPattern and - result = e.getImmediateTypeRepr() and - partialPredicateCall = "TypeRepr()" + index = nSubPattern and result = e.getTypeRepr() and partialPredicateCall = "TypeRepr()" ) ) } @@ -3419,7 +3438,7 @@ private module Impl { partialPredicateCall = "Initializer()" or index = nInitializer and - result = e.getImmediateAvailability() and + result = e.getAvailability() and partialPredicateCall = "Availability()" ) ) @@ -3445,13 +3464,13 @@ private module Impl { b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and n = bAstNode and - nElement = n + 1 + max(int i | i = -1 or exists(e.getImmediateElement(i)) | i) and + nElement = n + 1 + max(int i | i = -1 or exists(e.getElement(i)) | i) and ( none() or result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) or - result = e.getImmediateElement(index - n) and + result = e.getElement(index - n) and partialPredicateCall = "Element(" + (index - n).toString() + ")" ) ) @@ -3462,13 +3481,13 @@ private module Impl { b = 0 and bStmt = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfStmt(e, i, _)) | i) and n = bStmt and - nElement = n + 1 + max(int i | i = -1 or exists(e.getImmediateElement(i)) | i) and + nElement = n + 1 + max(int i | i = -1 or exists(e.getElement(i)) | i) and ( none() or result = getImmediateChildOfStmt(e, index - b, partialPredicateCall) or - result = e.getImmediateElement(index - n) and + result = e.getElement(index - n) and partialPredicateCall = "Element(" + (index - n).toString() + ")" ) ) @@ -3493,15 +3512,15 @@ private module Impl { bStmt = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfStmt(e, i, _)) | i) and n = bStmt and nBody = n + 1 and - nLabel = nBody + 1 + max(int i | i = -1 or exists(e.getImmediateLabel(i)) | i) and + nLabel = nBody + 1 + max(int i | i = -1 or exists(e.getLabel(i)) | i) and ( none() or result = getImmediateChildOfStmt(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = n and result = e.getBody() and partialPredicateCall = "Body()" or - result = e.getImmediateLabel(index - nBody) and + result = e.getLabel(index - nBody) and partialPredicateCall = "Label(" + (index - nBody).toString() + ")" ) ) @@ -3533,7 +3552,7 @@ private module Impl { or result = getImmediateChildOfStmt(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = n and result = e.getBody() and partialPredicateCall = "Body()" ) ) } @@ -3654,15 +3673,15 @@ private module Impl { b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLabeledStmt(e, i, _)) | i) and n = bLabeledStmt and nBody = n + 1 and - nCatch = nBody + 1 + max(int i | i = -1 or exists(e.getImmediateCatch(i)) | i) and + nCatch = nBody + 1 + max(int i | i = -1 or exists(e.getCatch(i)) | i) and ( none() or result = getImmediateChildOfLabeledStmt(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = n and result = e.getBody() and partialPredicateCall = "Body()" or - result = e.getImmediateCatch(index - nBody) and + result = e.getCatch(index - nBody) and partialPredicateCall = "Catch(" + (index - nBody).toString() + ")" ) ) @@ -3680,7 +3699,7 @@ private module Impl { or result = getImmediateChildOfLabeledStmt(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = n and result = e.getBody() and partialPredicateCall = "Body()" ) ) } @@ -3710,7 +3729,7 @@ private module Impl { or index = nSequence and result = e.getImmediateWhere() and partialPredicateCall = "Where()" or - index = nWhere and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = nWhere and result = e.getBody() and partialPredicateCall = "Body()" ) ) } @@ -3729,7 +3748,7 @@ private module Impl { or result = getImmediateChildOfLabeledStmt(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateCondition() and partialPredicateCall = "Condition()" + index = n and result = e.getCondition() and partialPredicateCall = "Condition()" ) ) } @@ -3751,7 +3770,7 @@ private module Impl { or index = n and result = e.getImmediateCondition() and partialPredicateCall = "Condition()" or - index = nCondition and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = nCondition and result = e.getBody() and partialPredicateCall = "Body()" ) ) } @@ -3763,7 +3782,7 @@ private module Impl { b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLabeledStmt(e, i, _)) | i) and n = bLabeledStmt and nExpr = n + 1 and - nCase = nExpr + 1 + max(int i | i = -1 or exists(e.getImmediateCase(i)) | i) and + nCase = nExpr + 1 + max(int i | i = -1 or exists(e.getCase(i)) | i) and ( none() or @@ -3771,7 +3790,7 @@ private module Impl { or index = n and result = e.getImmediateExpr() and partialPredicateCall = "Expr()" or - result = e.getImmediateCase(index - nExpr) and + result = e.getCase(index - nExpr) and partialPredicateCall = "Case(" + (index - nExpr).toString() + ")" ) ) @@ -3790,7 +3809,7 @@ private module Impl { or result = getImmediateChildOfLabeledConditionalStmt(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = n and result = e.getBody() and partialPredicateCall = "Body()" ) ) } @@ -3809,9 +3828,9 @@ private module Impl { or result = getImmediateChildOfLabeledConditionalStmt(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateThen() and partialPredicateCall = "Then()" + index = n and result = e.getThen() and partialPredicateCall = "Then()" or - index = nThen and result = e.getImmediateElse() and partialPredicateCall = "Else()" + index = nThen and result = e.getElse() and partialPredicateCall = "Else()" ) ) } @@ -3829,20 +3848,21 @@ private module Impl { or result = getImmediateChildOfLabeledConditionalStmt(e, index - b, partialPredicateCall) or - index = n and result = e.getImmediateBody() and partialPredicateCall = "Body()" + index = n and result = e.getBody() and partialPredicateCall = "Body()" ) ) } private Element getImmediateChildOfType(Type e, int index, string partialPredicateCall) { - exists(int b, int bElement, int n | + exists(int b, int bHideableElement, int n | b = 0 and - bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and - n = bElement and + bHideableElement = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfHideableElement(e, i, _)) | i) and + n = bHideableElement and ( none() or - result = getImmediateChildOfElement(e, index - b, partialPredicateCall) + result = getImmediateChildOfHideableElement(e, index - b, partialPredicateCall) ) ) } @@ -5301,7 +5321,7 @@ private module Impl { } Element resolve(Element e) { - if e instanceof Element then result = e.(Element).resolve() else result = e + if e instanceof HideableElement then result = e.(HideableElement).resolve() else result = e } } diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index dc5ddeed979..f7c127818d7 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -62,6 +62,11 @@ module Raw { predicate isSuccessfullyExtracted() { file_is_successfully_extracted(this) } } + /** + * INTERNAL: Do not use. + */ + class HideableElement extends @hideable_element, Element { } + /** * INTERNAL: Do not use. */ @@ -986,7 +991,7 @@ module Raw { * INTERNAL: Do not use. * The base class for all expressions in Swift. */ - class Expr extends @expr, AstNode { + class Expr extends @expr, AstNode, HideableElement { /** * Gets the type of this expression, if it exists. */ @@ -2353,7 +2358,7 @@ module Raw { /** * INTERNAL: Do not use. */ - class Pattern extends @pattern, AstNode { } + class Pattern extends @pattern, AstNode, HideableElement { } /** * INTERNAL: Do not use. @@ -2869,7 +2874,7 @@ module Raw { /** * INTERNAL: Do not use. */ - class Type extends @type, Element { + class Type extends @type, HideableElement { /** * Gets the name of this type. */ diff --git a/swift/ql/lib/codeql/swift/generated/Synth.qll b/swift/ql/lib/codeql/swift/generated/Synth.qll index fdbadffcd33..f79d71f84a3 100644 --- a/swift/ql/lib/codeql/swift/generated/Synth.qll +++ b/swift/ql/lib/codeql/swift/generated/Synth.qll @@ -1043,6 +1043,11 @@ module Synth { */ class TFile = TDbFile or TUnknownFile; + /** + * INTERNAL: Do not use. + */ + class THideableElement = TExpr or TPattern or TType; + /** * INTERNAL: Do not use. */ @@ -3223,11 +3228,11 @@ module Synth { or result = convertGenericContextFromRaw(e) or + result = convertHideableElementFromRaw(e) + or result = convertLocatableFromRaw(e) or result = convertLocationFromRaw(e) - or - result = convertTypeFromRaw(e) } /** @@ -3272,6 +3277,19 @@ module Synth { result = convertUnknownFileFromRaw(e) } + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `THideableElement`, if possible. + */ + cached + THideableElement convertHideableElementFromRaw(Raw::Element e) { + result = convertExprFromRaw(e) + or + result = convertPatternFromRaw(e) + or + result = convertTypeFromRaw(e) + } + /** * INTERNAL: Do not use. * Converts a raw DB element to a synthesized `TLocatable`, if possible. @@ -6028,11 +6046,11 @@ module Synth { or result = convertGenericContextToRaw(e) or + result = convertHideableElementToRaw(e) + or result = convertLocatableToRaw(e) or result = convertLocationToRaw(e) - or - result = convertTypeToRaw(e) } /** @@ -6077,6 +6095,19 @@ module Synth { result = convertUnknownFileToRaw(e) } + /** + * INTERNAL: Do not use. + * Converts a synthesized `THideableElement` to a raw DB element, if possible. + */ + cached + Raw::Element convertHideableElementToRaw(THideableElement e) { + result = convertExprToRaw(e) + or + result = convertPatternToRaw(e) + or + result = convertTypeToRaw(e) + } + /** * INTERNAL: Do not use. * Converts a synthesized `TLocatable` to a raw DB element, if possible. diff --git a/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll b/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll index f2f78d9cafc..af422cbd10d 100644 --- a/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll +++ b/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the parent of this unspecified element, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Element getImmediateParent() { + Element getParent() { result = Synth::convertElementFromRaw(Synth::convertUnspecifiedElementToRaw(this) .(Raw::UnspecifiedElement) .getParent()) } - /** - * Gets the parent of this unspecified element, if it exists. - */ - final Element getParent() { - exists(Element immediate | - immediate = this.getImmediateParent() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getParent()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/AbstractStorageDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/AbstractStorageDecl.qll index 0ecb0836313..b60203d43b4 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/AbstractStorageDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/AbstractStorageDecl.qll @@ -8,27 +8,14 @@ module Generated { class AbstractStorageDecl extends Synth::TAbstractStorageDecl, ValueDecl { /** * Gets the `index`th accessor of this abstract storage declaration (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Accessor getImmediateAccessor(int index) { + Accessor getAccessor(int index) { result = Synth::convertAccessorFromRaw(Synth::convertAbstractStorageDeclToRaw(this) .(Raw::AbstractStorageDecl) .getAccessor(index)) } - /** - * Gets the `index`th accessor of this abstract storage declaration (0-based). - */ - final Accessor getAccessor(int index) { - exists(Accessor immediate | - immediate = this.getImmediateAccessor(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the accessors of this abstract storage declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/CapturedDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/CapturedDecl.qll index 9749202fec3..d2c54edfde9 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/CapturedDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/CapturedDecl.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the the declaration captured by the parent closure. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ValueDecl getImmediateDecl() { + ValueDecl getDecl() { result = Synth::convertValueDeclFromRaw(Synth::convertCapturedDeclToRaw(this) .(Raw::CapturedDecl) .getDecl()) } - /** - * Gets the the declaration captured by the parent closure. - */ - final ValueDecl getDecl() { - exists(ValueDecl immediate | - immediate = this.getImmediateDecl() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if this captured declaration is direct. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/Decl.qll b/swift/ql/lib/codeql/swift/generated/decl/Decl.qll index 33cb4ec46ca..568f9297c99 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/Decl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/Decl.qll @@ -8,45 +8,19 @@ module Generated { class Decl extends Synth::TDecl, AstNode { /** * Gets the module of this declaration. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ModuleDecl getImmediateModule() { + ModuleDecl getModule() { result = Synth::convertModuleDeclFromRaw(Synth::convertDeclToRaw(this).(Raw::Decl).getModule()) } - /** - * Gets the module of this declaration. - */ - final ModuleDecl getModule() { - exists(ModuleDecl immediate | - immediate = this.getImmediateModule() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the `index`th member of this declaration (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Decl getImmediateMember(int index) { + Decl getMember(int index) { result = Synth::convertDeclFromRaw(Synth::convertDeclToRaw(this).(Raw::Decl).getMember(index)) } - /** - * Gets the `index`th member of this declaration (0-based). - */ - final Decl getMember(int index) { - exists(Decl immediate | - immediate = this.getImmediateMember(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the members of this declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/EnumCaseDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/EnumCaseDecl.qll index 59834181269..68966a3a7d3 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/EnumCaseDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/EnumCaseDecl.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the `index`th element of this enum case declaration (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - EnumElementDecl getImmediateElement(int index) { + EnumElementDecl getElement(int index) { result = Synth::convertEnumElementDeclFromRaw(Synth::convertEnumCaseDeclToRaw(this) .(Raw::EnumCaseDecl) .getElement(index)) } - /** - * Gets the `index`th element of this enum case declaration (0-based). - */ - final EnumElementDecl getElement(int index) { - exists(EnumElementDecl immediate | - immediate = this.getImmediateElement(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the elements of this enum case declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/EnumElementDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/EnumElementDecl.qll index 148124d0f8f..e8c68320053 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/EnumElementDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/EnumElementDecl.qll @@ -17,27 +17,14 @@ module Generated { /** * Gets the `index`th parameter of this enum element declaration (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ParamDecl getImmediateParam(int index) { + ParamDecl getParam(int index) { result = Synth::convertParamDeclFromRaw(Synth::convertEnumElementDeclToRaw(this) .(Raw::EnumElementDecl) .getParam(index)) } - /** - * Gets the `index`th parameter of this enum element declaration (0-based). - */ - final ParamDecl getParam(int index) { - exists(ParamDecl immediate | - immediate = this.getImmediateParam(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the parameters of this enum element declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/ExtensionDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ExtensionDecl.qll index 2863c3aca52..5fa3dd2bc3a 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ExtensionDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ExtensionDecl.qll @@ -12,50 +12,24 @@ module Generated { /** * Gets the extended type declaration of this extension declaration. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - NominalTypeDecl getImmediateExtendedTypeDecl() { + NominalTypeDecl getExtendedTypeDecl() { result = Synth::convertNominalTypeDeclFromRaw(Synth::convertExtensionDeclToRaw(this) .(Raw::ExtensionDecl) .getExtendedTypeDecl()) } - /** - * Gets the extended type declaration of this extension declaration. - */ - final NominalTypeDecl getExtendedTypeDecl() { - exists(NominalTypeDecl immediate | - immediate = this.getImmediateExtendedTypeDecl() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the `index`th protocol of this extension declaration (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ProtocolDecl getImmediateProtocol(int index) { + ProtocolDecl getProtocol(int index) { result = Synth::convertProtocolDeclFromRaw(Synth::convertExtensionDeclToRaw(this) .(Raw::ExtensionDecl) .getProtocol(index)) } - /** - * Gets the `index`th protocol of this extension declaration (0-based). - */ - final ProtocolDecl getProtocol(int index) { - exists(ProtocolDecl immediate | - immediate = this.getImmediateProtocol(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the protocols of this extension declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/GenericContext.qll b/swift/ql/lib/codeql/swift/generated/decl/GenericContext.qll index 4855a60fa10..ade061da641 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/GenericContext.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/GenericContext.qll @@ -8,27 +8,14 @@ module Generated { class GenericContext extends Synth::TGenericContext, Element { /** * Gets the `index`th generic type parameter of this generic context (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - GenericTypeParamDecl getImmediateGenericTypeParam(int index) { + GenericTypeParamDecl getGenericTypeParam(int index) { result = Synth::convertGenericTypeParamDeclFromRaw(Synth::convertGenericContextToRaw(this) .(Raw::GenericContext) .getGenericTypeParam(index)) } - /** - * Gets the `index`th generic type parameter of this generic context (0-based). - */ - final GenericTypeParamDecl getGenericTypeParam(int index) { - exists(GenericTypeParamDecl immediate | - immediate = this.getImmediateGenericTypeParam(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the generic type parameters of this generic context. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll index 23c42ea9c6c..9a93bce7540 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the `index`th active element of this if config declaration (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - AstNode getImmediateActiveElement(int index) { + AstNode getActiveElement(int index) { result = Synth::convertAstNodeFromRaw(Synth::convertIfConfigDeclToRaw(this) .(Raw::IfConfigDecl) .getActiveElement(index)) } - /** - * Gets the `index`th active element of this if config declaration (0-based). - */ - final AstNode getActiveElement(int index) { - exists(AstNode immediate | - immediate = this.getImmediateActiveElement(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the active elements of this if config declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll index df928494a73..8686d55c405 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll @@ -16,27 +16,14 @@ module Generated { /** * Gets the imported module of this import declaration, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ModuleDecl getImmediateImportedModule() { + ModuleDecl getImportedModule() { result = Synth::convertModuleDeclFromRaw(Synth::convertImportDeclToRaw(this) .(Raw::ImportDecl) .getImportedModule()) } - /** - * Gets the imported module of this import declaration, if it exists. - */ - final ModuleDecl getImportedModule() { - exists(ModuleDecl immediate | - immediate = this.getImmediateImportedModule() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getImportedModule()` exists. */ @@ -44,27 +31,14 @@ module Generated { /** * Gets the `index`th declaration of this import declaration (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ValueDecl getImmediateDeclaration(int index) { + ValueDecl getDeclaration(int index) { result = Synth::convertValueDeclFromRaw(Synth::convertImportDeclToRaw(this) .(Raw::ImportDecl) .getDeclaration(index)) } - /** - * Gets the `index`th declaration of this import declaration (0-based). - */ - final ValueDecl getDeclaration(int index) { - exists(ValueDecl immediate | - immediate = this.getImmediateDeclaration(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the declarations of this import declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/InfixOperatorDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/InfixOperatorDecl.qll index e9749c13355..30649ed8ec6 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/InfixOperatorDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/InfixOperatorDecl.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the precedence group of this infix operator declaration, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - PrecedenceGroupDecl getImmediatePrecedenceGroup() { + PrecedenceGroupDecl getPrecedenceGroup() { result = Synth::convertPrecedenceGroupDeclFromRaw(Synth::convertInfixOperatorDeclToRaw(this) .(Raw::InfixOperatorDecl) .getPrecedenceGroup()) } - /** - * Gets the precedence group of this infix operator declaration, if it exists. - */ - final PrecedenceGroupDecl getPrecedenceGroup() { - exists(PrecedenceGroupDecl immediate | - immediate = this.getImmediatePrecedenceGroup() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getPrecedenceGroup()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll index 3fc71350932..6654dfd4e49 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll @@ -24,28 +24,14 @@ module Generated { /** * Gets the `index`th imported module of this module declaration (0-based). *Gets any of the imported modules of this module declaration. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ModuleDecl getAnImmediateImportedModule() { + ModuleDecl getAnImportedModule() { result = Synth::convertModuleDeclFromRaw(Synth::convertModuleDeclToRaw(this) .(Raw::ModuleDecl) .getAnImportedModule()) } - /** - * Gets the `index`th imported module of this module declaration (0-based). - *Gets any of the imported modules of this module declaration. - */ - final ModuleDecl getAnImportedModule() { - exists(ModuleDecl immediate | - immediate = this.getAnImmediateImportedModule() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the number of imported modules of this module declaration. */ @@ -54,28 +40,14 @@ module Generated { /** * Gets the `index`th exported module of this module declaration (0-based). *Gets any of the exported modules of this module declaration. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ModuleDecl getAnImmediateExportedModule() { + ModuleDecl getAnExportedModule() { result = Synth::convertModuleDeclFromRaw(Synth::convertModuleDeclToRaw(this) .(Raw::ModuleDecl) .getAnExportedModule()) } - /** - * Gets the `index`th exported module of this module declaration (0-based). - *Gets any of the exported modules of this module declaration. - */ - final ModuleDecl getAnExportedModule() { - exists(ModuleDecl immediate | - immediate = this.getAnImmediateExportedModule() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the number of exported modules of this module declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/NominalTypeDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/NominalTypeDecl.qll index b007e2b1b52..5f9543d3ab7 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/NominalTypeDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/NominalTypeDecl.qll @@ -25,7 +25,7 @@ module Generated { final Type getType() { exists(Type immediate | immediate = this.getImmediateType() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/OpaqueTypeDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/OpaqueTypeDecl.qll index 33eaec9bc2e..e815fe5561a 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/OpaqueTypeDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/OpaqueTypeDecl.qll @@ -22,27 +22,14 @@ module Generated { /** * Gets the naming declaration of this opaque type declaration. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ValueDecl getImmediateNamingDeclaration() { + ValueDecl getNamingDeclaration() { result = Synth::convertValueDeclFromRaw(Synth::convertOpaqueTypeDeclToRaw(this) .(Raw::OpaqueTypeDecl) .getNamingDeclaration()) } - /** - * Gets the naming declaration of this opaque type declaration. - */ - final ValueDecl getNamingDeclaration() { - exists(ValueDecl immediate | - immediate = this.getImmediateNamingDeclaration() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the `index`th opaque generic parameter of this opaque type declaration (0-based). * @@ -62,7 +49,7 @@ module Generated { final GenericTypeParamType getOpaqueGenericParam(int index) { exists(GenericTypeParamType immediate | immediate = this.getImmediateOpaqueGenericParam(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/decl/ParamDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ParamDecl.qll index 99f80d18772..da45ffbeb2e 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ParamDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ParamDecl.qll @@ -16,29 +16,16 @@ module Generated { /** * Gets the property wrapper local wrapped variable binding of this parameter declaration, if it exists. * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. + * This is the synthesized binding introducing the property wrapper local wrapped projection + * variable for this variable, if any. */ - PatternBindingDecl getImmediatePropertyWrapperLocalWrappedVarBinding() { + PatternBindingDecl getPropertyWrapperLocalWrappedVarBinding() { result = Synth::convertPatternBindingDeclFromRaw(Synth::convertParamDeclToRaw(this) .(Raw::ParamDecl) .getPropertyWrapperLocalWrappedVarBinding()) } - /** - * Gets the property wrapper local wrapped variable binding of this parameter declaration, if it exists. - * - * This is the synthesized binding introducing the property wrapper local wrapped projection - * variable for this variable, if any. - */ - final PatternBindingDecl getPropertyWrapperLocalWrappedVarBinding() { - exists(PatternBindingDecl immediate | - immediate = this.getImmediatePropertyWrapperLocalWrappedVarBinding() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getPropertyWrapperLocalWrappedVarBinding()` exists. */ @@ -49,29 +36,16 @@ module Generated { /** * Gets the property wrapper local wrapped variable of this parameter declaration, if it exists. * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. + * This is the synthesized local wrapped value, shadowing this parameter declaration in case it + * has a property wrapper. */ - VarDecl getImmediatePropertyWrapperLocalWrappedVar() { + VarDecl getPropertyWrapperLocalWrappedVar() { result = Synth::convertVarDeclFromRaw(Synth::convertParamDeclToRaw(this) .(Raw::ParamDecl) .getPropertyWrapperLocalWrappedVar()) } - /** - * Gets the property wrapper local wrapped variable of this parameter declaration, if it exists. - * - * This is the synthesized local wrapped value, shadowing this parameter declaration in case it - * has a property wrapper. - */ - final VarDecl getPropertyWrapperLocalWrappedVar() { - exists(VarDecl immediate | - immediate = this.getImmediatePropertyWrapperLocalWrappedVar() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getPropertyWrapperLocalWrappedVar()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/PatternBindingDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/PatternBindingDecl.qll index 00ca18b1185..290803257bd 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/PatternBindingDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/PatternBindingDecl.qll @@ -28,7 +28,7 @@ module Generated { final Expr getInit(int index) { exists(Expr immediate | immediate = this.getImmediateInit(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -61,7 +61,7 @@ module Generated { final Pattern getPattern(int index) { exists(Pattern immediate | immediate = this.getImmediatePattern(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/decl/PoundDiagnosticDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/PoundDiagnosticDecl.qll index fe7cfaf701f..3c5a663ce72 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/PoundDiagnosticDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/PoundDiagnosticDecl.qll @@ -39,7 +39,7 @@ module Generated { final StringLiteralExpr getMessage() { exists(StringLiteralExpr immediate | immediate = this.getImmediateMessage() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/SubscriptDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/SubscriptDecl.qll index a6fe783be42..b6e7f963d6d 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/SubscriptDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/SubscriptDecl.qll @@ -12,27 +12,14 @@ module Generated { /** * Gets the `index`th parameter of this subscript declaration (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ParamDecl getImmediateParam(int index) { + ParamDecl getParam(int index) { result = Synth::convertParamDeclFromRaw(Synth::convertSubscriptDeclToRaw(this) .(Raw::SubscriptDecl) .getParam(index)) } - /** - * Gets the `index`th parameter of this subscript declaration (0-based). - */ - final ParamDecl getParam(int index) { - exists(ParamDecl immediate | - immediate = this.getImmediateParam(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the parameters of this subscript declaration. */ @@ -62,7 +49,7 @@ module Generated { final Type getElementType() { exists(Type immediate | immediate = this.getImmediateElementType() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/TopLevelCodeDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/TopLevelCodeDecl.qll index d53c5ec5e3f..9af4944bd3d 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/TopLevelCodeDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/TopLevelCodeDecl.qll @@ -10,25 +10,12 @@ module Generated { /** * Gets the body of this top level code declaration. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - BraceStmt getImmediateBody() { + BraceStmt getBody() { result = Synth::convertBraceStmtFromRaw(Synth::convertTopLevelCodeDeclToRaw(this) .(Raw::TopLevelCodeDecl) .getBody()) } - - /** - * Gets the body of this top level code declaration. - */ - final BraceStmt getBody() { - exists(BraceStmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll index d0e7fa1164d..e35b6895874 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll @@ -38,7 +38,7 @@ module Generated { final Type getAliasedType() { exists(Type immediate | immediate = this.getImmediateAliasedType() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/TypeDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/TypeDecl.qll index 7a70183bac1..bae701326d2 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/TypeDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/TypeDecl.qll @@ -30,7 +30,7 @@ module Generated { final Type getBaseType(int index) { exists(Type immediate | immediate = this.getImmediateBaseType(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/decl/ValueDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ValueDecl.qll index 237d668eade..026e410b569 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ValueDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ValueDecl.qll @@ -25,7 +25,7 @@ module Generated { final Type getInterfaceType() { exists(Type immediate | immediate = this.getImmediateInterfaceType() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/VarDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/VarDecl.qll index 86f91c9d128..6d72f5bd4ed 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/VarDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/VarDecl.qll @@ -48,7 +48,7 @@ module Generated { final Type getType() { exists(Type immediate | immediate = this.getImmediateType() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -71,7 +71,7 @@ module Generated { final Type getAttachedPropertyWrapperType() { exists(Type immediate | immediate = this.getImmediateAttachedPropertyWrapperType() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -101,7 +101,7 @@ module Generated { final Pattern getParentPattern() { exists(Pattern immediate | immediate = this.getImmediateParentPattern() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -129,7 +129,7 @@ module Generated { final Expr getParentInitializer() { exists(Expr immediate | immediate = this.getImmediateParentInitializer() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -141,29 +141,16 @@ module Generated { /** * Gets the property wrapper backing variable binding of this variable declaration, if it exists. * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. + * This is the synthesized binding introducing the property wrapper backing variable for this + * variable, if any. See `getPropertyWrapperBackingVar`. */ - PatternBindingDecl getImmediatePropertyWrapperBackingVarBinding() { + PatternBindingDecl getPropertyWrapperBackingVarBinding() { result = Synth::convertPatternBindingDeclFromRaw(Synth::convertVarDeclToRaw(this) .(Raw::VarDecl) .getPropertyWrapperBackingVarBinding()) } - /** - * Gets the property wrapper backing variable binding of this variable declaration, if it exists. - * - * This is the synthesized binding introducing the property wrapper backing variable for this - * variable, if any. See `getPropertyWrapperBackingVar`. - */ - final PatternBindingDecl getPropertyWrapperBackingVarBinding() { - exists(PatternBindingDecl immediate | - immediate = this.getImmediatePropertyWrapperBackingVarBinding() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getPropertyWrapperBackingVarBinding()` exists. */ @@ -171,19 +158,6 @@ module Generated { exists(this.getPropertyWrapperBackingVarBinding()) } - /** - * Gets the property wrapper backing variable of this variable declaration, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. - */ - VarDecl getImmediatePropertyWrapperBackingVar() { - result = - Synth::convertVarDeclFromRaw(Synth::convertVarDeclToRaw(this) - .(Raw::VarDecl) - .getPropertyWrapperBackingVar()) - } - /** * Gets the property wrapper backing variable of this variable declaration, if it exists. * @@ -203,11 +177,11 @@ module Generated { * ``` * This predicate returns such variable declaration. */ - final VarDecl getPropertyWrapperBackingVar() { - exists(VarDecl immediate | - immediate = this.getImmediatePropertyWrapperBackingVar() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) + VarDecl getPropertyWrapperBackingVar() { + result = + Synth::convertVarDeclFromRaw(Synth::convertVarDeclToRaw(this) + .(Raw::VarDecl) + .getPropertyWrapperBackingVar()) } /** @@ -218,29 +192,16 @@ module Generated { /** * Gets the property wrapper projection variable binding of this variable declaration, if it exists. * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. + * This is the synthesized binding introducing the property wrapper projection variable for this + * variable, if any. See `getPropertyWrapperProjectionVar`. */ - PatternBindingDecl getImmediatePropertyWrapperProjectionVarBinding() { + PatternBindingDecl getPropertyWrapperProjectionVarBinding() { result = Synth::convertPatternBindingDeclFromRaw(Synth::convertVarDeclToRaw(this) .(Raw::VarDecl) .getPropertyWrapperProjectionVarBinding()) } - /** - * Gets the property wrapper projection variable binding of this variable declaration, if it exists. - * - * This is the synthesized binding introducing the property wrapper projection variable for this - * variable, if any. See `getPropertyWrapperProjectionVar`. - */ - final PatternBindingDecl getPropertyWrapperProjectionVarBinding() { - exists(PatternBindingDecl immediate | - immediate = this.getImmediatePropertyWrapperProjectionVarBinding() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getPropertyWrapperProjectionVarBinding()` exists. */ @@ -248,19 +209,6 @@ module Generated { exists(this.getPropertyWrapperProjectionVarBinding()) } - /** - * Gets the property wrapper projection variable of this variable declaration, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. - */ - VarDecl getImmediatePropertyWrapperProjectionVar() { - result = - Synth::convertVarDeclFromRaw(Synth::convertVarDeclToRaw(this) - .(Raw::VarDecl) - .getPropertyWrapperProjectionVar()) - } - /** * Gets the property wrapper projection variable of this variable declaration, if it exists. * @@ -286,11 +234,11 @@ module Generated { * ``` * This predicate returns such variable declaration. */ - final VarDecl getPropertyWrapperProjectionVar() { - exists(VarDecl immediate | - immediate = this.getImmediatePropertyWrapperProjectionVar() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) + VarDecl getPropertyWrapperProjectionVar() { + result = + Synth::convertVarDeclFromRaw(Synth::convertVarDeclToRaw(this) + .(Raw::VarDecl) + .getPropertyWrapperProjectionVar()) } /** diff --git a/swift/ql/lib/codeql/swift/generated/expr/AppliedPropertyWrapperExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/AppliedPropertyWrapperExpr.qll index 3ee26f38f89..1710534e9a6 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/AppliedPropertyWrapperExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/AppliedPropertyWrapperExpr.qll @@ -50,25 +50,12 @@ module Generated { /** * Gets the parameter declaration owning this wrapper application. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ParamDecl getImmediateParam() { + ParamDecl getParam() { result = Synth::convertParamDeclFromRaw(Synth::convertAppliedPropertyWrapperExprToRaw(this) .(Raw::AppliedPropertyWrapperExpr) .getParam()) } - - /** - * Gets the parameter declaration owning this wrapper application. - */ - final ParamDecl getParam() { - exists(ParamDecl immediate | - immediate = this.getImmediateParam() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/ApplyExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/ApplyExpr.qll index 6529ca4882a..01aabf3ef17 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/ApplyExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/ApplyExpr.qll @@ -29,27 +29,14 @@ module Generated { /** * Gets the `index`th argument passed to the applied function (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Argument getImmediateArgument(int index) { + Argument getArgument(int index) { result = Synth::convertArgumentFromRaw(Synth::convertApplyExprToRaw(this) .(Raw::ApplyExpr) .getArgument(index)) } - /** - * Gets the `index`th argument passed to the applied function (0-based). - */ - final Argument getArgument(int index) { - exists(Argument immediate | - immediate = this.getImmediateArgument(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the arguments passed to the applied function. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/Argument.qll b/swift/ql/lib/codeql/swift/generated/expr/Argument.qll index 3040a549ec9..16b8da0887f 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/Argument.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/Argument.qll @@ -30,7 +30,7 @@ module Generated { final Expr getExpr() { exists(Expr immediate | immediate = this.getImmediateExpr() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll index b3a6653ce77..521eb9f074d 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll @@ -11,27 +11,14 @@ module Generated { /** * Gets the `index`th binding declaration of this capture list expression (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - PatternBindingDecl getImmediateBindingDecl(int index) { + PatternBindingDecl getBindingDecl(int index) { result = Synth::convertPatternBindingDeclFromRaw(Synth::convertCaptureListExprToRaw(this) .(Raw::CaptureListExpr) .getBindingDecl(index)) } - /** - * Gets the `index`th binding declaration of this capture list expression (0-based). - */ - final PatternBindingDecl getBindingDecl(int index) { - exists(PatternBindingDecl immediate | - immediate = this.getImmediateBindingDecl(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the binding declarations of this capture list expression. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll index 6aa2c0522f5..0f8bef8745a 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/DeclRefExpr.qll @@ -11,25 +11,12 @@ module Generated { /** * Gets the declaration of this declaration reference expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Decl getImmediateDecl() { + Decl getDecl() { result = Synth::convertDeclFromRaw(Synth::convertDeclRefExprToRaw(this).(Raw::DeclRefExpr).getDecl()) } - /** - * Gets the declaration of this declaration reference expression. - */ - final Decl getDecl() { - exists(Decl immediate | - immediate = this.getImmediateDecl() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the `index`th replacement type of this declaration reference expression (0-based). * diff --git a/swift/ql/lib/codeql/swift/generated/expr/DefaultArgumentExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/DefaultArgumentExpr.qll index e457353ada4..23f791afff8 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/DefaultArgumentExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/DefaultArgumentExpr.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the parameter declaration of this default argument expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ParamDecl getImmediateParamDecl() { + ParamDecl getParamDecl() { result = Synth::convertParamDeclFromRaw(Synth::convertDefaultArgumentExprToRaw(this) .(Raw::DefaultArgumentExpr) .getParamDecl()) } - /** - * Gets the parameter declaration of this default argument expression. - */ - final ParamDecl getParamDecl() { - exists(ParamDecl immediate | - immediate = this.getImmediateParamDecl() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the parameter index of this default argument expression. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll index 0ec0a3275dd..146c769f2a1 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll @@ -33,25 +33,12 @@ module Generated { /** * Gets the element of this enum is case expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - EnumElementDecl getImmediateElement() { + EnumElementDecl getElement() { result = Synth::convertEnumElementDeclFromRaw(Synth::convertEnumIsCaseExprToRaw(this) .(Raw::EnumIsCaseExpr) .getElement()) } - - /** - * Gets the element of this enum is case expression. - */ - final EnumElementDecl getElement() { - exists(EnumElementDecl immediate | - immediate = this.getImmediateElement() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/Expr.qll b/swift/ql/lib/codeql/swift/generated/expr/Expr.qll index dad004bc2bd..6f488acbe59 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/Expr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/Expr.qll @@ -2,13 +2,14 @@ private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw import codeql.swift.elements.AstNode +import codeql.swift.elements.HideableElement import codeql.swift.elements.type.Type module Generated { /** * The base class for all expressions in Swift. */ - class Expr extends Synth::TExpr, AstNode { + class Expr extends Synth::TExpr, AstNode, HideableElement { /** * Gets the type of this expression, if it exists. * diff --git a/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll index a74a289cf83..cd1d20d37aa 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll @@ -14,27 +14,14 @@ module Generated { /** * Gets the root of this key path expression, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - TypeRepr getImmediateRoot() { + TypeRepr getRoot() { result = Synth::convertTypeReprFromRaw(Synth::convertKeyPathExprToRaw(this) .(Raw::KeyPathExpr) .getRoot()) } - /** - * Gets the root of this key path expression, if it exists. - */ - final TypeRepr getRoot() { - exists(TypeRepr immediate | - immediate = this.getImmediateRoot() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getRoot()` exists. */ @@ -42,27 +29,14 @@ module Generated { /** * Gets the `index`th component of this key path expression (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - KeyPathComponent getImmediateComponent(int index) { + KeyPathComponent getComponent(int index) { result = Synth::convertKeyPathComponentFromRaw(Synth::convertKeyPathExprToRaw(this) .(Raw::KeyPathExpr) .getComponent(index)) } - /** - * Gets the `index`th component of this key path expression (0-based). - */ - final KeyPathComponent getComponent(int index) { - exists(KeyPathComponent immediate | - immediate = this.getImmediateComponent(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the components of this key path expression. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/LookupExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/LookupExpr.qll index a2d5edccbff..496312312fc 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/LookupExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/LookupExpr.qll @@ -29,25 +29,12 @@ module Generated { /** * Gets the member of this lookup expression, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Decl getImmediateMember() { + Decl getMember() { result = Synth::convertDeclFromRaw(Synth::convertLookupExprToRaw(this).(Raw::LookupExpr).getMember()) } - /** - * Gets the member of this lookup expression, if it exists. - */ - final Decl getMember() { - exists(Decl immediate | - immediate = this.getImmediateMember() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getMember()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/ObjCSelectorExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/ObjCSelectorExpr.qll index 1a19498c020..8445d13227e 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/ObjCSelectorExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/ObjCSelectorExpr.qll @@ -33,25 +33,12 @@ module Generated { /** * Gets the method of this obj c selector expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Function getImmediateMethod() { + Function getMethod() { result = Synth::convertFunctionFromRaw(Synth::convertObjCSelectorExprToRaw(this) .(Raw::ObjCSelectorExpr) .getMethod()) } - - /** - * Gets the method of this obj c selector expression. - */ - final Function getMethod() { - exists(Function immediate | - immediate = this.getImmediateMethod() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/ObjectLiteralExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/ObjectLiteralExpr.qll index adbc4cb3f34..57aaae68bb5 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/ObjectLiteralExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/ObjectLiteralExpr.qll @@ -22,27 +22,14 @@ module Generated { /** * Gets the `index`th argument of this object literal expression (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Argument getImmediateArgument(int index) { + Argument getArgument(int index) { result = Synth::convertArgumentFromRaw(Synth::convertObjectLiteralExprToRaw(this) .(Raw::ObjectLiteralExpr) .getArgument(index)) } - /** - * Gets the `index`th argument of this object literal expression (0-based). - */ - final Argument getArgument(int index) { - exists(Argument immediate | - immediate = this.getImmediateArgument(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the arguments of this object literal expression. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/OtherInitializerRefExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/OtherInitializerRefExpr.qll index cf66c7d3c79..674f5a217e7 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/OtherInitializerRefExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/OtherInitializerRefExpr.qll @@ -10,25 +10,12 @@ module Generated { /** * Gets the initializer of this other initializer reference expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Initializer getImmediateInitializer() { + Initializer getInitializer() { result = Synth::convertInitializerFromRaw(Synth::convertOtherInitializerRefExprToRaw(this) .(Raw::OtherInitializerRefExpr) .getInitializer()) } - - /** - * Gets the initializer of this other initializer reference expression. - */ - final Initializer getInitializer() { - exists(Initializer immediate | - immediate = this.getImmediateInitializer() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/OverloadedDeclRefExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/OverloadedDeclRefExpr.qll index 8a923e918f7..c13924bba35 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/OverloadedDeclRefExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/OverloadedDeclRefExpr.qll @@ -15,27 +15,14 @@ module Generated { /** * Gets the `index`th possible declaration of this overloaded declaration reference expression (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ValueDecl getImmediatePossibleDeclaration(int index) { + ValueDecl getPossibleDeclaration(int index) { result = Synth::convertValueDeclFromRaw(Synth::convertOverloadedDeclRefExprToRaw(this) .(Raw::OverloadedDeclRefExpr) .getPossibleDeclaration(index)) } - /** - * Gets the `index`th possible declaration of this overloaded declaration reference expression (0-based). - */ - final ValueDecl getPossibleDeclaration(int index) { - exists(ValueDecl immediate | - immediate = this.getImmediatePossibleDeclaration(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the possible declarations of this overloaded declaration reference expression. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/RebindSelfInInitializerExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/RebindSelfInInitializerExpr.qll index 6a2c298e360..fa8bc92876e 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/RebindSelfInInitializerExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/RebindSelfInInitializerExpr.qll @@ -33,25 +33,12 @@ module Generated { /** * Gets the self of this rebind self in initializer expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - VarDecl getImmediateSelf() { + VarDecl getSelf() { result = Synth::convertVarDeclFromRaw(Synth::convertRebindSelfInInitializerExprToRaw(this) .(Raw::RebindSelfInInitializerExpr) .getSelf()) } - - /** - * Gets the self of this rebind self in initializer expression. - */ - final VarDecl getSelf() { - exists(VarDecl immediate | - immediate = this.getImmediateSelf() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll index 8e9734917b7..561383ff57e 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/SubscriptExpr.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the `index`th argument of this subscript expression (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Argument getImmediateArgument(int index) { + Argument getArgument(int index) { result = Synth::convertArgumentFromRaw(Synth::convertSubscriptExprToRaw(this) .(Raw::SubscriptExpr) .getArgument(index)) } - /** - * Gets the `index`th argument of this subscript expression (0-based). - */ - final Argument getArgument(int index) { - exists(Argument immediate | - immediate = this.getImmediateArgument(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the arguments of this subscript expression. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/SuperRefExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/SuperRefExpr.qll index 5058db3f175..9731b002eef 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/SuperRefExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/SuperRefExpr.qll @@ -10,25 +10,12 @@ module Generated { /** * Gets the self of this super reference expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - VarDecl getImmediateSelf() { + VarDecl getSelf() { result = Synth::convertVarDeclFromRaw(Synth::convertSuperRefExprToRaw(this) .(Raw::SuperRefExpr) .getSelf()) } - - /** - * Gets the self of this super reference expression. - */ - final VarDecl getSelf() { - exists(VarDecl immediate | - immediate = this.getImmediateSelf() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/TapExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/TapExpr.qll index 0132d9363f3..596a565115a 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/TapExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/TapExpr.qll @@ -37,44 +37,18 @@ module Generated { /** * Gets the body of this tap expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - BraceStmt getImmediateBody() { + BraceStmt getBody() { result = Synth::convertBraceStmtFromRaw(Synth::convertTapExprToRaw(this).(Raw::TapExpr).getBody()) } - /** - * Gets the body of this tap expression. - */ - final BraceStmt getBody() { - exists(BraceStmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the variable of this tap expression. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - VarDecl getImmediateVar() { + VarDecl getVar() { result = Synth::convertVarDeclFromRaw(Synth::convertTapExprToRaw(this).(Raw::TapExpr).getVar()) } - - /** - * Gets the variable of this tap expression. - */ - final VarDecl getVar() { - exists(VarDecl immediate | - immediate = this.getImmediateVar() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll index 96fb7141531..d070555e6a6 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the type representation of this type expression, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - TypeRepr getImmediateTypeRepr() { + TypeRepr getTypeRepr() { result = Synth::convertTypeReprFromRaw(Synth::convertTypeExprToRaw(this) .(Raw::TypeExpr) .getTypeRepr()) } - /** - * Gets the type representation of this type expression, if it exists. - */ - final TypeRepr getTypeRepr() { - exists(TypeRepr immediate | - immediate = this.getImmediateTypeRepr() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getTypeRepr()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/pattern/EnumElementPattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/EnumElementPattern.qll index bbed4615ce1..b6ef3dd514e 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/EnumElementPattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/EnumElementPattern.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the element of this enum element pattern. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - EnumElementDecl getImmediateElement() { + EnumElementDecl getElement() { result = Synth::convertEnumElementDeclFromRaw(Synth::convertEnumElementPatternToRaw(this) .(Raw::EnumElementPattern) .getElement()) } - /** - * Gets the element of this enum element pattern. - */ - final EnumElementDecl getElement() { - exists(EnumElementDecl immediate | - immediate = this.getImmediateElement() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the sub pattern of this enum element pattern, if it exists. * diff --git a/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll index 7864297866c..a0fffd05155 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the cast type representation of this is pattern, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - TypeRepr getImmediateCastTypeRepr() { + TypeRepr getCastTypeRepr() { result = Synth::convertTypeReprFromRaw(Synth::convertIsPatternToRaw(this) .(Raw::IsPattern) .getCastTypeRepr()) } - /** - * Gets the cast type representation of this is pattern, if it exists. - */ - final TypeRepr getCastTypeRepr() { - exists(TypeRepr immediate | - immediate = this.getImmediateCastTypeRepr() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getCastTypeRepr()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/Pattern.qll index 5c795e45107..5ba24c9fcda 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/Pattern.qll @@ -2,7 +2,8 @@ private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw import codeql.swift.elements.AstNode +import codeql.swift.elements.HideableElement module Generated { - class Pattern extends Synth::TPattern, AstNode { } + class Pattern extends Synth::TPattern, AstNode, HideableElement { } } diff --git a/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll index 2570eca03f8..40a7884bd31 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll @@ -33,27 +33,14 @@ module Generated { /** * Gets the type representation of this typed pattern, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - TypeRepr getImmediateTypeRepr() { + TypeRepr getTypeRepr() { result = Synth::convertTypeReprFromRaw(Synth::convertTypedPatternToRaw(this) .(Raw::TypedPattern) .getTypeRepr()) } - /** - * Gets the type representation of this typed pattern, if it exists. - */ - final TypeRepr getTypeRepr() { - exists(TypeRepr immediate | - immediate = this.getImmediateTypeRepr() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getTypeRepr()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll index 08cc9c6ce2b..360366dcaa3 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the `index`th element of this brace statement (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - AstNode getImmediateElement(int index) { + AstNode getElement(int index) { result = Synth::convertAstNodeFromRaw(Synth::convertBraceStmtToRaw(this) .(Raw::BraceStmt) .getElement(index)) } - /** - * Gets the `index`th element of this brace statement (0-based). - */ - final AstNode getElement(int index) { - exists(AstNode immediate | - immediate = this.getImmediateElement(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the elements of this brace statement. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/BreakStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/BreakStmt.qll index f9adaeb9ddb..2c8de492f08 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/BreakStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/BreakStmt.qll @@ -21,25 +21,12 @@ module Generated { /** * Gets the target of this break statement, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Stmt getImmediateTarget() { + Stmt getTarget() { result = Synth::convertStmtFromRaw(Synth::convertBreakStmtToRaw(this).(Raw::BreakStmt).getTarget()) } - /** - * Gets the target of this break statement, if it exists. - */ - final Stmt getTarget() { - exists(Stmt immediate | - immediate = this.getImmediateTarget() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getTarget()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/CaseLabelItem.qll b/swift/ql/lib/codeql/swift/generated/stmt/CaseLabelItem.qll index b69e392cc1e..c27e1ed893b 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/CaseLabelItem.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/CaseLabelItem.qll @@ -28,7 +28,7 @@ module Generated { final Pattern getPattern() { exists(Pattern immediate | immediate = this.getImmediatePattern() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -51,7 +51,7 @@ module Generated { final Expr getGuard() { exists(Expr immediate | immediate = this.getImmediateGuard() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/CaseStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/CaseStmt.qll index e39ba24d48c..d0c2db1d752 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/CaseStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/CaseStmt.qll @@ -11,48 +11,22 @@ module Generated { /** * Gets the body of this case statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Stmt getImmediateBody() { + Stmt getBody() { result = Synth::convertStmtFromRaw(Synth::convertCaseStmtToRaw(this).(Raw::CaseStmt).getBody()) } - /** - * Gets the body of this case statement. - */ - final Stmt getBody() { - exists(Stmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the `index`th label of this case statement (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - CaseLabelItem getImmediateLabel(int index) { + CaseLabelItem getLabel(int index) { result = Synth::convertCaseLabelItemFromRaw(Synth::convertCaseStmtToRaw(this) .(Raw::CaseStmt) .getLabel(index)) } - /** - * Gets the `index`th label of this case statement (0-based). - */ - final CaseLabelItem getLabel(int index) { - exists(CaseLabelItem immediate | - immediate = this.getImmediateLabel(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the labels of this case statement. */ @@ -65,27 +39,14 @@ module Generated { /** * Gets the `index`th variable of this case statement (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - VarDecl getImmediateVariable(int index) { + VarDecl getVariable(int index) { result = Synth::convertVarDeclFromRaw(Synth::convertCaseStmtToRaw(this) .(Raw::CaseStmt) .getVariable(index)) } - /** - * Gets the `index`th variable of this case statement (0-based). - */ - final VarDecl getVariable(int index) { - exists(VarDecl immediate | - immediate = this.getImmediateVariable(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the variables of this case statement. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/ConditionElement.qll b/swift/ql/lib/codeql/swift/generated/stmt/ConditionElement.qll index 2eddaa245e7..6555c537e30 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/ConditionElement.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/ConditionElement.qll @@ -29,7 +29,7 @@ module Generated { final Expr getBoolean() { exists(Expr immediate | immediate = this.getImmediateBoolean() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -57,7 +57,7 @@ module Generated { final Pattern getPattern() { exists(Pattern immediate | immediate = this.getImmediatePattern() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -85,7 +85,7 @@ module Generated { final Expr getInitializer() { exists(Expr immediate | immediate = this.getImmediateInitializer() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -96,27 +96,14 @@ module Generated { /** * Gets the availability of this condition element, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - AvailabilityInfo getImmediateAvailability() { + AvailabilityInfo getAvailability() { result = Synth::convertAvailabilityInfoFromRaw(Synth::convertConditionElementToRaw(this) .(Raw::ConditionElement) .getAvailability()) } - /** - * Gets the availability of this condition element, if it exists. - */ - final AvailabilityInfo getAvailability() { - exists(AvailabilityInfo immediate | - immediate = this.getImmediateAvailability() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getAvailability()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/ContinueStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/ContinueStmt.qll index d247f507d9a..617c903dc52 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/ContinueStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/ContinueStmt.qll @@ -21,27 +21,14 @@ module Generated { /** * Gets the target of this continue statement, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Stmt getImmediateTarget() { + Stmt getTarget() { result = Synth::convertStmtFromRaw(Synth::convertContinueStmtToRaw(this) .(Raw::ContinueStmt) .getTarget()) } - /** - * Gets the target of this continue statement, if it exists. - */ - final Stmt getTarget() { - exists(Stmt immediate | - immediate = this.getImmediateTarget() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getTarget()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/DeferStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/DeferStmt.qll index 21da3aa706c..17cf8f07db0 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/DeferStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/DeferStmt.qll @@ -10,23 +10,10 @@ module Generated { /** * Gets the body of this defer statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - BraceStmt getImmediateBody() { + BraceStmt getBody() { result = Synth::convertBraceStmtFromRaw(Synth::convertDeferStmtToRaw(this).(Raw::DeferStmt).getBody()) } - - /** - * Gets the body of this defer statement. - */ - final BraceStmt getBody() { - exists(BraceStmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/DoCatchStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/DoCatchStmt.qll index 180c4103841..51639d9289c 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/DoCatchStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/DoCatchStmt.qll @@ -11,48 +11,22 @@ module Generated { /** * Gets the body of this do catch statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Stmt getImmediateBody() { + Stmt getBody() { result = Synth::convertStmtFromRaw(Synth::convertDoCatchStmtToRaw(this).(Raw::DoCatchStmt).getBody()) } - /** - * Gets the body of this do catch statement. - */ - final Stmt getBody() { - exists(Stmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the `index`th catch of this do catch statement (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - CaseStmt getImmediateCatch(int index) { + CaseStmt getCatch(int index) { result = Synth::convertCaseStmtFromRaw(Synth::convertDoCatchStmtToRaw(this) .(Raw::DoCatchStmt) .getCatch(index)) } - /** - * Gets the `index`th catch of this do catch statement (0-based). - */ - final CaseStmt getCatch(int index) { - exists(CaseStmt immediate | - immediate = this.getImmediateCatch(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the catches of this do catch statement. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/DoStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/DoStmt.qll index b4661b21d8e..b77a310de90 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/DoStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/DoStmt.qll @@ -10,23 +10,10 @@ module Generated { /** * Gets the body of this do statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - BraceStmt getImmediateBody() { + BraceStmt getBody() { result = Synth::convertBraceStmtFromRaw(Synth::convertDoStmtToRaw(this).(Raw::DoStmt).getBody()) } - - /** - * Gets the body of this do statement. - */ - final BraceStmt getBody() { - exists(BraceStmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/FallthroughStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/FallthroughStmt.qll index 20fadcc91f3..e9e05ea4c9a 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/FallthroughStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/FallthroughStmt.qll @@ -10,48 +10,22 @@ module Generated { /** * Gets the fallthrough source of this fallthrough statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - CaseStmt getImmediateFallthroughSource() { + CaseStmt getFallthroughSource() { result = Synth::convertCaseStmtFromRaw(Synth::convertFallthroughStmtToRaw(this) .(Raw::FallthroughStmt) .getFallthroughSource()) } - /** - * Gets the fallthrough source of this fallthrough statement. - */ - final CaseStmt getFallthroughSource() { - exists(CaseStmt immediate | - immediate = this.getImmediateFallthroughSource() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the fallthrough dest of this fallthrough statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - CaseStmt getImmediateFallthroughDest() { + CaseStmt getFallthroughDest() { result = Synth::convertCaseStmtFromRaw(Synth::convertFallthroughStmtToRaw(this) .(Raw::FallthroughStmt) .getFallthroughDest()) } - - /** - * Gets the fallthrough dest of this fallthrough statement. - */ - final CaseStmt getFallthroughDest() { - exists(CaseStmt immediate | - immediate = this.getImmediateFallthroughDest() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/ForEachStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/ForEachStmt.qll index fccf5f3ed3b..ad5422a7ec0 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/ForEachStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/ForEachStmt.qll @@ -29,7 +29,7 @@ module Generated { final Pattern getPattern() { exists(Pattern immediate | immediate = this.getImmediatePattern() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -52,7 +52,7 @@ module Generated { final Expr getSequence() { exists(Expr immediate | immediate = this.getImmediateSequence() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -73,7 +73,7 @@ module Generated { final Expr getWhere() { exists(Expr immediate | immediate = this.getImmediateWhere() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } @@ -84,25 +84,12 @@ module Generated { /** * Gets the body of this for each statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - BraceStmt getImmediateBody() { + BraceStmt getBody() { result = Synth::convertBraceStmtFromRaw(Synth::convertForEachStmtToRaw(this) .(Raw::ForEachStmt) .getBody()) } - - /** - * Gets the body of this for each statement. - */ - final BraceStmt getBody() { - exists(BraceStmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/GuardStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/GuardStmt.qll index 53d1a8a54aa..01989e827df 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/GuardStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/GuardStmt.qll @@ -10,23 +10,10 @@ module Generated { /** * Gets the body of this guard statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - BraceStmt getImmediateBody() { + BraceStmt getBody() { result = Synth::convertBraceStmtFromRaw(Synth::convertGuardStmtToRaw(this).(Raw::GuardStmt).getBody()) } - - /** - * Gets the body of this guard statement. - */ - final BraceStmt getBody() { - exists(BraceStmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/IfStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/IfStmt.qll index 1f0ad8717cd..1c33e2383df 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/IfStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/IfStmt.qll @@ -10,44 +10,18 @@ module Generated { /** * Gets the then of this if statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Stmt getImmediateThen() { + Stmt getThen() { result = Synth::convertStmtFromRaw(Synth::convertIfStmtToRaw(this).(Raw::IfStmt).getThen()) } - /** - * Gets the then of this if statement. - */ - final Stmt getThen() { - exists(Stmt immediate | - immediate = this.getImmediateThen() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets the else of this if statement, if it exists. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Stmt getImmediateElse() { + Stmt getElse() { result = Synth::convertStmtFromRaw(Synth::convertIfStmtToRaw(this).(Raw::IfStmt).getElse()) } - /** - * Gets the else of this if statement, if it exists. - */ - final Stmt getElse() { - exists(Stmt immediate | - immediate = this.getImmediateElse() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Holds if `getElse()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/LabeledConditionalStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/LabeledConditionalStmt.qll index 41f728962bd..e2796dffb82 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/LabeledConditionalStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/LabeledConditionalStmt.qll @@ -8,25 +8,12 @@ module Generated { class LabeledConditionalStmt extends Synth::TLabeledConditionalStmt, LabeledStmt { /** * Gets the condition of this labeled conditional statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - StmtCondition getImmediateCondition() { + StmtCondition getCondition() { result = Synth::convertStmtConditionFromRaw(Synth::convertLabeledConditionalStmtToRaw(this) .(Raw::LabeledConditionalStmt) .getCondition()) } - - /** - * Gets the condition of this labeled conditional statement. - */ - final StmtCondition getCondition() { - exists(StmtCondition immediate | - immediate = this.getImmediateCondition() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll index b2f9624447e..a38be8e4b18 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll @@ -27,7 +27,7 @@ module Generated { final Expr getCondition() { exists(Expr immediate | immediate = this.getImmediateCondition() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/RepeatWhileStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/RepeatWhileStmt.qll index 2f4ada62ccf..a9b9c606f0e 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/RepeatWhileStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/RepeatWhileStmt.qll @@ -28,31 +28,18 @@ module Generated { final Expr getCondition() { exists(Expr immediate | immediate = this.getImmediateCondition() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } /** * Gets the body of this repeat while statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Stmt getImmediateBody() { + Stmt getBody() { result = Synth::convertStmtFromRaw(Synth::convertRepeatWhileStmtToRaw(this) .(Raw::RepeatWhileStmt) .getBody()) } - - /** - * Gets the body of this repeat while statement. - */ - final Stmt getBody() { - exists(Stmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/ReturnStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/ReturnStmt.qll index c37671aba34..8e9d421da46 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/ReturnStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/ReturnStmt.qll @@ -25,7 +25,7 @@ module Generated { final Expr getResult() { exists(Expr immediate | immediate = this.getImmediateResult() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/StmtCondition.qll b/swift/ql/lib/codeql/swift/generated/stmt/StmtCondition.qll index 1be4eaf361a..6ba5e85f0b4 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/StmtCondition.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/StmtCondition.qll @@ -10,27 +10,14 @@ module Generated { /** * Gets the `index`th element of this statement condition (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ConditionElement getImmediateElement(int index) { + ConditionElement getElement(int index) { result = Synth::convertConditionElementFromRaw(Synth::convertStmtConditionToRaw(this) .(Raw::StmtCondition) .getElement(index)) } - /** - * Gets the `index`th element of this statement condition (0-based). - */ - final ConditionElement getElement(int index) { - exists(ConditionElement immediate | - immediate = this.getImmediateElement(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the elements of this statement condition. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/SwitchStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/SwitchStmt.qll index 819be668d5c..9cfc7cfb2d2 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/SwitchStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/SwitchStmt.qll @@ -26,33 +26,20 @@ module Generated { final Expr getExpr() { exists(Expr immediate | immediate = this.getImmediateExpr() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } /** * Gets the `index`th case of this switch statement (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - CaseStmt getImmediateCase(int index) { + CaseStmt getCase(int index) { result = Synth::convertCaseStmtFromRaw(Synth::convertSwitchStmtToRaw(this) .(Raw::SwitchStmt) .getCase(index)) } - /** - * Gets the `index`th case of this switch statement (0-based). - */ - final CaseStmt getCase(int index) { - exists(CaseStmt immediate | - immediate = this.getImmediateCase(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the cases of this switch statement. */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/ThrowStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/ThrowStmt.qll index fd6c6920b00..294e7ed5bb8 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/ThrowStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/ThrowStmt.qll @@ -25,7 +25,7 @@ module Generated { final Expr getSubExpr() { exists(Expr immediate | immediate = this.getImmediateSubExpr() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/WhileStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/WhileStmt.qll index 0482887cc57..3ed59b4cc3c 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/WhileStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/WhileStmt.qll @@ -10,23 +10,10 @@ module Generated { /** * Gets the body of this while statement. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - Stmt getImmediateBody() { + Stmt getBody() { result = Synth::convertStmtFromRaw(Synth::convertWhileStmtToRaw(this).(Raw::WhileStmt).getBody()) } - - /** - * Gets the body of this while statement. - */ - final Stmt getBody() { - exists(Stmt immediate | - immediate = this.getImmediateBody() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/YieldStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/YieldStmt.qll index df8b51cb2c4..31a691ba91c 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/YieldStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/YieldStmt.qll @@ -27,7 +27,7 @@ module Generated { final Expr getResult(int index) { exists(Expr immediate | immediate = this.getImmediateResult(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/type/AnyGenericType.qll b/swift/ql/lib/codeql/swift/generated/type/AnyGenericType.qll index 3cb6fe2786c..57a0ace8b58 100644 --- a/swift/ql/lib/codeql/swift/generated/type/AnyGenericType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/AnyGenericType.qll @@ -36,25 +36,12 @@ module Generated { /** * Gets the declaration of this any generic type. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - GenericTypeDecl getImmediateDeclaration() { + GenericTypeDecl getDeclaration() { result = Synth::convertGenericTypeDeclFromRaw(Synth::convertAnyGenericTypeToRaw(this) .(Raw::AnyGenericType) .getDeclaration()) } - - /** - * Gets the declaration of this any generic type. - */ - final GenericTypeDecl getDeclaration() { - exists(GenericTypeDecl immediate | - immediate = this.getImmediateDeclaration() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll b/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll index 7d907166dcf..2128967a8f8 100644 --- a/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll @@ -60,27 +60,14 @@ module Generated { /** * Gets the `index`th protocol of this archetype type (0-based). - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ProtocolDecl getImmediateProtocol(int index) { + ProtocolDecl getProtocol(int index) { result = Synth::convertProtocolDeclFromRaw(Synth::convertArchetypeTypeToRaw(this) .(Raw::ArchetypeType) .getProtocol(index)) } - /** - * Gets the `index`th protocol of this archetype type (0-based). - */ - final ProtocolDecl getProtocol(int index) { - exists(ProtocolDecl immediate | - immediate = this.getImmediateProtocol(index) and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } - /** * Gets any of the protocols of this archetype type. */ diff --git a/swift/ql/lib/codeql/swift/generated/type/DependentMemberType.qll b/swift/ql/lib/codeql/swift/generated/type/DependentMemberType.qll index 007748ae2c4..8192ed17213 100644 --- a/swift/ql/lib/codeql/swift/generated/type/DependentMemberType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/DependentMemberType.qll @@ -33,25 +33,12 @@ module Generated { /** * Gets the associated type declaration of this dependent member type. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - AssociatedTypeDecl getImmediateAssociatedTypeDecl() { + AssociatedTypeDecl getAssociatedTypeDecl() { result = Synth::convertAssociatedTypeDeclFromRaw(Synth::convertDependentMemberTypeToRaw(this) .(Raw::DependentMemberType) .getAssociatedTypeDecl()) } - - /** - * Gets the associated type declaration of this dependent member type. - */ - final AssociatedTypeDecl getAssociatedTypeDecl() { - exists(AssociatedTypeDecl immediate | - immediate = this.getImmediateAssociatedTypeDecl() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll b/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll index e43a1107533..6303b4df206 100644 --- a/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll @@ -10,25 +10,12 @@ module Generated { /** * Gets the module of this module type. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - ModuleDecl getImmediateModule() { + ModuleDecl getModule() { result = Synth::convertModuleDeclFromRaw(Synth::convertModuleTypeToRaw(this) .(Raw::ModuleType) .getModule()) } - - /** - * Gets the module of this module type. - */ - final ModuleDecl getModule() { - exists(ModuleDecl immediate | - immediate = this.getImmediateModule() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/type/OpaqueTypeArchetypeType.qll b/swift/ql/lib/codeql/swift/generated/type/OpaqueTypeArchetypeType.qll index b503969d8ab..520c7785287 100644 --- a/swift/ql/lib/codeql/swift/generated/type/OpaqueTypeArchetypeType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/OpaqueTypeArchetypeType.qll @@ -15,25 +15,12 @@ module Generated { /** * Gets the declaration of this opaque type archetype type. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - OpaqueTypeDecl getImmediateDeclaration() { + OpaqueTypeDecl getDeclaration() { result = Synth::convertOpaqueTypeDeclFromRaw(Synth::convertOpaqueTypeArchetypeTypeToRaw(this) .(Raw::OpaqueTypeArchetypeType) .getDeclaration()) } - - /** - * Gets the declaration of this opaque type archetype type. - */ - final OpaqueTypeDecl getDeclaration() { - exists(OpaqueTypeDecl immediate | - immediate = this.getImmediateDeclaration() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/type/Type.qll b/swift/ql/lib/codeql/swift/generated/type/Type.qll index a3074fdd4d3..7f09e7d7e94 100644 --- a/swift/ql/lib/codeql/swift/generated/type/Type.qll +++ b/swift/ql/lib/codeql/swift/generated/type/Type.qll @@ -1,10 +1,10 @@ // generated by codegen/codegen.py private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw -import codeql.swift.elements.Element +import codeql.swift.elements.HideableElement module Generated { - class Type extends Synth::TType, Element { + class Type extends Synth::TType, HideableElement { /** * Gets the name of this type. */ diff --git a/swift/ql/lib/codeql/swift/generated/type/TypeAliasType.qll b/swift/ql/lib/codeql/swift/generated/type/TypeAliasType.qll index fa6ea238996..6bb41db6655 100644 --- a/swift/ql/lib/codeql/swift/generated/type/TypeAliasType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/TypeAliasType.qll @@ -10,25 +10,12 @@ module Generated { /** * Gets the declaration of this type alias type. - * - * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the - * behavior of both the `Immediate` and non-`Immediate` versions. */ - TypeAliasDecl getImmediateDecl() { + TypeAliasDecl getDecl() { result = Synth::convertTypeAliasDeclFromRaw(Synth::convertTypeAliasTypeToRaw(this) .(Raw::TypeAliasType) .getDecl()) } - - /** - * Gets the declaration of this type alias type. - */ - final TypeAliasDecl getDecl() { - exists(TypeAliasDecl immediate | - immediate = this.getImmediateDecl() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() - ) - } } } diff --git a/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll b/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll index 4a3d11bd074..4dc124e2bda 100644 --- a/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll +++ b/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll @@ -25,7 +25,7 @@ module Generated { final Type getType() { exists(Type immediate | immediate = this.getImmediateType() and - if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() + result = immediate.resolve() ) } } diff --git a/swift/ql/lib/codeql/swift/printast/PrintAstNode.qll b/swift/ql/lib/codeql/swift/printast/PrintAstNode.qll index 57e68648636..dc6af553f43 100644 --- a/swift/ql/lib/codeql/swift/printast/PrintAstNode.qll +++ b/swift/ql/lib/codeql/swift/printast/PrintAstNode.qll @@ -66,7 +66,7 @@ private string prettyPrint(Locatable e) { result = "[" + concat(e.getPrimaryQlClasses(), ", ") + "] " + e } -private class Unresolved extends Locatable { +private class Unresolved extends HideableElement, Locatable { Unresolved() { this != this.resolve() } } @@ -89,7 +89,7 @@ class PrintLocatable extends PrintAstNode, TLocatable { // use even indexes for normal children, leaving odd slots for conversions if any child = TLocatable(c) and index = 2 * i and label = accessor or - child = TLocatable(c.getFullyUnresolved().(Unresolved)) and + child = TLocatable(c.(HideableElement).getFullyUnresolved().(Unresolved)) and index = 2 * i + 1 and ( if c instanceof Expr diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index ba4171b90d0..37e784cc154 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -15,9 +15,9 @@ sourceLocationPrefix( @callable | @file | @generic_context +| @hideable_element | @locatable | @location -| @type ; #keyset[id] @@ -77,6 +77,12 @@ file_is_successfully_extracted( int id: @file ref ); +@hideable_element = + @expr +| @pattern +| @type +; + @locatable = @argument | @ast_node diff --git a/swift/schema.py b/swift/schema.py index f2d1283974f..76ac53dcb5c 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -14,7 +14,6 @@ from misc.codegen.lib.schemadefs import * include("prefix.dbscheme") @qltest.skip -@ql.hideable class Element: is_unknown: predicate | cpp.skip @@ -73,8 +72,12 @@ class UnknownLocation(Location): class AstNode(Locatable): pass +@ql.hideable +class HideableElement(Element): + pass + @group("type") -class Type(Element): +class Type(HideableElement): name: string canonical_type: "Type" @@ -84,12 +87,12 @@ class Decl(AstNode): members: list["Decl"] | child @group("expr") -class Expr(AstNode): +class Expr(AstNode, HideableElement): """The base class for all expressions in Swift.""" type: optional[Type] @group("pattern") -class Pattern(AstNode): +class Pattern(AstNode, HideableElement): pass @group("stmt") From b4edc92079dfe4a1e15bf607c564ed9de729cda8 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 12:17:03 +0200 Subject: [PATCH 080/739] Swift: make hideability spread upward in the hierarchy --- misc/codegen/generators/qlgen.py | 1 - misc/codegen/lib/ql.py | 1 - misc/codegen/lib/schema.py | 1 - misc/codegen/loaders/schemaloader.py | 14 ++++- misc/codegen/templates/ql_class.mustache | 5 +- misc/codegen/templates/ql_parent.mustache | 14 ++--- misc/codegen/test/test_qlgen.py | 8 --- misc/codegen/test/test_schemaloader.py | 17 ++++-- swift/ql/.generated.list | 23 ++++---- swift/ql/.gitattributes | 1 - .../swift/controlflow/internal/Completion.qll | 6 +-- .../internal/ControlFlowGraphImpl.qll | 46 ++++++++-------- swift/ql/lib/codeql/swift/elements.qll | 1 - .../ql/lib/codeql/swift/elements/Element.qll | 11 ++++ .../codeql/swift/elements/HideableElement.qll | 14 ----- .../ql/lib/codeql/swift/generated/Element.qll | 17 ++++++ .../swift/generated/HideableElement.qll | 25 --------- .../codeql/swift/generated/ParentChild.qll | 52 ++++--------------- swift/ql/lib/codeql/swift/generated/Raw.qll | 11 ++-- swift/ql/lib/codeql/swift/generated/Synth.qll | 39 ++------------ .../swift/generated/UnspecifiedElement.qll | 15 +++++- .../swift/generated/decl/IfConfigDecl.qll | 15 +++++- .../lib/codeql/swift/generated/expr/Expr.qll | 3 +- .../swift/generated/pattern/Pattern.qll | 3 +- .../codeql/swift/generated/stmt/BraceStmt.qll | 15 +++++- .../lib/codeql/swift/generated/type/Type.qll | 4 +- .../codeql/swift/printast/PrintAstNode.qll | 4 +- swift/ql/lib/swift.dbscheme | 8 +-- swift/schema.py | 13 +++-- 29 files changed, 174 insertions(+), 213 deletions(-) delete mode 100644 swift/ql/lib/codeql/swift/elements/HideableElement.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/HideableElement.qll diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index 6e4017b81f6..891533383d3 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -166,7 +166,6 @@ def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> q ipa=bool(cls.ipa), doc=cls.doc, hideable=cls.hideable, - hideable_root=cls.hideable_root, **pragmas, ) diff --git a/misc/codegen/lib/ql.py b/misc/codegen/lib/ql.py index 508db816beb..57a74f1f9d3 100644 --- a/misc/codegen/lib/ql.py +++ b/misc/codegen/lib/ql.py @@ -114,7 +114,6 @@ class Class: ql_internal: bool = False ipa: bool = False doc: List[str] = field(default_factory=list) - hideable_root: bool = False hideable: bool = False def __post_init__(self): diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py index d72fa46adf4..023891b6b2d 100644 --- a/misc/codegen/lib/schema.py +++ b/misc/codegen/lib/schema.py @@ -91,7 +91,6 @@ class Class: """^^^ filled with `True` for non-final classes with only synthesized final descendants """ doc: List[str] = field(default_factory=list) default_doc_name: Optional[str] = None - hideable_root: bool = False hideable: bool = False @property diff --git a/misc/codegen/loaders/schemaloader.py b/misc/codegen/loaders/schemaloader.py index 0202c98f439..64f4d03cb57 100644 --- a/misc/codegen/loaders/schemaloader.py +++ b/misc/codegen/loaders/schemaloader.py @@ -39,7 +39,6 @@ def _get_class(cls: type) -> schema.Class: group=getattr(cls, "_group", ""), hideable=getattr(cls, "_hideable", False), # in the following we don't use `getattr` to avoid inheriting - hideable_root=cls.__dict__.get("_hideable", False), pragmas=cls.__dict__.get("_pragmas", []), ipa=cls.__dict__.get("_ipa", None), properties=[ @@ -96,6 +95,18 @@ def _fill_ipa_information(classes: typing.Dict[str, schema.Class]): cls.ipa = True +def _fill_hideable_information(classes: typing.Dict[str, schema.Class]): + """ Update the class map propagating the `hideable` attribute upwards in the hierarchy """ + todo = [cls for cls in classes.values() if cls.hideable] + while todo: + cls = todo.pop() + for base in cls.bases: + supercls = classes[base] + if not supercls.hideable: + supercls.hideable = True + todo.append(supercls) + + def load(m: types.ModuleType) -> schema.Schema: includes = set() classes = {} @@ -124,6 +135,7 @@ def load(m: types.ModuleType) -> schema.Schema: cls.is_null_class = True _fill_ipa_information(classes) + _fill_hideable_information(classes) return schema.Schema(includes=includes, classes=_toposort_classes_by_group(classes), null=null) diff --git a/misc/codegen/templates/ql_class.mustache b/misc/codegen/templates/ql_class.mustache index 63e4f0088fe..a22639ee4b6 100644 --- a/misc/codegen/templates/ql_class.mustache +++ b/misc/codegen/templates/ql_class.mustache @@ -37,8 +37,7 @@ module Generated { * Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs. */ final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") } - {{/root}} - {{#hideable_root}} + /** * Gets the most immediate element that should substitute this element in the explicit AST, if any. * Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved @@ -55,7 +54,7 @@ module Generated { or result = this.getResolveStep().resolve() } - {{/hideable_root}} + {{/root}} {{#final}} override string getAPrimaryQlClass() { result = "{{name}}" } {{/final}} diff --git a/misc/codegen/templates/ql_parent.mustache b/misc/codegen/templates/ql_parent.mustache index 2dcac6c45dc..d310323e74f 100644 --- a/misc/codegen/templates/ql_parent.mustache +++ b/misc/codegen/templates/ql_parent.mustache @@ -64,10 +64,6 @@ none() {{/final}} {{/classes}} } - -Element resolve(Element e) { - {{#classes}}{{#hideable_root}}if e instanceof {{name}} then result = e.({{name}}).resolve() else {{/hideable_root}}{{/classes}}result = e -} } /** @@ -75,21 +71,21 @@ Element resolve(Element e) { * if `e` has conversions, `getImmediateParent(e)` will give the innermost conversion in the hidden AST. */ Element getImmediateParent(Element e) { -// `unique` is used here to tell the optimizer that there is in fact only one result -// this is tested by the `library-tests/parent/no_double_parents.ql` test -result = unique(Element x | e = Impl::getImmediateChild(x, _, _) | x) + // `unique` is used here to tell the optimizer that there is in fact only one result + // this is tested by the `library-tests/parent/no_double_parents.ql` test + result = unique(Element x | e = Impl::getImmediateChild(x, _, _) | x) } /** * Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child. */ Element getImmediateChildAndAccessor(Element e, int index, string accessor) { -exists(string partialAccessor | result = Impl::getImmediateChild(e, index, partialAccessor) and accessor = "get" + partialAccessor) + exists(string partialAccessor | result = Impl::getImmediateChild(e, index, partialAccessor) and accessor = "get" + partialAccessor) } /** * Gets the child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child. */ Element getChildAndAccessor(Element e, int index, string accessor) { -exists(string partialAccessor | result = Impl::resolve(Impl::getImmediateChild(e, index, partialAccessor)) and accessor = "get" + partialAccessor) + exists(string partialAccessor | result = Impl::getImmediateChild(e, index, partialAccessor).resolve() and accessor = "get" + partialAccessor) } diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index 32f65bbc851..44c5e63f05d 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -880,14 +880,6 @@ def test_hideable_class(generate_classes): } -def test_hideable_root_class(generate_classes): - assert generate_classes([ - schema.Class("MyObject", hideable_root=True), - ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, hideable_root=True)), - } - - def test_hideable_property(generate_classes): assert generate_classes([ schema.Class("MyObject", hideable=True), diff --git a/misc/codegen/test/test_schemaloader.py b/misc/codegen/test/test_schemaloader.py index 2479fc08500..25b4c43f161 100644 --- a/misc/codegen/test/test_schemaloader.py +++ b/misc/codegen/test/test_schemaloader.py @@ -698,11 +698,22 @@ def test_hideable(): class A(Root): pass - class B(A): + class IndirectlyHideable(Root): pass - assert data.classes["A"] == schema.Class("A", bases=["Root"], derived={"B"}, hideable_root=True, hideable=True) - assert data.classes["B"] == schema.Class("B", bases=["A"], hideable=True) + class B(A, IndirectlyHideable): + pass + + class NonHideable(Root): + pass + + assert data.classes == { + "Root": schema.Class("Root", derived={"A", "IndirectlyHideable", "NonHideable"}, hideable=True), + "A": schema.Class("A", bases=["Root"], derived={"B"}, hideable=True), + "IndirectlyHideable": schema.Class("IndirectlyHideable", bases=["Root"], derived={"B"}, hideable=True), + "B": schema.Class("B", bases=["A", "IndirectlyHideable"], hideable=True), + "NonHideable": schema.Class("NonHideable", bases=["Root"], hideable=False), + } if __name__ == '__main__': diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 3de24cd5c71..530a9e62795 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -365,7 +365,7 @@ lib/codeql/swift/elements/type/VariadicSequenceType.qll 325e4c4481e9ac07acdc6aeb lib/codeql/swift/elements/type/VariadicSequenceTypeConstructor.qll 0d1d2328a3b5e503a883e7e6d7efd0ca5e7f2633abead9e4c94a9f98ed3cb223 69bff81c1b9413949eacb9298d2efb718ea808e68364569a1090c9878c4af856 lib/codeql/swift/elements/type/WeakStorageType.qll 7c07739cfc1459f068f24fef74838428128054adf611504d22532e4a156073e7 9c968414d7cc8d672f3754bced5d4f83f43a6d7872d0d263d79ff60483e1f996 lib/codeql/swift/elements/type/WeakStorageTypeConstructor.qll d88b031ef44d6de14b3ddcff2eb47b53dbd11550c37250ff2edb42e5d21ec3e9 26d855c33492cf7a118e439f7baeed0e5425cfaf058b1dcc007eca7ed765c897 -lib/codeql/swift/elements.qll cba02ae777269061af0713f6b003c97679434ddc8b2e871fc00c5d17c5265d2a cba02ae777269061af0713f6b003c97679434ddc8b2e871fc00c5d17c5265d2a +lib/codeql/swift/elements.qll 3df0060edd2b2030f4e4d7d5518afe0073d798474d9b1d6185d833bec63ca8bd 3df0060edd2b2030f4e4d7d5518afe0073d798474d9b1d6185d833bec63ca8bd lib/codeql/swift/generated/AstNode.qll 02ca56d82801f942ae6265c6079d92ccafdf6b532f6bcebd98a04029ddf696e4 6216fda240e45bd4302fa0cf0f08f5f945418b144659264cdda84622b0420aa2 lib/codeql/swift/generated/AvailabilityInfo.qll 1e38e7f52ccbcecd4dd088eae15c482d87911682dabb426332cc0e207fc6bf2f 7c6640530cdbece90d4172e8d6cfd119656860da08bb61ed4ef3a6757723994f lib/codeql/swift/generated/AvailabilitySpec.qll fb1255f91bb5e41ad4e9c675a2efbc50d0fb366ea2de68ab7eebd177b0795309 144e0c2e7d6c62ecee43325f7f26dcf437881edf0b75cc1bc898c6c4b61fdeaf @@ -374,23 +374,22 @@ lib/codeql/swift/generated/Comment.qll f58b49f6e68c21f87c51e2ff84c8a64b09286d733 lib/codeql/swift/generated/DbFile.qll a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc lib/codeql/swift/generated/DbLocation.qll b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 lib/codeql/swift/generated/Diagnostics.qll d2ee2db55e932dcaee95fcc1164a51ffbe1a78d86ee0f50aabb299b458462afe 566d554d579cadde26dc4d1d6b1750ca800511201b737b629f15b6f873af3733 -lib/codeql/swift/generated/Element.qll 1c6a757f3c1218b02a98f075b2cfb5bd0cc31dff31bd1d04acdf4d4f040dee45 a3221cd9250706e6313a82450466326e5a1e6ffa5ae0b308e943d0979d03919e +lib/codeql/swift/generated/Element.qll 81a01c1965cf8154596c753b20536ef8630b30567d8c077660ab2d11143f060b 74f5c76db5ec82a9c1675ec0282acd44f1a86ef447d1961c47aea3eed50f79cb lib/codeql/swift/generated/ErrorElement.qll 4b032abe8ffb71376a29c63e470a52943ace2527bf7b433c97a8bf716f9ad102 4f2b1be162a5c275e3264dbc51bf98bce8846d251be8490a0d4b16cbc85f630f lib/codeql/swift/generated/File.qll f88c485883dd9b2b4a366080e098372912e03fb3177e5cae58aa4449c2b03399 0333c49e3a11c48e6146a7f492ee31ac022d80150fc3f8bfafc3c8f94d66ff76 -lib/codeql/swift/generated/HideableElement.qll 0eb3bb2fd9fb2b5ba444f4cd1aa4f91c87926618dcfa0051b048cf9d63f9602e 0eb3bb2fd9fb2b5ba444f4cd1aa4f91c87926618dcfa0051b048cf9d63f9602e lib/codeql/swift/generated/KeyPathComponent.qll c79c7bc04fc1426992ab472eedc1a20a7aa496ff3f43305400022f1a02ba44f4 a9935b68b511329d157bcd7a7d27aa4803d2163306db8b41808a2b736f80f4d8 lib/codeql/swift/generated/Locatable.qll be20967d48a34cdba126fe298606e0adc11697831f097acba9c52a0b7ce9983e 8aa01bc376614abbc3209e25785c72f86c9b4e94bb5f471a4a0677fedaec4f61 lib/codeql/swift/generated/Location.qll c5793987e77812059a28254dadee29bfe9b38153c0399fbb1bf6a2f5c237fdab 6e6d8802b021e36bbaad81845657769dd48a798ea33080ada05e9818a20b38f7 lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 -lib/codeql/swift/generated/ParentChild.qll ffec94e3ee076ff73dd7b4e6561c8d8c1f9a198547085baa40a1e5e28adc5827 a28adf13137431f55ce218ade6848bf5b853d3f27315765e9e6c45032c02ddd3 +lib/codeql/swift/generated/ParentChild.qll 7d2d0628965c38d59877fed220b39bd3b02d3652990caf7eeabe966b73534c7d a5a9df21d0a6a00aed6ebb60f13fea3456bf97ca84a140ebca52610eb7c8ff8b lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 56e12381886fe9eb6aef74968cb542e179116ad6722640a21bda37f1d9d26e77 ae93d0caebecf3ce593c95887b44cd1686b5c7e989d5cce4bb39d97312c3cb68 -lib/codeql/swift/generated/Synth.qll 14dbc93375bcde4d792c1ec6157ee9c825119dcc9de31bcfeea56b3636f32d27 e84970ed295aa0af59135ee09b9cddbd6a26dcbce3baaf0e2a958b0552aac6d1 +lib/codeql/swift/generated/Raw.qll 8d4880e5ee1fdd120adeb7bf0dfa1399e7b1a53b2cc7598aed8e15cbf996d1c0 da0d446347d29f5cd05281c17c24e87610f31c32adb7e05ab8f3a26bed55bd90 +lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 lib/codeql/swift/generated/UnknownLocation.qll e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 e50efefa02a0ec1ff635a00951b5924602fc8cab57e5756e4a039382c69d3882 -lib/codeql/swift/generated/UnspecifiedElement.qll 2b66070944ad36316476b6bf8a811131ca6d4232591353b2b23e881b547463cc c9bff46bcb6f6d106eb57ab8bb04584d9a0b2513abdc1be6e98c0bd227c5f1e0 +lib/codeql/swift/generated/UnspecifiedElement.qll ad04c197266069baf505e529e62751ab3056b4bac5db378fe1f79bbdfa29e066 a5058c7e3e0ba7d52710161e349a71f3e963d4abe07ca581ad663395fc50e972 lib/codeql/swift/generated/decl/AbstractStorageDecl.qll 4e827d05b3b98c043f925a3bd9c00622da3dc6e3d3406f5a18b2c3a684e3774f 47e5767a6f9a87f848cccce651d8c40af8aa3e0e727fc147cbf4d5a2a3e483d9 lib/codeql/swift/generated/decl/AbstractTypeParamDecl.qll 1e268b00d0f2dbbd85aa70ac206c5e4a4612f06ba0091e5253483635f486ccf9 5479e13e99f68f1f347283535f8098964f7fd4a34326ff36ad5711b2de1ab0d0 lib/codeql/swift/generated/decl/Accessor.qll c93cdf7dbb87e6c9b09b5fcf469b952041f753914a892addeb24bb46eaa51d29 1e8104da2da146d3e4d8f5f96b87872e63162e53b46f9c7038c75db51a676599 @@ -409,7 +408,7 @@ lib/codeql/swift/generated/decl/Function.qll 92d1fbceb9e96afd00a1dfbfd15cec0063b lib/codeql/swift/generated/decl/GenericContext.qll 9f7e17d11bf898429a921ba7726b07aab382c97f8326bd186f2bded3d090852c 14d558b6e498d49b850f862d85091a11954dad13f16c60f700cf2c66fa37c473 lib/codeql/swift/generated/decl/GenericTypeDecl.qll 71f5c9c6078567dda0a3ac17e2d2d590454776b2459267e31fed975724f84aec 669c5dbd8fad8daf007598e719ac0b2dbcb4f9fad698bffb6f1d0bcd2cee9102 lib/codeql/swift/generated/decl/GenericTypeParamDecl.qll bc41a9d854e65b1e0da86350870a8fe050eb1dc031cd17ded11c15b5ad8ad183 bc41a9d854e65b1e0da86350870a8fe050eb1dc031cd17ded11c15b5ad8ad183 -lib/codeql/swift/generated/decl/IfConfigDecl.qll 085e2c70d3e158b7f3d3d3ade94593f1331d681d07da8a968c537830a67a62fe 19bb842314e8edb6a8dce4d78ec8043a527f13569da8be4ad03ba876a09998a5 +lib/codeql/swift/generated/decl/IfConfigDecl.qll f1decc68b28dfb43ec70070156d19d6ef0943d8cf375ea639adf13da19398586 75fe6359304693a002987d57865d52b9fca84023752432c98e2f0dbc2830da7e lib/codeql/swift/generated/decl/ImportDecl.qll 542405d7a75659d048d1ff8894a0cc0d357802c2936407ec39b7e4f69d2dd864 41ee9a9f1fc8068db587ac786145cf50f74f74161555ca94b502a57cca23288a lib/codeql/swift/generated/decl/InfixOperatorDecl.qll 3da133c325380fbc10448b731d5826959056ca861d3a0661e7c37694e5ccb208 bb81c8e1597a1fb7e791e3c4c4ed28a73c442591bff2b12d13a7a327a7b6db08 lib/codeql/swift/generated/decl/Initializer.qll a72005f0abebd31b7b91f496ddae8dff49a027ba01b5a827e9b8870ecf34de17 a72005f0abebd31b7b91f496ddae8dff49a027ba01b5a827e9b8870ecf34de17 @@ -484,7 +483,7 @@ lib/codeql/swift/generated/expr/ErrorExpr.qll 8e354eed5655e7261d939f3831eb6fa296 lib/codeql/swift/generated/expr/ExistentialMetatypeToObjectExpr.qll eb0d42aac3f6331011a0e26cf5581c5e0a1b5523d2da94672abdebe70000d65b efe2bc0424e551454acc919abe4dac7fd246b84f1ae0e5d2e31a49cbcf84ce40 lib/codeql/swift/generated/expr/ExplicitCastExpr.qll 162f94461d41cf10a81567e13d5141d7aca417cc92d4ef55de97c7909681882e c8e7d1f569265a9bc2ae6a82e33783ec3ac077c3ae6e582edcb49a4eb816f7b5 lib/codeql/swift/generated/expr/ExplicitClosureExpr.qll c5291fb91e04a99133d1b4caf25f8bd6e7f2e7b9d5d99558143899f4dc9a7861 c5291fb91e04a99133d1b4caf25f8bd6e7f2e7b9d5d99558143899f4dc9a7861 -lib/codeql/swift/generated/expr/Expr.qll 91b45df8d77ece59147e330b1a93515ad791e1da84128a079be2160ee5f87796 4a57263c533d9d5a9e1cacc997d09434fe7ebbabff9ac1a49602b618b828839b +lib/codeql/swift/generated/expr/Expr.qll b09ddd296693ad78a2b0e7dc17d2b746357ae88645b046a026861eafeba616cb 498c628f904fbf48be10f32b146168b71f8f7d9f829614e422020701ccc0f8e4 lib/codeql/swift/generated/expr/FloatLiteralExpr.qll ae851773886b3d33ab5535572a4d6f771d4b11d6c93e802f01348edb2d80c454 35f103436fc2d1b2cec67b5fbae07b28c054c9687d57cbd3245c38c55d8bde0b lib/codeql/swift/generated/expr/ForceTryExpr.qll 062997b5e9a9e993de703856ae6af60fe1950951cf77cdab11b972fb0a5a4ed3 062997b5e9a9e993de703856ae6af60fe1950951cf77cdab11b972fb0a5a4ed3 lib/codeql/swift/generated/expr/ForceValueExpr.qll cd7ee5fa4a6f7094c7fbb9c5831f60d5ce18b123fe7beea3dcb26ca78e387118 7cdef6e9b501f9e9cb0d48828e68b349b25e4e5f312e5bcee91868ae8b196e7d @@ -565,10 +564,10 @@ lib/codeql/swift/generated/pattern/IsPattern.qll c809159dff26b86d44f560742d66e75 lib/codeql/swift/generated/pattern/NamedPattern.qll 5d25e51eb83e86363b95a6531ffb164e5a6070b4a577f3900140edbef0e83c71 9e88b2b2b90a547b402d4782e8d494bc555d4200763c094dd985fe3b7ebc1ec8 lib/codeql/swift/generated/pattern/OptionalSomePattern.qll 5b9c7032584619d4921d1a1324e3ce4bd7207f0d4daa703e1e059f983bf1b132 e6d44514cd123a7ad27f657a2b83d46277a961a849139380ece886430a862920 lib/codeql/swift/generated/pattern/ParenPattern.qll 337cb03dcb7384f7ef13e35d843b3498c0ae391374f5e870d1e52c2d1baacd95 cba288ee99726f5bbf15cf61971e000a835cf6e8b7507dcf6f6c6dea91ec287a -lib/codeql/swift/generated/pattern/Pattern.qll abdb00ae9ee55061de85fa77ecff6f3df9ddf395f45a38dde94983ac423d861a 67ffece7bd83150bb0981b2fda86468c2df7c4d2015526b90ca40c71eec6b542 +lib/codeql/swift/generated/pattern/Pattern.qll 0e96528a8dd87185f4fb23ba33ea418932762127e99739d7e56e5c8988e024d1 ba1e010c9f7f891048fb8c4ff8ea5a6c664c09e43d74b860d559f6459f82554a lib/codeql/swift/generated/pattern/TuplePattern.qll b3a138b0942f7e3eecb52ad2f095584a6cd5f555e9487c6eaad6a5527ae99f0c d6ff67ecc7395571acef4b82da514cb737c72d97ea557d89da534469feda340c lib/codeql/swift/generated/pattern/TypedPattern.qll 6a9fd2815755eddc6918d6be8221c7afb90e4fba4fcb8eb54ff42754269bb481 f198c3b09553a5f5f3d97f8088ef82c00552b9635560750c56d801b09dbd9e26 -lib/codeql/swift/generated/stmt/BraceStmt.qll 72557bdbde907042a936b55039e6032afd5eb92b21a6bb3d669437f3141a7e76 a2fb52f3d77444880edcafec6d107f27cf8c528c21241b1222823136fd4cfbb9 +lib/codeql/swift/generated/stmt/BraceStmt.qll eea1a33767c14a3b96aea6bbe10f17c3ecd1d8ac263de07e475e23b46d85a20d a5ee6c19a38e968c245886c28c82513f39ca90a80a9ea11d0e3139a35f682046 lib/codeql/swift/generated/stmt/BreakStmt.qll 879cf66911cc7f53e7e8f4ae8244681018fb17d6501b269fb7cf9d8481f0b539 c78fc1b0e3e76321fc1653aa8b0aabaaacf082e01a003b78f693b106cc05faa0 lib/codeql/swift/generated/stmt/CaseLabelItem.qll 9536d2909a274c3a969eec25f8e5966adfaa9b0d6451ea6319d9f7bb2fd6fe07 02e25f036db50e9a6e9a7ceab6002dd605b73afb55fa1dee6f22e7af33a40913 lib/codeql/swift/generated/stmt/CaseStmt.qll c180478c6161439bc76bd39edfab343faba7450900ffedcadd3ccea12dc3a08c b537eb517db76113cfbc91c59e6bdfbf16ff83d639dfe6fd6892171f71a97090 @@ -647,7 +646,7 @@ lib/codeql/swift/generated/type/SubstitutableType.qll 9e74ec2d281cd3dedbc5791d66 lib/codeql/swift/generated/type/SugarType.qll 4ea82201ae20e769c0c3e6e158bae86493e1b16bbd3ef6495e2a3760baa1fc6b 6c78df86db6f9c70398484819a9b9ecc8ee337b0a4ac2d84e17294951a6fd788 lib/codeql/swift/generated/type/SyntaxSugarType.qll 253e036452e0ba8ae3bb60d6ed22f4efb8436f4ef19f158f1114a6f9a14df42c 743fe4dede40ca173b19d5757d14e0f606fe36f51119445503e8eea7cf6df3b0 lib/codeql/swift/generated/type/TupleType.qll af224031c3bea6dfca6138903cca940a4f00ba6494ad7b591b9f017d69ee9a6c f59ad1bb4994196ec49836ae169e550a70dbb25a359ff889ed6456882fe2d9a0 -lib/codeql/swift/generated/type/Type.qll ada3973ed840643fa9f015d721d1f3c58994cda46b169e875b77473281d9122f 6a43dc43be0ac6f315b58ca4dc9b015769281eb5011220f28b5e9b6ed9436207 +lib/codeql/swift/generated/type/Type.qll c08acc943c9b52662a465d77fcd39d12f869c42b24a3755225b3bddbb1cf72f5 6d82c5bddded75fd5598bb559ecfa07360ad802d5e9541af2c334dc9d0159335 lib/codeql/swift/generated/type/TypeAliasType.qll 7c1397c4a145d3265e8d1b4dac4ae6a58a2c4026145cfb2d8d28c01309b0ea26 0e3c3a2c166285f4ac1b417b8cc74a5095c8a8e1a102d7b5ca2829a06b61de23 lib/codeql/swift/generated/type/TypeRepr.qll 25a412f029bf2d4b283ea07f0f0ff5713b1b4f369f8cb06991328fdee030e14a 2a39717f2e023c96015b797b59812b0e0bef1ea2780ee83869b68da549abbf2f lib/codeql/swift/generated/type/UnarySyntaxSugarType.qll 6f3822691d04531cc1dd6a78fb184f3e18d42ee324123dc4338fdd368fbd0bd6 d489aac77955de0d71fd5c271fddccd40050db4ef8ce8d817320ca9554057c3a diff --git a/swift/ql/.gitattributes b/swift/ql/.gitattributes index c1bcfc90e69..71cc5c58ecf 100644 --- a/swift/ql/.gitattributes +++ b/swift/ql/.gitattributes @@ -379,7 +379,6 @@ /lib/codeql/swift/generated/Element.qll linguist-generated /lib/codeql/swift/generated/ErrorElement.qll linguist-generated /lib/codeql/swift/generated/File.qll linguist-generated -/lib/codeql/swift/generated/HideableElement.qll linguist-generated /lib/codeql/swift/generated/KeyPathComponent.qll linguist-generated /lib/codeql/swift/generated/Locatable.qll linguist-generated /lib/codeql/swift/generated/Location.qll linguist-generated diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll index ad96fcb12de..9e7975890e6 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll @@ -98,7 +98,7 @@ private predicate isBooleanConstant(ControlFlowElement n, boolean value) { // Boolean constants hidden inside conversions are also // constants that resolve to the same value. exists(ControlFlowElement parent | - parent.asAstNode() = n.asAstNode().(HideableElement).getResolveStep() and + parent.asAstNode() = n.asAstNode().getResolveStep() and isBooleanConstant(parent, value) ) } @@ -122,9 +122,9 @@ private predicate inBooleanContext(ControlFlowElement n) { private predicate astInBooleanContext(AstNode n) { n = any(ConditionElement condElem).getBoolean().getFullyUnresolved() or - n = any(ConditionElement condElem).getAvailability() + n = any(ConditionElement condElem).getAvailability().getFullyUnresolved() or - n = any(StmtCondition stmtCond) + n = any(StmtCondition stmtCond).getFullyUnresolved() or exists(RepeatWhileStmt repeat | n = repeat.getCondition().getFullyConverted()) or diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll index 3efa0dd8bc3..d3eb3aaa244 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll @@ -264,7 +264,7 @@ module Stmts { or child.asAstNode() = ast.getAnElement().getBoolean().getFullyConverted() or - child.asAstNode() = ast.getAnElement().getAvailability() + child.asAstNode() = ast.getAnElement().getAvailability().getFullyUnresolved() } predicate firstElement(int i, ControlFlowElement first) { @@ -278,7 +278,7 @@ module Stmts { astFirst(ast.getElement(i).getBoolean().getFullyConverted(), first) or // ... or an availability check. - astFirst(ast.getElement(i).getAvailability(), first) + astFirst(ast.getElement(i).getAvailability().getFullyUnresolved(), first) ) } @@ -296,7 +296,7 @@ module Stmts { astLast(ast.getElement(i).getBoolean().getFullyConverted(), pred, c) or // ... or the availability check ... - astLast(ast.getElement(i).getAvailability(), pred, c) + astLast(ast.getElement(i).getAvailability().getFullyUnresolved(), pred, c) ) and // We evaluate the next element c instanceof NormalCompletion and @@ -313,7 +313,7 @@ module Stmts { not c.(MatchingCompletion).isMatch() or // Stop if an availability check failed - astLast(ast.getAnElement().getAvailability(), last, c) and + astLast(ast.getAnElement().getAvailability().getFullyUnresolved(), last, c) and c instanceof FalseCompletion or // Stop if we successfully evaluated all the conditionals @@ -322,7 +322,7 @@ module Stmts { or astLast(ast.getLastElement().getPattern().getFullyUnresolved(), last, c) or - astLast(ast.getLastElement().getAvailability(), last, c) + astLast(ast.getLastElement().getAvailability().getFullyUnresolved(), last, c) ) and c instanceof NormalCompletion } @@ -342,14 +342,14 @@ module Stmts { override IfStmt ast; final override predicate propagatesAbnormal(ControlFlowElement child) { - child.asAstNode() = ast.getCondition() or + child.asAstNode() = ast.getCondition().getFullyUnresolved() or child.asAstNode() = ast.getThen() or child.asAstNode() = ast.getElse() } final override predicate last(ControlFlowElement last, Completion c) { // Condition exits with a false completion and there is no `else` branch - astLast(ast.getCondition(), last, c) and + astLast(ast.getCondition().getFullyUnresolved(), last, c) and c instanceof FalseOrNonMatchCompletion and not exists(ast.getElse()) or @@ -360,10 +360,10 @@ module Stmts { final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Pre-order: flow from statement itself to first element of condition pred.asAstNode() = ast and - astFirst(ast.getCondition(), succ) and + astFirst(ast.getCondition().getFullyUnresolved(), succ) and c instanceof SimpleCompletion or - astLast(ast.getCondition(), pred, c) and + astLast(ast.getCondition().getFullyUnresolved(), pred, c) and ( // Flow from last element of condition to first element of then branch c instanceof TrueOrMatchCompletion and @@ -380,7 +380,7 @@ module Stmts { override GuardStmt ast; final override predicate propagatesAbnormal(ControlFlowElement child) { - child.asAstNode() = ast.getCondition() or + child.asAstNode() = ast.getCondition().getFullyUnresolved() or child.asAstNode() = ast.getBody() } @@ -390,18 +390,18 @@ module Stmts { c instanceof NormalCompletion or // Exit when a condition is true - astLast(ast.getCondition(), last, c) and + astLast(ast.getCondition().getFullyUnresolved(), last, c) and c instanceof TrueOrMatchCompletion } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Pre-order: flow from statement itself to first element of condition pred.asAstNode() = ast and - astFirst(ast.getCondition(), succ) and + astFirst(ast.getCondition().getFullyUnresolved(), succ) and c instanceof SimpleCompletion or // Flow to the body when the condition is false - astLast(ast.getCondition(), pred, c) and + astLast(ast.getCondition().getFullyUnresolved(), pred, c) and c instanceof FalseOrNonMatchCompletion and astFirst(ast.getBody(), succ) } @@ -458,7 +458,9 @@ module Stmts { private class WhileTree extends LoopTree { override WhileStmt ast; - final override ControlFlowElement getCondition() { result.asAstNode() = ast.getCondition() } + final override ControlFlowElement getCondition() { + result.asAstNode() = ast.getCondition().getFullyUnresolved() + } final override ControlFlowElement getBody() { result.asAstNode() = ast.getBody() } @@ -672,7 +674,7 @@ module Stmts { final override predicate last(ControlFlowElement last, Completion c) { // Case pattern exits with a non-match - astLast(ast.getLastLabel(), last, c) and + astLast(ast.getLastLabel().getFullyUnresolved(), last, c) and not c.(MatchingCompletion).isMatch() or // Case body exits with any completion @@ -682,18 +684,18 @@ module Stmts { override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Pre-order: Flow from the case statement itself to the first label pred.asAstNode() = ast and - astFirst(ast.getFirstLabel(), succ) and + astFirst(ast.getFirstLabel().getFullyUnresolved(), succ) and c instanceof SimpleCompletion or // Left-to-right evaluation of labels until we find a match exists(int i | - astLast(ast.getLabel(i), pred, c) and - astFirst(ast.getLabel(i + 1), succ) and + astLast(ast.getLabel(i).getFullyUnresolved(), pred, c) and + astFirst(ast.getLabel(i + 1).getFullyUnresolved(), succ) and c.(MatchingCompletion).isNonMatch() ) or // Flow from last element of pattern to first element of body - astLast(ast.getALabel(), pred, c) and + astLast(ast.getALabel().getFullyUnresolved(), pred, c) and astFirst(ast.getBody(), succ) and c.(MatchingCompletion).isMatch() } @@ -1162,7 +1164,7 @@ module Exprs { override CaptureListExpr ast; final override ControlFlowElement getChildElement(int i) { - result.asAstNode() = ast.getBindingDecl(i) + result.asAstNode() = ast.getBindingDecl(i).getFullyUnresolved() or i = ast.getNumberOfBindingDecls() and result.asAstNode() = ast.getClosureBody().getFullyConverted() @@ -1794,7 +1796,9 @@ module AvailabilityInfo { private class AvailabilityInfoTree extends AstStandardPostOrderTree { override AvailabilityInfo ast; - final override ControlFlowElement getChildElement(int i) { result.asAstNode() = ast.getSpec(i) } + final override ControlFlowElement getChildElement(int i) { + result.asAstNode() = ast.getSpec(i).getFullyUnresolved() + } } private class AvailabilitySpecTree extends AstLeafTree { diff --git a/swift/ql/lib/codeql/swift/elements.qll b/swift/ql/lib/codeql/swift/elements.qll index 486b2aa6cd0..7c75c11c976 100644 --- a/swift/ql/lib/codeql/swift/elements.qll +++ b/swift/ql/lib/codeql/swift/elements.qll @@ -10,7 +10,6 @@ import codeql.swift.elements.Diagnostics import codeql.swift.elements.Element import codeql.swift.elements.ErrorElement import codeql.swift.elements.File -import codeql.swift.elements.HideableElement import codeql.swift.elements.KeyPathComponent import codeql.swift.elements.Locatable import codeql.swift.elements.Location diff --git a/swift/ql/lib/codeql/swift/elements/Element.qll b/swift/ql/lib/codeql/swift/elements/Element.qll index b7bdd621eaf..394d1caab3b 100644 --- a/swift/ql/lib/codeql/swift/elements/Element.qll +++ b/swift/ql/lib/codeql/swift/elements/Element.qll @@ -1,7 +1,18 @@ private import codeql.swift.generated.Element class Element extends Generated::Element { + private predicate resolvesFrom(Element e) { e.getResolveStep() = this } + override string toString() { result = this.getPrimaryQlClasses() } + + Element getFullyUnresolved() { + not this.resolvesFrom(_) and result = this + or + exists(Element e | + this.resolvesFrom(e) and + result = e.getFullyUnresolved() + ) + } } class UnknownElement extends Element { diff --git a/swift/ql/lib/codeql/swift/elements/HideableElement.qll b/swift/ql/lib/codeql/swift/elements/HideableElement.qll deleted file mode 100644 index fdc392817dd..00000000000 --- a/swift/ql/lib/codeql/swift/elements/HideableElement.qll +++ /dev/null @@ -1,14 +0,0 @@ -private import codeql.swift.generated.HideableElement - -class HideableElement extends Generated::HideableElement { - private predicate resolvesFrom(HideableElement e) { e.getResolveStep() = this } - - HideableElement getFullyUnresolved() { - not this.resolvesFrom(_) and result = this - or - exists(HideableElement e | - this.resolvesFrom(e) and - result = e.getFullyUnresolved() - ) - } -} diff --git a/swift/ql/lib/codeql/swift/generated/Element.qll b/swift/ql/lib/codeql/swift/generated/Element.qll index 88e9b4cdd34..0fa588e0667 100644 --- a/swift/ql/lib/codeql/swift/generated/Element.qll +++ b/swift/ql/lib/codeql/swift/generated/Element.qll @@ -24,6 +24,23 @@ module Generated { */ final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") } + /** + * Gets the most immediate element that should substitute this element in the explicit AST, if any. + * Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved + * for conversions and syntactic sugar nodes like parentheses. + */ + Element getResolveStep() { none() } // overridden by subclasses + + /** + * Gets the element that should substitute this element in the explicit AST, applying `getResolveStep` + * transitively. + */ + final Element resolve() { + not exists(this.getResolveStep()) and result = this + or + result = this.getResolveStep().resolve() + } + /** * Holds if this element is unknown. */ diff --git a/swift/ql/lib/codeql/swift/generated/HideableElement.qll b/swift/ql/lib/codeql/swift/generated/HideableElement.qll deleted file mode 100644 index 9d8b323313c..00000000000 --- a/swift/ql/lib/codeql/swift/generated/HideableElement.qll +++ /dev/null @@ -1,25 +0,0 @@ -// generated by codegen/codegen.py -private import codeql.swift.generated.Synth -private import codeql.swift.generated.Raw -import codeql.swift.elements.Element - -module Generated { - class HideableElement extends Synth::THideableElement, Element { - /** - * Gets the most immediate element that should substitute this element in the explicit AST, if any. - * Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved - * for conversions and syntactic sugar nodes like parentheses. - */ - HideableElement getResolveStep() { none() } // overridden by subclasses - - /** - * Gets the element that should substitute this element in the explicit AST, applying `getResolveStep` - * transitively. - */ - final HideableElement resolve() { - not exists(this.getResolveStep()) and result = this - or - result = this.getResolveStep().resolve() - } - } -} diff --git a/swift/ql/lib/codeql/swift/generated/ParentChild.qll b/swift/ql/lib/codeql/swift/generated/ParentChild.qll index 61b61ab0459..ab0ce2dba37 100644 --- a/swift/ql/lib/codeql/swift/generated/ParentChild.qll +++ b/swift/ql/lib/codeql/swift/generated/ParentChild.qll @@ -50,21 +50,6 @@ private module Impl { ) } - private Element getImmediateChildOfHideableElement( - HideableElement e, int index, string partialPredicateCall - ) { - exists(int b, int bElement, int n | - b = 0 and - bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and - n = bElement and - ( - none() - or - result = getImmediateChildOfElement(e, index - b, partialPredicateCall) - ) - ) - } - private Element getImmediateChildOfLocatable(Locatable e, int index, string partialPredicateCall) { exists(int b, int bElement, int n | b = 0 and @@ -1043,19 +1028,14 @@ private module Impl { } private Element getImmediateChildOfExpr(Expr e, int index, string partialPredicateCall) { - exists(int b, int bAstNode, int bHideableElement, int n | + exists(int b, int bAstNode, int n | b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and - bHideableElement = - bAstNode + 1 + - max(int i | i = -1 or exists(getImmediateChildOfHideableElement(e, i, _)) | i) and - n = bHideableElement and + n = bAstNode and ( none() or result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) - or - result = getImmediateChildOfHideableElement(e, index - bAstNode, partialPredicateCall) ) ) } @@ -3179,19 +3159,14 @@ private module Impl { } private Element getImmediateChildOfPattern(Pattern e, int index, string partialPredicateCall) { - exists(int b, int bAstNode, int bHideableElement, int n | + exists(int b, int bAstNode, int n | b = 0 and bAstNode = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAstNode(e, i, _)) | i) and - bHideableElement = - bAstNode + 1 + - max(int i | i = -1 or exists(getImmediateChildOfHideableElement(e, i, _)) | i) and - n = bHideableElement and + n = bAstNode and ( none() or result = getImmediateChildOfAstNode(e, index - b, partialPredicateCall) - or - result = getImmediateChildOfHideableElement(e, index - bAstNode, partialPredicateCall) ) ) } @@ -3481,13 +3456,13 @@ private module Impl { b = 0 and bStmt = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfStmt(e, i, _)) | i) and n = bStmt and - nElement = n + 1 + max(int i | i = -1 or exists(e.getElement(i)) | i) and + nElement = n + 1 + max(int i | i = -1 or exists(e.getImmediateElement(i)) | i) and ( none() or result = getImmediateChildOfStmt(e, index - b, partialPredicateCall) or - result = e.getElement(index - n) and + result = e.getImmediateElement(index - n) and partialPredicateCall = "Element(" + (index - n).toString() + ")" ) ) @@ -3854,15 +3829,14 @@ private module Impl { } private Element getImmediateChildOfType(Type e, int index, string partialPredicateCall) { - exists(int b, int bHideableElement, int n | + exists(int b, int bElement, int n | b = 0 and - bHideableElement = - b + 1 + max(int i | i = -1 or exists(getImmediateChildOfHideableElement(e, i, _)) | i) and - n = bHideableElement and + bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and + n = bElement and ( none() or - result = getImmediateChildOfHideableElement(e, index - b, partialPredicateCall) + result = getImmediateChildOfElement(e, index - b, partialPredicateCall) ) ) } @@ -5319,10 +5293,6 @@ private module Impl { or result = getImmediateChildOfVariadicSequenceType(e, index, partialAccessor) } - - Element resolve(Element e) { - if e instanceof HideableElement then result = e.(HideableElement).resolve() else result = e - } } /** @@ -5350,7 +5320,7 @@ Element getImmediateChildAndAccessor(Element e, int index, string accessor) { */ Element getChildAndAccessor(Element e, int index, string accessor) { exists(string partialAccessor | - result = Impl::resolve(Impl::getImmediateChild(e, index, partialAccessor)) and + result = Impl::getImmediateChild(e, index, partialAccessor).resolve() and accessor = "get" + partialAccessor ) } diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index f7c127818d7..dc5ddeed979 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -62,11 +62,6 @@ module Raw { predicate isSuccessfullyExtracted() { file_is_successfully_extracted(this) } } - /** - * INTERNAL: Do not use. - */ - class HideableElement extends @hideable_element, Element { } - /** * INTERNAL: Do not use. */ @@ -991,7 +986,7 @@ module Raw { * INTERNAL: Do not use. * The base class for all expressions in Swift. */ - class Expr extends @expr, AstNode, HideableElement { + class Expr extends @expr, AstNode { /** * Gets the type of this expression, if it exists. */ @@ -2358,7 +2353,7 @@ module Raw { /** * INTERNAL: Do not use. */ - class Pattern extends @pattern, AstNode, HideableElement { } + class Pattern extends @pattern, AstNode { } /** * INTERNAL: Do not use. @@ -2874,7 +2869,7 @@ module Raw { /** * INTERNAL: Do not use. */ - class Type extends @type, HideableElement { + class Type extends @type, Element { /** * Gets the name of this type. */ diff --git a/swift/ql/lib/codeql/swift/generated/Synth.qll b/swift/ql/lib/codeql/swift/generated/Synth.qll index f79d71f84a3..fdbadffcd33 100644 --- a/swift/ql/lib/codeql/swift/generated/Synth.qll +++ b/swift/ql/lib/codeql/swift/generated/Synth.qll @@ -1043,11 +1043,6 @@ module Synth { */ class TFile = TDbFile or TUnknownFile; - /** - * INTERNAL: Do not use. - */ - class THideableElement = TExpr or TPattern or TType; - /** * INTERNAL: Do not use. */ @@ -3228,11 +3223,11 @@ module Synth { or result = convertGenericContextFromRaw(e) or - result = convertHideableElementFromRaw(e) - or result = convertLocatableFromRaw(e) or result = convertLocationFromRaw(e) + or + result = convertTypeFromRaw(e) } /** @@ -3277,19 +3272,6 @@ module Synth { result = convertUnknownFileFromRaw(e) } - /** - * INTERNAL: Do not use. - * Converts a raw DB element to a synthesized `THideableElement`, if possible. - */ - cached - THideableElement convertHideableElementFromRaw(Raw::Element e) { - result = convertExprFromRaw(e) - or - result = convertPatternFromRaw(e) - or - result = convertTypeFromRaw(e) - } - /** * INTERNAL: Do not use. * Converts a raw DB element to a synthesized `TLocatable`, if possible. @@ -6046,11 +6028,11 @@ module Synth { or result = convertGenericContextToRaw(e) or - result = convertHideableElementToRaw(e) - or result = convertLocatableToRaw(e) or result = convertLocationToRaw(e) + or + result = convertTypeToRaw(e) } /** @@ -6095,19 +6077,6 @@ module Synth { result = convertUnknownFileToRaw(e) } - /** - * INTERNAL: Do not use. - * Converts a synthesized `THideableElement` to a raw DB element, if possible. - */ - cached - Raw::Element convertHideableElementToRaw(THideableElement e) { - result = convertExprToRaw(e) - or - result = convertPatternToRaw(e) - or - result = convertTypeToRaw(e) - } - /** * INTERNAL: Do not use. * Converts a synthesized `TLocatable` to a raw DB element, if possible. diff --git a/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll b/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll index af422cbd10d..7a5c1b5903f 100644 --- a/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll +++ b/swift/ql/lib/codeql/swift/generated/UnspecifiedElement.qll @@ -10,14 +10,27 @@ module Generated { /** * Gets the parent of this unspecified element, if it exists. + * + * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the + * behavior of both the `Immediate` and non-`Immediate` versions. */ - Element getParent() { + Element getImmediateParent() { result = Synth::convertElementFromRaw(Synth::convertUnspecifiedElementToRaw(this) .(Raw::UnspecifiedElement) .getParent()) } + /** + * Gets the parent of this unspecified element, if it exists. + */ + final Element getParent() { + exists(Element immediate | + immediate = this.getImmediateParent() and + result = immediate.resolve() + ) + } + /** * Holds if `getParent()` exists. */ diff --git a/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll index 9a93bce7540..aec001a1122 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll @@ -10,14 +10,27 @@ module Generated { /** * Gets the `index`th active element of this if config declaration (0-based). + * + * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the + * behavior of both the `Immediate` and non-`Immediate` versions. */ - AstNode getActiveElement(int index) { + AstNode getImmediateActiveElement(int index) { result = Synth::convertAstNodeFromRaw(Synth::convertIfConfigDeclToRaw(this) .(Raw::IfConfigDecl) .getActiveElement(index)) } + /** + * Gets the `index`th active element of this if config declaration (0-based). + */ + final AstNode getActiveElement(int index) { + exists(AstNode immediate | + immediate = this.getImmediateActiveElement(index) and + result = immediate.resolve() + ) + } + /** * Gets any of the active elements of this if config declaration. */ diff --git a/swift/ql/lib/codeql/swift/generated/expr/Expr.qll b/swift/ql/lib/codeql/swift/generated/expr/Expr.qll index 6f488acbe59..dad004bc2bd 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/Expr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/Expr.qll @@ -2,14 +2,13 @@ private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw import codeql.swift.elements.AstNode -import codeql.swift.elements.HideableElement import codeql.swift.elements.type.Type module Generated { /** * The base class for all expressions in Swift. */ - class Expr extends Synth::TExpr, AstNode, HideableElement { + class Expr extends Synth::TExpr, AstNode { /** * Gets the type of this expression, if it exists. * diff --git a/swift/ql/lib/codeql/swift/generated/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/Pattern.qll index 5ba24c9fcda..5c795e45107 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/Pattern.qll @@ -2,8 +2,7 @@ private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw import codeql.swift.elements.AstNode -import codeql.swift.elements.HideableElement module Generated { - class Pattern extends Synth::TPattern, AstNode, HideableElement { } + class Pattern extends Synth::TPattern, AstNode { } } diff --git a/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll index 360366dcaa3..d136e02df08 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll @@ -10,14 +10,27 @@ module Generated { /** * Gets the `index`th element of this brace statement (0-based). + * + * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the + * behavior of both the `Immediate` and non-`Immediate` versions. */ - AstNode getElement(int index) { + AstNode getImmediateElement(int index) { result = Synth::convertAstNodeFromRaw(Synth::convertBraceStmtToRaw(this) .(Raw::BraceStmt) .getElement(index)) } + /** + * Gets the `index`th element of this brace statement (0-based). + */ + final AstNode getElement(int index) { + exists(AstNode immediate | + immediate = this.getImmediateElement(index) and + result = immediate.resolve() + ) + } + /** * Gets any of the elements of this brace statement. */ diff --git a/swift/ql/lib/codeql/swift/generated/type/Type.qll b/swift/ql/lib/codeql/swift/generated/type/Type.qll index 7f09e7d7e94..a3074fdd4d3 100644 --- a/swift/ql/lib/codeql/swift/generated/type/Type.qll +++ b/swift/ql/lib/codeql/swift/generated/type/Type.qll @@ -1,10 +1,10 @@ // generated by codegen/codegen.py private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw -import codeql.swift.elements.HideableElement +import codeql.swift.elements.Element module Generated { - class Type extends Synth::TType, HideableElement { + class Type extends Synth::TType, Element { /** * Gets the name of this type. */ diff --git a/swift/ql/lib/codeql/swift/printast/PrintAstNode.qll b/swift/ql/lib/codeql/swift/printast/PrintAstNode.qll index dc6af553f43..57e68648636 100644 --- a/swift/ql/lib/codeql/swift/printast/PrintAstNode.qll +++ b/swift/ql/lib/codeql/swift/printast/PrintAstNode.qll @@ -66,7 +66,7 @@ private string prettyPrint(Locatable e) { result = "[" + concat(e.getPrimaryQlClasses(), ", ") + "] " + e } -private class Unresolved extends HideableElement, Locatable { +private class Unresolved extends Locatable { Unresolved() { this != this.resolve() } } @@ -89,7 +89,7 @@ class PrintLocatable extends PrintAstNode, TLocatable { // use even indexes for normal children, leaving odd slots for conversions if any child = TLocatable(c) and index = 2 * i and label = accessor or - child = TLocatable(c.(HideableElement).getFullyUnresolved().(Unresolved)) and + child = TLocatable(c.getFullyUnresolved().(Unresolved)) and index = 2 * i + 1 and ( if c instanceof Expr diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 37e784cc154..ba4171b90d0 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -15,9 +15,9 @@ sourceLocationPrefix( @callable | @file | @generic_context -| @hideable_element | @locatable | @location +| @type ; #keyset[id] @@ -77,12 +77,6 @@ file_is_successfully_extracted( int id: @file ref ); -@hideable_element = - @expr -| @pattern -| @type -; - @locatable = @argument | @ast_node diff --git a/swift/schema.py b/swift/schema.py index 76ac53dcb5c..5f000b32a8c 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -72,12 +72,9 @@ class UnknownLocation(Location): class AstNode(Locatable): pass -@ql.hideable -class HideableElement(Element): - pass - @group("type") -class Type(HideableElement): +@ql.hideable +class Type(Element): name: string canonical_type: "Type" @@ -87,12 +84,14 @@ class Decl(AstNode): members: list["Decl"] | child @group("expr") -class Expr(AstNode, HideableElement): +@ql.hideable +class Expr(AstNode): """The base class for all expressions in Swift.""" type: optional[Type] @group("pattern") -class Pattern(AstNode, HideableElement): +@ql.hideable +class Pattern(AstNode): pass @group("stmt") From 99c211955b2b00a9c95914b835f8ab6a0e3bcb52 Mon Sep 17 00:00:00 2001 From: Chris Smowton <smowton@github.com> Date: Tue, 23 May 2023 14:31:25 +0100 Subject: [PATCH 081/739] Hotfix: Go: exclude method receivers from dead-store-of-field query --- go/ql/src/RedundantCode/DeadStoreOfField.ql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/ql/src/RedundantCode/DeadStoreOfField.ql b/go/ql/src/RedundantCode/DeadStoreOfField.ql index 9dd2c4de65c..edc1d62cb00 100644 --- a/go/ql/src/RedundantCode/DeadStoreOfField.ql +++ b/go/ql/src/RedundantCode/DeadStoreOfField.ql @@ -38,6 +38,9 @@ predicate escapes(DataFlow::Node nd) { // if `nd` is passed to a function, then it escapes nd = any(DataFlow::CallNode c).getASyntacticArgument() or + // if `nd` is the receiver of a function, then it escapes + nd = any(DataFlow::MethodCallNode c).getReceiver() + or // if `nd` has its address taken, then it escapes exists(AddressExpr ae | nd.asExpr() = ae.getOperand()) or From 9b4914c3f6c3e4c90021ad9c54974ca8623e4be1 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 23 May 2023 13:47:23 +0100 Subject: [PATCH 082/739] Ruby: split ActionDispatch modelling into multiple component files --- .../codeql/ruby/frameworks/ActionDispatch.qll | 1003 +---------------- .../ruby/frameworks/actiondispatch/Mime.qll | 46 + .../frameworks/actiondispatch/Routing.qll | 961 ++++++++++++++++ 3 files changed, 1010 insertions(+), 1000 deletions(-) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Mime.qll create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Routing.qll diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll index cc898abe034..c8720d5f1dc 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll @@ -3,1010 +3,13 @@ * Version: 7.1.0. */ -private import codeql.ruby.AST -private import codeql.ruby.Concepts -private import codeql.ruby.DataFlow -private import codeql.ruby.Regexp as RE -private import codeql.ruby.dataflow.FlowSummary -private import codeql.ruby.frameworks.data.ModelsAsData - /** * Models the `ActionDispatch` HTTP library, which is part of Rails. * Version: 7.1.0. */ module ActionDispatch { - /** - * Type summaries for the `Mime::Type` class, i.e. method calls that produce new - * `Mime::Type` instances. - */ - private class MimeTypeTypeSummary extends ModelInput::TypeModelCsv { - override predicate row(string row) { - // type1;type2;path - row = - [ - // Mime[type] : Mime::Type (omitted) - // Method names with brackets like [] cannot be represented in MaD. - // Mime.fetch(type) : Mime::Type - "Mime::Type;Mime!;Method[fetch].ReturnValue", - // Mime::Type.lookup(str) : Mime::Type - "Mime::Type;Mime::Type!;Method[lookup].ReturnValue", - // Mime::Type.lookup_by_extension(str) : Mime::Type - "Mime::Type;Mime::Type!;Method[lookup_by_extension].ReturnValue", - // Mime::Type.register(str) : Mime::Type - "Mime::Type;Mime::Type!;Method[register].ReturnValue", - // Mime::Type.register_alias(str) : Mime::Type - "Mime::Type;Mime::Type!;Method[register_alias].ReturnValue", - ] - } - } + private import actiondispatch.Mime + import actiondispatch.Routing - /** - * An argument to `Mime::Type#match?`, which is converted to a RegExp via - * `Regexp.new`. - */ - class MimeTypeMatchRegExpInterpretation extends RE::RegExpInterpretation::Range { - MimeTypeMatchRegExpInterpretation() { - this = ModelOutput::getATypeNode("Mime::Type").getAMethodCall(["match?", "=~"]).getArgument(0) - } - } - - /** - * Models routing configuration specified using the `ActionDispatch` library, which is part of Rails. - */ - module Routing { - /** - * A block that defines some routes. - * Route blocks can contribute to the path or controller namespace of their child routes. - * For example, in the block below - * ```rb - * scope path: "/admin" do - * get "/dashboard", to: "admin_dashboard#show" - * end - * ``` - * the route defined by the call to `get` has the full path `/admin/dashboard`. - * We track these contributions via `getPathComponent` and `getControllerComponent`. - */ - abstract private class RouteBlock extends TRouteBlock { - /** - * Gets the name of a primary CodeQL class to which this route block belongs. - */ - string getAPrimaryQlClass() { result = "RouteBlock" } - - /** - * Gets a string representation of this route block. - */ - string toString() { none() } - - /** - * Gets a `Stmt` within this route block. - */ - abstract Stmt getAStmt(); - - /** - * Gets the parent of this route block, if one exists. - */ - abstract RouteBlock getParent(); - - /** - * Gets the `n`th parent of this route block. - * The zeroth parent is this block, the first parent is the direct parent of this block, etc. - */ - RouteBlock getParent(int n) { - if n = 0 then result = this else result = this.getParent().getParent(n - 1) - } - - /** - * Gets the component of the path defined by this block, if it exists. - */ - abstract string getPathComponent(); - - /** - * Gets the component of the controller namespace defined by this block, if it exists. - */ - abstract string getControllerComponent(); - - /** - * Gets the location of this route block. - */ - abstract Location getLocation(); - } - - /** - * A route block that is not the top-level block. - * This block will always have a parent. - */ - abstract private class NestedRouteBlock extends RouteBlock { - RouteBlock parent; - - override RouteBlock getParent() { result = parent } - - override string getAPrimaryQlClass() { result = "NestedRouteBlock" } - } - - /** - * A top-level routes block. - * ```rb - * Rails.application.routes.draw do - * ... - * end - * ``` - */ - private class TopLevelRouteBlock extends RouteBlock, TTopLevelRouteBlock { - MethodCall call; - // Routing blocks create scopes which define the namespace for controllers and paths, - // though they can be overridden in various ways. - // The namespaces can differ, so we track them separately. - Block block; - - TopLevelRouteBlock() { this = TTopLevelRouteBlock(_, call, block) } - - override string getAPrimaryQlClass() { result = "TopLevelRouteBlock" } - - Block getBlock() { result = block } - - override Stmt getAStmt() { result = block.getAStmt() } - - override RouteBlock getParent() { none() } - - override string toString() { result = call.toString() } - - override Location getLocation() { result = call.getLocation() } - - override string getPathComponent() { none() } - - override string getControllerComponent() { none() } - } - - /** - * A route block defined by a call to `constraints`. - * ```rb - * constraints(foo: /some_regex/) do - * get "/posts/:foo", to "posts#something" - * end - * ``` - * https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-constraints - */ - private class ConstraintsRouteBlock extends NestedRouteBlock, TConstraintsRouteBlock { - private Block block; - private MethodCall call; - - ConstraintsRouteBlock() { this = TConstraintsRouteBlock(parent, call, block) } - - override string getAPrimaryQlClass() { result = "ConstraintsRouteBlock" } - - override Stmt getAStmt() { result = block.getAStmt() } - - override string getPathComponent() { result = "" } - - override string getControllerComponent() { result = "" } - - override string toString() { result = call.toString() } - - override Location getLocation() { result = call.getLocation() } - } - - /** - * A route block defined by a call to `scope`. - * ```rb - * scope(path: "/some_path", module: "some_module") do - * get "/posts/:foo", to "posts#something" - * end - * ``` - * https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-scope - */ - private class ScopeRouteBlock extends NestedRouteBlock, TScopeRouteBlock { - private MethodCall call; - private Block block; - - ScopeRouteBlock() { this = TScopeRouteBlock(parent, call, block) } - - override string getAPrimaryQlClass() { result = "ScopeRouteBlock" } - - override Stmt getAStmt() { result = block.getAStmt() } - - override string toString() { result = call.toString() } - - override Location getLocation() { result = call.getLocation() } - - override string getPathComponent() { - call.getKeywordArgument("path").getConstantValue().isStringlikeValue(result) - or - not exists(call.getKeywordArgument("path")) and - call.getArgument(0).getConstantValue().isStringlikeValue(result) - } - - override string getControllerComponent() { - call.getKeywordArgument(["controller", "module"]) - .getConstantValue() - .isStringlikeValue(result) - } - } - - /** - * A route block defined by a call to `resources`. - * ```rb - * resources :articles do - * get "/comments", to "comments#index" - * end - * ``` - * https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-resources - */ - private class ResourcesRouteBlock extends NestedRouteBlock, TResourcesRouteBlock { - private MethodCall call; - private Block block; - - ResourcesRouteBlock() { this = TResourcesRouteBlock(parent, call, block) } - - override string getAPrimaryQlClass() { result = "ResourcesRouteBlock" } - - override Stmt getAStmt() { result = block.getAStmt() } - - /** - * Gets the `resources` call that gives rise to this route block. - */ - MethodCall getDefiningMethodCall() { result = call } - - override string getPathComponent() { - exists(string resource | - call.getArgument(0).getConstantValue().isStringlikeValue(resource) - | - result = resource + "/:" + singularize(resource) + "_id" - ) - } - - override string getControllerComponent() { result = "" } - - override string toString() { result = call.toString() } - - override Location getLocation() { result = call.getLocation() } - } - - /** - * A route block that is guarded by a conditional statement. - * For example: - * ```rb - * if Rails.env.test? - * get "/foo/bar", to: "foo#bar" - * end - * ``` - * We ignore the condition and analyze both branches to obtain as - * much routing information as possible. - */ - private class ConditionalRouteBlock extends NestedRouteBlock, TConditionalRouteBlock { - private ConditionalExpr e; - - ConditionalRouteBlock() { this = TConditionalRouteBlock(parent, e) } - - override string getAPrimaryQlClass() { result = "ConditionalRouteBlock" } - - override Stmt getAStmt() { result = e.getBranch(_).(StmtSequence).getAStmt() } - - override string getPathComponent() { none() } - - override string getControllerComponent() { none() } - - override string toString() { result = e.toString() } - - override Location getLocation() { result = e.getLocation() } - } - - /** - * A route block defined by a call to `namespace`. - * ```rb - * namespace :admin do - * resources :posts - * end - * ``` - * https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-namespace - */ - private class NamespaceRouteBlock extends NestedRouteBlock, TNamespaceRouteBlock { - private MethodCall call; - private Block block; - - NamespaceRouteBlock() { this = TNamespaceRouteBlock(parent, call, block) } - - override Stmt getAStmt() { result = block.getAStmt() } - - override string getPathComponent() { result = this.getNamespace() } - - override string getControllerComponent() { result = this.getNamespace() } - - private string getNamespace() { - call.getArgument(0).getConstantValue().isStringlikeValue(result) - } - - override string toString() { result = call.toString() } - - override Location getLocation() { result = call.getLocation() } - } - - /** - * A route configuration. This defines a combination of HTTP method and URL - * path which should be routed to a particular controller-action pair. - * This can arise from an explicit call to a routing method, for example: - * ```rb - * get "/photos", to: "photos#index" - * ``` - * or via a convenience method like `resources`, which defines multiple routes at once: - * ```rb - * resources :photos - * ``` - */ - class Route extends TRoute instanceof RouteImpl { - /** - * Gets the name of a primary CodeQL class to which this route belongs. - */ - string getAPrimaryQlClass() { result = "Route" } - - /** Gets a string representation of this route. */ - string toString() { result = super.toString() } - - /** - * Gets the location of the method call that defines this route. - */ - Location getLocation() { result = super.getLocation() } - - /** - * Gets the full controller targeted by this route. - */ - string getController() { result = super.getController() } - - /** - * Gets the action targeted by this route. - */ - string getAction() { result = super.getAction() } - - /** - * Gets the HTTP method of this route. - * The result is one of [get, post, put, patch, delete]. - */ - string getHttpMethod() { result = super.getHttpMethod() } - - /** - * Gets the full path of the route. - */ - string getPath() { result = super.getPath() } - - /** - * Get a URL capture. This is a wildcard URL segment whose value is placed in `params`. - * For example, in - * ```ruby - * get "/foo/:bar/baz", to: "users#index" - * ``` - * the capture is `:bar`. - */ - string getACapture() { result = super.getACapture() } - } - - /** - * The implementation of `Route`. - * This class is abstract and is thus kept private so we don't expose it to - * users. - * Extend this class to add new instances of routes. - */ - abstract private class RouteImpl extends TRoute { - /** - * Gets the name of a primary CodeQL class to which this route belongs. - */ - string getAPrimaryQlClass() { result = "RouteImpl" } - - MethodCall method; - - /** Gets a string representation of this route. */ - string toString() { result = method.toString() } - - /** - * Gets the location of the method call that defines this route. - */ - Location getLocation() { result = method.getLocation() } - - /** - * Gets the method call that defines this route. - */ - MethodCall getDefiningMethodCall() { result = method } - - /** - * Get the last component of the path. For example, in - * ```rb - * get "/photos", to: "photos#index" - * ``` - * this is `/photos`. - * If the string has any interpolations, this predicate will have no result. - */ - abstract string getLastPathComponent(); - - /** - * Gets the HTTP method of this route. - * The result is one of [get, post, put, patch, delete]. - */ - abstract string getHttpMethod(); - - /** - * Gets the last controller component. - * This is the controller specified in the route itself. - */ - abstract string getLastControllerComponent(); - - /** - * Gets a component of the controller. - * This behaves identically to `getPathComponent`, but for controller information. - */ - string getControllerComponent(int n) { - if n = 0 - then result = this.getLastControllerComponent() - else result = this.getParentBlock().getParent(n - 1).getControllerComponent() - } - - /** - * Gets the full controller targeted by this route. - */ - string getController() { - result = - concat(int n | - this.getControllerComponent(n) != "" - | - this.getControllerComponent(n), "/" order by n desc - ) - } - - /** - * Gets the action targeted by this route. - */ - abstract string getAction(); - - /** - * Gets the parent `RouteBlock` of this route. - */ - abstract RouteBlock getParentBlock(); - - /** - * Gets a component of the path. Components are numbered from 0 up, where 0 - * is the last component, 1 is the second-last, etc. - * For example, in the following route: - * - * ```rb - * namespace path: "foo" do - * namespace path: "bar" do - * get "baz", to: "foo#bar - * end - * end - * ``` - * - * the components are: - * - * | n | component - * |---|---------- - * | 0 | baz - * | 1 | bar - * | 2 | foo - */ - string getPathComponent(int n) { - if n = 0 - then result = this.getLastPathComponent() - else result = this.getParentBlock().getParent(n - 1).getPathComponent() - } - - /** - * Gets the full path of the route. - */ - string getPath() { - result = - concat(int n | - this.getPathComponent(n) != "" - | - // Strip leading and trailing slashes from each path component before combining - stripSlashes(this.getPathComponent(n)), "/" order by n desc - ) - } - - /** - * Get a URL capture. This is a wildcard URL segment whose value is placed in `params`. - * For example, in - * ```ruby - * get "/foo/:bar/baz", to: "users#index" - * ``` - * the capture is `:bar`. - * We don't currently make use of this, but it may be useful in future to more accurately - * model the contents of the `params` hash. - */ - string getACapture() { result = this.getPathComponent(_).regexpFind(":[^:/]+", _, _) } - } - - /** - * A route generated by an explicit call to `get`, `post`, etc. - * - * ```ruby - * get "/photos", to: "photos#index" - * put "/photos/:id", to: "photos#update" - * ``` - */ - private class ExplicitRoute extends RouteImpl, TExplicitRoute { - RouteBlock parentBlock; - - ExplicitRoute() { this = TExplicitRoute(parentBlock, method) } - - override string getAPrimaryQlClass() { result = "ExplicitRoute" } - - override RouteBlock getParentBlock() { result = parentBlock } - - override string getLastPathComponent() { - method.getArgument(0).getConstantValue().isStringlikeValue(result) - } - - override string getLastControllerComponent() { - method.getKeywordArgument("controller").getConstantValue().isStringlikeValue(result) - or - not exists(method.getKeywordArgument("controller")) and - ( - result = extractController(this.getActionString()) - or - // If controller is not specified, and we're in a `resources` route block, use the controller of that route. - // For example, in - // - // resources :posts do - // get "timestamp", to: :timestamp - // end - // - // The route is GET /posts/:post_id/timestamp => posts/timestamp - not exists(extractController(this.getActionString())) and - exists(ResourcesRoute r | - r.getDefiningMethodCall() = parentBlock.(ResourcesRouteBlock).getDefiningMethodCall() - | - result = r.getLastControllerComponent() - ) - ) - } - - private string getActionString() { - method.getKeywordArgument("to").getConstantValue().isStringlikeValue(result) - or - method.getKeywordArgument("to").(MethodCall).getMethodName() = "redirect" and - result = "<redirect>#<redirect>" - } - - override string getAction() { - // get "/photos", action: "index" - method.getKeywordArgument("action").getConstantValue().isStringlikeValue(result) - or - not exists(method.getKeywordArgument("action")) and - ( - // get "/photos", to: "photos#index" - // get "/photos", to: redirect("some_url") - result = extractAction(this.getActionString()) - or - // resources :photos, only: [] do - // get "/", to: "index" - // end - not exists(extractAction(this.getActionString())) and result = this.getActionString() - or - // get :some_action - not exists(this.getActionString()) and - method.getArgument(0).getConstantValue().isStringlikeValue(result) - ) - } - - override string getHttpMethod() { result = method.getMethodName().toString() } - } - - /** - * A route generated by a call to `resources`. - * - * ```ruby - * resources :photos - * ``` - * This creates eight routes, equivalent to the following code: - * ```ruby - * get "/photos", to: "photos#index" - * get "/photos/new", to: "photos#new" - * post "/photos", to: "photos#create" - * get "/photos/:id", to: "photos#show" - * get "/photos/:id/edit", to: "photos#edit" - * patch "/photos/:id", to: "photos#update" - * put "/photos/:id", to: "photos#update" - * delete "/photos/:id", to: "photos#delete" - * ``` - * - * `resources` can take a block. Any routes defined inside the block will inherit a path component of - * `/<resource>/:<resource>_id`. For example: - * - * ```ruby - * resources :photos do - * get "/foo", to: "photos#foo" - * end - * ``` - * This creates the eight default routes, plus one more, which is nested under "/photos/:photo_id", equivalent to: - * ```ruby - * get "/photos/:photo_id/foo", to: "photos#foo" - * ``` - */ - private class ResourcesRoute extends RouteImpl, TResourcesRoute { - RouteBlock parent; - string action; - string httpMethod; - string pathComponent; - - ResourcesRoute() { - exists(string resource | - this = TResourcesRoute(parent, method, action) and - method.getArgument(0).getConstantValue().isStringlikeValue(resource) and - isDefaultResourceRoute(resource, httpMethod, pathComponent, action) - ) - } - - override string getAPrimaryQlClass() { result = "ResourcesRoute" } - - override RouteBlock getParentBlock() { result = parent } - - override string getLastPathComponent() { result = pathComponent } - - override string getLastControllerComponent() { - method.getArgument(0).getConstantValue().isStringlikeValue(result) - } - - override string getAction() { result = action } - - override string getHttpMethod() { result = httpMethod } - } - - /** - * A route generated by a call to `resource`. - * This is like a `resources` route, but creates routes for a singular resource. - * This means there's no index route, no id parameter, and the resource name is expected to be singular. - * It will still be routed to a pluralised controller name. - * ```ruby - * resource :account - * ``` - */ - private class SingularResourceRoute extends RouteImpl, TResourceRoute { - RouteBlock parent; - string action; - string httpMethod; - string pathComponent; - - SingularResourceRoute() { - exists(string resource | - this = TResourceRoute(parent, method, action) and - method.getArgument(0).getConstantValue().isStringlikeValue(resource) and - isDefaultSingularResourceRoute(resource, httpMethod, pathComponent, action) - ) - } - - override string getAPrimaryQlClass() { result = "SingularResourceRoute" } - - override RouteBlock getParentBlock() { result = parent } - - override string getLastPathComponent() { result = pathComponent } - - override string getLastControllerComponent() { - method.getArgument(0).getConstantValue().isStringlikeValue(result) - } - - override string getAction() { result = action } - - override string getHttpMethod() { result = httpMethod } - } - - /** - * A route generated by a call to `match`. - * This is a lower level primitive that powers `get`, `post` etc. - * The first argument can be a path or a (path, controller-action) pair. - * The controller, action and HTTP method can be specified with the - * `controller:`, `action:` and `via:` keyword arguments, respectively. - * ```ruby - * match 'photos/:id' => 'photos#show', via: :get - * match 'photos/:id', to: 'photos#show', via: :get - * match 'photos/:id', to 'photos#show', via: [:get, :post] - * match 'photos/:id', controller: 'photos', action: 'show', via: :get - * ``` - */ - private class MatchRoute extends RouteImpl, TMatchRoute { - private RouteBlock parent; - - MatchRoute() { this = TMatchRoute(parent, method) } - - override string getAPrimaryQlClass() { result = "MatchRoute" } - - override RouteBlock getParentBlock() { result = parent } - - override string getLastPathComponent() { - [method.getArgument(0), method.getArgument(0).(Pair).getKey()] - .getConstantValue() - .isStringlikeValue(result) - } - - override string getLastControllerComponent() { - result = - extractController(method.getKeywordArgument("to").getConstantValue().getStringlikeValue()) or - method.getKeywordArgument("controller").getConstantValue().isStringlikeValue(result) or - result = - extractController(method - .getArgument(0) - .(Pair) - .getValue() - .getConstantValue() - .getStringlikeValue()) - } - - override string getHttpMethod() { - exists(string via | - method.getKeywordArgument("via").getConstantValue().isStringlikeValue(via) - | - via = "all" and result = anyHttpMethod() - or - via != "all" and result = via - ) - or - result = - method - .getKeywordArgument("via") - .(ArrayLiteral) - .getElement(_) - .getConstantValue() - .getStringlikeValue() - } - - override string getAction() { - result = - extractAction(method.getKeywordArgument("to").getConstantValue().getStringlikeValue()) or - method.getKeywordArgument("action").getConstantValue().isStringlikeValue(result) or - result = - extractAction(method - .getArgument(0) - .(Pair) - .getValue() - .getConstantValue() - .getStringlikeValue()) - } - } - - private import Cached - - /** - * This module contains the IPA types backing `RouteBlock` and `Route`, cached for performance. - */ - cached - private module Cached { - cached - newtype TRouteBlock = - TTopLevelRouteBlock(MethodCall routes, MethodCall draw, Block b) { - routes.getMethodName() = "routes" and - draw.getMethodName() = "draw" and - draw.getReceiver() = routes and - draw.getBlock() = b - } or - // constraints(foo: /some_regex/) do - // get "/posts/:foo", to "posts#something" - // end - TConstraintsRouteBlock(RouteBlock parent, MethodCall constraints, Block b) { - parent.getAStmt() = constraints and - constraints.getMethodName() = "constraints" and - constraints.getBlock() = b - } or - // scope(path: "/some_path", module: "some_module") do - // get "/posts/:foo", to "posts#something" - // end - TScopeRouteBlock(RouteBlock parent, MethodCall scope, Block b) { - parent.getAStmt() = scope and scope.getMethodName() = "scope" and scope.getBlock() = b - } or - // resources :articles do - // get "/comments", to "comments#index" - // end - TResourcesRouteBlock(RouteBlock parent, MethodCall resources, Block b) { - parent.getAStmt() = resources and - resources.getMethodName() = "resources" and - resources.getBlock() = b - } or - // A conditional statement guarding some routes. - // We ignore the condition and analyze both branches to obtain as - // much routing information as possible. - TConditionalRouteBlock(RouteBlock parent, ConditionalExpr e) { parent.getAStmt() = e } or - // namespace :admin do - // resources :posts - // end - TNamespaceRouteBlock(RouteBlock parent, MethodCall namespace, Block b) { - parent.getAStmt() = namespace and - namespace.getMethodName() = "namespace" and - namespace.getBlock() = b - } - - /** - * A route configuration. See `Route` for more info - */ - cached - newtype TRoute = - /** - * See `ExplicitRoute` - */ - TExplicitRoute(RouteBlock b, MethodCall m) { - b.getAStmt() = m and m.getMethodName() = anyHttpMethod() - } or - /** - * See `ResourcesRoute` - */ - TResourcesRoute(RouteBlock b, MethodCall m, string action) { - b.getAStmt() = m and - m.getMethodName() = "resources" and - action in ["show", "index", "new", "edit", "create", "update", "destroy"] and - applyActionFilters(m, action) - } or - /** - * See `SingularResourceRoute` - */ - TResourceRoute(RouteBlock b, MethodCall m, string action) { - b.getAStmt() = m and - m.getMethodName() = "resource" and - action in ["show", "new", "edit", "create", "update", "destroy"] and - applyActionFilters(m, action) - } or - /** - * See `MatchRoute` - */ - TMatchRoute(RouteBlock b, MethodCall m) { b.getAStmt() = m and m.getMethodName() = "match" } - } - - /** - * Several routing methods support the keyword arguments `only:` and `except:`. - * - `only:` restricts the set of actions to just those in the argument. - * - `except:` removes the given actions from the set. - */ - bindingset[action] - private predicate applyActionFilters(MethodCall m, string action) { - // Respect the `only` keyword argument, which restricts the set of actions. - ( - not exists(m.getKeywordArgument("only")) - or - exists(Expr only | only = m.getKeywordArgument("only") | - [only.(ArrayLiteral).getElement(_), only].getConstantValue().isStringlikeValue(action) - ) - ) and - // Respect the `except` keyword argument, which removes actions from the default set. - ( - not exists(m.getKeywordArgument("except")) - or - exists(Expr except | except = m.getKeywordArgument("except") | - [except.(ArrayLiteral).getElement(_), except].getConstantValue().getStringlikeValue() != - action - ) - ) - } - - /** - * Holds if the (resource, method, path, action) combination would be generated by a call to `resources :<resource>`. - */ - bindingset[resource] - private predicate isDefaultResourceRoute( - string resource, string method, string path, string action - ) { - action = "create" and - (method = "post" and path = "/" + resource) - or - action = "index" and - (method = "get" and path = "/" + resource) - or - action = "new" and - (method = "get" and path = "/" + resource + "/new") - or - action = "edit" and - (method = "get" and path = "/" + resource + ":id/edit") - or - action = "show" and - (method = "get" and path = "/" + resource + "/:id") - or - action = "update" and - (method in ["put", "patch"] and path = "/" + resource + "/:id") - or - action = "destroy" and - (method = "delete" and path = "/" + resource + "/:id") - } - - /** - * Holds if the (resource, method, path, action) combination would be generated by a call to `resource :<resource>`. - */ - bindingset[resource] - private predicate isDefaultSingularResourceRoute( - string resource, string method, string path, string action - ) { - action = "create" and - (method = "post" and path = "/" + resource) - or - action = "new" and - (method = "get" and path = "/" + resource + "/new") - or - action = "edit" and - (method = "get" and path = "/" + resource + "/edit") - or - action = "show" and - (method = "get" and path = "/" + resource) - or - action = "update" and - (method in ["put", "patch"] and path = "/" + resource) - or - action = "destroy" and - (method = "delete" and path = "/" + resource) - } - - /** - * Extract the controller from a Rails routing string - * ``` - * extractController("posts#show") = "posts" - * ``` - */ - bindingset[input] - private string extractController(string input) { result = input.regexpCapture("([^#]+)#.+", 1) } - - /** - * Extract the action from a Rails routing string - * ``` - * extractAction("posts#show") = "show" - */ - bindingset[input] - private string extractAction(string input) { result = input.regexpCapture("[^#]+#(.+)", 1) } - - /** - * Returns the lowercase name of every HTTP method we support. - */ - private string anyHttpMethod() { result = ["get", "post", "put", "patch", "delete"] } - - /** - * The inverse of `pluralize`. If `input` is a plural word, it returns the - * singular version. - * - * Examples: - * - * - photos -> photo - * - stories -> story - * - not_plural -> not_plural - */ - bindingset[input] - private string singularize(string input) { - exists(string prefix | prefix = input.regexpCapture("(.*)ies", 1) | result = prefix + "y") - or - not input.matches("%ies") and - exists(string prefix | prefix = input.regexpCapture("(.*)s", 1) | result = prefix) - or - not input.regexpMatch(".*(ies|s)") and result = input - } - - /** - * Convert a camel-case string to underscore case. Converts `::` to `/`. - * This can be used to convert ActiveRecord controller names to a canonical form that matches the routes they handle. - * Note: All-uppercase words like `CONSTANT` are not handled correctly. - */ - bindingset[base] - string underscore(string base) { - base = "" and result = "" - or - result = - base.charAt(0).toLowerCase() + - // Walk along the string, keeping track of the previous character - // in order to determine if we've crossed a boundary. - // Boundaries are: - // - lower case to upper case: B in FooBar - // - entering a namespace: B in Foo::Bar - concat(int i, string prev, string char | - prev = base.charAt(i) and - char = base.charAt(i + 1) - | - any(string s | - char.regexpMatch("[A-Za-z0-9]") and - if prev = ":" - then s = "/" + char.toLowerCase() - else - if prev.isLowercase() and char.isUppercase() - then s = "_" + char.toLowerCase() - else s = char.toLowerCase() - ) - order by - i - ) - } - - /** - * Strip leading and trailing forward slashes from the string. - */ - bindingset[input] - private string stripSlashes(string input) { - result = input.regexpReplaceAll("^/+(.+)$", "$1").regexpReplaceAll("^(.*[^/])/+$", "$1") - } - } + class MimeTypeMatchRegExpInterpretation = Mime::MimeTypeMatchRegExpInterpretation; } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Mime.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Mime.qll new file mode 100644 index 00000000000..a47b4700d93 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Mime.qll @@ -0,0 +1,46 @@ +/** + * Models MIME type handling using the `ActionDispatch` library, which is part of Rails. + */ + +private import codeql.ruby.Regexp as RE +private import codeql.ruby.frameworks.data.ModelsAsData + +/** + * Models MIME type handling using the `ActionDispatch` library, which is part of Rails. + */ +module Mime { + /** + * Type summaries for the `Mime::Type` class, i.e. method calls that produce new + * `Mime::Type` instances. + */ + private class MimeTypeTypeSummary extends ModelInput::TypeModelCsv { + override predicate row(string row) { + // type1;type2;path + row = + [ + // Mime[type] : Mime::Type (omitted) + // Method names with brackets like [] cannot be represented in MaD. + // Mime.fetch(type) : Mime::Type + "Mime::Type;Mime!;Method[fetch].ReturnValue", + // Mime::Type.lookup(str) : Mime::Type + "Mime::Type;Mime::Type!;Method[lookup].ReturnValue", + // Mime::Type.lookup_by_extension(str) : Mime::Type + "Mime::Type;Mime::Type!;Method[lookup_by_extension].ReturnValue", + // Mime::Type.register(str) : Mime::Type + "Mime::Type;Mime::Type!;Method[register].ReturnValue", + // Mime::Type.register_alias(str) : Mime::Type + "Mime::Type;Mime::Type!;Method[register_alias].ReturnValue", + ] + } + } + + /** + * An argument to `Mime::Type#match?`, which is converted to a RegExp via + * `Regexp.new`. + */ + class MimeTypeMatchRegExpInterpretation extends RE::RegExpInterpretation::Range { + MimeTypeMatchRegExpInterpretation() { + this = ModelOutput::getATypeNode("Mime::Type").getAMethodCall(["match?", "=~"]).getArgument(0) + } + } +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Routing.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Routing.qll new file mode 100644 index 00000000000..3c34846bee8 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Routing.qll @@ -0,0 +1,961 @@ +/** + * Models routing configuration specified using the `ActionDispatch` library, which is part of Rails. + */ + +private import codeql.ruby.AST + +/** + * Models routing configuration specified using the `ActionDispatch` library, which is part of Rails. + */ +module Routing { + /** + * A block that defines some routes. + * Route blocks can contribute to the path or controller namespace of their child routes. + * For example, in the block below + * ```rb + * scope path: "/admin" do + * get "/dashboard", to: "admin_dashboard#show" + * end + * ``` + * the route defined by the call to `get` has the full path `/admin/dashboard`. + * We track these contributions via `getPathComponent` and `getControllerComponent`. + */ + abstract private class RouteBlock extends TRouteBlock { + /** + * Gets the name of a primary CodeQL class to which this route block belongs. + */ + string getAPrimaryQlClass() { result = "RouteBlock" } + + /** + * Gets a string representation of this route block. + */ + string toString() { none() } + + /** + * Gets a `Stmt` within this route block. + */ + abstract Stmt getAStmt(); + + /** + * Gets the parent of this route block, if one exists. + */ + abstract RouteBlock getParent(); + + /** + * Gets the `n`th parent of this route block. + * The zeroth parent is this block, the first parent is the direct parent of this block, etc. + */ + RouteBlock getParent(int n) { + if n = 0 then result = this else result = this.getParent().getParent(n - 1) + } + + /** + * Gets the component of the path defined by this block, if it exists. + */ + abstract string getPathComponent(); + + /** + * Gets the component of the controller namespace defined by this block, if it exists. + */ + abstract string getControllerComponent(); + + /** + * Gets the location of this route block. + */ + abstract Location getLocation(); + } + + /** + * A route block that is not the top-level block. + * This block will always have a parent. + */ + abstract private class NestedRouteBlock extends RouteBlock { + RouteBlock parent; + + override RouteBlock getParent() { result = parent } + + override string getAPrimaryQlClass() { result = "NestedRouteBlock" } + } + + /** + * A top-level routes block. + * ```rb + * Rails.application.routes.draw do + * ... + * end + * ``` + */ + private class TopLevelRouteBlock extends RouteBlock, TTopLevelRouteBlock { + MethodCall call; + // Routing blocks create scopes which define the namespace for controllers and paths, + // though they can be overridden in various ways. + // The namespaces can differ, so we track them separately. + Block block; + + TopLevelRouteBlock() { this = TTopLevelRouteBlock(_, call, block) } + + override string getAPrimaryQlClass() { result = "TopLevelRouteBlock" } + + Block getBlock() { result = block } + + override Stmt getAStmt() { result = block.getAStmt() } + + override RouteBlock getParent() { none() } + + override string toString() { result = call.toString() } + + override Location getLocation() { result = call.getLocation() } + + override string getPathComponent() { none() } + + override string getControllerComponent() { none() } + } + + /** + * A route block defined by a call to `constraints`. + * ```rb + * constraints(foo: /some_regex/) do + * get "/posts/:foo", to "posts#something" + * end + * ``` + * https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-constraints + */ + private class ConstraintsRouteBlock extends NestedRouteBlock, TConstraintsRouteBlock { + private Block block; + private MethodCall call; + + ConstraintsRouteBlock() { this = TConstraintsRouteBlock(parent, call, block) } + + override string getAPrimaryQlClass() { result = "ConstraintsRouteBlock" } + + override Stmt getAStmt() { result = block.getAStmt() } + + override string getPathComponent() { result = "" } + + override string getControllerComponent() { result = "" } + + override string toString() { result = call.toString() } + + override Location getLocation() { result = call.getLocation() } + } + + /** + * A route block defined by a call to `scope`. + * ```rb + * scope(path: "/some_path", module: "some_module") do + * get "/posts/:foo", to "posts#something" + * end + * ``` + * https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-scope + */ + private class ScopeRouteBlock extends NestedRouteBlock, TScopeRouteBlock { + private MethodCall call; + private Block block; + + ScopeRouteBlock() { this = TScopeRouteBlock(parent, call, block) } + + override string getAPrimaryQlClass() { result = "ScopeRouteBlock" } + + override Stmt getAStmt() { result = block.getAStmt() } + + override string toString() { result = call.toString() } + + override Location getLocation() { result = call.getLocation() } + + override string getPathComponent() { + call.getKeywordArgument("path").getConstantValue().isStringlikeValue(result) + or + not exists(call.getKeywordArgument("path")) and + call.getArgument(0).getConstantValue().isStringlikeValue(result) + } + + override string getControllerComponent() { + call.getKeywordArgument(["controller", "module"]).getConstantValue().isStringlikeValue(result) + } + } + + /** + * A route block defined by a call to `resources`. + * ```rb + * resources :articles do + * get "/comments", to "comments#index" + * end + * ``` + * https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-resources + */ + private class ResourcesRouteBlock extends NestedRouteBlock, TResourcesRouteBlock { + private MethodCall call; + private Block block; + + ResourcesRouteBlock() { this = TResourcesRouteBlock(parent, call, block) } + + override string getAPrimaryQlClass() { result = "ResourcesRouteBlock" } + + override Stmt getAStmt() { result = block.getAStmt() } + + /** + * Gets the `resources` call that gives rise to this route block. + */ + MethodCall getDefiningMethodCall() { result = call } + + override string getPathComponent() { + exists(string resource | call.getArgument(0).getConstantValue().isStringlikeValue(resource) | + result = resource + "/:" + singularize(resource) + "_id" + ) + } + + override string getControllerComponent() { result = "" } + + override string toString() { result = call.toString() } + + override Location getLocation() { result = call.getLocation() } + } + + /** + * A route block that is guarded by a conditional statement. + * For example: + * ```rb + * if Rails.env.test? + * get "/foo/bar", to: "foo#bar" + * end + * ``` + * We ignore the condition and analyze both branches to obtain as + * much routing information as possible. + */ + private class ConditionalRouteBlock extends NestedRouteBlock, TConditionalRouteBlock { + private ConditionalExpr e; + + ConditionalRouteBlock() { this = TConditionalRouteBlock(parent, e) } + + override string getAPrimaryQlClass() { result = "ConditionalRouteBlock" } + + override Stmt getAStmt() { result = e.getBranch(_).(StmtSequence).getAStmt() } + + override string getPathComponent() { none() } + + override string getControllerComponent() { none() } + + override string toString() { result = e.toString() } + + override Location getLocation() { result = e.getLocation() } + } + + /** + * A route block defined by a call to `namespace`. + * ```rb + * namespace :admin do + * resources :posts + * end + * ``` + * https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-namespace + */ + private class NamespaceRouteBlock extends NestedRouteBlock, TNamespaceRouteBlock { + private MethodCall call; + private Block block; + + NamespaceRouteBlock() { this = TNamespaceRouteBlock(parent, call, block) } + + override Stmt getAStmt() { result = block.getAStmt() } + + override string getPathComponent() { result = this.getNamespace() } + + override string getControllerComponent() { result = this.getNamespace() } + + private string getNamespace() { + call.getArgument(0).getConstantValue().isStringlikeValue(result) + } + + override string toString() { result = call.toString() } + + override Location getLocation() { result = call.getLocation() } + } + + /** + * A route configuration. This defines a combination of HTTP method and URL + * path which should be routed to a particular controller-action pair. + * This can arise from an explicit call to a routing method, for example: + * ```rb + * get "/photos", to: "photos#index" + * ``` + * or via a convenience method like `resources`, which defines multiple routes at once: + * ```rb + * resources :photos + * ``` + */ + class Route extends TRoute instanceof RouteImpl { + /** + * Gets the name of a primary CodeQL class to which this route belongs. + */ + string getAPrimaryQlClass() { result = "Route" } + + /** Gets a string representation of this route. */ + string toString() { result = super.toString() } + + /** + * Gets the location of the method call that defines this route. + */ + Location getLocation() { result = super.getLocation() } + + /** + * Gets the full controller targeted by this route. + */ + string getController() { result = super.getController() } + + /** + * Gets the action targeted by this route. + */ + string getAction() { result = super.getAction() } + + /** + * Gets the HTTP method of this route. + * The result is one of [get, post, put, patch, delete]. + */ + string getHttpMethod() { result = super.getHttpMethod() } + + /** + * Gets the full path of the route. + */ + string getPath() { result = super.getPath() } + + /** + * Get a URL capture. This is a wildcard URL segment whose value is placed in `params`. + * For example, in + * ```ruby + * get "/foo/:bar/baz", to: "users#index" + * ``` + * the capture is `:bar`. + */ + string getACapture() { result = super.getACapture() } + } + + /** + * The implementation of `Route`. + * This class is abstract and is thus kept private so we don't expose it to + * users. + * Extend this class to add new instances of routes. + */ + abstract private class RouteImpl extends TRoute { + /** + * Gets the name of a primary CodeQL class to which this route belongs. + */ + string getAPrimaryQlClass() { result = "RouteImpl" } + + MethodCall method; + + /** Gets a string representation of this route. */ + string toString() { result = method.toString() } + + /** + * Gets the location of the method call that defines this route. + */ + Location getLocation() { result = method.getLocation() } + + /** + * Gets the method call that defines this route. + */ + MethodCall getDefiningMethodCall() { result = method } + + /** + * Get the last component of the path. For example, in + * ```rb + * get "/photos", to: "photos#index" + * ``` + * this is `/photos`. + * If the string has any interpolations, this predicate will have no result. + */ + abstract string getLastPathComponent(); + + /** + * Gets the HTTP method of this route. + * The result is one of [get, post, put, patch, delete]. + */ + abstract string getHttpMethod(); + + /** + * Gets the last controller component. + * This is the controller specified in the route itself. + */ + abstract string getLastControllerComponent(); + + /** + * Gets a component of the controller. + * This behaves identically to `getPathComponent`, but for controller information. + */ + string getControllerComponent(int n) { + if n = 0 + then result = this.getLastControllerComponent() + else result = this.getParentBlock().getParent(n - 1).getControllerComponent() + } + + /** + * Gets the full controller targeted by this route. + */ + string getController() { + result = + concat(int n | + this.getControllerComponent(n) != "" + | + this.getControllerComponent(n), "/" order by n desc + ) + } + + /** + * Gets the action targeted by this route. + */ + abstract string getAction(); + + /** + * Gets the parent `RouteBlock` of this route. + */ + abstract RouteBlock getParentBlock(); + + /** + * Gets a component of the path. Components are numbered from 0 up, where 0 + * is the last component, 1 is the second-last, etc. + * For example, in the following route: + * + * ```rb + * namespace path: "foo" do + * namespace path: "bar" do + * get "baz", to: "foo#bar + * end + * end + * ``` + * + * the components are: + * + * | n | component + * |---|---------- + * | 0 | baz + * | 1 | bar + * | 2 | foo + */ + string getPathComponent(int n) { + if n = 0 + then result = this.getLastPathComponent() + else result = this.getParentBlock().getParent(n - 1).getPathComponent() + } + + /** + * Gets the full path of the route. + */ + string getPath() { + result = + concat(int n | + this.getPathComponent(n) != "" + | + // Strip leading and trailing slashes from each path component before combining + stripSlashes(this.getPathComponent(n)), "/" order by n desc + ) + } + + /** + * Get a URL capture. This is a wildcard URL segment whose value is placed in `params`. + * For example, in + * ```ruby + * get "/foo/:bar/baz", to: "users#index" + * ``` + * the capture is `:bar`. + * We don't currently make use of this, but it may be useful in future to more accurately + * model the contents of the `params` hash. + */ + string getACapture() { result = this.getPathComponent(_).regexpFind(":[^:/]+", _, _) } + } + + /** + * A route generated by an explicit call to `get`, `post`, etc. + * + * ```ruby + * get "/photos", to: "photos#index" + * put "/photos/:id", to: "photos#update" + * ``` + */ + private class ExplicitRoute extends RouteImpl, TExplicitRoute { + RouteBlock parentBlock; + + ExplicitRoute() { this = TExplicitRoute(parentBlock, method) } + + override string getAPrimaryQlClass() { result = "ExplicitRoute" } + + override RouteBlock getParentBlock() { result = parentBlock } + + override string getLastPathComponent() { + method.getArgument(0).getConstantValue().isStringlikeValue(result) + } + + override string getLastControllerComponent() { + method.getKeywordArgument("controller").getConstantValue().isStringlikeValue(result) + or + not exists(method.getKeywordArgument("controller")) and + ( + result = extractController(this.getActionString()) + or + // If controller is not specified, and we're in a `resources` route block, use the controller of that route. + // For example, in + // + // resources :posts do + // get "timestamp", to: :timestamp + // end + // + // The route is GET /posts/:post_id/timestamp => posts/timestamp + not exists(extractController(this.getActionString())) and + exists(ResourcesRoute r | + r.getDefiningMethodCall() = parentBlock.(ResourcesRouteBlock).getDefiningMethodCall() + | + result = r.getLastControllerComponent() + ) + ) + } + + private string getActionString() { + method.getKeywordArgument("to").getConstantValue().isStringlikeValue(result) + or + method.getKeywordArgument("to").(MethodCall).getMethodName() = "redirect" and + result = "<redirect>#<redirect>" + } + + override string getAction() { + // get "/photos", action: "index" + method.getKeywordArgument("action").getConstantValue().isStringlikeValue(result) + or + not exists(method.getKeywordArgument("action")) and + ( + // get "/photos", to: "photos#index" + // get "/photos", to: redirect("some_url") + result = extractAction(this.getActionString()) + or + // resources :photos, only: [] do + // get "/", to: "index" + // end + not exists(extractAction(this.getActionString())) and result = this.getActionString() + or + // get :some_action + not exists(this.getActionString()) and + method.getArgument(0).getConstantValue().isStringlikeValue(result) + ) + } + + override string getHttpMethod() { result = method.getMethodName().toString() } + } + + /** + * A route generated by a call to `resources`. + * + * ```ruby + * resources :photos + * ``` + * This creates eight routes, equivalent to the following code: + * ```ruby + * get "/photos", to: "photos#index" + * get "/photos/new", to: "photos#new" + * post "/photos", to: "photos#create" + * get "/photos/:id", to: "photos#show" + * get "/photos/:id/edit", to: "photos#edit" + * patch "/photos/:id", to: "photos#update" + * put "/photos/:id", to: "photos#update" + * delete "/photos/:id", to: "photos#delete" + * ``` + * + * `resources` can take a block. Any routes defined inside the block will inherit a path component of + * `/<resource>/:<resource>_id`. For example: + * + * ```ruby + * resources :photos do + * get "/foo", to: "photos#foo" + * end + * ``` + * This creates the eight default routes, plus one more, which is nested under "/photos/:photo_id", equivalent to: + * ```ruby + * get "/photos/:photo_id/foo", to: "photos#foo" + * ``` + */ + private class ResourcesRoute extends RouteImpl, TResourcesRoute { + RouteBlock parent; + string action; + string httpMethod; + string pathComponent; + + ResourcesRoute() { + exists(string resource | + this = TResourcesRoute(parent, method, action) and + method.getArgument(0).getConstantValue().isStringlikeValue(resource) and + isDefaultResourceRoute(resource, httpMethod, pathComponent, action) + ) + } + + override string getAPrimaryQlClass() { result = "ResourcesRoute" } + + override RouteBlock getParentBlock() { result = parent } + + override string getLastPathComponent() { result = pathComponent } + + override string getLastControllerComponent() { + method.getArgument(0).getConstantValue().isStringlikeValue(result) + } + + override string getAction() { result = action } + + override string getHttpMethod() { result = httpMethod } + } + + /** + * A route generated by a call to `resource`. + * This is like a `resources` route, but creates routes for a singular resource. + * This means there's no index route, no id parameter, and the resource name is expected to be singular. + * It will still be routed to a pluralised controller name. + * ```ruby + * resource :account + * ``` + */ + private class SingularResourceRoute extends RouteImpl, TResourceRoute { + RouteBlock parent; + string action; + string httpMethod; + string pathComponent; + + SingularResourceRoute() { + exists(string resource | + this = TResourceRoute(parent, method, action) and + method.getArgument(0).getConstantValue().isStringlikeValue(resource) and + isDefaultSingularResourceRoute(resource, httpMethod, pathComponent, action) + ) + } + + override string getAPrimaryQlClass() { result = "SingularResourceRoute" } + + override RouteBlock getParentBlock() { result = parent } + + override string getLastPathComponent() { result = pathComponent } + + override string getLastControllerComponent() { + method.getArgument(0).getConstantValue().isStringlikeValue(result) + } + + override string getAction() { result = action } + + override string getHttpMethod() { result = httpMethod } + } + + /** + * A route generated by a call to `match`. + * This is a lower level primitive that powers `get`, `post` etc. + * The first argument can be a path or a (path, controller-action) pair. + * The controller, action and HTTP method can be specified with the + * `controller:`, `action:` and `via:` keyword arguments, respectively. + * ```ruby + * match 'photos/:id' => 'photos#show', via: :get + * match 'photos/:id', to: 'photos#show', via: :get + * match 'photos/:id', to 'photos#show', via: [:get, :post] + * match 'photos/:id', controller: 'photos', action: 'show', via: :get + * ``` + */ + private class MatchRoute extends RouteImpl, TMatchRoute { + private RouteBlock parent; + + MatchRoute() { this = TMatchRoute(parent, method) } + + override string getAPrimaryQlClass() { result = "MatchRoute" } + + override RouteBlock getParentBlock() { result = parent } + + override string getLastPathComponent() { + [method.getArgument(0), method.getArgument(0).(Pair).getKey()] + .getConstantValue() + .isStringlikeValue(result) + } + + override string getLastControllerComponent() { + result = + extractController(method.getKeywordArgument("to").getConstantValue().getStringlikeValue()) or + method.getKeywordArgument("controller").getConstantValue().isStringlikeValue(result) or + result = + extractController(method + .getArgument(0) + .(Pair) + .getValue() + .getConstantValue() + .getStringlikeValue()) + } + + override string getHttpMethod() { + exists(string via | + method.getKeywordArgument("via").getConstantValue().isStringlikeValue(via) + | + via = "all" and result = anyHttpMethod() + or + via != "all" and result = via + ) + or + result = + method + .getKeywordArgument("via") + .(ArrayLiteral) + .getElement(_) + .getConstantValue() + .getStringlikeValue() + } + + override string getAction() { + result = + extractAction(method.getKeywordArgument("to").getConstantValue().getStringlikeValue()) or + method.getKeywordArgument("action").getConstantValue().isStringlikeValue(result) or + result = + extractAction(method + .getArgument(0) + .(Pair) + .getValue() + .getConstantValue() + .getStringlikeValue()) + } + } + + private import Cached + + /** + * This module contains the IPA types backing `RouteBlock` and `Route`, cached for performance. + */ + cached + private module Cached { + cached + newtype TRouteBlock = + TTopLevelRouteBlock(MethodCall routes, MethodCall draw, Block b) { + routes.getMethodName() = "routes" and + draw.getMethodName() = "draw" and + draw.getReceiver() = routes and + draw.getBlock() = b + } or + // constraints(foo: /some_regex/) do + // get "/posts/:foo", to "posts#something" + // end + TConstraintsRouteBlock(RouteBlock parent, MethodCall constraints, Block b) { + parent.getAStmt() = constraints and + constraints.getMethodName() = "constraints" and + constraints.getBlock() = b + } or + // scope(path: "/some_path", module: "some_module") do + // get "/posts/:foo", to "posts#something" + // end + TScopeRouteBlock(RouteBlock parent, MethodCall scope, Block b) { + parent.getAStmt() = scope and scope.getMethodName() = "scope" and scope.getBlock() = b + } or + // resources :articles do + // get "/comments", to "comments#index" + // end + TResourcesRouteBlock(RouteBlock parent, MethodCall resources, Block b) { + parent.getAStmt() = resources and + resources.getMethodName() = "resources" and + resources.getBlock() = b + } or + // A conditional statement guarding some routes. + // We ignore the condition and analyze both branches to obtain as + // much routing information as possible. + TConditionalRouteBlock(RouteBlock parent, ConditionalExpr e) { parent.getAStmt() = e } or + // namespace :admin do + // resources :posts + // end + TNamespaceRouteBlock(RouteBlock parent, MethodCall namespace, Block b) { + parent.getAStmt() = namespace and + namespace.getMethodName() = "namespace" and + namespace.getBlock() = b + } + + /** + * A route configuration. See `Route` for more info + */ + cached + newtype TRoute = + /** + * See `ExplicitRoute` + */ + TExplicitRoute(RouteBlock b, MethodCall m) { + b.getAStmt() = m and m.getMethodName() = anyHttpMethod() + } or + /** + * See `ResourcesRoute` + */ + TResourcesRoute(RouteBlock b, MethodCall m, string action) { + b.getAStmt() = m and + m.getMethodName() = "resources" and + action in ["show", "index", "new", "edit", "create", "update", "destroy"] and + applyActionFilters(m, action) + } or + /** + * See `SingularResourceRoute` + */ + TResourceRoute(RouteBlock b, MethodCall m, string action) { + b.getAStmt() = m and + m.getMethodName() = "resource" and + action in ["show", "new", "edit", "create", "update", "destroy"] and + applyActionFilters(m, action) + } or + /** + * See `MatchRoute` + */ + TMatchRoute(RouteBlock b, MethodCall m) { b.getAStmt() = m and m.getMethodName() = "match" } + } + + /** + * Several routing methods support the keyword arguments `only:` and `except:`. + * - `only:` restricts the set of actions to just those in the argument. + * - `except:` removes the given actions from the set. + */ + bindingset[action] + private predicate applyActionFilters(MethodCall m, string action) { + // Respect the `only` keyword argument, which restricts the set of actions. + ( + not exists(m.getKeywordArgument("only")) + or + exists(Expr only | only = m.getKeywordArgument("only") | + [only.(ArrayLiteral).getElement(_), only].getConstantValue().isStringlikeValue(action) + ) + ) and + // Respect the `except` keyword argument, which removes actions from the default set. + ( + not exists(m.getKeywordArgument("except")) + or + exists(Expr except | except = m.getKeywordArgument("except") | + [except.(ArrayLiteral).getElement(_), except].getConstantValue().getStringlikeValue() != + action + ) + ) + } + + /** + * Holds if the (resource, method, path, action) combination would be generated by a call to `resources :<resource>`. + */ + bindingset[resource] + private predicate isDefaultResourceRoute( + string resource, string method, string path, string action + ) { + action = "create" and + (method = "post" and path = "/" + resource) + or + action = "index" and + (method = "get" and path = "/" + resource) + or + action = "new" and + (method = "get" and path = "/" + resource + "/new") + or + action = "edit" and + (method = "get" and path = "/" + resource + ":id/edit") + or + action = "show" and + (method = "get" and path = "/" + resource + "/:id") + or + action = "update" and + (method in ["put", "patch"] and path = "/" + resource + "/:id") + or + action = "destroy" and + (method = "delete" and path = "/" + resource + "/:id") + } + + /** + * Holds if the (resource, method, path, action) combination would be generated by a call to `resource :<resource>`. + */ + bindingset[resource] + private predicate isDefaultSingularResourceRoute( + string resource, string method, string path, string action + ) { + action = "create" and + (method = "post" and path = "/" + resource) + or + action = "new" and + (method = "get" and path = "/" + resource + "/new") + or + action = "edit" and + (method = "get" and path = "/" + resource + "/edit") + or + action = "show" and + (method = "get" and path = "/" + resource) + or + action = "update" and + (method in ["put", "patch"] and path = "/" + resource) + or + action = "destroy" and + (method = "delete" and path = "/" + resource) + } + + /** + * Extract the controller from a Rails routing string + * ``` + * extractController("posts#show") = "posts" + * ``` + */ + bindingset[input] + private string extractController(string input) { result = input.regexpCapture("([^#]+)#.+", 1) } + + /** + * Extract the action from a Rails routing string + * ``` + * extractAction("posts#show") = "show" + */ + bindingset[input] + private string extractAction(string input) { result = input.regexpCapture("[^#]+#(.+)", 1) } + + /** + * Returns the lowercase name of every HTTP method we support. + */ + private string anyHttpMethod() { result = ["get", "post", "put", "patch", "delete"] } + + /** + * The inverse of `pluralize`. If `input` is a plural word, it returns the + * singular version. + * + * Examples: + * + * - photos -> photo + * - stories -> story + * - not_plural -> not_plural + */ + bindingset[input] + private string singularize(string input) { + exists(string prefix | prefix = input.regexpCapture("(.*)ies", 1) | result = prefix + "y") + or + not input.matches("%ies") and + exists(string prefix | prefix = input.regexpCapture("(.*)s", 1) | result = prefix) + or + not input.regexpMatch(".*(ies|s)") and result = input + } + + /** + * Convert a camel-case string to underscore case. Converts `::` to `/`. + * This can be used to convert ActiveRecord controller names to a canonical form that matches the routes they handle. + * Note: All-uppercase words like `CONSTANT` are not handled correctly. + */ + bindingset[base] + string underscore(string base) { + base = "" and result = "" + or + result = + base.charAt(0).toLowerCase() + + // Walk along the string, keeping track of the previous character + // in order to determine if we've crossed a boundary. + // Boundaries are: + // - lower case to upper case: B in FooBar + // - entering a namespace: B in Foo::Bar + concat(int i, string prev, string char | + prev = base.charAt(i) and + char = base.charAt(i + 1) + | + any(string s | + char.regexpMatch("[A-Za-z0-9]") and + if prev = ":" + then s = "/" + char.toLowerCase() + else + if prev.isLowercase() and char.isUppercase() + then s = "_" + char.toLowerCase() + else s = char.toLowerCase() + ) + order by + i + ) + } + + /** + * Strip leading and trailing forward slashes from the string. + */ + bindingset[input] + private string stripSlashes(string input) { + result = input.regexpReplaceAll("^/+(.+)$", "$1").regexpReplaceAll("^(.*[^/])/+$", "$1") + } +} From 27729af088e0ee5c4abd2f933cb44b6a89703c45 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 23 May 2023 13:48:58 +0100 Subject: [PATCH 083/739] Ruby: move ActionDispatch::Request logic out of ActionController.qll --- .../ruby/frameworks/ActionController.qll | 146 +---------------- .../codeql/ruby/frameworks/ActionDispatch.qll | 1 + .../frameworks/actiondispatch/Request.qll | 147 ++++++++++++++++++ 3 files changed, 150 insertions(+), 144 deletions(-) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll index 480a1f78035..9e4ce72a249 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll @@ -83,7 +83,8 @@ class ActionControllerClass extends DataFlow::ClassNode { } } -private DataFlow::LocalSourceNode actionControllerInstance() { +// TODO: private +DataFlow::LocalSourceNode actionControllerInstance() { result = any(ActionControllerClass cls).getSelf() } @@ -204,149 +205,6 @@ private class ActionControllerParamsCall extends ParamsCallImpl { } } -/** Modeling for `ActionDispatch::Request`. */ -private module Request { - /** - * A call to `request` from within a controller. This is an instance of - * `ActionDispatch::Request`. - */ - private class RequestNode extends DataFlow::CallNode { - RequestNode() { this = actionControllerInstance().getAMethodCall("request") } - } - - /** - * A method call on `request`. - */ - private class RequestMethodCall extends DataFlow::CallNode { - RequestMethodCall() { - any(RequestNode r).(DataFlow::LocalSourceNode).flowsTo(this.getReceiver()) - } - } - - abstract private class RequestInputAccess extends RequestMethodCall, - Http::Server::RequestInputAccess::Range - { - override string getSourceType() { result = "ActionDispatch::Request#" + this.getMethodName() } - } - - /** - * A method call on `request` which returns request parameters. - */ - private class ParametersCall extends RequestInputAccess { - ParametersCall() { - this.getMethodName() = - [ - "parameters", "params", "GET", "POST", "query_parameters", "request_parameters", - "filtered_parameters" - ] - } - - override Http::Server::RequestInputKind getKind() { - result = Http::Server::parameterInputKind() - } - } - - /** A method call on `request` which returns part or all of the request path. */ - private class PathCall extends RequestInputAccess { - PathCall() { - this.getMethodName() = - ["path", "filtered_path", "fullpath", "original_fullpath", "original_url", "url"] - } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::urlInputKind() } - } - - /** A method call on `request` which returns a specific request header. */ - private class HeadersCall extends RequestInputAccess { - HeadersCall() { - this.getMethodName() = - [ - "authorization", "script_name", "path_info", "user_agent", "referer", "referrer", - "host_authority", "content_type", "host", "hostname", "accept_encoding", - "accept_language", "if_none_match", "if_none_match_etags", "content_mime_type" - ] - or - // Request headers are prefixed with `HTTP_` to distinguish them from - // "headers" supplied by Rack middleware. - this.getMethodName() = ["get_header", "fetch_header"] and - this.getArgument(0).getConstantValue().getString().regexpMatch("^HTTP_.+") - } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } - } - - // TODO: each_header - /** - * A method call on `request` which returns part or all of the host. - * This can be influenced by headers such as Host and X-Forwarded-Host. - */ - private class HostCall extends RequestInputAccess { - HostCall() { - this.getMethodName() = - [ - "authority", "host", "host_authority", "host_with_port", "hostname", "forwarded_for", - "forwarded_host", "port", "forwarded_port" - ] - } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } - } - - /** - * A method call on `request` which is influenced by one or more request - * headers. - */ - private class HeaderTaintedCall extends RequestInputAccess { - HeaderTaintedCall() { - this.getMethodName() = ["media_type", "media_type_params", "content_charset", "base_url"] - } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } - } - - /** A method call on `request` which returns the request body. */ - private class BodyCall extends RequestInputAccess { - BodyCall() { this.getMethodName() = ["body", "raw_post", "body_stream"] } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::bodyInputKind() } - } - - private module Env { - abstract private class Env extends DataFlow::LocalSourceNode { } - - /** - * A method call on `request` which returns the rack env. - * This is a hash containing all the information about the request. Values - * under keys starting with `HTTP_` are user-controlled. - */ - private class RequestEnvCall extends DataFlow::CallNode, Env { - RequestEnvCall() { this.getMethodName() = ["env", "filtered_env"] } - } - - private import codeql.ruby.frameworks.Rack - - private class RackEnv extends Env { - RackEnv() { this = any(Rack::AppCandidate app).getEnv().getALocalUse() } - } - - /** - * A read of a user-controlled parameter from the request env. - */ - private class EnvHttpAccess extends DataFlow::CallNode, Http::Server::RequestInputAccess::Range { - EnvHttpAccess() { - this = any(Env c).getAMethodCall("[]") and - exists(string key | key = this.getArgument(0).getConstantValue().getString() | - key.regexpMatch("^HTTP_.+") or key = "PATH_INFO" - ) - } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } - - override string getSourceType() { result = "ActionDispatch::Request#env[]" } - } - } -} - /** A call to `render` from within a controller. */ private class ActionControllerRenderCall extends RenderCallImpl { ActionControllerRenderCall() { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll index c8720d5f1dc..1493307982f 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll @@ -9,6 +9,7 @@ */ module ActionDispatch { private import actiondispatch.Mime + private import actiondispatch.Request import actiondispatch.Routing class MimeTypeMatchRegExpInterpretation = Mime::MimeTypeMatchRegExpInterpretation; diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll new file mode 100644 index 00000000000..864767afd28 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll @@ -0,0 +1,147 @@ +/** Modeling for `ActionDispatch::Request`. */ + +private import codeql.ruby.Concepts +private import codeql.ruby.DataFlow +private import codeql.ruby.frameworks.ActionController + +/** Modeling for `ActionDispatch::Request`. */ +module Request { + /** + * An instance of `ActionDispatch::Request`. + */ + private class RequestNode extends DataFlow::CallNode { + RequestNode() { this = actionControllerInstance().getAMethodCall("request") } + } + + /** + * A method call on `request`. + */ + private class RequestMethodCall extends DataFlow::CallNode { + RequestMethodCall() { + any(RequestNode r).(DataFlow::LocalSourceNode).flowsTo(this.getReceiver()) + } + } + + abstract private class RequestInputAccess extends RequestMethodCall, + Http::Server::RequestInputAccess::Range + { + override string getSourceType() { result = "ActionDispatch::Request#" + this.getMethodName() } + } + + /** + * A method call on `request` which returns request parameters. + */ + private class ParametersCall extends RequestInputAccess { + ParametersCall() { + this.getMethodName() = + [ + "parameters", "params", "GET", "POST", "query_parameters", "request_parameters", + "filtered_parameters" + ] + } + + override Http::Server::RequestInputKind getKind() { + result = Http::Server::parameterInputKind() + } + } + + /** A method call on `request` which returns part or all of the request path. */ + private class PathCall extends RequestInputAccess { + PathCall() { + this.getMethodName() = + ["path", "filtered_path", "fullpath", "original_fullpath", "original_url", "url"] + } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::urlInputKind() } + } + + /** A method call on `request` which returns a specific request header. */ + private class HeadersCall extends RequestInputAccess { + HeadersCall() { + this.getMethodName() = + [ + "authorization", "script_name", "path_info", "user_agent", "referer", "referrer", + "host_authority", "content_type", "host", "hostname", "accept_encoding", + "accept_language", "if_none_match", "if_none_match_etags", "content_mime_type" + ] + or + // Request headers are prefixed with `HTTP_` to distinguish them from + // "headers" supplied by Rack middleware. + this.getMethodName() = ["get_header", "fetch_header"] and + this.getArgument(0).getConstantValue().getString().regexpMatch("^HTTP_.+") + } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } + } + + // TODO: each_header + /** + * A method call on `request` which returns part or all of the host. + * This can be influenced by headers such as Host and X-Forwarded-Host. + */ + private class HostCall extends RequestInputAccess { + HostCall() { + this.getMethodName() = + [ + "authority", "host", "host_authority", "host_with_port", "hostname", "forwarded_for", + "forwarded_host", "port", "forwarded_port" + ] + } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } + } + + /** + * A method call on `request` which is influenced by one or more request + * headers. + */ + private class HeaderTaintedCall extends RequestInputAccess { + HeaderTaintedCall() { + this.getMethodName() = ["media_type", "media_type_params", "content_charset", "base_url"] + } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } + } + + /** A method call on `request` which returns the request body. */ + private class BodyCall extends RequestInputAccess { + BodyCall() { this.getMethodName() = ["body", "raw_post", "body_stream"] } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::bodyInputKind() } + } + + private module Env { + abstract private class Env extends DataFlow::LocalSourceNode { } + + /** + * A method call on `request` which returns the rack env. + * This is a hash containing all the information about the request. Values + * under keys starting with `HTTP_` are user-controlled. + */ + private class RequestEnvCall extends DataFlow::CallNode, Env { + RequestEnvCall() { this.getMethodName() = ["env", "filtered_env"] } + } + + private import codeql.ruby.frameworks.Rack + + private class RackEnv extends Env { + RackEnv() { this = any(Rack::AppCandidate app).getEnv().getALocalUse() } + } + + /** + * A read of a user-controlled parameter from the request env. + */ + private class EnvHttpAccess extends DataFlow::CallNode, Http::Server::RequestInputAccess::Range { + EnvHttpAccess() { + this = any(Env c).getAMethodCall("[]") and + exists(string key | key = this.getArgument(0).getConstantValue().getString() | + key.regexpMatch("^HTTP_.+") or key = "PATH_INFO" + ) + } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } + + override string getSourceType() { result = "ActionDispatch::Request#env[]" } + } + } +} From c2f5bacc4782e133d28f185fe0672df937ca80bf Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 23 May 2023 14:10:07 +0100 Subject: [PATCH 084/739] Ruby: consider more calls to e.g. ActionDispatch::Request#params as remote input sources --- .../ruby/frameworks/ActionController.qll | 3 +-- .../frameworks/actiondispatch/Request.qll | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll index 9e4ce72a249..31bdc42e350 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll @@ -83,8 +83,7 @@ class ActionControllerClass extends DataFlow::ClassNode { } } -// TODO: private -DataFlow::LocalSourceNode actionControllerInstance() { +private DataFlow::LocalSourceNode actionControllerInstance() { result = any(ActionControllerClass cls).getSelf() } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll index 864767afd28..d749b87f273 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll @@ -2,23 +2,26 @@ private import codeql.ruby.Concepts private import codeql.ruby.DataFlow +private import codeql.ruby.ApiGraphs private import codeql.ruby.frameworks.ActionController /** Modeling for `ActionDispatch::Request`. */ module Request { /** - * An instance of `ActionDispatch::Request`. - */ - private class RequestNode extends DataFlow::CallNode { - RequestNode() { this = actionControllerInstance().getAMethodCall("request") } - } - - /** - * A method call on `request`. + * A method call against an `ActionDispatch::Request` instance. */ private class RequestMethodCall extends DataFlow::CallNode { RequestMethodCall() { - any(RequestNode r).(DataFlow::LocalSourceNode).flowsTo(this.getReceiver()) + any(ActionControllerClass cls) + .getSelf() + .getAMethodCall("request") + .(DataFlow::LocalSourceNode) + .flowsTo(this.getReceiver()) or + this = + API::getTopLevelMember("ActionDispatch") + .getMember("Request") + .getInstance() + .getAMethodCall(_) } } From 1c9e4c0f0bd9161a1e4b18139b461623bdd3d1f1 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 23 May 2023 15:17:38 +0100 Subject: [PATCH 085/739] Ruby: test for RequestInputAccess instances in ActionDispatch --- .../action_dispatch/ActionDispatch.expected | 13 +++++++++++++ .../frameworks/action_dispatch/ActionDispatch.ql | 3 +++ 2 files changed, 16 insertions(+) diff --git a/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.expected b/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.expected index 4524e715d4f..74e9b30b19a 100644 --- a/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.expected +++ b/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.expected @@ -66,3 +66,16 @@ mimeTypeMatchRegExpInterpretations | mime_type.rb:12:7:12:15 | "foo/bar" | | mime_type.rb:13:11:13:11 | s | | mime_type.rb:14:7:14:7 | s | +requestInputAccesses +| app/controllers/comments_controller.rb:3:5:3:18 | call to params | +| app/controllers/comments_controller.rb:4:5:4:22 | call to parameters | +| app/controllers/comments_controller.rb:5:5:5:15 | call to GET | +| app/controllers/comments_controller.rb:6:5:6:16 | call to POST | +| app/controllers/comments_controller.rb:7:5:7:28 | call to query_parameters | +| app/controllers/comments_controller.rb:8:5:8:30 | call to request_parameters | +| app/controllers/comments_controller.rb:9:5:9:31 | call to filtered_parameters | +| app/controllers/foo/bars_controller.rb:10:27:10:33 | call to cookies | +| app/controllers/foo/bars_controller.rb:13:21:13:26 | call to params | +| app/controllers/foo/bars_controller.rb:14:10:14:15 | call to params | +| app/controllers/foo/bars_controller.rb:21:21:21:26 | call to params | +| app/controllers/foo/bars_controller.rb:22:10:22:15 | call to params | diff --git a/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.ql b/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.ql index 5b1275595ea..f7931ea7569 100644 --- a/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.ql +++ b/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.ql @@ -2,6 +2,7 @@ private import codeql.ruby.AST private import codeql.ruby.frameworks.ActionDispatch private import codeql.ruby.frameworks.ActionController private import codeql.ruby.ApiGraphs +private import codeql.ruby.Concepts private import codeql.ruby.frameworks.data.ModelsAsData private import codeql.ruby.DataFlow private import codeql.ruby.Regexp as RE @@ -36,3 +37,5 @@ query predicate mimeTypeMatchRegExpInterpretations( ) { any() } + +query predicate requestInputAccesses(Http::Server::RequestInputAccess a) { any() } From 9f5c73cf6353b9212e763ebb4ad92d80d196e9e0 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 23 May 2023 15:18:32 +0100 Subject: [PATCH 086/739] Ruby: add a test case for instantiating ActionDispatch::Request directly --- .../frameworks/action_dispatch/ActionDispatch.expected | 5 +++-- .../action_dispatch/app/controllers/comments_controller.rb | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.expected b/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.expected index 74e9b30b19a..71327350941 100644 --- a/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.expected +++ b/ruby/ql/test/library-tests/frameworks/action_dispatch/ActionDispatch.expected @@ -36,8 +36,8 @@ actionDispatchRoutes actionDispatchControllerMethods | app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index | | app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show | -| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:2:3:36:5 | index | -| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:38:3:39:5 | show | +| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:2:3:39:5 | index | +| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:41:3:42:5 | show | | app/config/routes.rb:7:5:7:37 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote | | app/config/routes.rb:27:3:27:48 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show | | app/config/routes.rb:28:3:28:50 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show | @@ -74,6 +74,7 @@ requestInputAccesses | app/controllers/comments_controller.rb:7:5:7:28 | call to query_parameters | | app/controllers/comments_controller.rb:8:5:8:30 | call to request_parameters | | app/controllers/comments_controller.rb:9:5:9:31 | call to filtered_parameters | +| app/controllers/comments_controller.rb:38:5:38:14 | call to params | | app/controllers/foo/bars_controller.rb:10:27:10:33 | call to cookies | | app/controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | app/controllers/foo/bars_controller.rb:14:10:14:15 | call to params | diff --git a/ruby/ql/test/library-tests/frameworks/action_dispatch/app/controllers/comments_controller.rb b/ruby/ql/test/library-tests/frameworks/action_dispatch/app/controllers/comments_controller.rb index 57fac7797bd..77918c53943 100644 --- a/ruby/ql/test/library-tests/frameworks/action_dispatch/app/controllers/comments_controller.rb +++ b/ruby/ql/test/library-tests/frameworks/action_dispatch/app/controllers/comments_controller.rb @@ -33,6 +33,9 @@ class CommentsController < ApplicationController response.last_modified = Date.yesterday response.weak_etag = "value" response.strong_etag = "value" + + req = ActionDispatch::Request.new(request.env) + req.params end def show From 9ccfec0571ed0b43aa999a3dd6e7054932f04a52 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 23 May 2023 15:26:52 +0100 Subject: [PATCH 087/739] Ruby: move actiondispatch components to an internal subdirectory --- ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll | 6 +++--- .../ruby/frameworks/actiondispatch/{ => internal}/Mime.qll | 0 .../frameworks/actiondispatch/{ => internal}/Request.qll | 0 .../frameworks/actiondispatch/{ => internal}/Routing.qll | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/{ => internal}/Mime.qll (100%) rename ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/{ => internal}/Request.qll (100%) rename ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/{ => internal}/Routing.qll (100%) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll index 1493307982f..fbd36e637cf 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionDispatch.qll @@ -8,9 +8,9 @@ * Version: 7.1.0. */ module ActionDispatch { - private import actiondispatch.Mime - private import actiondispatch.Request - import actiondispatch.Routing + private import actiondispatch.internal.Mime + private import actiondispatch.internal.Request + import actiondispatch.internal.Routing class MimeTypeMatchRegExpInterpretation = Mime::MimeTypeMatchRegExpInterpretation; } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Mime.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Mime.qll similarity index 100% rename from ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Mime.qll rename to ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Mime.qll diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll similarity index 100% rename from ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Request.qll rename to ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Routing.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Routing.qll similarity index 100% rename from ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/Routing.qll rename to ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Routing.qll From deee3143700d507ef7c7f8f0c21b9cf1008844e2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Thu, 4 May 2023 13:21:46 +0200 Subject: [PATCH 088/739] Python/Ruby: Optimize join-order in `TypeTracker::[small]step` --- .../dataflow/new/internal/TypeTracker.qll | 170 ++++++++++++++++-- .../codeql/ruby/typetracking/TypeTracker.qll | 170 ++++++++++++++++-- 2 files changed, 320 insertions(+), 20 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll index d4d9e1f31f5..4be26f6cea9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll @@ -224,6 +224,74 @@ private module Cached { private import Cached +pragma[nomagic] +private predicate stepNoCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { + stepNoCall(nodeFrom, _, summary) +} + +bindingset[nodeFrom, t] +pragma[inline_late] +pragma[noopt] +private TypeTracker stepNoCallInlineLate( + TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo +) { + exists(StepSummary summary | + stepNoCallProj(nodeFrom, summary) and + result = t.append(summary) and + stepNoCall(nodeFrom, nodeTo, summary) + ) +} + +pragma[nomagic] +private predicate stepCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { + stepCall(nodeFrom, _, summary) +} + +bindingset[nodeFrom, t] +pragma[inline_late] +pragma[noopt] +private TypeTracker stepCallInlineLate( + TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo +) { + exists(StepSummary summary | + stepCallProj(nodeFrom, summary) and + result = t.append(summary) and + stepCall(nodeFrom, nodeTo, summary) + ) +} + +pragma[nomagic] +private predicate smallstepNoCallProj(Node nodeFrom, StepSummary summary) { + smallstepNoCall(nodeFrom, _, summary) +} + +bindingset[nodeFrom, t] +pragma[inline_late] +pragma[noopt] +private TypeTracker smallstepNoCallInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { + exists(StepSummary summary | + smallstepNoCallProj(nodeFrom, summary) and + result = t.append(summary) and + smallstepNoCall(nodeFrom, nodeTo, summary) + ) +} + +pragma[nomagic] +private predicate smallstepCallProj(Node nodeFrom, StepSummary summary) { + smallstepCall(nodeFrom, _, summary) +} + +bindingset[nodeFrom, t] +pragma[inline_late] +pragma[noopt] +private TypeTracker smallstepCallInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { + exists(StepSummary summary | + smallstepCallProj(nodeFrom, summary) and + result = t.append(summary) and + smallstepCall(nodeFrom, nodeTo, summary) + ) +} + /** * Holds if `nodeFrom` is being written to the `content` of the object in `nodeTo`. * @@ -296,6 +364,24 @@ class StepSummary extends TStepSummary { /** Provides predicates for updating step summaries (`StepSummary`s). */ module StepSummary { + /** + * Gets the summary that corresponds to having taken a forwards + * inter-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + predicate stepCall = Cached::stepCall/3; + + /** + * Gets the summary that corresponds to having taken a forwards + * intra-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + predicate stepNoCall = Cached::stepNoCall/3; + /** * Gets the summary that corresponds to having taken a forwards * heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. @@ -313,6 +399,24 @@ module StepSummary { stepCall(nodeFrom, nodeTo, summary) } + /** + * Gets the summary that corresponds to having taken a forwards + * inter-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + predicate smallstepNoCall = Cached::smallstepNoCall/3; + + /** + * Gets the summary that corresponds to having taken a forwards + * intra-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + predicate smallstepCall = Cached::smallstepCall/3; + /** * Gets the summary that corresponds to having taken a forwards * local, heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. @@ -425,16 +529,66 @@ class TypeTracker extends TTypeTracker { */ TypeTracker continue() { content = noContent() and result = this } + /** + * Gets the summary that corresponds to having taken a forwards + * intra-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + pragma[inline] + TypeTracker stepNoCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { + result = stepNoCallInlineLate(this, nodeFrom, nodeTo) + } + + /** + * Gets the summary that corresponds to having taken a forwards + * inter-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + pragma[inline] + TypeTracker stepCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { + result = stepCallInlineLate(this, nodeFrom, nodeTo) + } + /** * Gets the summary that corresponds to having taken a forwards * heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. */ pragma[inline] TypeTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - exists(StepSummary summary | - StepSummary::step(nodeFrom, pragma[only_bind_out](nodeTo), pragma[only_bind_into](summary)) and - result = this.append(pragma[only_bind_into](summary)) - ) + result = this.stepNoCall(nodeFrom, nodeTo) + or + result = this.stepCall(nodeFrom, nodeTo) + } + + /** + * Gets the summary that corresponds to having taken a forwards + * intra-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + pragma[inline] + TypeTracker smallstepNoCall(Node nodeFrom, Node nodeTo) { + result = smallstepNoCallInlineLate(this, nodeFrom, nodeTo) + or + simpleLocalFlowStep(nodeFrom, nodeTo) and + result = this + } + + /** + * Gets the summary that corresponds to having taken a forwards + * inter-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + pragma[inline] + TypeTracker smallstepCall(Node nodeFrom, Node nodeTo) { + result = smallstepCallInlineLate(this, nodeFrom, nodeTo) } /** @@ -463,13 +617,9 @@ class TypeTracker extends TTypeTracker { */ pragma[inline] TypeTracker smallstep(Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - StepSummary::smallstep(nodeFrom, nodeTo, summary) and - result = this.append(summary) - ) + result = this.smallstepNoCall(nodeFrom, nodeTo) or - simpleLocalFlowStep(nodeFrom, nodeTo) and - result = this + result = this.smallstepCall(nodeFrom, nodeTo) } } diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll index d4d9e1f31f5..4be26f6cea9 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll @@ -224,6 +224,74 @@ private module Cached { private import Cached +pragma[nomagic] +private predicate stepNoCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { + stepNoCall(nodeFrom, _, summary) +} + +bindingset[nodeFrom, t] +pragma[inline_late] +pragma[noopt] +private TypeTracker stepNoCallInlineLate( + TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo +) { + exists(StepSummary summary | + stepNoCallProj(nodeFrom, summary) and + result = t.append(summary) and + stepNoCall(nodeFrom, nodeTo, summary) + ) +} + +pragma[nomagic] +private predicate stepCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { + stepCall(nodeFrom, _, summary) +} + +bindingset[nodeFrom, t] +pragma[inline_late] +pragma[noopt] +private TypeTracker stepCallInlineLate( + TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo +) { + exists(StepSummary summary | + stepCallProj(nodeFrom, summary) and + result = t.append(summary) and + stepCall(nodeFrom, nodeTo, summary) + ) +} + +pragma[nomagic] +private predicate smallstepNoCallProj(Node nodeFrom, StepSummary summary) { + smallstepNoCall(nodeFrom, _, summary) +} + +bindingset[nodeFrom, t] +pragma[inline_late] +pragma[noopt] +private TypeTracker smallstepNoCallInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { + exists(StepSummary summary | + smallstepNoCallProj(nodeFrom, summary) and + result = t.append(summary) and + smallstepNoCall(nodeFrom, nodeTo, summary) + ) +} + +pragma[nomagic] +private predicate smallstepCallProj(Node nodeFrom, StepSummary summary) { + smallstepCall(nodeFrom, _, summary) +} + +bindingset[nodeFrom, t] +pragma[inline_late] +pragma[noopt] +private TypeTracker smallstepCallInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { + exists(StepSummary summary | + smallstepCallProj(nodeFrom, summary) and + result = t.append(summary) and + smallstepCall(nodeFrom, nodeTo, summary) + ) +} + /** * Holds if `nodeFrom` is being written to the `content` of the object in `nodeTo`. * @@ -296,6 +364,24 @@ class StepSummary extends TStepSummary { /** Provides predicates for updating step summaries (`StepSummary`s). */ module StepSummary { + /** + * Gets the summary that corresponds to having taken a forwards + * inter-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + predicate stepCall = Cached::stepCall/3; + + /** + * Gets the summary that corresponds to having taken a forwards + * intra-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + predicate stepNoCall = Cached::stepNoCall/3; + /** * Gets the summary that corresponds to having taken a forwards * heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. @@ -313,6 +399,24 @@ module StepSummary { stepCall(nodeFrom, nodeTo, summary) } + /** + * Gets the summary that corresponds to having taken a forwards + * inter-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + predicate smallstepNoCall = Cached::smallstepNoCall/3; + + /** + * Gets the summary that corresponds to having taken a forwards + * intra-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + predicate smallstepCall = Cached::smallstepCall/3; + /** * Gets the summary that corresponds to having taken a forwards * local, heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. @@ -425,16 +529,66 @@ class TypeTracker extends TTypeTracker { */ TypeTracker continue() { content = noContent() and result = this } + /** + * Gets the summary that corresponds to having taken a forwards + * intra-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + pragma[inline] + TypeTracker stepNoCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { + result = stepNoCallInlineLate(this, nodeFrom, nodeTo) + } + + /** + * Gets the summary that corresponds to having taken a forwards + * inter-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + pragma[inline] + TypeTracker stepCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { + result = stepCallInlineLate(this, nodeFrom, nodeTo) + } + /** * Gets the summary that corresponds to having taken a forwards * heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. */ pragma[inline] TypeTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - exists(StepSummary summary | - StepSummary::step(nodeFrom, pragma[only_bind_out](nodeTo), pragma[only_bind_into](summary)) and - result = this.append(pragma[only_bind_into](summary)) - ) + result = this.stepNoCall(nodeFrom, nodeTo) + or + result = this.stepCall(nodeFrom, nodeTo) + } + + /** + * Gets the summary that corresponds to having taken a forwards + * intra-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + pragma[inline] + TypeTracker smallstepNoCall(Node nodeFrom, Node nodeTo) { + result = smallstepNoCallInlineLate(this, nodeFrom, nodeTo) + or + simpleLocalFlowStep(nodeFrom, nodeTo) and + result = this + } + + /** + * Gets the summary that corresponds to having taken a forwards + * inter-procedural step from `nodeFrom` to `nodeTo`. + * + * This predicate should normally not be used; consider using `step` + * instead. + */ + pragma[inline] + TypeTracker smallstepCall(Node nodeFrom, Node nodeTo) { + result = smallstepCallInlineLate(this, nodeFrom, nodeTo) } /** @@ -463,13 +617,9 @@ class TypeTracker extends TTypeTracker { */ pragma[inline] TypeTracker smallstep(Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - StepSummary::smallstep(nodeFrom, nodeTo, summary) and - result = this.append(summary) - ) + result = this.smallstepNoCall(nodeFrom, nodeTo) or - simpleLocalFlowStep(nodeFrom, nodeTo) and - result = this + result = this.smallstepCall(nodeFrom, nodeTo) } } From 13ada1e6ad4643bf146b456c26fbd844d752dbdb Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Thu, 4 May 2023 13:21:41 +0200 Subject: [PATCH 089/739] Ruby: Remove canonical return nodes --- ruby/ql/lib/codeql/ruby/ApiGraphs.qll | 4 +- .../dataflow/internal/DataFlowDispatch.qll | 227 ++++++++++++------ .../dataflow/internal/DataFlowPrivate.qll | 137 ++++------- .../ruby/dataflow/internal/DataFlowPublic.qll | 31 ++- .../codeql/ruby/frameworks/ActiveRecord.qll | 7 +- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 2 +- .../frameworks/actioncontroller/Filters.qll | 4 +- .../ruby/typetracking/TypeTrackerSpecific.qll | 41 +--- .../library-tests/dataflow/local/Nodes.ql | 2 +- .../type-tracker/TypeTracker.expected | 203 ---------------- 10 files changed, 235 insertions(+), 423 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ApiGraphs.qll b/ruby/ql/lib/codeql/ruby/ApiGraphs.qll index b1320d047cc..1cf4c445781 100644 --- a/ruby/ql/lib/codeql/ruby/ApiGraphs.qll +++ b/ruby/ql/lib/codeql/ruby/ApiGraphs.qll @@ -778,7 +778,7 @@ module API { or exists(TypeTracker t2 | result = trackUseNode(src, t2).track(t2, t) and - not result instanceof DataFlowPrivate::SelfParameterNode + not result instanceof DataFlow::SelfParameterNode ) } @@ -800,7 +800,7 @@ module API { or exists(TypeBackTracker t2, DataFlow::LocalSourceNode mid | mid = trackDefNode(rhs, t2) and - not mid instanceof DataFlowPrivate::SelfParameterNode and + not mid instanceof DataFlow::SelfParameterNode and result = mid.backtrack(t2, t) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index 2b4c030707b..410867c7ead 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -10,16 +10,17 @@ private import codeql.ruby.dataflow.FlowSummary private import codeql.ruby.dataflow.SSA /** - * A `LocalSourceNode` for a `self` variable. This is either an implicit `self` - * parameter or an implicit SSA entry definition. + * A `LocalSourceNode` for a `self` variable. This is the implicit `self` + * parameter, when it exists, otherwise the implicit SSA entry definition. */ private class SelfLocalSourceNode extends DataFlow::LocalSourceNode { private SelfVariable self; SelfLocalSourceNode() { - self = this.(SelfParameterNode).getSelfVariable() + self = this.(SelfParameterNodeImpl).getSelfVariable() or - self = this.(SsaSelfDefinitionNode).getVariable() + self = this.(SsaSelfDefinitionNode).getVariable() and + not LocalFlow::localFlowSsaParamInput(_, this) } /** Gets the `self` variable. */ @@ -469,23 +470,43 @@ private module Cached { import Cached +pragma[nomagic] +private predicate stepCallProj(DataFlow::LocalSourceNode nodeFrom, StepSummary summary) { + StepSummary::stepCall(nodeFrom, _, summary) +} + +pragma[nomagic] +private predicate isNotSelf(DataFlow::Node n) { not n instanceof SelfParameterNodeImpl } + pragma[nomagic] private DataFlow::LocalSourceNode trackModuleAccess(Module m, TypeTracker t) { t.start() and m = resolveConstantReadAccess(result.asExpr().getExpr()) or - exists(TypeTracker t2, StepSummary summary | - result = trackModuleAccessRec(m, t2, summary) and t = t2.append(summary) + // We exclude steps into `self` parameters, and instead rely on the type of the + // enclosing module + isNotSelf(result) and + ( + exists(TypeTracker t2 | t = t2.stepNoCall(trackModuleAccess(m, t2), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(trackModuleAccessCall(m, t, summary), result, summary) + ) ) } -/** - * We exclude steps into `self` parameters, and instead rely on the type of the - * enclosing module. - */ +bindingset[t, summary] +pragma[inline_late] +private TypeTracker append(TypeTracker t, StepSummary summary) { result = t.append(summary) } + pragma[nomagic] -private DataFlow::LocalSourceNode trackModuleAccessRec(Module m, TypeTracker t, StepSummary summary) { - StepSummary::step(trackModuleAccess(m, t), result, summary) and - not result instanceof SelfParameterNode +private DataFlow::LocalSourceNode trackModuleAccessCall(Module m, TypeTracker t, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = trackModuleAccess(m, t2) and + stepCallProj(result, summary) and + t = append(t2, summary) + ) } pragma[nomagic] @@ -498,7 +519,7 @@ private predicate hasUserDefinedNew(Module m) { exists(DataFlow::MethodNode method | // not `getAnAncestor` because singleton methods cannot be included singletonMethodOnModule(method.asCallableAstNode(), "new", m.getSuperClass*()) and - not method.getSelfParameter().getAMethodCall("allocate").flowsTo(method.getAReturningNode()) + not method.getSelfParameter().getAMethodCall("allocate").flowsTo(method.getAReturnNode()) ) } @@ -610,6 +631,49 @@ private predicate isInstance(DataFlow::Node n, Module tp, boolean exact) { exact = false } +private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary) { + localFlowStepTypeTracker(nodeFrom, nodeTo) and + summary.toString() = "level" +} + +pragma[nomagic] +private predicate hasAdjacentTypeCheckedReads(DataFlow::Node node) { + hasAdjacentTypeCheckedReads(_, _, node.asExpr(), _) +} + +pragma[nomagic] +private predicate smallStepNoCallForTrackInstance0( + DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary +) { + // We exclude steps into `self` parameters. For those, we instead rely on the type of + // the enclosing module + StepSummary::smallstepNoCall(nodeFrom, nodeTo, summary) and + isNotSelf(nodeTo) + or + // We exclude steps into type checked variables. For those, we instead rely on the + // type being checked against + localFlowStep(nodeFrom, nodeTo, summary) and + not hasAdjacentTypeCheckedReads(nodeTo) +} + +pragma[nomagic] +private predicate smallStepNoCallForTrackInstance0Proj(DataFlow::Node nodeFrom, StepSummary summary) { + smallStepNoCallForTrackInstance0(nodeFrom, _, summary) +} + +bindingset[t, nodeFrom] +pragma[inline_late] +pragma[noopt] +private TypeTracker smallStepNoCallForTrackInstance( + TypeTracker t, DataFlow::Node nodeFrom, DataFlow::Node nodeTo +) { + exists(StepSummary summary | + smallStepNoCallForTrackInstance0Proj(nodeFrom, summary) and + result = t.append(summary) and + smallStepNoCallForTrackInstance0(nodeFrom, nodeTo, summary) + ) +} + pragma[nomagic] private DataFlow::Node trackInstance(Module tp, boolean exact, TypeTracker t) { t.start() and @@ -631,35 +695,33 @@ private DataFlow::Node trackInstance(Module tp, boolean exact, TypeTracker t) { ) ) or - exists(TypeTracker t2, StepSummary summary | - result = trackInstanceRec(tp, t2, exact, summary) and t = t2.append(summary) + exists(TypeTracker t2 | + t = smallStepNoCallForTrackInstance(t2, trackInstance(tp, exact, t2), result) + ) + or + // We exclude steps into `self` parameters. For those, we instead rely on the type of + // the enclosing module + exists(StepSummary summary | + // non-linear recursion + StepSummary::smallstepCall(trackInstanceCall(tp, t, exact, summary), result, summary) and + isNotSelf(result) ) } -private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary) { - localFlowStepTypeTracker(nodeFrom, nodeTo) and - summary.toString() = "level" +pragma[nomagic] +private predicate smallStepCallProj(DataFlow::Node nodeFrom, StepSummary summary) { + StepSummary::smallstepCall(nodeFrom, _, summary) } pragma[nomagic] -private predicate hasAdjacentTypeCheckedReads(DataFlow::Node node) { - hasAdjacentTypeCheckedReads(_, _, node.asExpr(), _) -} - -/** - * We exclude steps into `self` parameters and type checked variables. For those, - * we instead rely on the type of the enclosing module resp. the type being checked - * against, and apply an open-world assumption when determining possible dispatch - * targets. - */ -pragma[nomagic] -private DataFlow::Node trackInstanceRec(Module tp, TypeTracker t, boolean exact, StepSummary summary) { - exists(DataFlow::Node mid | mid = trackInstance(tp, exact, t) | - StepSummary::smallstep(mid, result, summary) and - not result instanceof SelfParameterNode - or - localFlowStep(mid, result, summary) and - not hasAdjacentTypeCheckedReads(result) +private DataFlow::Node trackInstanceCall( + Module tp, TypeTracker t, boolean exact, StepSummary summary +) { + exists(TypeTracker t2 | + // non-linear recursion + result = trackInstance(tp, exact, t2) and + smallStepCallProj(result, summary) and + t = append(t2, summary) ) } @@ -710,20 +772,27 @@ pragma[nomagic] private DataFlow::LocalSourceNode trackBlock(Block block, TypeTracker t) { t.start() and result.asExpr().getExpr() = block or - exists(TypeTracker t2, StepSummary summary | - result = trackBlockRec(block, t2, summary) and - t = t2.append(summary) + // We exclude steps into `self` parameters, which may happen when the code + // base contains implementations of `call`. + isNotSelf(result) and + ( + exists(TypeTracker t2 | t = t2.stepNoCall(trackBlock(block, t2), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(trackBlockCall(block, t, summary), result, summary) + ) ) } -/** - * We exclude steps into `self` parameters, which may happen when the code - * base contains implementations of `call`. - */ pragma[nomagic] -private DataFlow::LocalSourceNode trackBlockRec(Block block, TypeTracker t, StepSummary summary) { - StepSummary::step(trackBlock(block, t), result, summary) and - not result instanceof SelfParameterNode +private DataFlow::LocalSourceNode trackBlockCall(Block block, TypeTracker t, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = trackBlock(block, t2) and + stepCallProj(result, summary) and + t = append(t2, summary) + ) } pragma[nomagic] @@ -942,7 +1011,7 @@ private predicate paramReturnFlow( | nodeFromPreExpr = p.getParameter().(NamedParameter).getVariable().getAnAccess() or - nodeFromPreExpr = p.(SelfParameterNode).getSelfVariable().getAnAccess() + nodeFromPreExpr = p.(SelfParameterNodeImpl).getSelfVariable().getAnAccess() ) } @@ -951,31 +1020,53 @@ private DataFlow::Node trackSingletonMethodOnInstance(MethodBase method, string t.start() and singletonMethodOnInstance(method, name, result.asExpr().getExpr()) or - exists(TypeTracker t2, StepSummary summary | - result = trackSingletonMethodOnInstanceRec(method, name, t2, summary) and - t = t2.append(summary) and - // Stop flow at redefinitions. - // - // Example: - // ```rb - // def x.foo; end - // def x.foo; end - // x.foo # <- we want to resolve this call to the second definition only - // ``` - not singletonMethodOnInstance(_, name, result.asExpr().getExpr()) - ) + ( + exists(TypeTracker t2 | + t = t2.smallstepNoCall(trackSingletonMethodOnInstance(method, name, t2), result) + ) + or + exists(StepSummary summary | + // non-linear recursion + smallStepCallForTrackSingletonMethodOnInstance(trackSingletonMethodOnInstanceCall(method, + name, t, summary), result, summary) + ) + ) and + // Stop flow at redefinitions. + // + // Example: + // ```rb + // def x.foo; end + // def x.foo; end + // x.foo # <- we want to resolve this call to the second definition only + // ``` + not singletonMethodOnInstance(_, name, result.asExpr().getExpr()) } pragma[nomagic] -private DataFlow::Node trackSingletonMethodOnInstanceRec( +private predicate smallStepCallForTrackSingletonMethodOnInstance( + DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary +) { + StepSummary::smallstepCall(nodeFrom, nodeTo, summary) + or + paramReturnFlow(nodeFrom, nodeTo, summary) +} + +pragma[nomagic] +private predicate smallStepCallForTrackSingletonMethodOnInstanceProj( + DataFlow::Node nodeFrom, StepSummary summary +) { + smallStepCallForTrackSingletonMethodOnInstance(nodeFrom, _, summary) +} + +pragma[nomagic] +private DataFlow::Node trackSingletonMethodOnInstanceCall( MethodBase method, string name, TypeTracker t, StepSummary summary ) { - exists(DataFlow::Node mid | mid = trackSingletonMethodOnInstance(method, name, t) | - StepSummary::smallstep(mid, result, summary) - or - paramReturnFlow(mid, result, summary) - or - localFlowStep(mid, result, summary) + exists(TypeTracker t2 | + // non-linear recursion + result = trackSingletonMethodOnInstance(method, name, t2) and + smallStepCallForTrackSingletonMethodOnInstanceProj(result, summary) and + t = append(t2, summary) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index d6908827ba9..6a7d87e9bd5 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -131,10 +131,10 @@ module LocalFlow { /** * Holds if `nodeFrom` is a parameter node, and `nodeTo` is a corresponding SSA node. */ - predicate localFlowSsaParamInput(Node nodeFrom, Node nodeTo) { + predicate localFlowSsaParamInput(Node nodeFrom, SsaDefinitionExtNode nodeTo) { nodeTo = getParameterDefNode(nodeFrom.(ParameterNodeImpl).getParameter()) or - nodeTo = getSelfParameterDefNode(nodeFrom.(SelfParameterNode).getMethod()) + nodeTo = getSelfParameterDefNode(nodeFrom.(SelfParameterNodeImpl).getMethod()) } /** @@ -143,14 +143,13 @@ module LocalFlow { * * This is intended to recover from flow not currently recognised by ordinary capture flow. */ - predicate localFlowSsaParamCaptureInput(Node nodeFrom, Node nodeTo) { - exists(Ssa::CapturedEntryDefinition def, ParameterNodeImpl p | - (nodeFrom = p or LocalFlow::localFlowSsaParamInput(p, nodeFrom)) and + predicate localFlowSsaParamCaptureInput(ParameterNodeImpl nodeFrom, Node nodeTo) { + exists(Ssa::CapturedEntryDefinition def | nodeTo.(SsaDefinitionExtNode).getDefinitionExt() = def | - p.getParameter().(NamedParameter).getVariable() = def.getSourceVariable() + nodeFrom.getParameter().(NamedParameter).getVariable() = def.getSourceVariable() or - p.(SelfParameterNode).getSelfVariable() = def.getSourceVariable() + nodeFrom.(SelfParameterNode).getSelfVariable() = def.getSourceVariable() ) } @@ -164,7 +163,7 @@ module LocalFlow { /** * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving - * SSA definition `def`. + * some SSA definition. */ private predicate localSsaFlowStep(Node nodeFrom, Node nodeTo) { exists(SsaImpl::DefinitionExt def | @@ -182,6 +181,8 @@ module LocalFlow { // Flow into phi (read) SSA definition node from def localFlowSsaInputFromDef(nodeFrom, def, nodeTo) ) + or + localFlowSsaParamInput(nodeFrom, nodeTo) // TODO // or // // Flow into uncertain SSA definition @@ -223,6 +224,13 @@ module LocalFlow { op.getExpr() instanceof BinaryLogicalOperation and nodeFrom.asExpr() = op.getAnOperand() ) + or + nodeTo.(ParameterNodeImpl).getParameter() = + any(NamedParameter p | + p.(OptionalParameter).getDefaultValue() = nodeFrom.asExpr().getExpr() + or + p.(KeywordParameter).getDefaultValue() = nodeFrom.asExpr().getExpr() + ) } } @@ -279,12 +287,6 @@ private module Cached { newtype TNode = TExprNode(CfgNodes::ExprCfgNode n) { TaintTrackingPrivate::forceCachingInSameStage() } or TReturningNode(CfgNodes::ReturningCfgNode n) or - TSynthReturnNode(CfgScope scope, ReturnKind kind) { - exists(ReturningNode ret | - ret.(NodeImpl).getCfgScope() = scope and - ret.getKind() = kind - ) - } or TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) or TNormalParameterNode(Parameter p) { p instanceof SimpleParameter or @@ -326,12 +328,6 @@ private module Cached { TNormalParameterNode or TBlockParameterNode or TSelfParameterNode or TSynthHashSplatParameterNode or TSummaryParameterNode; - private predicate defaultValueFlow(NamedParameter p, ExprNode e) { - p.(OptionalParameter).getDefaultValue() = e.getExprNode().getExpr() - or - p.(KeywordParameter).getDefaultValue() = e.getExprNode().getExpr() - } - cached Location getLocation(NodeImpl n) { result = n.getLocationImpl() } @@ -346,12 +342,6 @@ private module Cached { predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { LocalFlow::localFlowStepCommon(nodeFrom, nodeTo) or - defaultValueFlow(nodeTo.(ParameterNodeImpl).getParameter(), nodeFrom) - or - LocalFlow::localFlowSsaParamInput(nodeFrom, nodeTo) - or - nodeTo.(SynthReturnNode).getAnInput() = nodeFrom - or LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo) and not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) or @@ -373,10 +363,6 @@ private module Cached { predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) { LocalFlow::localFlowStepCommon(nodeFrom, nodeTo) or - defaultValueFlow(nodeTo.(ParameterNodeImpl).getParameter(), nodeFrom) - or - LocalFlow::localFlowSsaParamInput(nodeFrom, nodeTo) - or LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo) or // Simple flow through library code is included in the exposed local @@ -386,19 +372,11 @@ private module Cached { /** * This is the local flow predicate that is used in type tracking. - * - * This needs to exclude `localFlowSsaParamInput` due to a performance trick - * in type tracking, where such steps are treated as call steps. */ cached predicate localFlowStepTypeTracker(Node nodeFrom, Node nodeTo) { LocalFlow::localFlowStepCommon(nodeFrom, nodeTo) or - exists(NamedParameter p | - defaultValueFlow(p, nodeFrom) and - nodeTo = LocalFlow::getParameterDefNode(p) - ) - or LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo) or // Flow into phi node from read @@ -440,12 +418,10 @@ private module Cached { n instanceof ExprNode and not reachedFromExprOrEntrySsaDef(n) or - // Ensure all entry SSA definitions are local sources -- for parameters, this - // is needed by type tracking - entrySsaDefinition(n) - or - // Needed for flow out in type tracking - n instanceof SynthReturnNode + // Ensure all entry SSA definitions are local sources, except those that correspond + // to parameters (which are themselves local sources) + entrySsaDefinition(n) and + not LocalFlow::localFlowSsaParamInput(_, n) or // Needed for stores in type tracking TypeTrackerSpecific::storeStepIntoSourceNode(_, n, _) @@ -507,7 +483,7 @@ private module Cached { */ cached predicate exprNodeReturnedFromCached(ExprNode e, Callable c) { - exists(ReturningNode r | + exists(ReturnNode r | nodeGetEnclosingCallable(r).asCallable() = c and ( r.(ExplicitReturnNode).getReturningNode().getReturnedValueNode() = e.asExpr() or @@ -542,8 +518,6 @@ predicate nodeIsHidden(Node n) { or n instanceof SummaryParameterNode or - n instanceof SynthReturnNode - or n instanceof SynthHashSplatParameterNode or n instanceof SynthHashSplatArgumentNode @@ -658,10 +632,10 @@ private module ParameterNodes { * The value of the `self` parameter at function entry, viewed as a node in a data * flow graph. */ - class SelfParameterNode extends ParameterNodeImpl, TSelfParameterNode { + class SelfParameterNodeImpl extends ParameterNodeImpl, TSelfParameterNode { private MethodBase method; - SelfParameterNode() { this = TSelfParameterNode(method) } + SelfParameterNodeImpl() { this = TSelfParameterNode(method) } final MethodBase getMethod() { result = method } @@ -937,24 +911,26 @@ private class NewCall extends DataFlowCall { NewCall() { this.asCall().getExpr().(MethodCall).getMethodName() = "new" } } -/** A data-flow node that represents a value syntactically returned by a callable. */ -abstract class ReturningNode extends Node { - /** Gets the kind of this return node. */ - abstract ReturnKind getKind(); - - pragma[nomagic] - predicate hasKind(ReturnKind kind, CfgScope scope) { - kind = this.getKind() and - scope = this.(NodeImpl).getCfgScope() - } -} - /** A data-flow node that represents a value returned by a callable. */ abstract class ReturnNode extends Node { /** Gets the kind of this return node. */ abstract ReturnKind getKind(); } +/** A data-flow node that represents a value returned by a callable. */ +abstract class SourceReturnNode extends ReturnNode { + /** Gets the kind of this return node. */ + abstract ReturnKind getKindSource(); // only exists to avoid spurious negative recursion + + final override ReturnKind getKind() { result = this.getKindSource() } + + pragma[nomagic] + predicate hasKind(ReturnKind kind, CfgScope scope) { + kind = this.getKindSource() and + scope = this.(NodeImpl).getCfgScope() + } +} + private module ReturnNodes { private predicate isValid(CfgNodes::ReturningCfgNode node) { exists(ReturningStmt stmt, Callable scope | @@ -976,14 +952,14 @@ private module ReturnNodes { * A data-flow node that represents an expression explicitly returned by * a callable. */ - class ExplicitReturnNode extends ReturningNode, ReturningStatementNode { + class ExplicitReturnNode extends SourceReturnNode, ReturningStatementNode { ExplicitReturnNode() { isValid(n) and n.getASuccessor().(CfgNodes::AnnotatedExitNode).isNormal() and n.getScope() instanceof Callable } - override ReturnKind getKind() { + override ReturnKind getKindSource() { if n.getNode() instanceof BreakStmt then result instanceof BreakReturnKind else @@ -1012,10 +988,10 @@ private module ReturnNodes { * a callable. An implicit return happens when an expression can be the * last thing that is evaluated in the body of the callable. */ - class ExprReturnNode extends ReturningNode, ExprNode { + class ExprReturnNode extends SourceReturnNode, ExprNode { ExprReturnNode() { exists(Callable c | implicitReturn(c, this) = c.getAStmt()) } - override ReturnKind getKind() { + override ReturnKind getKindSource() { exists(CfgScope scope | scope = this.(NodeImpl).getCfgScope() | if isUserDefinedNew(scope) then result instanceof NewReturnKind @@ -1040,7 +1016,7 @@ private module ReturnNodes { * the implicit `self` reference in `@x` will return data stored in the field * `x` out to the call `C.new`. */ - class InitializeReturnNode extends ExprPostUpdateNode, ReturningNode { + class InitializeReturnNode extends ExprPostUpdateNode, ReturnNode { InitializeReturnNode() { exists(Method initialize | this.getCfgScope() = initialize and @@ -1053,32 +1029,6 @@ private module ReturnNodes { override ReturnKind getKind() { result instanceof NewReturnKind } } - /** - * A synthetic data-flow node for joining flow from different syntactic - * returns into a single node. - * - * This node only exists to avoid computing the product of a large fan-in - * with a large fan-out. - */ - class SynthReturnNode extends NodeImpl, ReturnNode, TSynthReturnNode { - private CfgScope scope; - private ReturnKind kind; - - SynthReturnNode() { this = TSynthReturnNode(scope, kind) } - - /** Gets a syntactic return node that flows into this synthetic node. */ - pragma[nomagic] - ReturningNode getAnInput() { result.hasKind(kind, scope) } - - override ReturnKind getKind() { result = kind } - - override CfgScope getCfgScope() { result = scope } - - override Location getLocationImpl() { result = scope.getLocation() } - - override string toStringImpl() { result = "return " + kind + " in " + scope } - } - private class SummaryReturnNode extends SummaryNode, ReturnNode { private ReturnKind rk; @@ -1339,9 +1289,6 @@ private import PostUpdateNodes /** A node that performs a type cast. */ class CastNode extends Node { CastNode() { - // ensure that actual return nodes are included in the path graph - this instanceof ReturningNode - or // ensure that all variable assignments are included in the path graph this.(SsaDefinitionExtNode).getDefinitionExt() instanceof Ssa::WriteDefinition } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index 9d668e0b300..501cf70593e 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -195,10 +195,22 @@ class ParameterNode extends LocalSourceNode, TParameterNode instanceof Parameter /** Gets the parameter corresponding to this node, if any. */ final Parameter getParameter() { result = super.getParameter() } + /** Gets the callable that this parameter belongs to. */ + final Callable getCallable() { result = super.getCfgScope() } + /** Gets the name of the parameter, if any. */ final string getName() { result = this.getParameter().(NamedParameter).getName() } } +/** + * The value of an implicit `self` parameter at function entry, viewed as a node in a data + * flow graph. + */ +class SelfParameterNode extends ParameterNode instanceof SelfParameterNodeImpl { + /** Gets the underlying `self` variable. */ + final SelfVariable getSelfVariable() { result = super.getSelfVariable() } +} + /** * A data-flow node that is a source of local flow. */ @@ -328,9 +340,6 @@ private module Cached { exists(Node mid | hasLocalSource(mid, source) | localFlowStepTypeTracker(mid, sink) or - // Explicitly include the SSA param input step as type-tracking omits this step. - LocalFlow::localFlowSsaParamInput(mid, sink) - or LocalFlow::localFlowSsaParamCaptureInput(mid, sink) ) } @@ -1176,19 +1185,15 @@ class CallableNode extends StmtSequenceNode { result = this.getBlockParameter().getAMethodCall("call") } - /** - * Gets the canonical return node from this callable. - * - * Each callable has exactly one such node, and its location may not correspond - * to any particular return site - consider using `getAReturningNode` to get nodes - * whose locations correspond to return sites. - */ - Node getReturn() { result.(SynthReturnNode).getCfgScope() = callable } - /** * Gets a data flow node whose value is about to be returned by this callable. */ - Node getAReturningNode() { result = this.getReturn().(SynthReturnNode).getAnInput() } + Node getAReturnNode() { result.(ReturnNode).(NodeImpl).getCfgScope() = callable } + + /** + * DEPRECATED. Use `getAReturnNode` instead. + */ + deprecated Node getAReturningNode() { result = this.getAReturnNode() } } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 5869486ac91..fcca078f933 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -7,7 +7,6 @@ private import codeql.ruby.Concepts private import codeql.ruby.controlflow.CfgNodes private import codeql.ruby.DataFlow private import codeql.ruby.dataflow.internal.DataFlowDispatch -private import codeql.ruby.dataflow.internal.DataFlowPrivate private import codeql.ruby.ApiGraphs private import codeql.ruby.frameworks.Stdlib private import codeql.ruby.frameworks.Core @@ -319,19 +318,19 @@ private class ActiveRecordModelFinderCall extends ActiveRecordModelInstantiation // A `self` reference that may resolve to an active record model object private class ActiveRecordModelClassSelfReference extends ActiveRecordModelInstantiation, - SsaSelfDefinitionNode + DataFlow::SelfParameterNode { private ActiveRecordModelClass cls; ActiveRecordModelClassSelfReference() { exists(MethodBase m | - m = this.getCfgScope() and + m = this.getCallable() and m.getEnclosingModule() = cls and m = cls.getAMethod() ) and // In a singleton method, `self` refers to the class itself rather than an // instance of that class - not this.getSelfScope() instanceof SingletonMethod + not this.getSelfVariable().getDeclaringScope() instanceof SingletonMethod } final override ActiveRecordModelClass getClass() { result = cls } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index 693cd4c197c..49281c609bd 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -21,7 +21,7 @@ module Rack { AppCandidate() { call = this.getInstanceMethod("call") and call.getNumberOfParameters() = 1 and - call.getReturn() = trackRackResponse() + call.getAReturnNode() = trackRackResponse() } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index 97ea8de1cd6..bc1766580e9 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -412,9 +412,7 @@ module Filters { /** * Holds if `n` is the self parameter of method `m`. */ - private predicate selfParameter(DataFlowPrivate::SelfParameterNode n, Method m) { - m = n.getMethod() - } + private predicate selfParameter(DataFlow::SelfParameterNode n, Method m) { m = n.getCallable() } /** * A class defining additional jump steps arising from filters. diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll index 7283ffedf09..889d0abbed8 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll @@ -79,7 +79,7 @@ predicate jumpStep = DataFlowPrivate::jumpStep/2; /** Holds if there is direct flow from `param` to a return. */ pragma[nomagic] private predicate flowThrough(DataFlowPublic::ParameterNode param) { - exists(DataFlowPrivate::ReturningNode returnNode, DataFlowDispatch::ReturnKind rk | + exists(DataFlowPrivate::SourceReturnNode returnNode, DataFlowDispatch::ReturnKind rk | param.flowsTo(returnNode) and returnNode.hasKind(rk, param.(DataFlowPrivate::NodeImpl).getCfgScope()) | @@ -210,15 +210,7 @@ predicate callStep(ExprNodes::CallCfgNode call, Node arg, DataFlowPrivate::Param * recursion (or, at best, terrible performance), since identifying calls to library * methods is done using API graphs (which uses type tracking). */ -predicate callStep(Node nodeFrom, Node nodeTo) { - callStep(_, nodeFrom, nodeTo) - or - // In normal data-flow, this will be a local flow step. But for type tracking - // we model it as a call step, in order to avoid computing a potential - // self-cross product of all calls to a function that returns one of its parameters - // (only to later filter that flow out using `TypeTracker::append`). - DataFlowPrivate::LocalFlow::localFlowSsaParamInput(nodeFrom, nodeTo) -} +predicate callStep(Node nodeFrom, Node nodeTo) { callStep(_, nodeFrom, nodeTo) } /** * Holds if `nodeFrom` steps to `nodeTo` by being returned from a call. @@ -230,19 +222,13 @@ predicate callStep(Node nodeFrom, Node nodeTo) { predicate returnStep(Node nodeFrom, Node nodeTo) { exists(ExprNodes::CallCfgNode call | nodeFrom instanceof DataFlowPrivate::ReturnNode and + not nodeFrom instanceof DataFlowPrivate::InitializeReturnNode and nodeFrom.(DataFlowPrivate::NodeImpl).getCfgScope() = DataFlowDispatch::getTarget(call) and // deliberately do not include `getInitializeTarget`, since calls to `new` should not // get the return value from `initialize`. Any fields being set in the initializer // will reach all reads via `callStep` and `localFieldStep`. nodeTo.asExpr().getNode() = call.getNode() ) - or - // In normal data-flow, this will be a local flow step. But for type tracking - // we model it as a returning flow step, in order to avoid computing a potential - // self-cross product of all calls to a function that returns one of its parameters - // (only to later filter that flow out using `TypeTracker::append`). - nodeTo.(DataFlowPrivate::SynthReturnNode).getAnInput() = nodeFrom and - not nodeFrom instanceof DataFlowPrivate::InitializeReturnNode } /** @@ -598,26 +584,15 @@ private DataFlow::Node evaluateSummaryComponentStackLocal( pragma[only_bind_out](tail)) and stack = SCS::push(pragma[only_bind_out](head), pragma[only_bind_out](tail)) | - exists( - DataFlowDispatch::ArgumentPosition apos, DataFlowDispatch::ParameterPosition ppos, - DataFlowPrivate::ParameterNodeImpl p - | + exists(DataFlowDispatch::ArgumentPosition apos, DataFlowDispatch::ParameterPosition ppos | head = SummaryComponent::parameter(apos) and DataFlowDispatch::parameterMatch(ppos, apos) and - p.isSourceParameterOf(prev.asExpr().getExpr(), ppos) and - // We need to include both `p` and the SSA definition for `p`, since in type-tracking - // the step from `p` to the SSA definition is considered a call step. - result = - [p.(DataFlow::Node), DataFlowPrivate::LocalFlow::getParameterDefNode(p.getParameter())] + result.(DataFlowPrivate::ParameterNodeImpl).isSourceParameterOf(prev.asExpr().getExpr(), ppos) ) or - exists(DataFlowPrivate::SynthReturnNode ret | - head = SummaryComponent::return() and - ret.getCfgScope() = prev.asExpr().getExpr() and - // We need to include both `ret` and `ret.getAnInput()`, since in type-tracking - // the step from `ret.getAnInput()` to `ret` is considered a return step. - result = [ret.(DataFlow::Node), ret.getAnInput()] - ) + head = SummaryComponent::return() and + result.(DataFlowPrivate::ReturnNode).(DataFlowPrivate::NodeImpl).getCfgScope() = + prev.asExpr().getExpr() or exists(DataFlow::ContentSet content | head = SummaryComponent::withoutContent(content) and diff --git a/ruby/ql/test/library-tests/dataflow/local/Nodes.ql b/ruby/ql/test/library-tests/dataflow/local/Nodes.ql index 2f89f667625..88ee1c5b208 100644 --- a/ruby/ql/test/library-tests/dataflow/local/Nodes.ql +++ b/ruby/ql/test/library-tests/dataflow/local/Nodes.ql @@ -2,7 +2,7 @@ import codeql.ruby.AST import codeql.ruby.dataflow.internal.DataFlowPrivate import codeql.ruby.dataflow.internal.DataFlowDispatch -query predicate ret(ReturningNode node) { any() } +query predicate ret(SourceReturnNode node) { any() } query predicate arg(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { n.argumentOf(call, pos) and diff --git a/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected b/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected index bc7b35eb941..9a4277f4c0e 100644 --- a/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected +++ b/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected @@ -1,129 +1,72 @@ track | type_tracker.rb:1:1:10:3 | self (Container) | type tracker without call steps | type_tracker.rb:1:1:10:3 | self (Container) | -| type_tracker.rb:1:1:53:4 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:18:1:21:3 | self (positional) | | type_tracker.rb:1:1:53:4 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:18:1:21:3 | self in positional | -| type_tracker.rb:1:1:53:4 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:25:1:28:3 | self (keyword) | | type_tracker.rb:1:1:53:4 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:25:1:28:3 | self in keyword | | type_tracker.rb:1:1:53:4 | self (type_tracker.rb) | type tracker without call steps | type_tracker.rb:1:1:53:4 | self (type_tracker.rb) | | type_tracker.rb:2:5:5:7 | &block | type tracker without call steps | type_tracker.rb:2:5:5:7 | &block | | type_tracker.rb:2:5:5:7 | field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | field= | -| type_tracker.rb:2:5:5:7 | return return in field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= | -| type_tracker.rb:2:5:5:7 | return return in field= | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= | -| type_tracker.rb:2:5:5:7 | self (field=) | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) | -| type_tracker.rb:2:5:5:7 | self (field=) | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field | -| type_tracker.rb:2:5:5:7 | self (field=) | type tracker without call steps | type_tracker.rb:2:5:5:7 | self (field=) | -| type_tracker.rb:2:5:5:7 | self in field= | type tracker with call steps | type_tracker.rb:2:5:5:7 | self (field=) | -| type_tracker.rb:2:5:5:7 | self in field= | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) | | type_tracker.rb:2:5:5:7 | self in field= | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:2:5:5:7 | self in field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | self in field= | -| type_tracker.rb:2:16:2:18 | val | type tracker with call steps | type_tracker.rb:2:16:2:18 | val | -| type_tracker.rb:2:16:2:18 | val | type tracker with call steps | type_tracker.rb:8:9:8:14 | @field | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:3:9:3:23 | call to puts | type tracker without call steps | type_tracker.rb:3:9:3:23 | call to puts | | type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field | | type_tracker.rb:4:9:4:14 | @field | type tracker without call steps | type_tracker.rb:4:9:4:14 | @field | | type_tracker.rb:7:5:9:7 | &block | type tracker without call steps | type_tracker.rb:7:5:9:7 | &block | | type_tracker.rb:7:5:9:7 | field | type tracker without call steps | type_tracker.rb:7:5:9:7 | field | -| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field | -| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | -| type_tracker.rb:7:5:9:7 | self (field) | type tracker without call steps | type_tracker.rb:7:5:9:7 | self (field) | -| type_tracker.rb:7:5:9:7 | self in field | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) | | type_tracker.rb:7:5:9:7 | self in field | type tracker without call steps | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field | | type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:12:1:16:3 | &block | type tracker without call steps | type_tracker.rb:12:1:16:3 | &block | | type_tracker.rb:12:1:16:3 | m | type tracker without call steps | type_tracker.rb:12:1:16:3 | m | -| type_tracker.rb:12:1:16:3 | return return in m | type tracker without call steps | type_tracker.rb:12:1:16:3 | return return in m | -| type_tracker.rb:12:1:16:3 | self (m) | type tracker without call steps | type_tracker.rb:12:1:16:3 | self (m) | -| type_tracker.rb:12:1:16:3 | self in m | type tracker with call steps | type_tracker.rb:12:1:16:3 | self (m) | | type_tracker.rb:12:1:16:3 | self in m | type tracker without call steps | type_tracker.rb:12:1:16:3 | self in m | | type_tracker.rb:13:5:13:7 | var | type tracker without call steps | type_tracker.rb:13:5:13:7 | var | | type_tracker.rb:13:11:13:19 | Container | type tracker without call steps | type_tracker.rb:13:11:13:19 | Container | -| type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:2:5:5:7 | self (field=) | | type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:2:5:5:7 | self in field= | -| type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) | | type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:13:11:13:23 | call to new | type tracker without call steps | type_tracker.rb:13:11:13:23 | call to new | -| type_tracker.rb:14:5:14:7 | [post] var | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) | | type_tracker.rb:14:5:14:7 | [post] var | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:14:5:14:7 | [post] var | type tracker without call steps | type_tracker.rb:14:5:14:7 | [post] var | | type_tracker.rb:14:5:14:13 | call to field= | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= | | type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:2:16:2:18 | val | -| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:8:9:8:14 | @field | -| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content attribute field | type_tracker.rb:7:5:9:7 | self (field) | | type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content attribute field | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= | | type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:14:17:14:23 | "hello" | | type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content attribute field | type_tracker.rb:14:5:14:7 | [post] var | | type_tracker.rb:14:17:14:23 | __synth__0 | type tracker without call steps | type_tracker.rb:14:17:14:23 | __synth__0 | -| type_tracker.rb:15:5:15:18 | call to puts | type tracker without call steps | type_tracker.rb:12:1:16:3 | return return in m | | type_tracker.rb:15:5:15:18 | call to puts | type tracker without call steps | type_tracker.rb:15:5:15:18 | call to puts | | type_tracker.rb:15:10:15:18 | call to field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:18:1:21:3 | &block | type tracker without call steps | type_tracker.rb:18:1:21:3 | &block | | type_tracker.rb:18:1:21:3 | positional | type tracker without call steps | type_tracker.rb:18:1:21:3 | positional | -| type_tracker.rb:18:1:21:3 | return return in positional | type tracker without call steps | type_tracker.rb:18:1:21:3 | return return in positional | -| type_tracker.rb:18:1:21:3 | return return in positional | type tracker without call steps | type_tracker.rb:23:1:23:16 | call to positional | -| type_tracker.rb:18:1:21:3 | self (positional) | type tracker without call steps | type_tracker.rb:18:1:21:3 | self (positional) | -| type_tracker.rb:18:1:21:3 | self in positional | type tracker with call steps | type_tracker.rb:18:1:21:3 | self (positional) | | type_tracker.rb:18:1:21:3 | self in positional | type tracker without call steps | type_tracker.rb:18:1:21:3 | self in positional | -| type_tracker.rb:18:16:18:17 | p1 | type tracker with call steps | type_tracker.rb:18:16:18:17 | p1 | | type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps | type_tracker.rb:18:16:18:17 | p1 | | type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps | type_tracker.rb:18:16:18:17 | p1 | -| type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps | type_tracker.rb:18:16:18:17 | p1 | -| type_tracker.rb:18:20:18:21 | p2 | type tracker with call steps | type_tracker.rb:18:20:18:21 | p2 | -| type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps | type_tracker.rb:18:20:18:21 | p2 | | type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps | type_tracker.rb:18:20:18:21 | p2 | | type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps | type_tracker.rb:18:20:18:21 | p2 | | type_tracker.rb:19:5:19:11 | call to puts | type tracker without call steps | type_tracker.rb:19:5:19:11 | call to puts | -| type_tracker.rb:20:5:20:11 | call to puts | type tracker without call steps | type_tracker.rb:18:1:21:3 | return return in positional | | type_tracker.rb:20:5:20:11 | call to puts | type tracker without call steps | type_tracker.rb:20:5:20:11 | call to puts | | type_tracker.rb:20:5:20:11 | call to puts | type tracker without call steps | type_tracker.rb:23:1:23:16 | call to positional | | type_tracker.rb:23:1:23:16 | call to positional | type tracker without call steps | type_tracker.rb:23:1:23:16 | call to positional | | type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps | type_tracker.rb:18:16:18:17 | p1 | -| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps | type_tracker.rb:18:16:18:17 | p1 | | type_tracker.rb:23:12:23:12 | 1 | type tracker without call steps | type_tracker.rb:23:12:23:12 | 1 | | type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps | type_tracker.rb:18:20:18:21 | p2 | -| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps | type_tracker.rb:18:20:18:21 | p2 | | type_tracker.rb:23:15:23:15 | 2 | type tracker without call steps | type_tracker.rb:23:15:23:15 | 2 | | type_tracker.rb:25:1:28:3 | &block | type tracker without call steps | type_tracker.rb:25:1:28:3 | &block | | type_tracker.rb:25:1:28:3 | **kwargs | type tracker without call steps | type_tracker.rb:25:1:28:3 | **kwargs | | type_tracker.rb:25:1:28:3 | keyword | type tracker without call steps | type_tracker.rb:25:1:28:3 | keyword | -| type_tracker.rb:25:1:28:3 | return return in keyword | type tracker without call steps | type_tracker.rb:25:1:28:3 | return return in keyword | -| type_tracker.rb:25:1:28:3 | return return in keyword | type tracker without call steps | type_tracker.rb:30:1:30:21 | call to keyword | -| type_tracker.rb:25:1:28:3 | return return in keyword | type tracker without call steps | type_tracker.rb:31:1:31:21 | call to keyword | -| type_tracker.rb:25:1:28:3 | return return in keyword | type tracker without call steps | type_tracker.rb:32:1:32:27 | call to keyword | -| type_tracker.rb:25:1:28:3 | self (keyword) | type tracker without call steps | type_tracker.rb:25:1:28:3 | self (keyword) | -| type_tracker.rb:25:1:28:3 | self in keyword | type tracker with call steps | type_tracker.rb:25:1:28:3 | self (keyword) | | type_tracker.rb:25:1:28:3 | self in keyword | type tracker without call steps | type_tracker.rb:25:1:28:3 | self in keyword | -| type_tracker.rb:25:13:25:14 | p1 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps | type_tracker.rb:25:13:25:14 | p1 | -| type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps | type_tracker.rb:25:13:25:14 | p1 | -| type_tracker.rb:25:18:25:19 | p2 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | -| type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:26:5:26:11 | call to puts | type tracker without call steps | type_tracker.rb:26:5:26:11 | call to puts | -| type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:25:1:28:3 | return return in keyword | | type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:27:5:27:11 | call to puts | | type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:30:1:30:21 | call to keyword | | type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:31:1:31:21 | call to keyword | @@ -134,14 +77,12 @@ track | type_tracker.rb:30:9:30:10 | :p1 | type tracker without call steps | type_tracker.rb:30:9:30:10 | :p1 | | type_tracker.rb:30:9:30:13 | Pair | type tracker without call steps | type_tracker.rb:30:9:30:13 | Pair | | type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | -| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content element :p1 | type_tracker.rb:25:1:28:3 | **kwargs | | type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps | type_tracker.rb:30:13:30:13 | 3 | | type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps with content element :p1 | type_tracker.rb:30:1:30:21 | ** | | type_tracker.rb:30:16:30:17 | :p2 | type tracker without call steps | type_tracker.rb:30:16:30:17 | :p2 | | type_tracker.rb:30:16:30:20 | Pair | type tracker without call steps | type_tracker.rb:30:16:30:20 | Pair | | type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | -| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content element :p2 | type_tracker.rb:25:1:28:3 | **kwargs | | type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps | type_tracker.rb:30:20:30:20 | 4 | | type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps with content element :p2 | type_tracker.rb:30:1:30:21 | ** | @@ -151,14 +92,12 @@ track | type_tracker.rb:31:9:31:10 | :p2 | type tracker without call steps | type_tracker.rb:31:9:31:10 | :p2 | | type_tracker.rb:31:9:31:13 | Pair | type tracker without call steps | type_tracker.rb:31:9:31:13 | Pair | | type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | -| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content element :p2 | type_tracker.rb:25:1:28:3 | **kwargs | | type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps | type_tracker.rb:31:13:31:13 | 5 | | type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps with content element :p2 | type_tracker.rb:31:1:31:21 | ** | | type_tracker.rb:31:16:31:17 | :p1 | type tracker without call steps | type_tracker.rb:31:16:31:17 | :p1 | | type_tracker.rb:31:16:31:20 | Pair | type tracker without call steps | type_tracker.rb:31:16:31:20 | Pair | | type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | -| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content element :p1 | type_tracker.rb:25:1:28:3 | **kwargs | | type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps | type_tracker.rb:31:20:31:20 | 6 | | type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps with content element :p1 | type_tracker.rb:31:1:31:21 | ** | @@ -168,68 +107,33 @@ track | type_tracker.rb:32:9:32:11 | :p2 | type tracker without call steps | type_tracker.rb:32:9:32:11 | :p2 | | type_tracker.rb:32:9:32:16 | Pair | type tracker without call steps | type_tracker.rb:32:9:32:16 | Pair | | type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | -| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content element :p2 | type_tracker.rb:25:1:28:3 | **kwargs | | type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps | type_tracker.rb:32:16:32:16 | 7 | | type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps with content element :p2 | type_tracker.rb:32:1:32:27 | ** | | type_tracker.rb:32:19:32:21 | :p1 | type tracker without call steps | type_tracker.rb:32:19:32:21 | :p1 | | type_tracker.rb:32:19:32:26 | Pair | type tracker without call steps | type_tracker.rb:32:19:32:26 | Pair | | type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | -| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content element :p1 | type_tracker.rb:25:1:28:3 | **kwargs | | type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps | type_tracker.rb:32:26:32:26 | 8 | | type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps with content element :p1 | type_tracker.rb:32:1:32:27 | ** | | type_tracker.rb:34:1:53:3 | &block | type tracker without call steps | type_tracker.rb:34:1:53:3 | &block | -| type_tracker.rb:34:1:53:3 | return return in throughArray | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:34:1:53:3 | self in throughArray | type tracker without call steps | type_tracker.rb:34:1:53:3 | self in throughArray | | type_tracker.rb:34:1:53:3 | throughArray | type tracker without call steps | type_tracker.rb:34:1:53:3 | throughArray | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps | type_tracker.rb:34:18:34:20 | obj | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps | type_tracker.rb:36:5:36:10 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps | type_tracker.rb:40:5:40:12 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps | type_tracker.rb:44:5:44:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element | type_tracker.rb:38:13:38:25 | call to [] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element | type_tracker.rb:44:5:44:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element | type_tracker.rb:50:14:50:26 | call to [] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element 0 or unknown | type_tracker.rb:35:11:35:15 | call to [] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] | -| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:36:5:36:10 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:36:5:36:10 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:40:5:40:12 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:40:5:40:12 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:38:13:38:25 | call to [] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:38:13:38:25 | call to [] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:44:5:44:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:44:5:44:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:50:14:50:26 | call to [] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:50:14:50:26 | call to [] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:35:11:35:15 | call to [] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:35:11:35:15 | call to [] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] | -| type_tracker.rb:34:23:34:23 | y | type tracker with call steps | type_tracker.rb:34:23:34:23 | y | | type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y | | type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y | -| type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y | -| type_tracker.rb:34:26:34:26 | z | type tracker with call steps | type_tracker.rb:34:26:34:26 | z | -| type_tracker.rb:34:26:34:26 | z | type tracker without call steps | type_tracker.rb:34:26:34:26 | z | | type_tracker.rb:34:26:34:26 | z | type tracker without call steps | type_tracker.rb:34:26:34:26 | z | | type_tracker.rb:34:26:34:26 | z | type tracker without call steps | type_tracker.rb:34:26:34:26 | z | | type_tracker.rb:35:5:35:7 | tmp | type tracker without call steps | type_tracker.rb:35:5:35:7 | tmp | @@ -315,46 +219,33 @@ track | type_tracker.rb:50:5:50:10 | array4 | type tracker without call steps | type_tracker.rb:50:5:50:10 | array4 | | type_tracker.rb:50:14:50:26 | Array | type tracker without call steps | type_tracker.rb:50:14:50:26 | Array | | type_tracker.rb:50:14:50:26 | call to [] | type tracker without call steps | type_tracker.rb:50:14:50:26 | call to [] | -| type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps | type_tracker.rb:50:15:50:15 | 1 | | type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | | type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps with content element 0 or unknown | type_tracker.rb:50:14:50:26 | call to [] | -| type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps | type_tracker.rb:50:17:50:17 | 2 | | type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | | type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps with content element 1 or unknown | type_tracker.rb:50:14:50:26 | call to [] | -| type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps | type_tracker.rb:50:19:50:19 | 3 | | type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | | type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps with content element 2 or unknown | type_tracker.rb:50:14:50:26 | call to [] | -| type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps | type_tracker.rb:50:21:50:21 | 4 | | type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | | type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps with content element 3 or unknown | type_tracker.rb:50:14:50:26 | call to [] | -| type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps | type_tracker.rb:50:23:50:23 | 5 | | type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | | type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps with content element 4 or unknown | type_tracker.rb:50:14:50:26 | call to [] | -| type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps | type_tracker.rb:50:25:50:25 | 6 | | type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] | | type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps with content element 5 or unknown | type_tracker.rb:50:14:50:26 | call to [] | | type_tracker.rb:51:5:51:10 | [post] array4 | type tracker without call steps | type_tracker.rb:51:5:51:10 | [post] array4 | | type_tracker.rb:51:5:51:13 | call to []= | type tracker without call steps | type_tracker.rb:51:5:51:13 | call to []= | | type_tracker.rb:51:17:51:19 | __synth__0 | type tracker without call steps | type_tracker.rb:51:17:51:19 | __synth__0 | -| type_tracker.rb:52:5:52:13 | ...[...] | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:52:5:52:13 | ...[...] | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] | trackEnd | type_tracker.rb:1:1:10:3 | self (Container) | type_tracker.rb:1:1:10:3 | self (Container) | @@ -373,15 +264,6 @@ trackEnd | type_tracker.rb:1:1:53:4 | self (type_tracker.rb) | type_tracker.rb:32:1:32:27 | self | | type_tracker.rb:2:5:5:7 | &block | type_tracker.rb:2:5:5:7 | &block | | type_tracker.rb:2:5:5:7 | field= | type_tracker.rb:2:5:5:7 | field= | -| type_tracker.rb:2:5:5:7 | return return in field= | type_tracker.rb:2:5:5:7 | return return in field= | -| type_tracker.rb:2:5:5:7 | return return in field= | type_tracker.rb:14:5:14:13 | call to field= | -| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:2:5:5:7 | self (field=) | -| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:3:9:3:23 | self | -| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:3:14:3:17 | self | -| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:4:9:4:14 | self | -| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:7:5:9:7 | self (field) | -| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:7:5:9:7 | self in field | -| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:8:9:8:14 | self | | type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:2:5:5:7 | self (field=) | | type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:2:5:5:7 | self in field= | | type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:3:9:3:23 | self | @@ -390,25 +272,14 @@ trackEnd | type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:7:5:9:7 | self (field) | | type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:8:9:8:14 | self | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:5:5:7 | return return in field= | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:5:5:7 | return return in field= | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:9:4:20 | ... = ... | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:9:4:20 | ... = ... | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:18:4:20 | val | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:18:4:20 | val | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:7:5:9:7 | return return in field | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:7:5:9:7 | return return in field | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:14:5:14:13 | call to field= | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:14:5:14:13 | call to field= | -| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:2:16:2:18 | val | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:3:9:3:23 | call to puts | type_tracker.rb:3:9:3:23 | call to puts | | type_tracker.rb:3:14:3:23 | call to field | type_tracker.rb:3:14:3:23 | call to field | @@ -416,23 +287,14 @@ trackEnd | type_tracker.rb:7:5:9:7 | &block | type_tracker.rb:7:5:9:7 | &block | | type_tracker.rb:7:5:9:7 | field | type_tracker.rb:1:1:10:3 | Container | | type_tracker.rb:7:5:9:7 | field | type_tracker.rb:7:5:9:7 | field | -| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:7:5:9:7 | return return in field | -| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:15:10:15:18 | call to field | -| type_tracker.rb:7:5:9:7 | self (field) | type_tracker.rb:7:5:9:7 | self (field) | -| type_tracker.rb:7:5:9:7 | self (field) | type_tracker.rb:8:9:8:14 | self | | type_tracker.rb:7:5:9:7 | self in field | type_tracker.rb:7:5:9:7 | self (field) | | type_tracker.rb:7:5:9:7 | self in field | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:7:5:9:7 | self in field | type_tracker.rb:8:9:8:14 | self | | type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:7:5:9:7 | return return in field | | type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:12:1:16:3 | &block | type_tracker.rb:12:1:16:3 | &block | | type_tracker.rb:12:1:16:3 | m | type_tracker.rb:12:1:16:3 | m | -| type_tracker.rb:12:1:16:3 | return return in m | type_tracker.rb:12:1:16:3 | return return in m | -| type_tracker.rb:12:1:16:3 | self (m) | type_tracker.rb:12:1:16:3 | self (m) | -| type_tracker.rb:12:1:16:3 | self (m) | type_tracker.rb:15:5:15:18 | self | | type_tracker.rb:12:1:16:3 | self in m | type_tracker.rb:12:1:16:3 | self (m) | | type_tracker.rb:12:1:16:3 | self in m | type_tracker.rb:12:1:16:3 | self in m | | type_tracker.rb:12:1:16:3 | self in m | type_tracker.rb:15:5:15:18 | self | @@ -470,16 +332,10 @@ trackEnd | type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:14:17:14:23 | __synth__0 | | type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:14:17:14:23 | __synth__0 | type_tracker.rb:14:17:14:23 | __synth__0 | -| type_tracker.rb:15:5:15:18 | call to puts | type_tracker.rb:12:1:16:3 | return return in m | | type_tracker.rb:15:5:15:18 | call to puts | type_tracker.rb:15:5:15:18 | call to puts | | type_tracker.rb:15:10:15:18 | call to field | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:18:1:21:3 | &block | type_tracker.rb:18:1:21:3 | &block | | type_tracker.rb:18:1:21:3 | positional | type_tracker.rb:18:1:21:3 | positional | -| type_tracker.rb:18:1:21:3 | return return in positional | type_tracker.rb:18:1:21:3 | return return in positional | -| type_tracker.rb:18:1:21:3 | return return in positional | type_tracker.rb:23:1:23:16 | call to positional | -| type_tracker.rb:18:1:21:3 | self (positional) | type_tracker.rb:18:1:21:3 | self (positional) | -| type_tracker.rb:18:1:21:3 | self (positional) | type_tracker.rb:19:5:19:11 | self | -| type_tracker.rb:18:1:21:3 | self (positional) | type_tracker.rb:20:5:20:11 | self | | type_tracker.rb:18:1:21:3 | self in positional | type_tracker.rb:18:1:21:3 | self (positional) | | type_tracker.rb:18:1:21:3 | self in positional | type_tracker.rb:18:1:21:3 | self in positional | | type_tracker.rb:18:1:21:3 | self in positional | type_tracker.rb:19:5:19:11 | self | @@ -487,17 +343,12 @@ trackEnd | type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:18:16:18:17 | p1 | | type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:18:16:18:17 | p1 | | type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:18:16:18:17 | p1 | -| type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:18:16:18:17 | p1 | -| type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:19:10:19:11 | p1 | | type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:19:10:19:11 | p1 | | type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:18:20:18:21 | p2 | | type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:18:20:18:21 | p2 | | type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:18:20:18:21 | p2 | -| type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:18:20:18:21 | p2 | -| type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:20:10:20:11 | p2 | | type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:20:10:20:11 | p2 | | type_tracker.rb:19:5:19:11 | call to puts | type_tracker.rb:19:5:19:11 | call to puts | -| type_tracker.rb:20:5:20:11 | call to puts | type_tracker.rb:18:1:21:3 | return return in positional | | type_tracker.rb:20:5:20:11 | call to puts | type_tracker.rb:20:5:20:11 | call to puts | | type_tracker.rb:20:5:20:11 | call to puts | type_tracker.rb:23:1:23:16 | call to positional | | type_tracker.rb:23:1:23:16 | call to positional | type_tracker.rb:23:1:23:16 | call to positional | @@ -512,13 +363,6 @@ trackEnd | type_tracker.rb:25:1:28:3 | &block | type_tracker.rb:25:1:28:3 | &block | | type_tracker.rb:25:1:28:3 | **kwargs | type_tracker.rb:25:1:28:3 | **kwargs | | type_tracker.rb:25:1:28:3 | keyword | type_tracker.rb:25:1:28:3 | keyword | -| type_tracker.rb:25:1:28:3 | return return in keyword | type_tracker.rb:25:1:28:3 | return return in keyword | -| type_tracker.rb:25:1:28:3 | return return in keyword | type_tracker.rb:30:1:30:21 | call to keyword | -| type_tracker.rb:25:1:28:3 | return return in keyword | type_tracker.rb:31:1:31:21 | call to keyword | -| type_tracker.rb:25:1:28:3 | return return in keyword | type_tracker.rb:32:1:32:27 | call to keyword | -| type_tracker.rb:25:1:28:3 | self (keyword) | type_tracker.rb:25:1:28:3 | self (keyword) | -| type_tracker.rb:25:1:28:3 | self (keyword) | type_tracker.rb:26:5:26:11 | self | -| type_tracker.rb:25:1:28:3 | self (keyword) | type_tracker.rb:27:5:27:11 | self | | type_tracker.rb:25:1:28:3 | self in keyword | type_tracker.rb:25:1:28:3 | self (keyword) | | type_tracker.rb:25:1:28:3 | self in keyword | type_tracker.rb:25:1:28:3 | self in keyword | | type_tracker.rb:25:1:28:3 | self in keyword | type_tracker.rb:26:5:26:11 | self | @@ -526,17 +370,12 @@ trackEnd | type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:25:13:25:14 | p1 | -| type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:25:13:25:14 | p1 | -| type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:26:10:26:11 | p1 | | type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:26:10:26:11 | p1 | | type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:25:18:25:19 | p2 | -| type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:25:18:25:19 | p2 | -| type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:27:10:27:11 | p2 | | type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:27:10:27:11 | p2 | | type_tracker.rb:26:5:26:11 | call to puts | type_tracker.rb:26:5:26:11 | call to puts | -| type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:25:1:28:3 | return return in keyword | | type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:27:5:27:11 | call to puts | | type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:30:1:30:21 | call to keyword | | type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:31:1:31:21 | call to keyword | @@ -587,80 +426,45 @@ trackEnd | type_tracker.rb:32:26:32:26 | 8 | type_tracker.rb:26:10:26:11 | p1 | | type_tracker.rb:32:26:32:26 | 8 | type_tracker.rb:32:26:32:26 | 8 | | type_tracker.rb:34:1:53:3 | &block | type_tracker.rb:34:1:53:3 | &block | -| type_tracker.rb:34:1:53:3 | return return in throughArray | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:34:1:53:3 | self in throughArray | type_tracker.rb:34:1:53:3 | self in throughArray | | type_tracker.rb:34:1:53:3 | throughArray | type_tracker.rb:34:1:53:3 | throughArray | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:1:53:3 | return return in throughArray | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:1:53:3 | return return in throughArray | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:35:12:35:14 | obj | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:35:12:35:14 | obj | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:36:5:36:10 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:36:5:36:10 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:5:39:12 | __synth__0 | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:5:39:12 | __synth__0 | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:5:39:18 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:5:39:18 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | obj | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | obj | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:40:5:40:12 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:40:5:40:12 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:5:43:13 | __synth__0 | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:5:43:13 | __synth__0 | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:5:43:19 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:5:43:19 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | obj | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | obj | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:44:5:44:13 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:44:5:44:13 | ...[...] | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:5:47:13 | __synth__0 | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:5:47:13 | __synth__0 | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:5:47:19 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:5:47:19 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | obj | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | obj | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:5:51:13 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:5:51:13 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:5:51:19 | ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:5:51:19 | ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | ... = ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | ... = ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | __synth__0 | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | __synth__0 | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:34:23:34:23 | y | type_tracker.rb:34:23:34:23 | y | | type_tracker.rb:34:23:34:23 | y | type_tracker.rb:34:23:34:23 | y | | type_tracker.rb:34:23:34:23 | y | type_tracker.rb:34:23:34:23 | y | | type_tracker.rb:34:23:34:23 | y | type_tracker.rb:34:23:34:23 | y | | type_tracker.rb:34:23:34:23 | y | type_tracker.rb:39:11:39:11 | y | -| type_tracker.rb:34:23:34:23 | y | type_tracker.rb:39:11:39:11 | y | -| type_tracker.rb:34:23:34:23 | y | type_tracker.rb:44:12:44:12 | y | | type_tracker.rb:34:23:34:23 | y | type_tracker.rb:44:12:44:12 | y | | type_tracker.rb:34:23:34:23 | y | type_tracker.rb:51:12:51:12 | y | -| type_tracker.rb:34:23:34:23 | y | type_tracker.rb:51:12:51:12 | y | | type_tracker.rb:34:26:34:26 | z | type_tracker.rb:34:26:34:26 | z | | type_tracker.rb:34:26:34:26 | z | type_tracker.rb:34:26:34:26 | z | | type_tracker.rb:34:26:34:26 | z | type_tracker.rb:34:26:34:26 | z | -| type_tracker.rb:34:26:34:26 | z | type_tracker.rb:34:26:34:26 | z | -| type_tracker.rb:34:26:34:26 | z | type_tracker.rb:52:12:52:12 | z | | type_tracker.rb:34:26:34:26 | z | type_tracker.rb:52:12:52:12 | z | | type_tracker.rb:35:5:35:7 | tmp | type_tracker.rb:35:5:35:7 | tmp | | type_tracker.rb:35:11:35:15 | Array | type_tracker.rb:35:11:35:15 | Array | @@ -743,29 +547,22 @@ trackEnd | type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:50:14:50:26 | call to [] | | type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:51:5:51:10 | array4 | | type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:52:5:52:10 | array4 | -| type_tracker.rb:50:15:50:15 | 1 | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:15:50:15 | 1 | type_tracker.rb:50:15:50:15 | 1 | | type_tracker.rb:50:15:50:15 | 1 | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:17:50:17 | 2 | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:17:50:17 | 2 | type_tracker.rb:50:17:50:17 | 2 | | type_tracker.rb:50:17:50:17 | 2 | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:19:50:19 | 3 | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:19:50:19 | 3 | type_tracker.rb:50:19:50:19 | 3 | | type_tracker.rb:50:19:50:19 | 3 | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:21:50:21 | 4 | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:21:50:21 | 4 | type_tracker.rb:50:21:50:21 | 4 | | type_tracker.rb:50:21:50:21 | 4 | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:23:50:23 | 5 | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:23:50:23 | 5 | type_tracker.rb:50:23:50:23 | 5 | | type_tracker.rb:50:23:50:23 | 5 | type_tracker.rb:52:5:52:13 | ...[...] | -| type_tracker.rb:50:25:50:25 | 6 | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:50:25:50:25 | 6 | type_tracker.rb:50:25:50:25 | 6 | | type_tracker.rb:50:25:50:25 | 6 | type_tracker.rb:52:5:52:13 | ...[...] | | type_tracker.rb:51:5:51:10 | [post] array4 | type_tracker.rb:51:5:51:10 | [post] array4 | | type_tracker.rb:51:5:51:10 | [post] array4 | type_tracker.rb:52:5:52:10 | array4 | | type_tracker.rb:51:5:51:13 | call to []= | type_tracker.rb:51:5:51:13 | call to []= | | type_tracker.rb:51:17:51:19 | __synth__0 | type_tracker.rb:51:17:51:19 | __synth__0 | -| type_tracker.rb:52:5:52:13 | ...[...] | type_tracker.rb:34:1:53:3 | return return in throughArray | | type_tracker.rb:52:5:52:13 | ...[...] | type_tracker.rb:52:5:52:13 | ...[...] | forwardButNoBackwardFlow backwardButNoForwardFlow From 1788c54bd8eed26609e78e0244cbc343772632e1 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Mon, 1 May 2023 13:13:26 +0200 Subject: [PATCH 090/739] Python: Avoid calling `TypeTracker::step` in call graph construction --- .../new/internal/DataFlowDispatch.qll | 331 +++++++++++++----- 1 file changed, 246 insertions(+), 85 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index cdca96cc4ac..958bca246cb 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -464,22 +464,55 @@ private predicate ignoreForCallGraph(File f) { f.getAbsolutePath().matches("%/site-packages/sympy/%") } +bindingset[n] +pragma[inline_late] +private predicate includeInCallGraph(TypeTrackingNode n) { + not ignoreForCallGraph(n.getLocation().getFile()) +} + +pragma[nomagic] +private predicate stepCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { + StepSummary::stepCall(nodeFrom, _, summary) +} + +bindingset[t, summary] +pragma[inline_late] +private TypeTracker append(TypeTracker t, StepSummary summary) { result = t.append(summary) } + /** * Gets a reference to the function `func`. */ private TypeTrackingNode functionTracker(TypeTracker t, Function func) { - not ignoreForCallGraph(result.getLocation().getFile()) and - t.start() and + includeInCallGraph(result) and ( - result.asExpr() = func.getDefinition() + t.start() and + ( + result.asExpr() = func.getDefinition() + or + // when a function is decorated, it's the result of the (last) decorator call that + // is used + result.asExpr() = func.getDefinition().(FunctionExpr).getADecoratorCall() + ) or - // when a function is decorated, it's the result of the (last) decorator call that - // is used - result.asExpr() = func.getDefinition().(FunctionExpr).getADecoratorCall() + ( + exists(TypeTracker t2 | t = t2.stepNoCall(functionTracker(t2, func), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(functionTrackerCall(t, func, summary), result, summary) + ) + ) + ) +} + +pragma[nomagic] +private TypeTrackingNode functionTrackerCall(TypeTracker t, Function func, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = functionTracker(t2, func) and + stepCallProj(result, summary) and + t = append(t2, summary) ) - or - not ignoreForCallGraph(result.getLocation().getFile()) and - exists(TypeTracker t2 | result = functionTracker(t2, func).track(t2, t)) } /** @@ -491,23 +524,41 @@ Node functionTracker(Function func) { functionTracker(TypeTracker::end(), func). * Gets a reference to the class `cls`. */ private TypeTrackingNode classTracker(TypeTracker t, Class cls) { - not ignoreForCallGraph(result.getLocation().getFile()) and - t.start() and + includeInCallGraph(result) and ( - result.asExpr() = cls.getParent() + t.start() and + ( + result.asExpr() = cls.getParent() + or + // when a class is decorated, it's the result of the (last) decorator call that + // is used + result.asExpr() = cls.getParent().getADecoratorCall() + or + // `type(obj)`, where obj is an instance of this class + result = getTypeCall() and + result.(CallCfgNode).getArg(0) = classInstanceTracker(cls) + ) or - // when a class is decorated, it's the result of the (last) decorator call that - // is used - result.asExpr() = cls.getParent().getADecoratorCall() - or - // `type(obj)`, where obj is an instance of this class - result = getTypeCall() and - result.(CallCfgNode).getArg(0) = classInstanceTracker(cls) + not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and + ( + exists(TypeTracker t2 | t = t2.stepNoCall(classTracker(t2, cls), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(classTrackerCall(t, cls, summary), result, summary) + ) + ) + ) +} + +pragma[nomagic] +private TypeTrackingNode classTrackerCall(TypeTracker t, Class cls, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = classTracker(t2, cls) and + stepCallProj(result, summary) and + t = append(t2, summary) ) - or - not ignoreForCallGraph(result.getLocation().getFile()) and - exists(TypeTracker t2 | result = classTracker(t2, cls).track(t2, t)) and - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) } /** @@ -519,21 +570,38 @@ Node classTracker(Class cls) { classTracker(TypeTracker::end(), cls).flowsTo(res * Gets a reference to an instance of the class `cls`. */ private TypeTrackingNode classInstanceTracker(TypeTracker t, Class cls) { - not ignoreForCallGraph(result.getLocation().getFile()) and - t.start() and - resolveClassCall(result.(CallCfgNode).asCfgNode(), cls) - or - // result of `super().__new__` as used in a `__new__` method implementation - not ignoreForCallGraph(result.getLocation().getFile()) and - t.start() and - exists(Class classUsedInSuper | - fromSuperNewCall(result.(CallCfgNode).asCfgNode(), classUsedInSuper, _, _) and - classUsedInSuper = getADirectSuperclass*(cls) + includeInCallGraph(result) and + ( + t.start() and + resolveClassCall(result.(CallCfgNode).asCfgNode(), cls) + or + // result of `super().__new__` as used in a `__new__` method implementation + t.start() and + exists(Class classUsedInSuper | + fromSuperNewCall(result.(CallCfgNode).asCfgNode(), classUsedInSuper, _, _) and + classUsedInSuper = getADirectSuperclass*(cls) + ) + or + not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and + ( + exists(TypeTracker t2 | t = t2.stepNoCall(classInstanceTracker(t2, cls), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(classInstanceTrackerCall(t, cls, summary), result, summary) + ) + ) + ) +} + +pragma[nomagic] +private TypeTrackingNode classInstanceTrackerCall(TypeTracker t, Class cls, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = classInstanceTracker(t2, cls) and + stepCallProj(result, summary) and + t = append(t2, summary) ) - or - not ignoreForCallGraph(result.getLocation().getFile()) and - exists(TypeTracker t2 | result = classInstanceTracker(t2, cls).track(t2, t)) and - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) } /** @@ -548,19 +616,37 @@ Node classInstanceTracker(Class cls) { * The method cannot be a `staticmethod` or `classmethod`. */ private TypeTrackingNode selfTracker(TypeTracker t, Class classWithMethod) { - not ignoreForCallGraph(result.getLocation().getFile()) and - t.start() and - exists(Function func | - func = classWithMethod.getAMethod() and - not isStaticmethod(func) and - not isClassmethod(func) - | - result.asExpr() = func.getArg(0) + includeInCallGraph(result) and + ( + t.start() and + exists(Function func | + func = classWithMethod.getAMethod() and + not isStaticmethod(func) and + not isClassmethod(func) + | + result.asExpr() = func.getArg(0) + ) + or + not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and + ( + exists(TypeTracker t2 | t = t2.stepNoCall(selfTracker(t2, classWithMethod), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(selfTrackerCall(t, classWithMethod, summary), result, summary) + ) + ) + ) +} + +pragma[nomagic] +private TypeTrackingNode selfTrackerCall(TypeTracker t, Class classWithMethod, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = selfTracker(t2, classWithMethod) and + stepCallProj(result, summary) and + t = append(t2, summary) ) - or - not ignoreForCallGraph(result.getLocation().getFile()) and - exists(TypeTracker t2 | result = selfTracker(t2, classWithMethod).track(t2, t)) and - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) } /** @@ -577,24 +663,44 @@ Node selfTracker(Class classWithMethod) { * from a normal method. */ private TypeTrackingNode clsArgumentTracker(TypeTracker t, Class classWithMethod) { - not ignoreForCallGraph(result.getLocation().getFile()) and - t.start() and + includeInCallGraph(result) and ( - exists(Function func | - func = classWithMethod.getAMethod() and - isClassmethod(func) - | - result.asExpr() = func.getArg(0) + t.start() and + ( + exists(Function func | + func = classWithMethod.getAMethod() and + isClassmethod(func) + | + result.asExpr() = func.getArg(0) + ) + or + // type(self) + result = getTypeCall() and + result.(CallCfgNode).getArg(0) = selfTracker(classWithMethod) ) or - // type(self) - result = getTypeCall() and - result.(CallCfgNode).getArg(0) = selfTracker(classWithMethod) + not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and + ( + exists(TypeTracker t2 | t = t2.stepNoCall(clsArgumentTracker(t2, classWithMethod), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(clsArgumentTrackerCall(t, classWithMethod, summary), result, summary) + ) + ) + ) +} + +pragma[nomagic] +private TypeTrackingNode clsArgumentTrackerCall( + TypeTracker t, Class classWithMethod, StepSummary summary +) { + exists(TypeTracker t2 | + // non-linear recursion + result = clsArgumentTracker(t2, classWithMethod) and + stepCallProj(result, summary) and + t = append(t2, summary) ) - or - not ignoreForCallGraph(result.getLocation().getFile()) and - exists(TypeTracker t2 | result = clsArgumentTracker(t2, classWithMethod).track(t2, t)) and - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) } /** @@ -611,18 +717,38 @@ Node clsArgumentTracker(Class classWithMethod) { * call happened in the method `func` (either a method or a classmethod). */ private TypeTrackingNode superCallNoArgumentTracker(TypeTracker t, Function func) { - not ignoreForCallGraph(result.getLocation().getFile()) and - t.start() and - not isStaticmethod(func) and - exists(CallCfgNode call | result = call | - call = getSuperCall() and - not exists(call.getArg(_)) and - call.getScope() = func + includeInCallGraph(result) and + ( + t.start() and + not isStaticmethod(func) and + exists(CallCfgNode call | result = call | + call = getSuperCall() and + not exists(call.getArg(_)) and + call.getScope() = func + ) + or + not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and + ( + exists(TypeTracker t2 | t = t2.stepNoCall(superCallNoArgumentTracker(t2, func), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(superCallNoArgumentTrackerCall(t, func, summary), result, summary) + ) + ) + ) +} + +pragma[nomagic] +private TypeTrackingNode superCallNoArgumentTrackerCall( + TypeTracker t, Function func, StepSummary summary +) { + exists(TypeTracker t2 | + // non-linear recursion + result = functionTracker(t2, func) and + stepCallProj(result, summary) and + t = append(t2, summary) ) - or - not ignoreForCallGraph(result.getLocation().getFile()) and - exists(TypeTracker t2 | result = superCallNoArgumentTracker(t2, func).track(t2, t)) and - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) } /** @@ -638,17 +764,37 @@ Node superCallNoArgumentTracker(Function func) { * first is a reference to the class `cls`, and the second argument is `obj`. */ private TypeTrackingNode superCallTwoArgumentTracker(TypeTracker t, Class cls, Node obj) { - not ignoreForCallGraph(result.getLocation().getFile()) and - t.start() and - exists(CallCfgNode call | result = call | - call = getSuperCall() and - call.getArg(0) = classTracker(cls) and - call.getArg(1) = obj + includeInCallGraph(result) and + ( + t.start() and + exists(CallCfgNode call | result = call | + call = getSuperCall() and + call.getArg(0) = classTracker(cls) and + call.getArg(1) = obj + ) + or + not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and + ( + exists(TypeTracker t2 | t = t2.stepNoCall(superCallTwoArgumentTracker(t2, cls, obj), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(superCallTwoArgumentTrackerCall(t, cls, obj, summary), result, summary) + ) + ) + ) +} + +pragma[nomagic] +private TypeTrackingNode superCallTwoArgumentTrackerCall( + TypeTracker t, Class cls, Node obj, StepSummary summary +) { + exists(TypeTracker t2 | + // non-linear recursion + result = superCallTwoArgumentTracker(t2, cls, obj) and + stepCallProj(result, summary) and + t = append(t2, summary) ) - or - not ignoreForCallGraph(result.getLocation().getFile()) and - exists(TypeTracker t2 | result = superCallTwoArgumentTracker(t2, cls, obj).track(t2, t)) and - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) } /** @@ -809,7 +955,22 @@ private TypeTrackingNode attrReadTracker(TypeTracker t, AttrRead attr) { superCallNoArgumentTracker(_), superCallTwoArgumentTracker(_, _) ] or - exists(TypeTracker t2 | result = attrReadTracker(t2, attr).track(t2, t)) + exists(TypeTracker t2 | t = t2.stepNoCall(attrReadTracker(t2, attr), result)) + or + exists(StepSummary summary | + // non-linear recursion + StepSummary::stepCall(attrReadTrackerCall(t, attr, summary), result, summary) + ) +} + +pragma[nomagic] +private TypeTrackingNode attrReadTrackerCall(TypeTracker t, AttrRead attr, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = attrReadTracker(t2, attr) and + stepCallProj(result, summary) and + t = append(t2, summary) + ) } /** Gets a reference to the attribute read `attr` */ From d2e192020b816f5092c3ac2f588432dc7b1153b4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions@github.com> Date: Wed, 24 May 2023 11:26:12 +0000 Subject: [PATCH 091/739] Post-release preparation for codeql-cli-2.13.3 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 2008adee602..1982886c434 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.7.2 +version: 0.7.3-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 8b2bb0ed100..46dffc3e763 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.6.2 +version: 0.6.3-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 9c09d378a20..4f2900e0b73 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.5.2 +version: 1.5.3-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 241bb764b7c..2318576e19e 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.5.2 +version: 1.5.3-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 1e56c93103b..17e00fa022c 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.6.2 +version: 0.6.3-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 663ad9efee2..95506e0f254 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.6.2 +version: 0.6.3-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 4da3e4ac60c..287c27187e3 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.5.2 +version: 0.5.3-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 81410e8a0bc..75963a0708e 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.5.2 +version: 0.5.3-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 94ec029ed07..ada2ac9e999 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.6.2 +version: 0.6.3-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 8936d5a4373..2da31e822ff 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.6.2 +version: 0.6.3-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index c45ff2f4732..52962f549b0 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.6.2 +version: 0.6.3-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index f64917ed51f..10e071e417c 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.6.2 +version: 0.6.3-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index a66a845730d..b6fbcda7201 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.5.2 +version: 0.5.3-dev groups: shared diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index be1ec0efa99..9d4522d5f58 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.9.2 +version: 0.9.3-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index d399ced2ccd..eb327c2e42e 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.7.2 +version: 0.7.3-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 7d01fb676db..bb01a5ff87d 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.6.2 +version: 0.6.3-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 2ba1f5ae58f..3bc462dc7ee 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.6.2 +version: 0.6.3-dev groups: - ruby - queries diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index deb3ab1029b..86b105c881a 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.13 +version: 0.0.14-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 2200a923da4..55ebe316292 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.0.17 +version: 0.0.18-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index dafd176c023..af7544c0ae9 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.0.10 +version: 0.0.11-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 697964c9078..10e32e39f99 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.0.10 +version: 0.0.11-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 41595203b56..fa4fe52aace 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.0.17 +version: 0.0.18-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index b6a5d413250..c044709ceee 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.0.10 +version: 0.0.11-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 5f61beb0f39..6b9f33c9125 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.0.2 +version: 0.0.3-dev groups: shared library: true warnOnImplicitThis: true From 765076bcba4b720a5eddf279f2479ce4e2bb8497 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 25 May 2023 13:28:39 +0200 Subject: [PATCH 092/739] fix whitespace in the samples in ReDoS.qhelp --- java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp | 3 +-- javascript/ql/src/Performance/ReDoS.qhelp | 3 +-- python/ql/src/Security/CWE-730/ReDoS.qhelp | 3 +-- ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp b/java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp index 08b67acb638..9f0d7a6fa07 100644 --- a/java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp +++ b/java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp @@ -25,8 +25,7 @@ the two branches of the alternative inside the repetition: </p> <sample language="java"> - ^_(__|[^_])+_$ - </sample> +^_(__|[^_])+_$</sample> </example> <include src="ReDoSReferences.inc.qhelp"/> diff --git a/javascript/ql/src/Performance/ReDoS.qhelp b/javascript/ql/src/Performance/ReDoS.qhelp index 21b937b17ef..a020a319207 100644 --- a/javascript/ql/src/Performance/ReDoS.qhelp +++ b/javascript/ql/src/Performance/ReDoS.qhelp @@ -25,8 +25,7 @@ the two branches of the alternative inside the repetition: </p> <sample language="javascript"> - /^_(__|[^_])+_$/ - </sample> +/^_(__|[^_])+_$/</sample> </example> <include src="ReDoSReferences.inc.qhelp"/> diff --git a/python/ql/src/Security/CWE-730/ReDoS.qhelp b/python/ql/src/Security/CWE-730/ReDoS.qhelp index 9cfbcc32354..74f3b8b87a1 100644 --- a/python/ql/src/Security/CWE-730/ReDoS.qhelp +++ b/python/ql/src/Security/CWE-730/ReDoS.qhelp @@ -25,8 +25,7 @@ the two branches of the alternative inside the repetition: </p> <sample language="python"> - ^_(__|[^_])+_$ - </sample> +^_(__|[^_])+_$</sample> </example> <include src="ReDoSReferences.inc.qhelp"/> diff --git a/ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp b/ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp index 4c85702a0d3..901315cba72 100644 --- a/ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp +++ b/ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp @@ -21,8 +21,7 @@ repetition: </p> <sample language="ruby"> - /^_(__|[^_])+_$/ - </sample> +/^_(__|[^_])+_$/</sample> </example> <include src="ReDoSReferences.inc.qhelp"/> </qhelp> From 9f5bf8fb2268d6975e9d791ad1b54da89428646c Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 25 May 2023 13:56:29 +0200 Subject: [PATCH 093/739] also fix the first code-block --- java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp | 3 +-- javascript/ql/src/Performance/ReDoS.qhelp | 3 +-- python/ql/src/Security/CWE-730/ReDoS.qhelp | 3 +-- ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp b/java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp index 9f0d7a6fa07..7fcdb97535b 100644 --- a/java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp +++ b/java/ql/src/Security/CWE/CWE-730/ReDoS.qhelp @@ -11,8 +11,7 @@ Consider this regular expression: </p> <sample language="java"> - ^_(__|.)+_$ - </sample> +^_(__|.)+_$</sample> <p> Its sub-expression <code>"(__|.)+?"</code> can match the string <code>"__"</code> either by the first alternative <code>"__"</code> to the left of the <code>"|"</code> operator, or by two diff --git a/javascript/ql/src/Performance/ReDoS.qhelp b/javascript/ql/src/Performance/ReDoS.qhelp index a020a319207..c152d646201 100644 --- a/javascript/ql/src/Performance/ReDoS.qhelp +++ b/javascript/ql/src/Performance/ReDoS.qhelp @@ -11,8 +11,7 @@ Consider this regular expression: </p> <sample language="javascript"> - /^_(__|.)+_$/ - </sample> +/^_(__|.)+_$/</sample> <p> Its sub-expression <code>"(__|.)+?"</code> can match the string <code>"__"</code> either by the first alternative <code>"__"</code> to the left of the <code>"|"</code> operator, or by two diff --git a/python/ql/src/Security/CWE-730/ReDoS.qhelp b/python/ql/src/Security/CWE-730/ReDoS.qhelp index 74f3b8b87a1..a881d94cd9f 100644 --- a/python/ql/src/Security/CWE-730/ReDoS.qhelp +++ b/python/ql/src/Security/CWE-730/ReDoS.qhelp @@ -11,8 +11,7 @@ Consider this regular expression: </p> <sample language="python"> - ^_(__|.)+_$ - </sample> +^_(__|.)+_$</sample> <p> Its sub-expression <code>"(__|.)+?"</code> can match the string <code>"__"</code> either by the first alternative <code>"__"</code> to the left of the <code>"|"</code> operator, or by two diff --git a/ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp b/ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp index 901315cba72..4c19e2bb6fe 100644 --- a/ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp +++ b/ruby/ql/src/queries/security/cwe-1333/ReDoS.qhelp @@ -4,8 +4,7 @@ <example> <p>Consider this regular expression:</p> <sample language="ruby"> - /^_(__|.)+_$/ - </sample> +/^_(__|.)+_$/</sample> <p> Its sub-expression <code>"(__|.)+?"</code> can match the string <code>"__"</code> either by the first alternative <code>"__"</code> to the From 6fc16574b33c0f284a40d185a4dbd9125a35b8a5 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Mon, 22 May 2023 12:36:42 +0000 Subject: [PATCH 094/739] Java: Add QL support for automodel application mode --- ...utomodelApplicationModeCharacteristics.qll | 360 ++++++++++++++++++ ...tomodelApplicationModeExtractCandidates.ql | 48 +++ ...AutomodelFrameworkModeExtractCandidates.ql | 2 +- 3 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll create mode 100644 java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll new file mode 100644 index 00000000000..b0dca8018a9 --- /dev/null +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -0,0 +1,360 @@ +/** + * For internal use only. + */ + +private import java +private import semmle.code.Location as Location +private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.TaintTracking +private import semmle.code.java.security.PathCreation +private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow +private import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +private import semmle.code.java.security.ExternalAPIs as ExternalAPIs +private import semmle.code.java.Expr as Expr +private import semmle.code.java.security.QueryInjection +private import semmle.code.java.security.RequestForgery +private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions +import AutomodelSharedCharacteristics as SharedCharacteristics +import AutomodelEndpointTypes as AutomodelEndpointTypes + +/** + * A meta data extractor. Any Java extraction mode needs to implement exactly + * one instance of this class. + */ +abstract class MetadataExtractor extends string { + bindingset[this] + MetadataExtractor() { any() } + + abstract predicate hasMetadata( + Endpoint e, string package, string type, boolean subtypes, string name, string signature, + int input + ); +} + +newtype JavaRelatedLocationType = CallContext() + +/** + * A class representing nodes that are arguments to calls. + */ +private class ArgumentNode extends DataFlow::Node { + ArgumentNode() { this.asExpr() = [any(Call c).getAnArgument(), any(Call c).getQualifier()] } +} + +/** + * A candidates implementation for framework mode. + * + * Some important notes: + * - This mode is using parameters as endpoints. + * - Sink- and neutral-information is being used from MaD models. + * - When available, we use method- and class-java-docs as related locations. + */ +module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { + // for documentation of the implementations here, see the QLDoc in the CandidateSig signature module. + class Endpoint = ArgumentNode; + + class EndpointType = AutomodelEndpointTypes::EndpointType; + + class NegativeEndpointType = AutomodelEndpointTypes::NegativeSinkType; + + class RelatedLocation = Location::Top; + + class RelatedLocationType = JavaRelatedLocationType; + + // Sanitizers are currently not modeled in MaD. TODO: check if this has large negative impact. + predicate isSanitizer(Endpoint e, EndpointType t) { none() } + + RelatedLocation asLocation(Endpoint e) { result = e.asExpr() } + + predicate isKnownKind(string kind, string humanReadableKind, EndpointType type) { + kind = "read-file" and + humanReadableKind = "read file" and + type instanceof AutomodelEndpointTypes::TaintedPathSinkType + or + kind = "create-file" and + humanReadableKind = "create file" and + type instanceof AutomodelEndpointTypes::TaintedPathSinkType + or + kind = "sql" and + humanReadableKind = "mad modeled sql" and + type instanceof AutomodelEndpointTypes::SqlSinkType + or + kind = "open-url" and + humanReadableKind = "open url" and + type instanceof AutomodelEndpointTypes::RequestForgerySinkType + or + kind = "jdbc-url" and + humanReadableKind = "jdbc url" and + type instanceof AutomodelEndpointTypes::RequestForgerySinkType + or + kind = "command-injection" and + humanReadableKind = "command injection" and + type instanceof AutomodelEndpointTypes::CommandInjectionSinkType + } + + predicate isSink(Endpoint e, string kind) { + exists(string package, string type, string name, string signature, string ext, string input | + sinkSpec(e, package, type, name, signature, ext, input) and + ExternalFlow::sinkModel(package, type, _, name, [signature, ""], ext, input, kind, _) + ) + } + + predicate isNeutral(Endpoint e) { + exists(string package, string type, string name, string signature | + sinkSpec(e, package, type, name, signature, _, _) and + ExternalFlow::neutralModel(package, type, name, [signature, ""], _, _) + ) + } + + additional predicate sinkSpec( + Endpoint e, string package, string type, string name, string signature, string ext, string input + ) { + FrameworkCandidatesImpl::getCallable(e).hasQualifiedName(package, type, name) and + signature = ExternalFlow::paramsString(getCallable(e)) and + ext = "" and + ( + exists(Call c, int argIdx | + e.asExpr() = c.getArgument(argIdx) and + input = "Argument[" + argIdx + "]" + ) + or + exists(Call c | e.asExpr() = c.getQualifier() and input = "Argument[this]") + ) + // exists(int paramIdx | e.isParameterOf(_, paramIdx) | + // if paramIdx = -1 then input = "Argument[this]" else input = "Argument[" + paramIdx + "]" + // ) + } + + /** + * Returns the related location for the given endpoint. + * + * Related locations can be JavaDoc comments of the class or the method. + */ + RelatedLocation getRelatedLocation(Endpoint e, RelatedLocationType type) { + type = CallContext() and + result = asLocation(e) + } + + /** + * Returns the callable that contains the given endpoint. + * + * Each Java mode should implement this predicate. + */ + additional Callable getCallable(Endpoint e) { + exists(Call c | + e.asExpr() = [c.getAnArgument(), c.getQualifier()] and + result = c.getCallee() + ) + } +} + +module CharacteristicsImpl = SharedCharacteristics::SharedCharacteristics<FrameworkCandidatesImpl>; + +class EndpointCharacteristic = CharacteristicsImpl::EndpointCharacteristic; + +class Endpoint = FrameworkCandidatesImpl::Endpoint; + +/* + * Predicates that are used to surface prompt examples and candidates for classification with an ML model. + */ + +/** + * A MetadataExtractor that extracts metadata for framework mode. + */ +class FrameworkModeMetadataExtractor extends MetadataExtractor { + FrameworkModeMetadataExtractor() { this = "FrameworkModeMetadataExtractor" } + + /** + * By convention, the subtypes property of the MaD declaration should only be + * true when there _can_ exist any subtypes with a different implementation. + * + * It would technically be ok to always use the value 'true', but this would + * break convention. + */ + boolean considerSubtypes(Callable callable) { + if + callable.isStatic() or + callable.getDeclaringType().isStatic() or + callable.isFinal() or + callable.getDeclaringType().isFinal() + then result = false + else result = true + } + + override predicate hasMetadata( + Endpoint e, string package, string type, boolean subtypes, string name, string signature, + int input + ) { + exists(Call call, Callable callable | + call.getCallee() = callable and + ( + e.asExpr() = call.getArgument(input) + or + e.asExpr() = call.getQualifier() and input = -1 + ) and + package = callable.getDeclaringType().getPackage().getName() and + type = callable.getDeclaringType().getErasure().(RefType).nestedName() and + subtypes = this.considerSubtypes(callable) and + name = callable.getName() and + signature = ExternalFlow::paramsString(callable) + ) + } +} + +/* + * EndpointCharacteristic classes that are specific to Automodel for Java. + */ + +/** + * A negative characteristic that indicates that an is-style boolean method is unexploitable even if it is a sink. + * + * A sink is highly unlikely to be exploitable if its callable's name starts with `is` and the callable has a boolean return + * type (e.g. `isDirectory`). These kinds of calls normally do only checks, and appear before the proper call that does + * the dangerous/interesting thing, so we want the latter to be modeled as the sink. + * + * TODO: this might filter too much, it's possible that methods with more than one parameter contain interesting sinks + */ +private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { + UnexploitableIsCharacteristic() { this = "unexploitable (is-style boolean method)" } + + override predicate appliesToEndpoint(Endpoint e) { + not FrameworkCandidatesImpl::isSink(e, _) and + FrameworkCandidatesImpl::getCallable(e).getName().matches("is%") and + FrameworkCandidatesImpl::getCallable(e).getReturnType() instanceof BooleanType + } +} + +/** + * A negative characteristic that indicates that an existence-checking boolean method is unexploitable even if it is a + * sink. + * + * A sink is highly unlikely to be exploitable if its callable's name is `exists` or `notExists` and the callable has a + * boolean return type. These kinds of calls normally do only checks, and appear before the proper call that does the + * dangerous/interesting thing, so we want the latter to be modeled as the sink. + */ +private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { + UnexploitableExistsCharacteristic() { this = "unexploitable (existence-checking boolean method)" } + + override predicate appliesToEndpoint(Endpoint e) { + not FrameworkCandidatesImpl::isSink(e, _) and + exists(Callable callable | + callable = FrameworkCandidatesImpl::getCallable(e) and + callable.getName().toLowerCase() = ["exists", "notexists"] and + callable.getReturnType() instanceof BooleanType + ) + } +} + +/** + * A negative characteristic that indicates that an endpoint is an argument to an exception, which is not a sink. + */ +private class ExceptionCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { + ExceptionCharacteristic() { this = "exception" } + + override predicate appliesToEndpoint(Endpoint e) { + FrameworkCandidatesImpl::getCallable(e).getDeclaringType().getASupertype*() instanceof + TypeThrowable + } +} + +/** + * A characteristic that limits candidates to parameters of methods that are recognized as `ModelApi`, iow., APIs that + * are considered worth modeling. + */ +private class NotAModelApiParameter extends CharacteristicsImpl::UninterestingToModelCharacteristic { + NotAModelApiParameter() { this = "not a model API parameter" } + + override predicate appliesToEndpoint(Endpoint e) { + not exists(ModelExclusions::ModelApi api | + exists(Call c | + c.getCallee() = api and + exists(int argIdx | exists(api.getParameter(argIdx)) | + argIdx = -1 and e.asExpr() = c.getQualifier() + or + argIdx >= 0 and e.asExpr() = c.getArgument(argIdx) + ) + ) + ) + } +} + +/** + * A negative characteristic that filters out non-public methods. Non-public methods are not interesting to include in + * the standard Java modeling, because they cannot be called from outside the package. + */ +private class NonPublicMethodCharacteristic extends CharacteristicsImpl::UninterestingToModelCharacteristic +{ + NonPublicMethodCharacteristic() { this = "non-public method" } + + override predicate appliesToEndpoint(Endpoint e) { + not FrameworkCandidatesImpl::getCallable(e).isPublic() + } +} + +/** + * Holds if the given endpoint has a self-contradictory combination of characteristics. Detects errors in our endpoint + * characteristics. Lists the problematic characteristics and their implications for all such endpoints, together with + * an error message indicating why this combination is problematic. + * + * Copied from + * javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/ContradictoryEndpointCharacteristics.ql + */ +predicate erroneousEndpoints( + Endpoint endpoint, EndpointCharacteristic characteristic, + AutomodelEndpointTypes::EndpointType endpointType, float confidence, string errorMessage, + boolean ignoreKnownModelingErrors +) { + // An endpoint's characteristics should not include positive indicators with medium/high confidence for more than one + // sink/source type (including the negative type). + exists( + EndpointCharacteristic characteristic2, AutomodelEndpointTypes::EndpointType endpointClass2, + float confidence2 + | + endpointType != endpointClass2 and + ( + endpointType instanceof AutomodelEndpointTypes::SinkType and + endpointClass2 instanceof AutomodelEndpointTypes::SinkType + or + endpointType instanceof AutomodelEndpointTypes::SourceType and + endpointClass2 instanceof AutomodelEndpointTypes::SourceType + ) and + characteristic.appliesToEndpoint(endpoint) and + characteristic2.appliesToEndpoint(endpoint) and + characteristic.hasImplications(endpointType, true, confidence) and + characteristic2.hasImplications(endpointClass2, true, confidence2) and + confidence > SharedCharacteristics::mediumConfidence() and + confidence2 > SharedCharacteristics::mediumConfidence() and + ( + ignoreKnownModelingErrors = true and + not knownOverlappingCharacteristics(characteristic, characteristic2) + or + ignoreKnownModelingErrors = false + ) + ) and + errorMessage = "Endpoint has high-confidence positive indicators for multiple classes" + or + // An endpoint's characteristics should not include positive indicators with medium/high confidence for some class and + // also include negative indicators with medium/high confidence for this same class. + exists(EndpointCharacteristic characteristic2, float confidence2 | + characteristic.appliesToEndpoint(endpoint) and + characteristic2.appliesToEndpoint(endpoint) and + characteristic.hasImplications(endpointType, true, confidence) and + characteristic2.hasImplications(endpointType, false, confidence2) and + confidence > SharedCharacteristics::mediumConfidence() and + confidence2 > SharedCharacteristics::mediumConfidence() + ) and + ignoreKnownModelingErrors = false and + errorMessage = "Endpoint has high-confidence positive and negative indicators for the same class" +} + +/** + * Holds if `characteristic1` and `characteristic2` are among the pairs of currently known positive characteristics that + * have some overlap in their results. This indicates a problem with the underlying Java modeling. Specifically, + * `PathCreation` is prone to FPs. + */ +private predicate knownOverlappingCharacteristics( + EndpointCharacteristic characteristic1, EndpointCharacteristic characteristic2 +) { + characteristic1 != characteristic2 and + characteristic1 = ["mad taint step", "create path", "read file", "known non-sink"] and + characteristic2 = ["mad taint step", "create path", "read file", "known non-sink"] +} diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql new file mode 100644 index 00000000000..14ba7b60799 --- /dev/null +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql @@ -0,0 +1,48 @@ +/** + * Surfaces the endpoints that are not already known to be sinks, and are therefore used as candidates for + * classification with an ML model. + * + * Note: This query does not actually classify the endpoints using the model. + * + * @name Automodel candidates + * @description A query to extract automodel candidates. + * @kind problem + * @severity info + * @id java/ml/extract-automodel-application-candidates + * @tags internal automodel extract candidates + */ + +private import AutomodelApplicationModeCharacteristics +private import AutomodelSharedUtil + +from + Endpoint endpoint, string message, MetadataExtractor meta, string package, string type, + boolean subtypes, string name, string signature, int input +where + not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | + u.appliesToEndpoint(endpoint) + ) and + // If a node is already a known sink for any of our existing ATM queries and is already modeled as a MaD sink, we + // don't include it as a candidate. Otherwise, we might include it as a candidate for query A, but the model will + // label it as a sink for one of the sink types of query B, for which it's already a known sink. This would result in + // overlap between our detected sinks and the pre-existing modeling. We assume that, if a sink has already been + // modeled in a MaD model, then it doesn't belong to any additional sink types, and we don't need to reexamine it. + not CharacteristicsImpl::isSink(endpoint, _) and + meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input) and + // The message is the concatenation of all sink types for which this endpoint is known neither to be a sink nor to be + // a non-sink, and we surface only endpoints that have at least one such sink type. + message = + strictconcat(AutomodelEndpointTypes::SinkType sinkType | + not CharacteristicsImpl::isKnownSink(endpoint, sinkType) and + CharacteristicsImpl::isSinkCandidate(endpoint, sinkType) + | + sinkType, ", " + ) +select endpoint, message + "\nrelated locations: $@." + "\nmetadata: $@, $@, $@, $@, $@, $@.", // + CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // + package.(DollarAtString), "package", // + type.(DollarAtString), "type", // + subtypes.toString().(DollarAtString), "subtypes", // + name.(DollarAtString), "name", // method name + signature.(DollarAtString), "signature", // + input.toString().(DollarAtString), "input" // diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql index a64327422a0..0fad9848efe 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql @@ -8,7 +8,7 @@ * @description A query to extract automodel candidates. * @kind problem * @severity info - * @id java/ml/extract-automodel-candidates + * @id java/ml/extract-automodel-framework-candidates * @tags internal automodel extract candidates */ From 9b30f9a4769d062d4f96de6b4d1081235bf034f4 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Mon, 22 May 2023 13:55:39 +0000 Subject: [PATCH 095/739] Java: Add negative characteristic for static calls --- .../AutomodelApplicationModeCharacteristics.qll | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index b0dca8018a9..33745806763 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -290,6 +290,21 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter } } +/** + * A negative characteristic that filters out qualifiers that are classes (i.e. static calls). These + *are unlikely to have any non-trivial flow going into them. + */ +private class ClassQualifierCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { + ClassQualifierCharacteristic() { this = "class qualifier" } + + override predicate appliesToEndpoint(Endpoint e) { + exists(Call c | + e.asExpr() = c.getQualifier() and + c.getCallee().isStatic() + ) + } +} + /** * Holds if the given endpoint has a self-contradictory combination of characteristics. Detects errors in our endpoint * characteristics. Lists the problematic characteristics and their implications for all such endpoints, together with From 185ad101b31bc1cdaf9106a366592ebb3906e429 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Tue, 23 May 2023 10:34:01 +0200 Subject: [PATCH 096/739] Java: add application-mode and framework-mode tags to extraction queries --- .../src/Telemetry/AutomodelApplicationModeExtractCandidates.ql | 2 +- .../ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql | 2 +- .../Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql | 2 +- .../Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql index 14ba7b60799..32665e77419 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql @@ -9,7 +9,7 @@ * @kind problem * @severity info * @id java/ml/extract-automodel-application-candidates - * @tags internal automodel extract candidates + * @tags internal automodel extract candidates application-mode */ private import AutomodelApplicationModeCharacteristics diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql index 0fad9848efe..1e9da50b72b 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql @@ -9,7 +9,7 @@ * @kind problem * @severity info * @id java/ml/extract-automodel-framework-candidates - * @tags internal automodel extract candidates + * @tags internal automodel extract candidates framework-mode */ private import AutomodelFrameworkModeCharacteristics diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql index f1ba8ee4119..28d673df9ed 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql @@ -5,7 +5,7 @@ * @kind problem * @severity info * @id java/ml/non-sink - * @tags internal automodel extract examples negative + * @tags internal automodel extract examples negative framework-mode */ private import AutomodelFrameworkModeCharacteristics diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql index e216c292538..b9c87d1dae6 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql @@ -5,7 +5,7 @@ * @kind problem * @severity info * @id java/ml/known-sink - * @tags internal automodel extract examples positive + * @tags internal automodel extract examples positive framework-mode */ private import AutomodelFrameworkModeCharacteristics From 7c3bc26c41309577bf492d44a4e4c96dafd66dd2 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Tue, 23 May 2023 12:02:02 +0000 Subject: [PATCH 097/739] Java: make input an actual string, not an integer --- .../AutomodelApplicationModeCharacteristics.qll | 10 +++++----- .../AutomodelApplicationModeExtractCandidates.ql | 4 ++-- .../AutomodelFrameworkModeCharacteristics.qll | 9 +++++---- .../AutomodelFrameworkModeExtractCandidates.ql | 4 ++-- .../AutomodelFrameworkModeExtractNegativeExamples.ql | 4 ++-- .../AutomodelFrameworkModeExtractPositiveExamples.ql | 4 ++-- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 33745806763..7b0a28c7a26 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -27,7 +27,7 @@ abstract class MetadataExtractor extends string { abstract predicate hasMetadata( Endpoint e, string package, string type, boolean subtypes, string name, string signature, - int input + string input ); } @@ -182,14 +182,14 @@ class FrameworkModeMetadataExtractor extends MetadataExtractor { override predicate hasMetadata( Endpoint e, string package, string type, boolean subtypes, string name, string signature, - int input + string input ) { - exists(Call call, Callable callable | + exists(Call call, Callable callable, int argIdx | call.getCallee() = callable and ( - e.asExpr() = call.getArgument(input) + e.asExpr() = call.getArgument(argIdx) and input = "Argument[" + argIdx + "]" or - e.asExpr() = call.getQualifier() and input = -1 + e.asExpr() = call.getQualifier() and argIdx = -1 and input = "Argument[this]" ) and package = callable.getDeclaringType().getPackage().getName() and type = callable.getDeclaringType().getErasure().(RefType).nestedName() and diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql index 32665e77419..43b2c2d626c 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql @@ -17,7 +17,7 @@ private import AutomodelSharedUtil from Endpoint endpoint, string message, MetadataExtractor meta, string package, string type, - boolean subtypes, string name, string signature, int input + boolean subtypes, string name, string signature, string input where not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | u.appliesToEndpoint(endpoint) @@ -45,4 +45,4 @@ select endpoint, message + "\nrelated locations: $@." + "\nmetadata: $@, $@, $@, subtypes.toString().(DollarAtString), "subtypes", // name.(DollarAtString), "name", // method name signature.(DollarAtString), "signature", // - input.toString().(DollarAtString), "input" // + input.(DollarAtString), "input" // diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index 57bd397f7a8..b3c9ea37e10 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -27,7 +27,7 @@ abstract class MetadataExtractor extends string { abstract predicate hasMetadata( DataFlow::ParameterNode e, string package, string type, boolean subtypes, string name, - string signature, int input, string parameterName + string signature, string input, string parameterName ); } @@ -167,10 +167,11 @@ class FrameworkModeMetadataExtractor extends MetadataExtractor { override predicate hasMetadata( Endpoint e, string package, string type, boolean subtypes, string name, string signature, - int input, string parameterName + string input, string parameterName ) { - exists(Callable callable | - e.asParameter() = callable.getParameter(input) and + exists(Callable callable, int paramIdx | + e.asParameter() = callable.getParameter(paramIdx) and + (if paramIdx = -1 then input = "Argument[this]" else input = "Argument[" + paramIdx + "]") and package = callable.getDeclaringType().getPackage().getName() and type = callable.getDeclaringType().getErasure().(RefType).nestedName() and subtypes = this.considerSubtypes(callable) and diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql index 1e9da50b72b..488ba532920 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql @@ -17,7 +17,7 @@ private import AutomodelSharedUtil from Endpoint endpoint, string message, MetadataExtractor meta, string package, string type, - boolean subtypes, string name, string signature, int input, string parameterName + boolean subtypes, string name, string signature, string input, string parameterName where not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | u.appliesToEndpoint(endpoint) @@ -47,5 +47,5 @@ select endpoint, subtypes.toString().(DollarAtString), "subtypes", // name.(DollarAtString), "name", // signature.(DollarAtString), "signature", // - input.toString().(DollarAtString), "input", // + input.(DollarAtString), "input", // parameterName.(DollarAtString), "parameterName" // diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql index 28d673df9ed..9c1076ae05d 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql @@ -15,7 +15,7 @@ private import AutomodelSharedUtil from Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string message, MetadataExtractor meta, string package, string type, boolean subtypes, string name, - string signature, int input, string parameterName + string signature, string input, string parameterName where characteristic.appliesToEndpoint(endpoint) and confidence >= SharedCharacteristics::highConfidence() and @@ -44,5 +44,5 @@ select endpoint, subtypes.toString().(DollarAtString), "subtypes", // name.(DollarAtString), "name", // signature.(DollarAtString), "signature", // - input.toString().(DollarAtString), "input", // + input.(DollarAtString), "input", // parameterName.(DollarAtString), "parameterName" // diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql index b9c87d1dae6..d6c4926bbac 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql @@ -14,7 +14,7 @@ private import AutomodelSharedUtil from Endpoint endpoint, SinkType sinkType, MetadataExtractor meta, string package, string type, - boolean subtypes, string name, string signature, int input, string parameterName + boolean subtypes, string name, string signature, string input, string parameterName where // Exclude endpoints that have contradictory endpoint characteristics, because we only want examples we're highly // certain about in the prompt. @@ -31,5 +31,5 @@ select endpoint, subtypes.toString().(DollarAtString), "subtypes", // name.(DollarAtString), "name", // signature.(DollarAtString), "signature", // - input.toString().(DollarAtString), "input", // + input.(DollarAtString), "input", // parameterName.(DollarAtString), "parameterName" // From 6e21f14c0971f4f6097a63cfcdfffd3f1e73f711 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Tue, 23 May 2023 12:17:17 +0000 Subject: [PATCH 098/739] Java: update extraction query metadata --- ...tomodelApplicationModeExtractCandidates.ql | 6 +-- ...lApplicationModeExtractNegativeExamples.ql | 45 +++++++++++++++++++ ...lApplicationModeExtractPositiveExamples.ql | 32 +++++++++++++ ...AutomodelFrameworkModeExtractCandidates.ql | 6 +-- ...delFrameworkModeExtractNegativeExamples.ql | 6 +-- ...delFrameworkModeExtractPositiveExamples.ql | 6 +-- 6 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql create mode 100644 java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql index 43b2c2d626c..1f4d12abbbc 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql @@ -4,12 +4,12 @@ * * Note: This query does not actually classify the endpoints using the model. * - * @name Automodel candidates - * @description A query to extract automodel candidates. + * @name Automodel candidates (application mode) + * @description A query to extract automodel candidates in application mode. * @kind problem * @severity info * @id java/ml/extract-automodel-application-candidates - * @tags internal automodel extract candidates application-mode + * @tags internal extract automodel application-mode candidates */ private import AutomodelApplicationModeCharacteristics diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql new file mode 100644 index 00000000000..3b3f1cd9c6f --- /dev/null +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -0,0 +1,45 @@ +/** + * Surfaces endpoints that are non-sinks with high confidence, for use as negative examples in the prompt. + * + * @name Negative examples (application mode) + * @kind problem + * @severity info + * @id java/ml/extract-automodel-application-negative-examples + * @tags internal extract automodel application-mode negative examples + */ + +private import AutomodelApplicationModeCharacteristics +private import AutomodelEndpointTypes +private import AutomodelSharedUtil + +from + Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string message, + MetadataExtractor meta, string package, string type, boolean subtypes, string name, + string signature, string input +where + characteristic.appliesToEndpoint(endpoint) and + confidence >= SharedCharacteristics::highConfidence() and + characteristic.hasImplications(any(NegativeSinkType negative), true, confidence) and + // Exclude endpoints that have contradictory endpoint characteristics, because we only want examples we're highly + // certain about in the prompt. + not erroneousEndpoints(endpoint, _, _, _, _, false) and + meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input) and + // It's valid for a node to satisfy the logic for both `isSink` and `isSanitizer`, but in that case it will be + // treated by the actual query as a sanitizer, since the final logic is something like + // `isSink(n) and not isSanitizer(n)`. We don't want to include such nodes as negative examples in the prompt, because + // they're ambiguous and might confuse the model, so we explicitly exclude all known sinks from the negative examples. + not exists(EndpointCharacteristic characteristic2, float confidence2, SinkType positiveType | + not positiveType instanceof NegativeSinkType and + characteristic2.appliesToEndpoint(endpoint) and + confidence2 >= SharedCharacteristics::maximalConfidence() and + characteristic2.hasImplications(positiveType, true, confidence2) + ) and + message = characteristic +select endpoint, message + "\nrelated locations: $@." + "\nmetadata: $@, $@, $@, $@, $@, $@.", // + CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // + package.(DollarAtString), "package", // + type.(DollarAtString), "type", // + subtypes.toString().(DollarAtString), "subtypes", // + name.(DollarAtString), "name", // + signature.(DollarAtString), "signature", // + input.(DollarAtString), "input" // diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql new file mode 100644 index 00000000000..37f3bb5cd69 --- /dev/null +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql @@ -0,0 +1,32 @@ +/** + * Surfaces endpoints that are sinks with high confidence, for use as positive examples in the prompt. + * + * @name Positive examples (application mode) + * @kind problem + * @severity info + * @id java/ml/extract-automodel-application-positive-examples + * @tags internal extract automodel application-mode positive examples + */ + +private import AutomodelApplicationModeCharacteristics +private import AutomodelEndpointTypes +private import AutomodelSharedUtil + +from + Endpoint endpoint, SinkType sinkType, MetadataExtractor meta, string package, string type, + boolean subtypes, string name, string signature, string input +where + // Exclude endpoints that have contradictory endpoint characteristics, because we only want examples we're highly + // certain about in the prompt. + not erroneousEndpoints(endpoint, _, _, _, _, false) and + meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input) and + // Extract positive examples of sinks belonging to the existing ATM query configurations. + CharacteristicsImpl::isKnownSink(endpoint, sinkType) +select endpoint, sinkType + "\nrelated locations: $@." + "\nmetadata: $@, $@, $@, $@, $@, $@.", // + CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // + package.(DollarAtString), "package", // + type.(DollarAtString), "type", // + subtypes.toString().(DollarAtString), "subtypes", // + name.(DollarAtString), "name", // + signature.(DollarAtString), "signature", // + input.(DollarAtString), "input" // diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql index 488ba532920..0f53399d2e3 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql @@ -4,12 +4,12 @@ * * Note: This query does not actually classify the endpoints using the model. * - * @name Automodel candidates - * @description A query to extract automodel candidates. + * @name Automodel candidates (framework mode) + * @description A query to extract automodel candidates in framework mode. * @kind problem * @severity info * @id java/ml/extract-automodel-framework-candidates - * @tags internal automodel extract candidates framework-mode + * @tags internal extract automodel framework-mode candidates */ private import AutomodelFrameworkModeCharacteristics diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql index 9c1076ae05d..9ecc1636c60 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql @@ -1,11 +1,11 @@ /** * Surfaces endpoints that are non-sinks with high confidence, for use as negative examples in the prompt. * - * @name Negative examples (experimental) + * @name Negative examples (framework mode) * @kind problem * @severity info - * @id java/ml/non-sink - * @tags internal automodel extract examples negative framework-mode + * @id java/ml/extract-automodel-framework-negative-examples + * @tags internal extract automodel framework-mode negative examples */ private import AutomodelFrameworkModeCharacteristics diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql index d6c4926bbac..f03bb995a19 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql @@ -1,11 +1,11 @@ /** * Surfaces endpoints that are sinks with high confidence, for use as positive examples in the prompt. * - * @name Positive examples (experimental) + * @name Positive examples (framework mode) * @kind problem * @severity info - * @id java/ml/known-sink - * @tags internal automodel extract examples positive framework-mode + * @id java/ml/extract-automodel-framework-positive-examples + * @tags internal extract automodel framework-mode positive examples */ private import AutomodelFrameworkModeCharacteristics From d93ad9b398d91dbf6c36c1bed287491d00ababa5 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Tue, 23 May 2023 12:40:00 +0000 Subject: [PATCH 099/739] Java: remove unneeded abstract metadata extractor classes and fix some names --- ...utomodelApplicationModeCharacteristics.qll | 47 +++++++------------ ...tomodelApplicationModeExtractCandidates.ql | 4 +- ...lApplicationModeExtractNegativeExamples.ql | 2 +- ...lApplicationModeExtractPositiveExamples.ql | 4 +- .../AutomodelFrameworkModeCharacteristics.qll | 18 +------ ...AutomodelFrameworkModeExtractCandidates.ql | 4 +- ...delFrameworkModeExtractNegativeExamples.ql | 2 +- ...delFrameworkModeExtractPositiveExamples.ql | 4 +- 8 files changed, 29 insertions(+), 56 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 7b0a28c7a26..d8789dd1a17 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -17,20 +17,6 @@ private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclus import AutomodelSharedCharacteristics as SharedCharacteristics import AutomodelEndpointTypes as AutomodelEndpointTypes -/** - * A meta data extractor. Any Java extraction mode needs to implement exactly - * one instance of this class. - */ -abstract class MetadataExtractor extends string { - bindingset[this] - MetadataExtractor() { any() } - - abstract predicate hasMetadata( - Endpoint e, string package, string type, boolean subtypes, string name, string signature, - string input - ); -} - newtype JavaRelatedLocationType = CallContext() /** @@ -41,14 +27,14 @@ private class ArgumentNode extends DataFlow::Node { } /** - * A candidates implementation for framework mode. + * A candidates implementation. * * Some important notes: * - This mode is using parameters as endpoints. * - Sink- and neutral-information is being used from MaD models. * - When available, we use method- and class-java-docs as related locations. */ -module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { +module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig { // for documentation of the implementations here, see the QLDoc in the CandidateSig signature module. class Endpoint = ArgumentNode; @@ -108,7 +94,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { additional predicate sinkSpec( Endpoint e, string package, string type, string name, string signature, string ext, string input ) { - FrameworkCandidatesImpl::getCallable(e).hasQualifiedName(package, type, name) and + ApplicationCandidatesImpl::getCallable(e).hasQualifiedName(package, type, name) and signature = ExternalFlow::paramsString(getCallable(e)) and ext = "" and ( @@ -147,21 +133,22 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { } } -module CharacteristicsImpl = SharedCharacteristics::SharedCharacteristics<FrameworkCandidatesImpl>; +module CharacteristicsImpl = + SharedCharacteristics::SharedCharacteristics<ApplicationCandidatesImpl>; class EndpointCharacteristic = CharacteristicsImpl::EndpointCharacteristic; -class Endpoint = FrameworkCandidatesImpl::Endpoint; +class Endpoint = ApplicationCandidatesImpl::Endpoint; /* * Predicates that are used to surface prompt examples and candidates for classification with an ML model. */ /** - * A MetadataExtractor that extracts metadata for framework mode. + * A MetadataExtractor that extracts metadata for application mode. */ -class FrameworkModeMetadataExtractor extends MetadataExtractor { - FrameworkModeMetadataExtractor() { this = "FrameworkModeMetadataExtractor" } +class ApplicationModeMetadataExtractor extends string { + ApplicationModeMetadataExtractor() { this = "ApplicationModeMetadataExtractor" } /** * By convention, the subtypes property of the MaD declaration should only be @@ -180,7 +167,7 @@ class FrameworkModeMetadataExtractor extends MetadataExtractor { else result = true } - override predicate hasMetadata( + predicate hasMetadata( Endpoint e, string package, string type, boolean subtypes, string name, string signature, string input ) { @@ -217,9 +204,9 @@ private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASin UnexploitableIsCharacteristic() { this = "unexploitable (is-style boolean method)" } override predicate appliesToEndpoint(Endpoint e) { - not FrameworkCandidatesImpl::isSink(e, _) and - FrameworkCandidatesImpl::getCallable(e).getName().matches("is%") and - FrameworkCandidatesImpl::getCallable(e).getReturnType() instanceof BooleanType + not ApplicationCandidatesImpl::isSink(e, _) and + ApplicationCandidatesImpl::getCallable(e).getName().matches("is%") and + ApplicationCandidatesImpl::getCallable(e).getReturnType() instanceof BooleanType } } @@ -235,9 +222,9 @@ private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::Not UnexploitableExistsCharacteristic() { this = "unexploitable (existence-checking boolean method)" } override predicate appliesToEndpoint(Endpoint e) { - not FrameworkCandidatesImpl::isSink(e, _) and + not ApplicationCandidatesImpl::isSink(e, _) and exists(Callable callable | - callable = FrameworkCandidatesImpl::getCallable(e) and + callable = ApplicationCandidatesImpl::getCallable(e) and callable.getName().toLowerCase() = ["exists", "notexists"] and callable.getReturnType() instanceof BooleanType ) @@ -251,7 +238,7 @@ private class ExceptionCharacteristic extends CharacteristicsImpl::NotASinkChara ExceptionCharacteristic() { this = "exception" } override predicate appliesToEndpoint(Endpoint e) { - FrameworkCandidatesImpl::getCallable(e).getDeclaringType().getASupertype*() instanceof + ApplicationCandidatesImpl::getCallable(e).getDeclaringType().getASupertype*() instanceof TypeThrowable } } @@ -286,7 +273,7 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter NonPublicMethodCharacteristic() { this = "non-public method" } override predicate appliesToEndpoint(Endpoint e) { - not FrameworkCandidatesImpl::getCallable(e).isPublic() + not ApplicationCandidatesImpl::getCallable(e).isPublic() } } diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql index 1f4d12abbbc..40e0e307300 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql @@ -16,8 +16,8 @@ private import AutomodelApplicationModeCharacteristics private import AutomodelSharedUtil from - Endpoint endpoint, string message, MetadataExtractor meta, string package, string type, - boolean subtypes, string name, string signature, string input + Endpoint endpoint, string message, ApplicationModeMetadataExtractor meta, string package, + string type, boolean subtypes, string name, string signature, string input where not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | u.appliesToEndpoint(endpoint) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index 3b3f1cd9c6f..5e12786e106 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -14,7 +14,7 @@ private import AutomodelSharedUtil from Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string message, - MetadataExtractor meta, string package, string type, boolean subtypes, string name, + ApplicationModeMetadataExtractor meta, string package, string type, boolean subtypes, string name, string signature, string input where characteristic.appliesToEndpoint(endpoint) and diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql index 37f3bb5cd69..0a70b376c82 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql @@ -13,8 +13,8 @@ private import AutomodelEndpointTypes private import AutomodelSharedUtil from - Endpoint endpoint, SinkType sinkType, MetadataExtractor meta, string package, string type, - boolean subtypes, string name, string signature, string input + Endpoint endpoint, SinkType sinkType, ApplicationModeMetadataExtractor meta, string package, + string type, boolean subtypes, string name, string signature, string input where // Exclude endpoints that have contradictory endpoint characteristics, because we only want examples we're highly // certain about in the prompt. diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index b3c9ea37e10..84a725931a5 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -17,20 +17,6 @@ private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclus import AutomodelSharedCharacteristics as SharedCharacteristics import AutomodelEndpointTypes as AutomodelEndpointTypes -/** - * A meta data extractor. Any Java extraction mode needs to implement exactly - * one instance of this class. - */ -abstract class MetadataExtractor extends string { - bindingset[this] - MetadataExtractor() { any() } - - abstract predicate hasMetadata( - DataFlow::ParameterNode e, string package, string type, boolean subtypes, string name, - string signature, string input, string parameterName - ); -} - newtype JavaRelatedLocationType = MethodDoc() or ClassDoc() @@ -145,7 +131,7 @@ class Endpoint = FrameworkCandidatesImpl::Endpoint; /** * A MetadataExtractor that extracts metadata for framework mode. */ -class FrameworkModeMetadataExtractor extends MetadataExtractor { +class FrameworkModeMetadataExtractor extends string { FrameworkModeMetadataExtractor() { this = "FrameworkModeMetadataExtractor" } /** @@ -165,7 +151,7 @@ class FrameworkModeMetadataExtractor extends MetadataExtractor { else result = true } - override predicate hasMetadata( + predicate hasMetadata( Endpoint e, string package, string type, boolean subtypes, string name, string signature, string input, string parameterName ) { diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql index 0f53399d2e3..7f7f050fac4 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql @@ -16,8 +16,8 @@ private import AutomodelFrameworkModeCharacteristics private import AutomodelSharedUtil from - Endpoint endpoint, string message, MetadataExtractor meta, string package, string type, - boolean subtypes, string name, string signature, string input, string parameterName + Endpoint endpoint, string message, FrameworkModeMetadataExtractor meta, string package, + string type, boolean subtypes, string name, string signature, string input, string parameterName where not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | u.appliesToEndpoint(endpoint) diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql index 9ecc1636c60..9036d638c2b 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql @@ -14,7 +14,7 @@ private import AutomodelSharedUtil from Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string message, - MetadataExtractor meta, string package, string type, boolean subtypes, string name, + FrameworkModeMetadataExtractor meta, string package, string type, boolean subtypes, string name, string signature, string input, string parameterName where characteristic.appliesToEndpoint(endpoint) and diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql index f03bb995a19..eeaf7037a15 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql @@ -13,8 +13,8 @@ private import AutomodelEndpointTypes private import AutomodelSharedUtil from - Endpoint endpoint, SinkType sinkType, MetadataExtractor meta, string package, string type, - boolean subtypes, string name, string signature, string input, string parameterName + Endpoint endpoint, SinkType sinkType, FrameworkModeMetadataExtractor meta, string package, + string type, boolean subtypes, string name, string signature, string input, string parameterName where // Exclude endpoints that have contradictory endpoint characteristics, because we only want examples we're highly // certain about in the prompt. From db61a2d09920f038f95e1adecdeee9ba2b027a91 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Tue, 23 May 2023 12:53:27 +0000 Subject: [PATCH 100/739] Java: share isKnownKind between modes --- ...utomodelApplicationModeCharacteristics.qll | 30 ++----------------- .../AutomodelFrameworkModeCharacteristics.qll | 27 ++--------------- java/ql/src/Telemetry/AutomodelSharedUtil.qll | 30 +++++++++++++++++++ 3 files changed, 34 insertions(+), 53 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index d8789dd1a17..8c13cecb774 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -14,6 +14,7 @@ private import semmle.code.java.Expr as Expr private import semmle.code.java.security.QueryInjection private import semmle.code.java.security.RequestForgery private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions +private import AutomodelSharedUtil as AutomodelSharedUtil import AutomodelSharedCharacteristics as SharedCharacteristics import AutomodelEndpointTypes as AutomodelEndpointTypes @@ -51,31 +52,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig RelatedLocation asLocation(Endpoint e) { result = e.asExpr() } - predicate isKnownKind(string kind, string humanReadableKind, EndpointType type) { - kind = "read-file" and - humanReadableKind = "read file" and - type instanceof AutomodelEndpointTypes::TaintedPathSinkType - or - kind = "create-file" and - humanReadableKind = "create file" and - type instanceof AutomodelEndpointTypes::TaintedPathSinkType - or - kind = "sql" and - humanReadableKind = "mad modeled sql" and - type instanceof AutomodelEndpointTypes::SqlSinkType - or - kind = "open-url" and - humanReadableKind = "open url" and - type instanceof AutomodelEndpointTypes::RequestForgerySinkType - or - kind = "jdbc-url" and - humanReadableKind = "jdbc url" and - type instanceof AutomodelEndpointTypes::RequestForgerySinkType - or - kind = "command-injection" and - humanReadableKind = "command injection" and - type instanceof AutomodelEndpointTypes::CommandInjectionSinkType - } + predicate isKnownKind = AutomodelSharedUtil::isKnownKind/3; predicate isSink(Endpoint e, string kind) { exists(string package, string type, string name, string signature, string ext, string input | @@ -105,9 +82,6 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig or exists(Call c | e.asExpr() = c.getQualifier() and input = "Argument[this]") ) - // exists(int paramIdx | e.isParameterOf(_, paramIdx) | - // if paramIdx = -1 then input = "Argument[this]" else input = "Argument[" + paramIdx + "]" - // ) } /** diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index 84a725931a5..19293e26e79 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -14,6 +14,7 @@ private import semmle.code.java.Expr as Expr private import semmle.code.java.security.QueryInjection private import semmle.code.java.security.RequestForgery private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions +private import AutomodelSharedUtil as AutomodelSharedUtil import AutomodelSharedCharacteristics as SharedCharacteristics import AutomodelEndpointTypes as AutomodelEndpointTypes @@ -46,31 +47,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { RelatedLocation asLocation(Endpoint e) { result = e.asParameter() } - predicate isKnownKind(string kind, string humanReadableKind, EndpointType type) { - kind = "read-file" and - humanReadableKind = "read file" and - type instanceof AutomodelEndpointTypes::TaintedPathSinkType - or - kind = "create-file" and - humanReadableKind = "create file" and - type instanceof AutomodelEndpointTypes::TaintedPathSinkType - or - kind = "sql" and - humanReadableKind = "mad modeled sql" and - type instanceof AutomodelEndpointTypes::SqlSinkType - or - kind = "open-url" and - humanReadableKind = "open url" and - type instanceof AutomodelEndpointTypes::RequestForgerySinkType - or - kind = "jdbc-url" and - humanReadableKind = "jdbc url" and - type instanceof AutomodelEndpointTypes::RequestForgerySinkType - or - kind = "command-injection" and - humanReadableKind = "command injection" and - type instanceof AutomodelEndpointTypes::CommandInjectionSinkType - } + predicate isKnownKind = AutomodelSharedUtil::isKnownKind/3; predicate isSink(Endpoint e, string kind) { exists(string package, string type, string name, string signature, string ext, string input | diff --git a/java/ql/src/Telemetry/AutomodelSharedUtil.qll b/java/ql/src/Telemetry/AutomodelSharedUtil.qll index e03e46abd1d..e3a2799be51 100644 --- a/java/ql/src/Telemetry/AutomodelSharedUtil.qll +++ b/java/ql/src/Telemetry/AutomodelSharedUtil.qll @@ -1,3 +1,5 @@ +import AutomodelEndpointTypes as AutomodelEndpointTypes + /** * A helper class to represent a string value that can be returned by a query using $@ notation. * @@ -19,3 +21,31 @@ class DollarAtString extends string { path = this and sl = 1 and sc = 1 and el = 1 and ec = 1 } } + +predicate isKnownKind( + string kind, string humanReadableKind, AutomodelEndpointTypes::EndpointType type +) { + kind = "read-file" and + humanReadableKind = "read file" and + type instanceof AutomodelEndpointTypes::TaintedPathSinkType + or + kind = "create-file" and + humanReadableKind = "create file" and + type instanceof AutomodelEndpointTypes::TaintedPathSinkType + or + kind = "sql" and + humanReadableKind = "mad modeled sql" and + type instanceof AutomodelEndpointTypes::SqlSinkType + or + kind = "open-url" and + humanReadableKind = "open url" and + type instanceof AutomodelEndpointTypes::RequestForgerySinkType + or + kind = "jdbc-url" and + humanReadableKind = "jdbc url" and + type instanceof AutomodelEndpointTypes::RequestForgerySinkType + or + kind = "command-injection" and + humanReadableKind = "command injection" and + type instanceof AutomodelEndpointTypes::CommandInjectionSinkType +} From 04b8bf35d4055595dd580c695b3fa4e1be199012 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Tue, 23 May 2023 13:16:01 +0000 Subject: [PATCH 101/739] Java: Avoid overlapping import Importing `AutomodelEndpointTypes` inside `AutomodelSharedUtil` non-privately made it overlap with the imports in the candidate extraction queries. --- java/ql/src/Telemetry/AutomodelSharedUtil.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelSharedUtil.qll b/java/ql/src/Telemetry/AutomodelSharedUtil.qll index e3a2799be51..9500b4ac635 100644 --- a/java/ql/src/Telemetry/AutomodelSharedUtil.qll +++ b/java/ql/src/Telemetry/AutomodelSharedUtil.qll @@ -1,4 +1,4 @@ -import AutomodelEndpointTypes as AutomodelEndpointTypes +private import AutomodelEndpointTypes as AutomodelEndpointTypes /** * A helper class to represent a string value that can be returned by a query using $@ notation. From 11ab7e2e7108603b83440ffe0aa53c35458e8dd2 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Tue, 23 May 2023 14:04:09 +0000 Subject: [PATCH 102/739] Java: Share argument indexing logic Adds a utility predicate for turning integer indices into the desired string representation. --- .../AutomodelApplicationModeCharacteristics.qll | 13 ++++++++----- .../AutomodelFrameworkModeCharacteristics.qll | 4 ++-- java/ql/src/Telemetry/AutomodelSharedUtil.qll | 8 ++++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 8c13cecb774..223a13127d2 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -77,10 +77,12 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig ( exists(Call c, int argIdx | e.asExpr() = c.getArgument(argIdx) and - input = "Argument[" + argIdx + "]" + input = AutomodelSharedUtil::getArgumentForIndex(argIdx) ) or - exists(Call c | e.asExpr() = c.getQualifier() and input = "Argument[this]") + exists(Call c | + e.asExpr() = c.getQualifier() and input = AutomodelSharedUtil::getArgumentForIndex(-1) + ) ) } @@ -148,10 +150,11 @@ class ApplicationModeMetadataExtractor extends string { exists(Call call, Callable callable, int argIdx | call.getCallee() = callable and ( - e.asExpr() = call.getArgument(argIdx) and input = "Argument[" + argIdx + "]" + e.asExpr() = call.getArgument(argIdx) or - e.asExpr() = call.getQualifier() and argIdx = -1 and input = "Argument[this]" + e.asExpr() = call.getQualifier() and argIdx = -1 ) and + input = AutomodelSharedUtil::getArgumentForIndex(argIdx) and package = callable.getDeclaringType().getPackage().getName() and type = callable.getDeclaringType().getErasure().(RefType).nestedName() and subtypes = this.considerSubtypes(callable) and @@ -231,7 +234,7 @@ private class NotAModelApiParameter extends CharacteristicsImpl::UninterestingTo exists(int argIdx | exists(api.getParameter(argIdx)) | argIdx = -1 and e.asExpr() = c.getQualifier() or - argIdx >= 0 and e.asExpr() = c.getArgument(argIdx) + e.asExpr() = c.getArgument(argIdx) ) ) ) diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index 19293e26e79..85e28436df3 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -70,7 +70,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { signature = ExternalFlow::paramsString(getCallable(e)) and ext = "" and exists(int paramIdx | e.isParameterOf(_, paramIdx) | - if paramIdx = -1 then input = "Argument[this]" else input = "Argument[" + paramIdx + "]" + input = AutomodelSharedUtil::getArgumentForIndex(paramIdx) ) } @@ -134,7 +134,7 @@ class FrameworkModeMetadataExtractor extends string { ) { exists(Callable callable, int paramIdx | e.asParameter() = callable.getParameter(paramIdx) and - (if paramIdx = -1 then input = "Argument[this]" else input = "Argument[" + paramIdx + "]") and + input = AutomodelSharedUtil::getArgumentForIndex(paramIdx) and package = callable.getDeclaringType().getPackage().getName() and type = callable.getDeclaringType().getErasure().(RefType).nestedName() and subtypes = this.considerSubtypes(callable) and diff --git a/java/ql/src/Telemetry/AutomodelSharedUtil.qll b/java/ql/src/Telemetry/AutomodelSharedUtil.qll index 9500b4ac635..2ca38506160 100644 --- a/java/ql/src/Telemetry/AutomodelSharedUtil.qll +++ b/java/ql/src/Telemetry/AutomodelSharedUtil.qll @@ -49,3 +49,11 @@ predicate isKnownKind( humanReadableKind = "command injection" and type instanceof AutomodelEndpointTypes::CommandInjectionSinkType } + +/** Gets the argument name for the argument with the index `index`. */ +bindingset[index] +string getArgumentForIndex(int index) { + index = -1 and result = "Argument[this]" + or + index >= 0 and result = "Argument[" + index + "]" +} From 2000f2253320429c8bc6752cff91d43a77bb04a9 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Wed, 24 May 2023 13:57:02 +0000 Subject: [PATCH 103/739] Java: Port over characteristics from codex branch --- ...utomodelApplicationModeCharacteristics.qll | 112 ++++++++++++++++-- 1 file changed, 105 insertions(+), 7 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 223a13127d2..13b494c377e 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -59,6 +59,8 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig sinkSpec(e, package, type, name, signature, ext, input) and ExternalFlow::sinkModel(package, type, _, name, [signature, ""], ext, input, kind, _) ) + or + isCustomSink(e, kind) } predicate isNeutral(Endpoint e) { @@ -109,6 +111,18 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig } } +/** + * Contains endpoints that are defined in QL code rather than as a MaD model. Ideally this predicate + * should be empty. + */ +private predicate isCustomSink(Endpoint e, string kind) { + e.asExpr() instanceof ArgumentToExec and kind = "command injection" + or + e instanceof RequestForgerySink and kind = "request forgery" + or + e instanceof QueryInjectionSink and kind = "sql" +} + module CharacteristicsImpl = SharedCharacteristics::SharedCharacteristics<ApplicationCandidatesImpl>; @@ -220,6 +234,37 @@ private class ExceptionCharacteristic extends CharacteristicsImpl::NotASinkChara } } +/** + * A negative characteristic that indicates that an endpoint is a MaD taint step. MaD modeled taint steps are global, + * so they are not sinks for any query. Non-MaD taint steps might be specific to a particular query, so we don't + * filter those out. + */ +private class IsMaDTaintStepCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { + IsMaDTaintStepCharacteristic() { this = "taint step" } + + override predicate appliesToEndpoint(Endpoint e) { + FlowSummaryImpl::Private::Steps::summaryThroughStepValue(e, _, _) or + FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(e, _, _) or + FlowSummaryImpl::Private::Steps::summaryGetterStep(e, _, _, _) or + FlowSummaryImpl::Private::Steps::summarySetterStep(e, _, _, _) + } +} + +/** + * A negative characteristic that filters out qualifiers that are classes (i.e. static calls). These + *are unlikely to have any non-trivial flow going into them. + */ +private class ClassQualifierCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { + ClassQualifierCharacteristic() { this = "class qualifier" } + + override predicate appliesToEndpoint(Endpoint e) { + exists(Call c | + e.asExpr() = c.getQualifier() and + c.getQualifier() instanceof TypeAccess + ) + } +} + /** * A characteristic that limits candidates to parameters of methods that are recognized as `ModelApi`, iow., APIs that * are considered worth modeling. @@ -255,20 +300,73 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter } /** - * A negative characteristic that filters out qualifiers that are classes (i.e. static calls). These - *are unlikely to have any non-trivial flow going into them. + * A negative characteristic that indicates that an endpoint is a non-sink argument to a method whose sinks have already + * been modeled. + * + * WARNING: These endpoints should not be used as negative samples for training, because some sinks may have been missed + * when the method was modeled. Specifically, as we start using ATM to merge in new declarations, we can be less sure + * that a method with one argument modeled as a MaD sink has also had its remaining arguments manually reviewed. The + * ML model might have predicted argument 0 of some method to be a sink but not argument 1, when in fact argument 1 is + * also a sink. */ -private class ClassQualifierCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { - ClassQualifierCharacteristic() { this = "class qualifier" } +private class OtherArgumentToModeledMethodCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic +{ + OtherArgumentToModeledMethodCharacteristic() { + this = "other argument to a method that has already been modeled" + } override predicate appliesToEndpoint(Endpoint e) { - exists(Call c | - e.asExpr() = c.getQualifier() and - c.getCallee().isStatic() + not ApplicationCandidatesImpl::isSink(e, _) and + exists(DataFlow::Node otherSink | + ApplicationCandidatesImpl::isSink(otherSink, _) and + e.asExpr() = otherSink.asExpr().(Argument).getCall().getAnArgument() and + e != otherSink ) } } +/** + * A negative characteristic that indicates that an endpoint is not part of the source code for the project being + * analyzed. + * + * WARNING: These endpoints should not be used as negative samples for training, because they are not necessarily + * non-sinks. They are merely not interesting sinks to run through the ML model. + * + * TODO: Check that this actually does anything. + */ +private class IsExternalCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic { + IsExternalCharacteristic() { this = "external" } + + override predicate appliesToEndpoint(Endpoint e) { + not exists(e.getLocation().getFile().getRelativePath()) + } +} + +/** + * A negative characteristic that indicates that an endpoint is not a `to` node for any known taint step. Such a node + * cannot be tainted, because taint can't flow into it. + * + * WARNING: These endpoints should not be used as negative samples for training, because they may include sinks for + * which our taint tracking modeling is incomplete. + */ +private class CannotBeTaintedCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic +{ + CannotBeTaintedCharacteristic() { this = "cannot be tainted" } + + override predicate appliesToEndpoint(Endpoint e) { not this.isKnownOutNodeForStep(e) } + + /** + * Holds if the node `n` is known as the predecessor in a modeled flow step. + */ + private predicate isKnownOutNodeForStep(Endpoint e) { + TaintTracking::localTaintStep(_, e) or + FlowSummaryImpl::Private::Steps::summaryThroughStepValue(_, e, _) or + FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(_, e, _) or + FlowSummaryImpl::Private::Steps::summaryGetterStep(_, _, e, _) or + FlowSummaryImpl::Private::Steps::summarySetterStep(_, _, e, _) + } +} + /** * Holds if the given endpoint has a self-contradictory combination of characteristics. Detects errors in our endpoint * characteristics. Lists the problematic characteristics and their implications for all such endpoints, together with From 33fdb0fc522a9e43aff2fda9203e8ccb417d165b Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 24 May 2023 16:09:25 +0200 Subject: [PATCH 104/739] Java: remove superfluous characteristic --- .../AutomodelApplicationModeCharacteristics.qll | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 13b494c377e..e8bd53a8aa3 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -325,23 +325,6 @@ private class OtherArgumentToModeledMethodCharacteristic extends Characteristics } } -/** - * A negative characteristic that indicates that an endpoint is not part of the source code for the project being - * analyzed. - * - * WARNING: These endpoints should not be used as negative samples for training, because they are not necessarily - * non-sinks. They are merely not interesting sinks to run through the ML model. - * - * TODO: Check that this actually does anything. - */ -private class IsExternalCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic { - IsExternalCharacteristic() { this = "external" } - - override predicate appliesToEndpoint(Endpoint e) { - not exists(e.getLocation().getFile().getRelativePath()) - } -} - /** * A negative characteristic that indicates that an endpoint is not a `to` node for any known taint step. Such a node * cannot be tainted, because taint can't flow into it. From f224a40dec00cb17c6a4fbc2e480a20b6334bb5b Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Thu, 25 May 2023 09:53:19 +0200 Subject: [PATCH 105/739] Java: use containing call as call context, not argument --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index e8bd53a8aa3..6e173e8232b 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -95,7 +95,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig */ RelatedLocation getRelatedLocation(Endpoint e, RelatedLocationType type) { type = CallContext() and - result = asLocation(e) + result = any(Call c | e.asExpr() = [c.getAnArgument(), c.getQualifier()]) } /** From 9a041243ffc4ca2b2005971da52c053f49802a63 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Thu, 25 May 2023 13:53:52 +0200 Subject: [PATCH 106/739] Java: fine-tune characteristics --- ...utomodelApplicationModeCharacteristics.qll | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 6e173e8232b..736e8b947bf 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -269,20 +269,23 @@ private class ClassQualifierCharacteristic extends CharacteristicsImpl::NotASink * A characteristic that limits candidates to parameters of methods that are recognized as `ModelApi`, iow., APIs that * are considered worth modeling. */ -private class NotAModelApiParameter extends CharacteristicsImpl::UninterestingToModelCharacteristic { - NotAModelApiParameter() { this = "not a model API parameter" } +private class ArgumentToLocalCall extends CharacteristicsImpl::UninterestingToModelCharacteristic { + ArgumentToLocalCall() { this = "argument to local call" } override predicate appliesToEndpoint(Endpoint e) { - not exists(ModelExclusions::ModelApi api | - exists(Call c | - c.getCallee() = api and - exists(int argIdx | exists(api.getParameter(argIdx)) | - argIdx = -1 and e.asExpr() = c.getQualifier() - or - e.asExpr() = c.getArgument(argIdx) - ) - ) - ) + ApplicationCandidatesImpl::getCallable(e).fromSource() + } +} + +/** + * A Characteristic that marks endpoints as uninteresting to model, according to the Java ModelExclusions module. + */ +private class ExcludedFromModeling extends CharacteristicsImpl::UninterestingToModelCharacteristic { + ExcludedFromModeling() { this = "excluded from modeling" } + + override predicate appliesToEndpoint(Endpoint e) { + ModelExclusions::isUninterestingForModels(ApplicationCandidatesImpl::getCallable(e)) or + ModelExclusions::isUninterestingForModels(e.getEnclosingCallable()) } } From 791ba81403721610f45f8d601413f78d2245d5a5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 May 2023 13:23:52 +0100 Subject: [PATCH 107/739] Swift: Add change note. --- .../change-notes/2023-05-25-string-length-conflation-fp.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md diff --git a/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md b/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md new file mode 100644 index 00000000000..937ebd4b41a --- /dev/null +++ b/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md @@ -0,0 +1,4 @@ +— +category: minorAnalysis +— +* Fixed some false positive results from the `swift/string-length-conflation` query, caused by imprecise sinks. From 242d263e8a11617492d7375193f7841521306431 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 15:18:15 +0200 Subject: [PATCH 108/739] Codegen: move ipa info from `ql.Class` to `ql.Property` --- misc/codegen/generators/qlgen.py | 6 +++--- misc/codegen/lib/ql.py | 2 +- misc/codegen/templates/ql_class.mustache | 16 ++++++++-------- misc/codegen/test/test_qlgen.py | 16 ++++++++++++---- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index 7affea51828..49b1b537bc2 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -110,7 +110,8 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str = is_optional=prop.is_optional, is_predicate=prop.is_predicate, is_unordered=prop.is_unordered, - description=prop.description + description=prop.description, + synth=bool(cls.ipa), ) if prop.is_single: args.update( @@ -162,7 +163,6 @@ def get_ql_class(cls: schema.Class) -> ql.Class: final=not cls.derived, properties=properties, dir=pathlib.Path(cls.group or ""), - ipa=bool(cls.ipa), doc=cls.doc, **pragmas, ) @@ -342,7 +342,7 @@ def generate(opts, renderer): with renderer.manage(generated=generated, stubs=stubs, registry=opts.generated_registry, force=opts.force) as renderer: - db_classes = [cls for cls in classes.values() if not cls.ipa] + db_classes = [cls for name, cls in classes.items() if not data.classes[name].ipa] renderer.render(ql.DbClasses(db_classes), out / "Raw.qll") classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name)) diff --git a/misc/codegen/lib/ql.py b/misc/codegen/lib/ql.py index 97165053fd0..e4bac3197cb 100644 --- a/misc/codegen/lib/ql.py +++ b/misc/codegen/lib/ql.py @@ -42,6 +42,7 @@ class Property: description: List[str] = field(default_factory=list) doc: Optional[str] = None doc_plural: Optional[str] = None + synth: bool = False def __post_init__(self): if self.tableparams: @@ -111,7 +112,6 @@ class Class: qltest_collapse_hierarchy: bool = False qltest_uncollapse_hierarchy: bool = False ql_internal: bool = False - ipa: bool = False doc: List[str] = field(default_factory=list) def __post_init__(self): diff --git a/misc/codegen/templates/ql_class.mustache b/misc/codegen/templates/ql_class.mustache index 9f72caef392..8ee465bf993 100644 --- a/misc/codegen/templates/ql_class.mustache +++ b/misc/codegen/templates/ql_class.mustache @@ -67,12 +67,12 @@ module Generated { * behavior of both the `Immediate` and non-`Immediate` versions. */ {{type}} get{{#is_unordered}}An{{/is_unordered}}Immediate{{singular}}({{#is_indexed}}int index{{/is_indexed}}) { - {{^ipa}} + {{^synth}} result = Synth::convert{{type}}FromRaw(Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}})) - {{/ipa}} - {{#ipa}} + {{/synth}} + {{#synth}} none() - {{/ipa}} + {{/synth}} } /** @@ -99,12 +99,12 @@ module Generated { {{/has_description}} */ {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { - {{^ipa}} + {{^synth}} {{^is_predicate}}result = {{/is_predicate}}Synth::convert{{name}}ToRaw(this){{^root}}.(Raw::{{name}}){{/root}}.{{getter}}({{#is_indexed}}index{{/is_indexed}}) - {{/ipa}} - {{#ipa}} + {{/synth}} + {{#synth}} none() - {{/ipa}} + {{/synth}} } {{/type_is_class}} diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index 1cd85762315..6ed83edf4e0 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -861,25 +861,33 @@ def test_property_on_class_with_default_doc_name(generate_classes): def test_stub_on_class_with_ipa_from_class(generate_classes): assert generate_classes([ - schema.Class("MyObject", ipa=schema.IpaInfo(from_class="A")), + schema.Class("MyObject", ipa=schema.IpaInfo(from_class="A"), + properties=[schema.SingleProperty("foo", "bar")]), ]) == { "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject", ipa_accessors=[ ql.IpaUnderlyingAccessor(argument="Entity", type="Raw::A", constructorparams=["result"]), ]), - a_ql_class(name="MyObject", final=True, ipa=True)), + a_ql_class(name="MyObject", final=True, properties=[ + ql.Property(singular="Foo", type="bar", tablename="my_objects", synth=True, + tableparams=["this", "result"], doc="foo of this my object"), + ])), } def test_stub_on_class_with_ipa_on_arguments(generate_classes): assert generate_classes([ - schema.Class("MyObject", ipa=schema.IpaInfo(on_arguments={"base": "A", "index": "int", "label": "string"})), + schema.Class("MyObject", ipa=schema.IpaInfo(on_arguments={"base": "A", "index": "int", "label": "string"}), + properties=[schema.SingleProperty("foo", "bar")]), ]) == { "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject", ipa_accessors=[ ql.IpaUnderlyingAccessor(argument="Base", type="Raw::A", constructorparams=["result", "_", "_"]), ql.IpaUnderlyingAccessor(argument="Index", type="int", constructorparams=["_", "result", "_"]), ql.IpaUnderlyingAccessor(argument="Label", type="string", constructorparams=["_", "_", "result"]), ]), - a_ql_class(name="MyObject", final=True, ipa=True)), + a_ql_class(name="MyObject", final=True, properties=[ + ql.Property(singular="Foo", type="bar", tablename="my_objects", synth=True, + tableparams=["this", "result"], doc="foo of this my object"), + ])), } From 165ac3eeaa2104b5947cc0869e9c9479abfa8e3c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 15:28:53 +0200 Subject: [PATCH 109/739] Codegen: define and propagate `synth` property flag --- misc/codegen/generators/qlgen.py | 2 +- misc/codegen/lib/schema.py | 1 + misc/codegen/test/test_qlgen.py | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index 49b1b537bc2..a5b8379580f 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -111,7 +111,7 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, prev_child: str = is_predicate=prop.is_predicate, is_unordered=prop.is_unordered, description=prop.description, - synth=bool(cls.ipa), + synth=bool(cls.ipa) or prop.synth, ) if prop.is_single: args.update( diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py index 64a4720093b..2f3ce1cb9d3 100644 --- a/misc/codegen/lib/schema.py +++ b/misc/codegen/lib/schema.py @@ -34,6 +34,7 @@ class Property: pragmas: List[str] = field(default_factory=list) doc: Optional[str] = None description: List[str] = field(default_factory=list) + synth: bool = False @property def is_single(self) -> bool: diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index 6ed83edf4e0..4650974510f 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -891,5 +891,19 @@ def test_stub_on_class_with_ipa_on_arguments(generate_classes): } +def test_synth_property(generate_classes): + assert generate_classes([ + schema.Class("MyObject", properties=[ + schema.SingleProperty("foo", "bar", synth=True)]), + ]) == { + "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + a_ql_class(name="MyObject", final=True, + properties=[ + ql.Property(singular="Foo", type="bar", tablename="my_objects", synth=True, + tableparams=["this", "result"], doc="foo of this my object"), + ])), + } + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) From d2c9847a790197ce1fe36b957f7ac511f3d630fa Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 15:36:32 +0200 Subject: [PATCH 110/739] Codegen: parse `synth` property modifier --- misc/codegen/lib/schemadefs.py | 7 ++++++- misc/codegen/test/test_schemaloader.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index f3bfd9840dc..3db8fe781ce 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -44,10 +44,15 @@ class _Namespace: self.__dict__.update(kwargs) +class _SynthModifier(_schema.PropertyModifier, _Namespace): + def modify(self, prop: _schema.Property): + prop.synth = True + + qltest = _Namespace() ql = _Namespace() cpp = _Namespace() -synth = _Namespace() +synth = _SynthModifier() @_dataclass diff --git a/misc/codegen/test/test_schemaloader.py b/misc/codegen/test/test_schemaloader.py index 9c9750818ea..949d2f385be 100644 --- a/misc/codegen/test/test_schemaloader.py +++ b/misc/codegen/test/test_schemaloader.py @@ -455,6 +455,17 @@ def test_ipa_class_hierarchy(): } +def test_synthesized_property(): + @load + class data: + class A: + x: defs.int | defs.synth + + assert data.classes["A"].properties == [ + schema.SingleProperty("x", "int", synth=True) + ] + + def test_class_docstring(): @load class data: From 00fb796f3bd79243830bbb11b97e675c70adac43 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 15:43:43 +0200 Subject: [PATCH 111/739] Codegen: ignore `synth` properties in `dbschemegen` --- misc/codegen/generators/dbschemegen.py | 7 +++++-- misc/codegen/test/test_dbschemegen.py | 27 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/misc/codegen/generators/dbschemegen.py b/misc/codegen/generators/dbschemegen.py index 8441b6fd61d..bc45ae3022f 100755 --- a/misc/codegen/generators/dbschemegen.py +++ b/misc/codegen/generators/dbschemegen.py @@ -49,7 +49,7 @@ def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], a # Leaf classes need a table to bind the `@` ids # 1-to-1 properties are added to a class specific table # in other cases, separate tables are used for the properties, and a class specific table is unneeded - if not cls.derived or any(f.is_single for f in cls.properties): + if not cls.derived or any(f.is_single and not f.synth for f in cls.properties): binding = not cls.derived keyset = KeySet(["id"]) if cls.derived else None yield Table( @@ -58,12 +58,15 @@ def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], a columns=[ Column("id", type=dbtype(cls.name), binding=binding), ] + [ - Column(f.name, dbtype(f.type, add_or_none_except)) for f in cls.properties if f.is_single + Column(f.name, dbtype(f.type, add_or_none_except)) + for f in cls.properties if f.is_single and not f.synth ], dir=dir, ) # use property-specific tables for 1-to-many and 1-to-at-most-1 properties for f in cls.properties: + if f.synth: + continue if f.is_unordered: yield Table( name=inflection.tableize(f"{cls.name}_{f.name}"), diff --git a/misc/codegen/test/test_dbschemegen.py b/misc/codegen/test/test_dbschemegen.py index 86b9dd2fc84..45b5718a876 100644 --- a/misc/codegen/test/test_dbschemegen.py +++ b/misc/codegen/test/test_dbschemegen.py @@ -566,5 +566,32 @@ def test_ipa_derived_classes_ignored(generate): ) +def test_synth_properties_ignored(generate): + assert generate([ + schema.Class(name="A", properties=[ + schema.SingleProperty("x", "a"), + schema.SingleProperty("y", "b", synth=True), + schema.SingleProperty("z", "c"), + schema.OptionalProperty("foo", "bar", synth=True), + schema.RepeatedProperty("baz", "bazz", synth=True), + schema.RepeatedOptionalProperty("bazzz", "bazzzz", synth=True), + schema.RepeatedUnorderedProperty("bazzzzz", "bazzzzzz", synth=True), + ]), + ]) == dbscheme.Scheme( + src=schema_file.name, + includes=[], + declarations=[ + dbscheme.Table( + name="as", + columns=[ + dbscheme.Column("id", "@a", binding=True), + dbscheme.Column("x", "a"), + dbscheme.Column("z", "c"), + ], + ) + ], + ) + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) From b09386a2c8ff10d6227a04236c688afe340a4f43 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 15:55:57 +0200 Subject: [PATCH 112/739] Codegen: ignore `synth` properties in `Raw.qll` --- misc/codegen/templates/ql_db.mustache | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/codegen/templates/ql_db.mustache b/misc/codegen/templates/ql_db.mustache index d16416f4a5b..188abebc120 100644 --- a/misc/codegen/templates/ql_db.mustache +++ b/misc/codegen/templates/ql_db.mustache @@ -15,6 +15,7 @@ module Raw { {{#final}}override string toString() { result = "{{name}}" }{{/final}} {{#properties}} + {{^synth}} /** * {{>ql_property_doc}} * {{#has_description}} @@ -26,6 +27,7 @@ module Raw { {{type}} {{getter}}({{#is_indexed}}int index{{/is_indexed}}) { {{tablename}}({{#tableparams}}{{^first}}, {{/first}}{{param}}{{/tableparams}}) } + {{/synth}} {{/properties}} } From cc271d682e387a0163fa21de7c50ce36fecf0d91 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Tue, 23 May 2023 16:46:43 +0200 Subject: [PATCH 113/739] Codegen: ignore `synth` properties in `cppgen` --- misc/codegen/generators/cppgen.py | 2 +- misc/codegen/test/test_cppgen.py | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/misc/codegen/generators/cppgen.py b/misc/codegen/generators/cppgen.py index 1cd6cc36450..8f522dc1435 100644 --- a/misc/codegen/generators/cppgen.py +++ b/misc/codegen/generators/cppgen.py @@ -76,7 +76,7 @@ class Processor: bases=[self._get_class(b) for b in cls.bases], fields=[ _get_field(cls, p, self._add_or_none_except) - for p in cls.properties if "cpp_skip" not in p.pragmas + for p in cls.properties if "cpp_skip" not in p.pragmas and not p.synth ], final=not cls.derived, trap_name=trap_name, diff --git a/misc/codegen/test/test_cppgen.py b/misc/codegen/test/test_cppgen.py index 1bc7d150b2e..ebb7b3887ef 100644 --- a/misc/codegen/test/test_cppgen.py +++ b/misc/codegen/test/test_cppgen.py @@ -203,5 +203,27 @@ def test_ipa_classes_ignored(generate): ] +def test_synth_properties_ignored(generate): + assert generate([ + schema.Class( + name="X", + properties=[ + schema.SingleProperty("x", "a"), + schema.SingleProperty("y", "b", synth=True), + schema.SingleProperty("z", "c"), + schema.OptionalProperty("foo", "bar", synth=True), + schema.RepeatedProperty("baz", "bazz", synth=True), + schema.RepeatedOptionalProperty("bazzz", "bazzzz", synth=True), + schema.RepeatedUnorderedProperty("bazzzzz", "bazzzzzz", synth=True), + ], + ), + ]) == [ + cpp.Class(name="X", final=True, trap_name="Xes", fields=[ + cpp.Field("x", "a"), + cpp.Field("z", "c"), + ]), + ] + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) From 76d731a61da81fac609f485fdbf36be997f8ecc5 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Thu, 25 May 2023 16:28:07 +0200 Subject: [PATCH 114/739] improve CannotBeTaintedCharacteristic --- .../ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 736e8b947bf..c0c02ffe3d6 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -345,6 +345,7 @@ private class CannotBeTaintedCharacteristic extends CharacteristicsImpl::LikelyN * Holds if the node `n` is known as the predecessor in a modeled flow step. */ private predicate isKnownOutNodeForStep(Endpoint e) { + e.asExpr() instanceof Call or // we just assume flow in that case TaintTracking::localTaintStep(_, e) or FlowSummaryImpl::Private::Steps::summaryThroughStepValue(_, e, _) or FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(_, e, _) or From db77c6b9a34f01922385c1947ae033b68c92f6e8 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Thu, 25 May 2023 16:39:27 +0200 Subject: [PATCH 115/739] Java: mark functional expressions as likely not sinks --- .../AutomodelApplicationModeCharacteristics.qll | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index c0c02ffe3d6..c3d6a91946a 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -328,6 +328,17 @@ private class OtherArgumentToModeledMethodCharacteristic extends Characteristics } } +/** + * A characteristic that marks functional expression as likely not sinks. + * + * These expressions may well _contain_ sinks, but rarely are sinks themselves. + */ +private class FunctionValueCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic { + FunctionValueCharacteristic() { this = "function value" } + + override predicate appliesToEndpoint(Endpoint e) { e.asExpr() instanceof FunctionalExpr } +} + /** * A negative characteristic that indicates that an endpoint is not a `to` node for any known taint step. Such a node * cannot be tainted, because taint can't flow into it. From 5ca22210976f0d91e8252b8c52c3237fac8d1654 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Thu, 25 May 2023 17:06:02 +0200 Subject: [PATCH 116/739] remove some of the biggest frameworks from application mode consideration --- ...utomodelApplicationModeCharacteristics.qll | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index c3d6a91946a..138e508b1d2 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -277,6 +277,29 @@ private class ArgumentToLocalCall extends CharacteristicsImpl::UninterestingToMo } } +/** + * A characteristic that avoids modeling endpoint that are passed to frameworks + * in application mode. + * + * It's much more economical to use framework mode for those. + */ +private class SkipFrameworkModeling extends CharacteristicsImpl::UninterestingToModelCharacteristic { + SkipFrameworkModeling() { this = "skip modeling of large frameworks" } + + override predicate appliesToEndpoint(Endpoint e) { + ApplicationCandidatesImpl::getCallable(e) + .getDeclaringType() + .getPackage() + .getName() + .matches([ + "com.google%", // + "java.%", // + "javax.%", // + "org.apache%", // + ]) + } +} + /** * A Characteristic that marks endpoints as uninteresting to model, according to the Java ModelExclusions module. */ From 85a1ab0264e62bef86b7564a7808b6d73220de66 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 May 2023 16:10:31 +0100 Subject: [PATCH 117/739] Swift: Undo autocorrect. --- .../change-notes/2023-05-25-string-length-conflation-fp.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md b/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md index 937ebd4b41a..7166b5e9ed7 100644 --- a/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md +++ b/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md @@ -1,4 +1,4 @@ -— +--- category: minorAnalysis -— +--- * Fixed some false positive results from the `swift/string-length-conflation` query, caused by imprecise sinks. From 0e443da7106bd86078b98e2ab3aeb09bb17ba49a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 May 2023 17:43:42 +0100 Subject: [PATCH 118/739] Swift: Remove id() categorization due to accuracy, and repair the old bank.?account case. --- .../codeql/swift/security/SensitiveExprs.qll | 8 +- .../CWE-311/CleartextTransmission.expected | 4 - .../Security/CWE-311/SensitiveExprs.expected | 85 +++++++++---------- .../Security/CWE-311/testURL.swift | 2 +- .../CWE-328/WeakSensitiveDataHashing.expected | 12 --- .../Security/CWE-328/testCryptoKit.swift | 12 +-- 6 files changed, 53 insertions(+), 70 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index c3432fa58e4..b6f5c231823 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -30,7 +30,11 @@ class SensitiveCredential extends SensitiveDataType, TCredential { override string toString() { result = "credential" } override string getRegexp() { - result = HeuristicNames::maybeSensitiveRegexp(_) or + exists(SensitiveDataClassification classification | + not classification = SensitiveDataClassification::id() and // not accurate enough + result = HeuristicNames::maybeSensitiveRegexp(classification) + ) + or result = "(?is).*(license.?key).*" } } @@ -54,7 +58,7 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo { // Geographic location - where the user is (or was) "latitude|longitude|" + // Financial data - such as credit card numbers, salary, bank accounts, and debts - "credit.?card|debit.?card|salary|" + + "credit.?card|debit.?card|salary|bank.?account|" + // Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc. "email|" + // Health - medical conditions, insurance status, prescription records diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected index c832cf51a15..94272faf6d0 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -13,7 +13,6 @@ edges | testSend.swift:54:17:54:17 | password | testSend.swift:41:10:41:18 | data | | testSend.swift:54:17:54:17 | password | testSend.swift:54:13:54:25 | call to pad(_:) | | testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | -| testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | nodes | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | @@ -41,8 +40,6 @@ nodes | testSend.swift:66:27:66:30 | .mobileNumber | semmle.label | .mobileNumber | | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testURL.swift:13:54:13:54 | passwd | semmle.label | passwd | -| testURL.swift:15:22:15:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | -| testURL.swift:15:55:15:55 | account_no | semmle.label | account_no | | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no | semmle.label | credit_card_no | | testURL.swift:20:22:20:22 | passwd | semmle.label | passwd | @@ -61,6 +58,5 @@ subpaths | testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | This operation transmits 'license_key', which may contain unencrypted sensitive data from $@. | testSend.swift:65:27:65:27 | license_key | license_key | | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | This operation transmits '.mobileNumber', which may contain unencrypted sensitive data from $@. | testSend.swift:66:27:66:30 | .mobileNumber | .mobileNumber | | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:13:54:13:54 | passwd | passwd | -| testURL.swift:15:22:15:55 | ... .+(_:_:) ... | testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:15:55:15:55 | account_no | account_no | | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:16:55:16:55 | credit_card_no | credit_card_no | | testURL.swift:20:22:20:22 | passwd | testURL.swift:20:22:20:22 | passwd | testURL.swift:20:22:20:22 | passwd | This operation transmits 'passwd', which may contain unencrypted sensitive data from $@. | testURL.swift:20:22:20:22 | passwd | passwd | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 708d68a05e9..89b8d36ccdf 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -4,54 +4,50 @@ | testAlamofire.swift:159:26:159:26 | email | label:email, type:private information | | testAlamofire.swift:171:35:171:35 | email | label:email, type:private information | | testAlamofire.swift:177:35:177:35 | email | label:email, type:private information | -| testAlamofire.swift:187:48:187:48 | username | label:username, type:credential | | testAlamofire.swift:187:65:187:65 | password | label:password, type:credential | -| testAlamofire.swift:195:47:195:47 | username | label:username, type:credential | | testAlamofire.swift:195:64:195:64 | password | label:password, type:credential | -| testAlamofire.swift:205:45:205:45 | username | label:username, type:credential | | testAlamofire.swift:205:62:205:62 | password | label:password, type:credential | -| testAlamofire.swift:213:48:213:48 | username | label:username, type:credential | | testAlamofire.swift:213:65:213:65 | password | label:password, type:credential | -| testCoreData2.swift:37:16:37:16 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:38:2:38:6 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | -| testCoreData2.swift:39:2:39:6 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | -| testCoreData2.swift:39:28:39:28 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:40:2:40:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential | -| testCoreData2.swift:41:2:41:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential | -| testCoreData2.swift:41:29:41:29 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:42:2:42:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential | -| testCoreData2.swift:43:2:43:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential | -| testCoreData2.swift:43:35:43:35 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:46:22:46:22 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:47:2:47:12 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | -| testCoreData2.swift:48:2:48:12 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | -| testCoreData2.swift:48:34:48:34 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:49:2:49:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential | -| testCoreData2.swift:50:2:50:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:credential | -| testCoreData2.swift:50:35:50:35 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:51:2:51:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential | -| testCoreData2.swift:52:2:52:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:credential | -| testCoreData2.swift:52:41:52:41 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:57:3:57:7 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | -| testCoreData2.swift:57:29:57:29 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:60:4:60:8 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | -| testCoreData2.swift:60:30:60:30 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:62:4:62:8 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | -| testCoreData2.swift:62:30:62:30 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:65:3:65:7 | .myBankAccountNumber | label:myBankAccountNumber, type:credential | -| testCoreData2.swift:65:29:65:29 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:79:18:79:28 | .bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 | label:bankAccountNo2, type:credential | -| testCoreData2.swift:82:18:82:18 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:83:18:83:18 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:84:18:84:18 | bankAccountNo2 | label:bankAccountNo2, type:credential | -| testCoreData2.swift:85:18:85:18 | bankAccountNo2 | label:bankAccountNo2, type:credential | -| testCoreData2.swift:87:22:87:32 | .bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:88:22:88:22 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:89:22:89:22 | bankAccountNo2 | label:bankAccountNo2, type:credential | -| testCoreData2.swift:91:10:91:10 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:95:10:95:10 | bankAccountNo | label:bankAccountNo, type:credential | -| testCoreData2.swift:101:10:101:10 | bankAccountNo | label:bankAccountNo, type:credential | +| testCoreData2.swift:37:16:37:16 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:38:2:38:6 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | +| testCoreData2.swift:39:2:39:6 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | +| testCoreData2.swift:39:28:39:28 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:40:2:40:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:private information | +| testCoreData2.swift:41:2:41:6 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:private information | +| testCoreData2.swift:41:29:41:29 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:42:2:42:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:private information | +| testCoreData2.swift:43:2:43:6 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:private information | +| testCoreData2.swift:43:35:43:35 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:46:22:46:22 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:47:2:47:12 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | +| testCoreData2.swift:48:2:48:12 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | +| testCoreData2.swift:48:34:48:34 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:49:2:49:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:private information | +| testCoreData2.swift:50:2:50:12 | .myBankAccountNumber2 | label:myBankAccountNumber2, type:private information | +| testCoreData2.swift:50:35:50:35 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:51:2:51:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:private information | +| testCoreData2.swift:52:2:52:12 | .notStoredBankAccountNumber | label:notStoredBankAccountNumber, type:private information | +| testCoreData2.swift:52:41:52:41 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:57:3:57:7 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | +| testCoreData2.swift:57:29:57:29 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:60:4:60:8 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | +| testCoreData2.swift:60:30:60:30 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:62:4:62:8 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | +| testCoreData2.swift:62:30:62:30 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:65:3:65:7 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | +| testCoreData2.swift:65:29:65:29 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:79:18:79:28 | .bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 | label:bankAccountNo2, type:private information | +| testCoreData2.swift:82:18:82:18 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:83:18:83:18 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:84:18:84:18 | bankAccountNo2 | label:bankAccountNo2, type:private information | +| testCoreData2.swift:85:18:85:18 | bankAccountNo2 | label:bankAccountNo2, type:private information | +| testCoreData2.swift:87:22:87:32 | .bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:88:22:88:22 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:89:22:89:22 | bankAccountNo2 | label:bankAccountNo2, type:private information | +| testCoreData2.swift:91:10:91:10 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:95:10:95:10 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:101:10:101:10 | bankAccountNo | label:bankAccountNo, type:private information | | testCoreData.swift:48:15:48:15 | password | label:password, type:credential | | testCoreData.swift:51:24:51:24 | password | label:password, type:credential | | testCoreData.swift:58:15:58:15 | password | label:password, type:credential | @@ -133,6 +129,5 @@ | testSend.swift:66:27:66:30 | .mobileNumber | label:mobileNumber, type:private information | | testSend.swift:69:27:69:30 | .passwordFeatureEnabled | label:passwordFeatureEnabled, type:credential | | testURL.swift:13:54:13:54 | passwd | label:passwd, type:credential | -| testURL.swift:15:55:15:55 | account_no | label:account_no, type:credential | | testURL.swift:16:55:16:55 | credit_card_no | label:credit_card_no, type:private information | | testURL.swift:20:22:20:22 | passwd | label:passwd, type:credential | diff --git a/swift/ql/test/query-tests/Security/CWE-311/testURL.swift b/swift/ql/test/query-tests/Security/CWE-311/testURL.swift index 7f9b64ff4f6..48ae815232f 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testURL.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testURL.swift @@ -12,7 +12,7 @@ struct URL func test1(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) { let a = URL(string: "http://example.com/login?p=" + passwd); // BAD let b = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive) - let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD + let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD [NOT DETECTED] let d = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD let base = URL(string: "http://example.com/"); // GOOD (not sensitive) diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected index 16fc67d4a6f..b6c7161b853 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -2,28 +2,22 @@ edges nodes | testCryptoKit.swift:56:47:56:47 | passwd | semmle.label | passwd | | testCryptoKit.swift:57:43:57:43 | cert | semmle.label | cert | -| testCryptoKit.swift:59:43:59:43 | account_no | semmle.label | account_no | | testCryptoKit.swift:60:43:60:43 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:61:43:61:43 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:63:44:63:44 | passwd | semmle.label | passwd | | testCryptoKit.swift:64:44:64:44 | cert | semmle.label | cert | -| testCryptoKit.swift:66:44:66:44 | account_no | semmle.label | account_no | | testCryptoKit.swift:67:44:67:44 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:90:23:90:23 | passwd | semmle.label | passwd | | testCryptoKit.swift:91:23:91:23 | cert | semmle.label | cert | -| testCryptoKit.swift:93:23:93:23 | account_no | semmle.label | account_no | | testCryptoKit.swift:94:23:94:23 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:99:23:99:23 | passwd | semmle.label | passwd | | testCryptoKit.swift:100:23:100:23 | cert | semmle.label | cert | -| testCryptoKit.swift:102:23:102:23 | account_no | semmle.label | account_no | | testCryptoKit.swift:103:23:103:23 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:132:32:132:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:133:32:133:32 | cert | semmle.label | cert | -| testCryptoKit.swift:135:32:135:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:136:32:136:32 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:141:32:141:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:142:32:142:32 | cert | semmle.label | cert | -| testCryptoKit.swift:144:32:144:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:145:32:145:32 | credit_card_no | semmle.label | credit_card_no | | testCryptoSwift.swift:113:30:113:30 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:115:31:115:31 | passwdArray | semmle.label | passwdArray | @@ -39,28 +33,22 @@ subpaths #select | testCryptoKit.swift:56:47:56:47 | passwd | testCryptoKit.swift:56:47:56:47 | passwd | testCryptoKit.swift:56:47:56:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:56:47:56:47 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:57:43:57:43 | cert | testCryptoKit.swift:57:43:57:43 | cert | testCryptoKit.swift:57:43:57:43 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:57:43:57:43 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:59:43:59:43 | account_no | testCryptoKit.swift:59:43:59:43 | account_no | testCryptoKit.swift:59:43:59:43 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:59:43:59:43 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:60:43:60:43 | credit_card_no | testCryptoKit.swift:60:43:60:43 | credit_card_no | testCryptoKit.swift:60:43:60:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:60:43:60:43 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:61:43:61:43 | credit_card_no | testCryptoKit.swift:61:43:61:43 | credit_card_no | testCryptoKit.swift:61:43:61:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:61:43:61:43 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:63:44:63:44 | passwd | testCryptoKit.swift:63:44:63:44 | passwd | testCryptoKit.swift:63:44:63:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:63:44:63:44 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:64:44:64:44 | cert | testCryptoKit.swift:64:44:64:44 | cert | testCryptoKit.swift:64:44:64:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:64:44:64:44 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:66:44:66:44 | account_no | testCryptoKit.swift:66:44:66:44 | account_no | testCryptoKit.swift:66:44:66:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:66:44:66:44 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:67:44:67:44 | credit_card_no | testCryptoKit.swift:67:44:67:44 | credit_card_no | testCryptoKit.swift:67:44:67:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:67:44:67:44 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:90:23:90:23 | passwd | testCryptoKit.swift:90:23:90:23 | passwd | testCryptoKit.swift:90:23:90:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:90:23:90:23 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:91:23:91:23 | cert | testCryptoKit.swift:91:23:91:23 | cert | testCryptoKit.swift:91:23:91:23 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:91:23:91:23 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:93:23:93:23 | account_no | testCryptoKit.swift:93:23:93:23 | account_no | testCryptoKit.swift:93:23:93:23 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:93:23:93:23 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:94:23:94:23 | credit_card_no | testCryptoKit.swift:94:23:94:23 | credit_card_no | testCryptoKit.swift:94:23:94:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:94:23:94:23 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:99:23:99:23 | passwd | testCryptoKit.swift:99:23:99:23 | passwd | testCryptoKit.swift:99:23:99:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:99:23:99:23 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:100:23:100:23 | cert | testCryptoKit.swift:100:23:100:23 | cert | testCryptoKit.swift:100:23:100:23 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:100:23:100:23 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:102:23:102:23 | account_no | testCryptoKit.swift:102:23:102:23 | account_no | testCryptoKit.swift:102:23:102:23 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:102:23:102:23 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:103:23:103:23 | credit_card_no | testCryptoKit.swift:103:23:103:23 | credit_card_no | testCryptoKit.swift:103:23:103:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:103:23:103:23 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:132:32:132:32 | passwd | testCryptoKit.swift:132:32:132:32 | passwd | testCryptoKit.swift:132:32:132:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:132:32:132:32 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:133:32:133:32 | cert | testCryptoKit.swift:133:32:133:32 | cert | testCryptoKit.swift:133:32:133:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:133:32:133:32 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:135:32:135:32 | account_no | testCryptoKit.swift:135:32:135:32 | account_no | testCryptoKit.swift:135:32:135:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:135:32:135:32 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:136:32:136:32 | credit_card_no | testCryptoKit.swift:136:32:136:32 | credit_card_no | testCryptoKit.swift:136:32:136:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:136:32:136:32 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:141:32:141:32 | passwd | testCryptoKit.swift:141:32:141:32 | passwd | testCryptoKit.swift:141:32:141:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:141:32:141:32 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:142:32:142:32 | cert | testCryptoKit.swift:142:32:142:32 | cert | testCryptoKit.swift:142:32:142:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:142:32:142:32 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:144:32:144:32 | account_no | testCryptoKit.swift:144:32:144:32 | account_no | testCryptoKit.swift:144:32:144:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:144:32:144:32 | account_no | sensitive data (credential account_no) | | testCryptoKit.swift:145:32:145:32 | credit_card_no | testCryptoKit.swift:145:32:145:32 | credit_card_no | testCryptoKit.swift:145:32:145:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:145:32:145:32 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoSwift.swift:113:30:113:30 | passwdArray | testCryptoSwift.swift:113:30:113:30 | passwdArray | testCryptoSwift.swift:113:30:113:30 | passwdArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:113:30:113:30 | passwdArray | sensitive data (credential passwdArray) | | testCryptoSwift.swift:115:31:115:31 | passwdArray | testCryptoSwift.swift:115:31:115:31 | passwdArray | testCryptoSwift.swift:115:31:115:31 | passwdArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:115:31:115:31 | passwdArray | sensitive data (credential passwdArray) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index 55fb9284fa6..4e6f301c84b 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -56,14 +56,14 @@ func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_pa var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD hash = Crypto.Insecure.MD5.hash(data: cert) // BAD hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD + hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED] hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD + hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD [NOT DETECTED] hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD hash = Crypto.SHA256.hash(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash @@ -90,7 +90,7 @@ func testMD5UpdateWithData(passwd : String, cert: String, encrypted_passwd : Str hash.update(data: passwd) // BAD hash.update(data: cert) // BAD hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD + hash.update(data: account_no) // BAD [NOT DETECTED] hash.update(data: credit_card_no) // BAD } @@ -99,7 +99,7 @@ func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : St hash.update(data: passwd) // BAD hash.update(data: cert) // BAD hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD + hash.update(data: account_no) // BAD [NOT DETECTED] hash.update(data: credit_card_no) // BAD } @@ -132,7 +132,7 @@ func testMD5UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, ce hash.update(bufferPointer: passwd) // BAD hash.update(bufferPointer: cert) // BAD hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive) - hash.update(bufferPointer: account_no) // BAD + hash.update(bufferPointer: account_no) // BAD [NOT DETECTED] hash.update(bufferPointer: credit_card_no) // BAD } @@ -141,7 +141,7 @@ func testSHA1UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, c hash.update(bufferPointer: passwd) // BAD hash.update(bufferPointer: cert) // BAD hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive) - hash.update(bufferPointer: account_no) // BAD + hash.update(bufferPointer: account_no) // BAD [NOT DETECTED] hash.update(bufferPointer: credit_card_no) // BAD } From 0d1d20c75b9c088fa5dea8d50565a2026485af2e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 25 May 2023 15:50:29 -0700 Subject: [PATCH 119/739] C++: Change range-analysis test to not use 'getAst'. This was creating confusing test expectation annotations. --- .../ir/range-analysis/RangeAnalysis.ql | 9 +- .../SimpleRangeAnalysis_tests.cpp | 114 +++++++++--------- .../library-tests/ir/range-analysis/test.cpp | 12 +- 3 files changed, 64 insertions(+), 71 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql index 84437827d0d..eadf0b90ef5 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql @@ -40,14 +40,7 @@ bindingset[delta] private string getBoundString(SemBound b, float delta) { b instanceof SemZeroBound and result = delta.toString() or - result = - strictconcat(b.(SemSsaBound) - .getAVariable() - .(SemanticExprConfig::SsaVariable) - .asInstruction() - .getAst() - .toString(), ":" - ) + getOffsetString(delta) + result = strictconcat(b.(SemSsaBound).getAVariable().toString(), ":") + getOffsetString(delta) } private string getARangeString(SemExpr e) { diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index eed0a7d7e47..92e197115b7 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -8,7 +8,7 @@ int test1(struct List* p) { int count = 0; for (; p; p = p->next) { count = count+1; - range(count); // $ range===count:p+1 + range(count); // $ range="==Phi: p:Store: count+1" } range(count); return count; @@ -18,7 +18,7 @@ int test2(struct List* p) { int count = 0; for (; p; p = p->next) { count = (count+1) % 10; - range(count); // $ range=<=9 range=>=-9 range=<=count:p+1 + range(count); // $ range=<=9 range=>=-9 range="<=Phi: p:Store: count+1" } range(count); // $ range=>=-9 range=<=9 return count; @@ -29,7 +29,7 @@ int test3(struct List* p) { for (; p; p = p->next) { range(count++); // $ range=>=-9 range=<=9 count = count % 10; - range(count); // $ range=<=9 range=>=-9 range="<=... +++0" range=<=count:p+1 + range(count); // $ range=<=9 range=>=-9 range="<=Store: ... +++0" range="<=Phi: p:Store: count+1" } range(count); // $ range=>=-9 range=<=9 return count; @@ -42,11 +42,11 @@ int test4() { range(i); // $ range=<=1 range=>=0 range(total); total += i; - range(total); // $ range=<=i+1 range=<=i+1 MISSING: range=>=0 range=>=i+0 + range(total); // $ range="<=Phi: i+1" MISSING: range=>=0 range=>=i+0 } range(total); // $ MISSING: range=>=0 range(i); // $ range===2 - range(total + i); // $ range=<=i+2 MISSING: range===i+2 range=>=2 range=>=i+0 + range(total + i); // $ range="<=Phi: i+2" MISSING: range===i+2 range=>=2 range=>=i+0 return total + i; } @@ -57,11 +57,11 @@ int test5() { range(i); // $ range=<=1 range=>=0 range(total); // $ MISSING: range=>=0 total += i; - range(total); // $ range=<=i+1 MISSING: range=>=0 range=>=i+0 + range(total); // $ range="<=Phi: i+1" MISSING: range=>=0 range=>=i+0 } range(total); // $ MISSING: range=>=0 range(i); // $ range===2 - range(total + i); // $ range=<=i+2 MISSING: range===i+2 range=>=2 range=>=i+0 + range(total + i); // $ range="<=Phi: i+2" MISSING: range===i+2 range=>=2 range=>=i+0 return total + i; } @@ -72,7 +72,7 @@ int test6() { range(i); // $ range=<=1 range=>=0 range(total); // $ MISSING: range=>=0 total += i; - range(total); // $ range=<=i+1 MISSING: range=>=0 range=>=i+0 + range(total); // $ range="<=Phi: i+1" MISSING: range=>=0 range=>=i+0 } return total + i; } @@ -93,12 +93,12 @@ int test8(int x, int y) { if (-1000 < y && y < 10) { range(y); // $ range=<=9 range=>=-999 if (x < y-2) { - range(x); // $ range=<=6 range=<=y-3 - range(y); // $ range=<=9 range=>=-999 range=>=x+3 + range(x); // $ range=<=6 range="<=InitializeParameter: y:Store: y-3" + range(y); // $ range=<=9 range=>=-999 range=">=InitializeParameter: x:Store: x+3" return x; } - range(x); // $ range=>=-1001 range=>=y-2 - range(y); // $ range=<=9 range=<=x+2 range=>=-999 + range(x); // $ range=>=-1001 range=">=InitializeParameter: y:Store: y-2" + range(y); // $ range=<=9 range="<=InitializeParameter: x:Store: x+2" range=>=-999 } range(x); range(y); @@ -127,12 +127,12 @@ int test10(int x, int y) { if (y > 7) { range(y); // $ range=>=8 if (x < y) { - range(x); // $ range=<=y-1 - range(y); // $ range=>=8 range=>=x+1 + range(x); // $ range="<=InitializeParameter: y-1" + range(y); // $ range=>=8 range=">=InitializeParameter: x:Store: x+1" return 0; } - range(x); // $ range=>=8 range=>=y+0 - range(y); // $ range=<=x+0 range=>=8 + range(x); // $ range=>=8 range=">=InitializeParameter: y+0" + range(y); // $ range="<=InitializeParameter: x:Store: x+0" range=>=8 return x; } range(y); // $ range=<=7 @@ -145,7 +145,7 @@ int test11(char *p) { range(*p); if (c != '\0') { *p++ = '\0'; - range(p); // $ range===p+1 + range(p); // $ range="==InitializeParameter: p+1" range(*p); } if (c == ':') { @@ -155,7 +155,7 @@ int test11(char *p) { if (c != '\0') { range(c); *p++ = '\0'; - range(p); // $ range=<=p+2 range===c+1 range=>=p+1 + range(p); // $ range="<=InitializeParameter: p+2" range="==Phi: c+1" range=">=InitializeParameter: p+1" } if (c != ',') { return 1; @@ -193,7 +193,7 @@ int test13(char c, int i) { unsigned int y = x-1; // $ overflow=- range(y); // $ range===-1 overflow=- int z = i+1; // $ overflow=+ - range(z); // $ range===i+1 + range(z); // $ range="==InitializeParameter: i+1" range(c + i + uc + x + y + z); // $ overflow=+- overflow=+ overflow=- MISSING: range=>=1 range((double)(c + i + uc + x + y + z)); // $ overflow=+ overflow=+- overflow=- MISSING: range=>=1 return (double)(c + i + uc + x + y + z); // $ overflow=+- overflow=+ overflow=- @@ -245,7 +245,7 @@ int test_unary(int a) { range(c); // $ range=<=0 range=>=-11 range(b+c); // $ range=<=11 range=>=-11 MISSING:range=">=- ...+0" total += b+c; - range(total); // $ range=<=0+11 range=<=19 range=>=0-11 range=>=-19 + range(total); // $ range="<=Phi: 0+11" range=<=19 range=">=Phi: 0-11" range=>=-19 } if (-7 <= a && a <= 11) { range(a); // $ range=<=11 range=>=-7 @@ -255,7 +255,7 @@ int test_unary(int a) { range(c); // $ range=<=7 range=>=-11 range(b+c); // $ range=<=18 range=>=-18 total += b+c; - range(total); // $ range="<=- ...+18" range=">=- ...-18" range=<=0+29 range=<=37 range=>=0-29 range=>=-37 + range(total); // $ range="<=Phi: - ...+18" range=">=Phi: - ...-18" range="<=Phi: 0+29" range=<=37 range=">=Phi: 0-29" range=>=-37 } if (-7 <= a && a <= 1) { range(a); // $ range=<=1 range=>=-7 @@ -265,7 +265,7 @@ int test_unary(int a) { range(c); // $ range=<=7 range=>=-1 range(b+c); // $ range=<=8 range=>=-8 total += b+c; - range(total); // $ range="<=- ...+8" range="<=- ...+26" range=">=- ...-8" range=">=- ...-26" range=<=0+37 range=<=45 range=>=0-37 range=>=-45 + range(total); // $ range="<=Phi: - ...+8" range="<=Phi: - ...+26" range=">=Phi: - ...-8" range=">=Phi: - ...-26" range="<=Phi: 0+37" range=<=45 range=">=Phi: 0-37" range=>=-45 } if (-7 <= a && a <= 0) { range(a); // $ range=<=0 range=>=-7 @@ -275,7 +275,7 @@ int test_unary(int a) { range(c); // $ range=<=7 range=>=0 range(b+c); // $ range=>=-7 range=<=7 MISSING:range="<=- ...+0" total += b+c; - range(total); // $ range="<=- ...+7" range="<=- ...+15" range="<=- ...+33" range=">=- ...-7" range=">=- ...-15" range=">=- ...-33" range=<=0+44 range=<=52 range=>=0-44 range=>=-52 + range(total); // $ range="<=Phi: - ...+7" range="<=Phi: - ...+15" range="<=Phi: - ...+33" range=">=Phi: - ...-7" range=">=Phi: - ...-15" range=">=Phi: - ...-33" range="<=Phi: 0+44" range=<=52 Unexpected result: range=">=Phi: 0-44" range=>=-52 } if (-7 <= a && a <= -2) { range(a); // $ range=<=-2 range=>=-7 @@ -285,9 +285,9 @@ int test_unary(int a) { range(c); // $ range=<=7 range=>=2 range(b+c); // $ range=<=5 range=>=-5 total += b+c; - range(total); // $ range="<=- ...+5" range="<=- ...+12" range="<=- ...+20" range="<=- ...+38" range=">=- ...-5" range=">=- ...-12" range=">=- ...-20" range=">=- ...-38" range=<=0+49 range=<=57 range=>=0-49 range=>=-57 + range(total); // $ range="<=Phi: - ...+5" range="<=Phi: - ...+12" range="<=Phi: - ...+20" range="<=Phi: - ...+38" range=">=Phi: - ...-5" range=">=Phi: - ...-12" range=">=Phi: - ...-20" range=">=Phi: - ...-38" range="<=Phi: 0+49" range=<=57 range=">=Phi: 0-49" range=>=-57 } - range(total); // $ range="<=- ...+5" range="<=- ...+12" range="<=- ...+20" range="<=- ...+38" range=">=- ...-5" range=">=- ...-12" range=">=- ...-20" range=">=- ...-38" range=<=0+49 range=<=57 range=>=0-49 range=>=-57 + range(total); // $ range="<=Phi: - ...+5" range="<=Phi: - ...+12" range="<=Phi: - ...+20" range="<=Phi: - ...+38" range=">=Phi: - ...-5" range=">=Phi: - ...-12" range=">=Phi: - ...-20" range=">=Phi: - ...-38" range="<=Phi: 0+49" range=<=57 range=">=Phi: 0-49" range=>=-57 return total; } @@ -310,7 +310,7 @@ int test_mult01(int a, int b) { int r = a*b; // 0 .. 253 range(r); // $ range=<=253 range=>=0 total += r; - range(total); // $ range=<=3+253 range=<=506 range=>=0 range=>=3+0 + range(total); // $ range="<=Phi: 3+253" range=<=506 range=>=0 range=">=Phi: 3+0" } if (3 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -326,7 +326,7 @@ int test_mult01(int a, int b) { int r = a*b; // -143 .. 0 range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ range=>=3-143 + range(total); // $ range=">=Phi: 3-143" } if (3 <= a && a <= 11 && -13 <= b && b <= -7) { range(a); // $ range=<=11 range=>=3 @@ -334,9 +334,9 @@ int test_mult01(int a, int b) { int r = a*b; // -143 .. -21 range(r); // $ range=<=-21 range=>=-143 total += r; - range(total); // $ range=>=3-143 range=>=3-286 + range(total); // $ range=">=Phi: 3-143" range=">=Phi: 3-286" } - range(total); // $ range=>=3-143 range=>=3-286 + range(total); // $ range=">=Phi: 3-143" range=">=Phi: 3-286" return total; } @@ -358,7 +358,7 @@ int test_mult02(int a, int b) { int r = a*b; // 0 .. 253 range(r); // $ range=<=253 range=>=0 total += r; - range(total); // $ range=>=0 range=>=0+0 range=<=0+253 range=<=506 + range(total); // $ range=>=0 range=">=Phi: 0+0" range="<=Phi: 0+253" range=<=506 } if (0 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=0 @@ -374,7 +374,7 @@ int test_mult02(int a, int b) { int r = a*b; // -143 .. 0 range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ range=>=0-143 + range(total); // $ range=">=Phi: 0-143" } if (0 <= a && a <= 11 && -13 <= b && b <= -7) { range(a); // $ range=<=11 range=>=0 @@ -382,9 +382,9 @@ int test_mult02(int a, int b) { int r = a*b; // -143 .. 0 range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ range=>=0-143 range=>=0-286 + range(total); // $ range=">=Phi: 0-143" range=">=Phi: 0-286" } - range(total); // $range=>=0-143 range=>=0-286 + range(total); // $range=">=Phi: 0-143" range=">=Phi: 0-286" return total; } @@ -453,7 +453,7 @@ int test_mult04(int a, int b) { int r = a*b; // -391 .. 0 range(r); // $ range=<=0 range=>=-391 total += r; - range(total); // $ range="<=- ...+0" range=<=0 range=">=- ...-391" range=>=-782 + range(total); // $ range="<=Phi: - ...+0" range=<=0 range=">=Phi: - ...-391" range=>=-782 } if (-17 <= a && a <= 0 && -13 <= b && b <= 23) { range(a); // $ range=<=0 range=>=-17 @@ -469,7 +469,7 @@ int test_mult04(int a, int b) { int r = a*b; // 0 .. 221 range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ range="<=- ...+221" + range(total); // $ range="<=Phi: - ...+221" } if (-17 <= a && a <= 0 && -13 <= b && b <= -7) { range(a); // $ range=<=0 range=>=-17 @@ -477,9 +477,9 @@ int test_mult04(int a, int b) { int r = a*b; // 0 .. 221 range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ range="<=- ...+221" range="<=- ...+442" + range(total); // $ range="<=Phi: - ...+221" range="<=Phi: - ...+442" } - range(total); // $ range="<=- ...+221" range="<=- ...+442" + range(total); // $ range="<=Phi: - ...+221" range="<=Phi: - ...+442" return total; } @@ -501,7 +501,7 @@ int test_mult05(int a, int b) { int r = a*b; // -391 .. 0 range(r); // $ range=<=0 range=>=-391 total += r; - range(total); // $ range="<=- ...+0" range=<=0 range=">=- ...-391" range=>=-782 + range(total); // $ range="<=Phi: - ...+0" range=<=0 range=">=Phi: - ...-391" range=>=-782 } if (-17 <= a && a <= -2 && -13 <= b && b <= 23) { range(a); // $ range=<=-2 range=>=-17 @@ -517,7 +517,7 @@ int test_mult05(int a, int b) { int r = a*b; // 0 .. 221 range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ range="<=- ...+221" + range(total); // $ range="<=Phi: - ...+221" } if (-17 <= a && a <= -2 && -13 <= b && b <= -7) { range(a); // $ range=<=-2 range=>=-17 @@ -525,9 +525,9 @@ int test_mult05(int a, int b) { int r = a*b; // 14 .. 221 range(r); // $ range=<=221 range=>=14 total += r; - range(total); // $ range="<=- ...+221" range="<=- ...+442" + range(total); // $ range="<=Phi: - ...+221" range="<=Phi: - ...+442" } - range(total); // $ range="<=- ...+221" range="<=- ...+442" + range(total); // $ range="<=Phi: - ...+221" range="<=Phi: - ...+442" return total; } @@ -541,7 +541,7 @@ int test16(int x) { while (i < 3) { range(i); // $ range=<=2 range=>=0 i++; - range(i); // $ range=<=3 range=>=1 range="==... = ...:i+1" SPURIOUS:range="==... = ...:i+1" + range(i); // $ range=<=3 range=>=1 range="==Phi: i:Store: ... = ...+1" } range(d); d = i; @@ -640,14 +640,14 @@ unsigned int test_comma01(unsigned int x) { unsigned int y1; unsigned int y2; y1 = (++y, y); - range(y1); // $ range=<=101 range="==... ? ... : ...+1" + range(y1); // $ range=<=101 range="==Phi: ... ? ... : ...:Store: ... ? ... : ...+1" y2 = (y++, - range(y), // $ range=<=102 range="==++ ...:... = ...+1" range="==... ? ... : ...+2" + range(y), // $ range=<=102 range="==Store: ++ ...:Store: ... = ...+1" range="==Phi: ... ? ... : ...:Store: ... ? ... : ...+2" y += 3, - range(y), // $ range=<=105 range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" + range(y), // $ range=<=105 range="==Store: ++ ...:Store: ... = ...+4" range="==Store: ... +++3" range="==Phi: ... ? ... : ...:Store: ... ? ... : ...+5" y); - range(y2); // $ range=<=105 range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" - range(y1 + y2); // $ range=<=206 range="<=... ? ... : ...+106" MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" + range(y2); // $ range=<=105 range="==Store: ++ ...:Store: ... = ...+4" range="==Store: ... +++3" Unexpected result: range="==Phi: ... ? ... : ...:Store: ... ? ... : ...+5" + range(y1 + y2); // $ range=<=206 range="<=Phi: ... ? ... : ...:Store: ... ? ... : ...+106" MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" return y1 + y2; } @@ -672,7 +672,7 @@ void test17() { range(i); // $ range===50 i = 20 + (j -= 10); - range(i); // $ range="==... += ...:... = ...+10" range===60 + range(i); // $ range="==Store: ... += ...:Store: ... = ...+10" range===60 } // Tests for unsigned multiplication. @@ -693,7 +693,7 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 0 .. 253 range(r);// $ range=>=0 range=<=253 total += r; - range(total); // $ range=">=(unsigned int)...+0" range=>=0 range=<=506 range="<=(unsigned int)...+253" + range(total); // $ range=">=Phi: (unsigned int)...+0" range=>=0 range=<=506 range="<=Phi: (unsigned int)...+253" } if (3 <= a && a <= 11 && 13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -701,9 +701,9 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 39 .. 253 range(r); // $ range=>=39 range=<=253 total += r; - range(total); // $ range=>=39 range=<=759 range="<=(unsigned int)...+253" range="<=(unsigned int)...+506" range=">=(unsigned int)...+39" + range(total); // $ range=>=39 range=<=759 range="<=Phi: (unsigned int)...+253" range="<=Phi: (unsigned int)...+506" range=">=Phi: (unsigned int)...+39" } - range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253" + range(total); // $ range=>=0 range=<=759 range=">=Phi: (unsigned int)...+0" range="<=Phi: (unsigned int)...+506" range="<=Phi: (unsigned int)...+253" return total; } @@ -722,16 +722,16 @@ int test_unsigned_mult02(unsigned b) { int r = 11*b; // 0 .. 253 range(r); // $ range=>=0 range=<=253 total += r; - range(total); // $ range=">=(unsigned int)...+0" range=>=0 range="<=(unsigned int)...+253" range=<=506 + range(total); // $ range=">=Phi: (unsigned int)...+0" range=>=0 range="<=Phi: (unsigned int)...+253" range=<=506 } if (13 <= b && b <= 23) { range(b); // $ range=<=23 range=>=13 int r = 11*b; // 143 .. 253 range(r); // $ range=>=143 range=<=253 total += r; - range(total); // $ range="<=(unsigned int)...+253" range="<=(unsigned int)...+506" range=">=(unsigned int)...+143" range=>=143 range=<=759 + range(total); // $ range="<=Phi: (unsigned int)...+253" range="<=Phi: (unsigned int)...+506" range=">=Phi: (unsigned int)...+143" range=>=143 range=<=759 } - range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253" + range(total); // $ range=>=0 range=<=759 range=">=Phi: (unsigned int)...+0" range="<=Phi: (unsigned int)...+506" range="<=Phi: (unsigned int)...+253" return total; } @@ -851,7 +851,7 @@ int notequal_type_endpoint(unsigned n) { n--; // 1 .. } - range(n); // $ range=<=n+0 // 0 .. 0 + range(n); // $ range="<=InitializeParameter: n+0" // 0 .. 0 } void notequal_refinement(short n) { @@ -946,7 +946,7 @@ void widen_recursive_expr() { for (s = 0; s < 10; s++) { range(s); // $ range=<=9 range=>=0 int result = s + s; - range(result); // $ range=<=18 range=<=s+9 range=>=0 range=>=s+0 + range(result); // $ range=<=18 Unexpected result: range="<=Phi: s+9" range=>=0 Unexpected result: range=">=Phi: s+0" } } @@ -974,7 +974,7 @@ void test_mod_neg(int s) { void test_mod_ternary(int s, bool b) { int s2 = s % (b ? 5 : 500); - range(s2); // $ range=>=-499 range=<=499 range="<=... ? ... : ...-1" + range(s2); // $ range=>=-499 range=<=499 range="<=Phi: ... ? ... : ...-1" } void test_mod_ternary2(int s, bool b1, bool b2) { diff --git a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp index 10b4c1a9a22..5d816f3cda4 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp @@ -16,8 +16,8 @@ int sum = x + y; // $ overflow=+- } else { if (y > 300) { - range(x); // $ range=>=302 range=<=400 range=<=y+1 MISSING: range===y+1 - range(y); // $ range=>=301 range=<=399 range===x-1 + range(x); // $ range=>=302 range=<=400 range="<=InitializeParameter: y+1" MISSING: range===y+1 + range(y); // $ range=>=301 range=<=399 range="==InitializeParameter: x:Store: x-1" int sum = x + y; } } @@ -39,9 +39,9 @@ } if (y == x - 1 && y > 300 && y + 2 == z && z == 350) { // $ overflow=+ overflow=- - range(x); // $ range===349 range===y+1 range===z-1 - range(y); // $ range===348 range=>=x-1 range===z-2 MISSING: range===x-1 - range(z); // $ range===350 range=<=y+2 MISSING: range===x+1 range===y+2 + range(x); // $ range===349 range="==InitializeParameter: y+1" range="==InitializeParameter: z-1" + range(y); // $ range===348 range=">=InitializeParameter: x:Store: x-1" range="==InitializeParameter: z-2" MISSING: range===x-1 + range(z); // $ range===350 range="<=InitializeParameter: y+2" MISSING: range===x+1 range===y+2 return x + y + z; } } @@ -56,7 +56,7 @@ while (f3_get(n)) n+=2; for (int i = 0; i < n; i += 2) { - range(i); // $ range=>=0 SPURIOUS: range="<=call to f3_get-1" range="<=call to f3_get-2" + range(i); // $ range=>=0 SPURIOUS: range="<=Phi: call to f3_get-1" range="<=Phi: call to f3_get-2" } } From 74a585222cb287157232a743bcd01f47f1933fe8 Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Thu, 25 May 2023 15:52:56 +0200 Subject: [PATCH 120/739] C#: Extract source files generated by source generators --- .../Semmle.Extraction.CSharp/Extractor/Extractor.cs | 11 ++++++++++- csharp/tools/tracing-config.lua | 9 +++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs index ec4f44c21c7..79855875d02 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs @@ -381,8 +381,17 @@ namespace Semmle.Extraction.CSharp references => ResolveReferences(compilerArguments, analyser, canonicalPathCache, references), (analyser, syntaxTrees) => { + var paths = compilerArguments.SourceFiles + .Select(src => src.Path) + .ToList(); + + if (compilerArguments.GeneratedFilesOutputDirectory is not null) + { + paths.AddRange(Directory.GetFiles(compilerArguments.GeneratedFilesOutputDirectory, "*.cs", SearchOption.AllDirectories)); + } + return ReadSyntaxTrees( - compilerArguments.SourceFiles.Select(src => canonicalPathCache.GetCanonicalPath(src.Path)), + paths.Select(canonicalPathCache.GetCanonicalPath), analyser, compilerArguments.ParseOptions, compilerArguments.Encoding, diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index 2db04d83524..79b2ea2ca1c 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -63,7 +63,7 @@ function RegisterExtractorPack(id) end end if match then - local injections = { '-p:UseSharedCompilation=false' } + local injections = { '-p:UseSharedCompilation=false', '-p:EmitCompilerGeneratedFiles=true' } if dotnetRunNeedsSeparator then table.insert(injections, '--') end @@ -118,7 +118,8 @@ function RegisterExtractorPack(id) compilerArguments, nil, { '/p:UseSharedCompilation=false', - '/p:MvcBuildViews=true' + '/p:MvcBuildViews=true', + '/p:EmitCompilerGeneratedFiles=true', }) } @@ -154,7 +155,7 @@ function RegisterExtractorPack(id) if seenCompilerCall then return { - order = ORDER_BEFORE, + order = ORDER_AFTER, invocation = { path = AbsolutifyExtractorPath(id, extractor), arguments = { @@ -194,7 +195,7 @@ function RegisterExtractorPack(id) if seenCompilerCall then return { - order = ORDER_BEFORE, + order = ORDER_AFTER, invocation = { path = AbsolutifyExtractorPath(id, extractor), arguments = { From 736f2871f9cc61c078e1839d12f255926861613e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 May 2023 22:02:32 +0100 Subject: [PATCH 121/739] Swift: Tweak private info regexps to restore 'account_no' results. --- .../ql/lib/codeql/swift/security/SensitiveExprs.qll | 2 +- .../Security/CWE-311/CleartextTransmission.expected | 4 ++++ .../Security/CWE-311/SensitiveExprs.expected | 1 + .../test/query-tests/Security/CWE-311/testURL.swift | 2 +- .../CWE-328/WeakSensitiveDataHashing.expected | 12 ++++++++++++ .../query-tests/Security/CWE-328/testCryptoKit.swift | 12 ++++++------ 6 files changed, 25 insertions(+), 8 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index b6f5c231823..71a250229e7 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -58,7 +58,7 @@ class SensitivePrivateInfo extends SensitiveDataType, TPrivateInfo { // Geographic location - where the user is (or was) "latitude|longitude|" + // Financial data - such as credit card numbers, salary, bank accounts, and debts - "credit.?card|debit.?card|salary|bank.?account|" + + "credit.?card|debit.?card|salary|bank.?account|acc(ou)?nt.?(no|num)|" + // Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc. "email|" + // Health - medical conditions, insurance status, prescription records diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected index 94272faf6d0..c832cf51a15 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -13,6 +13,7 @@ edges | testSend.swift:54:17:54:17 | password | testSend.swift:41:10:41:18 | data | | testSend.swift:54:17:54:17 | password | testSend.swift:54:13:54:25 | call to pad(_:) | | testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | +| testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | nodes | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | @@ -40,6 +41,8 @@ nodes | testSend.swift:66:27:66:30 | .mobileNumber | semmle.label | .mobileNumber | | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testURL.swift:13:54:13:54 | passwd | semmle.label | passwd | +| testURL.swift:15:22:15:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | +| testURL.swift:15:55:15:55 | account_no | semmle.label | account_no | | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no | semmle.label | credit_card_no | | testURL.swift:20:22:20:22 | passwd | semmle.label | passwd | @@ -58,5 +61,6 @@ subpaths | testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | testSend.swift:65:27:65:27 | license_key | This operation transmits 'license_key', which may contain unencrypted sensitive data from $@. | testSend.swift:65:27:65:27 | license_key | license_key | | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | testSend.swift:66:27:66:30 | .mobileNumber | This operation transmits '.mobileNumber', which may contain unencrypted sensitive data from $@. | testSend.swift:66:27:66:30 | .mobileNumber | .mobileNumber | | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | testURL.swift:13:54:13:54 | passwd | testURL.swift:13:22:13:54 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:13:54:13:54 | passwd | passwd | +| testURL.swift:15:22:15:55 | ... .+(_:_:) ... | testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:15:55:15:55 | account_no | account_no | | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testURL.swift:16:55:16:55 | credit_card_no | credit_card_no | | testURL.swift:20:22:20:22 | passwd | testURL.swift:20:22:20:22 | passwd | testURL.swift:20:22:20:22 | passwd | This operation transmits 'passwd', which may contain unencrypted sensitive data from $@. | testURL.swift:20:22:20:22 | passwd | passwd | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index 89b8d36ccdf..69de9137213 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -129,5 +129,6 @@ | testSend.swift:66:27:66:30 | .mobileNumber | label:mobileNumber, type:private information | | testSend.swift:69:27:69:30 | .passwordFeatureEnabled | label:passwordFeatureEnabled, type:credential | | testURL.swift:13:54:13:54 | passwd | label:passwd, type:credential | +| testURL.swift:15:55:15:55 | account_no | label:account_no, type:private information | | testURL.swift:16:55:16:55 | credit_card_no | label:credit_card_no, type:private information | | testURL.swift:20:22:20:22 | passwd | label:passwd, type:credential | diff --git a/swift/ql/test/query-tests/Security/CWE-311/testURL.swift b/swift/ql/test/query-tests/Security/CWE-311/testURL.swift index 48ae815232f..7f9b64ff4f6 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testURL.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testURL.swift @@ -12,7 +12,7 @@ struct URL func test1(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) { let a = URL(string: "http://example.com/login?p=" + passwd); // BAD let b = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive) - let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD [NOT DETECTED] + let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD let d = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD let base = URL(string: "http://example.com/"); // GOOD (not sensitive) diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected index b6c7161b853..a23916e1a5c 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -2,22 +2,28 @@ edges nodes | testCryptoKit.swift:56:47:56:47 | passwd | semmle.label | passwd | | testCryptoKit.swift:57:43:57:43 | cert | semmle.label | cert | +| testCryptoKit.swift:59:43:59:43 | account_no | semmle.label | account_no | | testCryptoKit.swift:60:43:60:43 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:61:43:61:43 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:63:44:63:44 | passwd | semmle.label | passwd | | testCryptoKit.swift:64:44:64:44 | cert | semmle.label | cert | +| testCryptoKit.swift:66:44:66:44 | account_no | semmle.label | account_no | | testCryptoKit.swift:67:44:67:44 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:90:23:90:23 | passwd | semmle.label | passwd | | testCryptoKit.swift:91:23:91:23 | cert | semmle.label | cert | +| testCryptoKit.swift:93:23:93:23 | account_no | semmle.label | account_no | | testCryptoKit.swift:94:23:94:23 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:99:23:99:23 | passwd | semmle.label | passwd | | testCryptoKit.swift:100:23:100:23 | cert | semmle.label | cert | +| testCryptoKit.swift:102:23:102:23 | account_no | semmle.label | account_no | | testCryptoKit.swift:103:23:103:23 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:132:32:132:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:133:32:133:32 | cert | semmle.label | cert | +| testCryptoKit.swift:135:32:135:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:136:32:136:32 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:141:32:141:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:142:32:142:32 | cert | semmle.label | cert | +| testCryptoKit.swift:144:32:144:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:145:32:145:32 | credit_card_no | semmle.label | credit_card_no | | testCryptoSwift.swift:113:30:113:30 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:115:31:115:31 | passwdArray | semmle.label | passwdArray | @@ -33,22 +39,28 @@ subpaths #select | testCryptoKit.swift:56:47:56:47 | passwd | testCryptoKit.swift:56:47:56:47 | passwd | testCryptoKit.swift:56:47:56:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:56:47:56:47 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:57:43:57:43 | cert | testCryptoKit.swift:57:43:57:43 | cert | testCryptoKit.swift:57:43:57:43 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:57:43:57:43 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:59:43:59:43 | account_no | testCryptoKit.swift:59:43:59:43 | account_no | testCryptoKit.swift:59:43:59:43 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:59:43:59:43 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:60:43:60:43 | credit_card_no | testCryptoKit.swift:60:43:60:43 | credit_card_no | testCryptoKit.swift:60:43:60:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:60:43:60:43 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:61:43:61:43 | credit_card_no | testCryptoKit.swift:61:43:61:43 | credit_card_no | testCryptoKit.swift:61:43:61:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:61:43:61:43 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:63:44:63:44 | passwd | testCryptoKit.swift:63:44:63:44 | passwd | testCryptoKit.swift:63:44:63:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:63:44:63:44 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:64:44:64:44 | cert | testCryptoKit.swift:64:44:64:44 | cert | testCryptoKit.swift:64:44:64:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:64:44:64:44 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:66:44:66:44 | account_no | testCryptoKit.swift:66:44:66:44 | account_no | testCryptoKit.swift:66:44:66:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:66:44:66:44 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:67:44:67:44 | credit_card_no | testCryptoKit.swift:67:44:67:44 | credit_card_no | testCryptoKit.swift:67:44:67:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:67:44:67:44 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:90:23:90:23 | passwd | testCryptoKit.swift:90:23:90:23 | passwd | testCryptoKit.swift:90:23:90:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:90:23:90:23 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:91:23:91:23 | cert | testCryptoKit.swift:91:23:91:23 | cert | testCryptoKit.swift:91:23:91:23 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:91:23:91:23 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:93:23:93:23 | account_no | testCryptoKit.swift:93:23:93:23 | account_no | testCryptoKit.swift:93:23:93:23 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:93:23:93:23 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:94:23:94:23 | credit_card_no | testCryptoKit.swift:94:23:94:23 | credit_card_no | testCryptoKit.swift:94:23:94:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:94:23:94:23 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:99:23:99:23 | passwd | testCryptoKit.swift:99:23:99:23 | passwd | testCryptoKit.swift:99:23:99:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:99:23:99:23 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:100:23:100:23 | cert | testCryptoKit.swift:100:23:100:23 | cert | testCryptoKit.swift:100:23:100:23 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:100:23:100:23 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:102:23:102:23 | account_no | testCryptoKit.swift:102:23:102:23 | account_no | testCryptoKit.swift:102:23:102:23 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:102:23:102:23 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:103:23:103:23 | credit_card_no | testCryptoKit.swift:103:23:103:23 | credit_card_no | testCryptoKit.swift:103:23:103:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:103:23:103:23 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:132:32:132:32 | passwd | testCryptoKit.swift:132:32:132:32 | passwd | testCryptoKit.swift:132:32:132:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:132:32:132:32 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:133:32:133:32 | cert | testCryptoKit.swift:133:32:133:32 | cert | testCryptoKit.swift:133:32:133:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:133:32:133:32 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:135:32:135:32 | account_no | testCryptoKit.swift:135:32:135:32 | account_no | testCryptoKit.swift:135:32:135:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:135:32:135:32 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:136:32:136:32 | credit_card_no | testCryptoKit.swift:136:32:136:32 | credit_card_no | testCryptoKit.swift:136:32:136:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:136:32:136:32 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:141:32:141:32 | passwd | testCryptoKit.swift:141:32:141:32 | passwd | testCryptoKit.swift:141:32:141:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:141:32:141:32 | passwd | sensitive data (credential passwd) | | testCryptoKit.swift:142:32:142:32 | cert | testCryptoKit.swift:142:32:142:32 | cert | testCryptoKit.swift:142:32:142:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:142:32:142:32 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:144:32:144:32 | account_no | testCryptoKit.swift:144:32:144:32 | account_no | testCryptoKit.swift:144:32:144:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:144:32:144:32 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:145:32:145:32 | credit_card_no | testCryptoKit.swift:145:32:145:32 | credit_card_no | testCryptoKit.swift:145:32:145:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:145:32:145:32 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoSwift.swift:113:30:113:30 | passwdArray | testCryptoSwift.swift:113:30:113:30 | passwdArray | testCryptoSwift.swift:113:30:113:30 | passwdArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:113:30:113:30 | passwdArray | sensitive data (credential passwdArray) | | testCryptoSwift.swift:115:31:115:31 | passwdArray | testCryptoSwift.swift:115:31:115:31 | passwdArray | testCryptoSwift.swift:115:31:115:31 | passwdArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:115:31:115:31 | passwdArray | sensitive data (credential passwdArray) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index 4e6f301c84b..55fb9284fa6 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -56,14 +56,14 @@ func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_pa var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD hash = Crypto.Insecure.MD5.hash(data: cert) // BAD hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD hash = Crypto.SHA256.hash(data: passwd) // BAD [NOT DETECTED] not a computationally expensive hash @@ -90,7 +90,7 @@ func testMD5UpdateWithData(passwd : String, cert: String, encrypted_passwd : Str hash.update(data: passwd) // BAD hash.update(data: cert) // BAD hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD [NOT DETECTED] + hash.update(data: account_no) // BAD hash.update(data: credit_card_no) // BAD } @@ -99,7 +99,7 @@ func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : St hash.update(data: passwd) // BAD hash.update(data: cert) // BAD hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD [NOT DETECTED] + hash.update(data: account_no) // BAD hash.update(data: credit_card_no) // BAD } @@ -132,7 +132,7 @@ func testMD5UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, ce hash.update(bufferPointer: passwd) // BAD hash.update(bufferPointer: cert) // BAD hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive) - hash.update(bufferPointer: account_no) // BAD [NOT DETECTED] + hash.update(bufferPointer: account_no) // BAD hash.update(bufferPointer: credit_card_no) // BAD } @@ -141,7 +141,7 @@ func testSHA1UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, c hash.update(bufferPointer: passwd) // BAD hash.update(bufferPointer: cert) // BAD hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive) - hash.update(bufferPointer: account_no) // BAD [NOT DETECTED] + hash.update(bufferPointer: account_no) // BAD hash.update(bufferPointer: credit_card_no) // BAD } From 918cfd6f44ca7f2b7931fbf6e6ebaff2096c41ab Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Fri, 26 May 2023 09:50:06 +0200 Subject: [PATCH 122/739] Add integration test --- .../all-platforms/cshtml/Files.expected | 6 ++++++ .../all-platforms/cshtml/Files.ql | 5 +++++ .../all-platforms/cshtml/Program.cs | 1 + .../all-platforms/cshtml/Views/Home/Index.cshtml | 8 ++++++++ .../all-platforms/cshtml/cshtml.csproj | 14 ++++++++++++++ .../integration-tests/all-platforms/cshtml/test.py | 3 +++ 6 files changed, 37 insertions(+) create mode 100644 csharp/ql/integration-tests/all-platforms/cshtml/Files.expected create mode 100644 csharp/ql/integration-tests/all-platforms/cshtml/Files.ql create mode 100644 csharp/ql/integration-tests/all-platforms/cshtml/Program.cs create mode 100644 csharp/ql/integration-tests/all-platforms/cshtml/Views/Home/Index.cshtml create mode 100644 csharp/ql/integration-tests/all-platforms/cshtml/cshtml.csproj create mode 100644 csharp/ql/integration-tests/all-platforms/cshtml/test.py diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/Files.expected b/csharp/ql/integration-tests/all-platforms/cshtml/Files.expected new file mode 100644 index 00000000000..86a8cd34b88 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/Files.expected @@ -0,0 +1,6 @@ +| Program.cs:0:0:0:0 | Program.cs | +| obj/Debug/net7.0/.NETCoreApp,Version=v7.0.AssemblyAttributes.cs:0:0:0:0 | obj/Debug/net7.0/.NETCoreApp,Version=v7.0.AssemblyAttributes.cs | +| obj/Debug/net7.0/cshtml.AssemblyInfo.cs:0:0:0:0 | obj/Debug/net7.0/cshtml.AssemblyInfo.cs | +| obj/Debug/net7.0/cshtml.GlobalUsings.g.cs:0:0:0:0 | obj/Debug/net7.0/cshtml.GlobalUsings.g.cs | +| obj/Debug/net7.0/cshtml.RazorAssemblyInfo.cs:0:0:0:0 | obj/Debug/net7.0/cshtml.RazorAssemblyInfo.cs | +| obj/Debug/net7.0/generated/Microsoft.NET.Sdk.Razor.SourceGenerators/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Views_Home_Index_cshtml.g.cs:0:0:0:0 | obj/Debug/net7.0/generated/Microsoft.NET.Sdk.Razor.SourceGenerators/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Views_Home_Index_cshtml.g.cs | diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/Files.ql b/csharp/ql/integration-tests/all-platforms/cshtml/Files.ql new file mode 100644 index 00000000000..bea5557a25f --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/Files.ql @@ -0,0 +1,5 @@ +import csharp + +from File f +where f.fromSource() +select f diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/Program.cs b/csharp/ql/integration-tests/all-platforms/cshtml/Program.cs new file mode 100644 index 00000000000..47eee48cc79 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/Program.cs @@ -0,0 +1 @@ +var dummy = "dummy"; \ No newline at end of file diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/Views/Home/Index.cshtml b/csharp/ql/integration-tests/all-platforms/cshtml/Views/Home/Index.cshtml new file mode 100644 index 00000000000..52ffe012e42 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/Views/Home/Index.cshtml @@ -0,0 +1,8 @@ +@{ + ViewData["Title"] = "Home Page"; +} + +<div class="text-center"> + <h1 class="display-4">Welcome</h1> + <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p> +</div> diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/cshtml.csproj b/csharp/ql/integration-tests/all-platforms/cshtml/cshtml.csproj new file mode 100644 index 00000000000..01d15e87dc4 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/cshtml.csproj @@ -0,0 +1,14 @@ +<Project Sdk="Microsoft.NET.Sdk.Web"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net7.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + </PropertyGroup> + + <Target Name="DeleteBinObjFolders" BeforeTargets="Clean"> + <RemoveDir Directories=".\bin" /> + <RemoveDir Directories=".\obj" /> + </Target> +</Project> diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/test.py b/csharp/ql/integration-tests/all-platforms/cshtml/test.py new file mode 100644 index 00000000000..24cc83b4f2d --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create(['dotnet build'], lang="csharp", extra_args=["--extractor-option=cil=false"]) From 903fdb0cb80ea99c455cb55a4d13f49efeeb5362 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Fri, 26 May 2023 10:23:43 +0200 Subject: [PATCH 123/739] Java: Add models for the Play Framework --- .../2023-05-26-play-framework-models.md | 4 ++ java/ql/lib/ext/play.libs.ws.model.yml | 7 +++ java/ql/lib/ext/play.mvc.model.yml | 45 +++++++++++++++++-- .../dataflow/taintsources/PlayMvc.java | 25 +++++++++++ .../security/CWE-918/mad/Test.java | 12 +++++ .../test/query-tests/security/CWE-918/options | 2 +- .../play/libs/ws/StandaloneWSClient.java | 9 ++++ .../play/libs/ws/StandaloneWSRequest.java | 5 +++ .../play/libs/ws/WSClient.java | 9 ++++ .../play/libs/ws/WSRequest.java | 5 +++ 10 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 java/ql/lib/change-notes/2023-05-26-play-framework-models.md create mode 100644 java/ql/lib/ext/play.libs.ws.model.yml create mode 100644 java/ql/test/library-tests/dataflow/taintsources/PlayMvc.java create mode 100644 java/ql/test/stubs/playframework-2.6.x/play/libs/ws/StandaloneWSClient.java create mode 100644 java/ql/test/stubs/playframework-2.6.x/play/libs/ws/StandaloneWSRequest.java create mode 100644 java/ql/test/stubs/playframework-2.6.x/play/libs/ws/WSClient.java create mode 100644 java/ql/test/stubs/playframework-2.6.x/play/libs/ws/WSRequest.java diff --git a/java/ql/lib/change-notes/2023-05-26-play-framework-models.md b/java/ql/lib/change-notes/2023-05-26-play-framework-models.md new file mode 100644 index 00000000000..69db10413eb --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-26-play-framework-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added more dataflow models for the Play Framework. diff --git a/java/ql/lib/ext/play.libs.ws.model.yml b/java/ql/lib/ext/play.libs.ws.model.yml new file mode 100644 index 00000000000..ab905bc463a --- /dev/null +++ b/java/ql/lib/ext/play.libs.ws.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["play.libs.ws", "WSClient", True, "url", "", "", "Argument[0]", "open-url", "manual"] + - ["play.libs.ws", "StandaloneWSClient", True, "url", "", "", "Argument[0]", "open-url", "manual"] diff --git a/java/ql/lib/ext/play.mvc.model.yml b/java/ql/lib/ext/play.mvc.model.yml index a1f8dc60fe0..ba9a11c3f78 100644 --- a/java/ql/lib/ext/play.mvc.model.yml +++ b/java/ql/lib/ext/play.mvc.model.yml @@ -3,7 +3,44 @@ extensions: pack: codeql/java-all extensible: sourceModel data: - - ["play.mvc", "Http$RequestHeader", False, "getHeader", "", "", "ReturnValue", "remote", "manual"] - - ["play.mvc", "Http$RequestHeader", False, "getQueryString", "", "", "ReturnValue", "remote", "manual"] - - ["play.mvc", "Http$RequestHeader", False, "header", "", "", "ReturnValue", "remote", "manual"] - - ["play.mvc", "Http$RequestHeader", False, "queryString", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$Request", True, "body", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", True, "cookie", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", True, "cookies", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", True, "getHeader", "", "", "ReturnValue", "remote", "manual"] # v2.4.x + - ["play.mvc", "Http$RequestHeader", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] # v2.7.x + - ["play.mvc", "Http$RequestHeader", True, "getQueryString", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", True, "header", "", "", "ReturnValue", "remote", "manual"] # v2.7.x + - ["play.mvc", "Http$RequestHeader", True, "headers", "", "", "ReturnValue", "remote", "manual"] # v2.4.x + - ["play.mvc", "Http$RequestHeader", True, "host", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", True, "path", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", True, "queryString", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", True, "remoteAddress", "", "", "ReturnValue", "remote", "manual"] + - ["play.mvc", "Http$RequestHeader", True, "uri", "", "", "ReturnValue", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["play.mvc", "Http$RequestBody", True, "as", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$RequestBody", True, "asBytes", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x + - ["play.mvc", "Http$RequestBody", True, "asFormUrlEncoded", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$RequestBody", True, "asJson", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$RequestBody", True, "asMultipartFormData", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$RequestBody", True, "asRaw", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$RequestBody", True, "asText", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$RequestBody", True, "asXml", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$RequestBody", True, "parseJson", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x + - ["play.mvc", "Http$MultipartFormData", True, "asFormUrlEncoded", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$MultipartFormData", True, "getFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$MultipartFormData", True, "getFiles", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$MultipartFormData$FilePart", True, "getContentType", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$MultipartFormData$FilePart", True, "getDispositionType", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x + - ["play.mvc", "Http$MultipartFormData$FilePart", True, "getFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.4.x + - ["play.mvc", "Http$MultipartFormData$FilePart", True, "getFilename", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$MultipartFormData$FilePart", True, "getKey", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$MultipartFormData$FilePart", True, "getRef", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x + - ["play.mvc", "Http$RawBuffer", True, "asBytes", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$RawBuffer", True, "asFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$Cookie", True, "name", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$Cookie", True, "value", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$Cookies", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["play.mvc", "Http$Cookies", True, "getCookie", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x diff --git a/java/ql/test/library-tests/dataflow/taintsources/PlayMvc.java b/java/ql/test/library-tests/dataflow/taintsources/PlayMvc.java new file mode 100644 index 00000000000..55087a6596b --- /dev/null +++ b/java/ql/test/library-tests/dataflow/taintsources/PlayMvc.java @@ -0,0 +1,25 @@ +import play.mvc.Http; + +public class PlayMvc { + + private Http.Request request; + private Http.RequestHeader header; + + private static void sink(Object o) {} + + public void test() throws Exception { + sink(request.body()); // $ hasRemoteValueFlow + sink(header.cookie(null)); // $ hasRemoteValueFlow + sink(header.cookies()); // $ hasRemoteValueFlow + sink(header.getHeader(null)); // $ hasRemoteValueFlow + sink(header.getHeaders()); // $ hasRemoteValueFlow + sink(header.getQueryString(null)); // $ hasRemoteValueFlow + sink(header.header(null)); // $ hasRemoteValueFlow + sink(header.headers()); // $ hasRemoteValueFlow + sink(header.host()); // $ hasRemoteValueFlow + sink(header.path()); // $ hasRemoteValueFlow + sink(header.queryString()); // $ hasRemoteValueFlow + sink(header.remoteAddress()); // $ hasRemoteValueFlow + sink(header.uri()); // $ hasRemoteValueFlow + } +} diff --git a/java/ql/test/query-tests/security/CWE-918/mad/Test.java b/java/ql/test/query-tests/security/CWE-918/mad/Test.java index 8666e821fd0..6c224b65d31 100644 --- a/java/ql/test/query-tests/security/CWE-918/mad/Test.java +++ b/java/ql/test/query-tests/security/CWE-918/mad/Test.java @@ -9,6 +9,8 @@ import javafx.scene.web.WebEngine; import org.apache.commons.jelly.JellyContext; import org.codehaus.cargo.container.installer.ZipURLInstaller; import org.kohsuke.stapler.HttpResponses; +import play.libs.ws.WSClient; +import play.libs.ws.StandaloneWSClient; public class Test { @@ -74,4 +76,14 @@ public class Test { r.staticResource((URL) source()); // $ SSRF } + public void test(WSClient c) { + // "play.libs.ws;WSClient;true;url;;;Argument[0];open-url;manual" + c.url((String) source()); // $ SSRF + } + + public void test(StandaloneWSClient c) { + // "play.libs.ws;StandaloneWSClient;true;url;;;Argument[0];open-url;manual" + c.url((String) source()); // $ SSRF + } + } diff --git a/java/ql/test/query-tests/security/CWE-918/options b/java/ql/test/query-tests/security/CWE-918/options index c8147ece2a9..82a3894bc18 100644 --- a/java/ql/test/query-tests/security/CWE-918/options +++ b/java/ql/test/query-tests/security/CWE-918/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5 +//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5:${testdir}/../../../stubs/playframework-2.6.x diff --git a/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/StandaloneWSClient.java b/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/StandaloneWSClient.java new file mode 100644 index 00000000000..5a75fc16132 --- /dev/null +++ b/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/StandaloneWSClient.java @@ -0,0 +1,9 @@ +package play.libs.ws; + +public class StandaloneWSClient { + + public StandaloneWSRequest url(String url) { + return null; + } + +} diff --git a/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/StandaloneWSRequest.java b/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/StandaloneWSRequest.java new file mode 100644 index 00000000000..2266d2cc24a --- /dev/null +++ b/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/StandaloneWSRequest.java @@ -0,0 +1,5 @@ +package play.libs.ws; + +public class StandaloneWSRequest { + +} diff --git a/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/WSClient.java b/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/WSClient.java new file mode 100644 index 00000000000..22b3546dddf --- /dev/null +++ b/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/WSClient.java @@ -0,0 +1,9 @@ +package play.libs.ws; + +public class WSClient { + + public WSRequest url(String url) { + return null; + } + +} diff --git a/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/WSRequest.java b/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/WSRequest.java new file mode 100644 index 00000000000..8dbd4521b06 --- /dev/null +++ b/java/ql/test/stubs/playframework-2.6.x/play/libs/ws/WSRequest.java @@ -0,0 +1,5 @@ +package play.libs.ws; + +public class WSRequest { + +} From e48fc667823f3b92cb7fb171267178c5a0770312 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" <mbg@github.com> Date: Wed, 17 May 2023 16:44:55 +0100 Subject: [PATCH 124/739] Swift: Add `identify-environment` script --- swift/tools/BUILD.bazel | 6 ++++++ swift/tools/identify-environment.cmd | 6 ++++++ swift/tools/identify-environment.sh | 5 +++++ 3 files changed, 17 insertions(+) create mode 100644 swift/tools/identify-environment.cmd create mode 100755 swift/tools/identify-environment.sh diff --git a/swift/tools/BUILD.bazel b/swift/tools/BUILD.bazel index e7cff7bd024..8a3496a2700 100644 --- a/swift/tools/BUILD.bazel +++ b/swift/tools/BUILD.bazel @@ -11,9 +11,15 @@ sh_binary( srcs = ["autobuild.sh"], ) +sh_binary( + name = "identify-environment", + srcs = ["identify-environment.sh"], +) + pkg_files( name = "scripts", srcs = [ + ":identify-environment", ":autobuild", ":qltest", ], diff --git a/swift/tools/identify-environment.cmd b/swift/tools/identify-environment.cmd new file mode 100644 index 00000000000..7fd1786f31f --- /dev/null +++ b/swift/tools/identify-environment.cmd @@ -0,0 +1,6 @@ +@echo off +SETLOCAL EnableDelayedExpansion + +echo { "swift": { "os": { "name": "macOS" } } } + +ENDLOCAL diff --git a/swift/tools/identify-environment.sh b/swift/tools/identify-environment.sh new file mode 100755 index 00000000000..d686315c527 --- /dev/null +++ b/swift/tools/identify-environment.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +set -eu + +echo '{ "swift": { "os": { "name": "macOS" } } }' From af803c88867c7629470bfc0162bf9a0962023f06 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" <mbg@github.com> Date: Wed, 17 May 2023 17:58:09 +0100 Subject: [PATCH 125/739] Go: include new scripts in Makefile --- go/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/Makefile b/go/Makefile index 7e119b36f03..8f28079f008 100644 --- a/go/Makefile +++ b/go/Makefile @@ -14,7 +14,7 @@ CODEQL_PLATFORM = osx64 endif endif -CODEQL_TOOLS = $(addprefix codeql-tools/,autobuild.cmd autobuild.sh pre-finalize.cmd pre-finalize.sh index.cmd index.sh tracing-config.lua) +CODEQL_TOOLS = $(addprefix codeql-tools/,autobuild.cmd autobuild.sh pre-finalize.cmd pre-finalize.sh index.cmd index.sh identify-environment.cmd identify-environment.sh tracing-config.lua) EXTRACTOR_PACK_OUT = build/codeql-extractor-go From 631ba6584d810c4fe59baf25e086fdca033a3d43 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" <mbg@github.com> Date: Thu, 18 May 2023 20:21:12 +0100 Subject: [PATCH 126/739] Go: Update `identify-environment` JSON format The spec changed after this was implemented and merged --- go/extractor/cli/go-autobuilder/go-autobuilder.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/extractor/cli/go-autobuilder/go-autobuilder.go b/go/extractor/cli/go-autobuilder/go-autobuilder.go index 9fcad68d42a..ed4a238743b 100644 --- a/go/extractor/cli/go-autobuilder/go-autobuilder.go +++ b/go/extractor/cli/go-autobuilder/go-autobuilder.go @@ -44,7 +44,7 @@ Build behavior: to 'false' disables the GOPATH set-up, CODEQL_EXTRACTOR_GO_BUILD_COMMAND (or alternatively LGTM_INDEX_BUILD_COMMAND), can be set to a newline-separated list of commands to run in order to install dependencies, and LGTM_INDEX_IMPORT_PATH can be used to override the package import path, - which is otherwise inferred from the SEMMLE_REPO_URL or GITHUB_REPOSITORY environment variables. + which is otherwise inferred from the SEMMLE_REPO_URL or GITHUB_REPOSITORY environment variables. In resource-constrained environments, the environment variable CODEQL_EXTRACTOR_GO_MAX_GOROUTINES (or its legacy alias SEMMLE_MAX_GOROUTINES) can be used to limit the number of parallel goroutines @@ -931,9 +931,9 @@ func getVersionToInstall(v versionInfo) (msg, version string) { func outputEnvironmentJson(version string) { var content string if version == "" { - content = `{ "include": [] }` + content = `{ "go": {} }` } else { - content = `{ "include": [ { "go": { "version": "` + version + `" } } ] }` + content = `{ "go": { "version": "` + version + `" } }` } _, err := fmt.Fprint(os.Stdout, content) From 2629ec1b1d0d0605862367409b649118e36f5441 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Thu, 25 May 2023 10:57:34 +0200 Subject: [PATCH 127/739] JS: Be more conservative about flagging "search" call arguments as regex --- .../ql/lib/semmle/javascript/Regexp.qll | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Regexp.qll b/javascript/ql/lib/semmle/javascript/Regexp.qll index 9cef1455746..a20f5343428 100644 --- a/javascript/ql/lib/semmle/javascript/Regexp.qll +++ b/javascript/ql/lib/semmle/javascript/Regexp.qll @@ -958,6 +958,27 @@ private predicate isUsedAsNonMatchObject(DataFlow::MethodCallNode call) { ) } +/** + * Holds if `call` is a call to `search` whose result is used in a way that suggests it returns a number. + */ +pragma[inline] +private predicate isUsedAsNumber(DataFlow::LocalSourceNode value) { + any(Comparison compare) + .hasOperands(value.getALocalUse().asExpr(), any(Expr e | e.analyze().getAType() = TTNumber())) + or + value.flowsToExpr(any(ArithmeticExpr e).getAnOperand()) + or + value.flowsToExpr(any(UnaryExpr e | e.getOperator() = "-").getOperand()) + or + value.flowsToExpr(any(IndexExpr expr).getPropertyNameExpr()) + or + exists(DataFlow::CallNode call | + call.getCalleeName() = + ["substring", "substr", "slice", "splice", "charAt", "charCodeAt", "codePointAt"] and + value.flowsTo(call.getAnArgument()) + ) +} + /** * Holds if `source` may be interpreted as a regular expression. */ @@ -985,9 +1006,9 @@ predicate isInterpretedAsRegExp(DataFlow::Node source) { methodName = "search" and source = mce.getArgument(0) and mce.getNumArgument() = 1 and - // "search" is a common method name, and so we exclude chained accesses - // because `String.prototype.search` returns a number - not exists(PropAccess p | p.getBase() = mce.getEnclosingExpr()) + // "search" is a common method name, and the built-in "search" method is rarely used, + // so to reduce FPs we also require that the return value appears to be used as a number. + isUsedAsNumber(mce) ) or exists(DataFlow::SourceNode schema | schema = JsonSchema::getAPartOfJsonSchema() | From 066554cee6e0a7437a5cc9701a5c23a89635af54 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 23 May 2023 16:22:57 +0200 Subject: [PATCH 128/739] C#: Re-factor getComponent. --- .../code/csharp/dataflow/internal/FlowSummaryImpl.qll | 9 ++------- .../csharp/dataflow/internal/FlowSummaryImplSpecific.qll | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index 034c6101de3..ce63ac5ef90 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -166,15 +166,10 @@ module Public { SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } } - private predicate noComponentSpecific(SummaryComponent sc) { - not exists(getComponentSpecific(sc)) - } - /** Gets a textual representation of this component used for flow summaries. */ private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - noComponentSpecific(sc) and ( exists(ArgumentPosition pos | sc = TParameterSummaryComponent(pos) and @@ -185,9 +180,9 @@ module Public { sc = TArgumentSummaryComponent(pos) and result = "Argument[" + getParameterPosition(pos) + "]" ) - or - sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" ) + or + sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } /** Gets a textual representation of this stack used for flow summaries. */ diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index b86601e6b54..97a27c65ef0 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -198,8 +198,8 @@ string getComponentSpecific(SummaryComponent sc) { or exists(ReturnKind rk | sc = TReturnSummaryComponent(rk) and - result = "ReturnValue[" + rk + "]" and - not rk instanceof NormalReturnKind + not rk = getReturnValueKind() and + result = "ReturnValue[" + rk + "]" ) } From b7a8660375ccb246d9de751b9878ecf02fdd1de7 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 23 May 2023 16:26:43 +0200 Subject: [PATCH 129/739] Java: Re-factor getComponent. --- .../code/java/dataflow/internal/FlowSummaryImpl.qll | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index 034c6101de3..ce63ac5ef90 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -166,15 +166,10 @@ module Public { SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } } - private predicate noComponentSpecific(SummaryComponent sc) { - not exists(getComponentSpecific(sc)) - } - /** Gets a textual representation of this component used for flow summaries. */ private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - noComponentSpecific(sc) and ( exists(ArgumentPosition pos | sc = TParameterSummaryComponent(pos) and @@ -185,9 +180,9 @@ module Public { sc = TArgumentSummaryComponent(pos) and result = "Argument[" + getParameterPosition(pos) + "]" ) - or - sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" ) + or + sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } /** Gets a textual representation of this stack used for flow summaries. */ From b79462733580dbf96c3501e867a19133d9fd900b Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 23 May 2023 16:32:56 +0200 Subject: [PATCH 130/739] Go: Re-factor getComponent. --- .../lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll | 9 ++------- .../go/dataflow/internal/FlowSummaryImplSpecific.qll | 6 +++--- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 034c6101de3..ce63ac5ef90 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -166,15 +166,10 @@ module Public { SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } } - private predicate noComponentSpecific(SummaryComponent sc) { - not exists(getComponentSpecific(sc)) - } - /** Gets a textual representation of this component used for flow summaries. */ private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - noComponentSpecific(sc) and ( exists(ArgumentPosition pos | sc = TParameterSummaryComponent(pos) and @@ -185,9 +180,9 @@ module Public { sc = TArgumentSummaryComponent(pos) and result = "Argument[" + getParameterPosition(pos) + "]" ) - or - sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" ) + or + sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } /** Gets a textual representation of this stack used for flow summaries. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index acaa34f943e..7afdb314929 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -111,10 +111,10 @@ private string getContentSpecific(Content c) { string getComponentSpecific(SummaryComponent sc) { exists(Content c | sc = TContentSummaryComponent(c) and result = getContentSpecific(c)) or - exists(ReturnKind rk, int n | n = rk.getIndex() | + exists(ReturnKind rk | sc = TReturnSummaryComponent(rk) and - result = "ReturnValue[" + n + "]" and - n != 0 + not rk = getReturnValueKind() and + result = "ReturnValue[" + rk.getIndex() + "]" ) } From 811eee1f0d01ce91bec166e9f19fe02449e4a9ae Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 23 May 2023 16:35:46 +0200 Subject: [PATCH 131/739] Python: Re-factor getComponent. --- .../python/dataflow/new/internal/FlowSummaryImpl.qll | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index 034c6101de3..ce63ac5ef90 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -166,15 +166,10 @@ module Public { SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } } - private predicate noComponentSpecific(SummaryComponent sc) { - not exists(getComponentSpecific(sc)) - } - /** Gets a textual representation of this component used for flow summaries. */ private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - noComponentSpecific(sc) and ( exists(ArgumentPosition pos | sc = TParameterSummaryComponent(pos) and @@ -185,9 +180,9 @@ module Public { sc = TArgumentSummaryComponent(pos) and result = "Argument[" + getParameterPosition(pos) + "]" ) - or - sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" ) + or + sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } /** Gets a textual representation of this stack used for flow summaries. */ From 58fcbc136cca0f5bf6fcf55fec86ea0460e6540e Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 23 May 2023 16:40:18 +0200 Subject: [PATCH 132/739] Ruby: Re-factor getComponent. --- .../codeql/ruby/dataflow/internal/FlowSummaryImpl.qll | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index 034c6101de3..ce63ac5ef90 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -166,15 +166,10 @@ module Public { SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } } - private predicate noComponentSpecific(SummaryComponent sc) { - not exists(getComponentSpecific(sc)) - } - /** Gets a textual representation of this component used for flow summaries. */ private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - noComponentSpecific(sc) and ( exists(ArgumentPosition pos | sc = TParameterSummaryComponent(pos) and @@ -185,9 +180,9 @@ module Public { sc = TArgumentSummaryComponent(pos) and result = "Argument[" + getParameterPosition(pos) + "]" ) - or - sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" ) + or + sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } /** Gets a textual representation of this stack used for flow summaries. */ From 783d560e7dd3b76e54845608595b7e89a4dd1c32 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 23 May 2023 16:49:34 +0200 Subject: [PATCH 133/739] Swift: Re-factor getComponent. --- .../codeql/swift/dataflow/internal/FlowSummaryImpl.qll | 9 ++------- .../swift/dataflow/internal/FlowSummaryImplSpecific.qll | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index 034c6101de3..ce63ac5ef90 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -166,15 +166,10 @@ module Public { SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } } - private predicate noComponentSpecific(SummaryComponent sc) { - not exists(getComponentSpecific(sc)) - } - /** Gets a textual representation of this component used for flow summaries. */ private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - noComponentSpecific(sc) and ( exists(ArgumentPosition pos | sc = TParameterSummaryComponent(pos) and @@ -185,9 +180,9 @@ module Public { sc = TArgumentSummaryComponent(pos) and result = "Argument[" + getParameterPosition(pos) + "]" ) - or - sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" ) + or + sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } /** Gets a textual representation of this stack used for flow summaries. */ diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll index e13636a911e..d5306461784 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll @@ -117,8 +117,8 @@ string getComponentSpecific(SummaryComponent sc) { or exists(ReturnKind rk | sc = TReturnSummaryComponent(rk) and - result = "ReturnValue[" + rk + "]" and - not rk instanceof NormalReturnKind + not rk = getReturnValueKind() and + result = "ReturnValue" + "[" + rk + "]" ) } From 915042a8819fdf8b87d52655d02b611958ec964c Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 24 May 2023 11:23:42 +0200 Subject: [PATCH 134/739] Minor cleanup and sync files. --- .../dataflow/internal/FlowSummaryImpl.qll | 18 ++++++++---------- .../go/dataflow/internal/FlowSummaryImpl.qll | 18 ++++++++---------- .../java/dataflow/internal/FlowSummaryImpl.qll | 18 ++++++++---------- .../dataflow/new/internal/FlowSummaryImpl.qll | 18 ++++++++---------- .../ruby/dataflow/internal/FlowSummaryImpl.qll | 18 ++++++++---------- .../dataflow/internal/FlowSummaryImpl.qll | 18 ++++++++---------- 6 files changed, 48 insertions(+), 60 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index ce63ac5ef90..e6379f6a170 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -170,16 +170,14 @@ module Public { private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - ( - exists(ArgumentPosition pos | - sc = TParameterSummaryComponent(pos) and - result = "Parameter[" + getArgumentPosition(pos) + "]" - ) - or - exists(ParameterPosition pos | - sc = TArgumentSummaryComponent(pos) and - result = "Argument[" + getParameterPosition(pos) + "]" - ) + exists(ArgumentPosition pos | + sc = TParameterSummaryComponent(pos) and + result = "Parameter[" + getArgumentPosition(pos) + "]" + ) + or + exists(ParameterPosition pos | + sc = TArgumentSummaryComponent(pos) and + result = "Argument[" + getParameterPosition(pos) + "]" ) or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index ce63ac5ef90..e6379f6a170 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -170,16 +170,14 @@ module Public { private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - ( - exists(ArgumentPosition pos | - sc = TParameterSummaryComponent(pos) and - result = "Parameter[" + getArgumentPosition(pos) + "]" - ) - or - exists(ParameterPosition pos | - sc = TArgumentSummaryComponent(pos) and - result = "Argument[" + getParameterPosition(pos) + "]" - ) + exists(ArgumentPosition pos | + sc = TParameterSummaryComponent(pos) and + result = "Parameter[" + getArgumentPosition(pos) + "]" + ) + or + exists(ParameterPosition pos | + sc = TArgumentSummaryComponent(pos) and + result = "Argument[" + getParameterPosition(pos) + "]" ) or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index ce63ac5ef90..e6379f6a170 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -170,16 +170,14 @@ module Public { private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - ( - exists(ArgumentPosition pos | - sc = TParameterSummaryComponent(pos) and - result = "Parameter[" + getArgumentPosition(pos) + "]" - ) - or - exists(ParameterPosition pos | - sc = TArgumentSummaryComponent(pos) and - result = "Argument[" + getParameterPosition(pos) + "]" - ) + exists(ArgumentPosition pos | + sc = TParameterSummaryComponent(pos) and + result = "Parameter[" + getArgumentPosition(pos) + "]" + ) + or + exists(ParameterPosition pos | + sc = TArgumentSummaryComponent(pos) and + result = "Argument[" + getParameterPosition(pos) + "]" ) or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index ce63ac5ef90..e6379f6a170 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -170,16 +170,14 @@ module Public { private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - ( - exists(ArgumentPosition pos | - sc = TParameterSummaryComponent(pos) and - result = "Parameter[" + getArgumentPosition(pos) + "]" - ) - or - exists(ParameterPosition pos | - sc = TArgumentSummaryComponent(pos) and - result = "Argument[" + getParameterPosition(pos) + "]" - ) + exists(ArgumentPosition pos | + sc = TParameterSummaryComponent(pos) and + result = "Parameter[" + getArgumentPosition(pos) + "]" + ) + or + exists(ParameterPosition pos | + sc = TArgumentSummaryComponent(pos) and + result = "Argument[" + getParameterPosition(pos) + "]" ) or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index ce63ac5ef90..e6379f6a170 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -170,16 +170,14 @@ module Public { private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - ( - exists(ArgumentPosition pos | - sc = TParameterSummaryComponent(pos) and - result = "Parameter[" + getArgumentPosition(pos) + "]" - ) - or - exists(ParameterPosition pos | - sc = TArgumentSummaryComponent(pos) and - result = "Argument[" + getParameterPosition(pos) + "]" - ) + exists(ArgumentPosition pos | + sc = TParameterSummaryComponent(pos) and + result = "Parameter[" + getArgumentPosition(pos) + "]" + ) + or + exists(ParameterPosition pos | + sc = TArgumentSummaryComponent(pos) and + result = "Argument[" + getParameterPosition(pos) + "]" ) or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index ce63ac5ef90..e6379f6a170 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -170,16 +170,14 @@ module Public { private string getComponent(SummaryComponent sc) { result = getComponentSpecific(sc) or - ( - exists(ArgumentPosition pos | - sc = TParameterSummaryComponent(pos) and - result = "Parameter[" + getArgumentPosition(pos) + "]" - ) - or - exists(ParameterPosition pos | - sc = TArgumentSummaryComponent(pos) and - result = "Argument[" + getParameterPosition(pos) + "]" - ) + exists(ArgumentPosition pos | + sc = TParameterSummaryComponent(pos) and + result = "Parameter[" + getArgumentPosition(pos) + "]" + ) + or + exists(ParameterPosition pos | + sc = TArgumentSummaryComponent(pos) and + result = "Argument[" + getParameterPosition(pos) + "]" ) or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" From 8e16a0d144e6baca0876c1731a076bcd7a7ae52d Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Fri, 26 May 2023 12:43:58 +0200 Subject: [PATCH 135/739] Add tests and stubs for the summaries --- .../frameworks/play/mad/Test.java | 194 ++++++++++++++++++ .../frameworks/play/test.expected | 0 .../library-tests/frameworks/play/test.ql | 2 + .../play/api/mvc/Cookie.java | 131 ++++++++++++ .../playframework-2.6.x/play/mvc/Http.java | 86 ++++---- 5 files changed, 365 insertions(+), 48 deletions(-) create mode 100644 java/ql/test/library-tests/frameworks/play/mad/Test.java create mode 100644 java/ql/test/library-tests/frameworks/play/test.expected create mode 100644 java/ql/test/library-tests/frameworks/play/test.ql create mode 100644 java/ql/test/stubs/playframework-2.6.x/play/api/mvc/Cookie.java diff --git a/java/ql/test/library-tests/frameworks/play/mad/Test.java b/java/ql/test/library-tests/frameworks/play/mad/Test.java new file mode 100644 index 00000000000..cb7fb123a62 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/play/mad/Test.java @@ -0,0 +1,194 @@ +package generatedtest; + +import akka.util.ByteString; +import com.fasterxml.jackson.databind.JsonNode; +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.w3c.dom.Document; +import play.mvc.Http; + +// Test case generated by GenerateFlowTestCase.ql +public class Test { + + Object source() { + return null; + } + + void sink(Object o) {} + + public void test() throws Exception { + + { + // "play.mvc;Http$Cookie;true;name;;;Argument[this];ReturnValue;taint;manual" + String out = null; + Http.Cookie in = (Http.Cookie) source(); + out = in.name(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$Cookie;true;value;;;Argument[this];ReturnValue;taint;manual" + String out = null; + Http.Cookie in = (Http.Cookie) source(); + out = in.value(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$Cookies;true;get;;;Argument[this];ReturnValue;taint;manual" + Http.Cookie out = null; + Http.Cookies in = (Http.Cookies) source(); + out = in.get(null); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$Cookies;true;getCookie;;;Argument[this];ReturnValue;taint;manual" + Optional out = null; + Http.Cookies in = (Http.Cookies) source(); + out = in.getCookie(null); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$MultipartFormData$FilePart;true;getContentType;;;Argument[this];ReturnValue;taint;manual" + String out = null; + Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source(); + out = in.getContentType(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$MultipartFormData$FilePart;true;getDispositionType;;;Argument[this];ReturnValue;taint;manual" + String out = null; + Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source(); + out = in.getDispositionType(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$MultipartFormData$FilePart;true;getFilename;;;Argument[this];ReturnValue;taint;manual" + String out = null; + Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source(); + out = in.getFilename(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$MultipartFormData$FilePart;true;getKey;;;Argument[this];ReturnValue;taint;manual" + String out = null; + Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source(); + out = in.getKey(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$MultipartFormData$FilePart;true;getRef;;;Argument[this];ReturnValue;taint;manual" + Object out = null; + Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source(); + out = in.getRef(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$MultipartFormData;true;asFormUrlEncoded;;;Argument[this];ReturnValue;taint;manual" + Map out = null; + Http.MultipartFormData in = (Http.MultipartFormData) source(); + out = in.asFormUrlEncoded(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$MultipartFormData;true;getFile;;;Argument[this];ReturnValue;taint;manual" + Http.MultipartFormData.FilePart out = null; + Http.MultipartFormData in = (Http.MultipartFormData) source(); + out = in.getFile(null); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$MultipartFormData;true;getFiles;;;Argument[this];ReturnValue;taint;manual" + List out = null; + Http.MultipartFormData in = (Http.MultipartFormData) source(); + out = in.getFiles(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RawBuffer;true;asBytes;;;Argument[this];ReturnValue;taint;manual" + ByteString out = null; + Http.RawBuffer in = (Http.RawBuffer) source(); + out = in.asBytes(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RawBuffer;true;asBytes;;;Argument[this];ReturnValue;taint;manual" + ByteString out = null; + Http.RawBuffer in = (Http.RawBuffer) source(); + out = in.asBytes(0); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RawBuffer;true;asFile;;;Argument[this];ReturnValue;taint;manual" + File out = null; + Http.RawBuffer in = (Http.RawBuffer) source(); + out = in.asFile(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;as;;;Argument[this];ReturnValue;taint;manual" + Object out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.as(null); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;asBytes;;;Argument[this];ReturnValue;taint;manual" + ByteString out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.asBytes(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;asFormUrlEncoded;;;Argument[this];ReturnValue;taint;manual" + Map out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.asFormUrlEncoded(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;asJson;;;Argument[this];ReturnValue;taint;manual" + JsonNode out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.asJson(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;asMultipartFormData;;;Argument[this];ReturnValue;taint;manual" + Http.MultipartFormData out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.asMultipartFormData(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;asRaw;;;Argument[this];ReturnValue;taint;manual" + Http.RawBuffer out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.asRaw(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;asText;;;Argument[this];ReturnValue;taint;manual" + String out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.asText(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;asXml;;;Argument[this];ReturnValue;taint;manual" + Document out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.asXml(); + sink(out); // $ hasTaintFlow + } + { + // "play.mvc;Http$RequestBody;true;parseJson;;;Argument[this];ReturnValue;taint;manual" + Optional out = null; + Http.RequestBody in = (Http.RequestBody) source(); + out = in.parseJson(null); + sink(out); // $ hasTaintFlow + } + + } + +} diff --git a/java/ql/test/library-tests/frameworks/play/test.expected b/java/ql/test/library-tests/frameworks/play/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/frameworks/play/test.ql b/java/ql/test/library-tests/frameworks/play/test.ql new file mode 100644 index 00000000000..5d91e4e8e26 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/play/test.ql @@ -0,0 +1,2 @@ +import java +import TestUtilities.InlineFlowTest diff --git a/java/ql/test/stubs/playframework-2.6.x/play/api/mvc/Cookie.java b/java/ql/test/stubs/playframework-2.6.x/play/api/mvc/Cookie.java new file mode 100644 index 00000000000..1b8377af641 --- /dev/null +++ b/java/ql/test/stubs/playframework-2.6.x/play/api/mvc/Cookie.java @@ -0,0 +1,131 @@ +// Generated automatically from play.api.mvc.Cookie for testing purposes + +package play.api.mvc; + +import play.mvc.Http; + +public class Cookie { + protected Cookie() {} + + abstract static public class SameSite { + protected SameSite() {} + + public Http.Cookie.SameSite asJava() { + return null; + } + + public SameSite(String p0) {} + + public String value() { + return null; + } + + public boolean play$api$mvc$Cookie$SameSite$$matches(String p0) { + return false; + } + } + + public Http.Cookie asJava() { + return null; + } + + public Object productElement(int p0) { + return null; + } + + public String copy$default$1() { + return null; + } + + public String copy$default$2() { + return null; + } + + public String copy$default$4() { + return null; + } + + public String name() { + return null; + } + + public String path() { + return null; + } + + public String productPrefix() { + return null; + } + + public String toString() { + return null; + } + + public String value() { + return null; + } + + public boolean canEqual(Object p0) { + return false; + } + + public boolean copy$default$6() { + return false; + } + + public boolean copy$default$7() { + return false; + } + + public boolean equals(Object p0) { + return false; + } + + public boolean httpOnly() { + return false; + } + + public boolean secure() { + return false; + } + + public int hashCode() { + return 0; + } + + public int productArity() { + return 0; + } + + public static String $lessinit$greater$default$4() { + return null; + } + + public static String apply$default$4() { + return null; + } + + public static boolean $lessinit$greater$default$6() { + return false; + } + + public static boolean $lessinit$greater$default$7() { + return false; + } + + public static boolean apply$default$6() { + return false; + } + + public static boolean apply$default$7() { + return false; + } + + public static int DiscardedMaxAge() { + return 0; + } + + public static play.api.mvc.Cookie validatePrefix(play.api.mvc.Cookie p0) { + return null; + } +} diff --git a/java/ql/test/stubs/playframework-2.6.x/play/mvc/Http.java b/java/ql/test/stubs/playframework-2.6.x/play/mvc/Http.java index 99e22cb5987..b4668362e6c 100644 --- a/java/ql/test/stubs/playframework-2.6.x/play/mvc/Http.java +++ b/java/ql/test/stubs/playframework-2.6.x/play/mvc/Http.java @@ -1,5 +1,6 @@ package play.mvc; +import akka.util.ByteString; import com.fasterxml.jackson.databind.JsonNode; import java.io.File; import java.net.URI; @@ -32,24 +33,12 @@ public class Http { public Context(Request request, JavaContextComponents components) {} - public Context( - Long id, - play.api.mvc.RequestHeader header, - Request request, - Map<String, String> sessionData, - Map<String, String> flashData, - Map<String, Object> args, + public Context(Long id, play.api.mvc.RequestHeader header, Request request, + Map<String, String> sessionData, Map<String, String> flashData, Map<String, Object> args, JavaContextComponents components) {} - public Context( - Long id, - play.api.mvc.RequestHeader header, - Request request, - Response response, - Session session, - Flash flash, - Map<String, Object> args, - JavaContextComponents components) {} + public Context(Long id, play.api.mvc.RequestHeader header, Request request, Response response, + Session session, Flash flash, Map<String, Object> args, JavaContextComponents components) {} public Long id() { return 0L; @@ -328,8 +317,8 @@ public class Http { return null; } - public RequestBuilder bodyMultipart( - List<String> data, Files.TemporaryFileCreator temporaryFileCreator, String mat) { + public RequestBuilder bodyMultipart(List<String> data, + Files.TemporaryFileCreator temporaryFileCreator, String mat) { return null; } @@ -536,6 +525,10 @@ public class Http { public abstract static class RawBuffer { + public abstract ByteString asBytes(); + + public abstract ByteString asBytes(int maxLength); + public abstract Long size(); public abstract File asFile(); @@ -559,7 +552,8 @@ public class Http { } } - public interface Part<A> {} + public interface Part<A> { + } public static class FilePart<A> implements Part<A> { @@ -577,9 +571,17 @@ public class Http { return ""; } + public String getDispositionType() { + return ""; + } + public A getFile() { return null; } + + public A getRef() { + return null; + } } public static class DataPart { @@ -608,6 +610,10 @@ public class Http { public RequestBody(Object body) {} + public ByteString asBytes() { + return null; + } + public <A> MultipartFormData<A> asMultipartFormData() { return null; } @@ -640,6 +646,10 @@ public class Http { return null; } + public <A> Optional<A> parseJson(Class<A> clazz) { + return null; + } + public String toString() { return ""; } @@ -657,15 +667,8 @@ public class Http { public void setContentType(String contentType) {} @Deprecated - public void setCookie( - String name, - String value, - Integer maxAge, - String path, - String domain, - boolean secure, - boolean httpOnly, - SameSite sameSite) {} + public void setCookie(String name, String value, Integer maxAge, String path, String domain, + boolean secure, boolean httpOnly, SameSite sameSite) {} public void setCookie(Cookie cookie) {} @@ -734,25 +737,12 @@ public class Http { public static class Cookie { - public Cookie( - String name, - String value, - Integer maxAge, - String path, - String domain, - boolean secure, - boolean httpOnly, - SameSite sameSite) {} + public Cookie(String name, String value, Integer maxAge, String path, String domain, + boolean secure, boolean httpOnly, SameSite sameSite) {} @Deprecated - public Cookie( - String name, - String value, - Integer maxAge, - String path, - String domain, - boolean secure, - boolean httpOnly) {} + public Cookie(String name, String value, Integer maxAge, String path, String domain, + boolean secure, boolean httpOnly) {} public static CookieBuilder builder(String name, String value) { return null; @@ -791,9 +781,7 @@ public class Http { } public enum SameSite { - STRICT("Strict"), - LAX("Lax"), - NONE("None"); + STRICT("Strict"), LAX("Lax"), NONE("None"); SameSite(String value) {} @@ -856,6 +844,8 @@ public class Http { public interface Cookies extends Iterable<Cookie> { Cookie get(String name); + + Optional<Cookie> getCookie(String name); } public interface HeaderNames { From 4dfc9b13cd2938219f913855158ae94faaadc75f Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Fri, 26 May 2023 12:44:53 +0200 Subject: [PATCH 136/739] Java: Fix performance issue in the stub generator --- java/ql/src/utils/stub-generator/Stubs.qll | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/java/ql/src/utils/stub-generator/Stubs.qll b/java/ql/src/utils/stub-generator/Stubs.qll index 785f621cba0..a42a806455e 100644 --- a/java/ql/src/utils/stub-generator/Stubs.qll +++ b/java/ql/src/utils/stub-generator/Stubs.qll @@ -285,14 +285,19 @@ private string stubQualifier(RefType t) { else result = "" } +pragma[nomagic] +private predicate needsPackageNameHelper(RefType t, GeneratedTopLevel top, string name) { + t.getSourceDeclaration() = [getAReferencedType(top), top].getSourceDeclaration() and + name = t.getName() +} + /** * Holds if `t` may clash with another type of the same name, so should be referred to using the fully qualified name */ private predicate needsPackageName(RefType t) { - exists(GeneratedTopLevel top, RefType other | - t.getSourceDeclaration() = [getAReferencedType(top), top].getSourceDeclaration() and - other.getSourceDeclaration() = [getAReferencedType(top), top].getSourceDeclaration() and - t.getName() = other.getName() and + exists(GeneratedTopLevel top, RefType other, string name | + needsPackageNameHelper(t, top, name) and + needsPackageNameHelper(other, top, name) and t != other ) } From a89378d86d8ee2a143564bbc193e7da3ae304af9 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Fri, 26 May 2023 11:25:45 +0200 Subject: [PATCH 137/739] Java: add extra known frameworks and sample negative samples to manage sarif file sizes --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 3 +++ .../AutomodelApplicationModeExtractNegativeExamples.ql | 1 + 2 files changed, 4 insertions(+) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 138e508b1d2..785b56d31da 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -296,6 +296,9 @@ private class SkipFrameworkModeling extends CharacteristicsImpl::UninterestingTo "java.%", // "javax.%", // "org.apache%", // + "org.eclipse%", // + "org.gradle%", // + "org.slf4j%", // ]) } } diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index 5e12786e106..f57079aa57a 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -17,6 +17,7 @@ from ApplicationModeMetadataExtractor meta, string package, string type, boolean subtypes, string name, string signature, string input where + endpoint.getLocation().getStartLine() % 100 = 0 and characteristic.appliesToEndpoint(endpoint) and confidence >= SharedCharacteristics::highConfidence() and characteristic.hasImplications(any(NegativeSinkType negative), true, confidence) and From 8d4f9447b1106e85c990c69740797bbc7ce412f3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 17 May 2023 16:51:09 +0200 Subject: [PATCH 138/739] python: remove explicit steps copy, pop, get, popitem --- .../new/internal/TaintTrackingPrivate.qll | 9 +- .../test_collections.py | 2 +- .../test_collections.py | 4 +- .../frameworks/aiohttp/taint_test.py | 4 +- .../frameworks/django-v2-v3/taint_forms.py | 4 +- .../frameworks/django-v2-v3/taint_test.py | 18 +- .../frameworks/flask/taint_test.py | 20 +-- .../frameworks/multidict/taint_test.py | 8 +- .../frameworks/requests/taint_test.py | 6 +- .../frameworks/rest_framework/taint_test.py | 6 +- .../frameworks/stdlib/http_server.py | 2 +- .../frameworks/twisted/taint_test.py | 6 +- ...ExternalAPIsUsedWithUntrustedData.expected | 4 - .../UntrustedDataToExternalAPI.expected | 47 ----- .../PathInjection.expected | 165 ------------------ .../flask_path_injection.py | 2 +- .../CWE-022-PathInjection/path_injection.py | 22 +-- .../CWE-022-PathInjection/pathlib_use.py | 4 +- .../Security/CWE-022-PathInjection/test.py | 8 +- .../CommandInjection.expected | 34 ---- .../CommandInjection.expected | 74 -------- .../command_injection.py | 26 +-- .../ReflectedXss.expected | 7 - .../CodeInjection.expected | 23 --- .../LogInjection.expected | 31 ---- .../PamAuthorization.expected | 10 -- .../UnsafeDeserialization.expected | 19 -- .../CWE-601-UrlRedirect/UrlRedirect.expected | 59 ------- .../XpathInjection.expected | 38 ---- .../PolynomialReDoS.expected | 26 --- 30 files changed, 73 insertions(+), 615 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 3b32d95ae0b..78fb529b05a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -190,14 +190,9 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { call.getArg(0) = nodeFrom ) or - // methods + // dict methods exists(DataFlow::MethodCallNode call, string methodName | call = nodeTo | - methodName in [ - // general - "copy", "pop", - // dict - "values", "items", "get", "popitem" - ] and + methodName in ["values", "items"] and call.calls(nodeFrom, methodName) ) or diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py index ec3a3b419cc..a2a89a403e0 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py @@ -13,7 +13,7 @@ def test_access(): tainted_list = TAINTED_LIST ensure_tainted( - tainted_list.copy(), # $ tainted + tainted_list.copy(), # $ MISSING: tainted ) for ((x, y, *z), a, b) in tainted_list: diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index 50f9a613f9b..746c0d469f7 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -103,9 +103,9 @@ def test_dict_access(x): ensure_tainted( tainted_dict["name"], # $ tainted - tainted_dict.get("name"), # $ tainted + tainted_dict.get("name"), # $ MISSING: tainted tainted_dict[x], # $ tainted - tainted_dict.copy(), # $ tainted + tainted_dict.copy(), # $ MISSING: tainted ) for v in tainted_dict.values(): diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index ec475a592ab..3efbc39c431 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -23,7 +23,7 @@ async def test_taint(request: web.Request): # $ requestHandler # dict-like for captured parts of the URL request.match_info, # $ tainted request.match_info["key"], # $ tainted - request.match_info.get("key"), # $ tainted + request.match_info.get("key"), # $ MISSING: tainted # multidict.MultiDictProxy[str] (see `multidict` framework tests) request.query, # $ tainted @@ -38,7 +38,7 @@ async def test_taint(request: web.Request): # $ requestHandler # dict-like (readonly) request.cookies, # $ tainted request.cookies["key"], # $ tainted - request.cookies.get("key"), # $ tainted + request.cookies.get("key"), # $ MISSING: tainted request.cookies.keys(), # $ MISSING: tainted request.cookies.values(), # $ tainted request.cookies.items(), # $ tainted diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/taint_forms.py b/python/ql/test/library-tests/frameworks/django-v2-v3/taint_forms.py index 66021b64d29..4f4bf40ebef 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/taint_forms.py +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/taint_forms.py @@ -32,13 +32,13 @@ class MyForm(django.forms.Form): ensure_tainted( cleaned_data, # $ tainted cleaned_data["key"], # $ tainted - cleaned_data.get("key"), # $ tainted + cleaned_data.get("key"), # $ MISSING: tainted ) ensure_tainted( self.cleaned_data, # $ tainted self.cleaned_data["key"], # $ tainted - self.cleaned_data.get("key"), # $ tainted + self.cleaned_data.get("key"), # $ MISSING: tainted ) def clean_foo(self): diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py b/python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py index aa6f78be509..7d56f6fc944 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py @@ -31,17 +31,17 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou # Dict[str, str] request.content_params, # $ tainted request.content_params["key"], # $ tainted - request.content_params.get("key"), # $ tainted + request.content_params.get("key"), # $ MISSING: tainted # django.http.QueryDict # see https://docs.djangoproject.com/en/3.0/ref/request-response/#querydict-objects request.GET, # $ tainted request.GET["key"], # $ tainted - request.GET.get("key"), # $ tainted + request.GET.get("key"), # $ MISSING: tainted request.GET.getlist("key"), # $ tainted request.GET.getlist("key")[0], # $ tainted - request.GET.pop("key"), # $ tainted - request.GET.pop("key")[0], # $ tainted + request.GET.pop("key"), # $ MISSING: tainted + request.GET.pop("key")[0], # $ MISSING: tainted # key request.GET.popitem()[0], # $ tainted # values @@ -59,7 +59,7 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou # Dict[str, str] request.COOKIES, # $ tainted request.COOKIES["key"], # $ tainted - request.COOKIES.get("key"), # $ tainted + request.COOKIES.get("key"), # $ MISSING: tainted # MultiValueDict[str, UploadedFile] request.FILES, # $ tainted @@ -73,20 +73,20 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou request.FILES["key"].file.read(), # $ tainted request.FILES["key"].read(), # $ tainted - request.FILES.get("key"), # $ tainted - request.FILES.get("key").name, # $ tainted + request.FILES.get("key"), # $ MISSING: tainted + request.FILES.get("key").name, # $ MISSING:tainted request.FILES.getlist("key"), # $ tainted request.FILES.getlist("key")[0], # $ tainted request.FILES.getlist("key")[0].name, # $ tainted request.FILES.dict(), # $ tainted request.FILES.dict()["key"], # $ tainted request.FILES.dict()["key"].name, # $ tainted - request.FILES.dict().get("key").name, # $ tainted + request.FILES.dict().get("key").name, # $ MISSING: tainted # Dict[str, Any] request.META, # $ tainted request.META["HTTP_USER_AGENT"], # $ tainted - request.META.get("HTTP_USER_AGENT"), # $ tainted + request.META.get("HTTP_USER_AGENT"), # $ MISSING: tainted # HttpHeaders (case insensitive dict-like) request.headers, # $ tainted diff --git a/python/ql/test/library-tests/frameworks/flask/taint_test.py b/python/ql/test/library-tests/frameworks/flask/taint_test.py index dcca8ff6681..bbbbd747834 100644 --- a/python/ql/test/library-tests/frameworks/flask/taint_test.py +++ b/python/ql/test/library-tests/frameworks/flask/taint_test.py @@ -12,7 +12,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route ensure_tainted( request.environ, # $ tainted - request.environ.get('HTTP_AUTHORIZATION'), # $ tainted + request.environ.get('HTTP_AUTHORIZATION'), # $ MISSING: tainted request.path, # $ tainted request.full_path, # $ tainted @@ -38,7 +38,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # By default werkzeug.datastructures.ImmutableMultiDict -- although can be changed :\ request.args, # $ tainted request.args['key'], # $ tainted - request.args.get('key'), # $ tainted + request.args.get('key'), # $ MISSING: tainted request.args.getlist('key'), # $ tainted # werkzeug.datastructures.Authorization (a dict, with some properties) @@ -81,9 +81,9 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route request.files['key'].stream, # $ tainted request.files['key'].read(), # $ tainted request.files['key'].stream.read(), # $ tainted - request.files.get('key'), # $ tainted - request.files.get('key').filename, # $ tainted - request.files.get('key').stream, # $ tainted + request.files.get('key'), # $ MISSING: tainted + request.files.get('key').filename, # $ MISSING: tainted + request.files.get('key').stream, # $ MISSING: tainted request.files.getlist('key'), # $ tainted request.files.getlist('key')[0].filename, # $ tainted request.files.getlist('key')[0].stream, # $ tainted @@ -91,7 +91,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # By default werkzeug.datastructures.ImmutableMultiDict -- although can be changed :\ request.form, # $ tainted request.form['key'], # $ tainted - request.form.get('key'), # $ tainted + request.form.get('key'), # $ MISSING: tainted request.form.getlist('key'), # $ tainted request.get_data(), # $ tainted @@ -104,7 +104,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # which has same interface as werkzeug.datastructures.Headers request.headers, # $ tainted request.headers['key'], # $ tainted - request.headers.get('key'), # $ tainted + request.headers.get('key'), # $ MISSING: tainted request.headers.get_all('key'), # $ tainted request.headers.getlist('key'), # $ tainted # popitem returns `(key, value)` @@ -149,13 +149,13 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # werkzeug.datastructures.CombinedMultiDict, which is basically just a werkzeug.datastructures.MultiDict request.values, # $ tainted request.values['key'], # $ tainted - request.values.get('key'), # $ tainted + request.values.get('key'), # $ MISSING: tainted request.values.getlist('key'), # $ tainted # dict request.view_args, # $ tainted request.view_args['key'], # $ tainted - request.view_args.get('key'), # $ tainted + request.view_args.get('key'), # $ MISSING: tainted ) ensure_not_tainted( @@ -204,7 +204,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route b.getlist('key'), # $ tainted gl('key'), # $ tainted - files.get('key').filename, # $ tainted + files.get('key').filename, # $ MISSING: tainted ) # aliasing tests diff --git a/python/ql/test/library-tests/frameworks/multidict/taint_test.py b/python/ql/test/library-tests/frameworks/multidict/taint_test.py index 8fbac79888f..8001bfe5c22 100644 --- a/python/ql/test/library-tests/frameworks/multidict/taint_test.py +++ b/python/ql/test/library-tests/frameworks/multidict/taint_test.py @@ -9,13 +9,13 @@ ensure_tainted( mdp, # $ tainted mdp["key"], # $ tainted - mdp.get("key"), # $ tainted + mdp.get("key"), # $ MISSING: tainted mdp.getone("key"), # $ tainted mdp.getall("key"), # $ tainted mdp.keys(), # $ MISSING: tainted mdp.values(), # $ tainted mdp.items(), # $ tainted - mdp.copy(), # $ tainted + mdp.copy(), # $ MISSING: tainted list(mdp), # $ tainted iter(mdp), # $ tainted ) @@ -29,13 +29,13 @@ ensure_tainted( ci_mdp, # $ tainted ci_mdp["key"], # $ tainted - ci_mdp.get("key"), # $ tainted + ci_mdp.get("key"), # $ MISSING: tainted ci_mdp.getone("key"), # $ tainted ci_mdp.getall("key"), # $ tainted ci_mdp.keys(), # $ MISSING: tainted ci_mdp.values(), # $ tainted ci_mdp.items(), # $ tainted - ci_mdp.copy(), # $ tainted + ci_mdp.copy(), # $ MISSING: tainted list(ci_mdp), # $ tainted iter(ci_mdp), # $ tainted ) diff --git a/python/ql/test/library-tests/frameworks/requests/taint_test.py b/python/ql/test/library-tests/frameworks/requests/taint_test.py index 48ff417baa7..11b781ffd11 100644 --- a/python/ql/test/library-tests/frameworks/requests/taint_test.py +++ b/python/ql/test/library-tests/frameworks/requests/taint_test.py @@ -30,15 +30,15 @@ def test_taint(): # $ requestHandler resp.links, # $ tainted resp.links['key'], # $ tainted - resp.links.get('key'), # $ tainted + resp.links.get('key'), # $ MISSING: tainted resp.cookies, # $ tainted resp.cookies['key'], # $ tainted - resp.cookies.get('key'), # $ tainted + resp.cookies.get('key'), # $ MISSING: tainted resp.headers, # $ tainted resp.headers['key'], # $ tainted - resp.headers.get('key'), # $ tainted + resp.headers.get('key'), # $ MISSING: tainted ) for content_chunk in resp.iter_content(): diff --git a/python/ql/test/library-tests/frameworks/rest_framework/taint_test.py b/python/ql/test/library-tests/frameworks/rest_framework/taint_test.py index 4a22e03b563..b839c392b51 100644 --- a/python/ql/test/library-tests/frameworks/rest_framework/taint_test.py +++ b/python/ql/test/library-tests/frameworks/rest_framework/taint_test.py @@ -31,11 +31,11 @@ def test_taint(request: Request, routed_param): # $ requestHandler routedParamet # alias for .GET request.query_params, # $ tainted request.query_params["key"], # $ tainted - request.query_params.get("key"), # $ tainted + request.query_params.get("key"), # $ MISSING: tainted request.query_params.getlist("key"), # $ tainted request.query_params.getlist("key")[0], # $ tainted - request.query_params.pop("key"), # $ tainted - request.query_params.pop("key")[0], # $ tainted + request.query_params.pop("key"), # $ MISSING: tainted + request.query_params.pop("key")[0], # $ MISSING: tainted # see more detailed tests of `request.user` below request.user, # $ tainted diff --git a/python/ql/test/library-tests/frameworks/stdlib/http_server.py b/python/ql/test/library-tests/frameworks/stdlib/http_server.py index 27ec2211f4b..0ec21bf5e20 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/http_server.py +++ b/python/ql/test/library-tests/frameworks/stdlib/http_server.py @@ -57,7 +57,7 @@ class MyHandler(BaseHTTPRequestHandler): self.headers, # $ tainted self.headers['Foo'], # $ tainted - self.headers.get('Foo'), # $ tainted + self.headers.get('Foo'), # $ MISSING: tainted self.headers.get_all('Foo'), # $ tainted self.headers.keys(), # $ tainted self.headers.values(), # $ tainted diff --git a/python/ql/test/library-tests/frameworks/twisted/taint_test.py b/python/ql/test/library-tests/frameworks/twisted/taint_test.py index cdc6592f90e..b48ab10e075 100644 --- a/python/ql/test/library-tests/frameworks/twisted/taint_test.py +++ b/python/ql/test/library-tests/frameworks/twisted/taint_test.py @@ -26,12 +26,12 @@ class MyTaintTest(Resource): request.args, # $ tainted request.args[b"key"], # $ tainted request.args[b"key"][0], # $ tainted - request.args.get(b"key"), # $ tainted - request.args.get(b"key")[0], # $ tainted + request.args.get(b"key"), # $ MISSING: tainted + request.args.get(b"key")[0], # $ MISSING: tainted request.received_cookies, # $ tainted request.received_cookies["key"], # $ tainted - request.received_cookies.get("key"), # $ tainted + request.received_cookies.get("key"), # $ MISSING: tainted request.getCookie(b"key"), # $ tainted # twisted.web.http_headers.Headers diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected index a346aef9d22..e69de29bb2d 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected @@ -1,4 +0,0 @@ -| hmac.new [keyword msg] | 1 | 1 | -| hmac.new [position 1] | 1 | 1 | -| unknown.lib.func [keyword kw] | 2 | 1 | -| unknown.lib.func [position 0] | 2 | 1 | diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected index f9a03ca8d5e..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected @@ -1,51 +1,4 @@ edges -| test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:5:26:5:32 | GSSA Variable request | -| test.py:5:26:5:32 | GSSA Variable request | test.py:13:16:13:22 | ControlFlowNode for request | -| test.py:5:26:5:32 | GSSA Variable request | test.py:23:16:23:22 | ControlFlowNode for request | -| test.py:5:26:5:32 | GSSA Variable request | test.py:34:12:34:18 | ControlFlowNode for request | -| test.py:5:26:5:32 | GSSA Variable request | test.py:42:12:42:18 | ControlFlowNode for request | -| test.py:5:26:5:32 | GSSA Variable request | test.py:54:12:54:18 | ControlFlowNode for request | -| test.py:13:16:13:22 | ControlFlowNode for request | test.py:13:16:13:27 | ControlFlowNode for Attribute | -| test.py:13:16:13:27 | ControlFlowNode for Attribute | test.py:15:36:15:39 | ControlFlowNode for data | -| test.py:23:16:23:22 | ControlFlowNode for request | test.py:23:16:23:27 | ControlFlowNode for Attribute | -| test.py:23:16:23:27 | ControlFlowNode for Attribute | test.py:25:44:25:47 | ControlFlowNode for data | -| test.py:34:12:34:18 | ControlFlowNode for request | test.py:34:12:34:23 | ControlFlowNode for Attribute | -| test.py:34:12:34:23 | ControlFlowNode for Attribute | test.py:35:10:35:13 | ControlFlowNode for data | -| test.py:34:12:34:23 | ControlFlowNode for Attribute | test.py:36:13:36:16 | ControlFlowNode for data | -| test.py:42:12:42:18 | ControlFlowNode for request | test.py:42:12:42:23 | ControlFlowNode for Attribute | -| test.py:42:12:42:23 | ControlFlowNode for Attribute | test.py:43:22:43:25 | ControlFlowNode for data | -| test.py:42:12:42:23 | ControlFlowNode for Attribute | test.py:44:25:44:28 | ControlFlowNode for data | -| test.py:47:17:47:19 | ControlFlowNode for arg | test.py:50:32:50:34 | ControlFlowNode for arg | -| test.py:54:12:54:18 | ControlFlowNode for request | test.py:54:12:54:23 | ControlFlowNode for Attribute | -| test.py:54:12:54:23 | ControlFlowNode for Attribute | test.py:55:17:55:20 | ControlFlowNode for data | -| test.py:55:17:55:20 | ControlFlowNode for data | test.py:47:17:47:19 | ControlFlowNode for arg | nodes -| test.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| test.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| test.py:13:16:13:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:13:16:13:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:15:36:15:39 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | -| test.py:23:16:23:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:23:16:23:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:25:44:25:47 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | -| test.py:34:12:34:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:34:12:34:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:35:10:35:13 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | -| test.py:36:13:36:16 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | -| test.py:42:12:42:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:42:12:42:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:43:22:43:25 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | -| test.py:44:25:44:28 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | -| test.py:47:17:47:19 | ControlFlowNode for arg | semmle.label | ControlFlowNode for arg | -| test.py:50:32:50:34 | ControlFlowNode for arg | semmle.label | ControlFlowNode for arg | -| test.py:54:12:54:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:54:12:54:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:55:17:55:20 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | subpaths #select -| test.py:15:36:15:39 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [position 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | -| test.py:25:44:25:47 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:25:44:25:47 | ControlFlowNode for data | Call to hmac.new [keyword msg] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | -| test.py:35:10:35:13 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:35:10:35:13 | ControlFlowNode for data | Call to unknown.lib.func [position 0] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | -| test.py:36:13:36:16 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:36:13:36:16 | ControlFlowNode for data | Call to unknown.lib.func [keyword kw] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | -| test.py:43:22:43:25 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:43:22:43:25 | ControlFlowNode for data | Call to unknown.lib.func [position 0] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | -| test.py:44:25:44:28 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:44:25:44:28 | ControlFlowNode for data | Call to unknown.lib.func [keyword kw] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected b/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected index 58bdb917690..da9eb4a10d7 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected @@ -1,177 +1,12 @@ edges -| flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_path_injection.py:1:26:1:32 | GSSA Variable request | -| flask_path_injection.py:1:26:1:32 | GSSA Variable request | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | -| flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | -| flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | -| path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:3:26:3:32 | GSSA Variable request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:12:16:12:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:19:16:19:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:27:16:27:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:46:16:46:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:63:16:63:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:84:16:84:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:107:16:107:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:118:16:118:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:129:16:129:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:138:16:138:22 | ControlFlowNode for request | -| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:149:16:149:22 | ControlFlowNode for request | -| path_injection.py:12:16:12:22 | ControlFlowNode for request | path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | -| path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | -| path_injection.py:19:16:19:22 | ControlFlowNode for request | path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | -| path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | path_injection.py:20:30:20:63 | ControlFlowNode for Attribute() | -| path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() | path_injection.py:21:14:21:18 | ControlFlowNode for npath | -| path_injection.py:20:30:20:63 | ControlFlowNode for Attribute() | path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() | -| path_injection.py:27:16:27:22 | ControlFlowNode for request | path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | -| path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | path_injection.py:28:30:28:63 | ControlFlowNode for Attribute() | -| path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() | path_injection.py:31:14:31:18 | ControlFlowNode for npath | -| path_injection.py:28:30:28:63 | ControlFlowNode for Attribute() | path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() | -| path_injection.py:46:16:46:22 | ControlFlowNode for request | path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | -| path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | path_injection.py:47:30:47:63 | ControlFlowNode for Attribute() | -| path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() | path_injection.py:48:14:48:18 | ControlFlowNode for npath | -| path_injection.py:47:30:47:63 | ControlFlowNode for Attribute() | path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() | -| path_injection.py:63:16:63:22 | ControlFlowNode for request | path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | -| path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | path_injection.py:64:29:64:62 | ControlFlowNode for Attribute() | -| path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | path_injection.py:65:14:65:18 | ControlFlowNode for npath | -| path_injection.py:64:29:64:62 | ControlFlowNode for Attribute() | path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | -| path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | -| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path | | path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path | -| path_injection.py:107:16:107:22 | ControlFlowNode for request | path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | -| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | path_injection.py:113:14:113:17 | ControlFlowNode for path | -| path_injection.py:118:16:118:22 | ControlFlowNode for request | path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | -| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | path_injection.py:124:14:124:17 | ControlFlowNode for path | -| path_injection.py:129:16:129:22 | ControlFlowNode for request | path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | -| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | -| path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | -| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:142:14:142:17 | ControlFlowNode for path | -| path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | -| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | path_injection.py:152:18:152:21 | ControlFlowNode for path | -| pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | pathlib_use.py:3:26:3:32 | GSSA Variable request | -| pathlib_use.py:3:26:3:32 | GSSA Variable request | pathlib_use.py:12:16:12:22 | ControlFlowNode for request | -| pathlib_use.py:12:16:12:22 | ControlFlowNode for request | pathlib_use.py:12:16:12:27 | ControlFlowNode for Attribute | -| pathlib_use.py:12:16:12:27 | ControlFlowNode for Attribute | pathlib_use.py:14:5:14:5 | ControlFlowNode for p | -| pathlib_use.py:12:16:12:27 | ControlFlowNode for Attribute | pathlib_use.py:17:5:17:6 | ControlFlowNode for p2 | -| test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:3:26:3:32 | GSSA Variable request | -| test.py:3:26:3:32 | GSSA Variable request | test.py:9:12:9:18 | ControlFlowNode for request | -| test.py:9:12:9:18 | ControlFlowNode for request | test.py:9:12:9:23 | ControlFlowNode for Attribute | -| test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() | -| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:18:9:18:16 | ControlFlowNode for source() | -| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:24:9:24:16 | ControlFlowNode for source() | -| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:31:9:31:16 | ControlFlowNode for source() | -| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:46:9:46:16 | ControlFlowNode for source() | -| test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:29:13:29 | ControlFlowNode for x | -| test.py:13:29:13:29 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | -| test.py:18:9:18:16 | ControlFlowNode for source() | test.py:19:10:19:10 | ControlFlowNode for x | -| test.py:24:9:24:16 | ControlFlowNode for source() | test.py:25:19:25:19 | ControlFlowNode for x | -| test.py:25:9:25:20 | ControlFlowNode for normalize() | test.py:26:10:26:10 | ControlFlowNode for y | -| test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | -| test.py:25:19:25:19 | ControlFlowNode for x | test.py:25:9:25:20 | ControlFlowNode for normalize() | -| test.py:31:9:31:16 | ControlFlowNode for source() | test.py:33:14:33:14 | ControlFlowNode for x | -| test.py:46:9:46:16 | ControlFlowNode for source() | test.py:48:23:48:23 | ControlFlowNode for x | -| test.py:48:13:48:24 | ControlFlowNode for normalize() | test.py:49:14:49:14 | ControlFlowNode for y | -| test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | -| test.py:48:23:48:23 | ControlFlowNode for x | test.py:48:13:48:24 | ControlFlowNode for normalize() | nodes -| flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| flask_path_injection.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | semmle.label | ControlFlowNode for dirname | -| path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| path_injection.py:3:26:3:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| path_injection.py:12:16:12:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:19:16:19:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:20:30:20:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:21:14:21:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath | -| path_injection.py:27:16:27:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:28:30:28:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:31:14:31:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath | -| path_injection.py:46:16:46:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:47:30:47:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:48:14:48:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath | -| path_injection.py:63:16:63:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:64:29:64:62 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| path_injection.py:65:14:65:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath | -| path_injection.py:84:16:84:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path | | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | semmle.label | ControlFlowNode for foo_id | | path_injection.py:94:14:94:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | path_injection.py:98:20:98:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | | path_injection.py:102:14:102:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | -| path_injection.py:107:16:107:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:113:14:113:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | -| path_injection.py:118:16:118:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:124:14:124:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | -| path_injection.py:129:16:129:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | semmle.label | ControlFlowNode for sanitized | -| path_injection.py:138:16:138:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:142:14:142:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | -| path_injection.py:149:16:149:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| path_injection.py:152:18:152:21 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | -| pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| pathlib_use.py:3:26:3:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| pathlib_use.py:12:16:12:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| pathlib_use.py:12:16:12:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| pathlib_use.py:14:5:14:5 | ControlFlowNode for p | semmle.label | ControlFlowNode for p | -| pathlib_use.py:17:5:17:6 | ControlFlowNode for p2 | semmle.label | ControlFlowNode for p2 | -| test.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| test.py:3:26:3:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| test.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:12:15:12:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:13:12:13:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:13:29:13:29 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:18:9:18:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | -| test.py:19:10:19:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:24:9:24:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | -| test.py:25:9:25:20 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() | -| test.py:25:19:25:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:26:10:26:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | -| test.py:31:9:31:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | -| test.py:33:14:33:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:46:9:46:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | -| test.py:48:13:48:24 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() | -| test.py:48:23:48:23 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | -| test.py:49:14:49:14 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | subpaths -| test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:25:9:25:20 | ControlFlowNode for normalize() | -| test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:48:13:48:24 | ControlFlowNode for normalize() | #select -| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | This path depends on a $@. | flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:21:14:21:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:21:14:21:18 | ControlFlowNode for npath | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:31:14:31:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:31:14:31:18 | ControlFlowNode for npath | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:48:14:48:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:48:14:48:18 | ControlFlowNode for npath | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:65:14:65:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:65:14:65:18 | ControlFlowNode for npath | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | | path_injection.py:94:14:94:17 | ControlFlowNode for path | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | user-provided value | | path_injection.py:102:14:102:17 | ControlFlowNode for path | path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:98:20:98:22 | ControlFlowNode for foo | user-provided value | -| path_injection.py:113:14:113:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:113:14:113:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:124:14:124:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:124:14:124:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:142:14:142:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:142:14:142:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| path_injection.py:152:18:152:21 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:152:18:152:21 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| pathlib_use.py:14:5:14:5 | ControlFlowNode for p | pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | pathlib_use.py:14:5:14:5 | ControlFlowNode for p | This path depends on a $@. | pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| pathlib_use.py:17:5:17:6 | ControlFlowNode for p2 | pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | pathlib_use.py:17:5:17:6 | ControlFlowNode for p2 | This path depends on a $@. | pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:19:10:19:10 | ControlFlowNode for x | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:19:10:19:10 | ControlFlowNode for x | This path depends on a $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:26:10:26:10 | ControlFlowNode for y | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:26:10:26:10 | ControlFlowNode for y | This path depends on a $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:33:14:33:14 | ControlFlowNode for x | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:33:14:33:14 | ControlFlowNode for x | This path depends on a $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:49:14:49:14 | ControlFlowNode for y | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:49:14:49:14 | ControlFlowNode for y | This path depends on a $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/flask_path_injection.py b/python/ql/test/query-tests/Security/CWE-022-PathInjection/flask_path_injection.py index f64d76a3b4d..d0ad06aa323 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/flask_path_injection.py +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/flask_path_injection.py @@ -18,4 +18,4 @@ def download_file(): def download_file(): dirname = request.args.get('dirname', '') filename = request.args.get('filename', '') - return send_from_directory(dirname, filename) # $result=BAD result=OK(filename) + return send_from_directory(dirname, filename) # $ result=OK(filename) MISSING: result=BAD diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py b/python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py index 39c17037480..bf8bfef44b5 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py @@ -10,7 +10,7 @@ STATIC_DIR = "/server/static/" @app.route("/path1") def path_injection(): filename = request.args.get('filename', '') - f = open(os.path.join(STATIC_DIR, filename)) # $result=BAD + f = open(os.path.join(STATIC_DIR, filename)) # $ MISSING: result=BAD @app.route("/path2") @@ -18,7 +18,7 @@ def path_injection(): # Normalized, but not checked filename = request.args.get('filename', '') npath = os.path.normpath(os.path.join(STATIC_DIR, filename)) - f = open(npath) # $result=BAD + f = open(npath) # $ MISSING: result=BAD @app.route("/path3") @@ -28,7 +28,7 @@ def unsafe_path_normpath(): npath = os.path.normpath(os.path.join(STATIC_DIR, filename)) if npath.startswith(STATIC_DIR): pass - f = open(npath) # $result=BAD + f = open(npath) # $ MISSING: result=BAD @app.route("/path4") @@ -45,7 +45,7 @@ def unsafe_path_realpath(): # Normalized (by `realpath` that also follows symlinks), but not checked properly filename = request.args.get('filename', '') npath = os.path.realpath(os.path.join(STATIC_DIR, filename)) - f = open(npath) # $result=BAD + f = open(npath) # $ MISSING: result=BAD @app.route("/path6") @@ -62,7 +62,7 @@ def unsafe_path_abspath(): # Normalized (by `abspath`), but not checked properly filename = request.args.get('filename', '') npath = os.path.abspath(os.path.join(STATIC_DIR, filename)) - f = open(npath) # $result=BAD + f = open(npath) # $ MISSING: result=BAD @app.route("/path7") @@ -84,7 +84,7 @@ def safe_path_abspath_tricky(): filename = request.args.get('filename', '') possibly_unsafe_path = os.path.join(STATIC_DIR, filename) if os.path.abspath(possibly_unsafe_path).startswith(STATIC_DIR): - f = open(possibly_unsafe_path) # $SPURIOUS: result=BAD + f = open(possibly_unsafe_path) # $ result=OK @app.route("/int-only/<int:foo_id>") @@ -110,7 +110,7 @@ def no_dot_dot(): # handle if `filename` is an absolute path if '../' in path: return "not this time" - f = open(path) # $result=BAD + f = open(path) # $ MISSING: result=BAD @app.route("/no-dot-dot-with-prefix") @@ -121,7 +121,7 @@ def no_dot_dot_with_prefix(): # Therefore, for UNIX-only programs, the `../` check is enough to stop path injections. if '../' in path: return "not this time" - f = open(path) # $result=BAD // OK if only running on UNIX systems, NOT OK if could be running on windows + f = open(path) # $ MISSING: result=BAD // OK if only running on UNIX systems, NOT OK if could be running on windows @app.route("/replace-slash") @@ -129,7 +129,7 @@ def replace_slash(): filename = request.args.get('filename', '') path = os.path.join(STATIC_DIR, filename) sanitized = path.replace("/", "_") - f = open(sanitized) # $result=BAD // OK if only running on UNIX systems, NOT OK if could be running on windows + f = open(sanitized) # $ MISSING: result=BAD // OK if only running on UNIX systems, NOT OK if could be running on windows @app.route("/stackoverflow-solution") @@ -139,7 +139,7 @@ def stackoverflow_solution(): path = os.path.join(STATIC_DIR, filename) if os.path.commonprefix((os.path.realpath(path), STATIC_DIR)) != STATIC_DIR: return "not this time" - f = open(path) # $SPURIOUS: result=BAD + f = open(path) # $ result=OK SAFE_FILES = ['foo', 'bar', 'baz'] @@ -149,4 +149,4 @@ def safe_set_of_files(): filename = request.args.get('filename', '') if filename in SAFE_FILES: path = os.path.join(STATIC_DIR, filename) - f = open(path) # $SPURIOUS: result=BAD + f = open(path) # $ result=OK diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/pathlib_use.py b/python/ql/test/query-tests/Security/CWE-022-PathInjection/pathlib_use.py index 6f703f903dc..c9d60ef9969 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/pathlib_use.py +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/pathlib_use.py @@ -11,7 +11,7 @@ STATIC_DIR = pathlib.Path("/server/static/") def path_injection(): filename = request.args.get('filename', '') p = STATIC_DIR / filename - p.open() # $ result=BAD + p.open() # $ MISSING: result=BAD p2 = pathlib.Path(STATIC_DIR, filename) - p2.open() # $ result=BAD + p2.open() # $ MISSING: result=BAD diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/test.py b/python/ql/test/query-tests/Security/CWE-022-PathInjection/test.py index 7200cd78f45..ed080f7d5c6 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/test.py +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/test.py @@ -16,21 +16,21 @@ def normalize(x): @app.route("/path") def simple(): x = source() - open(x) # $result=BAD + open(x) # $ MISSING: result=BAD @app.route("/path") def normalization(): x = source() y = normalize(x) - open(y) # $result=BAD + open(y) # $ MISSING: result=BAD @app.route("/path") def check(): x = source() if x.startswith("subfolder/"): - open(x) # $result=BAD + open(x) # $ MISSING: result=BAD @app.route("/path") @@ -46,4 +46,4 @@ def check_then_normalize(): x = source() if x.startswith("subfolder/"): y = normalize(x) - open(y) # $result=BAD + open(y) # $ MISSING: result=BAD diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected index aa6baf79588..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected @@ -1,38 +1,4 @@ edges -| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:5:26:5:32 | GSSA Variable request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:18:13:18:19 | ControlFlowNode for request | -| command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | nodes -| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| command_injection.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| command_injection.py:18:13:18:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select -| command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected index 7a0c72e07d6..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected @@ -1,78 +1,4 @@ edges -| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:5:26:5:32 | GSSA Variable request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:11:13:11:19 | ControlFlowNode for request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:18:13:18:19 | ControlFlowNode for request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:25:11:25:17 | ControlFlowNode for request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:31:13:31:19 | ControlFlowNode for request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:38:15:38:21 | ControlFlowNode for request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:54:15:54:21 | ControlFlowNode for request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:71:12:71:18 | ControlFlowNode for request | -| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:78:12:78:18 | ControlFlowNode for request | -| command_injection.py:11:13:11:19 | ControlFlowNode for request | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | -| command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | -| command_injection.py:25:11:25:17 | ControlFlowNode for request | command_injection.py:25:11:25:22 | ControlFlowNode for Attribute | -| command_injection.py:25:11:25:22 | ControlFlowNode for Attribute | command_injection.py:26:23:26:25 | ControlFlowNode for cmd | -| command_injection.py:31:13:31:19 | ControlFlowNode for request | command_injection.py:31:13:31:24 | ControlFlowNode for Attribute | -| command_injection.py:31:13:31:24 | ControlFlowNode for Attribute | command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | -| command_injection.py:38:15:38:21 | ControlFlowNode for request | command_injection.py:38:15:38:26 | ControlFlowNode for Attribute | -| command_injection.py:38:15:38:26 | ControlFlowNode for Attribute | command_injection.py:41:15:41:21 | ControlFlowNode for command | -| command_injection.py:38:15:38:26 | ControlFlowNode for Attribute | command_injection.py:42:15:42:21 | ControlFlowNode for command | -| command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | -| command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | command_injection.py:55:15:55:21 | ControlFlowNode for command | -| command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | command_injection.py:56:14:56:20 | ControlFlowNode for command | -| command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | command_injection.py:57:21:57:27 | ControlFlowNode for command | -| command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | command_injection.py:58:27:58:33 | ControlFlowNode for command | -| command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | command_injection.py:59:20:59:26 | ControlFlowNode for command | -| command_injection.py:71:12:71:18 | ControlFlowNode for request | command_injection.py:71:12:71:23 | ControlFlowNode for Attribute | -| command_injection.py:71:12:71:23 | ControlFlowNode for Attribute | command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | -| command_injection.py:78:12:78:18 | ControlFlowNode for request | command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | -| command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | nodes -| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| command_injection.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| command_injection.py:11:13:11:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:18:13:18:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:25:11:25:17 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:25:11:25:22 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:26:23:26:25 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | -| command_injection.py:31:13:31:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:31:13:31:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:38:15:38:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:38:15:38:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:41:15:41:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | -| command_injection.py:42:15:42:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | -| command_injection.py:54:15:54:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:55:15:55:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | -| command_injection.py:56:14:56:20 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | -| command_injection.py:57:21:57:27 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | -| command_injection.py:58:27:58:33 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | -| command_injection.py:59:20:59:26 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | -| command_injection.py:71:12:71:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:71:12:71:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| command_injection.py:78:12:78:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select -| command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:26:23:26:25 | ControlFlowNode for cmd | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:26:23:26:25 | ControlFlowNode for cmd | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:41:15:41:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:41:15:41:21 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:42:15:42:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:42:15:42:21 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:55:15:55:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:55:15:55:21 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:56:14:56:20 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:56:14:56:20 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:57:21:57:27 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:57:21:57:27 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:58:27:58:33 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:58:27:58:33 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:59:20:59:26 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:59:20:59:26 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | -| command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/command_injection.py b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/command_injection.py index c969a1b1020..64b622acd72 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/command_injection.py +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/command_injection.py @@ -10,27 +10,27 @@ app = Flask(__name__) def command_injection1(): files = request.args.get('files', '') # Don't let files be `; rm -rf /` - os.system("ls " + files) # $result=BAD + os.system("ls " + files) # $ MISSING: result=BAD @app.route("/command2") def command_injection2(): files = request.args.get('files', '') # Don't let files be `; rm -rf /` - subprocess.Popen("ls " + files, shell=True) # $result=BAD + subprocess.Popen("ls " + files, shell=True) # $ MISSING: result=BAD @app.route("/command3") def first_arg_injection(): cmd = request.args.get('cmd', '') - subprocess.Popen([cmd, "param1"]) # $result=BAD + subprocess.Popen([cmd, "param1"]) # $ MISSING: result=BAD @app.route("/other_cases") def others(): files = request.args.get('files', '') # Don't let files be `; rm -rf /` - os.popen("ls " + files) # $result=BAD + os.popen("ls " + files) # $ MISSING: result=BAD @app.route("/multiple") @@ -38,8 +38,8 @@ def multiple(): command = request.args.get('command', '') # We should mark flow to both calls here, which conflicts with removing flow out of # a sink due to use-use flow. - os.system(command) # $result=BAD - os.system(command) # $result=BAD + os.system(command) # $ MISSING: result=BAD + os.system(command) # $ MISSING: result=BAD @app.route("/not-into-sink-impl") @@ -52,11 +52,11 @@ def not_into_sink_impl(): subprocess.call implementation: https://github.com/python/cpython/blob/fa7ce080175f65d678a7d5756c94f82887fc9803/Lib/subprocess.py#L341 """ command = request.args.get('command', '') - os.system(command) # $result=BAD - os.popen(command) # $result=BAD - subprocess.call(command) # $result=BAD - subprocess.check_call(command) # $result=BAD - subprocess.run(command) # $result=BAD + os.system(command) # $ MISSING: result=BAD + os.popen(command) # $ MISSING: result=BAD + subprocess.call(command) # $ MISSING: result=BAD + subprocess.check_call(command) # $ MISSING: result=BAD + subprocess.run(command) # $ MISSING: result=BAD @app.route("/path-exists-not-sanitizer") @@ -70,11 +70,11 @@ def path_exists_not_sanitizer(): """ path = request.args.get('path', '') if os.path.exists(path): - os.system("ls " + path) # $result=BAD + os.system("ls " + path) # $ MISSING: result=BAD @app.route("/restricted-characters") def restricted_characters(): path = request.args.get('path', '') if re.match(r'^[a-zA-Z0-9_-]+$', path): - os.system("ls " + path) # $SPURIOUS: result=BAD + os.system("ls " + path) # $ result=OK diff --git a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected index cfeb912d186..5f5962b6a7e 100644 --- a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected @@ -1,10 +1,7 @@ edges | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:2:26:2:32 | GSSA Variable request | -| reflected_xss.py:2:26:2:32 | GSSA Variable request | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | | reflected_xss.py:2:26:2:32 | GSSA Variable request | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | | reflected_xss.py:2:26:2:32 | GSSA Variable request | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | -| reflected_xss.py:9:18:9:24 | ControlFlowNode for request | reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | -| reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | reflected_xss.py:21:23:21:34 | ControlFlowNode for Attribute | | reflected_xss.py:21:23:21:34 | ControlFlowNode for Attribute | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | reflected_xss.py:27:23:27:34 | ControlFlowNode for Attribute | @@ -12,9 +9,6 @@ edges nodes | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | reflected_xss.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| reflected_xss.py:9:18:9:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | reflected_xss.py:21:23:21:34 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -23,6 +17,5 @@ nodes | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths #select -| reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected b/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected index f8e45884ff0..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected @@ -1,27 +1,4 @@ edges -| code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:1:26:1:32 | GSSA Variable request | -| code_injection.py:1:26:1:32 | GSSA Variable request | code_injection.py:6:12:6:18 | ControlFlowNode for request | -| code_injection.py:1:26:1:32 | GSSA Variable request | code_injection.py:18:16:18:22 | ControlFlowNode for request | -| code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | -| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:7:10:7:13 | ControlFlowNode for code | -| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:8:10:8:13 | ControlFlowNode for code | -| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | -| code_injection.py:18:16:18:22 | ControlFlowNode for request | code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | -| code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | nodes -| code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| code_injection.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| code_injection.py:6:12:6:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| code_injection.py:7:10:7:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code | -| code_injection.py:8:10:8:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code | -| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | -| code_injection.py:18:16:18:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | semmle.label | ControlFlowNode for obj_name | subpaths #select -| code_injection.py:7:10:7:13 | ControlFlowNode for code | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:7:10:7:13 | ControlFlowNode for code | This code execution depends on a $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| code_injection.py:8:10:8:13 | ControlFlowNode for code | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:8:10:8:13 | ControlFlowNode for code | This code execution depends on a $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | This code execution depends on a $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | This code execution depends on a $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected index d7736a271c6..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected @@ -1,35 +1,4 @@ edges -| LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:7:19:7:25 | GSSA Variable request | -| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | -| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | -| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | -| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | -| LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | -| LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | -| LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | -| LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | -| LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute | -| LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | -| LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | -| LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | nodes -| LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | semmle.label | GSSA Variable request | -| LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select -| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | -| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | -| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | -| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected index 8cd6466ae11..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected +++ b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected @@ -1,14 +1,4 @@ edges -| pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | pam_test.py:4:26:4:32 | GSSA Variable request | -| pam_test.py:4:26:4:32 | GSSA Variable request | pam_test.py:71:16:71:22 | ControlFlowNode for request | -| pam_test.py:71:16:71:22 | ControlFlowNode for request | pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | -| pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | nodes -| pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| pam_test.py:4:26:4:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| pam_test.py:71:16:71:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | semmle.label | ControlFlowNode for pam_authenticate() | subpaths #select -| pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | This PAM authentication depends on a $@, and 'pam_acct_mgmt' is not called afterwards. | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected index 0ee851ac1cb..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected +++ b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected @@ -1,23 +1,4 @@ edges -| unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | -| unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | -| unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | -| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | -| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | -| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | -| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | nodes -| unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | -| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | -| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | -| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | subpaths #select -| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | -| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | -| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | -| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected index 5be1168abd6..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected +++ b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected @@ -1,63 +1,4 @@ edges -| test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:1:26:1:32 | GSSA Variable request | -| test.py:1:26:1:32 | GSSA Variable request | test.py:7:14:7:20 | ControlFlowNode for request | -| test.py:1:26:1:32 | GSSA Variable request | test.py:30:17:30:23 | ControlFlowNode for request | -| test.py:1:26:1:32 | GSSA Variable request | test.py:37:17:37:23 | ControlFlowNode for request | -| test.py:1:26:1:32 | GSSA Variable request | test.py:44:17:44:23 | ControlFlowNode for request | -| test.py:1:26:1:32 | GSSA Variable request | test.py:60:17:60:23 | ControlFlowNode for request | -| test.py:1:26:1:32 | GSSA Variable request | test.py:67:17:67:23 | ControlFlowNode for request | -| test.py:1:26:1:32 | GSSA Variable request | test.py:74:17:74:23 | ControlFlowNode for request | -| test.py:1:26:1:32 | GSSA Variable request | test.py:81:17:81:23 | ControlFlowNode for request | -| test.py:7:14:7:20 | ControlFlowNode for request | test.py:7:14:7:25 | ControlFlowNode for Attribute | -| test.py:7:14:7:25 | ControlFlowNode for Attribute | test.py:8:21:8:26 | ControlFlowNode for target | -| test.py:30:17:30:23 | ControlFlowNode for request | test.py:30:17:30:28 | ControlFlowNode for Attribute | -| test.py:30:17:30:28 | ControlFlowNode for Attribute | test.py:32:21:32:24 | ControlFlowNode for safe | -| test.py:37:17:37:23 | ControlFlowNode for request | test.py:37:17:37:28 | ControlFlowNode for Attribute | -| test.py:37:17:37:28 | ControlFlowNode for Attribute | test.py:39:21:39:24 | ControlFlowNode for safe | -| test.py:44:17:44:23 | ControlFlowNode for request | test.py:44:17:44:28 | ControlFlowNode for Attribute | -| test.py:44:17:44:28 | ControlFlowNode for Attribute | test.py:46:21:46:24 | ControlFlowNode for safe | -| test.py:60:17:60:23 | ControlFlowNode for request | test.py:60:17:60:28 | ControlFlowNode for Attribute | -| test.py:60:17:60:28 | ControlFlowNode for Attribute | test.py:62:21:62:26 | ControlFlowNode for unsafe | -| test.py:67:17:67:23 | ControlFlowNode for request | test.py:67:17:67:28 | ControlFlowNode for Attribute | -| test.py:67:17:67:28 | ControlFlowNode for Attribute | test.py:69:21:69:26 | ControlFlowNode for unsafe | -| test.py:74:17:74:23 | ControlFlowNode for request | test.py:74:17:74:28 | ControlFlowNode for Attribute | -| test.py:74:17:74:28 | ControlFlowNode for Attribute | test.py:76:21:76:26 | ControlFlowNode for unsafe | -| test.py:81:17:81:23 | ControlFlowNode for request | test.py:81:17:81:28 | ControlFlowNode for Attribute | -| test.py:81:17:81:28 | ControlFlowNode for Attribute | test.py:83:21:83:26 | ControlFlowNode for unsafe | nodes -| test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| test.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| test.py:7:14:7:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:7:14:7:25 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:8:21:8:26 | ControlFlowNode for target | semmle.label | ControlFlowNode for target | -| test.py:30:17:30:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:30:17:30:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:32:21:32:24 | ControlFlowNode for safe | semmle.label | ControlFlowNode for safe | -| test.py:37:17:37:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:37:17:37:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:39:21:39:24 | ControlFlowNode for safe | semmle.label | ControlFlowNode for safe | -| test.py:44:17:44:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:44:17:44:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:46:21:46:24 | ControlFlowNode for safe | semmle.label | ControlFlowNode for safe | -| test.py:60:17:60:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:60:17:60:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:62:21:62:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | -| test.py:67:17:67:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:67:17:67:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:69:21:69:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | -| test.py:74:17:74:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:74:17:74:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:76:21:76:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | -| test.py:81:17:81:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:81:17:81:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:83:21:83:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | subpaths #select -| test.py:8:21:8:26 | ControlFlowNode for target | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:8:21:8:26 | ControlFlowNode for target | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:32:21:32:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:32:21:32:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:39:21:39:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:39:21:39:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:46:21:46:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:46:21:46:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:62:21:62:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:62:21:62:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:69:21:69:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:69:21:69:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:76:21:76:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:76:21:76:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:83:21:83:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:83:21:83:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected index 94a74b9baef..649dc8e5415 100644 --- a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected @@ -2,49 +2,11 @@ edges | xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | -| xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:2:26:2:32 | GSSA Variable request | -| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | -| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | -| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | -| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | -| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | -| xpathFlow.py:11:18:11:24 | ControlFlowNode for request | xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | -| xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | -| xpathFlow.py:20:18:20:24 | ControlFlowNode for request | xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | -| xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | -| xpathFlow.py:30:18:30:24 | ControlFlowNode for request | xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | -| xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | -| xpathFlow.py:39:18:39:24 | ControlFlowNode for request | xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | -| xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | -| xpathFlow.py:47:18:47:24 | ControlFlowNode for request | xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | -| xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | nodes | xpathBad.py:9:7:9:13 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| xpathFlow.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| xpathFlow.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | -| xpathFlow.py:20:18:20:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | -| xpathFlow.py:30:18:30:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | -| xpathFlow.py:39:18:39:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | -| xpathFlow.py:47:18:47:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | subpaths #select | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | XPath expression depends on a $@. | xpathBad.py:9:7:9:13 | ControlFlowNode for request | user-provided value | -| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected index 6ff7710ef50..e217064d1df 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected @@ -1,30 +1,4 @@ edges -| test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:2:26:2:32 | GSSA Variable request | -| test.py:2:26:2:32 | GSSA Variable request | test.py:7:12:7:18 | ControlFlowNode for request | -| test.py:7:12:7:18 | ControlFlowNode for request | test.py:7:12:7:23 | ControlFlowNode for Attribute | -| test.py:7:12:7:23 | ControlFlowNode for Attribute | test.py:8:30:8:33 | ControlFlowNode for text | -| test.py:7:12:7:23 | ControlFlowNode for Attribute | test.py:9:32:9:35 | ControlFlowNode for text | -| test.py:7:12:7:23 | ControlFlowNode for Attribute | test.py:12:17:12:20 | ControlFlowNode for text | -| test.py:7:12:7:23 | ControlFlowNode for Attribute | test.py:18:28:18:31 | ControlFlowNode for text | -| test.py:7:12:7:23 | ControlFlowNode for Attribute | test.py:21:18:21:21 | ControlFlowNode for text | -| test.py:14:33:14:39 | ControlFlowNode for my_text | test.py:16:24:16:30 | ControlFlowNode for my_text | -| test.py:18:28:18:31 | ControlFlowNode for text | test.py:14:33:14:39 | ControlFlowNode for my_text | nodes -| test.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| test.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| test.py:7:12:7:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| test.py:7:12:7:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:8:30:8:33 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | -| test.py:9:32:9:35 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | -| test.py:12:17:12:20 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | -| test.py:14:33:14:39 | ControlFlowNode for my_text | semmle.label | ControlFlowNode for my_text | -| test.py:16:24:16:30 | ControlFlowNode for my_text | semmle.label | ControlFlowNode for my_text | -| test.py:18:28:18:31 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | -| test.py:21:18:21:21 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | subpaths #select -| test.py:8:30:8:33 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:8:30:8:33 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:8:21:8:23 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:9:32:9:35 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with '0.9' and with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:12:17:12:20 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:12:17:12:20 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:11:31:11:33 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:16:24:16:30 | ControlFlowNode for my_text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:16:24:16:30 | ControlFlowNode for my_text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:18:23:18:25 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:21:18:21:21 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:21:18:21:21 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | test.py:20:273:20:274 | .* | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | From 144df9a39e4616509c4ccfe8b762cf0c9d91751f Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 23 May 2023 14:21:37 +0200 Subject: [PATCH 139/739] python: remove explicit dataflow steps --- .../dataflow/new/internal/DataFlowPrivate.qll | 49 ------------------- .../experimental/dataflow/coverage/test.py | 10 ++-- .../dataflow/coverage/test_builtins.py | 16 +++--- .../dataflow/fieldflow/test_dict.py | 6 +-- .../UnsafeUnpack.expected | 4 +- 5 files changed, 17 insertions(+), 68 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 693a2f13fc4..cb80d7500aa 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -792,14 +792,10 @@ predicate defaultValueFlowStep(CfgNode nodeFrom, CfgNode nodeTo) { predicate readStep(Node nodeFrom, Content c, Node nodeTo) { subscriptReadStep(nodeFrom, c, nodeTo) or - dictReadStep(nodeFrom, c, nodeTo) - or iterableUnpackingReadStep(nodeFrom, c, nodeTo) or matchReadStep(nodeFrom, c, nodeTo) or - popReadStep(nodeFrom, c, nodeTo) - or forReadStep(nodeFrom, c, nodeTo) or attributeReadStep(nodeFrom, c, nodeTo) @@ -832,51 +828,6 @@ predicate subscriptReadStep(CfgNode nodeFrom, Content c, CfgNode nodeTo) { ) } -predicate dictReadStep(CfgNode nodeFrom, Content c, CfgNode nodeTo) { - // see - // - https://docs.python.org/3.10/library/stdtypes.html#dict.get - // - https://docs.python.org/3.10/library/stdtypes.html#dict.setdefault - exists(MethodCallNode call | - call.calls(nodeFrom, ["get", "setdefault"]) and - call.getArg(0).asExpr().(StrConst).getText() = c.(DictionaryElementContent).getKey() and - nodeTo = call - ) -} - -/** Data flows from a sequence to a call to `pop` on the sequence. */ -predicate popReadStep(CfgNode nodeFrom, Content c, CfgNode nodeTo) { - // set.pop or list.pop - // `s.pop()` - // nodeFrom is `s`, cfg node - // nodeTo is `s.pop()`, cfg node - // c denotes element of list or set - exists(CallNode call, AttrNode a | - call.getFunction() = a and - a.getName() = "pop" and // Should match appropriate call since we tracked a sequence here. - not exists(call.getAnArg()) and - nodeFrom.getNode() = a.getObject() and - nodeTo.getNode() = call and - ( - c instanceof ListElementContent - or - c instanceof SetElementContent - ) - ) - or - // dict.pop - // `d.pop("key")` - // nodeFrom is `d`, cfg node - // nodeTo is `d.pop("key")`, cfg node - // c denotes the key `"key"` - exists(CallNode call, AttrNode a | - call.getFunction() = a and - a.getName() = "pop" and // Should match appropriate call since we tracked a dictionary here. - nodeFrom.getNode() = a.getObject() and - nodeTo.getNode() = call and - c.(DictionaryElementContent).getKey() = call.getArg(0).getNode().(StrConst).getS() - ) -} - predicate forReadStep(CfgNode nodeFrom, Content c, Node nodeTo) { exists(ForTarget target | nodeFrom.asExpr() = target.getSource() and diff --git a/python/ql/test/experimental/dataflow/coverage/test.py b/python/ql/test/experimental/dataflow/coverage/test.py index f35339e4dca..66dacb79b22 100644 --- a/python/ql/test/experimental/dataflow/coverage/test.py +++ b/python/ql/test/experimental/dataflow/coverage/test.py @@ -123,23 +123,23 @@ def test_nested_list_display(): # 6.2.6. Set displays def test_set_display(): x = {SOURCE} - SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()" + SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()" def test_set_comprehension(): x = {SOURCE for y in [NONSOURCE]} - SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()" + SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()" def test_set_comprehension_flow(): x = {y for y in [SOURCE]} - SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()" + SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()" def test_set_comprehension_inflow(): l = {SOURCE} x = {y for y in l} - SINK(x.pop()) #$ flow="SOURCE, l:-2 -> x.pop()" + SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-2 -> x.pop()" def test_nested_set_display(): @@ -155,7 +155,7 @@ def test_dict_display(): def test_dict_display_pop(): x = {"s": SOURCE} - SINK(x.pop("s")) #$ flow="SOURCE, l:-1 -> x.pop(..)" + SINK(x.pop("s")) #$ MISSING:flow="SOURCE, l:-1 -> x.pop(..)" def test_dict_comprehension(): diff --git a/python/ql/test/experimental/dataflow/coverage/test_builtins.py b/python/ql/test/experimental/dataflow/coverage/test_builtins.py index 4a3ee95fedf..340853176e5 100644 --- a/python/ql/test/experimental/dataflow/coverage/test_builtins.py +++ b/python/ql/test/experimental/dataflow/coverage/test_builtins.py @@ -100,19 +100,19 @@ def test_set_from_list(): l = [SOURCE] s = set(l) v = s.pop() - SINK(v) #$ flow="SOURCE, l:-3 -> v" + SINK(v) #$ MISSING:flow="SOURCE, l:-3 -> v" def test_set_from_tuple(): t = (SOURCE,) s = set(t) v = s.pop() - SINK(v) #$ flow="SOURCE, l:-3 -> v" + SINK(v) #$ MISSING:flow="SOURCE, l:-3 -> v" def test_set_from_set(): s0 = {SOURCE} s = set(s0) v = s.pop() - SINK(v) #$ flow="SOURCE, l:-3 -> v" + SINK(v) #$ MISSING:flow="SOURCE, l:-3 -> v" def test_set_from_dict(): d = {SOURCE: "val"} @@ -149,7 +149,7 @@ def test_dict_from_dict(): def test_list_pop(): l = [SOURCE] v = l.pop() - SINK(v) #$ flow="SOURCE, l:-2 -> v" + SINK(v) #$ MISSING:flow="SOURCE, l:-2 -> v" def test_list_pop_index(): l = [SOURCE] @@ -178,7 +178,7 @@ def test_list_append(): def test_set_pop(): s = {SOURCE} v = s.pop() - SINK(v) #$ flow="SOURCE, l:-2 -> v" + SINK(v) #$ MISSING:flow="SOURCE, l:-2 -> v" def test_set_copy(): s0 = {SOURCE} @@ -218,9 +218,9 @@ def test_dict_items(): def test_dict_pop(): d = {'k': SOURCE} v = d.pop("k") - SINK(v) #$ flow="SOURCE, l:-2 -> v" + SINK(v) #$ MISSING:flow="SOURCE, l:-2 -> v" v1 = d.pop("k", NONSOURCE) - SINK_F(v1) #$ SPURIOUS: flow="SOURCE, l:-4 -> v1" + SINK_F(v1) v2 = d.pop("non-existing", SOURCE) SINK(v2) #$ MISSING: flow="SOURCE, l:-1 -> v2" @@ -228,7 +228,7 @@ def test_dict_pop(): def test_dict_get(): d = {'k': SOURCE} v = d.get("k") - SINK(v) #$ flow="SOURCE, l:-2 -> v" + SINK(v) #$ MISSING:flow="SOURCE, l:-2 -> v" v1 = d.get("non-existing", SOURCE) SINK(v1) #$ MISSING: flow="SOURCE, l:-1 -> v1" diff --git a/python/ql/test/experimental/dataflow/fieldflow/test_dict.py b/python/ql/test/experimental/dataflow/fieldflow/test_dict.py index c2f74b83c3d..87526c8dd01 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/test_dict.py +++ b/python/ql/test/experimental/dataflow/fieldflow/test_dict.py @@ -35,7 +35,7 @@ def SINK_F(x): def test_dict_literal(): d = {"key": SOURCE} SINK(d["key"]) # $ flow="SOURCE, l:-1 -> d['key']" - SINK(d.get("key")) # $ flow="SOURCE, l:-2 -> d.get(..)" + SINK(d.get("key")) # $ MISSING:flow="SOURCE, l:-2 -> d.get(..)" @expects(2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) @@ -43,7 +43,7 @@ def test_dict_update(): d = {} d["key"] = SOURCE SINK(d["key"]) # $ flow="SOURCE, l:-1 -> d['key']" - SINK(d.get("key")) # $ flow="SOURCE, l:-2 -> d.get(..)" + SINK(d.get("key")) # $ MISSING:flow="SOURCE, l:-2 -> d.get(..)" @expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) def test_dict_setdefault(): @@ -51,7 +51,7 @@ def test_dict_setdefault(): x = d.setdefault("key", SOURCE) SINK(x) # $ flow="SOURCE, l:-1 -> x" SINK(d["key"]) # $ flow="SOURCE, l:-2 -> d['key']" - SINK(d.setdefault("key", NONSOURCE)) # $ flow="SOURCE, l:-3 -> d.setdefault(..)" + SINK(d.setdefault("key", NONSOURCE)) # $ MISSING:flow="SOURCE, l:-3 -> d.setdefault(..)" @expects(2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) def test_dict_override(): diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index 3439034aff6..2dd571d0d41 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -2,8 +2,7 @@ edges | UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for ImportMember | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | -| UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | -| UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | +| UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | | UnsafeUnpack.py:33:50:33:65 | ControlFlowNode for local_ziped_path | UnsafeUnpack.py:34:23:34:38 | ControlFlowNode for local_ziped_path | | UnsafeUnpack.py:47:20:47:34 | ControlFlowNode for compressed_file | UnsafeUnpack.py:48:23:48:37 | ControlFlowNode for compressed_file | @@ -31,7 +30,6 @@ nodes | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | semmle.label | ControlFlowNode for tarpath | | UnsafeUnpack.py:33:50:33:65 | ControlFlowNode for local_ziped_path | semmle.label | ControlFlowNode for local_ziped_path | From 9cb83fcdc92eaf73a6f0d405d1856a4a5254515d Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 23 May 2023 14:22:52 +0200 Subject: [PATCH 140/739] python: add summaries for copy, pop, get, getitem, setdefault Also add read steps to taint tracking. Reading from a tainted collection can be done in two situations: 1. There is an acces path In this case a read step (possibly from a flow summary) gives rise to a taint step. 2. There is no access path In this case an explicit taint step (possibly via a flow summary) should exist. --- .../new/internal/TaintTrackingPrivate.qll | 13 ++ .../lib/semmle/python/frameworks/Stdlib.qll | 204 ++++++++++++++++++ .../experimental/dataflow/coverage/test.py | 10 +- .../dataflow/coverage/test_builtins.py | 34 +-- .../dataflow/fieldflow/test_dict.py | 6 +- .../test_collections.py | 2 +- .../test_collections.py | 4 +- .../UnsafeUnpack.expected | 6 + .../Security/CWE-1236/CsvInjection.expected | 10 +- .../frameworks/aiohttp/taint_test.py | 4 +- .../frameworks/django-v2-v3/taint_forms.py | 4 +- .../frameworks/django-v2-v3/taint_test.py | 18 +- .../frameworks/flask/taint_test.py | 20 +- .../frameworks/multidict/taint_test.py | 8 +- .../frameworks/requests/taint_test.py | 6 +- .../frameworks/rest_framework/taint_test.py | 6 +- .../frameworks/stdlib/http_server.py | 2 +- .../frameworks/twisted/taint_test.py | 6 +- ...ExternalAPIsUsedWithUntrustedData.expected | 4 + .../UntrustedDataToExternalAPI.expected | 57 +++++ .../PathInjection.expected | 191 ++++++++++++++++ .../flask_path_injection.py | 2 +- .../CWE-022-PathInjection/path_injection.py | 22 +- .../CWE-022-PathInjection/pathlib_use.py | 4 +- .../Security/CWE-022-PathInjection/test.py | 8 +- .../CommandInjection.expected | 36 ++++ .../CommandInjection.expected | 90 ++++++++ .../command_injection.py | 26 +-- .../ReflectedXss.expected | 9 + .../CodeInjection.expected | 27 +++ .../LogInjection.expected | 39 ++++ .../PamAuthorization.expected | 12 ++ .../UnsafeDeserialization.expected | 21 ++ .../CWE-601-UrlRedirect/UrlRedirect.expected | 75 +++++++ .../XpathInjection.expected | 48 +++++ .../PolynomialReDoS.expected | 28 +++ 36 files changed, 963 insertions(+), 99 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 78fb529b05a..423ba24e432 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -202,6 +202,19 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { obj = nodeTo.(DataFlow::PostUpdateNode).getPreUpdateNode() and call.getArg(0) = nodeFrom ) + or + // Although flow through collections is modeled precisely using stores/reads, we still + // allow flow out of a _tainted_ collection. This is needed in order to support taint- + // tracking configurations where the source is a collection. + exists(DataFlow::Content c | DataFlowPrivate::readStep(nodeFrom, c, nodeTo) | + // c instanceof DataFlow::ListElementContent + // or + // c instanceof DataFlow::SetElementContent + // or + c instanceof DataFlow::DictionaryElementContent + // or + // c instanceof DataFlow::DictionaryElementAnyContent + ) } /** diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index cd5ec31945e..b4412909cf1 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -3939,6 +3939,176 @@ private module StdlibPrivate { } } + // --------------------------------------------------------------------------- + // Flow summaries for container methods + // --------------------------------------------------------------------------- + /** A flow summary for `copy`. */ + class CopySummary extends SummarizedCallable { + CopySummary() { this = "collection.copy" } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).getMethodName() = "copy" + } + + override DataFlow::ArgumentNode getACallback() { none() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + exists(string content | + content = "ListElement" + or + content = "SetElement" + or + exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() | + content = "TupleElement[" + i.toString() + "]" + ) + or + exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | + content = "DictionaryElement[" + key + "]" + ) + | + input = "Argument[self]." + content and + output = "ReturnValue." + content and + preservesValue = true + ) + or + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** + * A flow summary for `pop` either for list or set. + * This ignores the index if given, since content is + * imprecise anyway. + * + * I also handles the default value when `pop` is called + * on a dictionary, since that also does not depend on the key. + */ + class PopSummary extends SummarizedCallable { + PopSummary() { this = "collection.pop" } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).getMethodName() = "pop" + } + + override DataFlow::ArgumentNode getACallback() { none() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self].ListElement" and + output = "ReturnValue" and + preservesValue = true + or + input = "Argument[self].SetElement" and + output = "ReturnValue" and + preservesValue = true + or + // default value for dictionary + input = "Argument[1]" and + output = "ReturnValue" and + preservesValue = true + or + // transfer taint on self to return value + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** A flow summary for `dict.pop` */ + class DictPopSummary extends SummarizedCallable { + string key; + + DictPopSummary() { + this = "dict.pop(" + key + ")" and + exists(DataFlow::DictionaryElementContent dc | key = dc.getKey()) + } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).getMethodName() = "pop" and + result.getArg(0).getALocalSource().asExpr().(StrConst).getText() = key + } + + override DataFlow::ArgumentNode getACallback() { none() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self].DictionaryElement[" + key + "]" and + output = "ReturnValue" and + preservesValue = true + } + } + + /** A flow summary for `dict.get` at specific content. */ + class DictGetSummary extends SummarizedCallable { + string key; + + DictGetSummary() { + this = "dict.get(" + key + ")" and + exists(DataFlow::DictionaryElementContent dc | key = dc.getKey()) + } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).getMethodName() = "get" and + result.getArg(0).getALocalSource().asExpr().(StrConst).getText() = key + } + + override DataFlow::ArgumentNode getACallback() { none() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self].DictionaryElement[" + key + "]" and + output = "ReturnValue" and + preservesValue = true + or + // optional default value + input = "Argument[1]" and + output = "ReturnValue" and + preservesValue = true + } + } + + /** A flow summary for `dict.get` disregarding content. */ + class DictGetAnySummary extends SummarizedCallable { + DictGetAnySummary() { this = "dict.get" } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).getMethodName() = "get" + } + + override DataFlow::ArgumentNode getACallback() { none() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + // default value + input = "Argument[1]" and + output = "ReturnValue" and + preservesValue = true + or + // transfer taint from self to return value + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** A flow summary for `dict.popitem` */ + class DictPopitemSummary extends SummarizedCallable { + DictPopitemSummary() { this = "dict.popitem" } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).getMethodName() = "popitem" + } + + override DataFlow::ArgumentNode getACallback() { none() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | + input = "Argument[self].DictionaryElement[" + key + "]" and + output = "ReturnValue.TupleElement[1]" and + preservesValue = true + // TODO: put `key` into "ReturnValue.TupleElement[0]" + ) + } + } + /** * A flow summary for `dict.setdefault`. * @@ -3962,6 +4132,40 @@ private module StdlibPrivate { preservesValue = true } } + + /** + * A flow summary for `dict.setdefault` at specifi key. + * See https://docs.python.org/3.10/library/stdtypes.html#dict.setdefault + * This summary handles read and store steps. See `DictSetdefaultSummary` + * for the dataflow steps. + */ + class DictSetdefaultKeySummary extends SummarizedCallable { + string key; + + DictSetdefaultKeySummary() { + this = "dict.setdefault(" + key + ")" and + exists(DataFlow::DictionaryElementContent dc | key = dc.getKey()) + } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).getMethodName() = "setdefault" and + result.getArg(0).getALocalSource().asExpr().(StrConst).getText() = key + } + + override DataFlow::ArgumentNode getACallback() { none() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + // If key is in the dictionary, return its value. + input = "Argument[self].DictionaryElement[" + key + "]" and + output = "ReturnValue" and + preservesValue = true + or + // If not, insert key with a value of default. + input = "Argument[1]" and + output = "ReturnValue.DictionaryElement[" + key + "]" and + preservesValue = true + } + } } // --------------------------------------------------------------------------- diff --git a/python/ql/test/experimental/dataflow/coverage/test.py b/python/ql/test/experimental/dataflow/coverage/test.py index 66dacb79b22..f35339e4dca 100644 --- a/python/ql/test/experimental/dataflow/coverage/test.py +++ b/python/ql/test/experimental/dataflow/coverage/test.py @@ -123,23 +123,23 @@ def test_nested_list_display(): # 6.2.6. Set displays def test_set_display(): x = {SOURCE} - SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()" + SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()" def test_set_comprehension(): x = {SOURCE for y in [NONSOURCE]} - SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()" + SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()" def test_set_comprehension_flow(): x = {y for y in [SOURCE]} - SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-1 -> x.pop()" + SINK(x.pop()) #$ flow="SOURCE, l:-1 -> x.pop()" def test_set_comprehension_inflow(): l = {SOURCE} x = {y for y in l} - SINK(x.pop()) #$ MISSING:flow="SOURCE, l:-2 -> x.pop()" + SINK(x.pop()) #$ flow="SOURCE, l:-2 -> x.pop()" def test_nested_set_display(): @@ -155,7 +155,7 @@ def test_dict_display(): def test_dict_display_pop(): x = {"s": SOURCE} - SINK(x.pop("s")) #$ MISSING:flow="SOURCE, l:-1 -> x.pop(..)" + SINK(x.pop("s")) #$ flow="SOURCE, l:-1 -> x.pop(..)" def test_dict_comprehension(): diff --git a/python/ql/test/experimental/dataflow/coverage/test_builtins.py b/python/ql/test/experimental/dataflow/coverage/test_builtins.py index 340853176e5..301871cfc61 100644 --- a/python/ql/test/experimental/dataflow/coverage/test_builtins.py +++ b/python/ql/test/experimental/dataflow/coverage/test_builtins.py @@ -100,19 +100,19 @@ def test_set_from_list(): l = [SOURCE] s = set(l) v = s.pop() - SINK(v) #$ MISSING:flow="SOURCE, l:-3 -> v" + SINK(v) #$ flow="SOURCE, l:-3 -> v" def test_set_from_tuple(): t = (SOURCE,) s = set(t) v = s.pop() - SINK(v) #$ MISSING:flow="SOURCE, l:-3 -> v" + SINK(v) #$ flow="SOURCE, l:-3 -> v" def test_set_from_set(): s0 = {SOURCE} s = set(s0) v = s.pop() - SINK(v) #$ MISSING:flow="SOURCE, l:-3 -> v" + SINK(v) #$ flow="SOURCE, l:-3 -> v" def test_set_from_dict(): d = {SOURCE: "val"} @@ -149,24 +149,24 @@ def test_dict_from_dict(): def test_list_pop(): l = [SOURCE] v = l.pop() - SINK(v) #$ MISSING:flow="SOURCE, l:-2 -> v" + SINK(v) #$ flow="SOURCE, l:-2 -> v" def test_list_pop_index(): l = [SOURCE] v = l.pop(0) - SINK(v) #$ MISSING: flow="SOURCE, l:-2 -> v" + SINK(v) #$ flow="SOURCE, l:-2 -> v" def test_list_pop_index_imprecise(): l = [SOURCE, NONSOURCE] v = l.pop(1) - SINK_F(v) + SINK_F(v) #$ SPURIOUS: flow="SOURCE, l:-2 -> v" @expects(2) def test_list_copy(): l0 = [SOURCE, NONSOURCE] l = l0.copy() - SINK(l[0]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]" - SINK_F(l[1]) + SINK(l[0]) #$ flow="SOURCE, l:-2 -> l[0]" + SINK_F(l[1]) #$ SPURIOUS: flow="SOURCE, l:-3 -> l[1]" def test_list_append(): l = [NONSOURCE] @@ -178,12 +178,12 @@ def test_list_append(): def test_set_pop(): s = {SOURCE} v = s.pop() - SINK(v) #$ MISSING:flow="SOURCE, l:-2 -> v" + SINK(v) #$ flow="SOURCE, l:-2 -> v" def test_set_copy(): s0 = {SOURCE} s = s0.copy() - SINK(s.pop()) #$ MISSING: flow="SOURCE, l:-2 -> s.pop()" + SINK(s.pop()) #$ flow="SOURCE, l:-2 -> s.pop()" def test_set_add(): s = set([]) @@ -218,32 +218,32 @@ def test_dict_items(): def test_dict_pop(): d = {'k': SOURCE} v = d.pop("k") - SINK(v) #$ MISSING:flow="SOURCE, l:-2 -> v" + SINK(v) #$ flow="SOURCE, l:-2 -> v" v1 = d.pop("k", NONSOURCE) - SINK_F(v1) + SINK_F(v1) #$ SPURIOUS: flow="SOURCE, l:-4 -> v1" v2 = d.pop("non-existing", SOURCE) - SINK(v2) #$ MISSING: flow="SOURCE, l:-1 -> v2" + SINK(v2) #$ flow="SOURCE, l:-1 -> v2" @expects(2) def test_dict_get(): d = {'k': SOURCE} v = d.get("k") - SINK(v) #$ MISSING:flow="SOURCE, l:-2 -> v" + SINK(v) #$ flow="SOURCE, l:-2 -> v" v1 = d.get("non-existing", SOURCE) - SINK(v1) #$ MISSING: flow="SOURCE, l:-1 -> v1" + SINK(v1) #$ flow="SOURCE, l:-1 -> v1" @expects(2) def test_dict_popitem(): d = {'k': SOURCE} t = d.popitem() # could be any pair (before 3.7), but we only have one SINK_F(t[0]) - SINK(t[1]) #$ MISSING: flow="SOURCE, l:-3 -> t[1]" + SINK(t[1]) #$ flow="SOURCE, l:-3 -> t[1]" @expects(2) def test_dict_copy(): d = {'k': SOURCE, 'k1': NONSOURCE} d1 = d.copy() - SINK(d1["k"]) #$ MISSING: flow="SOURCE, l:-2 -> d[k]" + SINK(d1["k"]) #$ flow="SOURCE, l:-2 -> d1['k']" SINK_F(d1["k1"]) diff --git a/python/ql/test/experimental/dataflow/fieldflow/test_dict.py b/python/ql/test/experimental/dataflow/fieldflow/test_dict.py index 87526c8dd01..c2f74b83c3d 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/test_dict.py +++ b/python/ql/test/experimental/dataflow/fieldflow/test_dict.py @@ -35,7 +35,7 @@ def SINK_F(x): def test_dict_literal(): d = {"key": SOURCE} SINK(d["key"]) # $ flow="SOURCE, l:-1 -> d['key']" - SINK(d.get("key")) # $ MISSING:flow="SOURCE, l:-2 -> d.get(..)" + SINK(d.get("key")) # $ flow="SOURCE, l:-2 -> d.get(..)" @expects(2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) @@ -43,7 +43,7 @@ def test_dict_update(): d = {} d["key"] = SOURCE SINK(d["key"]) # $ flow="SOURCE, l:-1 -> d['key']" - SINK(d.get("key")) # $ MISSING:flow="SOURCE, l:-2 -> d.get(..)" + SINK(d.get("key")) # $ flow="SOURCE, l:-2 -> d.get(..)" @expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) def test_dict_setdefault(): @@ -51,7 +51,7 @@ def test_dict_setdefault(): x = d.setdefault("key", SOURCE) SINK(x) # $ flow="SOURCE, l:-1 -> x" SINK(d["key"]) # $ flow="SOURCE, l:-2 -> d['key']" - SINK(d.setdefault("key", NONSOURCE)) # $ MISSING:flow="SOURCE, l:-3 -> d.setdefault(..)" + SINK(d.setdefault("key", NONSOURCE)) # $ flow="SOURCE, l:-3 -> d.setdefault(..)" @expects(2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..) def test_dict_override(): diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py index a2a89a403e0..ec3a3b419cc 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_collections.py @@ -13,7 +13,7 @@ def test_access(): tainted_list = TAINTED_LIST ensure_tainted( - tainted_list.copy(), # $ MISSING: tainted + tainted_list.copy(), # $ tainted ) for ((x, y, *z), a, b) in tainted_list: diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index 746c0d469f7..50f9a613f9b 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -103,9 +103,9 @@ def test_dict_access(x): ensure_tainted( tainted_dict["name"], # $ tainted - tainted_dict.get("name"), # $ MISSING: tainted + tainted_dict.get("name"), # $ tainted tainted_dict[x], # $ tainted - tainted_dict.copy(), # $ MISSING: tainted + tainted_dict.copy(), # $ tainted ) for v in tainted_dict.values(): diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index 2dd571d0d41..f32d3037bbc 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -2,7 +2,9 @@ edges | UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for ImportMember | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | +| UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | +| UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | | UnsafeUnpack.py:33:50:33:65 | ControlFlowNode for local_ziped_path | UnsafeUnpack.py:34:23:34:38 | ControlFlowNode for local_ziped_path | | UnsafeUnpack.py:47:20:47:34 | ControlFlowNode for compressed_file | UnsafeUnpack.py:48:23:48:37 | ControlFlowNode for compressed_file | @@ -14,7 +16,9 @@ edges | UnsafeUnpack.py:103:23:103:27 | SSA variable chunk | UnsafeUnpack.py:105:35:105:42 | ControlFlowNode for savepath | | UnsafeUnpack.py:103:32:103:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:103:32:103:54 | ControlFlowNode for Subscript | | UnsafeUnpack.py:103:32:103:54 | ControlFlowNode for Subscript | UnsafeUnpack.py:103:23:103:27 | SSA variable chunk | +| UnsafeUnpack.py:108:22:108:34 | ControlFlowNode for Attribute | UnsafeUnpack.py:108:22:108:48 | ControlFlowNode for Attribute() | | UnsafeUnpack.py:108:22:108:34 | ControlFlowNode for Attribute | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | +| UnsafeUnpack.py:108:22:108:48 | ControlFlowNode for Attribute() | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | | UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | UnsafeUnpack.py:118:38:118:47 | ControlFlowNode for Attribute | | UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | | UnsafeUnpack.py:118:38:118:47 | ControlFlowNode for Attribute | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | @@ -30,6 +34,7 @@ nodes | UnsafeUnpack.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:17:27:17:38 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | semmle.label | ControlFlowNode for tarpath | | UnsafeUnpack.py:33:50:33:65 | ControlFlowNode for local_ziped_path | semmle.label | ControlFlowNode for local_ziped_path | @@ -48,6 +53,7 @@ nodes | UnsafeUnpack.py:103:32:103:54 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | UnsafeUnpack.py:105:35:105:42 | ControlFlowNode for savepath | semmle.label | ControlFlowNode for savepath | | UnsafeUnpack.py:108:22:108:34 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| UnsafeUnpack.py:108:22:108:48 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | semmle.label | ControlFlowNode for file_path | | UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | semmle.label | SSA variable ufile | | UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected index 558882458d5..06eb5f3b71b 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected @@ -3,19 +3,23 @@ edges | csv_bad.py:9:19:9:25 | GSSA Variable request | csv_bad.py:16:16:16:22 | ControlFlowNode for request | | csv_bad.py:9:19:9:25 | GSSA Variable request | csv_bad.py:24:16:24:22 | ControlFlowNode for request | | csv_bad.py:16:16:16:22 | ControlFlowNode for request | csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | -| csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | -| csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | +| csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | csv_bad.py:16:16:16:38 | ControlFlowNode for Attribute() | +| csv_bad.py:16:16:16:38 | ControlFlowNode for Attribute() | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | +| csv_bad.py:16:16:16:38 | ControlFlowNode for Attribute() | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | | csv_bad.py:24:16:24:22 | ControlFlowNode for request | csv_bad.py:24:16:24:27 | ControlFlowNode for Attribute | -| csv_bad.py:24:16:24:27 | ControlFlowNode for Attribute | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | +| csv_bad.py:24:16:24:27 | ControlFlowNode for Attribute | csv_bad.py:24:16:24:38 | ControlFlowNode for Attribute() | +| csv_bad.py:24:16:24:38 | ControlFlowNode for Attribute() | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | nodes | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | csv_bad.py:9:19:9:25 | GSSA Variable request | semmle.label | GSSA Variable request | | csv_bad.py:16:16:16:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | csv_bad.py:16:16:16:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| csv_bad.py:16:16:16:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | semmle.label | ControlFlowNode for csv_data | | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | semmle.label | ControlFlowNode for csv_data | | csv_bad.py:24:16:24:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | csv_bad.py:24:16:24:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| csv_bad.py:24:16:24:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | semmle.label | ControlFlowNode for csv_data | subpaths #select diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index 3efbc39c431..ec475a592ab 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -23,7 +23,7 @@ async def test_taint(request: web.Request): # $ requestHandler # dict-like for captured parts of the URL request.match_info, # $ tainted request.match_info["key"], # $ tainted - request.match_info.get("key"), # $ MISSING: tainted + request.match_info.get("key"), # $ tainted # multidict.MultiDictProxy[str] (see `multidict` framework tests) request.query, # $ tainted @@ -38,7 +38,7 @@ async def test_taint(request: web.Request): # $ requestHandler # dict-like (readonly) request.cookies, # $ tainted request.cookies["key"], # $ tainted - request.cookies.get("key"), # $ MISSING: tainted + request.cookies.get("key"), # $ tainted request.cookies.keys(), # $ MISSING: tainted request.cookies.values(), # $ tainted request.cookies.items(), # $ tainted diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/taint_forms.py b/python/ql/test/library-tests/frameworks/django-v2-v3/taint_forms.py index 4f4bf40ebef..66021b64d29 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/taint_forms.py +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/taint_forms.py @@ -32,13 +32,13 @@ class MyForm(django.forms.Form): ensure_tainted( cleaned_data, # $ tainted cleaned_data["key"], # $ tainted - cleaned_data.get("key"), # $ MISSING: tainted + cleaned_data.get("key"), # $ tainted ) ensure_tainted( self.cleaned_data, # $ tainted self.cleaned_data["key"], # $ tainted - self.cleaned_data.get("key"), # $ MISSING: tainted + self.cleaned_data.get("key"), # $ tainted ) def clean_foo(self): diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py b/python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py index 7d56f6fc944..aa6f78be509 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/taint_test.py @@ -31,17 +31,17 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou # Dict[str, str] request.content_params, # $ tainted request.content_params["key"], # $ tainted - request.content_params.get("key"), # $ MISSING: tainted + request.content_params.get("key"), # $ tainted # django.http.QueryDict # see https://docs.djangoproject.com/en/3.0/ref/request-response/#querydict-objects request.GET, # $ tainted request.GET["key"], # $ tainted - request.GET.get("key"), # $ MISSING: tainted + request.GET.get("key"), # $ tainted request.GET.getlist("key"), # $ tainted request.GET.getlist("key")[0], # $ tainted - request.GET.pop("key"), # $ MISSING: tainted - request.GET.pop("key")[0], # $ MISSING: tainted + request.GET.pop("key"), # $ tainted + request.GET.pop("key")[0], # $ tainted # key request.GET.popitem()[0], # $ tainted # values @@ -59,7 +59,7 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou # Dict[str, str] request.COOKIES, # $ tainted request.COOKIES["key"], # $ tainted - request.COOKIES.get("key"), # $ MISSING: tainted + request.COOKIES.get("key"), # $ tainted # MultiValueDict[str, UploadedFile] request.FILES, # $ tainted @@ -73,20 +73,20 @@ def test_taint(request: HttpRequest, foo, bar, baz=None): # $requestHandler rou request.FILES["key"].file.read(), # $ tainted request.FILES["key"].read(), # $ tainted - request.FILES.get("key"), # $ MISSING: tainted - request.FILES.get("key").name, # $ MISSING:tainted + request.FILES.get("key"), # $ tainted + request.FILES.get("key").name, # $ tainted request.FILES.getlist("key"), # $ tainted request.FILES.getlist("key")[0], # $ tainted request.FILES.getlist("key")[0].name, # $ tainted request.FILES.dict(), # $ tainted request.FILES.dict()["key"], # $ tainted request.FILES.dict()["key"].name, # $ tainted - request.FILES.dict().get("key").name, # $ MISSING: tainted + request.FILES.dict().get("key").name, # $ tainted # Dict[str, Any] request.META, # $ tainted request.META["HTTP_USER_AGENT"], # $ tainted - request.META.get("HTTP_USER_AGENT"), # $ MISSING: tainted + request.META.get("HTTP_USER_AGENT"), # $ tainted # HttpHeaders (case insensitive dict-like) request.headers, # $ tainted diff --git a/python/ql/test/library-tests/frameworks/flask/taint_test.py b/python/ql/test/library-tests/frameworks/flask/taint_test.py index bbbbd747834..dcca8ff6681 100644 --- a/python/ql/test/library-tests/frameworks/flask/taint_test.py +++ b/python/ql/test/library-tests/frameworks/flask/taint_test.py @@ -12,7 +12,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route ensure_tainted( request.environ, # $ tainted - request.environ.get('HTTP_AUTHORIZATION'), # $ MISSING: tainted + request.environ.get('HTTP_AUTHORIZATION'), # $ tainted request.path, # $ tainted request.full_path, # $ tainted @@ -38,7 +38,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # By default werkzeug.datastructures.ImmutableMultiDict -- although can be changed :\ request.args, # $ tainted request.args['key'], # $ tainted - request.args.get('key'), # $ MISSING: tainted + request.args.get('key'), # $ tainted request.args.getlist('key'), # $ tainted # werkzeug.datastructures.Authorization (a dict, with some properties) @@ -81,9 +81,9 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route request.files['key'].stream, # $ tainted request.files['key'].read(), # $ tainted request.files['key'].stream.read(), # $ tainted - request.files.get('key'), # $ MISSING: tainted - request.files.get('key').filename, # $ MISSING: tainted - request.files.get('key').stream, # $ MISSING: tainted + request.files.get('key'), # $ tainted + request.files.get('key').filename, # $ tainted + request.files.get('key').stream, # $ tainted request.files.getlist('key'), # $ tainted request.files.getlist('key')[0].filename, # $ tainted request.files.getlist('key')[0].stream, # $ tainted @@ -91,7 +91,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # By default werkzeug.datastructures.ImmutableMultiDict -- although can be changed :\ request.form, # $ tainted request.form['key'], # $ tainted - request.form.get('key'), # $ MISSING: tainted + request.form.get('key'), # $ tainted request.form.getlist('key'), # $ tainted request.get_data(), # $ tainted @@ -104,7 +104,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # which has same interface as werkzeug.datastructures.Headers request.headers, # $ tainted request.headers['key'], # $ tainted - request.headers.get('key'), # $ MISSING: tainted + request.headers.get('key'), # $ tainted request.headers.get_all('key'), # $ tainted request.headers.getlist('key'), # $ tainted # popitem returns `(key, value)` @@ -149,13 +149,13 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route # werkzeug.datastructures.CombinedMultiDict, which is basically just a werkzeug.datastructures.MultiDict request.values, # $ tainted request.values['key'], # $ tainted - request.values.get('key'), # $ MISSING: tainted + request.values.get('key'), # $ tainted request.values.getlist('key'), # $ tainted # dict request.view_args, # $ tainted request.view_args['key'], # $ tainted - request.view_args.get('key'), # $ MISSING: tainted + request.view_args.get('key'), # $ tainted ) ensure_not_tainted( @@ -204,7 +204,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route b.getlist('key'), # $ tainted gl('key'), # $ tainted - files.get('key').filename, # $ MISSING: tainted + files.get('key').filename, # $ tainted ) # aliasing tests diff --git a/python/ql/test/library-tests/frameworks/multidict/taint_test.py b/python/ql/test/library-tests/frameworks/multidict/taint_test.py index 8001bfe5c22..8fbac79888f 100644 --- a/python/ql/test/library-tests/frameworks/multidict/taint_test.py +++ b/python/ql/test/library-tests/frameworks/multidict/taint_test.py @@ -9,13 +9,13 @@ ensure_tainted( mdp, # $ tainted mdp["key"], # $ tainted - mdp.get("key"), # $ MISSING: tainted + mdp.get("key"), # $ tainted mdp.getone("key"), # $ tainted mdp.getall("key"), # $ tainted mdp.keys(), # $ MISSING: tainted mdp.values(), # $ tainted mdp.items(), # $ tainted - mdp.copy(), # $ MISSING: tainted + mdp.copy(), # $ tainted list(mdp), # $ tainted iter(mdp), # $ tainted ) @@ -29,13 +29,13 @@ ensure_tainted( ci_mdp, # $ tainted ci_mdp["key"], # $ tainted - ci_mdp.get("key"), # $ MISSING: tainted + ci_mdp.get("key"), # $ tainted ci_mdp.getone("key"), # $ tainted ci_mdp.getall("key"), # $ tainted ci_mdp.keys(), # $ MISSING: tainted ci_mdp.values(), # $ tainted ci_mdp.items(), # $ tainted - ci_mdp.copy(), # $ MISSING: tainted + ci_mdp.copy(), # $ tainted list(ci_mdp), # $ tainted iter(ci_mdp), # $ tainted ) diff --git a/python/ql/test/library-tests/frameworks/requests/taint_test.py b/python/ql/test/library-tests/frameworks/requests/taint_test.py index 11b781ffd11..48ff417baa7 100644 --- a/python/ql/test/library-tests/frameworks/requests/taint_test.py +++ b/python/ql/test/library-tests/frameworks/requests/taint_test.py @@ -30,15 +30,15 @@ def test_taint(): # $ requestHandler resp.links, # $ tainted resp.links['key'], # $ tainted - resp.links.get('key'), # $ MISSING: tainted + resp.links.get('key'), # $ tainted resp.cookies, # $ tainted resp.cookies['key'], # $ tainted - resp.cookies.get('key'), # $ MISSING: tainted + resp.cookies.get('key'), # $ tainted resp.headers, # $ tainted resp.headers['key'], # $ tainted - resp.headers.get('key'), # $ MISSING: tainted + resp.headers.get('key'), # $ tainted ) for content_chunk in resp.iter_content(): diff --git a/python/ql/test/library-tests/frameworks/rest_framework/taint_test.py b/python/ql/test/library-tests/frameworks/rest_framework/taint_test.py index b839c392b51..4a22e03b563 100644 --- a/python/ql/test/library-tests/frameworks/rest_framework/taint_test.py +++ b/python/ql/test/library-tests/frameworks/rest_framework/taint_test.py @@ -31,11 +31,11 @@ def test_taint(request: Request, routed_param): # $ requestHandler routedParamet # alias for .GET request.query_params, # $ tainted request.query_params["key"], # $ tainted - request.query_params.get("key"), # $ MISSING: tainted + request.query_params.get("key"), # $ tainted request.query_params.getlist("key"), # $ tainted request.query_params.getlist("key")[0], # $ tainted - request.query_params.pop("key"), # $ MISSING: tainted - request.query_params.pop("key")[0], # $ MISSING: tainted + request.query_params.pop("key"), # $ tainted + request.query_params.pop("key")[0], # $ tainted # see more detailed tests of `request.user` below request.user, # $ tainted diff --git a/python/ql/test/library-tests/frameworks/stdlib/http_server.py b/python/ql/test/library-tests/frameworks/stdlib/http_server.py index 0ec21bf5e20..27ec2211f4b 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/http_server.py +++ b/python/ql/test/library-tests/frameworks/stdlib/http_server.py @@ -57,7 +57,7 @@ class MyHandler(BaseHTTPRequestHandler): self.headers, # $ tainted self.headers['Foo'], # $ tainted - self.headers.get('Foo'), # $ MISSING: tainted + self.headers.get('Foo'), # $ tainted self.headers.get_all('Foo'), # $ tainted self.headers.keys(), # $ tainted self.headers.values(), # $ tainted diff --git a/python/ql/test/library-tests/frameworks/twisted/taint_test.py b/python/ql/test/library-tests/frameworks/twisted/taint_test.py index b48ab10e075..cdc6592f90e 100644 --- a/python/ql/test/library-tests/frameworks/twisted/taint_test.py +++ b/python/ql/test/library-tests/frameworks/twisted/taint_test.py @@ -26,12 +26,12 @@ class MyTaintTest(Resource): request.args, # $ tainted request.args[b"key"], # $ tainted request.args[b"key"][0], # $ tainted - request.args.get(b"key"), # $ MISSING: tainted - request.args.get(b"key")[0], # $ MISSING: tainted + request.args.get(b"key"), # $ tainted + request.args.get(b"key")[0], # $ tainted request.received_cookies, # $ tainted request.received_cookies["key"], # $ tainted - request.received_cookies.get("key"), # $ MISSING: tainted + request.received_cookies.get("key"), # $ tainted request.getCookie(b"key"), # $ tainted # twisted.web.http_headers.Headers diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected index e69de29bb2d..a346aef9d22 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected @@ -0,0 +1,4 @@ +| hmac.new [keyword msg] | 1 | 1 | +| hmac.new [position 1] | 1 | 1 | +| unknown.lib.func [keyword kw] | 2 | 1 | +| unknown.lib.func [position 0] | 2 | 1 | diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected index e217064d1df..14048735594 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected @@ -1,4 +1,61 @@ edges +| test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:5:26:5:32 | GSSA Variable request | +| test.py:5:26:5:32 | GSSA Variable request | test.py:13:16:13:22 | ControlFlowNode for request | +| test.py:5:26:5:32 | GSSA Variable request | test.py:23:16:23:22 | ControlFlowNode for request | +| test.py:5:26:5:32 | GSSA Variable request | test.py:34:12:34:18 | ControlFlowNode for request | +| test.py:5:26:5:32 | GSSA Variable request | test.py:42:12:42:18 | ControlFlowNode for request | +| test.py:5:26:5:32 | GSSA Variable request | test.py:54:12:54:18 | ControlFlowNode for request | +| test.py:13:16:13:22 | ControlFlowNode for request | test.py:13:16:13:27 | ControlFlowNode for Attribute | +| test.py:13:16:13:27 | ControlFlowNode for Attribute | test.py:13:16:13:39 | ControlFlowNode for Attribute() | +| test.py:13:16:13:39 | ControlFlowNode for Attribute() | test.py:15:36:15:39 | ControlFlowNode for data | +| test.py:23:16:23:22 | ControlFlowNode for request | test.py:23:16:23:27 | ControlFlowNode for Attribute | +| test.py:23:16:23:27 | ControlFlowNode for Attribute | test.py:23:16:23:39 | ControlFlowNode for Attribute() | +| test.py:23:16:23:39 | ControlFlowNode for Attribute() | test.py:25:44:25:47 | ControlFlowNode for data | +| test.py:34:12:34:18 | ControlFlowNode for request | test.py:34:12:34:23 | ControlFlowNode for Attribute | +| test.py:34:12:34:23 | ControlFlowNode for Attribute | test.py:34:12:34:35 | ControlFlowNode for Attribute() | +| test.py:34:12:34:35 | ControlFlowNode for Attribute() | test.py:35:10:35:13 | ControlFlowNode for data | +| test.py:34:12:34:35 | ControlFlowNode for Attribute() | test.py:36:13:36:16 | ControlFlowNode for data | +| test.py:42:12:42:18 | ControlFlowNode for request | test.py:42:12:42:23 | ControlFlowNode for Attribute | +| test.py:42:12:42:23 | ControlFlowNode for Attribute | test.py:42:12:42:35 | ControlFlowNode for Attribute() | +| test.py:42:12:42:35 | ControlFlowNode for Attribute() | test.py:43:22:43:25 | ControlFlowNode for data | +| test.py:42:12:42:35 | ControlFlowNode for Attribute() | test.py:44:25:44:28 | ControlFlowNode for data | +| test.py:47:17:47:19 | ControlFlowNode for arg | test.py:50:32:50:34 | ControlFlowNode for arg | +| test.py:54:12:54:18 | ControlFlowNode for request | test.py:54:12:54:23 | ControlFlowNode for Attribute | +| test.py:54:12:54:23 | ControlFlowNode for Attribute | test.py:54:12:54:35 | ControlFlowNode for Attribute() | +| test.py:54:12:54:35 | ControlFlowNode for Attribute() | test.py:55:17:55:20 | ControlFlowNode for data | +| test.py:55:17:55:20 | ControlFlowNode for data | test.py:47:17:47:19 | ControlFlowNode for arg | nodes +| test.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test.py:13:16:13:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:13:16:13:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:13:16:13:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:15:36:15:39 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +| test.py:23:16:23:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:23:16:23:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:23:16:23:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:25:44:25:47 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +| test.py:34:12:34:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:34:12:34:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:34:12:34:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:35:10:35:13 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +| test.py:36:13:36:16 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +| test.py:42:12:42:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:42:12:42:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:42:12:42:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:43:22:43:25 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +| test.py:44:25:44:28 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +| test.py:47:17:47:19 | ControlFlowNode for arg | semmle.label | ControlFlowNode for arg | +| test.py:50:32:50:34 | ControlFlowNode for arg | semmle.label | ControlFlowNode for arg | +| test.py:54:12:54:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:54:12:54:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:54:12:54:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:55:17:55:20 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | subpaths #select +| test.py:15:36:15:39 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [position 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | +| test.py:25:44:25:47 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:25:44:25:47 | ControlFlowNode for data | Call to hmac.new [keyword msg] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | +| test.py:35:10:35:13 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:35:10:35:13 | ControlFlowNode for data | Call to unknown.lib.func [position 0] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | +| test.py:36:13:36:16 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:36:13:36:16 | ControlFlowNode for data | Call to unknown.lib.func [keyword kw] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | +| test.py:43:22:43:25 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:43:22:43:25 | ControlFlowNode for data | Call to unknown.lib.func [position 0] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | +| test.py:44:25:44:28 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:44:25:44:28 | ControlFlowNode for data | Call to unknown.lib.func [keyword kw] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected b/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected index da9eb4a10d7..f907f96930b 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected @@ -1,12 +1,203 @@ edges +| flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_path_injection.py:1:26:1:32 | GSSA Variable request | +| flask_path_injection.py:1:26:1:32 | GSSA Variable request | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | +| flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | +| flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | flask_path_injection.py:19:15:19:45 | ControlFlowNode for Attribute() | +| flask_path_injection.py:19:15:19:45 | ControlFlowNode for Attribute() | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | +| path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:3:26:3:32 | GSSA Variable request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:12:16:12:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:19:16:19:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:27:16:27:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:46:16:46:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:63:16:63:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:84:16:84:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:107:16:107:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:118:16:118:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:129:16:129:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:138:16:138:22 | ControlFlowNode for request | +| path_injection.py:3:26:3:32 | GSSA Variable request | path_injection.py:149:16:149:22 | ControlFlowNode for request | +| path_injection.py:12:16:12:22 | ControlFlowNode for request | path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | +| path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | path_injection.py:12:16:12:47 | ControlFlowNode for Attribute() | +| path_injection.py:12:16:12:47 | ControlFlowNode for Attribute() | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | +| path_injection.py:19:16:19:22 | ControlFlowNode for request | path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | +| path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | path_injection.py:19:16:19:47 | ControlFlowNode for Attribute() | +| path_injection.py:19:16:19:47 | ControlFlowNode for Attribute() | path_injection.py:20:30:20:63 | ControlFlowNode for Attribute() | +| path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() | path_injection.py:21:14:21:18 | ControlFlowNode for npath | +| path_injection.py:20:30:20:63 | ControlFlowNode for Attribute() | path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() | +| path_injection.py:27:16:27:22 | ControlFlowNode for request | path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | +| path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | path_injection.py:27:16:27:47 | ControlFlowNode for Attribute() | +| path_injection.py:27:16:27:47 | ControlFlowNode for Attribute() | path_injection.py:28:30:28:63 | ControlFlowNode for Attribute() | +| path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() | path_injection.py:31:14:31:18 | ControlFlowNode for npath | +| path_injection.py:28:30:28:63 | ControlFlowNode for Attribute() | path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() | +| path_injection.py:46:16:46:22 | ControlFlowNode for request | path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | +| path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | path_injection.py:46:16:46:47 | ControlFlowNode for Attribute() | +| path_injection.py:46:16:46:47 | ControlFlowNode for Attribute() | path_injection.py:47:30:47:63 | ControlFlowNode for Attribute() | +| path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() | path_injection.py:48:14:48:18 | ControlFlowNode for npath | +| path_injection.py:47:30:47:63 | ControlFlowNode for Attribute() | path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() | +| path_injection.py:63:16:63:22 | ControlFlowNode for request | path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | +| path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | path_injection.py:63:16:63:47 | ControlFlowNode for Attribute() | +| path_injection.py:63:16:63:47 | ControlFlowNode for Attribute() | path_injection.py:64:29:64:62 | ControlFlowNode for Attribute() | +| path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | path_injection.py:65:14:65:18 | ControlFlowNode for npath | +| path_injection.py:64:29:64:62 | ControlFlowNode for Attribute() | path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | +| path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | +| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() | +| path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path | | path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path | +| path_injection.py:107:16:107:22 | ControlFlowNode for request | path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | +| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | path_injection.py:107:16:107:47 | ControlFlowNode for Attribute() | +| path_injection.py:107:16:107:47 | ControlFlowNode for Attribute() | path_injection.py:113:14:113:17 | ControlFlowNode for path | +| path_injection.py:118:16:118:22 | ControlFlowNode for request | path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | +| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | path_injection.py:118:16:118:47 | ControlFlowNode for Attribute() | +| path_injection.py:118:16:118:47 | ControlFlowNode for Attribute() | path_injection.py:124:14:124:17 | ControlFlowNode for path | +| path_injection.py:129:16:129:22 | ControlFlowNode for request | path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | +| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | path_injection.py:129:16:129:47 | ControlFlowNode for Attribute() | +| path_injection.py:129:16:129:47 | ControlFlowNode for Attribute() | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | +| path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | +| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() | +| path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() | path_injection.py:142:14:142:17 | ControlFlowNode for path | +| path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | +| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | path_injection.py:149:16:149:47 | ControlFlowNode for Attribute() | +| path_injection.py:149:16:149:47 | ControlFlowNode for Attribute() | path_injection.py:152:18:152:21 | ControlFlowNode for path | +| pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | pathlib_use.py:3:26:3:32 | GSSA Variable request | +| pathlib_use.py:3:26:3:32 | GSSA Variable request | pathlib_use.py:12:16:12:22 | ControlFlowNode for request | +| pathlib_use.py:12:16:12:22 | ControlFlowNode for request | pathlib_use.py:12:16:12:27 | ControlFlowNode for Attribute | +| pathlib_use.py:12:16:12:27 | ControlFlowNode for Attribute | pathlib_use.py:12:16:12:47 | ControlFlowNode for Attribute() | +| pathlib_use.py:12:16:12:47 | ControlFlowNode for Attribute() | pathlib_use.py:14:5:14:5 | ControlFlowNode for p | +| pathlib_use.py:12:16:12:47 | ControlFlowNode for Attribute() | pathlib_use.py:17:5:17:6 | ControlFlowNode for p2 | +| test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:3:26:3:32 | GSSA Variable request | +| test.py:3:26:3:32 | GSSA Variable request | test.py:9:12:9:18 | ControlFlowNode for request | +| test.py:9:12:9:18 | ControlFlowNode for request | test.py:9:12:9:23 | ControlFlowNode for Attribute | +| test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() | +| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:18:9:18:16 | ControlFlowNode for source() | +| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:24:9:24:16 | ControlFlowNode for source() | +| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:31:9:31:16 | ControlFlowNode for source() | +| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:46:9:46:16 | ControlFlowNode for source() | +| test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:29:13:29 | ControlFlowNode for x | +| test.py:13:29:13:29 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | +| test.py:18:9:18:16 | ControlFlowNode for source() | test.py:19:10:19:10 | ControlFlowNode for x | +| test.py:24:9:24:16 | ControlFlowNode for source() | test.py:25:19:25:19 | ControlFlowNode for x | +| test.py:25:9:25:20 | ControlFlowNode for normalize() | test.py:26:10:26:10 | ControlFlowNode for y | +| test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | +| test.py:25:19:25:19 | ControlFlowNode for x | test.py:25:9:25:20 | ControlFlowNode for normalize() | +| test.py:31:9:31:16 | ControlFlowNode for source() | test.py:33:14:33:14 | ControlFlowNode for x | +| test.py:46:9:46:16 | ControlFlowNode for source() | test.py:48:23:48:23 | ControlFlowNode for x | +| test.py:48:13:48:24 | ControlFlowNode for normalize() | test.py:49:14:49:14 | ControlFlowNode for y | +| test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | +| test.py:48:23:48:23 | ControlFlowNode for x | test.py:48:13:48:24 | ControlFlowNode for normalize() | nodes +| flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_path_injection.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| flask_path_injection.py:19:15:19:45 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | semmle.label | ControlFlowNode for dirname | +| path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| path_injection.py:3:26:3:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| path_injection.py:12:16:12:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:12:16:12:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:19:16:19:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:19:16:19:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:20:30:20:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:21:14:21:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath | +| path_injection.py:27:16:27:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:27:16:27:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:28:30:28:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:31:14:31:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath | +| path_injection.py:46:16:46:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:46:16:46:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:47:30:47:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:48:14:48:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath | +| path_injection.py:63:16:63:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:63:16:63:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:64:29:64:62 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:65:14:65:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath | +| path_injection.py:84:16:84:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:84:16:84:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path | | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | semmle.label | ControlFlowNode for foo_id | | path_injection.py:94:14:94:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | path_injection.py:98:20:98:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | | path_injection.py:102:14:102:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| path_injection.py:107:16:107:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:107:16:107:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:113:14:113:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| path_injection.py:118:16:118:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:118:16:118:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:124:14:124:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| path_injection.py:129:16:129:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:129:16:129:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | semmle.label | ControlFlowNode for sanitized | +| path_injection.py:138:16:138:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:138:16:138:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:142:14:142:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| path_injection.py:149:16:149:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| path_injection.py:149:16:149:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| path_injection.py:152:18:152:21 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| pathlib_use.py:3:26:3:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| pathlib_use.py:12:16:12:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| pathlib_use.py:12:16:12:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| pathlib_use.py:12:16:12:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| pathlib_use.py:14:5:14:5 | ControlFlowNode for p | semmle.label | ControlFlowNode for p | +| pathlib_use.py:17:5:17:6 | ControlFlowNode for p2 | semmle.label | ControlFlowNode for p2 | +| test.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:3:26:3:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:12:15:12:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:13:12:13:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:13:29:13:29 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:18:9:18:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | +| test.py:19:10:19:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:24:9:24:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | +| test.py:25:9:25:20 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() | +| test.py:25:19:25:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:26:10:26:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | +| test.py:31:9:31:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | +| test.py:33:14:33:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:46:9:46:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | +| test.py:48:13:48:24 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() | +| test.py:48:23:48:23 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:49:14:49:14 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | subpaths +| test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:25:9:25:20 | ControlFlowNode for normalize() | +| test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:48:13:48:24 | ControlFlowNode for normalize() | #select +| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | This path depends on a $@. | flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:21:14:21:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:21:14:21:18 | ControlFlowNode for npath | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:31:14:31:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:31:14:31:18 | ControlFlowNode for npath | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:48:14:48:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:48:14:48:18 | ControlFlowNode for npath | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:65:14:65:18 | ControlFlowNode for npath | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:65:14:65:18 | ControlFlowNode for npath | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | | path_injection.py:94:14:94:17 | ControlFlowNode for path | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | user-provided value | | path_injection.py:102:14:102:17 | ControlFlowNode for path | path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:98:20:98:22 | ControlFlowNode for foo | user-provided value | +| path_injection.py:113:14:113:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:113:14:113:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:124:14:124:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:124:14:124:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:142:14:142:17 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:142:14:142:17 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| path_injection.py:152:18:152:21 | ControlFlowNode for path | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | path_injection.py:152:18:152:21 | ControlFlowNode for path | This path depends on a $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| pathlib_use.py:14:5:14:5 | ControlFlowNode for p | pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | pathlib_use.py:14:5:14:5 | ControlFlowNode for p | This path depends on a $@. | pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| pathlib_use.py:17:5:17:6 | ControlFlowNode for p2 | pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | pathlib_use.py:17:5:17:6 | ControlFlowNode for p2 | This path depends on a $@. | pathlib_use.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:19:10:19:10 | ControlFlowNode for x | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:19:10:19:10 | ControlFlowNode for x | This path depends on a $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:26:10:26:10 | ControlFlowNode for y | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:26:10:26:10 | ControlFlowNode for y | This path depends on a $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:33:14:33:14 | ControlFlowNode for x | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:33:14:33:14 | ControlFlowNode for x | This path depends on a $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:49:14:49:14 | ControlFlowNode for y | test.py:3:26:3:32 | ControlFlowNode for ImportMember | test.py:49:14:49:14 | ControlFlowNode for y | This path depends on a $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/flask_path_injection.py b/python/ql/test/query-tests/Security/CWE-022-PathInjection/flask_path_injection.py index d0ad06aa323..f64d76a3b4d 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/flask_path_injection.py +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/flask_path_injection.py @@ -18,4 +18,4 @@ def download_file(): def download_file(): dirname = request.args.get('dirname', '') filename = request.args.get('filename', '') - return send_from_directory(dirname, filename) # $ result=OK(filename) MISSING: result=BAD + return send_from_directory(dirname, filename) # $result=BAD result=OK(filename) diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py b/python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py index bf8bfef44b5..39c17037480 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py @@ -10,7 +10,7 @@ STATIC_DIR = "/server/static/" @app.route("/path1") def path_injection(): filename = request.args.get('filename', '') - f = open(os.path.join(STATIC_DIR, filename)) # $ MISSING: result=BAD + f = open(os.path.join(STATIC_DIR, filename)) # $result=BAD @app.route("/path2") @@ -18,7 +18,7 @@ def path_injection(): # Normalized, but not checked filename = request.args.get('filename', '') npath = os.path.normpath(os.path.join(STATIC_DIR, filename)) - f = open(npath) # $ MISSING: result=BAD + f = open(npath) # $result=BAD @app.route("/path3") @@ -28,7 +28,7 @@ def unsafe_path_normpath(): npath = os.path.normpath(os.path.join(STATIC_DIR, filename)) if npath.startswith(STATIC_DIR): pass - f = open(npath) # $ MISSING: result=BAD + f = open(npath) # $result=BAD @app.route("/path4") @@ -45,7 +45,7 @@ def unsafe_path_realpath(): # Normalized (by `realpath` that also follows symlinks), but not checked properly filename = request.args.get('filename', '') npath = os.path.realpath(os.path.join(STATIC_DIR, filename)) - f = open(npath) # $ MISSING: result=BAD + f = open(npath) # $result=BAD @app.route("/path6") @@ -62,7 +62,7 @@ def unsafe_path_abspath(): # Normalized (by `abspath`), but not checked properly filename = request.args.get('filename', '') npath = os.path.abspath(os.path.join(STATIC_DIR, filename)) - f = open(npath) # $ MISSING: result=BAD + f = open(npath) # $result=BAD @app.route("/path7") @@ -84,7 +84,7 @@ def safe_path_abspath_tricky(): filename = request.args.get('filename', '') possibly_unsafe_path = os.path.join(STATIC_DIR, filename) if os.path.abspath(possibly_unsafe_path).startswith(STATIC_DIR): - f = open(possibly_unsafe_path) # $ result=OK + f = open(possibly_unsafe_path) # $SPURIOUS: result=BAD @app.route("/int-only/<int:foo_id>") @@ -110,7 +110,7 @@ def no_dot_dot(): # handle if `filename` is an absolute path if '../' in path: return "not this time" - f = open(path) # $ MISSING: result=BAD + f = open(path) # $result=BAD @app.route("/no-dot-dot-with-prefix") @@ -121,7 +121,7 @@ def no_dot_dot_with_prefix(): # Therefore, for UNIX-only programs, the `../` check is enough to stop path injections. if '../' in path: return "not this time" - f = open(path) # $ MISSING: result=BAD // OK if only running on UNIX systems, NOT OK if could be running on windows + f = open(path) # $result=BAD // OK if only running on UNIX systems, NOT OK if could be running on windows @app.route("/replace-slash") @@ -129,7 +129,7 @@ def replace_slash(): filename = request.args.get('filename', '') path = os.path.join(STATIC_DIR, filename) sanitized = path.replace("/", "_") - f = open(sanitized) # $ MISSING: result=BAD // OK if only running on UNIX systems, NOT OK if could be running on windows + f = open(sanitized) # $result=BAD // OK if only running on UNIX systems, NOT OK if could be running on windows @app.route("/stackoverflow-solution") @@ -139,7 +139,7 @@ def stackoverflow_solution(): path = os.path.join(STATIC_DIR, filename) if os.path.commonprefix((os.path.realpath(path), STATIC_DIR)) != STATIC_DIR: return "not this time" - f = open(path) # $ result=OK + f = open(path) # $SPURIOUS: result=BAD SAFE_FILES = ['foo', 'bar', 'baz'] @@ -149,4 +149,4 @@ def safe_set_of_files(): filename = request.args.get('filename', '') if filename in SAFE_FILES: path = os.path.join(STATIC_DIR, filename) - f = open(path) # $ result=OK + f = open(path) # $SPURIOUS: result=BAD diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/pathlib_use.py b/python/ql/test/query-tests/Security/CWE-022-PathInjection/pathlib_use.py index c9d60ef9969..6f703f903dc 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/pathlib_use.py +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/pathlib_use.py @@ -11,7 +11,7 @@ STATIC_DIR = pathlib.Path("/server/static/") def path_injection(): filename = request.args.get('filename', '') p = STATIC_DIR / filename - p.open() # $ MISSING: result=BAD + p.open() # $ result=BAD p2 = pathlib.Path(STATIC_DIR, filename) - p2.open() # $ MISSING: result=BAD + p2.open() # $ result=BAD diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/test.py b/python/ql/test/query-tests/Security/CWE-022-PathInjection/test.py index ed080f7d5c6..7200cd78f45 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/test.py +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/test.py @@ -16,21 +16,21 @@ def normalize(x): @app.route("/path") def simple(): x = source() - open(x) # $ MISSING: result=BAD + open(x) # $result=BAD @app.route("/path") def normalization(): x = source() y = normalize(x) - open(y) # $ MISSING: result=BAD + open(y) # $result=BAD @app.route("/path") def check(): x = source() if x.startswith("subfolder/"): - open(x) # $ MISSING: result=BAD + open(x) # $result=BAD @app.route("/path") @@ -46,4 +46,4 @@ def check_then_normalize(): x = source() if x.startswith("subfolder/"): y = normalize(x) - open(y) # $ MISSING: result=BAD + open(y) # $result=BAD diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected index e217064d1df..2cf670a65e5 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected @@ -1,4 +1,40 @@ edges +| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:5:26:5:32 | GSSA Variable request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:18:13:18:19 | ControlFlowNode for request | +| command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | +| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | nodes +| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| command_injection.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| command_injection.py:18:13:18:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select +| command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected index e217064d1df..db33e40d9d8 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected @@ -1,4 +1,94 @@ edges +| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:5:26:5:32 | GSSA Variable request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:11:13:11:19 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:18:13:18:19 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:25:11:25:17 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:31:13:31:19 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:38:15:38:21 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:54:15:54:21 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:71:12:71:18 | ControlFlowNode for request | +| command_injection.py:5:26:5:32 | GSSA Variable request | command_injection.py:78:12:78:18 | ControlFlowNode for request | +| command_injection.py:11:13:11:19 | ControlFlowNode for request | command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | +| command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | command_injection.py:11:13:11:41 | ControlFlowNode for Attribute() | +| command_injection.py:11:13:11:41 | ControlFlowNode for Attribute() | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | +| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | +| command_injection.py:25:11:25:17 | ControlFlowNode for request | command_injection.py:25:11:25:22 | ControlFlowNode for Attribute | +| command_injection.py:25:11:25:22 | ControlFlowNode for Attribute | command_injection.py:25:11:25:37 | ControlFlowNode for Attribute() | +| command_injection.py:25:11:25:37 | ControlFlowNode for Attribute() | command_injection.py:26:23:26:25 | ControlFlowNode for cmd | +| command_injection.py:31:13:31:19 | ControlFlowNode for request | command_injection.py:31:13:31:24 | ControlFlowNode for Attribute | +| command_injection.py:31:13:31:24 | ControlFlowNode for Attribute | command_injection.py:31:13:31:41 | ControlFlowNode for Attribute() | +| command_injection.py:31:13:31:41 | ControlFlowNode for Attribute() | command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | +| command_injection.py:38:15:38:21 | ControlFlowNode for request | command_injection.py:38:15:38:26 | ControlFlowNode for Attribute | +| command_injection.py:38:15:38:26 | ControlFlowNode for Attribute | command_injection.py:38:15:38:45 | ControlFlowNode for Attribute() | +| command_injection.py:38:15:38:45 | ControlFlowNode for Attribute() | command_injection.py:41:15:41:21 | ControlFlowNode for command | +| command_injection.py:38:15:38:45 | ControlFlowNode for Attribute() | command_injection.py:42:15:42:21 | ControlFlowNode for command | +| command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | +| command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | command_injection.py:54:15:54:45 | ControlFlowNode for Attribute() | +| command_injection.py:54:15:54:45 | ControlFlowNode for Attribute() | command_injection.py:55:15:55:21 | ControlFlowNode for command | +| command_injection.py:54:15:54:45 | ControlFlowNode for Attribute() | command_injection.py:56:14:56:20 | ControlFlowNode for command | +| command_injection.py:54:15:54:45 | ControlFlowNode for Attribute() | command_injection.py:57:21:57:27 | ControlFlowNode for command | +| command_injection.py:54:15:54:45 | ControlFlowNode for Attribute() | command_injection.py:58:27:58:33 | ControlFlowNode for command | +| command_injection.py:54:15:54:45 | ControlFlowNode for Attribute() | command_injection.py:59:20:59:26 | ControlFlowNode for command | +| command_injection.py:71:12:71:18 | ControlFlowNode for request | command_injection.py:71:12:71:23 | ControlFlowNode for Attribute | +| command_injection.py:71:12:71:23 | ControlFlowNode for Attribute | command_injection.py:71:12:71:39 | ControlFlowNode for Attribute() | +| command_injection.py:71:12:71:39 | ControlFlowNode for Attribute() | command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | +| command_injection.py:78:12:78:18 | ControlFlowNode for request | command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | +| command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | command_injection.py:78:12:78:39 | ControlFlowNode for Attribute() | +| command_injection.py:78:12:78:39 | ControlFlowNode for Attribute() | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | nodes +| command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| command_injection.py:5:26:5:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| command_injection.py:11:13:11:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:11:13:11:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:11:13:11:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:18:13:18:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:18:13:18:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:25:11:25:17 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:25:11:25:22 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:25:11:25:37 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:26:23:26:25 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | +| command_injection.py:31:13:31:19 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:31:13:31:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:31:13:31:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:38:15:38:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:38:15:38:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:38:15:38:45 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:41:15:41:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | +| command_injection.py:42:15:42:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | +| command_injection.py:54:15:54:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:54:15:54:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:54:15:54:45 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:55:15:55:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | +| command_injection.py:56:14:56:20 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | +| command_injection.py:57:21:57:27 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | +| command_injection.py:58:27:58:33 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | +| command_injection.py:59:20:59:26 | ControlFlowNode for command | semmle.label | ControlFlowNode for command | +| command_injection.py:71:12:71:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:71:12:71:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:71:12:71:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| command_injection.py:78:12:78:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| command_injection.py:78:12:78:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select +| command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:26:23:26:25 | ControlFlowNode for cmd | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:26:23:26:25 | ControlFlowNode for cmd | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:41:15:41:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:41:15:41:21 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:42:15:42:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:42:15:42:21 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:55:15:55:21 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:55:15:55:21 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:56:14:56:20 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:56:14:56:20 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:57:21:57:27 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:57:21:57:27 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:58:27:58:33 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:58:27:58:33 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:59:20:59:26 | ControlFlowNode for command | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:59:20:59:26 | ControlFlowNode for command | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | +| command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | This command line depends on a $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/command_injection.py b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/command_injection.py index 64b622acd72..c969a1b1020 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/command_injection.py +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/command_injection.py @@ -10,27 +10,27 @@ app = Flask(__name__) def command_injection1(): files = request.args.get('files', '') # Don't let files be `; rm -rf /` - os.system("ls " + files) # $ MISSING: result=BAD + os.system("ls " + files) # $result=BAD @app.route("/command2") def command_injection2(): files = request.args.get('files', '') # Don't let files be `; rm -rf /` - subprocess.Popen("ls " + files, shell=True) # $ MISSING: result=BAD + subprocess.Popen("ls " + files, shell=True) # $result=BAD @app.route("/command3") def first_arg_injection(): cmd = request.args.get('cmd', '') - subprocess.Popen([cmd, "param1"]) # $ MISSING: result=BAD + subprocess.Popen([cmd, "param1"]) # $result=BAD @app.route("/other_cases") def others(): files = request.args.get('files', '') # Don't let files be `; rm -rf /` - os.popen("ls " + files) # $ MISSING: result=BAD + os.popen("ls " + files) # $result=BAD @app.route("/multiple") @@ -38,8 +38,8 @@ def multiple(): command = request.args.get('command', '') # We should mark flow to both calls here, which conflicts with removing flow out of # a sink due to use-use flow. - os.system(command) # $ MISSING: result=BAD - os.system(command) # $ MISSING: result=BAD + os.system(command) # $result=BAD + os.system(command) # $result=BAD @app.route("/not-into-sink-impl") @@ -52,11 +52,11 @@ def not_into_sink_impl(): subprocess.call implementation: https://github.com/python/cpython/blob/fa7ce080175f65d678a7d5756c94f82887fc9803/Lib/subprocess.py#L341 """ command = request.args.get('command', '') - os.system(command) # $ MISSING: result=BAD - os.popen(command) # $ MISSING: result=BAD - subprocess.call(command) # $ MISSING: result=BAD - subprocess.check_call(command) # $ MISSING: result=BAD - subprocess.run(command) # $ MISSING: result=BAD + os.system(command) # $result=BAD + os.popen(command) # $result=BAD + subprocess.call(command) # $result=BAD + subprocess.check_call(command) # $result=BAD + subprocess.run(command) # $result=BAD @app.route("/path-exists-not-sanitizer") @@ -70,11 +70,11 @@ def path_exists_not_sanitizer(): """ path = request.args.get('path', '') if os.path.exists(path): - os.system("ls " + path) # $ MISSING: result=BAD + os.system("ls " + path) # $result=BAD @app.route("/restricted-characters") def restricted_characters(): path = request.args.get('path', '') if re.match(r'^[a-zA-Z0-9_-]+$', path): - os.system("ls " + path) # $ result=OK + os.system("ls " + path) # $SPURIOUS: result=BAD diff --git a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected index 5f5962b6a7e..bb62167c585 100644 --- a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected @@ -1,7 +1,11 @@ edges | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:2:26:2:32 | GSSA Variable request | +| reflected_xss.py:2:26:2:32 | GSSA Variable request | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | | reflected_xss.py:2:26:2:32 | GSSA Variable request | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | | reflected_xss.py:2:26:2:32 | GSSA Variable request | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | +| reflected_xss.py:9:18:9:24 | ControlFlowNode for request | reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | +| reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | reflected_xss.py:9:18:9:45 | ControlFlowNode for Attribute() | +| reflected_xss.py:9:18:9:45 | ControlFlowNode for Attribute() | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | reflected_xss.py:21:23:21:34 | ControlFlowNode for Attribute | | reflected_xss.py:21:23:21:34 | ControlFlowNode for Attribute | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | reflected_xss.py:27:23:27:34 | ControlFlowNode for Attribute | @@ -9,6 +13,10 @@ edges nodes | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | reflected_xss.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| reflected_xss.py:9:18:9:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| reflected_xss.py:9:18:9:45 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | reflected_xss.py:21:23:21:34 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -17,5 +25,6 @@ nodes | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths #select +| reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected b/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected index e217064d1df..6e1a89a6b24 100644 --- a/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected @@ -1,4 +1,31 @@ edges +| code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:1:26:1:32 | GSSA Variable request | +| code_injection.py:1:26:1:32 | GSSA Variable request | code_injection.py:6:12:6:18 | ControlFlowNode for request | +| code_injection.py:1:26:1:32 | GSSA Variable request | code_injection.py:18:16:18:22 | ControlFlowNode for request | +| code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | +| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:6:12:6:35 | ControlFlowNode for Attribute() | +| code_injection.py:6:12:6:35 | ControlFlowNode for Attribute() | code_injection.py:7:10:7:13 | ControlFlowNode for code | +| code_injection.py:6:12:6:35 | ControlFlowNode for Attribute() | code_injection.py:8:10:8:13 | ControlFlowNode for code | +| code_injection.py:6:12:6:35 | ControlFlowNode for Attribute() | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | +| code_injection.py:18:16:18:22 | ControlFlowNode for request | code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | +| code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | code_injection.py:18:16:18:38 | ControlFlowNode for Attribute() | +| code_injection.py:18:16:18:38 | ControlFlowNode for Attribute() | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | nodes +| code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| code_injection.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| code_injection.py:6:12:6:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| code_injection.py:6:12:6:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| code_injection.py:7:10:7:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code | +| code_injection.py:8:10:8:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code | +| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | +| code_injection.py:18:16:18:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| code_injection.py:18:16:18:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | semmle.label | ControlFlowNode for obj_name | subpaths #select +| code_injection.py:7:10:7:13 | ControlFlowNode for code | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:7:10:7:13 | ControlFlowNode for code | This code execution depends on a $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| code_injection.py:8:10:8:13 | ControlFlowNode for code | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:8:10:8:13 | ControlFlowNode for code | This code execution depends on a $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | This code execution depends on a $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | This code execution depends on a $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected index e217064d1df..4d4c98b099c 100644 --- a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected @@ -1,4 +1,43 @@ edges +| LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:7:19:7:25 | GSSA Variable request | +| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | +| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | +| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | +| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | +| LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | +| LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | LogInjectionBad.py:17:12:17:35 | ControlFlowNode for Attribute() | +| LogInjectionBad.py:17:12:17:35 | ControlFlowNode for Attribute() | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | +| LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | +| LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | LogInjectionBad.py:23:12:23:35 | ControlFlowNode for Attribute() | +| LogInjectionBad.py:23:12:23:35 | ControlFlowNode for Attribute() | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | +| LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute | +| LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute | LogInjectionBad.py:29:12:29:35 | ControlFlowNode for Attribute() | +| LogInjectionBad.py:29:12:29:35 | ControlFlowNode for Attribute() | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | +| LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | +| LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | LogInjectionBad.py:35:12:35:35 | ControlFlowNode for Attribute() | +| LogInjectionBad.py:35:12:35:35 | ControlFlowNode for Attribute() | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | nodes +| LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| LogInjectionBad.py:7:19:7:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| LogInjectionBad.py:17:12:17:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| LogInjectionBad.py:23:12:23:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| LogInjectionBad.py:29:12:29:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| LogInjectionBad.py:35:12:35:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths #select +| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | +| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | +| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | +| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected index e217064d1df..1bcc05a954b 100644 --- a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected +++ b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.expected @@ -1,4 +1,16 @@ edges +| pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | pam_test.py:4:26:4:32 | GSSA Variable request | +| pam_test.py:4:26:4:32 | GSSA Variable request | pam_test.py:71:16:71:22 | ControlFlowNode for request | +| pam_test.py:71:16:71:22 | ControlFlowNode for request | pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | +| pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() | +| pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | nodes +| pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| pam_test.py:4:26:4:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| pam_test.py:71:16:71:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | semmle.label | ControlFlowNode for pam_authenticate() | subpaths #select +| pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | This PAM authentication depends on a $@, and 'pam_acct_mgmt' is not called afterwards. | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected index e217064d1df..a1709f0a784 100644 --- a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected +++ b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected @@ -1,4 +1,25 @@ edges +| unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | +| unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | +| unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | +| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:14:15:14:41 | ControlFlowNode for Attribute() | +| unsafe_deserialization.py:14:15:14:41 | ControlFlowNode for Attribute() | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | +| unsafe_deserialization.py:14:15:14:41 | ControlFlowNode for Attribute() | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | +| unsafe_deserialization.py:14:15:14:41 | ControlFlowNode for Attribute() | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | +| unsafe_deserialization.py:14:15:14:41 | ControlFlowNode for Attribute() | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | nodes +| unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| unsafe_deserialization.py:8:26:8:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| unsafe_deserialization.py:14:15:14:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | +| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | +| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | +| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | subpaths #select +| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | +| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | +| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | +| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected index e217064d1df..9808142a4b2 100644 --- a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected +++ b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected @@ -1,4 +1,79 @@ edges +| test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:1:26:1:32 | GSSA Variable request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:7:14:7:20 | ControlFlowNode for request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:30:17:30:23 | ControlFlowNode for request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:37:17:37:23 | ControlFlowNode for request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:44:17:44:23 | ControlFlowNode for request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:60:17:60:23 | ControlFlowNode for request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:67:17:67:23 | ControlFlowNode for request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:74:17:74:23 | ControlFlowNode for request | +| test.py:1:26:1:32 | GSSA Variable request | test.py:81:17:81:23 | ControlFlowNode for request | +| test.py:7:14:7:20 | ControlFlowNode for request | test.py:7:14:7:25 | ControlFlowNode for Attribute | +| test.py:7:14:7:25 | ControlFlowNode for Attribute | test.py:7:14:7:43 | ControlFlowNode for Attribute() | +| test.py:7:14:7:43 | ControlFlowNode for Attribute() | test.py:8:21:8:26 | ControlFlowNode for target | +| test.py:30:17:30:23 | ControlFlowNode for request | test.py:30:17:30:28 | ControlFlowNode for Attribute | +| test.py:30:17:30:28 | ControlFlowNode for Attribute | test.py:30:17:30:46 | ControlFlowNode for Attribute() | +| test.py:30:17:30:46 | ControlFlowNode for Attribute() | test.py:32:21:32:24 | ControlFlowNode for safe | +| test.py:37:17:37:23 | ControlFlowNode for request | test.py:37:17:37:28 | ControlFlowNode for Attribute | +| test.py:37:17:37:28 | ControlFlowNode for Attribute | test.py:37:17:37:46 | ControlFlowNode for Attribute() | +| test.py:37:17:37:46 | ControlFlowNode for Attribute() | test.py:39:21:39:24 | ControlFlowNode for safe | +| test.py:44:17:44:23 | ControlFlowNode for request | test.py:44:17:44:28 | ControlFlowNode for Attribute | +| test.py:44:17:44:28 | ControlFlowNode for Attribute | test.py:44:17:44:46 | ControlFlowNode for Attribute() | +| test.py:44:17:44:46 | ControlFlowNode for Attribute() | test.py:46:21:46:24 | ControlFlowNode for safe | +| test.py:60:17:60:23 | ControlFlowNode for request | test.py:60:17:60:28 | ControlFlowNode for Attribute | +| test.py:60:17:60:28 | ControlFlowNode for Attribute | test.py:60:17:60:46 | ControlFlowNode for Attribute() | +| test.py:60:17:60:46 | ControlFlowNode for Attribute() | test.py:62:21:62:26 | ControlFlowNode for unsafe | +| test.py:67:17:67:23 | ControlFlowNode for request | test.py:67:17:67:28 | ControlFlowNode for Attribute | +| test.py:67:17:67:28 | ControlFlowNode for Attribute | test.py:67:17:67:46 | ControlFlowNode for Attribute() | +| test.py:67:17:67:46 | ControlFlowNode for Attribute() | test.py:69:21:69:26 | ControlFlowNode for unsafe | +| test.py:74:17:74:23 | ControlFlowNode for request | test.py:74:17:74:28 | ControlFlowNode for Attribute | +| test.py:74:17:74:28 | ControlFlowNode for Attribute | test.py:74:17:74:46 | ControlFlowNode for Attribute() | +| test.py:74:17:74:46 | ControlFlowNode for Attribute() | test.py:76:21:76:26 | ControlFlowNode for unsafe | +| test.py:81:17:81:23 | ControlFlowNode for request | test.py:81:17:81:28 | ControlFlowNode for Attribute | +| test.py:81:17:81:28 | ControlFlowNode for Attribute | test.py:81:17:81:46 | ControlFlowNode for Attribute() | +| test.py:81:17:81:46 | ControlFlowNode for Attribute() | test.py:83:21:83:26 | ControlFlowNode for unsafe | nodes +| test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test.py:7:14:7:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:7:14:7:25 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:7:14:7:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:8:21:8:26 | ControlFlowNode for target | semmle.label | ControlFlowNode for target | +| test.py:30:17:30:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:30:17:30:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:30:17:30:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:32:21:32:24 | ControlFlowNode for safe | semmle.label | ControlFlowNode for safe | +| test.py:37:17:37:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:37:17:37:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:37:17:37:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:39:21:39:24 | ControlFlowNode for safe | semmle.label | ControlFlowNode for safe | +| test.py:44:17:44:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:44:17:44:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:44:17:44:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:46:21:46:24 | ControlFlowNode for safe | semmle.label | ControlFlowNode for safe | +| test.py:60:17:60:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:60:17:60:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:60:17:60:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:62:21:62:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | +| test.py:67:17:67:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:67:17:67:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:67:17:67:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:69:21:69:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | +| test.py:74:17:74:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:74:17:74:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:74:17:74:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:76:21:76:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | +| test.py:81:17:81:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:81:17:81:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:81:17:81:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:83:21:83:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | subpaths #select +| test.py:8:21:8:26 | ControlFlowNode for target | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:8:21:8:26 | ControlFlowNode for target | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:32:21:32:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:32:21:32:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:39:21:39:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:39:21:39:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:46:21:46:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:46:21:46:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:62:21:62:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:62:21:62:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:69:21:69:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:69:21:69:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:76:21:76:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:76:21:76:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:83:21:83:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:83:21:83:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected index 649dc8e5415..fcf2c26a03b 100644 --- a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.expected @@ -2,11 +2,59 @@ edges | xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | +| xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:2:26:2:32 | GSSA Variable request | +| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | +| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | +| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | +| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | +| xpathFlow.py:2:26:2:32 | GSSA Variable request | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | +| xpathFlow.py:11:18:11:24 | ControlFlowNode for request | xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | +| xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | xpathFlow.py:11:18:11:44 | ControlFlowNode for Attribute() | +| xpathFlow.py:11:18:11:44 | ControlFlowNode for Attribute() | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | +| xpathFlow.py:20:18:20:24 | ControlFlowNode for request | xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | +| xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | xpathFlow.py:20:18:20:44 | ControlFlowNode for Attribute() | +| xpathFlow.py:20:18:20:44 | ControlFlowNode for Attribute() | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | +| xpathFlow.py:30:18:30:24 | ControlFlowNode for request | xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | +| xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | xpathFlow.py:30:18:30:44 | ControlFlowNode for Attribute() | +| xpathFlow.py:30:18:30:44 | ControlFlowNode for Attribute() | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | +| xpathFlow.py:39:18:39:24 | ControlFlowNode for request | xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | +| xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | xpathFlow.py:39:18:39:44 | ControlFlowNode for Attribute() | +| xpathFlow.py:39:18:39:44 | ControlFlowNode for Attribute() | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | +| xpathFlow.py:47:18:47:24 | ControlFlowNode for request | xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | +| xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | xpathFlow.py:47:18:47:44 | ControlFlowNode for Attribute() | +| xpathFlow.py:47:18:47:44 | ControlFlowNode for Attribute() | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | nodes | xpathBad.py:9:7:9:13 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| xpathFlow.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| xpathFlow.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:11:18:11:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:20:18:20:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:20:18:20:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:30:18:30:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:30:18:30:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:39:18:39:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:39:18:39:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:47:18:47:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:47:18:47:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | subpaths #select | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | XPath expression depends on a $@. | xpathBad.py:9:7:9:13 | ControlFlowNode for request | user-provided value | +| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | XPath expression depends on a $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected index e217064d1df..3a434d227d7 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected @@ -1,4 +1,32 @@ edges +| test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:2:26:2:32 | GSSA Variable request | +| test.py:2:26:2:32 | GSSA Variable request | test.py:7:12:7:18 | ControlFlowNode for request | +| test.py:7:12:7:18 | ControlFlowNode for request | test.py:7:12:7:23 | ControlFlowNode for Attribute | +| test.py:7:12:7:23 | ControlFlowNode for Attribute | test.py:7:12:7:35 | ControlFlowNode for Attribute() | +| test.py:7:12:7:35 | ControlFlowNode for Attribute() | test.py:8:30:8:33 | ControlFlowNode for text | +| test.py:7:12:7:35 | ControlFlowNode for Attribute() | test.py:9:32:9:35 | ControlFlowNode for text | +| test.py:7:12:7:35 | ControlFlowNode for Attribute() | test.py:12:17:12:20 | ControlFlowNode for text | +| test.py:7:12:7:35 | ControlFlowNode for Attribute() | test.py:18:28:18:31 | ControlFlowNode for text | +| test.py:7:12:7:35 | ControlFlowNode for Attribute() | test.py:21:18:21:21 | ControlFlowNode for text | +| test.py:14:33:14:39 | ControlFlowNode for my_text | test.py:16:24:16:30 | ControlFlowNode for my_text | +| test.py:18:28:18:31 | ControlFlowNode for text | test.py:14:33:14:39 | ControlFlowNode for my_text | nodes +| test.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test.py:7:12:7:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| test.py:7:12:7:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:7:12:7:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:8:30:8:33 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | +| test.py:9:32:9:35 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | +| test.py:12:17:12:20 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | +| test.py:14:33:14:39 | ControlFlowNode for my_text | semmle.label | ControlFlowNode for my_text | +| test.py:16:24:16:30 | ControlFlowNode for my_text | semmle.label | ControlFlowNode for my_text | +| test.py:18:28:18:31 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | +| test.py:21:18:21:21 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | subpaths #select +| test.py:8:30:8:33 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:8:30:8:33 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:8:21:8:23 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:9:32:9:35 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with '0.9' and with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:12:17:12:20 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:12:17:12:20 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:11:31:11:33 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:16:24:16:30 | ControlFlowNode for my_text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:16:24:16:30 | ControlFlowNode for my_text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:18:23:18:25 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:21:18:21:21 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:21:18:21:21 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | test.py:20:273:20:274 | .* | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | From 40daa9c906c972be22aff4e8961c5f07d4dc9c9d Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 26 May 2023 14:05:36 +0200 Subject: [PATCH 141/739] JS: Update RegExpInjection test and expectations --- .../Security/CWE-730/RegExpInjection.expected | 35 ++++++++----------- .../Security/CWE-730/RegExpInjection.js | 12 +++---- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected index 693ef9e5e95..391be36fbb9 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected @@ -31,14 +31,12 @@ nodes | RegExpInjection.js:41:26:41:30 | input | | RegExpInjection.js:42:25:42:29 | input | | RegExpInjection.js:42:25:42:29 | input | -| RegExpInjection.js:45:20:45:24 | input | -| RegExpInjection.js:45:20:45:24 | input | -| RegExpInjection.js:46:23:46:27 | input | -| RegExpInjection.js:46:23:46:27 | input | -| RegExpInjection.js:47:22:47:26 | input | -| RegExpInjection.js:47:22:47:26 | input | -| RegExpInjection.js:50:46:50:50 | input | -| RegExpInjection.js:50:46:50:50 | input | +| RegExpInjection.js:45:24:45:28 | input | +| RegExpInjection.js:45:24:45:28 | input | +| RegExpInjection.js:46:27:46:31 | input | +| RegExpInjection.js:46:27:46:31 | input | +| RegExpInjection.js:47:26:47:30 | input | +| RegExpInjection.js:47:26:47:30 | input | | RegExpInjection.js:54:14:54:16 | key | | RegExpInjection.js:54:14:54:27 | key.split(".") | | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | @@ -89,14 +87,12 @@ edges | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:41:26:41:30 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:25:42:29 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:25:42:29 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:20:45:24 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:20:45:24 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:23:46:27 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:23:46:27 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:22:47:26 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:22:47:26 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:50:46:50:50 | input | -| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:50:46:50:50 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:24:45:28 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:24:45:28 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:27:46:31 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:27:46:31 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:26:47:30 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:26:47:30 | input | | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input | | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input | | RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | @@ -157,10 +153,9 @@ edges | RegExpInjection.js:40:23:40:27 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:40:23:40:27 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | | RegExpInjection.js:41:26:41:30 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:41:26:41:30 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | | RegExpInjection.js:42:25:42:29 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:42:25:42:29 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | -| RegExpInjection.js:45:20:45:24 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:45:20:45:24 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | -| RegExpInjection.js:46:23:46:27 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:46:23:46:27 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | -| RegExpInjection.js:47:22:47:26 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:47:22:47:26 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | -| RegExpInjection.js:50:46:50:50 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:50:46:50:50 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | +| RegExpInjection.js:45:24:45:28 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:45:24:45:28 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | +| RegExpInjection.js:46:27:46:31 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:46:27:46:31 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | +| RegExpInjection.js:47:26:47:30 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:47:26:47:30 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value | | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value | | RegExpInjection.js:64:14:64:18 | input | RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:64:14:64:18 | input | This regular expression is constructed from a $@. | RegExpInjection.js:60:39:60:56 | req.param("input") | user-provided value | | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | This regular expression is constructed from a $@. | RegExpInjection.js:82:15:82:32 | req.param("input") | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js index 1f8113f7d75..6cf3938486e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js @@ -42,12 +42,12 @@ app.get('/findKey', function(req, res) { if (maybeString.match(input)) {} // NOT OK if (notString.match(input)) {} // OK - defString.search(input); // NOT OK - likelyString.search(input); // NOT OK - maybeString.search(input); // NOT OK - notString.search(input); // OK + if (defString.search(input) > -1) {} // NOT OK + if (likelyString.search(input) > -1) {} // NOT OK + if (maybeString.search(input) > -1) {} // NOT OK + if (notString.search(input) > -1) {} // OK - URI(`${protocol}://${host}${path}`).search(input); // OK, but still flagged [INCONSISTENCY] + URI(`${protocol}://${host}${path}`).search(input); // OK URI(`${protocol}://${host}${path}`).search(input).href(); // OK unknown.search(input).unknown; // OK @@ -62,7 +62,7 @@ app.get('/findKey', function(req, res) { Search.search(input); // OK! new RegExp(input); // NOT OK - + var sanitized = input.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); new RegExp(sanitized); // OK }); From 9df9ca2916d90fdc4cc86a50581e35c98c2309ac Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 26 May 2023 14:07:34 +0200 Subject: [PATCH 142/739] JS: Update test and expectations for MissingRegExpAnchor --- .../CWE-020/MissingRegExpAnchor/MissingRegExpAnchor.expected | 2 +- .../CWE-020/MissingRegExpAnchor/tst-UnanchoredUrlRegExp.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-020/MissingRegExpAnchor/MissingRegExpAnchor.expected b/javascript/ql/test/query-tests/Security/CWE-020/MissingRegExpAnchor/MissingRegExpAnchor.expected index 0554d826383..a7933f2926e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/MissingRegExpAnchor/MissingRegExpAnchor.expected +++ b/javascript/ql/test/query-tests/Security/CWE-020/MissingRegExpAnchor/MissingRegExpAnchor.expected @@ -49,7 +49,7 @@ | tst-UnanchoredUrlRegExp.js:8:47:8:90 | "(https ... e.com)" | This hostname pattern may match any domain name, as it is missing a '$' or '/' at the end. | | tst-UnanchoredUrlRegExp.js:10:2:10:22 | /https? ... od.com/ | When this is used as a regular expression on a URL, it may match anywhere, and arbitrary hosts may come before or after it. | | tst-UnanchoredUrlRegExp.js:11:13:11:31 | "https?://good.com" | When this is used as a regular expression on a URL, it may match anywhere, and arbitrary hosts may come before or after it. | -| tst-UnanchoredUrlRegExp.js:13:44:13:62 | "https?://good.com" | When this is used as a regular expression on a URL, it may match anywhere, and arbitrary hosts may come before or after it. | +| tst-UnanchoredUrlRegExp.js:13:48:13:66 | "https?://good.com" | When this is used as a regular expression on a URL, it may match anywhere, and arbitrary hosts may come before or after it. | | tst-UnanchoredUrlRegExp.js:15:13:15:31 | "https?://good.com" | When this is used as a regular expression on a URL, it may match anywhere, and arbitrary hosts may come before or after it. | | tst-UnanchoredUrlRegExp.js:19:47:19:65 | "https?://good.com" | When this is used as a regular expression on a URL, it may match anywhere, and arbitrary hosts may come before or after it. | | tst-UnanchoredUrlRegExp.js:20:47:20:70 | "https? ... m:8080" | When this is used as a regular expression on a URL, it may match anywhere, and arbitrary hosts may come before or after it. | diff --git a/javascript/ql/test/query-tests/Security/CWE-020/MissingRegExpAnchor/tst-UnanchoredUrlRegExp.js b/javascript/ql/test/query-tests/Security/CWE-020/MissingRegExpAnchor/tst-UnanchoredUrlRegExp.js index 5db3aa740fb..24815ebe59e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-020/MissingRegExpAnchor/tst-UnanchoredUrlRegExp.js +++ b/javascript/ql/test/query-tests/Security/CWE-020/MissingRegExpAnchor/tst-UnanchoredUrlRegExp.js @@ -10,7 +10,7 @@ /https?:\/\/good.com/.exec("http://evil.com/?http://good.com"); // NOT OK new RegExp("https?://good.com").exec("http://evil.com/?http://good.com"); // NOT OK - "http://evil.com/?http://good.com".search("https?://good.com"); // NOT OK + if ("http://evil.com/?http://good.com".search("https?://good.com") > -1) {} // NOT OK new RegExp("https?://good.com").test("http://evil.com/?http://good.com"); // NOT OK From c637b6f59a623a32720865da7fae2d4bcc67b2a5 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 26 May 2023 14:10:26 +0200 Subject: [PATCH 143/739] JS: Update test for RegExpAlwaysMatches --- .../test/query-tests/RegExp/RegExpAlwaysMatches/tst.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/ql/test/query-tests/RegExp/RegExpAlwaysMatches/tst.js b/javascript/ql/test/query-tests/RegExp/RegExpAlwaysMatches/tst.js index a266e2d86f6..b4c54be9b8a 100644 --- a/javascript/ql/test/query-tests/RegExp/RegExpAlwaysMatches/tst.js +++ b/javascript/ql/test/query-tests/RegExp/RegExpAlwaysMatches/tst.js @@ -55,23 +55,23 @@ function emptyAlt3(x) { } function search(x) { - return x.search(/[a-z]*/); // NOT OK + return x.search(/[a-z]*/) > -1; // NOT OK } function search2(x) { - return x.search(/[a-z]/); // OK + return x.search(/[a-z]/) > -1; // OK } function lookahead(x) { - return x.search(/(?!x)/); // OK + return x.search(/(?!x)/) > -1; // OK } function searchPrefix(x) { - return x.search(/^(foo)?/); // NOT OK - `foo?` does not affect the returned index + return x.search(/^(foo)?/) > -1; // NOT OK - `foo?` does not affect the returned index } function searchSuffix(x) { - return x.search(/(foo)?$/); // OK - `foo?` affects the returned index + return x.search(/(foo)?$/) > -1; // OK - `foo?` affects the returned index } function wordBoundary(x) { From efe539eb32d76696e1e7593a10f69a0a997d9f38 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Fri, 26 May 2023 14:07:59 +0200 Subject: [PATCH 144/739] Java: better sampling of negative examples --- ...odelApplicationModeExtractNegativeExamples.ql | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index f57079aa57a..41c91b06668 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -12,13 +12,25 @@ private import AutomodelApplicationModeCharacteristics private import AutomodelEndpointTypes private import AutomodelSharedUtil +/** + * Gets a sample of endpoints for which the given characteristic applies. + */ +bindingset[limit] +Endpoint getSampleForCharacteristic(EndpointCharacteristic c, int limit) { + exists(int n | + result = + rank[n](Endpoint e2 | c.appliesToEndpoint(e2) | e2 order by e2.getLocation().toString()) and + // we order the endpoints by location, but (to avoid bias) we select the indices semi-randomly + n = 1 + (([1 .. limit] * 271) % count(Endpoint e | c.appliesToEndpoint(e))) + ) +} + from Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string message, ApplicationModeMetadataExtractor meta, string package, string type, boolean subtypes, string name, string signature, string input where - endpoint.getLocation().getStartLine() % 100 = 0 and - characteristic.appliesToEndpoint(endpoint) and + endpoint = getSampleForCharacteristic(characteristic, 100) and confidence >= SharedCharacteristics::highConfidence() and characteristic.hasImplications(any(NegativeSinkType negative), true, confidence) and // Exclude endpoints that have contradictory endpoint characteristics, because we only want examples we're highly From 227c5fab4093a8098feaee89d86ce2e9592ac88c Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Fri, 26 May 2023 14:52:08 +0000 Subject: [PATCH 145/739] Java: Get location ordering without `toString` --- .../AutomodelApplicationModeExtractNegativeExamples.ql | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index 41c91b06668..0fe785de26b 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -8,6 +8,7 @@ * @tags internal extract automodel application-mode negative examples */ +private import java private import AutomodelApplicationModeCharacteristics private import AutomodelEndpointTypes private import AutomodelSharedUtil @@ -19,7 +20,14 @@ bindingset[limit] Endpoint getSampleForCharacteristic(EndpointCharacteristic c, int limit) { exists(int n | result = - rank[n](Endpoint e2 | c.appliesToEndpoint(e2) | e2 order by e2.getLocation().toString()) and + rank[n](Endpoint e, Location loc | + loc = e.getLocation() and c.appliesToEndpoint(e) + | + e + order by + loc.getFile().getAbsolutePath(), loc.getStartLine(), loc.getStartColumn(), + loc.getEndLine(), loc.getEndColumn() + ) and // we order the endpoints by location, but (to avoid bias) we select the indices semi-randomly n = 1 + (([1 .. limit] * 271) % count(Endpoint e | c.appliesToEndpoint(e))) ) From 0f08642653bffb3206a2660cdb42feebb0384875 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 26 May 2023 11:16:44 -0700 Subject: [PATCH 146/739] C++: Fix join in 'pointerArithOverflow0'. --- .../Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql index 88db396f2cf..735375870ea 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -78,11 +78,16 @@ predicate isInvalidPointerDerefSink2(DataFlow::Node sink, Instruction i, string ) } +pragma[nomagic] +predicate arrayTypeHasSizes(ArrayType arr, int baseTypeSize, int arraySize) { + arr.getBaseType().getSize() = baseTypeSize and + arr.getArraySize() = arraySize +} + predicate pointerArithOverflow0( PointerArithmeticInstruction pai, Field f, int size, int bound, int delta ) { - pai.getElementSize() = f.getUnspecifiedType().(ArrayType).getBaseType().getSize() and - f.getUnspecifiedType().(ArrayType).getArraySize() = size and + arrayTypeHasSizes(f.getUnspecifiedType(), pai.getElementSize(), size) and semBounded(getSemanticExpr(pai.getRight()), any(SemZeroBound b), bound, true, _) and delta = bound - size and delta >= 0 and From 9828af45a1754cd9f6902c1ed5af1cce9e526870 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 26 May 2023 15:23:48 -0700 Subject: [PATCH 147/739] C++: Change separator from ':' to '|'. --- .../ir/range-analysis/RangeAnalysis.ql | 2 +- .../SimpleRangeAnalysis_tests.cpp | 32 +++++++++---------- .../library-tests/ir/range-analysis/test.cpp | 4 +-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql index eadf0b90ef5..b5a86c23d97 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql @@ -40,7 +40,7 @@ bindingset[delta] private string getBoundString(SemBound b, float delta) { b instanceof SemZeroBound and result = delta.toString() or - result = strictconcat(b.(SemSsaBound).getAVariable().toString(), ":") + getOffsetString(delta) + result = strictconcat(b.(SemSsaBound).getAVariable().toString(), " | ") + getOffsetString(delta) } private string getARangeString(SemExpr e) { diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index 92e197115b7..df29578409b 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -8,7 +8,7 @@ int test1(struct List* p) { int count = 0; for (; p; p = p->next) { count = count+1; - range(count); // $ range="==Phi: p:Store: count+1" + range(count); // $ range="==Phi: p | Store: count+1" } range(count); return count; @@ -18,7 +18,7 @@ int test2(struct List* p) { int count = 0; for (; p; p = p->next) { count = (count+1) % 10; - range(count); // $ range=<=9 range=>=-9 range="<=Phi: p:Store: count+1" + range(count); // $ range=<=9 range=>=-9 range="<=Phi: p | Store: count+1" } range(count); // $ range=>=-9 range=<=9 return count; @@ -29,7 +29,7 @@ int test3(struct List* p) { for (; p; p = p->next) { range(count++); // $ range=>=-9 range=<=9 count = count % 10; - range(count); // $ range=<=9 range=>=-9 range="<=Store: ... +++0" range="<=Phi: p:Store: count+1" + range(count); // $ range=<=9 range=>=-9 range="<=Store: ... +++0" range="<=Phi: p | Store: count+1" } range(count); // $ range=>=-9 range=<=9 return count; @@ -93,12 +93,12 @@ int test8(int x, int y) { if (-1000 < y && y < 10) { range(y); // $ range=<=9 range=>=-999 if (x < y-2) { - range(x); // $ range=<=6 range="<=InitializeParameter: y:Store: y-3" - range(y); // $ range=<=9 range=>=-999 range=">=InitializeParameter: x:Store: x+3" + range(x); // $ range=<=6 range="<=InitializeParameter: y | Store: y-3" + range(y); // $ range=<=9 range=>=-999 range=">=InitializeParameter: x | Store: x+3" return x; } - range(x); // $ range=>=-1001 range=">=InitializeParameter: y:Store: y-2" - range(y); // $ range=<=9 range="<=InitializeParameter: x:Store: x+2" range=>=-999 + range(x); // $ range=>=-1001 range=">=InitializeParameter: y | Store: y-2" + range(y); // $ range=<=9 range="<=InitializeParameter: x | Store: x+2" range=>=-999 } range(x); range(y); @@ -128,11 +128,11 @@ int test10(int x, int y) { range(y); // $ range=>=8 if (x < y) { range(x); // $ range="<=InitializeParameter: y-1" - range(y); // $ range=>=8 range=">=InitializeParameter: x:Store: x+1" + range(y); // $ range=>=8 range=">=InitializeParameter: x | Store: x+1" return 0; } range(x); // $ range=>=8 range=">=InitializeParameter: y+0" - range(y); // $ range="<=InitializeParameter: x:Store: x+0" range=>=8 + range(y); // $ range="<=InitializeParameter: x | Store: x+0" range=>=8 return x; } range(y); // $ range=<=7 @@ -541,7 +541,7 @@ int test16(int x) { while (i < 3) { range(i); // $ range=<=2 range=>=0 i++; - range(i); // $ range=<=3 range=>=1 range="==Phi: i:Store: ... = ...+1" + range(i); // $ range=<=3 range=>=1 range="==Phi: i | Store: ... = ...+1" } range(d); d = i; @@ -640,14 +640,14 @@ unsigned int test_comma01(unsigned int x) { unsigned int y1; unsigned int y2; y1 = (++y, y); - range(y1); // $ range=<=101 range="==Phi: ... ? ... : ...:Store: ... ? ... : ...+1" + range(y1); // $ range=<=101 range="==Phi: ... ? ... : ... | Store: ... ? ... : ...+1" y2 = (y++, - range(y), // $ range=<=102 range="==Store: ++ ...:Store: ... = ...+1" range="==Phi: ... ? ... : ...:Store: ... ? ... : ...+2" + range(y), // $ range=<=102 range="==Store: ++ ... | Store: ... = ...+1" range="==Phi: ... ? ... : ... | Store: ... ? ... : ...+2" y += 3, - range(y), // $ range=<=105 range="==Store: ++ ...:Store: ... = ...+4" range="==Store: ... +++3" range="==Phi: ... ? ... : ...:Store: ... ? ... : ...+5" + range(y), // $ range=<=105 range="==Store: ++ ... | Store: ... = ...+4" range="==Store: ... +++3" range="==Phi: ... ? ... : ... | Store: ... ? ... : ...+5" y); - range(y2); // $ range=<=105 range="==Store: ++ ...:Store: ... = ...+4" range="==Store: ... +++3" Unexpected result: range="==Phi: ... ? ... : ...:Store: ... ? ... : ...+5" - range(y1 + y2); // $ range=<=206 range="<=Phi: ... ? ... : ...:Store: ... ? ... : ...+106" MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" + range(y2); // $ range=<=105 range="==Store: ++ ... | Store: ... = ...+4" range="==Store: ... +++3" Unexpected result: range="==Phi: ... ? ... : ... | Store: ... ? ... : ...+5" + range(y1 + y2); // $ range=<=206 range="<=Phi: ... ? ... : ... | Store: ... ? ... : ...+106" MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" return y1 + y2; } @@ -672,7 +672,7 @@ void test17() { range(i); // $ range===50 i = 20 + (j -= 10); - range(i); // $ range="==Store: ... += ...:Store: ... = ...+10" range===60 + range(i); // $ range="==Store: ... += ... | Store: ... = ...+10" range===60 } // Tests for unsigned multiplication. diff --git a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp index 5d816f3cda4..95e6474124a 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp @@ -17,7 +17,7 @@ } else { if (y > 300) { range(x); // $ range=>=302 range=<=400 range="<=InitializeParameter: y+1" MISSING: range===y+1 - range(y); // $ range=>=301 range=<=399 range="==InitializeParameter: x:Store: x-1" + range(y); // $ range=>=301 range=<=399 range="==InitializeParameter: x | Store: x-1" int sum = x + y; } } @@ -40,7 +40,7 @@ if (y == x - 1 && y > 300 && y + 2 == z && z == 350) { // $ overflow=+ overflow=- range(x); // $ range===349 range="==InitializeParameter: y+1" range="==InitializeParameter: z-1" - range(y); // $ range===348 range=">=InitializeParameter: x:Store: x-1" range="==InitializeParameter: z-2" MISSING: range===x-1 + range(y); // $ range===348 range=">=InitializeParameter: x | Store: x-1" range="==InitializeParameter: z-2" MISSING: range===x-1 range(z); // $ range===350 range="<=InitializeParameter: y+2" MISSING: range===x+1 range===y+2 return x + y + z; } From 65dd7eb8e77178d91d9b5a05d0a43311ead5f18b Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 11 May 2023 15:48:36 -0400 Subject: [PATCH 148/739] Java: add neutral models discovered with path-inj and ssrf heuristics --- java/ql/lib/ext/java.io.model.yml | 5 +++++ java/ql/lib/ext/java.nio.file.model.yml | 18 ++++++++++++++++++ java/ql/lib/ext/java.nio.file.spi.model.yml | 7 +++++++ java/ql/lib/ext/java.text.model.yml | 4 ++++ java/ql/lib/ext/java.util.prefs.model.yml | 7 +++++++ ...g.apache.hc.client5.http.protocol.model.yml | 6 ++++++ 6 files changed, 47 insertions(+) create mode 100644 java/ql/lib/ext/java.nio.file.spi.model.yml create mode 100644 java/ql/lib/ext/java.util.prefs.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index 2db99b7027e..e3a48d4138d 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -100,6 +100,7 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + # summary neutrals - ["java.io", "Closeable", "close", "()", "summary", "manual"] - ["java.io", "DataOutput", "writeBoolean", "(boolean)", "summary", "manual"] - ["java.io", "File", "delete", "()", "summary", "manual"] @@ -117,3 +118,7 @@ extensions: - ["java.io", "DataInput", "readLong", "()", "summary", "manual"] # taint-numeric - ["java.io", "DataOutput", "writeInt", "(int)", "summary", "manual"] # taint-numeric - ["java.io", "DataOutput", "writeLong", "(long)", "summary", "manual"] # taint-numeric + + # sink neutrals + - ["java.io", "File", "compareTo", "", "sink", "manual"] + - ["java.io", "File", "exists", "()", "sink", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 42ae8b9052b..c178f628980 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -81,4 +81,22 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + # summary neutrals - ["java.nio.file", "Files", "exists", "(Path,LinkOption[])", "summary", "manual"] + + # sink neutrals + - ["java.nio.file", "Files" "exists", "", "sink", "manual"] + - ["java.nio.file", "Files" "getLastModifiedTime", "", "sink", "manual"] + - ["java.nio.file", "Files" "getOwner", "", "sink", "manual"] + - ["java.nio.file", "Files" "getPosixFilePermissions", "", "sink", "manual"] + - ["java.nio.file", "Files" "isDirectory", "", "sink", "manual"] + - ["java.nio.file", "Files" "isExecutable", "", "sink", "manual"] + - ["java.nio.file", "Files" "isHidden", "", "sink", "manual"] + - ["java.nio.file", "Files" "isReadable", "", "sink", "manual"] + - ["java.nio.file", "Files" "isRegularFile", "", "sink", "manual"] + - ["java.nio.file", "Files" "isSameFile", "", "sink", "manual"] + - ["java.nio.file", "Files" "isSymbolicLink", "", "sink", "manual"] + - ["java.nio.file", "Files" "isWritable", "", "sink", "manual"] + - ["java.nio.file", "Files" "notExists", "", "sink", "manual"] + - ["java.nio.file", "Files" "setLastModifiedTime", "", "sink", "manual"] + - ["java.nio.file", "Files" "size", "", "sink", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.spi.model.yml b/java/ql/lib/ext/java.nio.file.spi.model.yml new file mode 100644 index 00000000000..a833c453eb3 --- /dev/null +++ b/java/ql/lib/ext/java.nio.file.spi.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "manual"] + - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "manual"] diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index 728ed4fa6b4..13b286b0438 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -3,6 +3,10 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.text", "Collator" "compare", "", "manual"] + - ["java.text", "Collator" "equals", "", "manual"] + - ["java.text", "RuleBasedCollator", "compare", "", "manual"] + # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.text", "DateFormat", "format", "(Date)", "summary", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.prefs.model.yml b/java/ql/lib/ext/java.util.prefs.model.yml new file mode 100644 index 00000000000..c27ba79029b --- /dev/null +++ b/java/ql/lib/ext/java.util.prefs.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "manual"] + - ["java.util.prefs", "Preferences", "nodeExists", "", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml new file mode 100644 index 00000000000..eb92d7b4334 --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "manual"] From 60b07083c3b54f5da0c8845d3bea39d6174d7eb1 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 11 May 2023 17:47:31 -0400 Subject: [PATCH 149/739] Java: add 'sink' kind --- java/ql/lib/ext/java.nio.file.spi.model.yml | 5 +++-- java/ql/lib/ext/java.text.model.yml | 10 ++++++---- java/ql/lib/ext/java.util.prefs.model.yml | 5 +++-- .../ext/org.apache.hc.client5.http.protocol.model.yml | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/ext/java.nio.file.spi.model.yml b/java/ql/lib/ext/java.nio.file.spi.model.yml index a833c453eb3..0a7396a482c 100644 --- a/java/ql/lib/ext/java.nio.file.spi.model.yml +++ b/java/ql/lib/ext/java.nio.file.spi.model.yml @@ -3,5 +3,6 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "manual"] - - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "manual"] + # sink neutrals + - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "sink", "manual"] + - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "sink", "manual"] diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index 13b286b0438..d4704c2ab97 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -3,12 +3,14 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.text", "Collator" "compare", "", "manual"] - - ["java.text", "Collator" "equals", "", "manual"] - - ["java.text", "RuleBasedCollator", "compare", "", "manual"] - + # summary neutrals # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.text", "DateFormat", "format", "(Date)", "summary", "manual"] # taint-numeric - ["java.text", "DateFormat", "parse", "(String)", "summary", "manual"] # taint-numeric - ["java.text", "SimpleDateFormat", "SimpleDateFormat", "(String)", "summary", "manual"] # taint-numeric + + # sink neutrals + - ["java.text", "Collator" "compare", "", "sink", "manual"] + - ["java.text", "Collator" "equals", "", "sink", "manual"] + - ["java.text", "RuleBasedCollator", "compare", "", "sink", "manual"] diff --git a/java/ql/lib/ext/java.util.prefs.model.yml b/java/ql/lib/ext/java.util.prefs.model.yml index c27ba79029b..412730c3807 100644 --- a/java/ql/lib/ext/java.util.prefs.model.yml +++ b/java/ql/lib/ext/java.util.prefs.model.yml @@ -3,5 +3,6 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "manual"] - - ["java.util.prefs", "Preferences", "nodeExists", "", "manual"] + # sink neutrals + - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "sink", "manual"] + - ["java.util.prefs", "Preferences", "nodeExists", "", "sink", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml index eb92d7b4334..eb30b29a50a 100644 --- a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml +++ b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml @@ -3,4 +3,5 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "manual"] + # sink neutrals + - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "sink", "manual"] From 7e6913af620e9d6d7127e8cee67d6e9a31dc6dec Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 11 May 2023 17:51:53 -0400 Subject: [PATCH 150/739] Java: update provenance to 'hq-manual' --- java/ql/lib/ext/java.io.model.yml | 4 +-- java/ql/lib/ext/java.nio.file.model.yml | 30 +++++++++---------- java/ql/lib/ext/java.nio.file.spi.model.yml | 4 +-- java/ql/lib/ext/java.text.model.yml | 6 ++-- java/ql/lib/ext/java.util.prefs.model.yml | 4 +-- ....apache.hc.client5.http.protocol.model.yml | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index e3a48d4138d..44d079c1474 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -120,5 +120,5 @@ extensions: - ["java.io", "DataOutput", "writeLong", "(long)", "summary", "manual"] # taint-numeric # sink neutrals - - ["java.io", "File", "compareTo", "", "sink", "manual"] - - ["java.io", "File", "exists", "()", "sink", "manual"] + - ["java.io", "File", "compareTo", "", "sink", "hq-manual"] + - ["java.io", "File", "exists", "()", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index c178f628980..243f6a528a1 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -85,18 +85,18 @@ extensions: - ["java.nio.file", "Files", "exists", "(Path,LinkOption[])", "summary", "manual"] # sink neutrals - - ["java.nio.file", "Files" "exists", "", "sink", "manual"] - - ["java.nio.file", "Files" "getLastModifiedTime", "", "sink", "manual"] - - ["java.nio.file", "Files" "getOwner", "", "sink", "manual"] - - ["java.nio.file", "Files" "getPosixFilePermissions", "", "sink", "manual"] - - ["java.nio.file", "Files" "isDirectory", "", "sink", "manual"] - - ["java.nio.file", "Files" "isExecutable", "", "sink", "manual"] - - ["java.nio.file", "Files" "isHidden", "", "sink", "manual"] - - ["java.nio.file", "Files" "isReadable", "", "sink", "manual"] - - ["java.nio.file", "Files" "isRegularFile", "", "sink", "manual"] - - ["java.nio.file", "Files" "isSameFile", "", "sink", "manual"] - - ["java.nio.file", "Files" "isSymbolicLink", "", "sink", "manual"] - - ["java.nio.file", "Files" "isWritable", "", "sink", "manual"] - - ["java.nio.file", "Files" "notExists", "", "sink", "manual"] - - ["java.nio.file", "Files" "setLastModifiedTime", "", "sink", "manual"] - - ["java.nio.file", "Files" "size", "", "sink", "manual"] + - ["java.nio.file", "Files" "exists", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "getLastModifiedTime", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "getOwner", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "getPosixFilePermissions", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isDirectory", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isExecutable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isHidden", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isReadable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isRegularFile", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isSameFile", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isSymbolicLink", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isWritable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "notExists", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "setLastModifiedTime", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "size", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.nio.file.spi.model.yml b/java/ql/lib/ext/java.nio.file.spi.model.yml index 0a7396a482c..0b6d1d89988 100644 --- a/java/ql/lib/ext/java.nio.file.spi.model.yml +++ b/java/ql/lib/ext/java.nio.file.spi.model.yml @@ -4,5 +4,5 @@ extensions: extensible: neutralModel data: # sink neutrals - - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "sink", "manual"] - - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "sink", "manual"] + - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "sink", "hq-manual"] + - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index d4704c2ab97..02e0eac7407 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -11,6 +11,6 @@ extensions: - ["java.text", "SimpleDateFormat", "SimpleDateFormat", "(String)", "summary", "manual"] # taint-numeric # sink neutrals - - ["java.text", "Collator" "compare", "", "sink", "manual"] - - ["java.text", "Collator" "equals", "", "sink", "manual"] - - ["java.text", "RuleBasedCollator", "compare", "", "sink", "manual"] + - ["java.text", "Collator" "compare", "", "sink", "hq-manual"] + - ["java.text", "Collator" "equals", "", "sink", "hq-manual"] + - ["java.text", "RuleBasedCollator", "compare", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.util.prefs.model.yml b/java/ql/lib/ext/java.util.prefs.model.yml index 412730c3807..a2a7c16bc5d 100644 --- a/java/ql/lib/ext/java.util.prefs.model.yml +++ b/java/ql/lib/ext/java.util.prefs.model.yml @@ -4,5 +4,5 @@ extensions: extensible: neutralModel data: # sink neutrals - - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "sink", "manual"] - - ["java.util.prefs", "Preferences", "nodeExists", "", "sink", "manual"] + - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "sink", "hq-manual"] + - ["java.util.prefs", "Preferences", "nodeExists", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml index eb30b29a50a..b5f46643f2f 100644 --- a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml +++ b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml @@ -4,4 +4,4 @@ extensions: extensible: neutralModel data: # sink neutrals - - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "sink", "manual"] + - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "sink", "hq-manual"] From f255b6acb805a5122bb7bdad47f023a6f557dcfd Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 22 May 2023 08:55:54 -0400 Subject: [PATCH 151/739] Java: fix typos --- java/ql/lib/ext/java.nio.file.model.yml | 30 ++++++++++----------- java/ql/lib/ext/java.nio.file.spi.model.yml | 4 +-- java/ql/lib/ext/java.text.model.yml | 4 +-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 243f6a528a1..6b08117d74f 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -85,18 +85,18 @@ extensions: - ["java.nio.file", "Files", "exists", "(Path,LinkOption[])", "summary", "manual"] # sink neutrals - - ["java.nio.file", "Files" "exists", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "getLastModifiedTime", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "getOwner", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "getPosixFilePermissions", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isDirectory", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isExecutable", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isHidden", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isReadable", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isRegularFile", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isSameFile", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isSymbolicLink", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isWritable", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "notExists", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "setLastModifiedTime", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "size", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "exists", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "getLastModifiedTime", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "getOwner", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "getPosixFilePermissions", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isDirectory", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isExecutable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isHidden", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isReadable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isRegularFile", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isSameFile", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isSymbolicLink", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isWritable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "notExists", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "setLastModifiedTime", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "size", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.nio.file.spi.model.yml b/java/ql/lib/ext/java.nio.file.spi.model.yml index 0b6d1d89988..91e465af105 100644 --- a/java/ql/lib/ext/java.nio.file.spi.model.yml +++ b/java/ql/lib/ext/java.nio.file.spi.model.yml @@ -4,5 +4,5 @@ extensions: extensible: neutralModel data: # sink neutrals - - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "sink", "hq-manual"] - - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "sink", "hq-manual"] + - ["java.nio.file.spi", "FileSystemProvider", "isHidden", "", "sink", "hq-manual"] + - ["java.nio.file.spi", "FileSystemProvider", "isSameFile", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index 02e0eac7407..5b315e9986d 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -11,6 +11,6 @@ extensions: - ["java.text", "SimpleDateFormat", "SimpleDateFormat", "(String)", "summary", "manual"] # taint-numeric # sink neutrals - - ["java.text", "Collator" "compare", "", "sink", "hq-manual"] - - ["java.text", "Collator" "equals", "", "sink", "hq-manual"] + - ["java.text", "Collator", "compare", "", "sink", "hq-manual"] + - ["java.text", "Collator", "equals", "", "sink", "hq-manual"] - ["java.text", "RuleBasedCollator", "compare", "", "sink", "hq-manual"] From 24fc4ba2d4e056f9d0838efad8ee76bd0912240f Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 26 May 2023 18:53:55 -0400 Subject: [PATCH 152/739] Java: add tests --- .../neutralsinks/NeutralSinksTest.expected | 0 .../neutrals/neutralsinks/NeutralSinksTest.ql | 20 ++++ .../neutrals/neutralsinks/Test.java | 61 ++++++++++ .../neutrals/neutralsinks/options | 1 + .../http/protocol/RedirectLocations.java | 111 ++++++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected create mode 100644 java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql create mode 100644 java/ql/test/library-tests/neutrals/neutralsinks/Test.java create mode 100644 java/ql/test/library-tests/neutrals/neutralsinks/options create mode 100644 java/ql/test/stubs/apache-http-5/org/apache/hc/client5/http/protocol/RedirectLocations.java diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql new file mode 100644 index 00000000000..422508f5711 --- /dev/null +++ b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql @@ -0,0 +1,20 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.ExternalFlow + +class NeutralSinksTest extends InlineExpectationsTest { + NeutralSinksTest() { this = "NeutralSinksTest" } + + override string getARelevantTag() { result = "isSink" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "isSink" and + exists(DataFlow::Node sink | + sinkNode(sink, _) and + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/Test.java b/java/ql/test/library-tests/neutrals/neutralsinks/Test.java new file mode 100644 index 00000000000..fee2cbbb7dd --- /dev/null +++ b/java/ql/test/library-tests/neutrals/neutralsinks/Test.java @@ -0,0 +1,61 @@ +import java.io.File; +import java.nio.file.Files; +import java.nio.file.spi.FileSystemProvider; +import java.nio.file.LinkOption; +import java.text.Collator; +import java.text.RuleBasedCollator; +import java.util.prefs.AbstractPreferences; +import java.util.prefs.Preferences; +import org.apache.hc.client5.http.protocol.RedirectLocations; + +public class Test { + + public void test() throws Exception { + + // java.io + File file = null; + file.exists(); // Neutral Sink + file.compareTo(null); // Neutral Sink + + // java.nio.file + Files.exists(null, (LinkOption[])null); // Neutral Sink + Files.getLastModifiedTime(null, (LinkOption[])null); // Neutral Sink + Files.getOwner(null, (LinkOption[])null); // Neutral Sink + Files.getPosixFilePermissions(null, (LinkOption[])null); // Neutral Sink + Files.isDirectory(null, (LinkOption[])null); // Neutral Sink + Files.isExecutable(null); // Neutral Sink + Files.isHidden(null); // Neutral Sink + Files.isReadable(null); // Neutral Sink + Files.isRegularFile(null, (LinkOption[])null); // Neutral Sink + Files.isSameFile(null, null); // Neutral Sink + Files.isSymbolicLink(null); // Neutral Sink + Files.isWritable(null); // Neutral Sink + Files.notExists(null, (LinkOption[])null); // Neutral Sink + Files.setLastModifiedTime(null, null); // Neutral Sink + Files.size(null); // Neutral Sink + + // java.nio.file.spi + FileSystemProvider fsp = null; + fsp.isHidden(null); // Neutral Sink + fsp.isSameFile(null, null); // Neutral Sink + + // java.text + Collator c = null; + c.compare(null, null); // Neutral Sink + c.equals(null); // Neutral Sink + c.equals(null, null); // Neutral Sink + RuleBasedCollator rbc = null; + rbc.compare(null, null); // Neutral Sink + + // java.util.prefs + AbstractPreferences ap = null; + ap.nodeExists(null); // Neutral Sink + Preferences p = null; + p.nodeExists(null); // Neutral Sink + + // org.apache.hc.client5.http.protocol + RedirectLocations rl = null; + rl.contains(null); // Neutral Sink + } + +} diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/options b/java/ql/test/library-tests/neutrals/neutralsinks/options new file mode 100644 index 00000000000..6de6bb95285 --- /dev/null +++ b/java/ql/test/library-tests/neutrals/neutralsinks/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/apache-http-5 diff --git a/java/ql/test/stubs/apache-http-5/org/apache/hc/client5/http/protocol/RedirectLocations.java b/java/ql/test/stubs/apache-http-5/org/apache/hc/client5/http/protocol/RedirectLocations.java new file mode 100644 index 00000000000..ca717c54ebd --- /dev/null +++ b/java/ql/test/stubs/apache-http-5/org/apache/hc/client5/http/protocol/RedirectLocations.java @@ -0,0 +1,111 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + + package org.apache.hc.client5.http.protocol; + + import java.net.URI; + import java.util.ArrayList; + import java.util.HashSet; + import java.util.List; + import java.util.Set; + + /** + * This class represents a collection of {@link java.net.URI}s used + * as redirect locations. + * + * @since 4.0 + */ + public final class RedirectLocations { + + private final Set<URI> unique; + private final List<URI> all; + + public RedirectLocations() { + super(); + this.unique = new HashSet<>(); + this.all = new ArrayList<>(); + } + + /** + * Test if the URI is present in the collection. + */ + public boolean contains(final URI uri) { + return this.unique.contains(uri); + } + + /** + * Adds a new URI to the collection. + */ + public void add(final URI uri) { + this.unique.add(uri); + this.all.add(uri); + } + + /** + * Returns all redirect {@link URI}s in the order they were added to the collection. + * + * @return list of all URIs + * + * @since 4.1 + */ + public List<URI> getAll() { + return new ArrayList<>(this.all); + } + + /** + * Returns the URI at the specified position in this list. + * + * @param index + * index of the location to return + * @return the URI at the specified position in this list + * @throws IndexOutOfBoundsException + * if the index is out of range ( + * {@code index < 0 || index >= size()}) + * @since 4.3 + */ + public URI get(final int index) { + return this.all.get(index); + } + + /** + * Returns the number of elements in this list. If this list contains more + * than {@code Integer.MAX_VALUE} elements, returns + * {@code Integer.MAX_VALUE}. + * + * @return the number of elements in this list + * @since 4.3 + */ + public int size() { + return this.all.size(); + } + + public void clear() { + unique.clear(); + all.clear(); + } + + } From 486a5ac96f1682c352ee033ab39312b9ebf721eb Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Thu, 23 Feb 2023 21:23:05 +0100 Subject: [PATCH 153/739] v1 --- .../YAMLUnsafeYamlDeserialization.qhelp | 20 +++++ .../CWE-502/YAMLUnsafeYamlDeserialization.ql | 87 +++++++++++++++++++ .../CWE-502/YAMLUnsafeYamlDeserialization.rb | 20 +++++ .../YAMLUnsafeYamlDeserialization.expected | 70 +++++++++++++++ .../YAMLUnsafeYamlDeserialization.qlref | 1 + .../CWE-502/YAMLUnsafeYamlDeserialization.rb | 20 +++++ 6 files changed, 218 insertions(+) create mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp create mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql create mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb create mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected create mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref create mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp new file mode 100644 index 00000000000..821747e0b52 --- /dev/null +++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp @@ -0,0 +1,20 @@ +<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> +<qhelp> + <overview> + <p> + Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application. + Unsafe deserializing the malicious serialized yaml document through the Psych (YAML) library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain. + </p> + </overview> + <recommendation> + <p> + After Psych(YAML) 4.0.0, the load method is same as safe_load method. + This vulnerability can be prevented by using YAML.load (same as <code>YAML.safe_load</code>), <code>YAML.load_file</code> (same as <code>YAML.safe_load_file</code>) instead of <code>YAML.unsafe_*</code> methods. + Be careful that <code>YAML.load_stream</code> don't use safe_load method, Also Be careful the <code>to_ruby</code> method of Psych get called on a trusted parsed (<code>YAML.parse*</code>) yaml document. + </p> + </recommendation> + <example> + <p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> + <sample src="YAMLUnsafeYamlDeserialization.rb" /> + </example> +</qhelp> \ No newline at end of file diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql new file mode 100644 index 00000000000..668dc822b15 --- /dev/null +++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql @@ -0,0 +1,87 @@ +/** + * @name Deserialization of user-controlled data by YAML + * @description Deserializing user-controlled data may allow attackers to + * execute arbitrary code. + * @kind path-problem + * @problem.severity warning + * @security-severity 9.8 + * @precision high + * @id rb/YAML-unsafe-deserialization + * @tags security + * experimental + * external/cwe/cwe-502 + */ + +import codeql.ruby.AST +import codeql.ruby.ApiGraphs +import codeql.ruby.DataFlow +import codeql.ruby.dataflow.RemoteFlowSources +import codeql.ruby.TaintTracking +import DataFlow::PathGraph + +abstract class YAMLSink extends DataFlow::Node { } + +class YamlunsafeLoadArgument extends YAMLSink { + YamlunsafeLoadArgument() { + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]) + .getArgument(0) + or + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["unsafe_load", "load_stream"]) + .getKeywordArgument("yaml") + or + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall("unsafe_load_file") + .getKeywordArgument("filename") + } +} + +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "UnsafeDeserialization" } + + override predicate isSource(DataFlow::Node source) { + // for detecting The CVE we should uncomment following line instead of current RemoteFlowSource + source instanceof DataFlow::LocalSourceNode + // source instanceof RemoteFlowSource + } + + override predicate isSink(DataFlow::Node sink) { + // for detecting The CVE we should uncomment following line + // sink.getLocation().getFile().toString().matches("%yaml_column%") and + sink instanceof YAMLSink or + sink = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["parse", "parse_stream", "parse_file"]) + .getAMethodCall("to_ruby") + } + + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(DataFlow::CallNode yaml_parser_methods | + yaml_parser_methods = + API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and + ( + nodeFrom = yaml_parser_methods.getArgument(0) or + nodeFrom = yaml_parser_methods.getKeywordArgument("yaml") + ) and + nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") + ) + or + exists(DataFlow::CallNode yaml_parser_methods | + yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and + ( + nodeFrom = yaml_parser_methods.getArgument(0) or + nodeFrom = yaml_parser_methods.getKeywordArgument("filename") + ) and + nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") + ) + } +} + +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb new file mode 100644 index 00000000000..58ea8024350 --- /dev/null +++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb @@ -0,0 +1,20 @@ +require 'yaml' +class UsersController < ActionController::Base + def example + # safe + Psych.load(params[:yaml_string]) + Psych.load_file(params[:yaml_file]) + Psych.parse_stream(params[:yaml_string]) + Psych.parse(params[:yaml_string]) + Psych.parse_file(params[:yaml_file]) + # unsafe + Psych.unsafe_load(params[:yaml_string]) + Psych.unsafe_load_file(params[:yaml_file]) + Psych.load_stream(params[:yaml_string]) + Psych.parse_stream(params[:yaml_string]).to_ruby + Psych.parse(params[:yaml_string]).to_ruby + Psych.parse_file(params[:yaml_file]).to_ruby + + end +end + diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected new file mode 100644 index 00000000000..e274fb6f005 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected @@ -0,0 +1,70 @@ +edges +| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | +| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | +| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | +| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | +| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | +| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | +| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | +| file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | +| file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | +| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | +| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | +| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | +| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | +nodes +| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | semmle.label | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | semmle.label | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | semmle.label | ...[...] : | +| file://:0:0:0:0 | parameter self of [] : | semmle.label | parameter self of [] : | +| file://:0:0:0:0 | parameter self of [](:yaml_file) : | semmle.label | parameter self of [](:yaml_file) : | +| file://:0:0:0:0 | parameter self of [](:yaml_string) : | semmle.label | parameter self of [](:yaml_string) : | +subpaths +#select +| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_file) | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_file) | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref new file mode 100644 index 00000000000..7e9e87117f9 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref @@ -0,0 +1 @@ +experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb new file mode 100644 index 00000000000..58ea8024350 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb @@ -0,0 +1,20 @@ +require 'yaml' +class UsersController < ActionController::Base + def example + # safe + Psych.load(params[:yaml_string]) + Psych.load_file(params[:yaml_file]) + Psych.parse_stream(params[:yaml_string]) + Psych.parse(params[:yaml_string]) + Psych.parse_file(params[:yaml_file]) + # unsafe + Psych.unsafe_load(params[:yaml_string]) + Psych.unsafe_load_file(params[:yaml_file]) + Psych.load_stream(params[:yaml_string]) + Psych.parse_stream(params[:yaml_string]).to_ruby + Psych.parse(params[:yaml_string]).to_ruby + Psych.parse_file(params[:yaml_file]).to_ruby + + end +end + From e4b8a0e06dcfd027ea28bf73f0ab2c564d8c47e7 Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Thu, 23 Feb 2023 21:45:33 +0100 Subject: [PATCH 154/739] v1.1 --- .../experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql index 668dc822b15..e8b3fb761f4 100644 --- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql +++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql @@ -18,6 +18,7 @@ import codeql.ruby.DataFlow import codeql.ruby.dataflow.RemoteFlowSources import codeql.ruby.TaintTracking import DataFlow::PathGraph +import codeql.ruby.security.UnsafeDeserializationCustomizations abstract class YAMLSink extends DataFlow::Node { } @@ -45,8 +46,8 @@ class Configuration extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { // for detecting The CVE we should uncomment following line instead of current RemoteFlowSource - source instanceof DataFlow::LocalSourceNode - // source instanceof RemoteFlowSource + // source instanceof DataFlow::LocalSourceNode + source instanceof UnsafeDeserialization::Source } override predicate isSink(DataFlow::Node sink) { From d96153a05ef945a0768888096468662e7cb8656d Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Fri, 24 Feb 2023 09:28:16 +0100 Subject: [PATCH 155/739] v1.2 change to PascalCase --- .../experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql index e8b3fb761f4..7612c556d90 100644 --- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql +++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql @@ -20,10 +20,10 @@ import codeql.ruby.TaintTracking import DataFlow::PathGraph import codeql.ruby.security.UnsafeDeserializationCustomizations -abstract class YAMLSink extends DataFlow::Node { } +abstract class YamlSink extends DataFlow::Node { } -class YamlunsafeLoadArgument extends YAMLSink { - YamlunsafeLoadArgument() { +class YamlUnsafeLoadArgument extends YamlSink { + YamlUnsafeLoadArgument() { this = API::getTopLevelMember(["YAML", "Psych"]) .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]) @@ -53,7 +53,7 @@ class Configuration extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { // for detecting The CVE we should uncomment following line // sink.getLocation().getFile().toString().matches("%yaml_column%") and - sink instanceof YAMLSink or + sink instanceof YamlSink or sink = API::getTopLevelMember(["YAML", "Psych"]) .getAMethodCall(["parse", "parse_stream", "parse_file"]) From 0e343e5a12b9dbb83dd0db30d79b6c42894a6ba9 Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Fri, 24 Feb 2023 11:45:06 +0100 Subject: [PATCH 156/739] v1.3 --- .../CWE-502/YAMLUnsafeYamlDeserialization.ql | 20 +++--- .../CWE-502/YAMLUnsafeYamlDeserialization.rb | 4 +- .../YAMLUnsafeYamlDeserialization.expected | 72 +++++-------------- .../CWE-502/YAMLUnsafeYamlDeserialization.rb | 4 +- 4 files changed, 34 insertions(+), 66 deletions(-) diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql index 7612c556d90..a3f42a9c84e 100644 --- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql +++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql @@ -12,10 +12,8 @@ * external/cwe/cwe-502 */ -import codeql.ruby.AST import codeql.ruby.ApiGraphs import codeql.ruby.DataFlow -import codeql.ruby.dataflow.RemoteFlowSources import codeql.ruby.TaintTracking import DataFlow::PathGraph import codeql.ruby.security.UnsafeDeserializationCustomizations @@ -38,26 +36,28 @@ class YamlUnsafeLoadArgument extends YamlSink { API::getTopLevelMember(["YAML", "Psych"]) .getAMethodCall("unsafe_load_file") .getKeywordArgument("filename") + or + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["parse", "parse_stream", "parse_file"]) + .getAMethodCall("to_ruby") } } class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeDeserialization" } + Configuration() { this = "UnsafeYAMLDeserialization" } override predicate isSource(DataFlow::Node source) { - // for detecting The CVE we should uncomment following line instead of current RemoteFlowSource + // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source // source instanceof DataFlow::LocalSourceNode source instanceof UnsafeDeserialization::Source } override predicate isSink(DataFlow::Node sink) { - // for detecting The CVE we should uncomment following line + // after changing the isSource for detecting CVE-2022-32224 + // uncomment the following line only see the CVE sink not other files similar sinks // sink.getLocation().getFile().toString().matches("%yaml_column%") and - sink instanceof YamlSink or - sink = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["parse", "parse_stream", "parse_file"]) - .getAMethodCall("to_ruby") + sink instanceof YamlSink } override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb index 58ea8024350..6e836a0a049 100644 --- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb +++ b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb @@ -11,10 +11,12 @@ class UsersController < ActionController::Base Psych.unsafe_load(params[:yaml_string]) Psych.unsafe_load_file(params[:yaml_file]) Psych.load_stream(params[:yaml_string]) - Psych.parse_stream(params[:yaml_string]).to_ruby + parse_output = Psych.parse_stream(params[:yaml_string]) + parse_output.to_ruby Psych.parse(params[:yaml_string]).to_ruby Psych.parse_file(params[:yaml_file]).to_ruby end end + diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected index e274fb6f005..c01afdfbe69 100644 --- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected +++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected @@ -2,24 +2,12 @@ edges | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | -| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | -| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | -| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | -| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | -| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | -| file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | -| file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | -| file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | -| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | -| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | -| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | -| file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | nodes | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : | | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] | @@ -27,44 +15,20 @@ nodes | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] | | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : | | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | semmle.label | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | semmle.label | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | semmle.label | ...[...] : | -| file://:0:0:0:0 | parameter self of [] : | semmle.label | parameter self of [] : | -| file://:0:0:0:0 | parameter self of [](:yaml_file) : | semmle.label | parameter self of [](:yaml_file) : | -| file://:0:0:0:0 | parameter self of [](:yaml_string) : | semmle.label | parameter self of [](:yaml_string) : | +| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : | subpaths #select | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source | | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_file) | potentially untrusted source | | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:24:14:29 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:24:14:43 | ...[...] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:14:5:14:52 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:17:15:22 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:15:17:15:36 | ...[...] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_string) : | YAMLUnsafeYamlDeserialization.rb:15:5:15:45 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_string) | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:22:16:27 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:22:16:39 | ...[...] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | file://:0:0:0:0 | parameter self of [] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [] | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | file://:0:0:0:0 | parameter self of [](:yaml_file) : | YAMLUnsafeYamlDeserialization.rb:16:5:16:48 | call to to_ruby | This file extraction depends on a $@. | file://:0:0:0:0 | parameter self of [](:yaml_file) | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb index 58ea8024350..6e836a0a049 100644 --- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb +++ b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb @@ -11,10 +11,12 @@ class UsersController < ActionController::Base Psych.unsafe_load(params[:yaml_string]) Psych.unsafe_load_file(params[:yaml_file]) Psych.load_stream(params[:yaml_string]) - Psych.parse_stream(params[:yaml_string]).to_ruby + parse_output = Psych.parse_stream(params[:yaml_string]) + parse_output.to_ruby Psych.parse(params[:yaml_string]).to_ruby Psych.parse_file(params[:yaml_file]).to_ruby end end + From 0521ffe175243a5bd9071c2f9bb231ced31d3ece Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Fri, 24 Feb 2023 13:13:06 +0100 Subject: [PATCH 157/739] v1.4 correct dirs uppercase issue --- .../YAMLUnsafeYamlDeserialization.qhelp | 20 +++++ .../cwe-502/YAMLUnsafeYamlDeserialization.ql | 88 +++++++++++++++++++ .../cwe-502/YAMLUnsafeYamlDeserialization.rb | 22 +++++ .../YAMLUnsafeYamlDeserialization.expected | 34 +++++++ .../YAMLUnsafeYamlDeserialization.qlref | 1 + .../cwe-502/YAMLUnsafeYamlDeserialization.rb | 22 +++++ 6 files changed, 187 insertions(+) create mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp create mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql create mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp new file mode 100644 index 00000000000..821747e0b52 --- /dev/null +++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp @@ -0,0 +1,20 @@ +<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> +<qhelp> + <overview> + <p> + Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application. + Unsafe deserializing the malicious serialized yaml document through the Psych (YAML) library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain. + </p> + </overview> + <recommendation> + <p> + After Psych(YAML) 4.0.0, the load method is same as safe_load method. + This vulnerability can be prevented by using YAML.load (same as <code>YAML.safe_load</code>), <code>YAML.load_file</code> (same as <code>YAML.safe_load_file</code>) instead of <code>YAML.unsafe_*</code> methods. + Be careful that <code>YAML.load_stream</code> don't use safe_load method, Also Be careful the <code>to_ruby</code> method of Psych get called on a trusted parsed (<code>YAML.parse*</code>) yaml document. + </p> + </recommendation> + <example> + <p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> + <sample src="YAMLUnsafeYamlDeserialization.rb" /> + </example> +</qhelp> \ No newline at end of file diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql new file mode 100644 index 00000000000..a3f42a9c84e --- /dev/null +++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql @@ -0,0 +1,88 @@ +/** + * @name Deserialization of user-controlled data by YAML + * @description Deserializing user-controlled data may allow attackers to + * execute arbitrary code. + * @kind path-problem + * @problem.severity warning + * @security-severity 9.8 + * @precision high + * @id rb/YAML-unsafe-deserialization + * @tags security + * experimental + * external/cwe/cwe-502 + */ + +import codeql.ruby.ApiGraphs +import codeql.ruby.DataFlow +import codeql.ruby.TaintTracking +import DataFlow::PathGraph +import codeql.ruby.security.UnsafeDeserializationCustomizations + +abstract class YamlSink extends DataFlow::Node { } + +class YamlUnsafeLoadArgument extends YamlSink { + YamlUnsafeLoadArgument() { + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]) + .getArgument(0) + or + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["unsafe_load", "load_stream"]) + .getKeywordArgument("yaml") + or + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall("unsafe_load_file") + .getKeywordArgument("filename") + or + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["parse", "parse_stream", "parse_file"]) + .getAMethodCall("to_ruby") + } +} + +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "UnsafeYAMLDeserialization" } + + override predicate isSource(DataFlow::Node source) { + // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source + // source instanceof DataFlow::LocalSourceNode + source instanceof UnsafeDeserialization::Source + } + + override predicate isSink(DataFlow::Node sink) { + // after changing the isSource for detecting CVE-2022-32224 + // uncomment the following line only see the CVE sink not other files similar sinks + // sink.getLocation().getFile().toString().matches("%yaml_column%") and + sink instanceof YamlSink + } + + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(DataFlow::CallNode yaml_parser_methods | + yaml_parser_methods = + API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and + ( + nodeFrom = yaml_parser_methods.getArgument(0) or + nodeFrom = yaml_parser_methods.getKeywordArgument("yaml") + ) and + nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") + ) + or + exists(DataFlow::CallNode yaml_parser_methods | + yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and + ( + nodeFrom = yaml_parser_methods.getArgument(0) or + nodeFrom = yaml_parser_methods.getKeywordArgument("filename") + ) and + nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") + ) + } +} + +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb new file mode 100644 index 00000000000..6e836a0a049 --- /dev/null +++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb @@ -0,0 +1,22 @@ +require 'yaml' +class UsersController < ActionController::Base + def example + # safe + Psych.load(params[:yaml_string]) + Psych.load_file(params[:yaml_file]) + Psych.parse_stream(params[:yaml_string]) + Psych.parse(params[:yaml_string]) + Psych.parse_file(params[:yaml_file]) + # unsafe + Psych.unsafe_load(params[:yaml_string]) + Psych.unsafe_load_file(params[:yaml_file]) + Psych.load_stream(params[:yaml_string]) + parse_output = Psych.parse_stream(params[:yaml_string]) + parse_output.to_ruby + Psych.parse(params[:yaml_string]).to_ruby + Psych.parse_file(params[:yaml_file]).to_ruby + + end +end + + diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected new file mode 100644 index 00000000000..c01afdfbe69 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected @@ -0,0 +1,34 @@ +edges +| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | +nodes +| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : | +| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : | +| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : | +subpaths +#select +| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref new file mode 100644 index 00000000000..7e9e87117f9 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref @@ -0,0 +1 @@ +experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb new file mode 100644 index 00000000000..6e836a0a049 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb @@ -0,0 +1,22 @@ +require 'yaml' +class UsersController < ActionController::Base + def example + # safe + Psych.load(params[:yaml_string]) + Psych.load_file(params[:yaml_file]) + Psych.parse_stream(params[:yaml_string]) + Psych.parse(params[:yaml_string]) + Psych.parse_file(params[:yaml_file]) + # unsafe + Psych.unsafe_load(params[:yaml_string]) + Psych.unsafe_load_file(params[:yaml_file]) + Psych.load_stream(params[:yaml_string]) + parse_output = Psych.parse_stream(params[:yaml_string]) + parse_output.to_ruby + Psych.parse(params[:yaml_string]).to_ruby + Psych.parse_file(params[:yaml_file]).to_ruby + + end +end + + From 4360a56b45483b658e583f5a8684ce96b80d5b73 Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Sat, 25 Feb 2023 20:49:48 +0100 Subject: [PATCH 158/739] v2 add plist.parse_xml as a dangerous sink and enhancements on documents --- .../YAMLUnsafeYamlDeserialization.qhelp | 20 ----- .../CWE-502/YAMLUnsafeYamlDeserialization.ql | 88 ------------------- .../CWE-502/YAMLUnsafeYamlDeserialization.rb | 22 ----- .../PlistUnsafeYamlDeserialization.qhelp | 25 ++++++ .../cwe-502/PlistUnsafeYamlDeserialization.ql | 68 ++++++++++++++ .../cwe-502/PlistUnsafeYamlDeserialization.rb | 13 +++ .../YAMLUnsafeYamlDeserialization.qhelp | 6 ++ .../cwe-502/YAMLUnsafeYamlDeserialization.ql | 14 +-- .../YAMLUnsafeYamlDeserialization.expected | 34 ------- .../YAMLUnsafeYamlDeserialization.qlref | 1 - .../CWE-502/YAMLUnsafeYamlDeserialization.rb | 22 ----- .../PlistUnsafeYamlDeserialization.expected | 12 +++ .../PlistUnsafeYamlDeserialization.qlref | 1 + .../cwe-502/PlistUnsafeYamlDeserialization.rb | 13 +++ .../YAMLUnsafeYamlDeserialization.expected | 12 +-- .../YAMLUnsafeYamlDeserialization.qlref | 2 +- 16 files changed, 152 insertions(+), 201 deletions(-) delete mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp delete mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql delete mode 100644 ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb create mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp create mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql create mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb delete mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected delete mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref delete mode 100644 ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp deleted file mode 100644 index 821747e0b52..00000000000 --- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.qhelp +++ /dev/null @@ -1,20 +0,0 @@ -<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> -<qhelp> - <overview> - <p> - Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application. - Unsafe deserializing the malicious serialized yaml document through the Psych (YAML) library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain. - </p> - </overview> - <recommendation> - <p> - After Psych(YAML) 4.0.0, the load method is same as safe_load method. - This vulnerability can be prevented by using YAML.load (same as <code>YAML.safe_load</code>), <code>YAML.load_file</code> (same as <code>YAML.safe_load_file</code>) instead of <code>YAML.unsafe_*</code> methods. - Be careful that <code>YAML.load_stream</code> don't use safe_load method, Also Be careful the <code>to_ruby</code> method of Psych get called on a trusted parsed (<code>YAML.parse*</code>) yaml document. - </p> - </recommendation> - <example> - <p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> - <sample src="YAMLUnsafeYamlDeserialization.rb" /> - </example> -</qhelp> \ No newline at end of file diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql deleted file mode 100644 index a3f42a9c84e..00000000000 --- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @name Deserialization of user-controlled data by YAML - * @description Deserializing user-controlled data may allow attackers to - * execute arbitrary code. - * @kind path-problem - * @problem.severity warning - * @security-severity 9.8 - * @precision high - * @id rb/YAML-unsafe-deserialization - * @tags security - * experimental - * external/cwe/cwe-502 - */ - -import codeql.ruby.ApiGraphs -import codeql.ruby.DataFlow -import codeql.ruby.TaintTracking -import DataFlow::PathGraph -import codeql.ruby.security.UnsafeDeserializationCustomizations - -abstract class YamlSink extends DataFlow::Node { } - -class YamlUnsafeLoadArgument extends YamlSink { - YamlUnsafeLoadArgument() { - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]) - .getArgument(0) - or - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["unsafe_load", "load_stream"]) - .getKeywordArgument("yaml") - or - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall("unsafe_load_file") - .getKeywordArgument("filename") - or - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["parse", "parse_stream", "parse_file"]) - .getAMethodCall("to_ruby") - } -} - -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeYAMLDeserialization" } - - override predicate isSource(DataFlow::Node source) { - // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source - // source instanceof DataFlow::LocalSourceNode - source instanceof UnsafeDeserialization::Source - } - - override predicate isSink(DataFlow::Node sink) { - // after changing the isSource for detecting CVE-2022-32224 - // uncomment the following line only see the CVE sink not other files similar sinks - // sink.getLocation().getFile().toString().matches("%yaml_column%") and - sink instanceof YamlSink - } - - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::CallNode yaml_parser_methods | - yaml_parser_methods = - API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and - ( - nodeFrom = yaml_parser_methods.getArgument(0) or - nodeFrom = yaml_parser_methods.getKeywordArgument("yaml") - ) and - nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") - ) - or - exists(DataFlow::CallNode yaml_parser_methods | - yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and - ( - nodeFrom = yaml_parser_methods.getArgument(0) or - nodeFrom = yaml_parser_methods.getKeywordArgument("filename") - ) and - nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") - ) - } -} - -from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb deleted file mode 100644 index 6e836a0a049..00000000000 --- a/ruby/ql/src/experimental/CWE-502/YAMLUnsafeYamlDeserialization.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'yaml' -class UsersController < ActionController::Base - def example - # safe - Psych.load(params[:yaml_string]) - Psych.load_file(params[:yaml_file]) - Psych.parse_stream(params[:yaml_string]) - Psych.parse(params[:yaml_string]) - Psych.parse_file(params[:yaml_file]) - # unsafe - Psych.unsafe_load(params[:yaml_string]) - Psych.unsafe_load_file(params[:yaml_file]) - Psych.load_stream(params[:yaml_string]) - parse_output = Psych.parse_stream(params[:yaml_string]) - parse_output.to_ruby - Psych.parse(params[:yaml_string]).to_ruby - Psych.parse_file(params[:yaml_file]).to_ruby - - end -end - - diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp new file mode 100644 index 00000000000..80ec6c51dc0 --- /dev/null +++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp @@ -0,0 +1,25 @@ +<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> +<qhelp> + <overview> + <p> + Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application. + Unsafe deserializing the malicious serialized xml document through the Plist library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain. + </p> + </overview> + <recommendation> + <p> + This vulnerability can be prevented by using <code>Plist.parse_xml</code>. + </p> + </recommendation> + <example> + <p>In the example below, you can see safe and unsafe call of this dangerous method that can be abused by a remote user input. You can use "marshal: false" as an arugument for <code>Plist.parse_xml</code> to use it safe. + </p> + <sample src="PlistUnsafeYamlDeserialization.rb" /> + </example> + <references> + <li> + Security considerations from library documentation + <a href="https://github.com/patsplat/plist#label-Security+considerations">patsplat/plist</a>. + </li> + </references> +</qhelp> \ No newline at end of file diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql new file mode 100644 index 00000000000..02d554cffb6 --- /dev/null +++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql @@ -0,0 +1,68 @@ +/** + * @name Unsafe Deserialization of user-controlled data by Plist + * @description Deserializing user-controlled data may allow attackers to + * execute arbitrary code. + * @kind path-problem + * @problem.severity warning + * @security-severity 9.8 + * @precision high + * @id rb/Plist-unsafe-deserialization + * @tags security + * experimental + * external/cwe/cwe-502 + */ + +import codeql.ruby.ApiGraphs +import codeql.ruby.DataFlow +import codeql.ruby.TaintTracking +import codeql.ruby.CFG +import DataFlow::PathGraph +import codeql.ruby.security.UnsafeDeserializationCustomizations + +abstract class PlistUnsafeSinks extends DataFlow::Node { } + +/** + * check whether an input argument has desired "key: value" input or not. + * borrowed from UnsafeDeserialization module with some changes + */ +predicate checkkeyBalue(CfgNodes::ExprNodes::PairCfgNode p, string key, string value) { + p.getKey().getConstantValue().isStringlikeValue(key) and + DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().toString() = value +} + +/** + * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is + * the default), considered a sink for unsafe deserialization. + * borrowed from UnsafeDeserialization module with some changes + */ +class UnsafePlistParsexmlArgument extends PlistUnsafeSinks { + UnsafePlistParsexmlArgument() { + exists(DataFlow::CallNode plistParsexml | + plistParsexml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml") + | + this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and + // Exclude calls that explicitly pass a safe mode option. + checkkeyBalue(plistParsexml.getArgument(1).asExpr(), "marshal", "true") + or + this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and + plistParsexml.getNumberOfArguments() = 1 + ) + } +} + +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "PlistUnsafeDeserialization" } + + override predicate isSource(DataFlow::Node source) { + // to detect CVE-2021-33575, we should uncomment following line instead of current UnsafeDeserialization::Source + // source instanceof DataFlow::LocalSourceNode + source instanceof UnsafeDeserialization::Source + } + + override predicate isSink(DataFlow::Node sink) { sink instanceof PlistUnsafeSinks } +} + +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb new file mode 100644 index 00000000000..63f64b5cd22 --- /dev/null +++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb @@ -0,0 +1,13 @@ +require 'yaml' +class UsersController < ActionController::Base + def example + # not safe + result = Plist.parse_xml(params[:yaml_string]) + result = Plist.parse_xml(params[:yaml_string], marshal: true) + + # safe + result = Plist.parse_xml(params[:yaml_string], marshal: false) + end +end + + diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp index 821747e0b52..c3a74527483 100644 --- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp +++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp @@ -17,4 +17,10 @@ <p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> <sample src="YAMLUnsafeYamlDeserialization.rb" /> </example> + <references> + <li> + You can read that how unsafe yaml load methods can lead to code executions. + <a href="https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html">Universal Deserialisation Gadget for Ruby 2.x-3.x </a>. + </li> + </references> </qhelp> \ No newline at end of file diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql index a3f42a9c84e..5cb720d19da 100644 --- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql +++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql @@ -1,5 +1,5 @@ /** - * @name Deserialization of user-controlled data by YAML + * @name Unsafe Deserialization of user-controlled data by YAML * @description Deserializing user-controlled data may allow attackers to * execute arbitrary code. * @kind path-problem @@ -18,10 +18,10 @@ import codeql.ruby.TaintTracking import DataFlow::PathGraph import codeql.ruby.security.UnsafeDeserializationCustomizations -abstract class YamlSink extends DataFlow::Node { } +abstract class YamlUnsafeSinks extends DataFlow::Node { } -class YamlUnsafeLoadArgument extends YamlSink { - YamlUnsafeLoadArgument() { +class YamlUnsafeArgument extends YamlUnsafeSinks { + YamlUnsafeArgument() { this = API::getTopLevelMember(["YAML", "Psych"]) .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]) @@ -45,7 +45,7 @@ class YamlUnsafeLoadArgument extends YamlSink { } class Configuration extends TaintTracking::Configuration { - Configuration() { this = "UnsafeYAMLDeserialization" } + Configuration() { this = "YamlUnsafeDeserialization" } override predicate isSource(DataFlow::Node source) { // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source @@ -57,7 +57,7 @@ class Configuration extends TaintTracking::Configuration { // after changing the isSource for detecting CVE-2022-32224 // uncomment the following line only see the CVE sink not other files similar sinks // sink.getLocation().getFile().toString().matches("%yaml_column%") and - sink instanceof YamlSink + sink instanceof YamlUnsafeSinks } override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { @@ -84,5 +84,5 @@ class Configuration extends TaintTracking::Configuration { from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), +select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), "potentially untrusted source" diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected deleted file mode 100644 index c01afdfbe69..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.expected +++ /dev/null @@ -1,34 +0,0 @@ -edges -| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | -nodes -| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : | -subpaths -#select -| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref deleted file mode 100644 index 7e9e87117f9..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb deleted file mode 100644 index 6e836a0a049..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/CWE-502/YAMLUnsafeYamlDeserialization.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'yaml' -class UsersController < ActionController::Base - def example - # safe - Psych.load(params[:yaml_string]) - Psych.load_file(params[:yaml_file]) - Psych.parse_stream(params[:yaml_string]) - Psych.parse(params[:yaml_string]) - Psych.parse_file(params[:yaml_file]) - # unsafe - Psych.unsafe_load(params[:yaml_string]) - Psych.unsafe_load_file(params[:yaml_file]) - Psych.load_stream(params[:yaml_string]) - parse_output = Psych.parse_stream(params[:yaml_string]) - parse_output.to_ruby - Psych.parse(params[:yaml_string]).to_ruby - Psych.parse_file(params[:yaml_file]).to_ruby - - end -end - - diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected new file mode 100644 index 00000000000..f5da2a260c4 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected @@ -0,0 +1,12 @@ +edges +| PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | +| PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | +nodes +| PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | semmle.label | call to params : | +| PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] | +| PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | semmle.label | call to params : | +| PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] | +subpaths +#select +| PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params | potentially untrusted source | +| PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref new file mode 100644 index 00000000000..74d9d37315a --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref @@ -0,0 +1 @@ +experimental/cwe-502/PlistUnsafeYamlDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb new file mode 100644 index 00000000000..63f64b5cd22 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb @@ -0,0 +1,13 @@ +require 'yaml' +class UsersController < ActionController::Base + def example + # not safe + result = Plist.parse_xml(params[:yaml_string]) + result = Plist.parse_xml(params[:yaml_string], marshal: true) + + # safe + result = Plist.parse_xml(params[:yaml_string], marshal: false) + end +end + + diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected index c01afdfbe69..489602044a7 100644 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected @@ -26,9 +26,9 @@ nodes | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : | subpaths #select -| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | This file extraction depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source | +| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref index 7e9e87117f9..87fe2520217 100644 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref @@ -1 +1 @@ -experimental/CWE-502/YAMLUnsafeYamlDeserialization.ql \ No newline at end of file +experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql \ No newline at end of file From b9296d3df88084252074f69bae97e986095b3b83 Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Sat, 25 Feb 2023 23:08:31 +0100 Subject: [PATCH 159/739] v2.1 fix file names --- ...qhelp => PlistUnsafeDeserialization.qhelp} | 0 ...ation.ql => PlistUnsafeDeserialization.ql} | 0 ...ation.rb => PlistUnsafeDeserialization.rb} | 0 ....qhelp => YAMLUnsafeDeserialization.qhelp} | 0 ...zation.ql => YAMLUnsafeDeserialization.ql} | 0 ...zation.rb => YAMLUnsafeDeserialization.rb} | 0 .../PlistUnsafeDeserialization.expected | 12 +++++++ .../cwe-502/PlistUnsafeDeserialization.qlref | 1 + ...ation.rb => PlistUnsafeDeserialization.rb} | 0 .../PlistUnsafeYamlDeserialization.expected | 12 ------- .../PlistUnsafeYamlDeserialization.qlref | 1 - .../YAMLUnsafeDeserialization.expected | 34 +++++++++++++++++++ .../cwe-502/YAMLUnsafeDeserialization.qlref | 1 + ...zation.rb => YAMLUnsafeDeserialization.rb} | 0 .../YAMLUnsafeYamlDeserialization.expected | 34 ------------------- .../YAMLUnsafeYamlDeserialization.qlref | 1 - 16 files changed, 48 insertions(+), 48 deletions(-) rename ruby/ql/src/experimental/cwe-502/{PlistUnsafeYamlDeserialization.qhelp => PlistUnsafeDeserialization.qhelp} (100%) rename ruby/ql/src/experimental/cwe-502/{PlistUnsafeYamlDeserialization.ql => PlistUnsafeDeserialization.ql} (100%) rename ruby/ql/src/experimental/cwe-502/{PlistUnsafeYamlDeserialization.rb => PlistUnsafeDeserialization.rb} (100%) rename ruby/ql/src/experimental/cwe-502/{YAMLUnsafeYamlDeserialization.qhelp => YAMLUnsafeDeserialization.qhelp} (100%) rename ruby/ql/src/experimental/cwe-502/{YAMLUnsafeYamlDeserialization.ql => YAMLUnsafeDeserialization.ql} (100%) rename ruby/ql/src/experimental/cwe-502/{YAMLUnsafeYamlDeserialization.rb => YAMLUnsafeDeserialization.rb} (100%) create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref rename ruby/ql/test/query-tests/experimental/Security/cwe-502/{PlistUnsafeYamlDeserialization.rb => PlistUnsafeDeserialization.rb} (100%) delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected create mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref rename ruby/ql/test/query-tests/experimental/Security/cwe-502/{YAMLUnsafeYamlDeserialization.rb => YAMLUnsafeDeserialization.rb} (100%) delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp similarity index 100% rename from ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.qhelp rename to ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql similarity index 100% rename from ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.ql rename to ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb similarity index 100% rename from ruby/ql/src/experimental/cwe-502/PlistUnsafeYamlDeserialization.rb rename to ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp similarity index 100% rename from ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.qhelp rename to ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql similarity index 100% rename from ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql rename to ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.rb similarity index 100% rename from ruby/ql/src/experimental/cwe-502/YAMLUnsafeYamlDeserialization.rb rename to ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.rb diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected new file mode 100644 index 00000000000..967ef978a3b --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected @@ -0,0 +1,12 @@ +edges +| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | +| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | +nodes +| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | semmle.label | call to params : | +| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] | +| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | semmle.label | call to params : | +| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] | +subpaths +#select +| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | potentially untrusted source | +| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref new file mode 100644 index 00000000000..f7bfbada7b5 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref @@ -0,0 +1 @@ +experimental/cwe-502/PlistUnsafeDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.rb similarity index 100% rename from ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.rb rename to ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.rb diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected deleted file mode 100644 index f5da2a260c4..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.expected +++ /dev/null @@ -1,12 +0,0 @@ -edges -| PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | -| PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | -nodes -| PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | semmle.label | call to params : | -| PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] | -| PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | semmle.label | call to params : | -| PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] | -subpaths -#select -| PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeYamlDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeYamlDeserialization.rb:5:30:5:35 | call to params | potentially untrusted source | -| PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeYamlDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeYamlDeserialization.rb:6:30:6:35 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref deleted file mode 100644 index 74d9d37315a..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeYamlDeserialization.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/cwe-502/PlistUnsafeYamlDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected new file mode 100644 index 00000000000..9a9bd05e514 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected @@ -0,0 +1,34 @@ +edges +| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | +| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | +| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | +| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | +| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | +| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | +| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | +| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | +| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | +nodes +| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : | +| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : | +| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : | +| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : | +| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : | +| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : | +| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : | +| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : | +| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : | +subpaths +#select +| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | +| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | +| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | +| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source | +| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source | +| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref new file mode 100644 index 00000000000..e06e0921159 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref @@ -0,0 +1 @@ +experimental/cwe-502/YAMLUnsafeDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb similarity index 100% rename from ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.rb rename to ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected deleted file mode 100644 index 489602044a7..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.expected +++ /dev/null @@ -1,34 +0,0 @@ -edges -| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | -nodes -| YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : | -| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : | -| YAMLUnsafeYamlDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : | -subpaths -#select -| YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeYamlDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeYamlDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeYamlDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeYamlDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source | -| YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeYamlDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeYamlDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref deleted file mode 100644 index 87fe2520217..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeYamlDeserialization.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/cwe-502/YAMLUnsafeYamlDeserialization.ql \ No newline at end of file From ad7e107ff57da219b2abc185fc8e80020b302082 Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Wed, 1 Mar 2023 08:55:17 +0100 Subject: [PATCH 160/739] add the new YAML/PLIST sinks into the existing rb/unsafe-deserialization query --- .../UnsafeDeserializationCustomizations.qll | 59 ++++++++++++++++++- .../security/UnsafeDeserializationQuery.qll | 22 +++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll index 45e0888eacd..96f7e87d7a2 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll @@ -75,13 +75,41 @@ module UnsafeDeserialization { } /** - * An argument in a call to `YAML.load`, considered a sink + * An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered sinks * for unsafe deserialization. The `YAML` module is an alias of `Psych` in * recent versions of Ruby. */ class YamlLoadArgument extends Sink { YamlLoadArgument() { - this = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("load").getArgument(0) + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]) + .getArgument(0) + or + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["unsafe_load", "load_stream"]) + .getKeywordArgument("yaml") + or + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall("unsafe_load_file") + .getKeywordArgument("filename") + } + } + + /** + * An argument in a call to `YAML.parse*`, considered sinks + * for unsafe deserialization if there is a call to `to_ruby` on returned value of them, + * so this need some additional taint steps. The `YAML` module is an alias of `Psych` in + * recent versions of Ruby. + */ + class YamlParseArgument extends Sink { + YamlParseArgument() { + this = + API::getTopLevelMember(["YAML", "Psych"]) + .getAMethodCall(["parse", "parse_stream", "parse_file"]) + .getAMethodCall("to_ruby") } } @@ -208,4 +236,31 @@ module UnsafeDeserialization { ) } } + + /** + * check whether an input argument has desired "key: value" input or not. + */ + predicate checkkeyValue(CfgNodes::ExprNodes::PairCfgNode p, string key, string value) { + p.getKey().getConstantValue().isStringlikeValue(key) and + DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().toString() = value + } + + /** + * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is + * the default), considered a sink for unsafe deserialization. + */ + class UnsafePlistParsexmlArgument extends Sink { + UnsafePlistParsexmlArgument() { + exists(DataFlow::CallNode plistParsexml | + plistParsexml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml") + | + this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and + // Exclude calls that explicitly pass a safe mode option. + checkkeyValue(plistParsexml.getArgument(1).asExpr(), "marshal", "true") + or + this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and + plistParsexml.getNumberOfArguments() = 1 + ) + } + } } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll index dc6293dc10e..fed9160ccd9 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll @@ -9,6 +9,7 @@ private import codeql.ruby.AST private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking +private import codeql.ruby.ApiGraphs import UnsafeDeserializationCustomizations /** @@ -23,6 +24,27 @@ class Configuration extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserialization::Sink } + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(DataFlow::CallNode yaml_parser_methods | + yaml_parser_methods = + API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and + ( + nodeFrom = yaml_parser_methods.getArgument(0) or + nodeFrom = yaml_parser_methods.getKeywordArgument("yaml") + ) and + nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") + ) + or + exists(DataFlow::CallNode yaml_parser_methods | + yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and + ( + nodeFrom = yaml_parser_methods.getArgument(0) or + nodeFrom = yaml_parser_methods.getKeywordArgument("filename") + ) and + nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") + ) + } + override predicate isSanitizer(DataFlow::Node node) { super.isSanitizer(node) or node instanceof UnsafeDeserialization::Sanitizer From e76ed9454ab924a1b9a1f2a99711180938ade110 Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Wed, 1 Mar 2023 10:45:45 +0100 Subject: [PATCH 161/739] v3 add global taint steps for to_ruby of YAML/Psych --- ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll | 30 +++++++++++++++++++ .../security/UnsafeDeserializationQuery.qll | 21 ------------- 3 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index 29eacf22e33..e6f2d9681f3 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -33,3 +33,4 @@ private import codeql.ruby.frameworks.Sinatra private import codeql.ruby.frameworks.Twirp private import codeql.ruby.frameworks.Sqlite3 private import codeql.ruby.frameworks.Pg +private import codeql.ruby.frameworks.Yaml diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll new file mode 100644 index 00000000000..d1fe6547e56 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll @@ -0,0 +1,30 @@ +/** + * add additional steps for to_ruby method of YAML/Psych library + */ + +private import codeql.ruby.dataflow.FlowSteps +private import codeql.ruby.DataFlow +private import codeql.ruby.ApiGraphs + +private class YamlParseStep extends AdditionalTaintStep { + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + exists(DataFlow::CallNode yaml_parser_methods | + yaml_parser_methods = + API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and + ( + pred = yaml_parser_methods.getArgument(0) or + pred = yaml_parser_methods.getKeywordArgument("yaml") + ) and + succ = yaml_parser_methods.getAMethodCall("to_ruby") + ) + or + exists(DataFlow::CallNode yaml_parser_methods | + yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and + ( + pred = yaml_parser_methods.getArgument(0) or + pred = yaml_parser_methods.getKeywordArgument("filename") + ) and + succ = yaml_parser_methods.getAMethodCall("to_ruby") + ) + } +} diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll index fed9160ccd9..c4c5a39e451 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll @@ -24,27 +24,6 @@ class Configuration extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserialization::Sink } - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::CallNode yaml_parser_methods | - yaml_parser_methods = - API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and - ( - nodeFrom = yaml_parser_methods.getArgument(0) or - nodeFrom = yaml_parser_methods.getKeywordArgument("yaml") - ) and - nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") - ) - or - exists(DataFlow::CallNode yaml_parser_methods | - yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and - ( - nodeFrom = yaml_parser_methods.getArgument(0) or - nodeFrom = yaml_parser_methods.getKeywordArgument("filename") - ) and - nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") - ) - } - override predicate isSanitizer(DataFlow::Node node) { super.isSanitizer(node) or node instanceof UnsafeDeserialization::Sanitizer From 335441ce041893314eb377e154f4d11876f3eb6f Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Mon, 24 Apr 2023 10:43:09 +0200 Subject: [PATCH 162/739] v4: make variable names camelCase, some inhancement, remove some duplicates --- ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll | 41 ++++++++++------ .../UnsafeDeserializationCustomizations.qll | 48 ++++++++----------- .../security/UnsafeDeserializationQuery.qll | 1 - .../cwe-502/PlistUnsafeDeserialization.qhelp | 7 ++- .../cwe-502/PlistUnsafeDeserialization.ql | 25 +++------- .../cwe-502/PlistUnsafeDeserialization.rb | 6 ++- .../cwe-502/UnsafeDeserialization.qhelp | 23 +++++++++ .../examples/PlistUnsafeDeserialization.rb | 17 +++++++ .../examples/YAMLUnsafeDeserialization.rb | 22 +++++++++ 9 files changed, 123 insertions(+), 67 deletions(-) create mode 100644 ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb create mode 100644 ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll index d1fe6547e56..81afdcbed7b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll @@ -1,30 +1,43 @@ /** - * add additional steps for to_ruby method of YAML/Psych library + * Provides modeling for the `YAML` and `Psych` libraries. */ private import codeql.ruby.dataflow.FlowSteps private import codeql.ruby.DataFlow private import codeql.ruby.ApiGraphs +/** + * A taint step related to the result of `YAML.parse` calls, or similar. + *In the following example, this step will propagate taint from + *`source` to `sink`: + * + *```rb + *x = source + *result = YAML.parse(x) + *sink result.to_ruby # Unsafe call + * ``` + */ private class YamlParseStep extends AdditionalTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { - exists(DataFlow::CallNode yaml_parser_methods | - yaml_parser_methods = - API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and + exists(DataFlow::CallNode yamlParserMethod | + yamlParserMethod = yamlNode().getAMethodCall(["parse", "parse_stream"]) and ( - pred = yaml_parser_methods.getArgument(0) or - pred = yaml_parser_methods.getKeywordArgument("yaml") + pred = yamlParserMethod.getArgument(0) or + pred = yamlParserMethod.getKeywordArgument("yaml") ) and - succ = yaml_parser_methods.getAMethodCall("to_ruby") - ) - or - exists(DataFlow::CallNode yaml_parser_methods | - yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and + succ = yamlParserMethod.getAMethodCall("to_ruby") + or + yamlParserMethod = yamlNode().getAMethodCall("parse_file") and ( - pred = yaml_parser_methods.getArgument(0) or - pred = yaml_parser_methods.getKeywordArgument("filename") + pred = yamlParserMethod.getArgument(0) or + pred = yamlParserMethod.getKeywordArgument("filename") ) and - succ = yaml_parser_methods.getAMethodCall("to_ruby") + succ = yamlParserMethod.getAMethodCall("to_ruby") ) } } + +/** + * YAML/Psych Top level Class member + */ +private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll index 96f7e87d7a2..fcaceed1b3a 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll @@ -78,26 +78,27 @@ module UnsafeDeserialization { * An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered sinks * for unsafe deserialization. The `YAML` module is an alias of `Psych` in * recent versions of Ruby. + * the `this = yamlNode().getAMethodCall("load").getArgument(0)` is safe + * in recent versions of YAML library, so it will be removed in future. */ class YamlLoadArgument extends Sink { YamlLoadArgument() { - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]) - .getArgument(0) + this = yamlNode().getAMethodCall("load").getArgument(0) or this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["unsafe_load", "load_stream"]) - .getKeywordArgument("yaml") + yamlNode().getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]).getArgument(0) or - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall("unsafe_load_file") - .getKeywordArgument("filename") + this = yamlNode().getAMethodCall(["unsafe_load", "load_stream"]).getKeywordArgument("yaml") + or + this = yamlNode().getAMethodCall("unsafe_load_file").getKeywordArgument("filename") } } + /** + * YAML/Psych Top level Class member + */ + private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) } + /** * An argument in a call to `YAML.parse*`, considered sinks * for unsafe deserialization if there is a call to `to_ruby` on returned value of them, @@ -107,9 +108,7 @@ module UnsafeDeserialization { class YamlParseArgument extends Sink { YamlParseArgument() { this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["parse", "parse_stream", "parse_file"]) - .getAMethodCall("to_ruby") + yamlNode().getAMethodCall(["parse", "parse_stream", "parse_file"]).getAMethodCall("to_ruby") } } @@ -237,29 +236,20 @@ module UnsafeDeserialization { } } - /** - * check whether an input argument has desired "key: value" input or not. - */ - predicate checkkeyValue(CfgNodes::ExprNodes::PairCfgNode p, string key, string value) { - p.getKey().getConstantValue().isStringlikeValue(key) and - DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().toString() = value - } - /** * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is * the default), considered a sink for unsafe deserialization. */ class UnsafePlistParsexmlArgument extends Sink { UnsafePlistParsexmlArgument() { - exists(DataFlow::CallNode plistParsexml | - plistParsexml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml") + exists(DataFlow::CallNode plistParseXml | + plistParseXml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml") | - this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and - // Exclude calls that explicitly pass a safe mode option. - checkkeyValue(plistParsexml.getArgument(1).asExpr(), "marshal", "true") + this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and + plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true) or - this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and - plistParsexml.getNumberOfArguments() = 1 + this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and + plistParseXml.getNumberOfArguments() = 1 ) } } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll index c4c5a39e451..dc6293dc10e 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll @@ -9,7 +9,6 @@ private import codeql.ruby.AST private import codeql.ruby.DataFlow private import codeql.ruby.TaintTracking -private import codeql.ruby.ApiGraphs import UnsafeDeserializationCustomizations /** diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp index 80ec6c51dc0..45c4220c1b4 100644 --- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp +++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp @@ -8,18 +8,17 @@ </overview> <recommendation> <p> - This vulnerability can be prevented by using <code>Plist.parse_xml</code>. + This vulnerability in Plist can be prevented by calling <code>Plist.parse_xml FileOrXmlString, marshal: false</code>. </p> </recommendation> <example> - <p>In the example below, you can see safe and unsafe call of this dangerous method that can be abused by a remote user input. You can use "marshal: false" as an arugument for <code>Plist.parse_xml</code> to use it safe. + <p>In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for <code>Plist.parse_xml</code> to use it safe. </p> <sample src="PlistUnsafeYamlDeserialization.rb" /> </example> <references> <li> - Security considerations from library documentation - <a href="https://github.com/patsplat/plist#label-Security+considerations">patsplat/plist</a>. + Security considerations from library documentation: <a href="https://github.com/patsplat/plist#label-Security+considerations">patsplat/plist Repository</a>. </li> </references> </qhelp> \ No newline at end of file diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql index 02d554cffb6..4ba55824598 100644 --- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql +++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql @@ -6,7 +6,7 @@ * @problem.severity warning * @security-severity 9.8 * @precision high - * @id rb/Plist-unsafe-deserialization + * @id rb/plist-unsafe-deserialization * @tags security * experimental * external/cwe/cwe-502 @@ -21,31 +21,20 @@ import codeql.ruby.security.UnsafeDeserializationCustomizations abstract class PlistUnsafeSinks extends DataFlow::Node { } -/** - * check whether an input argument has desired "key: value" input or not. - * borrowed from UnsafeDeserialization module with some changes - */ -predicate checkkeyBalue(CfgNodes::ExprNodes::PairCfgNode p, string key, string value) { - p.getKey().getConstantValue().isStringlikeValue(key) and - DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().toString() = value -} - /** * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is * the default), considered a sink for unsafe deserialization. - * borrowed from UnsafeDeserialization module with some changes */ class UnsafePlistParsexmlArgument extends PlistUnsafeSinks { UnsafePlistParsexmlArgument() { - exists(DataFlow::CallNode plistParsexml | - plistParsexml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml") + exists(DataFlow::CallNode plistParseXml | + plistParseXml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml") | - this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and - // Exclude calls that explicitly pass a safe mode option. - checkkeyBalue(plistParsexml.getArgument(1).asExpr(), "marshal", "true") + this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and + plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true) or - this = [plistParsexml.getArgument(0), plistParsexml.getKeywordArgument("filename_or_xml")] and - plistParsexml.getNumberOfArguments() = 1 + this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and + plistParseXml.getNumberOfArguments() = 1 ) } } diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb index 63f64b5cd22..433873d6fa0 100644 --- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb +++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb @@ -1,12 +1,16 @@ -require 'yaml' +require 'plist' class UsersController < ActionController::Base def example # not safe + config = true result = Plist.parse_xml(params[:yaml_string]) + result = Plist.parse_xml(params[:yaml_string], marshal: config) result = Plist.parse_xml(params[:yaml_string], marshal: true) # safe + config = false result = Plist.parse_xml(params[:yaml_string], marshal: false) + result = Plist.parse_xml(params[:yaml_string], marshal: config) end end diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp index 406ba24935b..9ee9234770e 100644 --- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp +++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp @@ -17,6 +17,17 @@ libraries that support it, such as the Ruby standard library's <code>JSON</code> module, ensure that the parser is configured to disable deserialization of arbitrary objects. </p> + +<p> +YAML/Psych recommendation: +After Psych(YAML) 4.0.0, the load method is same as safe_load method. +This vulnerability can be prevented by using YAML.load (same as <code>YAML.safe_load</code>), <code>YAML.load_file</code> (same as <code>YAML.safe_load_file</code>) instead of <code>YAML.unsafe_*</code> methods. +Be careful that <code>YAML.load_stream</code> don't use safe_load method, Also Be careful the <code>to_ruby</code> method of Psych get called on a trusted parsed (<code>YAML.parse*</code>) yaml document. +</p> + +<p> +This vulnerability in Plist can be prevented by calling <code>Plist.parse_xml FileOrXmlString, marshal: false</code>. +</p> </recommendation> <example> @@ -27,6 +38,14 @@ on data from an HTTP request. Since these methods are capable of deserializing to arbitrary objects, this is inherently unsafe. </p> <sample src="examples/UnsafeDeserializationBad.rb"/> + +<p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> +<sample src="examples/YAMLUnsafeYamlDeserialization.rb"/> + +<p>In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for <code>Plist.parse_xml</code> to use it safe. +</p> +<sample src="examples/PlistUnsafeYamlDeserialization.rb"/> + <p> Using <code>JSON.parse</code> and <code>YAML.safe_load</code> instead, as in the following example, removes the vulnerability. Similarly, calling @@ -55,6 +74,10 @@ Ruby documentation: <a href="https://ruby-doc.org/stdlib-3.0.2/libdoc/json/rdoc/ <li> Ruby documentation: <a href="https://ruby-doc.org/stdlib-3.0.2/libdoc/yaml/rdoc/YAML.html#module-YAML-label-Security">security guidance on the YAML library</a>. </li> +<li> +You can read that how unsafe yaml load methods can lead to code executions: +<a href="https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html">Universal Deserialisation Gadget for Ruby 2.x-3.x </a>. +</li> </references> </qhelp> diff --git a/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb b/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb new file mode 100644 index 00000000000..433873d6fa0 --- /dev/null +++ b/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb @@ -0,0 +1,17 @@ +require 'plist' +class UsersController < ActionController::Base + def example + # not safe + config = true + result = Plist.parse_xml(params[:yaml_string]) + result = Plist.parse_xml(params[:yaml_string], marshal: config) + result = Plist.parse_xml(params[:yaml_string], marshal: true) + + # safe + config = false + result = Plist.parse_xml(params[:yaml_string], marshal: false) + result = Plist.parse_xml(params[:yaml_string], marshal: config) + end +end + + diff --git a/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb b/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb new file mode 100644 index 00000000000..6e836a0a049 --- /dev/null +++ b/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb @@ -0,0 +1,22 @@ +require 'yaml' +class UsersController < ActionController::Base + def example + # safe + Psych.load(params[:yaml_string]) + Psych.load_file(params[:yaml_file]) + Psych.parse_stream(params[:yaml_string]) + Psych.parse(params[:yaml_string]) + Psych.parse_file(params[:yaml_file]) + # unsafe + Psych.unsafe_load(params[:yaml_string]) + Psych.unsafe_load_file(params[:yaml_file]) + Psych.load_stream(params[:yaml_string]) + parse_output = Psych.parse_stream(params[:yaml_string]) + parse_output.to_ruby + Psych.parse(params[:yaml_string]).to_ruby + Psych.parse_file(params[:yaml_file]).to_ruby + + end +end + + From 40e24b6b94508d98dde7090dcd439714775f8bd0 Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Thu, 27 Apr 2023 06:35:34 +0200 Subject: [PATCH 163/739] v4.1 fix file names in qhelp --- .../src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp | 2 +- .../src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp | 2 +- .../src/queries/security/cwe-502/UnsafeDeserialization.qhelp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp index 45c4220c1b4..9863402d583 100644 --- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp +++ b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp @@ -14,7 +14,7 @@ <example> <p>In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for <code>Plist.parse_xml</code> to use it safe. </p> - <sample src="PlistUnsafeYamlDeserialization.rb" /> + <sample src="PlistUnsafeDeserialization.rb" /> </example> <references> <li> diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp index c3a74527483..c644f495271 100644 --- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp +++ b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp @@ -15,7 +15,7 @@ </recommendation> <example> <p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> - <sample src="YAMLUnsafeYamlDeserialization.rb" /> + <sample src="YAMLUnsafeDeserialization.rb" /> </example> <references> <li> diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp index 9ee9234770e..1ebf32750a1 100644 --- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp +++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp @@ -40,11 +40,11 @@ to arbitrary objects, this is inherently unsafe. <sample src="examples/UnsafeDeserializationBad.rb"/> <p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> -<sample src="examples/YAMLUnsafeYamlDeserialization.rb"/> +<sample src="examples/YAMLUnsafeDeserialization.rb"/> <p>In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for <code>Plist.parse_xml</code> to use it safe. </p> -<sample src="examples/PlistUnsafeYamlDeserialization.rb"/> +<sample src="examples/PlistUnsafeDeserialization.rb"/> <p> Using <code>JSON.parse</code> and <code>YAML.safe_load</code> instead, as in the From d727d573d5ce139e8356bfca8765fc4dbcc9caa4 Mon Sep 17 00:00:00 2001 From: amammad <amg2027amg@gmail.com> Date: Thu, 27 Apr 2023 06:48:15 +0200 Subject: [PATCH 164/739] v4.2 write exact version of yaml.load default loader change --- .../ruby/security/UnsafeDeserializationCustomizations.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll index fcaceed1b3a..9dea66252e5 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll @@ -79,7 +79,7 @@ module UnsafeDeserialization { * for unsafe deserialization. The `YAML` module is an alias of `Psych` in * recent versions of Ruby. * the `this = yamlNode().getAMethodCall("load").getArgument(0)` is safe - * in recent versions of YAML library, so it will be removed in future. + * in psych/yaml library after [v4.0.0](https://github.com/ruby/psych/releases/tag/v4.0.0), so it will be removed in future. */ class YamlLoadArgument extends Sink { YamlLoadArgument() { From b8c3cba4ff0fa9819982425cca1bf41dcbd0e2c0 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Fri, 26 May 2023 14:48:16 +0000 Subject: [PATCH 165/739] Ruby: Consolidate unsafe deserialization queries Merge the experimental YAMLUnsafeDeserialization and PlistUnsafeDeserialization queries into the generate UnsafeDeserialization query in the default suite. These queries look for some specific sinks that we now find in the general query. Also apply some small code and comment refactors. --- ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll | 34 +++---- .../UnsafeDeserializationCustomizations.qll | 25 +++--- .../cwe-502/PlistUnsafeDeserialization.qhelp | 24 ----- .../cwe-502/PlistUnsafeDeserialization.ql | 57 ------------ .../cwe-502/PlistUnsafeDeserialization.rb | 17 ---- .../cwe-502/YAMLUnsafeDeserialization.qhelp | 26 ------ .../cwe-502/YAMLUnsafeDeserialization.ql | 88 ------------------- .../cwe-502/UnsafeDeserialization.qhelp | 22 +++-- .../PlistUnsafeDeserialization.expected | 12 --- .../cwe-502/PlistUnsafeDeserialization.qlref | 1 - .../YAMLUnsafeDeserialization.expected | 34 ------- .../cwe-502/YAMLUnsafeDeserialization.qlref | 1 - .../cwe-502/YAMLUnsafeDeserialization.rb | 22 ----- .../PlistUnsafeDeserialization.rb | 0 .../UnsafeDeserialization.expected | 42 +++++++++ .../YAMLUnsafeDeserialization.rb | 0 16 files changed, 75 insertions(+), 330 deletions(-) delete mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp delete mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql delete mode 100644 ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb delete mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp delete mode 100644 ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref delete mode 100644 ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb rename ruby/ql/test/query-tests/{experimental/Security/cwe-502 => security/cwe-502/unsafe-deserialization}/PlistUnsafeDeserialization.rb (100%) rename ruby/ql/{src/experimental/cwe-502 => test/query-tests/security/cwe-502/unsafe-deserialization}/YAMLUnsafeDeserialization.rb (100%) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll index 81afdcbed7b..65596df7fe2 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Yaml.qll @@ -8,36 +8,28 @@ private import codeql.ruby.ApiGraphs /** * A taint step related to the result of `YAML.parse` calls, or similar. - *In the following example, this step will propagate taint from - *`source` to `sink`: + * In the following example, this step will propagate taint from + * `source` to `sink`: * - *```rb - *x = source - *result = YAML.parse(x) - *sink result.to_ruby # Unsafe call + * ```rb + * x = source + * result = YAML.parse(x) + * sink result.to_ruby # Unsafe call * ``` */ private class YamlParseStep extends AdditionalTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::CallNode yamlParserMethod | - yamlParserMethod = yamlNode().getAMethodCall(["parse", "parse_stream"]) and + succ = yamlParserMethod.getAMethodCall("to_ruby") and ( - pred = yamlParserMethod.getArgument(0) or - pred = yamlParserMethod.getKeywordArgument("yaml") - ) and - succ = yamlParserMethod.getAMethodCall("to_ruby") - or - yamlParserMethod = yamlNode().getAMethodCall("parse_file") and - ( - pred = yamlParserMethod.getArgument(0) or - pred = yamlParserMethod.getKeywordArgument("filename") - ) and - succ = yamlParserMethod.getAMethodCall("to_ruby") + yamlParserMethod = yamlNode().getAMethodCall(["parse", "parse_stream"]) and + pred = [yamlParserMethod.getArgument(0), yamlParserMethod.getKeywordArgument("yaml")] + or + yamlParserMethod = yamlNode().getAMethodCall("parse_file") and + pred = [yamlParserMethod.getArgument(0), yamlParserMethod.getKeywordArgument("filename")] + ) ) } } -/** - * YAML/Psych Top level Class member - */ private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) } diff --git a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll index 9dea66252e5..e38a38af2dc 100644 --- a/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll @@ -75,14 +75,13 @@ module UnsafeDeserialization { } /** - * An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered sinks + * An argument in a call to `YAML.unsafe_*` and `YAML.load_stream` , considered a sink * for unsafe deserialization. The `YAML` module is an alias of `Psych` in * recent versions of Ruby. - * the `this = yamlNode().getAMethodCall("load").getArgument(0)` is safe - * in psych/yaml library after [v4.0.0](https://github.com/ruby/psych/releases/tag/v4.0.0), so it will be removed in future. */ class YamlLoadArgument extends Sink { YamlLoadArgument() { + // Note: this is safe in psych/yaml >= 4.0.0. this = yamlNode().getAMethodCall("load").getArgument(0) or this = @@ -94,16 +93,11 @@ module UnsafeDeserialization { } } - /** - * YAML/Psych Top level Class member - */ private API::Node yamlNode() { result = API::getTopLevelMember(["YAML", "Psych"]) } /** - * An argument in a call to `YAML.parse*`, considered sinks - * for unsafe deserialization if there is a call to `to_ruby` on returned value of them, - * so this need some additional taint steps. The `YAML` module is an alias of `Psych` in - * recent versions of Ruby. + * An argument in a call to `YAML.parse*`, considered a sink for unsafe deserialization + * if there is a call to `to_ruby` on the returned value. */ class YamlParseArgument extends Sink { YamlParseArgument() { @@ -237,7 +231,7 @@ module UnsafeDeserialization { } /** - * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is + * An argument in a call to `Plist.parse_xml` where `marshal` is `true` (which is * the default), considered a sink for unsafe deserialization. */ class UnsafePlistParsexmlArgument extends Sink { @@ -246,10 +240,11 @@ module UnsafeDeserialization { plistParseXml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml") | this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and - plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true) - or - this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and - plistParseXml.getNumberOfArguments() = 1 + ( + plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true) + or + plistParseXml.getNumberOfArguments() = 1 + ) ) } } diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp deleted file mode 100644 index 9863402d583..00000000000 --- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.qhelp +++ /dev/null @@ -1,24 +0,0 @@ -<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> -<qhelp> - <overview> - <p> - Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application. - Unsafe deserializing the malicious serialized xml document through the Plist library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain. - </p> - </overview> - <recommendation> - <p> - This vulnerability in Plist can be prevented by calling <code>Plist.parse_xml FileOrXmlString, marshal: false</code>. - </p> - </recommendation> - <example> - <p>In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for <code>Plist.parse_xml</code> to use it safe. - </p> - <sample src="PlistUnsafeDeserialization.rb" /> - </example> - <references> - <li> - Security considerations from library documentation: <a href="https://github.com/patsplat/plist#label-Security+considerations">patsplat/plist Repository</a>. - </li> - </references> -</qhelp> \ No newline at end of file diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql deleted file mode 100644 index 4ba55824598..00000000000 --- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.ql +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @name Unsafe Deserialization of user-controlled data by Plist - * @description Deserializing user-controlled data may allow attackers to - * execute arbitrary code. - * @kind path-problem - * @problem.severity warning - * @security-severity 9.8 - * @precision high - * @id rb/plist-unsafe-deserialization - * @tags security - * experimental - * external/cwe/cwe-502 - */ - -import codeql.ruby.ApiGraphs -import codeql.ruby.DataFlow -import codeql.ruby.TaintTracking -import codeql.ruby.CFG -import DataFlow::PathGraph -import codeql.ruby.security.UnsafeDeserializationCustomizations - -abstract class PlistUnsafeSinks extends DataFlow::Node { } - -/** - * An argument in a call to `Plist.parse_xml` where the marshal is `true` (which is - * the default), considered a sink for unsafe deserialization. - */ -class UnsafePlistParsexmlArgument extends PlistUnsafeSinks { - UnsafePlistParsexmlArgument() { - exists(DataFlow::CallNode plistParseXml | - plistParseXml = API::getTopLevelMember("Plist").getAMethodCall("parse_xml") - | - this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and - plistParseXml.getKeywordArgument("marshal").getConstantValue().isBoolean(true) - or - this = [plistParseXml.getArgument(0), plistParseXml.getKeywordArgument("filename_or_xml")] and - plistParseXml.getNumberOfArguments() = 1 - ) - } -} - -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "PlistUnsafeDeserialization" } - - override predicate isSource(DataFlow::Node source) { - // to detect CVE-2021-33575, we should uncomment following line instead of current UnsafeDeserialization::Source - // source instanceof DataFlow::LocalSourceNode - source instanceof UnsafeDeserialization::Source - } - - override predicate isSink(DataFlow::Node sink) { sink instanceof PlistUnsafeSinks } -} - -from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb b/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb deleted file mode 100644 index 433873d6fa0..00000000000 --- a/ruby/ql/src/experimental/cwe-502/PlistUnsafeDeserialization.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'plist' -class UsersController < ActionController::Base - def example - # not safe - config = true - result = Plist.parse_xml(params[:yaml_string]) - result = Plist.parse_xml(params[:yaml_string], marshal: config) - result = Plist.parse_xml(params[:yaml_string], marshal: true) - - # safe - config = false - result = Plist.parse_xml(params[:yaml_string], marshal: false) - result = Plist.parse_xml(params[:yaml_string], marshal: config) - end -end - - diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp deleted file mode 100644 index c644f495271..00000000000 --- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.qhelp +++ /dev/null @@ -1,26 +0,0 @@ -<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> -<qhelp> - <overview> - <p> - Processing an unvalidated user input can allow an attacker to execute arbitrary code in your application. - Unsafe deserializing the malicious serialized yaml document through the Psych (YAML) library, making it possible to execute some code or execute arbitrary code with the help of a complete gadget chain. - </p> - </overview> - <recommendation> - <p> - After Psych(YAML) 4.0.0, the load method is same as safe_load method. - This vulnerability can be prevented by using YAML.load (same as <code>YAML.safe_load</code>), <code>YAML.load_file</code> (same as <code>YAML.safe_load_file</code>) instead of <code>YAML.unsafe_*</code> methods. - Be careful that <code>YAML.load_stream</code> don't use safe_load method, Also Be careful the <code>to_ruby</code> method of Psych get called on a trusted parsed (<code>YAML.parse*</code>) yaml document. - </p> - </recommendation> - <example> - <p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> - <sample src="YAMLUnsafeDeserialization.rb" /> - </example> - <references> - <li> - You can read that how unsafe yaml load methods can lead to code executions. - <a href="https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html">Universal Deserialisation Gadget for Ruby 2.x-3.x </a>. - </li> - </references> -</qhelp> \ No newline at end of file diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql b/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql deleted file mode 100644 index 5cb720d19da..00000000000 --- a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.ql +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @name Unsafe Deserialization of user-controlled data by YAML - * @description Deserializing user-controlled data may allow attackers to - * execute arbitrary code. - * @kind path-problem - * @problem.severity warning - * @security-severity 9.8 - * @precision high - * @id rb/YAML-unsafe-deserialization - * @tags security - * experimental - * external/cwe/cwe-502 - */ - -import codeql.ruby.ApiGraphs -import codeql.ruby.DataFlow -import codeql.ruby.TaintTracking -import DataFlow::PathGraph -import codeql.ruby.security.UnsafeDeserializationCustomizations - -abstract class YamlUnsafeSinks extends DataFlow::Node { } - -class YamlUnsafeArgument extends YamlUnsafeSinks { - YamlUnsafeArgument() { - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["unsafe_load_file", "unsafe_load", "load_stream"]) - .getArgument(0) - or - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["unsafe_load", "load_stream"]) - .getKeywordArgument("yaml") - or - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall("unsafe_load_file") - .getKeywordArgument("filename") - or - this = - API::getTopLevelMember(["YAML", "Psych"]) - .getAMethodCall(["parse", "parse_stream", "parse_file"]) - .getAMethodCall("to_ruby") - } -} - -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "YamlUnsafeDeserialization" } - - override predicate isSource(DataFlow::Node source) { - // to detect CVE-2022-32224, we should uncomment following line instead of current UnsafeDeserialization::Source - // source instanceof DataFlow::LocalSourceNode - source instanceof UnsafeDeserialization::Source - } - - override predicate isSink(DataFlow::Node sink) { - // after changing the isSource for detecting CVE-2022-32224 - // uncomment the following line only see the CVE sink not other files similar sinks - // sink.getLocation().getFile().toString().matches("%yaml_column%") and - sink instanceof YamlUnsafeSinks - } - - override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::CallNode yaml_parser_methods | - yaml_parser_methods = - API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall(["parse", "parse_stream"]) and - ( - nodeFrom = yaml_parser_methods.getArgument(0) or - nodeFrom = yaml_parser_methods.getKeywordArgument("yaml") - ) and - nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") - ) - or - exists(DataFlow::CallNode yaml_parser_methods | - yaml_parser_methods = API::getTopLevelMember(["YAML", "Psych"]).getAMethodCall("parse_file") and - ( - nodeFrom = yaml_parser_methods.getArgument(0) or - nodeFrom = yaml_parser_methods.getKeywordArgument("filename") - ) and - nodeTo = yaml_parser_methods.getAMethodCall("to_ruby") - ) - } -} - -from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp index 1ebf32750a1..17f03853570 100644 --- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp +++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp @@ -19,14 +19,19 @@ deserialization of arbitrary objects. </p> <p> -YAML/Psych recommendation: -After Psych(YAML) 4.0.0, the load method is same as safe_load method. -This vulnerability can be prevented by using YAML.load (same as <code>YAML.safe_load</code>), <code>YAML.load_file</code> (same as <code>YAML.safe_load_file</code>) instead of <code>YAML.unsafe_*</code> methods. -Be careful that <code>YAML.load_stream</code> don't use safe_load method, Also Be careful the <code>to_ruby</code> method of Psych get called on a trusted parsed (<code>YAML.parse*</code>) yaml document. +If deserializing an untrusted YAML document using the <code>psych</code> gem +prior to version 4.0.0, the <code>load</code> method is vulnerable. Use +<code>safe_load</code> instead. With <code>psych</code> version 4.0.0 and later, +the <code>load</code> is safe. The same applies to <code>load_file</code>. +<code>load_stream</code> is vulnerable in all versions. The safe versions of these +methods (<code>safe_load</code> and <code>safe_load_file</code>) are not vulnerable +in any known version. </p> <p> -This vulnerability in Plist can be prevented by calling <code>Plist.parse_xml FileOrXmlString, marshal: false</code>. +To safely deserialize <a href="https://en.wikipedia.org/wiki/Property_list">Property List</a> +files using the <code>plist</code> gem, ensure that you pass <code>marshal: false</code> +when calling <code>Plist.parse_xml</code>. </p> </recommendation> @@ -39,13 +44,6 @@ to arbitrary objects, this is inherently unsafe. </p> <sample src="examples/UnsafeDeserializationBad.rb"/> -<p>In the example below, you can see safe and unsafe methods get called by a remote user input. You can give correct authorization to users, or you can use safe methods for loading yaml documents.</p> -<sample src="examples/YAMLUnsafeDeserialization.rb"/> - -<p>In the example below, you can see safe and unsafe Plist dangerous method calls that can be abused by a remote user input. You can use "marshal: false" as an arugument for <code>Plist.parse_xml</code> to use it safe. -</p> -<sample src="examples/PlistUnsafeDeserialization.rb"/> - <p> Using <code>JSON.parse</code> and <code>YAML.safe_load</code> instead, as in the following example, removes the vulnerability. Similarly, calling diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected deleted file mode 100644 index 967ef978a3b..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.expected +++ /dev/null @@ -1,12 +0,0 @@ -edges -| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | -| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | -nodes -| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | semmle.label | call to params : | -| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] | -| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | semmle.label | call to params : | -| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] | -subpaths -#select -| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params : | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | potentially untrusted source | -| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params : | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref deleted file mode 100644 index f7bfbada7b5..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/cwe-502/PlistUnsafeDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected deleted file mode 100644 index 9a9bd05e514..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.expected +++ /dev/null @@ -1,34 +0,0 @@ -edges -| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | -| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | -| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | -| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | -| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | -| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | -| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | -| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | -| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | -nodes -| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | semmle.label | call to params : | -| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | semmle.label | call to params : | -| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | semmle.label | call to params : | -| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] | -| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | semmle.label | call to params : | -| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] : | semmle.label | ...[...] : | -| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | semmle.label | call to params : | -| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] : | semmle.label | ...[...] : | -| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby | -| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | semmle.label | call to params : | -| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] : | semmle.label | ...[...] : | -subpaths -#select -| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params : | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | potentially untrusted source | -| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params : | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | potentially untrusted source | -| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params : | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | potentially untrusted source | -| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params : | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | potentially untrusted source | -| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params : | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | potentially untrusted source | -| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params : | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref deleted file mode 100644 index e06e0921159..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/cwe-502/YAMLUnsafeDeserialization.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb b/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb deleted file mode 100644 index 6e836a0a049..00000000000 --- a/ruby/ql/test/query-tests/experimental/Security/cwe-502/YAMLUnsafeDeserialization.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'yaml' -class UsersController < ActionController::Base - def example - # safe - Psych.load(params[:yaml_string]) - Psych.load_file(params[:yaml_file]) - Psych.parse_stream(params[:yaml_string]) - Psych.parse(params[:yaml_string]) - Psych.parse_file(params[:yaml_file]) - # unsafe - Psych.unsafe_load(params[:yaml_string]) - Psych.unsafe_load_file(params[:yaml_file]) - Psych.load_stream(params[:yaml_string]) - parse_output = Psych.parse_stream(params[:yaml_string]) - parse_output.to_ruby - Psych.parse(params[:yaml_string]).to_ruby - Psych.parse_file(params[:yaml_file]).to_ruby - - end -end - - diff --git a/ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.rb b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/PlistUnsafeDeserialization.rb similarity index 100% rename from ruby/ql/test/query-tests/experimental/Security/cwe-502/PlistUnsafeDeserialization.rb rename to ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/PlistUnsafeDeserialization.rb diff --git a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected index 6fbbb14ef8a..b1f1d701a73 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected +++ b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected @@ -1,4 +1,6 @@ edges +| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | +| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | | UnsafeDeserialization.rb:10:5:10:19 | serialized_data | UnsafeDeserialization.rb:11:27:11:41 | serialized_data | | UnsafeDeserialization.rb:10:23:10:50 | call to decode64 | UnsafeDeserialization.rb:10:5:10:19 | serialized_data | | UnsafeDeserialization.rb:10:39:10:44 | call to params | UnsafeDeserialization.rb:10:39:10:50 | ...[...] | @@ -29,7 +31,21 @@ edges | UnsafeDeserialization.rb:87:5:87:13 | yaml_data | UnsafeDeserialization.rb:88:25:88:33 | yaml_data | | UnsafeDeserialization.rb:87:17:87:22 | call to params | UnsafeDeserialization.rb:87:17:87:28 | ...[...] | | UnsafeDeserialization.rb:87:17:87:28 | ...[...] | UnsafeDeserialization.rb:87:5:87:13 | yaml_data | +| YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | +| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | +| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | +| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | +| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] | +| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | +| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] | +| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | +| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] | +| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | nodes +| PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | semmle.label | call to params | +| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | semmle.label | ...[...] | +| PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | semmle.label | call to params | +| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | semmle.label | ...[...] | | UnsafeDeserialization.rb:10:5:10:19 | serialized_data | semmle.label | serialized_data | | UnsafeDeserialization.rb:10:23:10:50 | call to decode64 | semmle.label | call to decode64 | | UnsafeDeserialization.rb:10:39:10:44 | call to params | semmle.label | call to params | @@ -74,8 +90,27 @@ nodes | UnsafeDeserialization.rb:98:24:98:32 | call to read | semmle.label | call to read | | UnsafeDeserialization.rb:101:24:101:27 | call to gets | semmle.label | call to gets | | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | semmle.label | call to readlines | +| YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | semmle.label | call to params | +| YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | semmle.label | call to params | +| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | semmle.label | call to params | +| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | semmle.label | call to params | +| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | semmle.label | call to params | +| YAMLUnsafeDeserialization.rb:14:39:14:58 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | semmle.label | call to params | +| YAMLUnsafeDeserialization.rb:16:17:16:36 | ...[...] | semmle.label | ...[...] | +| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | semmle.label | call to to_ruby | +| YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | semmle.label | call to params | +| YAMLUnsafeDeserialization.rb:17:22:17:39 | ...[...] | semmle.label | ...[...] | subpaths #select +| PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | PlistUnsafeDeserialization.rb:5:30:5:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:5:30:5:35 | call to params | user-provided value | +| PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | PlistUnsafeDeserialization.rb:6:30:6:49 | ...[...] | Unsafe deserialization depends on a $@. | PlistUnsafeDeserialization.rb:6:30:6:35 | call to params | user-provided value | | UnsafeDeserialization.rb:11:27:11:41 | serialized_data | UnsafeDeserialization.rb:10:39:10:44 | call to params | UnsafeDeserialization.rb:11:27:11:41 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:10:39:10:44 | call to params | user-provided value | | UnsafeDeserialization.rb:17:30:17:44 | serialized_data | UnsafeDeserialization.rb:16:39:16:44 | call to params | UnsafeDeserialization.rb:17:30:17:44 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:16:39:16:44 | call to params | user-provided value | | UnsafeDeserialization.rb:23:24:23:32 | json_data | UnsafeDeserialization.rb:22:17:22:22 | call to params | UnsafeDeserialization.rb:23:24:23:32 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:22:17:22:22 | call to params | user-provided value | @@ -91,3 +126,10 @@ subpaths | UnsafeDeserialization.rb:98:24:98:32 | call to read | UnsafeDeserialization.rb:98:24:98:32 | call to read | UnsafeDeserialization.rb:98:24:98:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:98:24:98:32 | call to read | value from stdin | | UnsafeDeserialization.rb:101:24:101:27 | call to gets | UnsafeDeserialization.rb:101:24:101:27 | call to gets | UnsafeDeserialization.rb:101:24:101:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:101:24:101:27 | call to gets | value from stdin | | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:104:24:104:32 | call to readlines | value from stdin | +| YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | YAMLUnsafeDeserialization.rb:5:16:5:35 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:5:16:5:21 | call to params | user-provided value | +| YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | YAMLUnsafeDeserialization.rb:11:23:11:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:11:23:11:28 | call to params | user-provided value | +| YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | YAMLUnsafeDeserialization.rb:12:28:12:45 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:12:28:12:33 | call to params | user-provided value | +| YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | YAMLUnsafeDeserialization.rb:13:23:13:42 | ...[...] | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:13:23:13:28 | call to params | user-provided value | +| YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | YAMLUnsafeDeserialization.rb:15:5:15:24 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:14:39:14:44 | call to params | user-provided value | +| YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | YAMLUnsafeDeserialization.rb:16:5:16:45 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:16:17:16:22 | call to params | user-provided value | +| YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | YAMLUnsafeDeserialization.rb:17:5:17:48 | call to to_ruby | Unsafe deserialization depends on a $@. | YAMLUnsafeDeserialization.rb:17:22:17:27 | call to params | user-provided value | diff --git a/ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.rb b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/YAMLUnsafeDeserialization.rb similarity index 100% rename from ruby/ql/src/experimental/cwe-502/YAMLUnsafeDeserialization.rb rename to ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/YAMLUnsafeDeserialization.rb From 562065f29e6fd387534e517942e89f907117a290 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Sat, 27 May 2023 00:59:36 +0000 Subject: [PATCH 166/739] Ruby: Add change note --- ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md diff --git a/ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md b/ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md new file mode 100644 index 00000000000..4039e7c90dc --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-05-27-unsafe-deserialization.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Additional sinks for `rb/unsafe-deserialization` have been added. This includes various methods from the `yaml` and `plist` gems, which deserialize YAML and Property List data, respectively. From e515981c81d1fd82d586de9bc4afa8f5e4988470 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Sat, 27 May 2023 12:01:00 +0000 Subject: [PATCH 167/739] Ruby: Remove unused examples --- .../examples/PlistUnsafeDeserialization.rb | 17 -------------- .../examples/YAMLUnsafeDeserialization.rb | 22 ------------------- 2 files changed, 39 deletions(-) delete mode 100644 ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb delete mode 100644 ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb diff --git a/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb b/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb deleted file mode 100644 index 433873d6fa0..00000000000 --- a/ruby/ql/src/queries/security/cwe-502/examples/PlistUnsafeDeserialization.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'plist' -class UsersController < ActionController::Base - def example - # not safe - config = true - result = Plist.parse_xml(params[:yaml_string]) - result = Plist.parse_xml(params[:yaml_string], marshal: config) - result = Plist.parse_xml(params[:yaml_string], marshal: true) - - # safe - config = false - result = Plist.parse_xml(params[:yaml_string], marshal: false) - result = Plist.parse_xml(params[:yaml_string], marshal: config) - end -end - - diff --git a/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb b/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb deleted file mode 100644 index 6e836a0a049..00000000000 --- a/ruby/ql/src/queries/security/cwe-502/examples/YAMLUnsafeDeserialization.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'yaml' -class UsersController < ActionController::Base - def example - # safe - Psych.load(params[:yaml_string]) - Psych.load_file(params[:yaml_file]) - Psych.parse_stream(params[:yaml_string]) - Psych.parse(params[:yaml_string]) - Psych.parse_file(params[:yaml_file]) - # unsafe - Psych.unsafe_load(params[:yaml_string]) - Psych.unsafe_load_file(params[:yaml_file]) - Psych.load_stream(params[:yaml_string]) - parse_output = Psych.parse_stream(params[:yaml_string]) - parse_output.to_ruby - Psych.parse(params[:yaml_string]).to_ruby - Psych.parse_file(params[:yaml_file]).to_ruby - - end -end - - From ca1024e2858c6f541c5adef4e0405dbc6b7625f1 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Mon, 29 May 2023 03:46:30 +0000 Subject: [PATCH 168/739] Ruby: Reword unsafe deserialization qhelp --- .../security/cwe-502/UnsafeDeserialization.qhelp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp index 17f03853570..8bacb266423 100644 --- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp +++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp @@ -19,13 +19,12 @@ deserialization of arbitrary objects. </p> <p> -If deserializing an untrusted YAML document using the <code>psych</code> gem -prior to version 4.0.0, the <code>load</code> method is vulnerable. Use -<code>safe_load</code> instead. With <code>psych</code> version 4.0.0 and later, -the <code>load</code> is safe. The same applies to <code>load_file</code>. -<code>load_stream</code> is vulnerable in all versions. The safe versions of these -methods (<code>safe_load</code> and <code>safe_load_file</code>) are not vulnerable -in any known version. +If deserializing an untrusted YAML document using the <code>psych</code> gem, +prefer the <code>safe_load</code> and <code>safe_load_file</code> methods over +<code>load</code> and <code>load_file</code>, as the former will safely +handle untrusted data. Avoid passing untrusted data to the <code>load_stream</code> +method. In <code>psych</code> version 4.0.0 and above, the <code>load</code> can +safely be used. </p> <p> From e70e3e52dcf7456465fdc6f59e687f08293c40d2 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Mon, 29 May 2023 04:05:42 +0000 Subject: [PATCH 169/739] Ruby: fix typo in qhelp --- .../ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp index 8bacb266423..e361b62338e 100644 --- a/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp +++ b/ruby/ql/src/queries/security/cwe-502/UnsafeDeserialization.qhelp @@ -23,7 +23,7 @@ If deserializing an untrusted YAML document using the <code>psych</code> gem, prefer the <code>safe_load</code> and <code>safe_load_file</code> methods over <code>load</code> and <code>load_file</code>, as the former will safely handle untrusted data. Avoid passing untrusted data to the <code>load_stream</code> -method. In <code>psych</code> version 4.0.0 and above, the <code>load</code> can +method. In <code>psych</code> version 4.0.0 and above, the <code>load</code> method can safely be used. </p> From 6386ef3b962cb6a16c9c09f4842a1383982a18da Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 29 May 2023 09:58:52 +0200 Subject: [PATCH 170/739] Further perf improvements --- java/ql/src/utils/stub-generator/Stubs.qll | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/java/ql/src/utils/stub-generator/Stubs.qll b/java/ql/src/utils/stub-generator/Stubs.qll index a42a806455e..889bc6b466c 100644 --- a/java/ql/src/utils/stub-generator/Stubs.qll +++ b/java/ql/src/utils/stub-generator/Stubs.qll @@ -287,18 +287,23 @@ private string stubQualifier(RefType t) { pragma[nomagic] private predicate needsPackageNameHelper(RefType t, GeneratedTopLevel top, string name) { - t.getSourceDeclaration() = [getAReferencedType(top), top].getSourceDeclaration() and + t.getSourceDeclaration() = + pragma[only_bind_out]([getAReferencedType(top), top].getSourceDeclaration()) and name = t.getName() } +pragma[nomagic] +private predicate describesMultipleTypes(GeneratedTopLevel top, string name) { + 2 <= strictcount(RefType t | needsPackageNameHelper(t, top, name)) +} + /** * Holds if `t` may clash with another type of the same name, so should be referred to using the fully qualified name */ private predicate needsPackageName(RefType t) { - exists(GeneratedTopLevel top, RefType other, string name | + exists(GeneratedTopLevel top, string name | needsPackageNameHelper(t, top, name) and - needsPackageNameHelper(other, top, name) and - t != other + describesMultipleTypes(top, name) ) } From 2d81e30d8191fcb749de6d3e95ffd3536eba674d Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg <aeisenberg@github.com> Date: Mon, 29 May 2023 13:45:41 -0700 Subject: [PATCH 171/739] Fix `addsTo.pack` references This change is a prerequisite for a CLI change where there will be strict testing of the `addsTo.pack` values. It must resolve to a pack reference that is a transitive dependency of the current query's pack. --- .../lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml | 2 +- .../src/utils/flowtestcasegenerator/GenerateFlowTestCase.py | 4 ++-- java/ql/test/ext/TestModels/test.ext.yml | 2 +- .../kotlin/library-tests/dataflow/notnullexpr/test.ext.yml | 2 +- .../test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml | 2 +- .../library-tests/dataflow/callback-dispatch/test.ext.yml | 3 +-- .../library-tests/dataflow/collections/containerflow.ext.yml | 2 +- .../test/library-tests/dataflow/external-models/sinks.ext.yml | 2 +- .../test/library-tests/dataflow/external-models/srcs.ext.yml | 2 +- .../test/library-tests/dataflow/external-models/steps.ext.yml | 2 +- java/ql/test/library-tests/dataflow/synth-global/test.ext.yml | 2 +- .../android/content-provider-summaries/test.ext.yml | 2 +- .../test/library-tests/frameworks/android/intent/test.ext.yml | 2 +- .../frameworks/android/notification/test.ext.yml | 2 +- .../library-tests/frameworks/apache-collections/test.ext.yml | 2 +- .../ql/test/library-tests/frameworks/apache-http/flow.ext.yml | 2 +- .../frameworks/guava/generated/collect/test.ext.yml | 2 +- .../ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml | 2 +- .../library-tests/frameworks/netty/generated/test.ext.yml | 2 +- java/ql/test/library-tests/frameworks/stream/test.ext.yml | 2 +- java/ql/test/library-tests/optional/test.ext.yml | 2 +- 21 files changed, 22 insertions(+), 23 deletions(-) diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml index a2789520908..c9515372645 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: sinkModel data: - ["org.apache.hc.core5.http.impl.bootstrap", "HttpAsyncRequester", True, "connect", "(HttpHost,Timeout)", "", "Argument[0]", "open-url", "hq-manual"] diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py index 5e35ca52dd1..1cc943a78ec 100755 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py @@ -18,7 +18,7 @@ GenerateFlowTestCase.py specsToTest projectPom.xml outdir [--force] This generates test cases exercising function model specifications found in specsToTest producing files Test.java, test.ql, test.ext.yml and test.expected in outdir. -specsToTest should either be a .csv file, a .yml file, or a directory of .yml files, containing the +specsToTest should either be a .csv file, a .yml file, or a directory of .yml files, containing the model specifications to test. projectPom.xml should be a Maven pom sufficient to resolve the classes named in specsToTest.csv. @@ -276,7 +276,7 @@ if len(supportModelRows) != 0: modelSpecRow[0].strip() for modelSpecRow in supportModelRows) dataextensions = f"""extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: {models} diff --git a/java/ql/test/ext/TestModels/test.ext.yml b/java/ql/test/ext/TestModels/test.ext.yml index 4fff7d575a3..c5873214f71 100644 --- a/java/ql/test/ext/TestModels/test.ext.yml +++ b/java/ql/test/ext/TestModels/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml index 589c787bf9a..700f3f51e6f 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml +++ b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["", "Uri", False, "getQueryParameter", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml index 589c787bf9a..700f3f51e6f 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml +++ b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["", "Uri", False, "getQueryParameter", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml index 5f35c923ad0..a153e39a0e0 100644 --- a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml +++ b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["my.callback.qltest", "A", False, "applyConsumer1", "(Object,Consumer1)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] @@ -15,4 +15,3 @@ extensions: - ["my.callback.qltest", "A", False, "produceConsume", "(Producer1,Consumer3)", "", "Argument[1].Parameter[0]", "ReturnValue", "value", "manual"] - ["my.callback.qltest", "A", False, "applyConverter1", "(Object,Converter1)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] - ["my.callback.qltest", "A", False, "applyConverter1", "(Object,Converter1)", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] - diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml b/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml index ebe7e3b6ea5..c12a0156d0c 100644 --- a/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml +++ b/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["", "B", False, "readElement", "(Spliterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml b/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml index 55a76b79b21..d469a2de0dc 100644 --- a/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml +++ b/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: sinkModel data: - ["my.qltest", "B", False, "sink1", "(Object)", "", "Argument[0]", "qltest", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml b/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml index 7730d41e549..9693152f1c0 100644 --- a/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml +++ b/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: sourceModel data: - ["my.qltest", "A", False, "src1", "()", "", "ReturnValue", "qltest", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml index 41d26cf815a..c6a1fb69d6d 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml +++ b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["my.qltest", "C", False, "stepArgRes", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml b/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml index 3d3bbe9fd47..58b4d2ecc24 100644 --- a/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml +++ b/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["my.qltest.synth", "A", False, "storeInArray", "(String)", "", "Argument[0]", "SyntheticGlobal[db1].ArrayElement", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml index cf5c80bc456..06781456552 100644 --- a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml b/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml index 31321102a46..0a3ce554bc7 100644 --- a/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newBundleWithMapValue", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml b/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml index bd5c804fddc..69b416a5b72 100644 --- a/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "getMapKeyDefault", "(Bundle)", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml b/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml index a5d1cc8e1ab..60531154074 100644 --- a/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newRBWithMapValue", "", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/apache-http/flow.ext.yml b/java/ql/test/library-tests/frameworks/apache-http/flow.ext.yml index ff32ab78646..6e41b8a4e24 100644 --- a/java/ql/test/library-tests/frameworks/apache-http/flow.ext.yml +++ b/java/ql/test/library-tests/frameworks/apache-http/flow.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Client", False, "getURIBuilder_pathDefault", "(Object)", "", "Argument[0].SyntheticField[org.apache.http.client.utils.URIBuilder.path]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml index 153b649a3e6..e711fa15ecc 100644 --- a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newWithElementDefault", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml b/java/ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml index 35050f48ec0..230733b3ebc 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "getThrowable_messageDefault", "(Object)", "", "Argument[0].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml b/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml index f6b69f08632..47a199c75f1 100644 --- a/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/stream/test.ext.yml b/java/ql/test/library-tests/frameworks/stream/test.ext.yml index 4f1cc3e38ac..a304f9542a4 100644 --- a/java/ql/test/library-tests/frameworks/stream/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/stream/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "getElementSpliterator", "(Spliterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/optional/test.ext.yml b/java/ql/test/library-tests/optional/test.ext.yml index 2aebf3bdb97..24842526782 100644 --- a/java/ql/test/library-tests/optional/test.ext.yml +++ b/java/ql/test/library-tests/optional/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "getStreamElement", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] From 53aecb1949dce5c6254bb94c4be6cbac16353d1e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 00:17:04 +0000 Subject: [PATCH 172/739] Add changed framework coverage reports --- csharp/documentation/library-coverage/coverage.csv | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/csharp/documentation/library-coverage/coverage.csv b/csharp/documentation/library-coverage/coverage.csv index 9c900cf79cd..a4a6a534105 100644 --- a/csharp/documentation/library-coverage/coverage.csv +++ b/csharp/documentation/library-coverage/coverage.csv @@ -1,9 +1,9 @@ -package,sink,source,summary,sink:code,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:html,sink:remote,sink:sql,sink:xss,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value -Dapper,55,,,,,,,,,,55,,,,,,, +package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:sql-injection,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value +Dapper,55,,,,,,,,,,,55,,,,,, JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,7, -Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,28,,,,,,, +Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,28,,,,,, Microsoft.CSharp,,,24,,,,,,,,,,,,,,24, -Microsoft.EntityFrameworkCore,6,,12,,,,,,,,6,,,,,,,12 +Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,6,,,,,,12 Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,15, Microsoft.Extensions.Caching.Memory,,,46,,,,,,,,,,,,,,45,1 Microsoft.Extensions.Configuration,,,83,,,,,,,,,,,,,,80,3 @@ -21,8 +21,8 @@ Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,1, Microsoft.NETCore.Platforms.BuildTasks,,,4,,,,,,,,,,,,,,4, Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,5,5 Microsoft.Win32,,,8,,,,,,,,,,,,,,8, -MySql.Data.MySqlClient,48,,,,,,,,,,48,,,,,,, +MySql.Data.MySqlClient,48,,,,,,,,,,,48,,,,,, Newtonsoft.Json,,,91,,,,,,,,,,,,,,73,18 -ServiceStack,194,,7,27,,,,,,75,92,,,,,,7, -System,65,25,12157,,8,8,9,,4,,33,3,1,17,3,4,10163,1994 +ServiceStack,194,,7,27,,,,,75,,,92,,,,,7, +System,65,25,12157,,8,8,9,,,4,3,33,1,17,3,4,10163,1994 Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,, From 39a07d42a1bca7edaffc56b4ec5beb6c621da668 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 04:03:50 +0000 Subject: [PATCH 173/739] Bump chrono from 0.4.24 to 0.4.25 in /ql Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.24 to 0.4.25. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.24...v0.4.25) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> --- ql/Cargo.lock | Bin 31708 -> 31667 bytes ql/buramu/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/Cargo.lock b/ql/Cargo.lock index 60a0ad5919a43dba84fa52a6aa9930bd588cf198..76437a85e057d43e2bf6bd6efa08833e2d6e19f3 100644 GIT binary patch delta 197 zcmWlTJ8l9o6aWQ*0)-YKktRV(gZS8f#&4}OThPN5{C+2(;u<~xJr!sVlO~r)MVrlN z`k9~SpnDGP%i(BqzDV62X7#u^wwimQrvTBwgD2;RJ#Yx(k~X|I!;r*N0^bxyrGP1C zB%)|)u70fM-P>?6slV^1)`S>PdP~+lu{IvTp!5OslF5J*Mo}dytcArXNg+{8YUH3k cUgq_>9#8%s%egGq_51a+n@;1l3tzYP4_iJx6951J delta 203 zcmXxcF-k*05CBjTkf5YXktU%0UimxoXLg66#2ZL%u)DJpQW!AA-YbN?M^N?}9>D_$ z9w4nYmalp3Jo-A1-n()89?vf8+v4eAD40o{^vqEWK+U6PDAZ@OtOcW|U=YI)l5?0S zusRFuAtd(o_&Bd^+D*2*L)nyl`<&k2{iFV@(+YqTF^DCkULp)x&?tkH#7PVMeMy3f m^^O@?%_ykPY@S%MO8r<~U)^-O*XP^AK5pwvw`dp3)9M$zN<X0h diff --git a/ql/buramu/Cargo.toml b/ql/buramu/Cargo.toml index c478297f5b8..a84be37dbd7 100644 --- a/ql/buramu/Cargo.toml +++ b/ql/buramu/Cargo.toml @@ -7,6 +7,6 @@ edition = "2018" [dependencies] lazy_static = "1.4.0" -chrono = "0.4.24" +chrono = "0.4.25" rayon = "1.7.0" regex = "1.8.3" From d4b964c8491401dd5236d5b94f441709f5383d2f Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Tue, 30 May 2023 10:25:36 +0200 Subject: [PATCH 174/739] add support for sanitizers --- .../AutomodelApplicationModeCharacteristics.qll | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 785b56d31da..4e753a4479d 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -15,6 +15,7 @@ private import semmle.code.java.security.QueryInjection private import semmle.code.java.security.RequestForgery private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions private import AutomodelSharedUtil as AutomodelSharedUtil +private import semmle.code.java.security.PathSanitizer as PathSanitizer import AutomodelSharedCharacteristics as SharedCharacteristics import AutomodelEndpointTypes as AutomodelEndpointTypes @@ -48,7 +49,19 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig class RelatedLocationType = JavaRelatedLocationType; // Sanitizers are currently not modeled in MaD. TODO: check if this has large negative impact. - predicate isSanitizer(Endpoint e, EndpointType t) { none() } + predicate isSanitizer(Endpoint e, EndpointType t) { + ( + exists(t) and + e.getType() instanceof BoxedType + or + e.getType() instanceof PrimitiveType + or + e.getType() instanceof NumberType + ) + or + t instanceof AutomodelEndpointTypes::TaintedPathSinkType and + e instanceof PathSanitizer::PathInjectionSanitizer + } RelatedLocation asLocation(Endpoint e) { result = e.asExpr() } From d50617202746b8cbb8558f8486975a804e9a71fd Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 30 May 2023 09:11:00 +0100 Subject: [PATCH 175/739] Swift: Change note. --- swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md diff --git a/swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md b/swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md new file mode 100644 index 00000000000..03de16f4269 --- /dev/null +++ b/swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* Incorporated the cross-language `SensitiveDataHeuristics.qll` heuristics library into the Swift `SensitiveExprs.qll` library. This adds a number of new heuristics enhancing detection from the library. \ No newline at end of file From 138bfad3d06c7ba84690f0e291721b91c9bfc174 Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Tue, 30 May 2023 12:00:31 +0200 Subject: [PATCH 176/739] Add change note --- csharp/ql/lib/change-notes/2023-05-30-source-generators.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2023-05-30-source-generators.md diff --git a/csharp/ql/lib/change-notes/2023-05-30-source-generators.md b/csharp/ql/lib/change-notes/2023-05-30-source-generators.md new file mode 100644 index 00000000000..5483ce6af35 --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-05-30-source-generators.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* The extractor has been changed to run after the traced compiler call. This allows inspecting compiler generated files, such as the output of source generators. With this change, `.cshtml` files and their generated `.cshtml.g.cs` counterparts are extracted on dotnet 6 and above. From 47b2d48da25ed1cd49c4e3dd5647b362477f2682 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 17 May 2023 23:16:59 +0200 Subject: [PATCH 177/739] python: add tests - add `getACallSimple` to `SummarizedCallable` (by adding it to `LibraryCallable`) --- .../new/internal/DataFlowDispatch.qll | 3 + .../typetracking-summaries/TestSummaries.qll | 189 ++++++++++++++++++ .../typetracking-summaries/summaries.py | 60 ++++++ .../typetracking-summaries/tracked.expected | 0 .../typetracking-summaries/tracked.ql | 36 ++++ 5 files changed, 288 insertions(+) create mode 100644 python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll create mode 100644 python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py create mode 100644 python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected create mode 100644 python/ql/test/experimental/dataflow/typetracking-summaries/tracked.ql diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index cdca96cc4ac..8dad2e8a032 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -250,6 +250,9 @@ abstract class LibraryCallable extends string { /** Gets a call to this library callable. */ abstract CallCfgNode getACall(); + /** Same as `getACall` but without referring to the call graph or API graph. */ + CallCfgNode getACallSimple() { none() } + /** Gets a data-flow node, where this library callable is used as a call-back. */ abstract ArgumentNode getACallback(); } diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll b/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll new file mode 100644 index 00000000000..1a6a504e1ee --- /dev/null +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll @@ -0,0 +1,189 @@ +private import python +private import semmle.python.dataflow.new.FlowSummary +private import semmle.python.ApiGraphs + +/** + * This module ensures that the `callStep` predicate in + * our type tracker implelemtation does not refer to the + * `getACall` predicate on `SummarizedCallable`. + */ +module RecursionGuard { + private import semmle.python.dataflow.new.internal.TypeTrackerSpecific as TT + + private class RecursionGuard extends SummarizedCallable { + RecursionGuard() { this = "RecursionGuard" } + + override DataFlow::CallCfgNode getACall() { + result.getFunction().asCfgNode().(NameNode).getId() = this and + (TT::callStep(_, _) implies any()) + } + + override DataFlow::CallCfgNode getACallSimple() { none() } + + override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this } + } + + predicate test(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + TT::levelStepNoCall(nodeFrom, nodeTo) + } +} + +private class SummarizedCallableIdentity extends SummarizedCallable { + SummarizedCallableIdentity() { this = "identity" } + + override DataFlow::CallCfgNode getACall() { none() } + + override DataFlow::CallCfgNode getACallSimple() { + result.getFunction().asCfgNode().(NameNode).getId() = this + } + + override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = true + } +} + +// For lambda flow to work, implement lambdaCall and lambdaCreation +private class SummarizedCallableApplyLambda extends SummarizedCallable { + SummarizedCallableApplyLambda() { this = "apply_lambda" } + + override DataFlow::CallCfgNode getACall() { none() } + + override DataFlow::CallCfgNode getACallSimple() { + result.getFunction().asCfgNode().(NameNode).getId() = this + } + + override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[1]" and + output = "Argument[0].Parameter[0]" and + preservesValue = true + or + input = "Argument[0].ReturnValue" and + output = "ReturnValue" and + preservesValue = true + } +} + +private class SummarizedCallableReversed extends SummarizedCallable { + SummarizedCallableReversed() { this = "reversed" } + + override DataFlow::CallCfgNode getACall() { none() } + + override DataFlow::CallCfgNode getACallSimple() { + result.getFunction().asCfgNode().(NameNode).getId() = this + } + + override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0].ListElement" and + output = "ReturnValue.ListElement" and + preservesValue = true + } +} + +private class SummarizedCallableMap extends SummarizedCallable { + SummarizedCallableMap() { this = "list_map" } + + override DataFlow::CallCfgNode getACall() { none() } + + override DataFlow::CallCfgNode getACallSimple() { + result.getFunction().asCfgNode().(NameNode).getId() = this + } + + override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[1].ListElement" and + output = "Argument[0].Parameter[0]" and + preservesValue = true + or + input = "Argument[0].ReturnValue" and + output = "ReturnValue.ListElement" and + preservesValue = true + } +} + +private class SummarizedCallableAppend extends SummarizedCallable { + SummarizedCallableAppend() { this = "append_to_list" } + + override DataFlow::CallCfgNode getACall() { none() } + + override DataFlow::CallCfgNode getACallSimple() { + result.getFunction().asCfgNode().(NameNode).getId() = this + } + + override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + or + input = "Argument[1]" and + output = "ReturnValue.ListElement" and + preservesValue = true + } +} + +private class SummarizedCallableJsonLoads extends SummarizedCallable { + SummarizedCallableJsonLoads() { this = "json.loads" } + + override DataFlow::CallCfgNode getACall() { + result = API::moduleImport("json").getMember("loads").getACall() + } + + override DataFlow::CallCfgNode getACallSimple() { none() } + + override DataFlow::ArgumentNode getACallback() { + result = API::moduleImport("json").getMember("loads").getAValueReachableFromSource() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and + output = "ReturnValue.ListElement" and + preservesValue = true + } +} + +// read and store +private class SummarizedCallableReadSecret extends SummarizedCallable { + SummarizedCallableReadSecret() { this = "read_secret" } + + override DataFlow::CallCfgNode getACall() { none() } + + override DataFlow::CallCfgNode getACallSimple() { + result.getFunction().asCfgNode().(NameNode).getId() = this + } + + override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0].Attribute[secret]" and + output = "ReturnValue" and + preservesValue = true + } +} + +private class SummarizedCallableSetSecret extends SummarizedCallable { + SummarizedCallableSetSecret() { this = "set_secret" } + + override DataFlow::CallCfgNode getACall() { none() } + + override DataFlow::CallCfgNode getACallSimple() { + result.getFunction().asCfgNode().(NameNode).getId() = this + } + + override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[1]" and + output = "Argument[0].Attribute[secret]" and + preservesValue = true + } +} diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py new file mode 100644 index 00000000000..f7affa6036f --- /dev/null +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py @@ -0,0 +1,60 @@ +import sys +import os + +# Simple summary +tainted = identity(tracked) # $ tracked +tainted # $ MISSING: tracked + +# Lambda summary +# I think the missing result is expected because type tracking +# is not allowed to flow back out of a call. +tainted_lambda = apply_lambda(lambda x: x, tracked) # $ tracked +tainted_lambda # $ MISSING: tracked + +# A lambda that directly introduces taint +bad_lambda = apply_lambda(lambda x: tracked, 1) # $ tracked +bad_lambda # $ MISSING: tracked + +# A lambda that breaks the flow +untainted_lambda = apply_lambda(lambda x: 1, tracked) # $ tracked +untainted_lambda + +# Collection summaries +tainted_list = reversed([tracked]) # $ tracked +tl = tainted_list[0] +tl # $ MISSING: tracked + +# Complex summaries +def add_colon(x): + return x + ":" + +tainted_mapped = list_map(add_colon, [tracked]) # $ tracked +tm = tainted_mapped[0] +tm # $ MISSING: tracked + +def explicit_identity(x): + return x + +tainted_mapped_explicit = list_map(explicit_identity, [tracked]) # $ tracked +tainted_mapped_explicit[0] # $ MISSING: tracked + +tainted_mapped_summary = list_map(identity, [tracked]) # $ tracked +tms = tainted_mapped_summary[0] +tms # $ MISSING: tracked + +another_tainted_list = append_to_list([], tracked) # $ tracked +atl = another_tainted_list[0] +atl # $ MISSING: tracked + +from json import loads as json_loads +tainted_resultlist = json_loads(tracked) # $ tracked +tr = tainted_resultlist[0] +tr # $ MISSING: tracked + +x.secret = tracked # $ tracked=secret tracked +r = read_secret(x) # $ tracked=secret MISSING: tracked +r # $ MISSING: tracked + +y # $ MISSING: tracked=secret +set_secret(y, tracked) # $ tracked MISSING: tracked=secret +y.secret # $ MISSING: tracked tracked=secret \ No newline at end of file diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected b/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.ql b/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.ql new file mode 100644 index 00000000000..e5bf62053a0 --- /dev/null +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.ql @@ -0,0 +1,36 @@ +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TypeTracker +import TestUtilities.InlineExpectationsTest +import semmle.python.ApiGraphs +import TestSummaries + +// ----------------------------------------------------------------------------- +// tracked +// ----------------------------------------------------------------------------- +private DataFlow::TypeTrackingNode tracked(TypeTracker t) { + t.start() and + result.asCfgNode() = any(NameNode n | n.getId() = "tracked") + or + exists(TypeTracker t2 | result = tracked(t2).track(t2, t)) +} + +class TrackedTest extends InlineExpectationsTest { + TrackedTest() { this = "TrackedTest" } + + override string getARelevantTag() { result = "tracked" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node e, TypeTracker t | + exists(e.getLocation().getFile().getRelativePath()) and + e.getLocation().getStartLine() > 0 and + tracked(t).flowsTo(e) and + // Module variables have no sensible location, and hence can't be annotated. + not e instanceof DataFlow::ModuleVariableNode and + tag = "tracked" and + location = e.getLocation() and + value = t.getAttr() and + element = e.toString() + ) + } +} From 73aa790cdd37f09cec4ae97c5efed4d1a5cfc02a Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Tue, 30 May 2023 11:22:26 +0000 Subject: [PATCH 178/739] Java: Improve sampling strategy Instead of the "random" sampling used before (which could -- in rare circumstances -- end up sampling fewer points than we want) we now sample an equally distributed set of points. --- .../AutomodelApplicationModeExtractNegativeExamples.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index 0fe785de26b..d817d3a244a 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -18,7 +18,7 @@ private import AutomodelSharedUtil */ bindingset[limit] Endpoint getSampleForCharacteristic(EndpointCharacteristic c, int limit) { - exists(int n | + exists(int n, int num_endpoints | num_endpoints = count(Endpoint e | c.appliesToEndpoint(e)) | result = rank[n](Endpoint e, Location loc | loc = e.getLocation() and c.appliesToEndpoint(e) @@ -29,7 +29,7 @@ Endpoint getSampleForCharacteristic(EndpointCharacteristic c, int limit) { loc.getEndLine(), loc.getEndColumn() ) and // we order the endpoints by location, but (to avoid bias) we select the indices semi-randomly - n = 1 + (([1 .. limit] * 271) % count(Endpoint e | c.appliesToEndpoint(e))) + n = 1 + (([0 .. limit - 1] * (num_endpoints / limit).floor() + 46337) % num_endpoints) ) } From 2daa9577bbbcdf762fb00c96dcd20849245e75b0 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 16 May 2023 14:20:29 +0200 Subject: [PATCH 179/739] ruby/python: implement shared module ruby: - create new shared file `SummaryTypeTracker.qll` - move much logic into the module - instantiate the module - remove old logic, now provided by module python: - clone shared file - instantiate module - use (some of the) steps provided by the module --- config/identical-files.json | 4 + .../new/internal/SummaryTypeTracker.qll | 382 ++++++++++++++++++ .../new/internal/TypeTrackerSpecific.qll | 128 +++++- .../typetracking-summaries/summaries.py | 14 +- .../ruby/typetracking/SummaryTypeTracker.qll | 382 ++++++++++++++++++ .../ruby/typetracking/TypeTrackerSpecific.qll | 370 +++++------------ 6 files changed, 1011 insertions(+), 269 deletions(-) create mode 100644 python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll create mode 100644 ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll diff --git a/config/identical-files.json b/config/identical-files.json index 29fae2d3855..3d84e84dc9c 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -522,6 +522,10 @@ "python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll", "ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll" ], + "SummaryTypeTracker": [ + "python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll", + "ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll" + ], "AccessPathSyntax": [ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/AccessPathSyntax.qll", "go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll", diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll new file mode 100644 index 00000000000..310dec3aadf --- /dev/null +++ b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll @@ -0,0 +1,382 @@ +/** + * Provides the implementation of a summary type tracker, that is type tracking through flow summaries. + * To use this, you must implement the `Input` signature. You can then use the predicates in the `Output` + * signature to implement the predicates of the same names inside `TypeTrackerSpecific.qll`. + */ + +/** The classes and predicates needed to generate a summary type tracker. */ +signature module Input { + // Dataflow nodes + class Node; + + // Content + class TypeTrackerContent; + + class TypeTrackerContentFilter; + + // Relating content and filters + /** + * Gets a content filter to use for a `WithoutContent[content]` step, or has no result if + * the step should be treated as ordinary flow. + * + * `WithoutContent` is often used to perform strong updates on individual collection elements, but for + * type-tracking this is rarely beneficial and quite expensive. However, `WithoutContent` can be quite useful + * for restricting the type of an object, and in these cases we translate it to a filter. + */ + TypeTrackerContentFilter getFilterFromWithoutContentStep(TypeTrackerContent content); + + /** + * Gets a content filter to use for a `WithContent[content]` step, or has no result if + * the step cannot be handled by type-tracking. + * + * `WithContent` is often used to perform strong updates on individual collection elements (or rather + * to preserve those that didn't get updated). But for type-tracking this is rarely beneficial and quite expensive. + * However, `WithContent` can be quite useful for restricting the type of an object, and in these cases we translate it to a filter. + */ + TypeTrackerContentFilter getFilterFromWithContentStep(TypeTrackerContent content); + + // Summaries and their stacks + class SummaryComponent; + + class SummaryComponentStack { + SummaryComponent head(); + } + + /** Gets a singleton stack containing `component`. */ + SummaryComponentStack singleton(SummaryComponent component); + + /** + * Gets the stack obtained by pushing `head` onto `tail`. + */ + SummaryComponentStack push(SummaryComponent component, SummaryComponentStack stack); + + /** Gets a singleton stack representing a return. */ + SummaryComponent return(); + + // Relating content to summaries + /** Gets a summary component for content `c`. */ + SummaryComponent content(TypeTrackerContent contents); + + /** Gets a summary component where data is not allowed to be stored in `c`. */ + SummaryComponent withoutContent(TypeTrackerContent contents); + + /** Gets a summary component where data must be stored in `c`. */ + SummaryComponent withContent(TypeTrackerContent contents); + + // Callables + class SummarizedCallable { + predicate propagatesFlow( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ); + } + + // Relating nodes to summaries + /** Gets a dataflow node respresenting the argument of `call` indicated by `arg`. */ + Node argumentOf(Node call, SummaryComponent arg); + + /** Gets a dataflow node respresenting the parameter of `callable` indicated by `param`. */ + Node parameterOf(Node callable, SummaryComponent param); + + /** Gets a dataflow node respresenting the return of `callable` indicated by `return`. */ + Node returnOf(Node callable, SummaryComponent return); + + // Specific summary handling + /** Holds if component should be treated as a level step by type tracking. */ + predicate componentLevelStep(SummaryComponent component); + + /** Holds if the given component can't be evaluated by `evaluateSummaryComponentStackLocal`. */ + predicate isNonLocal(SummaryComponent component); + + // Relating callables to nodes + /** Gets a dataflow node respresenting a call to `callable`. */ + Node callTo(SummarizedCallable callable); +} + +/** + * The predicates provided by a summary type tracker. + * These are meant to be used in `TypeTrackerSpecific.qll` + * inside the predicates of the same names. + */ +signature module Output<Input I> { + /** + * Holds if there is a level step from `nodeFrom` to `nodeTo`, which does not depend on the call graph. + */ + predicate levelStepNoCall(I::Node nodeFrom, I::Node nodeTo); + + /** + * Holds if `nodeTo` is the result of accessing the `content` content of `nodeFrom`. + */ + predicate basicLoadStep(I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent content); + + /** + * Holds if `nodeFrom` is being written to the `content` content of the object in `nodeTo`. + */ + predicate basicStoreStep(I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent content); + + /** + * Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`. + */ + predicate basicLoadStoreStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent loadContent, + I::TypeTrackerContent storeContent + ); + + /** + * Holds if type-tracking should step from `nodeFrom` to `nodeTo` but block flow of contents matched by `filter` through here. + */ + predicate basicWithoutContentStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContentFilter filter + ); + + /** + * Holds if type-tracking should step from `nodeFrom` to `nodeTo` if inside a content matched by `filter`. + */ + predicate basicWithContentStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContentFilter filter + ); +} + +/** + * Implementation of the summary type tracker, that is type tracking through flow summaries. + */ +module SummaryFlow<Input I> implements Output<I> { + pragma[nomagic] + private predicate hasLoadSummary( + I::SummarizedCallable callable, I::TypeTrackerContent contents, I::SummaryComponentStack input, + I::SummaryComponentStack output + ) { + callable.propagatesFlow(I::push(I::content(contents), input), output, true) and + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) + } + + pragma[nomagic] + private predicate hasStoreSummary( + I::SummarizedCallable callable, I::TypeTrackerContent contents, I::SummaryComponentStack input, + I::SummaryComponentStack output + ) { + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) and + ( + callable.propagatesFlow(input, I::push(I::content(contents), output), true) + or + // Allow the input to start with an arbitrary WithoutContent[X]. + // Since type-tracking only tracks one content deep, and we're about to store into another content, + // we're already preventing the input from being in a content. + callable + .propagatesFlow(I::push(I::withoutContent(_), input), + I::push(I::content(contents), output), true) + ) + } + + pragma[nomagic] + private predicate hasLoadStoreSummary( + I::SummarizedCallable callable, I::TypeTrackerContent loadContents, + I::TypeTrackerContent storeContents, I::SummaryComponentStack input, + I::SummaryComponentStack output + ) { + callable + .propagatesFlow(I::push(I::content(loadContents), input), + I::push(I::content(storeContents), output), true) and + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) + } + + pragma[nomagic] + private predicate hasWithoutContentSummary( + I::SummarizedCallable callable, I::TypeTrackerContentFilter filter, + I::SummaryComponentStack input, I::SummaryComponentStack output + ) { + exists(I::TypeTrackerContent content | + callable.propagatesFlow(I::push(I::withoutContent(content), input), output, true) and + filter = I::getFilterFromWithoutContentStep(content) and + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) and + input != output + ) + } + + pragma[nomagic] + private predicate hasWithContentSummary( + I::SummarizedCallable callable, I::TypeTrackerContentFilter filter, + I::SummaryComponentStack input, I::SummaryComponentStack output + ) { + exists(I::TypeTrackerContent content | + callable.propagatesFlow(I::push(I::withContent(content), input), output, true) and + filter = I::getFilterFromWithContentStep(content) and + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) and + input != output + ) + } + + /** + * Gets a data flow I::Node corresponding an argument or return value of `call`, + * as specified by `component`. + */ + bindingset[call, component] + private I::Node evaluateSummaryComponentLocal(I::Node call, I::SummaryComponent component) { + result = I::argumentOf(call, component) + or + component = I::return() and + result = call + } + + /** + * Holds if `callable` is relevant for type-tracking and we therefore want `stack` to + * be evaluated locally at its call sites. + */ + pragma[nomagic] + private predicate dependsOnSummaryComponentStack( + I::SummarizedCallable callable, I::SummaryComponentStack stack + ) { + exists(I::callTo(callable)) and + ( + callable.propagatesFlow(stack, _, true) + or + callable.propagatesFlow(_, stack, true) + or + // include store summaries as they may skip an initial step at the input + hasStoreSummary(callable, _, stack, _) + ) + or + dependsOnSummaryComponentStackCons(callable, _, stack) + } + + pragma[nomagic] + private predicate dependsOnSummaryComponentStackCons( + I::SummarizedCallable callable, I::SummaryComponent head, I::SummaryComponentStack tail + ) { + dependsOnSummaryComponentStack(callable, I::push(head, tail)) + } + + pragma[nomagic] + private predicate dependsOnSummaryComponentStackConsLocal( + I::SummarizedCallable callable, I::SummaryComponent head, I::SummaryComponentStack tail + ) { + dependsOnSummaryComponentStackCons(callable, head, tail) and + not I::isNonLocal(head) + } + + pragma[nomagic] + private predicate dependsOnSummaryComponentStackLeaf( + I::SummarizedCallable callable, I::SummaryComponent leaf + ) { + dependsOnSummaryComponentStack(callable, I::singleton(leaf)) + } + + /** + * Gets a data flow I::Node corresponding to the local input or output of `call` + * identified by `stack`, if possible. + */ + pragma[nomagic] + private I::Node evaluateSummaryComponentStackLocal( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack stack + ) { + exists(I::SummaryComponent component | + dependsOnSummaryComponentStackLeaf(callable, component) and + stack = I::singleton(component) and + call = I::callTo(callable) and + result = evaluateSummaryComponentLocal(call, component) + ) + or + exists(I::Node prev, I::SummaryComponent head, I::SummaryComponentStack tail | + prev = evaluateSummaryComponentStackLocal(callable, call, tail) and + dependsOnSummaryComponentStackConsLocal(callable, pragma[only_bind_into](head), + pragma[only_bind_out](tail)) and + stack = I::push(pragma[only_bind_out](head), pragma[only_bind_out](tail)) + | + result = I::parameterOf(prev, head) + or + result = I::returnOf(prev, head) + or + I::componentLevelStep(head) and + result = prev + ) + } + + // Implement Output + predicate levelStepNoCall(I::Node nodeFrom, I::Node nodeTo) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + callable.propagatesFlow(input, output, true) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicLoadStep(I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent content) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasLoadSummary(callable, content, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicStoreStep(I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent content) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasStoreSummary(callable, content, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicLoadStoreStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent loadContent, + I::TypeTrackerContent storeContent + ) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasLoadStoreSummary(callable, loadContent, storeContent, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicWithoutContentStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContentFilter filter + ) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasWithoutContentSummary(callable, filter, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicWithContentStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContentFilter filter + ) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasWithContentSummary(callable, filter, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } +} diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index 9e05b7869c5..81e673dc30b 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -61,7 +61,9 @@ predicate capturedJumpStep(Node nodeFrom, Node nodeTo) { predicate levelStepCall(Node nodeFrom, Node nodeTo) { none() } /** Holds if there is a level step from `nodeFrom` to `nodeTo`, which does not depend on the call graph. */ -predicate levelStepNoCall(Node nodeFrom, Node nodeTo) { none() } +predicate levelStepNoCall(Node nodeFrom, Node nodeTo) { + TypeTrackerSummaryFlow::levelStepNoCall(nodeFrom, nodeTo) +} /** * Gets the name of a possible piece of content. For Python, this is currently only attribute names, @@ -108,6 +110,12 @@ predicate basicStoreStep(Node nodeFrom, Node nodeTo, string content) { nodeFrom = a.getValue() and nodeTo = a.getObject() ) + or + exists(DataFlowPublic::ContentSet contents | + contents.(DataFlowPublic::AttributeContent).getAttribute() = content + | + TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, contents) + ) } /** @@ -119,13 +127,24 @@ predicate basicLoadStep(Node nodeFrom, Node nodeTo, string content) { nodeFrom = a.getObject() and nodeTo = a ) + or + exists(DataFlowPublic::ContentSet contents | + contents.(DataFlowPublic::AttributeContent).getAttribute() = content + | + TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, contents) + ) } /** * Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`. */ predicate basicLoadStoreStep(Node nodeFrom, Node nodeTo, string loadContent, string storeContent) { - none() + exists(DataFlowPublic::ContentSet loadContents, DataFlowPublic::ContentSet storeContents | + loadContents.(DataFlowPublic::AttributeContent).getAttribute() = loadContent and + storeContents.(DataFlowPublic::AttributeContent).getAttribute() = storeContent + | + TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, loadContents, storeContents) + ) } /** @@ -144,3 +163,108 @@ predicate basicWithContentStep(Node nodeFrom, Node nodeTo, ContentFilter filter) class Boolean extends boolean { Boolean() { this = true or this = false } } + +private import SummaryTypeTracker as SummaryTypeTracker +private import semmle.python.dataflow.new.FlowSummary as FlowSummary +private import semmle.python.dataflow.new.internal.DataFlowDispatch as DataFlowDispatch + +pragma[noinline] +private predicate argumentPositionMatch( + DataFlowPublic::CallCfgNode call, DataFlowPublic::ArgumentNode arg, + DataFlowDispatch::ParameterPosition ppos +) { + exists(DataFlowDispatch::ArgumentPosition apos, DataFlowPrivate::DataFlowCall c | + c.getNode() = call.asCfgNode() and + arg.argumentOf(c, apos) and + DataFlowDispatch::parameterMatch(ppos, apos) + ) +} + +module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { + // Dataflow nodes + class Node = DataFlowPublic::Node; + + // Content + class TypeTrackerContent = DataFlowPublic::ContentSet; + + class TypeTrackerContentFilter = ContentFilter; + + TypeTrackerContentFilter getFilterFromWithoutContentStep(TypeTrackerContent content) { none() } + + TypeTrackerContentFilter getFilterFromWithContentStep(TypeTrackerContent content) { none() } + + // Callables + class SummarizedCallable = FlowSummary::SummarizedCallable; + + // Summaries and their stacks + class SummaryComponent = FlowSummary::SummaryComponent; + + class SummaryComponentStack = FlowSummary::SummaryComponentStack; + + SummaryComponentStack singleton(SummaryComponent component) { + result = FlowSummary::SummaryComponentStack::singleton(component) + } + + SummaryComponentStack push(SummaryComponent component, SummaryComponentStack stack) { + result = FlowSummary::SummaryComponentStack::push(component, stack) + } + + // Relating content to summaries + SummaryComponent content(TypeTrackerContent contents) { + result = FlowSummary::SummaryComponent::content(contents) + } + + SummaryComponent withoutContent(TypeTrackerContent contents) { none() } + + SummaryComponent withContent(TypeTrackerContent contents) { none() } + + SummaryComponent return() { result = FlowSummary::SummaryComponent::return() } + + // Relating nodes to summaries + Node argumentOf(Node call, SummaryComponent arg) { + exists(DataFlowDispatch::ParameterPosition pos | + arg = FlowSummary::SummaryComponent::argument(pos) and + argumentPositionMatch(call, result, pos) + ) + } + + Node parameterOf(Node callable, SummaryComponent param) { + exists( + DataFlowDispatch::ArgumentPosition apos, DataFlowDispatch::ParameterPosition ppos, Parameter p + | + param = FlowSummary::SummaryComponent::parameter(apos) and + DataFlowDispatch::parameterMatch(ppos, apos) and + // pick the SsaNode rather than the CfgNode + result.asVar().getDefinition().(ParameterDefinition).getParameter() = p and + ( + exists(int i | ppos.isPositional(i) | + p = callable.getALocalSource().asExpr().(CallableExpr).getInnerScope().getArg(i) + ) + or + exists(string name | ppos.isKeyword(name) | + p = callable.getALocalSource().asExpr().(CallableExpr).getInnerScope().getArgByName(name) + ) + ) + ) + } + + Node returnOf(Node callable, SummaryComponent return) { + return = FlowSummary::SummaryComponent::return() and + // result should be return value of callable which should be a lambda + result.asCfgNode() = + callable.getALocalSource().asExpr().(CallableExpr).getInnerScope().getAReturnValueFlowNode() + } + + // Specific summary handling + predicate componentLevelStep(SummaryComponent component) { none() } + + pragma[nomagic] + predicate isNonLocal(SummaryComponent component) { + component = FlowSummary::SummaryComponent::content(_) + } + + // Relating callables to nodes + Node callTo(SummarizedCallable callable) { result = callable.getACallSimple() } +} + +module TypeTrackerSummaryFlow = SummaryTypeTracker::SummaryFlow<SummaryTypeTrackerInput>; diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py index f7affa6036f..728456cc711 100644 --- a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py @@ -3,7 +3,7 @@ import os # Simple summary tainted = identity(tracked) # $ tracked -tainted # $ MISSING: tracked +tainted # $ tracked # Lambda summary # I think the missing result is expected because type tracking @@ -13,7 +13,7 @@ tainted_lambda # $ MISSING: tracked # A lambda that directly introduces taint bad_lambda = apply_lambda(lambda x: tracked, 1) # $ tracked -bad_lambda # $ MISSING: tracked +bad_lambda # $ tracked # A lambda that breaks the flow untainted_lambda = apply_lambda(lambda x: 1, tracked) # $ tracked @@ -52,9 +52,9 @@ tr = tainted_resultlist[0] tr # $ MISSING: tracked x.secret = tracked # $ tracked=secret tracked -r = read_secret(x) # $ tracked=secret MISSING: tracked -r # $ MISSING: tracked +r = read_secret(x) # $ tracked=secret tracked +r # $ tracked -y # $ MISSING: tracked=secret -set_secret(y, tracked) # $ tracked MISSING: tracked=secret -y.secret # $ MISSING: tracked tracked=secret \ No newline at end of file +y # $ tracked=secret +set_secret(y, tracked) # $ tracked tracked=secret +y.secret # $ tracked tracked=secret \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll new file mode 100644 index 00000000000..310dec3aadf --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll @@ -0,0 +1,382 @@ +/** + * Provides the implementation of a summary type tracker, that is type tracking through flow summaries. + * To use this, you must implement the `Input` signature. You can then use the predicates in the `Output` + * signature to implement the predicates of the same names inside `TypeTrackerSpecific.qll`. + */ + +/** The classes and predicates needed to generate a summary type tracker. */ +signature module Input { + // Dataflow nodes + class Node; + + // Content + class TypeTrackerContent; + + class TypeTrackerContentFilter; + + // Relating content and filters + /** + * Gets a content filter to use for a `WithoutContent[content]` step, or has no result if + * the step should be treated as ordinary flow. + * + * `WithoutContent` is often used to perform strong updates on individual collection elements, but for + * type-tracking this is rarely beneficial and quite expensive. However, `WithoutContent` can be quite useful + * for restricting the type of an object, and in these cases we translate it to a filter. + */ + TypeTrackerContentFilter getFilterFromWithoutContentStep(TypeTrackerContent content); + + /** + * Gets a content filter to use for a `WithContent[content]` step, or has no result if + * the step cannot be handled by type-tracking. + * + * `WithContent` is often used to perform strong updates on individual collection elements (or rather + * to preserve those that didn't get updated). But for type-tracking this is rarely beneficial and quite expensive. + * However, `WithContent` can be quite useful for restricting the type of an object, and in these cases we translate it to a filter. + */ + TypeTrackerContentFilter getFilterFromWithContentStep(TypeTrackerContent content); + + // Summaries and their stacks + class SummaryComponent; + + class SummaryComponentStack { + SummaryComponent head(); + } + + /** Gets a singleton stack containing `component`. */ + SummaryComponentStack singleton(SummaryComponent component); + + /** + * Gets the stack obtained by pushing `head` onto `tail`. + */ + SummaryComponentStack push(SummaryComponent component, SummaryComponentStack stack); + + /** Gets a singleton stack representing a return. */ + SummaryComponent return(); + + // Relating content to summaries + /** Gets a summary component for content `c`. */ + SummaryComponent content(TypeTrackerContent contents); + + /** Gets a summary component where data is not allowed to be stored in `c`. */ + SummaryComponent withoutContent(TypeTrackerContent contents); + + /** Gets a summary component where data must be stored in `c`. */ + SummaryComponent withContent(TypeTrackerContent contents); + + // Callables + class SummarizedCallable { + predicate propagatesFlow( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ); + } + + // Relating nodes to summaries + /** Gets a dataflow node respresenting the argument of `call` indicated by `arg`. */ + Node argumentOf(Node call, SummaryComponent arg); + + /** Gets a dataflow node respresenting the parameter of `callable` indicated by `param`. */ + Node parameterOf(Node callable, SummaryComponent param); + + /** Gets a dataflow node respresenting the return of `callable` indicated by `return`. */ + Node returnOf(Node callable, SummaryComponent return); + + // Specific summary handling + /** Holds if component should be treated as a level step by type tracking. */ + predicate componentLevelStep(SummaryComponent component); + + /** Holds if the given component can't be evaluated by `evaluateSummaryComponentStackLocal`. */ + predicate isNonLocal(SummaryComponent component); + + // Relating callables to nodes + /** Gets a dataflow node respresenting a call to `callable`. */ + Node callTo(SummarizedCallable callable); +} + +/** + * The predicates provided by a summary type tracker. + * These are meant to be used in `TypeTrackerSpecific.qll` + * inside the predicates of the same names. + */ +signature module Output<Input I> { + /** + * Holds if there is a level step from `nodeFrom` to `nodeTo`, which does not depend on the call graph. + */ + predicate levelStepNoCall(I::Node nodeFrom, I::Node nodeTo); + + /** + * Holds if `nodeTo` is the result of accessing the `content` content of `nodeFrom`. + */ + predicate basicLoadStep(I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent content); + + /** + * Holds if `nodeFrom` is being written to the `content` content of the object in `nodeTo`. + */ + predicate basicStoreStep(I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent content); + + /** + * Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`. + */ + predicate basicLoadStoreStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent loadContent, + I::TypeTrackerContent storeContent + ); + + /** + * Holds if type-tracking should step from `nodeFrom` to `nodeTo` but block flow of contents matched by `filter` through here. + */ + predicate basicWithoutContentStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContentFilter filter + ); + + /** + * Holds if type-tracking should step from `nodeFrom` to `nodeTo` if inside a content matched by `filter`. + */ + predicate basicWithContentStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContentFilter filter + ); +} + +/** + * Implementation of the summary type tracker, that is type tracking through flow summaries. + */ +module SummaryFlow<Input I> implements Output<I> { + pragma[nomagic] + private predicate hasLoadSummary( + I::SummarizedCallable callable, I::TypeTrackerContent contents, I::SummaryComponentStack input, + I::SummaryComponentStack output + ) { + callable.propagatesFlow(I::push(I::content(contents), input), output, true) and + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) + } + + pragma[nomagic] + private predicate hasStoreSummary( + I::SummarizedCallable callable, I::TypeTrackerContent contents, I::SummaryComponentStack input, + I::SummaryComponentStack output + ) { + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) and + ( + callable.propagatesFlow(input, I::push(I::content(contents), output), true) + or + // Allow the input to start with an arbitrary WithoutContent[X]. + // Since type-tracking only tracks one content deep, and we're about to store into another content, + // we're already preventing the input from being in a content. + callable + .propagatesFlow(I::push(I::withoutContent(_), input), + I::push(I::content(contents), output), true) + ) + } + + pragma[nomagic] + private predicate hasLoadStoreSummary( + I::SummarizedCallable callable, I::TypeTrackerContent loadContents, + I::TypeTrackerContent storeContents, I::SummaryComponentStack input, + I::SummaryComponentStack output + ) { + callable + .propagatesFlow(I::push(I::content(loadContents), input), + I::push(I::content(storeContents), output), true) and + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) + } + + pragma[nomagic] + private predicate hasWithoutContentSummary( + I::SummarizedCallable callable, I::TypeTrackerContentFilter filter, + I::SummaryComponentStack input, I::SummaryComponentStack output + ) { + exists(I::TypeTrackerContent content | + callable.propagatesFlow(I::push(I::withoutContent(content), input), output, true) and + filter = I::getFilterFromWithoutContentStep(content) and + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) and + input != output + ) + } + + pragma[nomagic] + private predicate hasWithContentSummary( + I::SummarizedCallable callable, I::TypeTrackerContentFilter filter, + I::SummaryComponentStack input, I::SummaryComponentStack output + ) { + exists(I::TypeTrackerContent content | + callable.propagatesFlow(I::push(I::withContent(content), input), output, true) and + filter = I::getFilterFromWithContentStep(content) and + not I::isNonLocal(input.head()) and + not I::isNonLocal(output.head()) and + input != output + ) + } + + /** + * Gets a data flow I::Node corresponding an argument or return value of `call`, + * as specified by `component`. + */ + bindingset[call, component] + private I::Node evaluateSummaryComponentLocal(I::Node call, I::SummaryComponent component) { + result = I::argumentOf(call, component) + or + component = I::return() and + result = call + } + + /** + * Holds if `callable` is relevant for type-tracking and we therefore want `stack` to + * be evaluated locally at its call sites. + */ + pragma[nomagic] + private predicate dependsOnSummaryComponentStack( + I::SummarizedCallable callable, I::SummaryComponentStack stack + ) { + exists(I::callTo(callable)) and + ( + callable.propagatesFlow(stack, _, true) + or + callable.propagatesFlow(_, stack, true) + or + // include store summaries as they may skip an initial step at the input + hasStoreSummary(callable, _, stack, _) + ) + or + dependsOnSummaryComponentStackCons(callable, _, stack) + } + + pragma[nomagic] + private predicate dependsOnSummaryComponentStackCons( + I::SummarizedCallable callable, I::SummaryComponent head, I::SummaryComponentStack tail + ) { + dependsOnSummaryComponentStack(callable, I::push(head, tail)) + } + + pragma[nomagic] + private predicate dependsOnSummaryComponentStackConsLocal( + I::SummarizedCallable callable, I::SummaryComponent head, I::SummaryComponentStack tail + ) { + dependsOnSummaryComponentStackCons(callable, head, tail) and + not I::isNonLocal(head) + } + + pragma[nomagic] + private predicate dependsOnSummaryComponentStackLeaf( + I::SummarizedCallable callable, I::SummaryComponent leaf + ) { + dependsOnSummaryComponentStack(callable, I::singleton(leaf)) + } + + /** + * Gets a data flow I::Node corresponding to the local input or output of `call` + * identified by `stack`, if possible. + */ + pragma[nomagic] + private I::Node evaluateSummaryComponentStackLocal( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack stack + ) { + exists(I::SummaryComponent component | + dependsOnSummaryComponentStackLeaf(callable, component) and + stack = I::singleton(component) and + call = I::callTo(callable) and + result = evaluateSummaryComponentLocal(call, component) + ) + or + exists(I::Node prev, I::SummaryComponent head, I::SummaryComponentStack tail | + prev = evaluateSummaryComponentStackLocal(callable, call, tail) and + dependsOnSummaryComponentStackConsLocal(callable, pragma[only_bind_into](head), + pragma[only_bind_out](tail)) and + stack = I::push(pragma[only_bind_out](head), pragma[only_bind_out](tail)) + | + result = I::parameterOf(prev, head) + or + result = I::returnOf(prev, head) + or + I::componentLevelStep(head) and + result = prev + ) + } + + // Implement Output + predicate levelStepNoCall(I::Node nodeFrom, I::Node nodeTo) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + callable.propagatesFlow(input, output, true) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicLoadStep(I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent content) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasLoadSummary(callable, content, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicStoreStep(I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent content) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasStoreSummary(callable, content, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicLoadStoreStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContent loadContent, + I::TypeTrackerContent storeContent + ) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasLoadStoreSummary(callable, loadContent, storeContent, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicWithoutContentStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContentFilter filter + ) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasWithoutContentSummary(callable, filter, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } + + predicate basicWithContentStep( + I::Node nodeFrom, I::Node nodeTo, I::TypeTrackerContentFilter filter + ) { + exists( + I::SummarizedCallable callable, I::Node call, I::SummaryComponentStack input, + I::SummaryComponentStack output + | + hasWithContentSummary(callable, filter, pragma[only_bind_into](input), + pragma[only_bind_into](output)) and + call = I::callTo(callable) and + nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and + nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) + ) + } +} diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll index 55ec26258d6..4f17302e72b 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll @@ -112,15 +112,7 @@ predicate levelStepCall(Node nodeFrom, Node nodeTo) { /** Holds if there is a level step from `nodeFrom` to `nodeTo`, which does not depend on the call graph. */ pragma[nomagic] predicate levelStepNoCall(Node nodeFrom, Node nodeTo) { - exists( - SummarizedCallable callable, DataFlowPublic::CallNode call, SummaryComponentStack input, - SummaryComponentStack output - | - callable.propagatesFlow(input, output, true) and - call.asExpr().getExpr() = callable.getACallSimple() and - nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and - nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) - ) + TypeTrackerSummaryFlow::levelStepNoCall(nodeFrom, nodeTo) or localFieldStep(nodeFrom, nodeTo) } @@ -290,16 +282,7 @@ predicate returnStep(Node nodeFrom, Node nodeTo) { predicate basicStoreStep(Node nodeFrom, Node nodeTo, DataFlow::ContentSet contents) { storeStepIntoSourceNode(nodeFrom, nodeTo, contents) or - exists( - SummarizedCallable callable, DataFlowPublic::CallNode call, SummaryComponentStack input, - SummaryComponentStack output - | - hasStoreSummary(callable, contents, pragma[only_bind_into](input), - pragma[only_bind_into](output)) and - call.asExpr().getExpr() = callable.getACallSimple() and - nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and - nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) - ) + TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, contents) } /** @@ -333,15 +316,7 @@ predicate basicLoadStep(Node nodeFrom, Node nodeTo, DataFlow::ContentSet content nodeTo.asExpr() = call ) or - exists( - SummarizedCallable callable, DataFlowPublic::CallNode call, SummaryComponentStack input, - SummaryComponentStack output - | - hasLoadSummary(callable, contents, pragma[only_bind_into](input), pragma[only_bind_into](output)) and - call.asExpr().getExpr() = callable.getACallSimple() and - nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and - nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) - ) + TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, contents) } /** @@ -350,48 +325,21 @@ predicate basicLoadStep(Node nodeFrom, Node nodeTo, DataFlow::ContentSet content predicate basicLoadStoreStep( Node nodeFrom, Node nodeTo, DataFlow::ContentSet loadContent, DataFlow::ContentSet storeContent ) { - exists( - SummarizedCallable callable, DataFlowPublic::CallNode call, SummaryComponentStack input, - SummaryComponentStack output - | - hasLoadStoreSummary(callable, loadContent, storeContent, pragma[only_bind_into](input), - pragma[only_bind_into](output)) and - call.asExpr().getExpr() = callable.getACallSimple() and - nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and - nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) - ) + TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, loadContent, storeContent) } /** * Holds if type-tracking should step from `nodeFrom` to `nodeTo` but block flow of contents matched by `filter` through here. */ predicate basicWithoutContentStep(Node nodeFrom, Node nodeTo, ContentFilter filter) { - exists( - SummarizedCallable callable, DataFlowPublic::CallNode call, SummaryComponentStack input, - SummaryComponentStack output - | - hasWithoutContentSummary(callable, filter, pragma[only_bind_into](input), - pragma[only_bind_into](output)) and - call.asExpr().getExpr() = callable.getACallSimple() and - nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and - nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) - ) + TypeTrackerSummaryFlow::basicWithoutContentStep(nodeFrom, nodeTo, filter) } /** * Holds if type-tracking should step from `nodeFrom` to `nodeTo` if inside a content matched by `filter`. */ predicate basicWithContentStep(Node nodeFrom, Node nodeTo, ContentFilter filter) { - exists( - SummarizedCallable callable, DataFlowPublic::CallNode call, SummaryComponentStack input, - SummaryComponentStack output - | - hasWithContentSummary(callable, filter, pragma[only_bind_into](input), - pragma[only_bind_into](output)) and - call.asExpr().getExpr() = callable.getACallSimple() and - nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and - nodeTo = evaluateSummaryComponentStackLocal(callable, call, output) - ) + TypeTrackerSummaryFlow::basicWithContentStep(nodeFrom, nodeTo, filter) } /** @@ -403,121 +351,6 @@ class Boolean extends boolean { private import SummaryComponentStack -pragma[nomagic] -private predicate hasStoreSummary( - SummarizedCallable callable, DataFlow::ContentSet contents, SummaryComponentStack input, - SummaryComponentStack output -) { - not isNonLocal(input.head()) and - not isNonLocal(output.head()) and - ( - callable.propagatesFlow(input, push(SummaryComponent::content(contents), output), true) - or - // Allow the input to start with an arbitrary WithoutContent[X]. - // Since type-tracking only tracks one content deep, and we're about to store into another content, - // we're already preventing the input from being in a content. - callable - .propagatesFlow(push(SummaryComponent::withoutContent(_), input), - push(SummaryComponent::content(contents), output), true) - ) -} - -pragma[nomagic] -private predicate hasLoadSummary( - SummarizedCallable callable, DataFlow::ContentSet contents, SummaryComponentStack input, - SummaryComponentStack output -) { - callable.propagatesFlow(push(SummaryComponent::content(contents), input), output, true) and - not isNonLocal(input.head()) and - not isNonLocal(output.head()) -} - -pragma[nomagic] -private predicate hasLoadStoreSummary( - SummarizedCallable callable, DataFlow::ContentSet loadContents, - DataFlow::ContentSet storeContents, SummaryComponentStack input, SummaryComponentStack output -) { - callable - .propagatesFlow(push(SummaryComponent::content(loadContents), input), - push(SummaryComponent::content(storeContents), output), true) and - not isNonLocal(input.head()) and - not isNonLocal(output.head()) -} - -/** - * Gets a content filter to use for a `WithoutContent[content]` step, or has no result if - * the step should be treated as ordinary flow. - * - * `WithoutContent` is often used to perform strong updates on individual collection elements, but for - * type-tracking this is rarely beneficial and quite expensive. However, `WithoutContent` can be quite useful - * for restricting the type of an object, and in these cases we translate it to a filter. - */ -private ContentFilter getFilterFromWithoutContentStep(DataFlow::ContentSet content) { - ( - content.isAnyElement() - or - content.isElementLowerBoundOrUnknown(_) - or - content.isElementOfTypeOrUnknown(_) - or - content.isSingleton(any(DataFlow::Content::UnknownElementContent c)) - ) and - result = MkElementFilter() -} - -pragma[nomagic] -private predicate hasWithoutContentSummary( - SummarizedCallable callable, ContentFilter filter, SummaryComponentStack input, - SummaryComponentStack output -) { - exists(DataFlow::ContentSet content | - callable.propagatesFlow(push(SummaryComponent::withoutContent(content), input), output, true) and - filter = getFilterFromWithoutContentStep(content) and - not isNonLocal(input.head()) and - not isNonLocal(output.head()) and - input != output - ) -} - -/** - * Gets a content filter to use for a `WithContent[content]` step, or has no result if - * the step cannot be handled by type-tracking. - * - * `WithContent` is often used to perform strong updates on individual collection elements (or rather - * to preserve those that didn't get updated). But for type-tracking this is rarely beneficial and quite expensive. - * However, `WithContent` can be quite useful for restricting the type of an object, and in these cases we translate it to a filter. - */ -private ContentFilter getFilterFromWithContentStep(DataFlow::ContentSet content) { - ( - content.isAnyElement() - or - content.isElementLowerBound(_) - or - content.isElementLowerBoundOrUnknown(_) - or - content.isElementOfType(_) - or - content.isElementOfTypeOrUnknown(_) - or - content.isSingleton(any(DataFlow::Content::ElementContent c)) - ) and - result = MkElementFilter() -} - -pragma[nomagic] -private predicate hasWithContentSummary( - SummarizedCallable callable, ContentFilter filter, SummaryComponentStack input, - SummaryComponentStack output -) { - exists(DataFlow::ContentSet content | - callable.propagatesFlow(push(SummaryComponent::withContent(content), input), output, true) and - filter = getFilterFromWithContentStep(content) and - not isNonLocal(input.head()) and - not isNonLocal(output.head()) and - input != output - ) -} - /** * Holds if the given component can't be evaluated by `evaluateSummaryComponentStackLocal`. */ @@ -528,112 +361,129 @@ predicate isNonLocal(SummaryComponent component) { component = SC::withContent(_) } -/** - * Gets a data flow node corresponding an argument or return value of `call`, - * as specified by `component`. - */ -bindingset[call, component] -private DataFlow::Node evaluateSummaryComponentLocal( - DataFlow::CallNode call, SummaryComponent component -) { - exists(DataFlowDispatch::ParameterPosition pos | - component = SummaryComponent::argument(pos) and - argumentPositionMatch(call.asExpr(), result, pos) - ) - or - component = SummaryComponent::return() and - result = call -} +private import SummaryTypeTracker as SummaryTypeTracker +private import codeql.ruby.dataflow.FlowSummary as FlowSummary -/** - * Holds if `callable` is relevant for type-tracking and we therefore want `stack` to - * be evaluated locally at its call sites. - */ -pragma[nomagic] -private predicate dependsOnSummaryComponentStack( - SummarizedCallable callable, SummaryComponentStack stack -) { - exists(callable.getACallSimple()) and - ( - callable.propagatesFlow(stack, _, true) - or - callable.propagatesFlow(_, stack, true) - or - // include store summaries as they may skip an initial step at the input - hasStoreSummary(callable, _, stack, _) - ) - or - dependsOnSummaryComponentStackCons(callable, _, stack) -} +module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { + // Dataflow nodes + class Node = DataFlow::Node; -pragma[nomagic] -private predicate dependsOnSummaryComponentStackCons( - SummarizedCallable callable, SummaryComponent head, SummaryComponentStack tail -) { - dependsOnSummaryComponentStack(callable, SCS::push(head, tail)) -} + // Content + class TypeTrackerContent = DataFlowPublic::ContentSet; -pragma[nomagic] -private predicate dependsOnSummaryComponentStackConsLocal( - SummarizedCallable callable, SummaryComponent head, SummaryComponentStack tail -) { - dependsOnSummaryComponentStackCons(callable, head, tail) and - not isNonLocal(head) -} + class TypeTrackerContentFilter = ContentFilter; -pragma[nomagic] -private predicate dependsOnSummaryComponentStackLeaf( - SummarizedCallable callable, SummaryComponent leaf -) { - dependsOnSummaryComponentStack(callable, SCS::singleton(leaf)) -} + TypeTrackerContentFilter getFilterFromWithoutContentStep(TypeTrackerContent content) { + ( + content.isAnyElement() + or + content.isElementLowerBoundOrUnknown(_) + or + content.isElementOfTypeOrUnknown(_) + or + content.isSingleton(any(DataFlow::Content::UnknownElementContent c)) + ) and + result = MkElementFilter() + } -/** - * Gets a data flow node corresponding to the local input or output of `call` - * identified by `stack`, if possible. - */ -pragma[nomagic] -private DataFlow::Node evaluateSummaryComponentStackLocal( - SummarizedCallable callable, DataFlow::CallNode call, SummaryComponentStack stack -) { - exists(SummaryComponent component | - dependsOnSummaryComponentStackLeaf(callable, component) and - stack = SCS::singleton(component) and - call.asExpr().getExpr() = callable.getACallSimple() and - result = evaluateSummaryComponentLocal(call, component) - ) - or - exists(DataFlow::Node prev, SummaryComponent head, SummaryComponentStack tail | - prev = evaluateSummaryComponentStackLocal(callable, call, tail) and - dependsOnSummaryComponentStackConsLocal(callable, pragma[only_bind_into](head), - pragma[only_bind_out](tail)) and - stack = SCS::push(pragma[only_bind_out](head), pragma[only_bind_out](tail)) - | + TypeTrackerContentFilter getFilterFromWithContentStep(TypeTrackerContent content) { + ( + content.isAnyElement() + or + content.isElementLowerBound(_) + or + content.isElementLowerBoundOrUnknown(_) + or + content.isElementOfType(_) + or + content.isElementOfTypeOrUnknown(_) + or + content.isSingleton(any(DataFlow::Content::ElementContent c)) + ) and + result = MkElementFilter() + } + + // Summaries and their stacks + class SummaryComponent = FlowSummary::SummaryComponent; + + class SummaryComponentStack = FlowSummary::SummaryComponentStack; + + SummaryComponentStack singleton(SummaryComponent component) { + result = FlowSummary::SummaryComponentStack::singleton(component) + } + + SummaryComponentStack push(SummaryComponent component, SummaryComponentStack stack) { + result = FlowSummary::SummaryComponentStack::push(component, stack) + } + + // Relating content to summaries + SummaryComponent content(TypeTrackerContent contents) { + result = FlowSummary::SummaryComponent::content(contents) + } + + SummaryComponent withoutContent(TypeTrackerContent contents) { + result = FlowSummary::SummaryComponent::withoutContent(contents) + } + + SummaryComponent withContent(TypeTrackerContent contents) { + result = FlowSummary::SummaryComponent::withContent(contents) + } + + SummaryComponent return() { result = FlowSummary::SummaryComponent::return() } + + // Callables + class SummarizedCallable = FlowSummary::SummarizedCallable; + + // Relating nodes to summaries + Node argumentOf(Node call, SummaryComponent arg) { + exists(DataFlowDispatch::ParameterPosition pos | + arg = SummaryComponent::argument(pos) and + argumentPositionMatch(call.asExpr(), result, pos) + ) + } + + Node parameterOf(Node callable, SummaryComponent param) { exists( DataFlowDispatch::ArgumentPosition apos, DataFlowDispatch::ParameterPosition ppos, DataFlowPrivate::ParameterNodeImpl p | - head = SummaryComponent::parameter(apos) and + param = SummaryComponent::parameter(apos) and DataFlowDispatch::parameterMatch(ppos, apos) and - p.isSourceParameterOf(prev.asExpr().getExpr(), ppos) and + p.isSourceParameterOf(callable.asExpr().getExpr(), ppos) and // We need to include both `p` and the SSA definition for `p`, since in type-tracking // the step from `p` to the SSA definition is considered a call step. result = [p.(DataFlow::Node), DataFlowPrivate::LocalFlow::getParameterDefNode(p.getParameter())] ) - or + } + + Node returnOf(Node callable, SummaryComponent return) { exists(DataFlowPrivate::SynthReturnNode ret | - head = SummaryComponent::return() and - ret.getCfgScope() = prev.asExpr().getExpr() and + return = SummaryComponent::return() and + ret.getCfgScope() = callable.asExpr().getExpr() and // We need to include both `ret` and `ret.getAnInput()`, since in type-tracking // the step from `ret.getAnInput()` to `ret` is considered a return step. result = [ret.(DataFlow::Node), ret.getAnInput()] ) - or - exists(DataFlow::ContentSet content | - head = SummaryComponent::withoutContent(content) and - not exists(getFilterFromWithoutContentStep(content)) and - result = prev + } + + // Specific summary handling + predicate componentLevelStep(SummaryComponent component) { + exists(TypeTrackerContent content | + component = SummaryComponent::withoutContent(content) and + not exists(getFilterFromWithoutContentStep(content)) ) - ) + } + + pragma[nomagic] + predicate isNonLocal(SummaryComponent component) { + component = SC::content(_) + or + component = SC::withContent(_) + } + + // Relating callables to nodes + Node callTo(SummarizedCallable callable) { result.asExpr().getExpr() = callable.getACallSimple() } } + +module TypeTrackerSummaryFlow = SummaryTypeTracker::SummaryFlow<SummaryTypeTrackerInput>; From 820b5f235eba6c92251dde37ad2f052092648c75 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 30 May 2023 13:36:10 +0200 Subject: [PATCH 180/739] python: add change note --- .../2023-05-30-typetracking-via-flow-summaries.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/lib/change-notes/2023-05-30-typetracking-via-flow-summaries.md diff --git a/python/ql/lib/change-notes/2023-05-30-typetracking-via-flow-summaries.md b/python/ql/lib/change-notes/2023-05-30-typetracking-via-flow-summaries.md new file mode 100644 index 00000000000..11c01629987 --- /dev/null +++ b/python/ql/lib/change-notes/2023-05-30-typetracking-via-flow-summaries.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Type tracking is now aware of flow summaries. This leads to a richer API graph, and may lead to more results in some queries. From 560aa43953a14843f0661420c40f13c1c66b0dae Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 30 May 2023 14:20:17 +0100 Subject: [PATCH 181/739] Swift: Repair for AccountID / AccountKey. --- swift/ql/lib/codeql/swift/security/SensitiveExprs.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index 71a250229e7..d750e673121 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -35,7 +35,7 @@ class SensitiveCredential extends SensitiveDataType, TCredential { result = HeuristicNames::maybeSensitiveRegexp(classification) ) or - result = "(?is).*(license.?key).*" + result = "(?is).*(account|accnt|license).?(id|key).*" } } From 00e4c455b5bd8750776283edd0aa97585ec28842 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Tue, 30 May 2023 16:11:30 +0200 Subject: [PATCH 182/739] Update MaD Declarations after Triage --- java/ql/lib/change-notes/2023-05-30-new-models.md | 6 ++++++ java/ql/lib/ext/okhttp3.model.yml | 2 ++ 2 files changed, 8 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-05-30-new-models.md diff --git a/java/ql/lib/change-notes/2023-05-30-new-models.md b/java/ql/lib/change-notes/2023-05-30-new-models.md new file mode 100644 index 00000000000..24e7563d727 --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-30-new-models.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Added models for the following packages: + + * okhttp3 diff --git a/java/ql/lib/ext/okhttp3.model.yml b/java/ql/lib/ext/okhttp3.model.yml index 21563331656..d5f38bcee57 100644 --- a/java/ql/lib/ext/okhttp3.model.yml +++ b/java/ql/lib/ext/okhttp3.model.yml @@ -3,6 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: + - ["okhttp3", "OkHttpClient", True, "newCall", "(Request)", "", "Argument[0]", "open-url", "ai-manual"] + - ["okhttp3", "OkHttpClient", True, "newWebSocket", "(Request,WebSocketListener)", "", "Argument[0]", "open-url", "ai-manual"] - ["okhttp3", "Request", True, "Request", "", "", "Argument[0]", "open-url", "manual"] - ["okhttp3", "Request$Builder", True, "url", "", "", "Argument[0]", "open-url", "manual"] - addsTo: From f00b29d3d29c0de4c0a79117f667ec987715a9ce Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 26 May 2023 12:23:56 -0700 Subject: [PATCH 183/739] C++: The small-string optimization commonly used inside 'std::string' is causing a lot of FPs. Let's exclude this for now to reduce the number of results for this query. --- .../Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql index 735375870ea..aa0358a99ad 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -87,6 +87,7 @@ predicate arrayTypeHasSizes(ArrayType arr, int baseTypeSize, int arraySize) { predicate pointerArithOverflow0( PointerArithmeticInstruction pai, Field f, int size, int bound, int delta ) { + not f.getNamespace() instanceof StdNamespace and arrayTypeHasSizes(f.getUnspecifiedType(), pai.getElementSize(), size) and semBounded(getSemanticExpr(pai.getRight()), any(SemZeroBound b), bound, true, _) and delta = bound - size and From d91fa2d03810bf9234f16fb2b17f8c5069c8f8ae Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Tue, 30 May 2023 17:30:04 +0200 Subject: [PATCH 184/739] Ruby: add print-cfg query --- .../ql/lib/ide-contextual-queries/printCfg.ql | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 ruby/ql/lib/ide-contextual-queries/printCfg.ql diff --git a/ruby/ql/lib/ide-contextual-queries/printCfg.ql b/ruby/ql/lib/ide-contextual-queries/printCfg.ql new file mode 100644 index 00000000000..9c42fe91361 --- /dev/null +++ b/ruby/ql/lib/ide-contextual-queries/printCfg.ql @@ -0,0 +1,22 @@ +/** + * @name Print CFG + * @description Produces a representation of a file's Control Flow Graph. + * This query is used by the VS Code extension. + * @id rb/print-cfg + * @kind graph + * @tags ide-contextual-queries/print-cfg + */ + +private import codeql.ruby.controlflow.internal.ControlFlowGraphImplShared::TestOutput +private import codeql.IDEContextual + +/** + * Gets the source file to generate a CFG from. + */ +external string selectedSourceFile(); + +class MyRelevantNode extends RelevantNode { + MyRelevantNode() { + this.getScope().getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile()) + } +} From 54e011188d8b98634b44e28e923a563ebda2e9ed Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 30 May 2023 17:50:50 +0200 Subject: [PATCH 185/739] Formatting --- .../code/java/frameworks/google/GsonSerializability.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index 34a333c8b11..470847f292e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -13,9 +13,7 @@ import semmle.code.java.dataflow.FlowSteps * deserialized. */ private class GsonReadValueMethod extends Method { - GsonReadValueMethod() { - this.hasQualifiedName("com.google.gson", "Gson", "fromJson") - } + GsonReadValueMethod() { this.hasQualifiedName("com.google.gson", "Gson", "fromJson") } } /** A type whose values may be deserialized by the Gson JSON framework. */ From 977263a126e190acb52fbfce90ea9ce6e3ea0b76 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 30 May 2023 17:51:41 +0200 Subject: [PATCH 186/739] Use container flow for more precision --- java/ql/lib/ext/com.google.gson.model.yml | 24 +++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/java/ql/lib/ext/com.google.gson.model.yml b/java/ql/lib/ext/com.google.gson.model.yml index b867997c8df..96f5355b2dc 100644 --- a/java/ql/lib/ext/com.google.gson.model.yml +++ b/java/ql/lib/ext/com.google.gson.model.yml @@ -26,15 +26,19 @@ extensions: - ["com.google.gson", "JsonElement", True, "getAsJsonPrimitive", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["com.google.gson", "JsonElement", True, "getAsString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["com.google.gson", "JsonElement", True, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "JsonArray", True, "add", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["com.google.gson", "JsonArray", True, "asList", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "JsonArray", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "JsonArray", True, "set", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - - ["com.google.gson", "JsonObject", True, "add", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - - ["com.google.gson", "JsonObject", True, "addProperty", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "manual"] - - ["com.google.gson", "JsonObject", True, "asMap", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "JsonObject", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "JsonObject", True, "keySet", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "add", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["com.google.gson", "JsonArray", True, "asList", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["com.google.gson", "JsonArray", True, "get", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["com.google.gson", "JsonArray", True, "set", "", "", "Argument[1]", "Argument[this].Element", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "add", "", "", "Argument[0]", "Argument[this].MapKey", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "add", "", "", "Argument[1]", "Argument[this].MapValue", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "addProperty", "(String,String)", "", "Argument[0]", "Argument[this].MapKey", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "addProperty", "(String,String)", "", "Argument[1]", "Argument[this].MapValue", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "asMap", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "asMap", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this].MapKey", "ReturnValue.Element.MapValue", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "get", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "keySet", "", "", "Argument[this].MapKey", "ReturnValue.Element", "value", "manual"] - ["com.google.gson", "JsonPrimitive", True, "JsonPrimitive", "(Character)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["com.google.gson", "JsonPrimitive", True, "JsonPrimitive", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] From d3d67f0fb07406242913e9443398a9fa2238c8bf Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 30 May 2023 17:52:00 +0200 Subject: [PATCH 187/739] Add tests & stubs --- .../dataflow/taint-gson/Test.java | 38 ++ .../dataflow/taint-gson/dataFlow.expected | 0 .../dataflow/taint-gson/dataFlow.ql | 2 + .../library-tests/dataflow/taint-gson/options | 1 + .../library-tests/frameworks/gson/Test.java | 468 ++++++++++++++++++ .../library-tests/frameworks/gson/options | 1 + .../frameworks/gson/test.expected | 0 .../library-tests/frameworks/gson/test.ql | 2 + .../com/google/gson/ExclusionStrategy.java | 11 + .../com/google/gson/FieldAttributes.java | 22 + .../com/google/gson/FieldNamingPolicy.java | 10 + .../com/google/gson/FieldNamingStrategy.java | 10 + .../gson-2.8.6/com/google/gson/Gson.java | 81 +-- .../com/google/gson/GsonBuilder.java | 135 ++--- .../gson-2.8.6/com/google/gson/JsonArray.java | 45 ++ .../com/google/gson/JsonElement.java | 37 ++ .../gson-2.8.6/com/google/gson/JsonNull.java | 14 + .../com/google/gson/JsonObject.java | 33 ++ .../com/google/gson/JsonPrimitive.java | 34 ++ .../google/gson/LongSerializationPolicy.java | 24 + .../google/gson/ReflectionAccessFilter.java | 18 + .../com/google/gson/ToNumberStrategy.java | 10 + .../com/google/gson/TypeAdapter.java | 137 +---- .../com/google/gson/TypeAdapterFactory.java | 30 +- .../com/google/gson/internal/Excluder.java | 25 + .../com/google/gson/reflect/TypeToken.java | 64 +-- .../com/google/gson/stream/JsonReader.java | 89 ++-- .../com/google/gson/stream/JsonToken.java | 10 + .../com/google/gson/stream/JsonWriter.java | 36 ++ 29 files changed, 1008 insertions(+), 379 deletions(-) create mode 100644 java/ql/test/library-tests/dataflow/taint-gson/Test.java create mode 100644 java/ql/test/library-tests/dataflow/taint-gson/dataFlow.expected create mode 100644 java/ql/test/library-tests/dataflow/taint-gson/dataFlow.ql create mode 100644 java/ql/test/library-tests/dataflow/taint-gson/options create mode 100644 java/ql/test/library-tests/frameworks/gson/Test.java create mode 100644 java/ql/test/library-tests/frameworks/gson/options create mode 100644 java/ql/test/library-tests/frameworks/gson/test.expected create mode 100644 java/ql/test/library-tests/frameworks/gson/test.ql create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/ExclusionStrategy.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldAttributes.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldNamingPolicy.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldNamingStrategy.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonArray.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonElement.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonNull.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonObject.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonPrimitive.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/LongSerializationPolicy.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/ReflectionAccessFilter.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/ToNumberStrategy.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/internal/Excluder.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonToken.java create mode 100644 java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonWriter.java diff --git a/java/ql/test/library-tests/dataflow/taint-gson/Test.java b/java/ql/test/library-tests/dataflow/taint-gson/Test.java new file mode 100644 index 00000000000..82ca2388bbe --- /dev/null +++ b/java/ql/test/library-tests/dataflow/taint-gson/Test.java @@ -0,0 +1,38 @@ +import com.google.gson.Gson; + +public class Test { + public static class Potato { + private String name; + private Potato inner; + private Object object; + + private String getName() { + return name; + } + + private Potato getInner() { + return inner; + } + + private Object getObject() { + return object; + } + + } + + public static String source() { + return ""; + } + + public static void sink(Object any) {} + + public static void gsonfromJson() throws Exception { + String s = source(); + Potato tainted = new Gson().fromJson(s, Potato.class); + sink(tainted); // $ hasTaintFlow + sink(tainted.getName()); // $ hasTaintFlow + sink(tainted.getInner()); // $ hasTaintFlow + sink(tainted.getInner().getName()); // $ hasTaintFlow + sink(tainted.getObject()); // $ hasTaintFlow + } +} diff --git a/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.expected b/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.ql b/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.ql new file mode 100644 index 00000000000..5d91e4e8e26 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.ql @@ -0,0 +1,2 @@ +import java +import TestUtilities.InlineFlowTest diff --git a/java/ql/test/library-tests/dataflow/taint-gson/options b/java/ql/test/library-tests/dataflow/taint-gson/options new file mode 100644 index 00000000000..a9cce94fd94 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/taint-gson/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/gson-2.8.6 diff --git a/java/ql/test/library-tests/frameworks/gson/Test.java b/java/ql/test/library-tests/frameworks/gson/Test.java new file mode 100644 index 00000000000..eb3e1e526f0 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/gson/Test.java @@ -0,0 +1,468 @@ +package generatedtest; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.Reader; +import java.io.Writer; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; +import java.util.Set; + +// Test case generated by GenerateFlowTestCase.ql +public class Test { + + <K> K getMapKey(Map<K,?> map) { return map.keySet().iterator().next(); } + <T> T getElement(Iterable<T> it) { return it.iterator().next(); } + <V> V getMapValue(Map<?,V> map) { return map.get(null); } + String getMapKeyDefault(JsonObject container) { return container.keySet().iterator().next(); } + <K> K getMapKeyDefault(Map.Entry<K,?> container) { return container.getKey(); } + JsonElement getMapValueDefault(JsonObject container) { return container.get(null); } + <V> V getMapValueDefault(Map.Entry<?,V> container) { return container.getValue(); } + JsonArray newWithElementDefault(String element) { JsonArray a = new JsonArray(); a.add(element); return a; } + JsonObject newWithMapKeyDefault(String key) { JsonObject o = new JsonObject(); o.add(key, (JsonElement) null); return o; } + JsonObject newWithMapValueDefault(JsonElement element) { JsonObject o = new JsonObject(); o.add(null, element); return o; } + Object source() { return null; } + void sink(Object o) { } + + public void test() throws Exception { + + { + // "com.google.gson.stream;JsonReader;false;nextName;;;Argument[this];ReturnValue;taint;manual" + String out = null; + JsonReader in = (JsonReader)source(); + out = in.nextName(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson.stream;JsonReader;false;nextString;;;Argument[this];ReturnValue;taint;manual" + String out = null; + JsonReader in = (JsonReader)source(); + out = in.nextString(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + JsonElement in = (JsonElement)source(); + Gson instance = null; + out = instance.fromJson(in, (Class)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + JsonElement in = (JsonElement)source(); + Gson instance = null; + out = instance.fromJson(in, (Type)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + JsonElement in = (JsonElement)source(); + Gson instance = null; + out = instance.fromJson(in, (TypeToken)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + JsonReader in = (JsonReader)source(); + Gson instance = null; + out = instance.fromJson(in, (Type)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + JsonReader in = (JsonReader)source(); + Gson instance = null; + out = instance.fromJson(in, (TypeToken)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + Reader in = (Reader)source(); + Gson instance = null; + out = instance.fromJson(in, (Class)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + Reader in = (Reader)source(); + Gson instance = null; + out = instance.fromJson(in, (Type)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + Reader in = (Reader)source(); + Gson instance = null; + out = instance.fromJson(in, (TypeToken)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + String in = (String)source(); + Gson instance = null; + out = instance.fromJson(in, (Class)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + String in = (String)source(); + Gson instance = null; + out = instance.fromJson(in, (Type)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;fromJson;;;Argument[0];ReturnValue;taint;manual" + Object out = null; + String in = (String)source(); + Gson instance = null; + out = instance.fromJson(in, (TypeToken)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;newJsonReader;;;Argument[0];ReturnValue;taint;manual" + JsonReader out = null; + Reader in = (Reader)source(); + Gson instance = null; + out = instance.newJsonReader(in); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;newJsonWriter;;;Argument[0];ReturnValue;taint;manual" + JsonWriter out = null; + Writer in = (Writer)source(); + Gson instance = null; + out = instance.newJsonWriter(in); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJson;(JsonElement);;Argument[0];ReturnValue;taint;manual" + String out = null; + JsonElement in = (JsonElement)source(); + Gson instance = null; + out = instance.toJson(in); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJson;(JsonElement,Appendable);;Argument[0];Argument[1];taint;manual" + Appendable out = null; + JsonElement in = (JsonElement)source(); + Gson instance = null; + instance.toJson(in, out); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJson;(JsonElement,JsonWriter);;Argument[0];Argument[1];taint;manual" + JsonWriter out = null; + JsonElement in = (JsonElement)source(); + Gson instance = null; + instance.toJson(in, out); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJson;(Object);;Argument[0];ReturnValue;taint;manual" + String out = null; + Object in = (Object)source(); + Gson instance = null; + out = instance.toJson(in); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJson;(Object,Appendable);;Argument[0];Argument[1];taint;manual" + Appendable out = null; + Object in = (Object)source(); + Gson instance = null; + instance.toJson(in, out); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJson;(Object,Type);;Argument[0];ReturnValue;taint;manual" + String out = null; + Object in = (Object)source(); + Gson instance = null; + out = instance.toJson(in, (Type)null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJson;(Object,Type,Appendable);;Argument[0];Argument[2];taint;manual" + Appendable out = null; + Object in = (Object)source(); + Gson instance = null; + instance.toJson(in, (Type)null, out); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJson;(Object,Type,JsonWriter);;Argument[0];Argument[2];taint;manual" + JsonWriter out = null; + Object in = (Object)source(); + Gson instance = null; + instance.toJson(in, (Type)null, out); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJsonTree;(Object);;Argument[0];ReturnValue;taint;manual" + JsonElement out = null; + Object in = (Object)source(); + Gson instance = null; + out = instance.toJsonTree(in); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;Gson;false;toJsonTree;(Object,Type);;Argument[0];ReturnValue;taint;manual" + JsonElement out = null; + Object in = (Object)source(); + Gson instance = null; + out = instance.toJsonTree(in, null); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + JsonArray out = null; + Boolean in = (Boolean)source(); + out.add(in); + sink(getElement(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + JsonArray out = null; + Character in = (Character)source(); + out.add(in); + sink(getElement(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + JsonArray out = null; + JsonElement in = (JsonElement)source(); + out.add(in); + sink(getElement(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + JsonArray out = null; + Number in = (Number)source(); + out.add(in); + sink(getElement(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + JsonArray out = null; + String in = (String)source(); + out.add(in); + sink(getElement(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonArray;true;asList;;;Argument[this].Element;ReturnValue.Element;value;manual" + List out = null; + JsonArray in = (JsonArray)newWithElementDefault((String) source()); + out = in.asList(); + sink(getElement(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonArray;true;get;;;Argument[this].Element;ReturnValue;value;manual" + JsonElement out = null; + JsonArray in = (JsonArray)newWithElementDefault((String) source()); + out = in.get(0); + sink(out); // $ hasValueFlow + } + { + // "com.google.gson;JsonArray;true;set;;;Argument[1];Argument[this].Element;value;manual" + JsonArray out = null; + JsonElement in = (JsonElement)source(); + out.set(0, in); + sink(getElement(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonElement;true;getAsByte;();;Argument[this];ReturnValue;taint;manual" + byte out = 0; + JsonArray in = (JsonArray)source(); + out = in.getAsByte(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsByte;();;Argument[this];ReturnValue;taint;manual" + byte out = 0; + JsonElement in = (JsonElement)source(); + out = in.getAsByte(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsByte;();;Argument[this];ReturnValue;taint;manual" + byte out = 0; + JsonPrimitive in = (JsonPrimitive)source(); + out = in.getAsByte(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsCharacter;();;Argument[this];ReturnValue;taint;manual" + char out = 'a'; + JsonArray in = (JsonArray)source(); + out = in.getAsCharacter(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsCharacter;();;Argument[this];ReturnValue;taint;manual" + char out = 'a'; + JsonElement in = (JsonElement)source(); + out = in.getAsCharacter(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsCharacter;();;Argument[this];ReturnValue;taint;manual" + char out = 'a'; + JsonPrimitive in = (JsonPrimitive)source(); + out = in.getAsCharacter(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsJsonArray;();;Argument[this];ReturnValue;taint;manual" + JsonArray out = null; + JsonElement in = (JsonElement)source(); + out = in.getAsJsonArray(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsJsonObject;();;Argument[this];ReturnValue;taint;manual" + JsonObject out = null; + JsonElement in = (JsonElement)source(); + out = in.getAsJsonObject(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsJsonPrimitive;();;Argument[this];ReturnValue;taint;manual" + JsonPrimitive out = null; + JsonElement in = (JsonElement)source(); + out = in.getAsJsonPrimitive(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsString;();;Argument[this];ReturnValue;taint;manual" + String out = null; + JsonArray in = (JsonArray)source(); + out = in.getAsString(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsString;();;Argument[this];ReturnValue;taint;manual" + String out = null; + JsonElement in = (JsonElement)source(); + out = in.getAsString(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;getAsString;();;Argument[this];ReturnValue;taint;manual" + String out = null; + JsonPrimitive in = (JsonPrimitive)source(); + out = in.getAsString(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonElement;true;toString;();;Argument[this];ReturnValue;taint;manual" + String out = null; + JsonElement in = (JsonElement)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonObject;true;add;;;Argument[0];Argument[this].MapKey;value;manual" + JsonObject out = null; + String in = (String)source(); + out.add(in, null); + sink(getMapKeyDefault(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;add;;;Argument[1];Argument[this].MapValue;value;manual" + JsonObject out = null; + JsonElement in = (JsonElement)source(); + out.add(null, in); + sink(getMapValueDefault(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;addProperty;(String,String);;Argument[0];Argument[this].MapKey;value;manual" + JsonObject out = null; + String in = (String)source(); + out.addProperty(in, (String)null); + sink(getMapKeyDefault(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;addProperty;(String,String);;Argument[1];Argument[this].MapValue;value;manual" + JsonObject out = null; + String in = (String)source(); + out.addProperty((String)null, in); + sink(getMapValueDefault(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;asMap;;;Argument[this].MapKey;ReturnValue.MapKey;value;manual" + Map out = null; + JsonObject in = (JsonObject)newWithMapKeyDefault((String) source()); + out = in.asMap(); + sink(getMapKey(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;asMap;;;Argument[this].MapValue;ReturnValue.MapValue;value;manual" + Map out = null; + JsonObject in = (JsonObject)newWithMapValueDefault((JsonElement) source()); + out = in.asMap(); + sink(getMapValue(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;entrySet;;;Argument[this].MapKey;ReturnValue.Element.MapKey;value;manual" + Set<Map.Entry<String,JsonElement>> out = null; + JsonObject in = (JsonObject)newWithMapKeyDefault((String) source()); + out = in.entrySet(); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;entrySet;;;Argument[this].MapKey;ReturnValue.Element.MapValue;value;manual" + Set<Map.Entry<String,JsonElement>> out = null; + JsonObject in = (JsonObject) newWithMapKeyDefault((String) source()); + out = in.entrySet(); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;get;;;Argument[this].MapValue;ReturnValue;value;manual" + JsonElement out = null; + JsonObject in = (JsonObject)newWithMapValueDefault((JsonElement) source()); + out = in.get(null); + sink(out); // $ hasValueFlow + } + { + // "com.google.gson;JsonObject;true;keySet;;;Argument[this].MapKey;ReturnValue.Element;value;manual" + Set out = null; + JsonObject in = (JsonObject)newWithMapKeyDefault((String) source()); + out = in.keySet(); + sink(getElement(out)); // $ hasValueFlow + } + { + // "com.google.gson;JsonPrimitive;true;JsonPrimitive;(Character);;Argument[0];Argument[this];taint;manual" + JsonPrimitive out = null; + Character in = (Character)source(); + out = new JsonPrimitive(in); + sink(out); // $ hasTaintFlow + } + { + // "com.google.gson;JsonPrimitive;true;JsonPrimitive;(String);;Argument[0];Argument[this];taint;manual" + JsonPrimitive out = null; + String in = (String)source(); + out = new JsonPrimitive(in); + sink(out); // $ hasTaintFlow + } + + } + +} \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/gson/options b/java/ql/test/library-tests/frameworks/gson/options new file mode 100644 index 00000000000..a9cce94fd94 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/gson/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/gson-2.8.6 diff --git a/java/ql/test/library-tests/frameworks/gson/test.expected b/java/ql/test/library-tests/frameworks/gson/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/frameworks/gson/test.ql b/java/ql/test/library-tests/frameworks/gson/test.ql new file mode 100644 index 00000000000..5d91e4e8e26 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/gson/test.ql @@ -0,0 +1,2 @@ +import java +import TestUtilities.InlineFlowTest diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/ExclusionStrategy.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/ExclusionStrategy.java new file mode 100644 index 00000000000..a1cac336243 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/ExclusionStrategy.java @@ -0,0 +1,11 @@ +// Generated automatically from com.google.gson.ExclusionStrategy for testing purposes + +package com.google.gson; + +import com.google.gson.FieldAttributes; + +public interface ExclusionStrategy +{ + boolean shouldSkipClass(Class<? extends Object> p0); + boolean shouldSkipField(FieldAttributes p0); +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldAttributes.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldAttributes.java new file mode 100644 index 00000000000..1db8d794976 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldAttributes.java @@ -0,0 +1,22 @@ +// Generated automatically from com.google.gson.FieldAttributes for testing purposes + +package com.google.gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.Collection; + +public class FieldAttributes +{ + protected FieldAttributes() {} + public <T extends Annotation> T getAnnotation(java.lang.Class<T> p0){ return null; } + public Class<? extends Object> getDeclaredClass(){ return null; } + public Class<? extends Object> getDeclaringClass(){ return null; } + public Collection<Annotation> getAnnotations(){ return null; } + public FieldAttributes(Field p0){} + public String getName(){ return null; } + public String toString(){ return null; } + public Type getDeclaredType(){ return null; } + public boolean hasModifier(int p0){ return false; } +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldNamingPolicy.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldNamingPolicy.java new file mode 100644 index 00000000000..465703ae28a --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldNamingPolicy.java @@ -0,0 +1,10 @@ +// Generated automatically from com.google.gson.FieldNamingPolicy for testing purposes + +package com.google.gson; + + +public enum FieldNamingPolicy { + IDENTITY, LOWER_CASE_WITH_DASHES, LOWER_CASE_WITH_DOTS, LOWER_CASE_WITH_UNDERSCORES, UPPER_CAMEL_CASE, UPPER_CAMEL_CASE_WITH_SPACES, UPPER_CASE_WITH_UNDERSCORES; + + private FieldNamingPolicy() {} +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldNamingStrategy.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldNamingStrategy.java new file mode 100644 index 00000000000..bb3ad76d598 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/FieldNamingStrategy.java @@ -0,0 +1,10 @@ +// Generated automatically from com.google.gson.FieldNamingStrategy for testing purposes + +package com.google.gson; + +import java.lang.reflect.Field; + +public interface FieldNamingStrategy +{ + String translateName(Field p0); +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/Gson.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/Gson.java index a269763665b..61c29245d15 100644 --- a/java/ql/test/stubs/gson-2.8.6/com/google/gson/Gson.java +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/Gson.java @@ -1,38 +1,53 @@ +// Generated automatically from com.google.gson.Gson for testing purposes + package com.google.gson; -import java.lang.reflect.Type; -import java.io.Reader; +import com.google.gson.FieldNamingStrategy; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.internal.Excluder; +import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.Reader; +import java.io.Writer; +import java.lang.reflect.Type; -public final class Gson { - public Gson() { - } - - public String toJson(Object src) { - return null; - } - - public String toJson(Object src, Type typeOfSrc) { - return null; - } - - public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException { - return null; - } - - public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException { - return null; - } - - public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException { - return null; - } - - public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException { - return null; - } - - public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException { - return null; - } +public class Gson +{ + public <T> T fromJson(JsonElement p0, Type p1){ return null; } + public <T> T fromJson(JsonElement p0, com.google.gson.reflect.TypeToken<T> p1){ return null; } + public <T> T fromJson(JsonElement p0, java.lang.Class<T> p1){ return null; } + public <T> T fromJson(JsonReader p0, Type p1){ return null; } + public <T> T fromJson(JsonReader p0, com.google.gson.reflect.TypeToken<T> p1){ return null; } + public <T> T fromJson(Reader p0, Type p1){ return null; } + public <T> T fromJson(Reader p0, com.google.gson.reflect.TypeToken<T> p1){ return null; } + public <T> T fromJson(Reader p0, java.lang.Class<T> p1){ return null; } + public <T> T fromJson(String p0, Type p1){ return null; } + public <T> T fromJson(String p0, com.google.gson.reflect.TypeToken<T> p1){ return null; } + public <T> T fromJson(String p0, java.lang.Class<T> p1){ return null; } + public <T> com.google.gson.TypeAdapter<T> getAdapter(com.google.gson.reflect.TypeToken<T> p0){ return null; } + public <T> com.google.gson.TypeAdapter<T> getAdapter(java.lang.Class<T> p0){ return null; } + public <T> com.google.gson.TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory p0, com.google.gson.reflect.TypeToken<T> p1){ return null; } + public Excluder excluder(){ return null; } + public FieldNamingStrategy fieldNamingStrategy(){ return null; } + public Gson(){} + public GsonBuilder newBuilder(){ return null; } + public JsonElement toJsonTree(Object p0){ return null; } + public JsonElement toJsonTree(Object p0, Type p1){ return null; } + public JsonReader newJsonReader(Reader p0){ return null; } + public JsonWriter newJsonWriter(Writer p0){ return null; } + public String toJson(JsonElement p0){ return null; } + public String toJson(Object p0){ return null; } + public String toJson(Object p0, Type p1){ return null; } + public String toString(){ return null; } + public boolean htmlSafe(){ return false; } + public boolean serializeNulls(){ return false; } + public void toJson(JsonElement p0, Appendable p1){} + public void toJson(JsonElement p0, JsonWriter p1){} + public void toJson(Object p0, Appendable p1){} + public void toJson(Object p0, Type p1, Appendable p2){} + public void toJson(Object p0, Type p1, JsonWriter p2){} } diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/GsonBuilder.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/GsonBuilder.java index 3853cb40356..33d656b7bd7 100644 --- a/java/ql/test/stubs/gson-2.8.6/com/google/gson/GsonBuilder.java +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/GsonBuilder.java @@ -1,99 +1,46 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.gson.GsonBuilder for testing purposes package com.google.gson; +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldNamingPolicy; +import com.google.gson.FieldNamingStrategy; +import com.google.gson.Gson; +import com.google.gson.LongSerializationPolicy; +import com.google.gson.ReflectionAccessFilter; +import com.google.gson.ToNumberStrategy; +import com.google.gson.TypeAdapterFactory; import java.lang.reflect.Type; -public final class GsonBuilder { - /** - * Creates a GsonBuilder instance that can be used to build Gson with various configuration - * settings. GsonBuilder follows the builder pattern, and it is typically used by first - * invoking various configuration methods to set desired options, and finally calling - * {@link #create()}. - */ - public GsonBuilder() { - } - - /** - * Constructs a GsonBuilder instance from a Gson instance. The newly constructed GsonBuilder - * has the same configuration as the previously built Gson instance. - * - * @param gson the gson instance whose configuration should by applied to a new GsonBuilder. - */ - GsonBuilder(Gson gson) { - } - - /** - * Configures Gson for custom serialization or deserialization. This method combines the - * registration of an {@link TypeAdapter}, {@link InstanceCreator}, {@link JsonSerializer}, and a - * {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter} implements - * all the required interfaces for custom serialization with Gson. If a type adapter was - * previously registered for the specified {@code type}, it is overwritten. - * - * <p>This registers the type specified and no other types: you must manually register related - * types! For example, applications registering {@code boolean.class} should also register {@code - * Boolean.class}. - * - * @param type the type definition for the type adapter being registered - * @param typeAdapter This object must implement at least one of the {@link TypeAdapter}, - * {@link InstanceCreator}, {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces. - * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern - */ - public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) { - return null; - } - - /** - * Register a factory for type adapters. Registering a factory is useful when the type - * adapter needs to be configured based on the type of the field being processed. Gson - * is designed to handle a large number of factories, so you should consider registering - * them to be at par with registering an individual type adapter. - * - * @since 2.1 - */ - public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) { - return null; - } - - /** - * Configures Gson for custom serialization or deserialization for an inheritance type hierarchy. - * This method combines the registration of a {@link TypeAdapter}, {@link JsonSerializer} and - * a {@link JsonDeserializer}. If a type adapter was previously registered for the specified - * type hierarchy, it is overridden. If a type adapter is registered for a specific type in - * the type hierarchy, it will be invoked instead of the one registered for the type hierarchy. - * - * @param baseType the class definition for the type adapter being registered for the base class - * or interface - * @param typeAdapter This object must implement at least one of {@link TypeAdapter}, - * {@link JsonSerializer} or {@link JsonDeserializer} interfaces. - * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern - * @since 1.7 - */ - public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) { - return null; - } - - /** - * Creates a {@link Gson} instance based on the current configuration. This method is free of - * side-effects to this {@code GsonBuilder} instance and hence can be called multiple times. - * - * @return an instance of Gson configured with the options currently set in this builder - */ - public Gson create() { - return null; - } -} \ No newline at end of file +public class GsonBuilder +{ + public Gson create(){ return null; } + public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy p0){ return null; } + public GsonBuilder addReflectionAccessFilter(ReflectionAccessFilter p0){ return null; } + public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy p0){ return null; } + public GsonBuilder disableHtmlEscaping(){ return null; } + public GsonBuilder disableInnerClassSerialization(){ return null; } + public GsonBuilder disableJdkUnsafe(){ return null; } + public GsonBuilder enableComplexMapKeySerialization(){ return null; } + public GsonBuilder excludeFieldsWithModifiers(int... p0){ return null; } + public GsonBuilder excludeFieldsWithoutExposeAnnotation(){ return null; } + public GsonBuilder generateNonExecutableJson(){ return null; } + public GsonBuilder registerTypeAdapter(Type p0, Object p1){ return null; } + public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory p0){ return null; } + public GsonBuilder registerTypeHierarchyAdapter(Class<? extends Object> p0, Object p1){ return null; } + public GsonBuilder serializeNulls(){ return null; } + public GsonBuilder serializeSpecialFloatingPointValues(){ return null; } + public GsonBuilder setDateFormat(String p0){ return null; } + public GsonBuilder setDateFormat(int p0){ return null; } + public GsonBuilder setDateFormat(int p0, int p1){ return null; } + public GsonBuilder setExclusionStrategies(ExclusionStrategy... p0){ return null; } + public GsonBuilder setFieldNamingPolicy(FieldNamingPolicy p0){ return null; } + public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy p0){ return null; } + public GsonBuilder setLenient(){ return null; } + public GsonBuilder setLongSerializationPolicy(LongSerializationPolicy p0){ return null; } + public GsonBuilder setNumberToNumberStrategy(ToNumberStrategy p0){ return null; } + public GsonBuilder setObjectToNumberStrategy(ToNumberStrategy p0){ return null; } + public GsonBuilder setPrettyPrinting(){ return null; } + public GsonBuilder setVersion(double p0){ return null; } + public GsonBuilder(){} +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonArray.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonArray.java new file mode 100644 index 00000000000..c4fbae6bc1f --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonArray.java @@ -0,0 +1,45 @@ +// Generated automatically from com.google.gson.JsonArray for testing purposes + +package com.google.gson; + +import com.google.gson.JsonElement; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Iterator; +import java.util.List; + +public class JsonArray extends JsonElement implements Iterable<JsonElement> +{ + public BigDecimal getAsBigDecimal(){ return null; } + public BigInteger getAsBigInteger(){ return null; } + public Iterator<JsonElement> iterator(){ return null; } + public JsonArray deepCopy(){ return null; } + public JsonArray(){} + public JsonArray(int p0){} + public JsonElement get(int p0){ return null; } + public JsonElement remove(int p0){ return null; } + public JsonElement set(int p0, JsonElement p1){ return null; } + public List<JsonElement> asList(){ return null; } + public Number getAsNumber(){ return null; } + public String getAsString(){ return null; } + public boolean contains(JsonElement p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean getAsBoolean(){ return false; } + public boolean isEmpty(){ return false; } + public boolean remove(JsonElement p0){ return false; } + public byte getAsByte(){ return 0; } + public char getAsCharacter(){ return '0'; } + public double getAsDouble(){ return 0; } + public float getAsFloat(){ return 0; } + public int getAsInt(){ return 0; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public long getAsLong(){ return 0; } + public short getAsShort(){ return 0; } + public void add(Boolean p0){} + public void add(Character p0){} + public void add(JsonElement p0){} + public void add(Number p0){} + public void add(String p0){} + public void addAll(JsonArray p0){} +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonElement.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonElement.java new file mode 100644 index 00000000000..592fce2b672 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonElement.java @@ -0,0 +1,37 @@ +// Generated automatically from com.google.gson.JsonElement for testing purposes + +package com.google.gson; + +import com.google.gson.JsonArray; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.math.BigDecimal; +import java.math.BigInteger; + +abstract public class JsonElement +{ + public BigDecimal getAsBigDecimal(){ return null; } + public BigInteger getAsBigInteger(){ return null; } + public JsonArray getAsJsonArray(){ return null; } + public JsonElement(){} + public JsonNull getAsJsonNull(){ return null; } + public JsonObject getAsJsonObject(){ return null; } + public JsonPrimitive getAsJsonPrimitive(){ return null; } + public Number getAsNumber(){ return null; } + public String getAsString(){ return null; } + public String toString(){ return null; } + public abstract JsonElement deepCopy(); + public boolean getAsBoolean(){ return false; } + public boolean isJsonArray(){ return false; } + public boolean isJsonNull(){ return false; } + public boolean isJsonObject(){ return false; } + public boolean isJsonPrimitive(){ return false; } + public byte getAsByte(){ return 0; } + public char getAsCharacter(){ return '0'; } + public double getAsDouble(){ return 0; } + public float getAsFloat(){ return 0; } + public int getAsInt(){ return 0; } + public long getAsLong(){ return 0; } + public short getAsShort(){ return 0; } +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonNull.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonNull.java new file mode 100644 index 00000000000..e38275991eb --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonNull.java @@ -0,0 +1,14 @@ +// Generated automatically from com.google.gson.JsonNull for testing purposes + +package com.google.gson; + +import com.google.gson.JsonElement; + +public class JsonNull extends JsonElement +{ + public JsonNull deepCopy(){ return null; } + public JsonNull(){} + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + public static JsonNull INSTANCE = null; +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonObject.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonObject.java new file mode 100644 index 00000000000..a37b5455b51 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonObject.java @@ -0,0 +1,33 @@ +// Generated automatically from com.google.gson.JsonObject for testing purposes + +package com.google.gson; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; +import java.util.Map; +import java.util.Set; + +public class JsonObject extends JsonElement +{ + public JsonArray getAsJsonArray(String p0){ return null; } + public JsonElement get(String p0){ return null; } + public JsonElement remove(String p0){ return null; } + public JsonObject deepCopy(){ return null; } + public JsonObject getAsJsonObject(String p0){ return null; } + public JsonObject(){} + public JsonPrimitive getAsJsonPrimitive(String p0){ return null; } + public Map<String, JsonElement> asMap(){ return null; } + public Set<Map.Entry<String, JsonElement>> entrySet(){ return null; } + public Set<String> keySet(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean has(String p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public void add(String p0, JsonElement p1){} + public void addProperty(String p0, Boolean p1){} + public void addProperty(String p0, Character p1){} + public void addProperty(String p0, Number p1){} + public void addProperty(String p0, String p1){} +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonPrimitive.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonPrimitive.java new file mode 100644 index 00000000000..21ec07c4246 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/JsonPrimitive.java @@ -0,0 +1,34 @@ +// Generated automatically from com.google.gson.JsonPrimitive for testing purposes + +package com.google.gson; + +import com.google.gson.JsonElement; +import java.math.BigDecimal; +import java.math.BigInteger; + +public class JsonPrimitive extends JsonElement +{ + protected JsonPrimitive() {} + public BigDecimal getAsBigDecimal(){ return null; } + public BigInteger getAsBigInteger(){ return null; } + public JsonPrimitive deepCopy(){ return null; } + public JsonPrimitive(Boolean p0){} + public JsonPrimitive(Character p0){} + public JsonPrimitive(Number p0){} + public JsonPrimitive(String p0){} + public Number getAsNumber(){ return null; } + public String getAsString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean getAsBoolean(){ return false; } + public boolean isBoolean(){ return false; } + public boolean isNumber(){ return false; } + public boolean isString(){ return false; } + public byte getAsByte(){ return 0; } + public char getAsCharacter(){ return '0'; } + public double getAsDouble(){ return 0; } + public float getAsFloat(){ return 0; } + public int getAsInt(){ return 0; } + public int hashCode(){ return 0; } + public long getAsLong(){ return 0; } + public short getAsShort(){ return 0; } +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/LongSerializationPolicy.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/LongSerializationPolicy.java new file mode 100644 index 00000000000..0452deec4b9 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/LongSerializationPolicy.java @@ -0,0 +1,24 @@ +// Generated automatically from com.google.gson.LongSerializationPolicy for testing purposes + +package com.google.gson; + +import com.google.gson.JsonElement; + +public enum LongSerializationPolicy { + DEFAULT { + @Override + public JsonElement serialize(Long p0) { + return null; + } + }, + STRING { + @Override + public JsonElement serialize(Long p0) { + return null; + } + }; + + private LongSerializationPolicy() {} + + public abstract JsonElement serialize(Long p0); +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/ReflectionAccessFilter.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/ReflectionAccessFilter.java new file mode 100644 index 00000000000..ff91f103f62 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/ReflectionAccessFilter.java @@ -0,0 +1,18 @@ +// Generated automatically from com.google.gson.ReflectionAccessFilter for testing purposes + +package com.google.gson; + + +public interface ReflectionAccessFilter +{ + ReflectionAccessFilter.FilterResult check(Class<? extends Object> p0); + static ReflectionAccessFilter BLOCK_ALL_ANDROID = null; + static ReflectionAccessFilter BLOCK_ALL_JAVA = null; + static ReflectionAccessFilter BLOCK_ALL_PLATFORM = null; + static ReflectionAccessFilter BLOCK_INACCESSIBLE_JAVA = null; + static public enum FilterResult + { + ALLOW, BLOCK_ALL, BLOCK_INACCESSIBLE, INDECISIVE; + private FilterResult() {} + } +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/ToNumberStrategy.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/ToNumberStrategy.java new file mode 100644 index 00000000000..1c6ccb23111 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/ToNumberStrategy.java @@ -0,0 +1,10 @@ +// Generated automatically from com.google.gson.ToNumberStrategy for testing purposes + +package com.google.gson; + +import com.google.gson.stream.JsonReader; + +public interface ToNumberStrategy +{ + Number readNumber(JsonReader p0); +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapter.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapter.java index 73e6ef993b7..cdd0d1185b1 100644 --- a/java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapter.java +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapter.java @@ -1,130 +1,23 @@ -/* - * Copyright (C) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.gson.TypeAdapter for testing purposes package com.google.gson; +import com.google.gson.JsonElement; import com.google.gson.stream.JsonReader; -import java.io.IOException; +import com.google.gson.stream.JsonWriter; import java.io.Reader; import java.io.Writer; -public abstract class TypeAdapter<T> { - /** - * Converts {@code value} to a JSON document and writes it to {@code out}. - * Unlike Gson's similar {@link Gson#toJson(JsonElement, Appendable) toJson} - * method, this write is strict. Create a {@link - * JsonWriter#setLenient(boolean) lenient} {@code JsonWriter} and call - * {@link #write(com.google.gson.stream.JsonWriter, Object)} for lenient - * writing. - * - * @param value the Java object to convert. May be null. - * @since 2.2 - */ - public final void toJson(Writer out, T value) throws IOException { - } - - /** - * This wrapper method is used to make a type adapter null tolerant. In general, a - * type adapter is required to handle nulls in write and read methods. Here is how this - * is typically done:<br> - * <pre> {@code - * - * Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class, - * new TypeAdapter<Foo>() { - * public Foo read(JsonReader in) throws IOException { - * if (in.peek() == JsonToken.NULL) { - * in.nextNull(); - * return null; - * } - * // read a Foo from in and return it - * } - * public void write(JsonWriter out, Foo src) throws IOException { - * if (src == null) { - * out.nullValue(); - * return; - * } - * // write src as JSON to out - * } - * }).create(); - * }</pre> - * You can avoid this boilerplate handling of nulls by wrapping your type adapter with - * this method. Here is how we will rewrite the above example: - * <pre> {@code - * - * Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class, - * new TypeAdapter<Foo>() { - * public Foo read(JsonReader in) throws IOException { - * // read a Foo from in and return it - * } - * public void write(JsonWriter out, Foo src) throws IOException { - * // write src as JSON to out - * } - * }.nullSafe()).create(); - * }</pre> - * Note that we didn't need to check for nulls in our type adapter after we used nullSafe. - */ - public final TypeAdapter<T> nullSafe() { - return null; - } - - /** - * Converts {@code value} to a JSON document. Unlike Gson's similar {@link - * Gson#toJson(Object) toJson} method, this write is strict. Create a {@link - * JsonWriter#setLenient(boolean) lenient} {@code JsonWriter} and call - * {@link #write(com.google.gson.stream.JsonWriter, Object)} for lenient - * writing. - * - * @param value the Java object to convert. May be null. - * @since 2.2 - */ - public final String toJson(T value) { - return null; - } - - /** - * Reads one JSON value (an array, object, string, number, boolean or null) - * and converts it to a Java object. Returns the converted object. - * - * @return the converted Java object. May be null. - */ - public abstract T read(JsonReader in) throws IOException; - - /** - * Converts the JSON document in {@code in} to a Java object. Unlike Gson's - * similar {@link Gson#fromJson(java.io.Reader, Class) fromJson} method, this - * read is strict. Create a {@link JsonReader#setLenient(boolean) lenient} - * {@code JsonReader} and call {@link #read(JsonReader)} for lenient reading. - * - * @return the converted Java object. May be null. - * @since 2.2 - */ - public final T fromJson(Reader in) throws IOException { - return null; - } - - /** - * Converts the JSON document in {@code json} to a Java object. Unlike Gson's - * similar {@link Gson#fromJson(String, Class) fromJson} method, this read is - * strict. Create a {@link JsonReader#setLenient(boolean) lenient} {@code - * JsonReader} and call {@link #read(JsonReader)} for lenient reading. - * - * @return the converted Java object. May be null. - * @since 2.2 - */ - public final T fromJson(String json) throws IOException { - return null; - } +abstract public class TypeAdapter<T> +{ + public TypeAdapter(){} + public abstract T read(JsonReader p0); + public abstract void write(JsonWriter p0, T p1); + public final JsonElement toJsonTree(T p0){ return null; } + public final String toJson(T p0){ return null; } + public final T fromJson(Reader p0){ return null; } + public final T fromJson(String p0){ return null; } + public final T fromJsonTree(JsonElement p0){ return null; } + public final TypeAdapter<T> nullSafe(){ return null; } + public final void toJson(Writer p0, T p1){} } diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapterFactory.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapterFactory.java index d6cc8133712..6b3728f38b0 100644 --- a/java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapterFactory.java +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/TypeAdapterFactory.java @@ -1,28 +1,12 @@ -/* - * Copyright (C) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.gson.TypeAdapterFactory for testing purposes package com.google.gson; +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; import com.google.gson.reflect.TypeToken; -public interface TypeAdapterFactory { - - /** - * Returns a type adapter for {@code type}, or null if this factory doesn't - * support {@code type}. - */ - <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type); -} \ No newline at end of file +public interface TypeAdapterFactory +{ + <T> com.google.gson.TypeAdapter<T> create(Gson p0, com.google.gson.reflect.TypeToken<T> p1); +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/internal/Excluder.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/internal/Excluder.java new file mode 100644 index 00000000000..dc05b0477c5 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/internal/Excluder.java @@ -0,0 +1,25 @@ +// Generated automatically from com.google.gson.internal.Excluder for testing purposes + +package com.google.gson.internal; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import java.lang.reflect.Field; + +public class Excluder implements Cloneable, TypeAdapterFactory +{ + protected Excluder clone(){ return null; } + public <T> com.google.gson.TypeAdapter<T> create(Gson p0, com.google.gson.reflect.TypeToken<T> p1){ return null; } + public Excluder disableInnerClassSerialization(){ return null; } + public Excluder excludeFieldsWithoutExposeAnnotation(){ return null; } + public Excluder withExclusionStrategy(ExclusionStrategy p0, boolean p1, boolean p2){ return null; } + public Excluder withModifiers(int... p0){ return null; } + public Excluder withVersion(double p0){ return null; } + public Excluder(){} + public boolean excludeClass(Class<? extends Object> p0, boolean p1){ return false; } + public boolean excludeField(Field p0, boolean p1){ return false; } + public static Excluder DEFAULT = null; +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/reflect/TypeToken.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/reflect/TypeToken.java index a35b2a45b85..ac3b84cb258 100644 --- a/java/ql/test/stubs/gson-2.8.6/com/google/gson/reflect/TypeToken.java +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/reflect/TypeToken.java @@ -1,50 +1,22 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.gson.reflect.TypeToken for testing purposes package com.google.gson.reflect; -/** - * Represents a generic type {@code T}. Java doesn't yet provide a way to - * represent generic types, so this class does. Forces clients to create a - * subclass of this class which enables retrieval the type information even at - * runtime. - * - * <p>For example, to create a type literal for {@code List<String>}, you can - * create an empty anonymous inner class: - * - * <p> - * {@code TypeToken<List<String>> list = new TypeToken<List<String>>() {};} - * - * <p>This syntax cannot be used to create type literals that have wildcard - * parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}. - * - * @author Bob Lee - * @author Sven Mawson - * @author Jesse Wilson - */ -public class TypeToken<T> { +import java.lang.reflect.Type; - /** - * Constructs a new type literal. Derives represented class from type - * parameter. - * - * <p>Clients create an empty anonymous subclass. Doing so embeds the type - * parameter in the anonymous class's type hierarchy so we can reconstitute it - * at runtime despite erasure. - */ - protected TypeToken() { - } -} \ No newline at end of file +public class TypeToken<T> +{ + protected TypeToken(){} + public boolean isAssignableFrom(Class<? extends Object> p0){ return false; } + public boolean isAssignableFrom(Type p0){ return false; } + public boolean isAssignableFrom(TypeToken<? extends Object> p0){ return false; } + public final String toString(){ return null; } + public final Type getType(){ return null; } + public final boolean equals(Object p0){ return false; } + public final int hashCode(){ return 0; } + public final java.lang.Class<? super T> getRawType(){ return null; } + public static <T> com.google.gson.reflect.TypeToken<T> get(java.lang.Class<T> p0){ return null; } + public static TypeToken<? extends Object> get(Type p0){ return null; } + public static TypeToken<? extends Object> getArray(Type p0){ return null; } + public static TypeToken<? extends Object> getParameterized(Type p0, Type... p1){ return null; } +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonReader.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonReader.java index 5d0d2ad112f..677d58d8cd8 100644 --- a/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonReader.java +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonReader.java @@ -1,66 +1,33 @@ +// Generated automatically from com.google.gson.stream.JsonReader for testing purposes + package com.google.gson.stream; +import com.google.gson.stream.JsonToken; import java.io.Closeable; -import java.io.IOException; import java.io.Reader; -public class JsonReader implements Closeable { - public JsonReader(Reader in) { - } - - public final void setLenient(boolean lenient) { - } - - public final boolean isLenient() { - return false; - } - - public void beginArray() throws IOException { - } - - public void endArray() throws IOException { - } - - public void beginObject() throws IOException { - } - - public void endObject() throws IOException { - } - - public boolean hasNext() throws IOException { - return false; - } - - public String nextName() throws IOException { - return null; - } - - public String nextString() throws IOException { - return null; - } - - public boolean nextBoolean() throws IOException { - return false; - } - - public void nextNull() throws IOException { - } - - public double nextDouble() throws IOException { - return -1; - } - - public long nextLong() throws IOException { - return -1; - } - - public int nextInt() throws IOException { - return -1; - } - - public void close() throws IOException { - } - - public void skipValue() throws IOException { - } -} \ No newline at end of file +public class JsonReader implements Closeable +{ + protected JsonReader() {} + public JsonReader(Reader p0){} + public JsonToken peek(){ return null; } + public String getPath(){ return null; } + public String getPreviousPath(){ return null; } + public String nextName(){ return null; } + public String nextString(){ return null; } + public String toString(){ return null; } + public boolean hasNext(){ return false; } + public boolean nextBoolean(){ return false; } + public double nextDouble(){ return 0; } + public final boolean isLenient(){ return false; } + public final void setLenient(boolean p0){} + public int nextInt(){ return 0; } + public long nextLong(){ return 0; } + public void beginArray(){} + public void beginObject(){} + public void close(){} + public void endArray(){} + public void endObject(){} + public void nextNull(){} + public void skipValue(){} +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonToken.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonToken.java new file mode 100644 index 00000000000..fbb2e7ac463 --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonToken.java @@ -0,0 +1,10 @@ +// Generated automatically from com.google.gson.stream.JsonToken for testing purposes + +package com.google.gson.stream; + + +public enum JsonToken +{ + BEGIN_ARRAY, BEGIN_OBJECT, BOOLEAN, END_ARRAY, END_DOCUMENT, END_OBJECT, NAME, NULL, NUMBER, STRING; + private JsonToken() {} +} diff --git a/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonWriter.java b/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonWriter.java new file mode 100644 index 00000000000..282343f0bed --- /dev/null +++ b/java/ql/test/stubs/gson-2.8.6/com/google/gson/stream/JsonWriter.java @@ -0,0 +1,36 @@ +// Generated automatically from com.google.gson.stream.JsonWriter for testing purposes + +package com.google.gson.stream; + +import java.io.Closeable; +import java.io.Flushable; +import java.io.Writer; + +public class JsonWriter implements Closeable, Flushable +{ + protected JsonWriter() {} + public JsonWriter beginArray(){ return null; } + public JsonWriter beginObject(){ return null; } + public JsonWriter endArray(){ return null; } + public JsonWriter endObject(){ return null; } + public JsonWriter jsonValue(String p0){ return null; } + public JsonWriter name(String p0){ return null; } + public JsonWriter nullValue(){ return null; } + public JsonWriter value(Boolean p0){ return null; } + public JsonWriter value(Number p0){ return null; } + public JsonWriter value(String p0){ return null; } + public JsonWriter value(boolean p0){ return null; } + public JsonWriter value(double p0){ return null; } + public JsonWriter value(float p0){ return null; } + public JsonWriter value(long p0){ return null; } + public JsonWriter(Writer p0){} + public boolean isLenient(){ return false; } + public final boolean getSerializeNulls(){ return false; } + public final boolean isHtmlSafe(){ return false; } + public final void setHtmlSafe(boolean p0){} + public final void setIndent(String p0){} + public final void setLenient(boolean p0){} + public final void setSerializeNulls(boolean p0){} + public void close(){} + public void flush(){} +} From 0151a728f8467d4af670803bb63b34b38fe65069 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 30 May 2023 17:53:03 +0200 Subject: [PATCH 188/739] Add change note --- java/ql/lib/change-notes/2023-05-30-gson-models.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-05-30-gson-models.md diff --git a/java/ql/lib/change-notes/2023-05-30-gson-models.md b/java/ql/lib/change-notes/2023-05-30-gson-models.md new file mode 100644 index 00000000000..306d797ff1a --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-30-gson-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added dataflow models for the Gson deserialization library. From 70138448c3077624c36b4d52e9a04f27200471b6 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 30 May 2023 17:54:59 +0200 Subject: [PATCH 189/739] Visibility --- .../code/java/frameworks/google/GsonSerializability.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index 470847f292e..dba25be7b22 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -4,9 +4,9 @@ */ import java -import semmle.code.java.Serializability -import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.FlowSteps +private import semmle.code.java.Serializability +private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSteps /** * A method used for deserializing objects using Gson. The first parameter is the object to be @@ -44,7 +44,7 @@ private class FieldReferencedGsonDeserializableType extends GsonDeserializableTy } /** A field that may be deserialized using the Gson JSON framework. */ -class GsonDeserializableField extends DeserializableField { +private class GsonDeserializableField extends DeserializableField { pragma[assume_small_delta] GsonDeserializableField() { exists(GsonDeserializableType superType | From a8c76388c0005f7ae1a5ab7637ba1b1b74a10667 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 30 May 2023 18:13:22 +0200 Subject: [PATCH 190/739] C++: Fix configuration names in comments in `cpp/invalid-pointer-deref` --- .../CWE/CWE-193/InvalidPointerDeref.ql | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 07189cea9d9..edfd7a76a5f 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -81,8 +81,8 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) { * ``` * * We do this by splitting the task up into two configurations: - * 1. `AllocToInvalidPointerConf` find flow from `malloc(size)` to `begin + size`, and - * 2. `InvalidPointerToDerefConf` finds flow from `begin + size` to an `end` (on line 3). + * 1. `AllocToInvalidPointerConfig` find flow from `malloc(size)` to `begin + size`, and + * 2. `InvalidPointerToDerefConfig` finds flow from `begin + size` to an `end` (on line 3). * * Finally, the range-analysis library will find a load from (or store to) an address that * is non-strictly upper-bounded by `end` (which in this case is `*p`). @@ -180,7 +180,7 @@ predicate isSinkImpl( } /** - * Holds if `sink` is a sink for `InvalidPointerToDerefConf` and `i` is a `StoreInstruction` that + * Holds if `sink` is a sink for `InvalidPointerToDerefConfig` and `i` is a `StoreInstruction` that * writes to an address that non-strictly upper-bounds `sink`, or `i` is a `LoadInstruction` that * reads from an address that non-strictly upper-bounds `sink`. */ @@ -201,7 +201,7 @@ predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string o /** * A configuration to track flow from a pointer-arithmetic operation found - * by `AllocToInvalidPointerConf` to a dereference of the pointer. + * by `AllocToInvalidPointerConfig` to a dereference of the pointer. */ module InvalidPointerToDerefConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { invalidPointerToDerefSource(_, source, _) } @@ -237,12 +237,12 @@ predicate invalidPointerToDerefSource( } newtype TMergedPathNode = - // The path nodes computed by the first projection of `AllocToInvalidPointerConf` + // The path nodes computed by the first projection of `AllocToInvalidPointerConfig` TPathNode1(AllocToInvalidPointerFlow::PathNode1 p) or - // The path nodes computed by `InvalidPointerToDerefConf` + // The path nodes computed by `InvalidPointerToDerefConfig` TPathNode3(InvalidPointerToDerefFlow::PathNode p) or - // The read/write that uses the invalid pointer identified by `InvalidPointerToDerefConf`. - // This one is needed because the sink identified by `InvalidPointerToDerefConf` is the + // The read/write that uses the invalid pointer identified by `InvalidPointerToDerefConfig`. + // This one is needed because the sink identified by `InvalidPointerToDerefConfig` is the // pointer, but we want to raise an alert at the dereference. TPathNodeSink(Instruction i) { exists(DataFlow::Node n | @@ -335,8 +335,8 @@ query predicate subpaths( } /** - * Holds if `p1` is a sink of `AllocToInvalidPointerConf` and `p2` is a source - * of `InvalidPointerToDerefConf`, and they are connected through `pai`. + * Holds if `p1` is a sink of `AllocToInvalidPointerConfig` and `p2` is a source + * of `InvalidPointerToDerefConfig`, and they are connected through `pai`. */ predicate joinOn1( PointerArithmeticInstruction pai, AllocToInvalidPointerFlow::PathNode1 p1, @@ -347,7 +347,7 @@ predicate joinOn1( } /** - * Holds if `p1` is a sink of `InvalidPointerToDerefConf` and `i` is the instruction + * Holds if `p1` is a sink of `InvalidPointerToDerefConfig` and `i` is the instruction * that dereferences `p1`. The string `operation` describes whether the `i` is * a `StoreInstruction` or `LoadInstruction`. */ From de974cc18a4792e7329de3f4323f42e4485048b0 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 30 May 2023 18:15:59 +0200 Subject: [PATCH 191/739] C++: Add `cpp/invalid-pointer-deref` test case that shows some duplicate results --- .../InvalidPointerDeref.expected | 57 +++++++++++++++++++ .../CWE/CWE-193/pointer-deref/test.cpp | 8 +++ 2 files changed, 65 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 1487088ca9f..4c6693a9d20 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -671,6 +671,58 @@ edges | test.cpp:350:16:350:19 | ... ++ | test.cpp:350:15:350:19 | Load: * ... | | test.cpp:350:16:350:19 | ... ++ | test.cpp:350:16:350:19 | ... ++ | | test.cpp:350:16:350:19 | ... ++ | test.cpp:350:16:350:19 | ... ++ | +| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:16 | xs | +| test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... | +| test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... | +| test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... | +| test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... | +| test.cpp:356:15:356:16 | xs | test.cpp:357:24:357:26 | end | +| test.cpp:356:15:356:16 | xs | test.cpp:357:24:357:30 | ... + ... | +| test.cpp:356:15:356:16 | xs | test.cpp:357:24:357:30 | ... + ... | +| test.cpp:356:15:356:16 | xs | test.cpp:357:24:357:30 | ... + ... | +| test.cpp:356:15:356:16 | xs | test.cpp:357:24:357:30 | ... + ... | +| test.cpp:356:15:356:16 | xs | test.cpp:358:15:358:26 | end_plus_one | +| test.cpp:356:15:356:16 | xs | test.cpp:358:15:358:26 | end_plus_one | +| test.cpp:356:15:356:16 | xs | test.cpp:359:16:359:27 | end_plus_one | +| test.cpp:356:15:356:16 | xs | test.cpp:359:16:359:31 | ... + ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:356:15:356:23 | ... + ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:356:15:356:23 | ... + ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:357:24:357:26 | end | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:357:24:357:26 | end | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:357:24:357:26 | end | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:357:24:357:26 | end | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:357:24:357:30 | ... + ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:357:24:357:30 | ... + ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:15:358:26 | end_plus_one | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:15:358:26 | end_plus_one | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:15:358:26 | end_plus_one | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:15:358:26 | end_plus_one | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:16:359:27 | end_plus_one | +| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:16:359:27 | end_plus_one | +| test.cpp:358:15:358:26 | end_plus_one | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:358:15:358:26 | end_plus_one | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:16:359:27 | end_plus_one | +| test.cpp:359:16:359:27 | end_plus_one | test.cpp:358:14:358:26 | Load: * ... | +| test.cpp:359:16:359:27 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:359:16:359:31 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | @@ -699,3 +751,8 @@ subpaths | test.cpp:333:5:333:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:333:5:333:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size | | test.cpp:341:5:341:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:341:5:341:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size | | test.cpp:350:15:350:19 | Load: * ... | test.cpp:347:14:347:27 | new[] | test.cpp:350:15:350:19 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:347:14:347:27 | new[] | new[] | test.cpp:348:20:348:23 | size | size | +| test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | +| test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | +| test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | +| test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | +| test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index b6741535e42..3dfd8b89097 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -350,3 +350,11 @@ void test24(unsigned size) { int val = *xs++; // GOOD [FALSE POSITIVE] } } + +void test25(unsigned size) { + char *xs = new char[size]; + char *end = xs + size; + char *end_plus_one = end + 1; + int val1 = *end_plus_one; // BAD + int val2 = *(end_plus_one + 1); // BAD +} From f5ed02a43376a503b3efd2ce4aadf97520c628aa Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 30 May 2023 18:23:22 +0200 Subject: [PATCH 192/739] C++: Take into account the delta at the final sink in `cpp/invalid-pointer-deref` --- .../CWE/CWE-193/InvalidPointerDeref.ql | 26 +++++++++---------- .../InvalidPointerDeref.expected | 6 ----- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index edfd7a76a5f..646843d077c 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -185,8 +185,8 @@ predicate isSinkImpl( * reads from an address that non-strictly upper-bounds `sink`. */ pragma[inline] -predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string operation) { - exists(AddressOperand addr, int delta | +predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string operation, int delta) { + exists(AddressOperand addr | bounded1(addr.getDef(), sink.asInstruction(), delta) and delta >= 0 and i.getAnOperand() = addr @@ -207,7 +207,7 @@ module InvalidPointerToDerefConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { invalidPointerToDerefSource(_, source, _) } pragma[inline] - predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _) } + predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _, _) } predicate isBarrier(DataFlow::Node node) { node = any(DataFlow::SsaPhiNode phi | not phi.isPhiRead()).getAnInput(true) @@ -247,7 +247,7 @@ newtype TMergedPathNode = TPathNodeSink(Instruction i) { exists(DataFlow::Node n | InvalidPointerToDerefFlow::flowTo(n) and - isInvalidPointerDerefSink(n, i, _) + isInvalidPointerDerefSink(n, i, _, _) ) } @@ -321,7 +321,7 @@ query predicate edges(MergedPathNode node1, MergedPathNode node2) { or node1.asPathNode3().getASuccessor() = node2.asPathNode3() or - joinOn2(node1.asPathNode3(), node2.asSinkNode(), _) + joinOn2(node1.asPathNode3(), node2.asSinkNode(), _, _) } query predicate subpaths( @@ -352,32 +352,32 @@ predicate joinOn1( * a `StoreInstruction` or `LoadInstruction`. */ pragma[inline] -predicate joinOn2(InvalidPointerToDerefFlow::PathNode p1, Instruction i, string operation) { - isInvalidPointerDerefSink(p1.getNode(), i, operation) +predicate joinOn2(InvalidPointerToDerefFlow::PathNode p1, Instruction i, string operation, int delta) { + isInvalidPointerDerefSink(p1.getNode(), i, operation, delta) } predicate hasFlowPath( MergedPathNode source1, MergedPathNode sink, InvalidPointerToDerefFlow::PathNode source3, - PointerArithmeticInstruction pai, string operation + PointerArithmeticInstruction pai, string operation, int delta ) { exists(InvalidPointerToDerefFlow::PathNode sink3, AllocToInvalidPointerFlow::PathNode1 sink1 | AllocToInvalidPointerFlow::flowPath(source1.asPathNode1(), _, sink1, _) and joinOn1(pai, sink1, source3) and InvalidPointerToDerefFlow::flowPath(source3, sink3) and - joinOn2(sink3, sink.asSinkNode(), operation) + joinOn2(sink3, sink.asSinkNode(), operation, delta) ) } from - MergedPathNode source, MergedPathNode sink, int k, string kstr, + MergedPathNode source, MergedPathNode sink, int k2, int k3, string kstr, InvalidPointerToDerefFlow::PathNode source3, PointerArithmeticInstruction pai, string operation, Expr offset, DataFlow::Node n where - hasFlowPath(source, sink, source3, pai, operation) and - invalidPointerToDerefSource(pai, source3.getNode(), k) and + hasFlowPath(source, sink, source3, pai, operation, k3) and + invalidPointerToDerefSource(pai, source3.getNode(), k2) and offset = pai.getRight().getUnconvertedResultExpression() and n = source.asPathNode1().getNode() and - if k = 0 then kstr = "" else kstr = " + " + k + if (k2 + k3) = 0 then kstr = "" else kstr = " + " + (k2 + k3) select sink, source, sink, "This " + operation + " might be out of bounds, as the pointer might be equal to $@ + $@" + kstr + ".", n, n.toString(), offset, offset.toString() diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 4c6693a9d20..ba5363dc4fa 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -727,14 +727,11 @@ subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | | test.cpp:8:14:8:21 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:8:14:8:21 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | -| test.cpp:8:14:8:21 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:8:14:8:21 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | | test.cpp:20:14:20:21 | Load: * ... | test.cpp:16:15:16:20 | call to malloc | test.cpp:20:14:20:21 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:16:15:16:20 | call to malloc | call to malloc | test.cpp:17:19:17:22 | size | size | | test.cpp:30:14:30:15 | Load: * ... | test.cpp:28:15:28:20 | call to malloc | test.cpp:30:14:30:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:28:15:28:20 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... | | test.cpp:32:14:32:21 | Load: * ... | test.cpp:28:15:28:20 | call to malloc | test.cpp:32:14:32:21 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:28:15:28:20 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... | -| test.cpp:32:14:32:21 | Load: * ... | test.cpp:28:15:28:20 | call to malloc | test.cpp:32:14:32:21 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:28:15:28:20 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... | | test.cpp:42:14:42:15 | Load: * ... | test.cpp:40:15:40:20 | call to malloc | test.cpp:42:14:42:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:40:15:40:20 | call to malloc | call to malloc | test.cpp:41:20:41:27 | ... - ... | ... - ... | | test.cpp:44:14:44:21 | Load: * ... | test.cpp:40:15:40:20 | call to malloc | test.cpp:44:14:44:21 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:40:15:40:20 | call to malloc | call to malloc | test.cpp:41:20:41:27 | ... - ... | ... - ... | -| test.cpp:44:14:44:21 | Load: * ... | test.cpp:40:15:40:20 | call to malloc | test.cpp:44:14:44:21 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:40:15:40:20 | call to malloc | call to malloc | test.cpp:41:20:41:27 | ... - ... | ... - ... | | test.cpp:67:9:67:14 | Store: ... = ... | test.cpp:52:19:52:24 | call to malloc | test.cpp:67:9:67:14 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:52:19:52:24 | call to malloc | call to malloc | test.cpp:53:20:53:23 | size | size | | test.cpp:96:9:96:14 | Store: ... = ... | test.cpp:82:17:82:22 | call to malloc | test.cpp:96:9:96:14 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:82:17:82:22 | call to malloc | call to malloc | test.cpp:83:27:83:30 | size | size | | test.cpp:110:9:110:14 | Store: ... = ... | test.cpp:82:17:82:22 | call to malloc | test.cpp:110:9:110:14 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:82:17:82:22 | call to malloc | call to malloc | test.cpp:83:27:83:30 | size | size | @@ -752,7 +749,4 @@ subpaths | test.cpp:341:5:341:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:341:5:341:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size | | test.cpp:350:15:350:19 | Load: * ... | test.cpp:347:14:347:27 | new[] | test.cpp:350:15:350:19 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:347:14:347:27 | new[] | new[] | test.cpp:348:20:348:23 | size | size | | test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | -| test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | -| test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | -| test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | From dd30acf1e335445613f674ba855557fac25287fb Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 30 May 2023 18:43:01 +0200 Subject: [PATCH 193/739] C++: Add nodes query predicate to `cpp/invalid-pointer-deref` --- .../CWE/CWE-193/InvalidPointerDeref.ql | 8 + .../InvalidPointerDeref.expected | 327 ++++++++++++++++++ 2 files changed, 335 insertions(+) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 646843d077c..610eb572d8c 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -324,6 +324,14 @@ query predicate edges(MergedPathNode node1, MergedPathNode node2) { joinOn2(node1.asPathNode3(), node2.asSinkNode(), _, _) } +query predicate nodes(MergedPathNode n, string key, string val) { + AllocToInvalidPointerFlow::PathGraph1::nodes(n.asPathNode1(), key, val) + or + InvalidPointerToDerefFlow::PathGraph::nodes(n.asPathNode3(), key, val) + or + key = "semmle.label" and val = n.asSinkNode().toString() +} + query predicate subpaths( MergedPathNode arg, MergedPathNode par, MergedPathNode ret, MergedPathNode out ) { diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index ba5363dc4fa..6b4d039ee6b 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -723,6 +723,333 @@ edges | test.cpp:359:16:359:27 | end_plus_one | test.cpp:358:14:358:26 | Load: * ... | | test.cpp:359:16:359:27 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:359:16:359:31 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +nodes +| test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc | +| test.cpp:5:15:5:15 | p | semmle.label | p | +| test.cpp:5:15:5:22 | ... + ... | semmle.label | ... + ... | +| test.cpp:5:15:5:22 | ... + ... | semmle.label | ... + ... | +| test.cpp:5:15:5:22 | ... + ... | semmle.label | ... + ... | +| test.cpp:5:15:5:22 | ... + ... | semmle.label | ... + ... | +| test.cpp:6:14:6:15 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:6:15:6:15 | q | semmle.label | q | +| test.cpp:6:15:6:15 | q | semmle.label | q | +| test.cpp:7:16:7:16 | q | semmle.label | q | +| test.cpp:7:16:7:16 | q | semmle.label | q | +| test.cpp:8:14:8:21 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:8:16:8:16 | q | semmle.label | q | +| test.cpp:8:16:8:16 | q | semmle.label | q | +| test.cpp:8:16:8:20 | ... + ... | semmle.label | ... + ... | +| test.cpp:9:16:9:16 | q | semmle.label | q | +| test.cpp:9:16:9:16 | q | semmle.label | q | +| test.cpp:10:16:10:16 | q | semmle.label | q | +| test.cpp:10:16:10:16 | q | semmle.label | q | +| test.cpp:11:16:11:16 | q | semmle.label | q | +| test.cpp:11:16:11:16 | q | semmle.label | q | +| test.cpp:12:16:12:16 | q | semmle.label | q | +| test.cpp:16:15:16:20 | call to malloc | semmle.label | call to malloc | +| test.cpp:17:15:17:15 | p | semmle.label | p | +| test.cpp:17:15:17:22 | ... + ... | semmle.label | ... + ... | +| test.cpp:20:14:20:21 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:20:16:20:20 | ... + ... | semmle.label | ... + ... | +| test.cpp:28:15:28:20 | call to malloc | semmle.label | call to malloc | +| test.cpp:29:15:29:15 | p | semmle.label | p | +| test.cpp:29:15:29:28 | ... + ... | semmle.label | ... + ... | +| test.cpp:29:15:29:28 | ... + ... | semmle.label | ... + ... | +| test.cpp:29:15:29:28 | ... + ... | semmle.label | ... + ... | +| test.cpp:29:15:29:28 | ... + ... | semmle.label | ... + ... | +| test.cpp:30:14:30:15 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:30:15:30:15 | q | semmle.label | q | +| test.cpp:30:15:30:15 | q | semmle.label | q | +| test.cpp:31:16:31:16 | q | semmle.label | q | +| test.cpp:31:16:31:16 | q | semmle.label | q | +| test.cpp:32:14:32:21 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:32:16:32:16 | q | semmle.label | q | +| test.cpp:32:16:32:16 | q | semmle.label | q | +| test.cpp:32:16:32:20 | ... + ... | semmle.label | ... + ... | +| test.cpp:33:16:33:16 | q | semmle.label | q | +| test.cpp:33:16:33:16 | q | semmle.label | q | +| test.cpp:34:16:34:16 | q | semmle.label | q | +| test.cpp:34:16:34:16 | q | semmle.label | q | +| test.cpp:35:16:35:16 | q | semmle.label | q | +| test.cpp:35:16:35:16 | q | semmle.label | q | +| test.cpp:36:16:36:16 | q | semmle.label | q | +| test.cpp:40:15:40:20 | call to malloc | semmle.label | call to malloc | +| test.cpp:41:15:41:15 | p | semmle.label | p | +| test.cpp:41:15:41:28 | ... + ... | semmle.label | ... + ... | +| test.cpp:41:15:41:28 | ... + ... | semmle.label | ... + ... | +| test.cpp:41:15:41:28 | ... + ... | semmle.label | ... + ... | +| test.cpp:41:15:41:28 | ... + ... | semmle.label | ... + ... | +| test.cpp:42:14:42:15 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:42:15:42:15 | q | semmle.label | q | +| test.cpp:42:15:42:15 | q | semmle.label | q | +| test.cpp:43:16:43:16 | q | semmle.label | q | +| test.cpp:43:16:43:16 | q | semmle.label | q | +| test.cpp:44:14:44:21 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:44:16:44:16 | q | semmle.label | q | +| test.cpp:44:16:44:16 | q | semmle.label | q | +| test.cpp:44:16:44:20 | ... + ... | semmle.label | ... + ... | +| test.cpp:45:16:45:16 | q | semmle.label | q | +| test.cpp:45:16:45:16 | q | semmle.label | q | +| test.cpp:46:16:46:16 | q | semmle.label | q | +| test.cpp:46:16:46:16 | q | semmle.label | q | +| test.cpp:47:16:47:16 | q | semmle.label | q | +| test.cpp:47:16:47:16 | q | semmle.label | q | +| test.cpp:48:16:48:16 | q | semmle.label | q | +| test.cpp:51:7:51:14 | mk_array indirection | semmle.label | mk_array indirection | +| test.cpp:51:33:51:35 | end | semmle.label | end | +| test.cpp:52:19:52:24 | call to malloc | semmle.label | call to malloc | +| test.cpp:53:5:53:23 | ... = ... | semmle.label | ... = ... | +| test.cpp:53:12:53:16 | begin | semmle.label | begin | +| test.cpp:53:12:53:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:60:19:60:26 | call to mk_array | semmle.label | call to mk_array | +| test.cpp:60:34:60:37 | mk_array output argument | semmle.label | mk_array output argument | +| test.cpp:62:32:62:34 | end | semmle.label | end | +| test.cpp:62:39:62:39 | p | semmle.label | p | +| test.cpp:66:32:66:34 | end | semmle.label | end | +| test.cpp:66:39:66:39 | p | semmle.label | p | +| test.cpp:67:9:67:14 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:70:31:70:33 | end | semmle.label | end | +| test.cpp:70:38:70:38 | p | semmle.label | p | +| test.cpp:80:9:80:16 | mk_array indirection [begin] | semmle.label | mk_array indirection [begin] | +| test.cpp:80:9:80:16 | mk_array indirection [end] | semmle.label | mk_array indirection [end] | +| test.cpp:82:5:82:28 | ... = ... | semmle.label | ... = ... | +| test.cpp:82:9:82:13 | arr indirection [post update] [begin] | semmle.label | arr indirection [post update] [begin] | +| test.cpp:82:17:82:22 | call to malloc | semmle.label | call to malloc | +| test.cpp:83:5:83:30 | ... = ... | semmle.label | ... = ... | +| test.cpp:83:9:83:11 | arr indirection [post update] [end] | semmle.label | arr indirection [post update] [end] | +| test.cpp:83:15:83:17 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:83:15:83:30 | ... + ... | semmle.label | ... + ... | +| test.cpp:83:19:83:23 | begin | semmle.label | begin | +| test.cpp:83:19:83:23 | begin indirection | semmle.label | begin indirection | +| test.cpp:89:19:89:26 | call to mk_array [begin] | semmle.label | call to mk_array [begin] | +| test.cpp:89:19:89:26 | call to mk_array [end] | semmle.label | call to mk_array [end] | +| test.cpp:91:20:91:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:91:24:91:28 | begin | semmle.label | begin | +| test.cpp:91:24:91:28 | begin indirection | semmle.label | begin indirection | +| test.cpp:91:36:91:38 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:91:40:91:42 | end | semmle.label | end | +| test.cpp:91:40:91:42 | end indirection | semmle.label | end indirection | +| test.cpp:91:47:91:47 | p | semmle.label | p | +| test.cpp:95:20:95:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:95:24:95:28 | begin | semmle.label | begin | +| test.cpp:95:24:95:28 | begin indirection | semmle.label | begin indirection | +| test.cpp:95:36:95:38 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:95:40:95:42 | end | semmle.label | end | +| test.cpp:95:40:95:42 | end indirection | semmle.label | end indirection | +| test.cpp:95:47:95:47 | p | semmle.label | p | +| test.cpp:96:9:96:14 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:99:20:99:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:99:24:99:28 | begin | semmle.label | begin | +| test.cpp:99:24:99:28 | begin indirection | semmle.label | begin indirection | +| test.cpp:99:35:99:37 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:99:39:99:41 | end | semmle.label | end | +| test.cpp:99:39:99:41 | end indirection | semmle.label | end indirection | +| test.cpp:99:46:99:46 | p | semmle.label | p | +| test.cpp:104:27:104:29 | arr [begin] | semmle.label | arr [begin] | +| test.cpp:104:27:104:29 | arr [end] | semmle.label | arr [end] | +| test.cpp:105:20:105:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:105:24:105:28 | begin | semmle.label | begin | +| test.cpp:105:24:105:28 | begin indirection | semmle.label | begin indirection | +| test.cpp:105:36:105:38 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:105:40:105:42 | end | semmle.label | end | +| test.cpp:105:40:105:42 | end indirection | semmle.label | end indirection | +| test.cpp:105:47:105:47 | p | semmle.label | p | +| test.cpp:109:20:109:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:109:24:109:28 | begin | semmle.label | begin | +| test.cpp:109:24:109:28 | begin indirection | semmle.label | begin indirection | +| test.cpp:109:36:109:38 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:109:40:109:42 | end | semmle.label | end | +| test.cpp:109:40:109:42 | end indirection | semmle.label | end indirection | +| test.cpp:109:47:109:47 | p | semmle.label | p | +| test.cpp:110:9:110:14 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:113:20:113:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:113:24:113:28 | begin | semmle.label | begin | +| test.cpp:113:24:113:28 | begin indirection | semmle.label | begin indirection | +| test.cpp:113:35:113:37 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:113:39:113:41 | end | semmle.label | end | +| test.cpp:113:39:113:41 | end indirection | semmle.label | end indirection | +| test.cpp:113:46:113:46 | p | semmle.label | p | +| test.cpp:119:18:119:25 | call to mk_array [begin] | semmle.label | call to mk_array [begin] | +| test.cpp:119:18:119:25 | call to mk_array [end] | semmle.label | call to mk_array [end] | +| test.cpp:124:15:124:20 | call to malloc | semmle.label | call to malloc | +| test.cpp:125:5:125:17 | ... = ... | semmle.label | ... = ... | +| test.cpp:125:9:125:13 | arr indirection [post update] [begin] | semmle.label | arr indirection [post update] [begin] | +| test.cpp:126:15:126:15 | p | semmle.label | p | +| test.cpp:129:11:129:13 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:129:15:129:19 | begin | semmle.label | begin | +| test.cpp:129:15:129:19 | begin indirection | semmle.label | begin indirection | +| test.cpp:133:11:133:13 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:133:15:133:19 | begin | semmle.label | begin | +| test.cpp:133:15:133:19 | begin indirection | semmle.label | begin indirection | +| test.cpp:137:11:137:13 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:137:15:137:19 | begin | semmle.label | begin | +| test.cpp:137:15:137:19 | begin indirection | semmle.label | begin indirection | +| test.cpp:141:10:141:19 | mk_array_p indirection [begin] | semmle.label | mk_array_p indirection [begin] | +| test.cpp:141:10:141:19 | mk_array_p indirection [end] | semmle.label | mk_array_p indirection [end] | +| test.cpp:143:5:143:29 | ... = ... | semmle.label | ... = ... | +| test.cpp:143:10:143:14 | arr indirection [post update] [begin] | semmle.label | arr indirection [post update] [begin] | +| test.cpp:143:18:143:23 | call to malloc | semmle.label | call to malloc | +| test.cpp:144:5:144:32 | ... = ... | semmle.label | ... = ... | +| test.cpp:144:10:144:12 | arr indirection [post update] [end] | semmle.label | arr indirection [post update] [end] | +| test.cpp:144:16:144:18 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:144:16:144:32 | ... + ... | semmle.label | ... + ... | +| test.cpp:144:21:144:25 | begin | semmle.label | begin | +| test.cpp:144:21:144:25 | begin indirection | semmle.label | begin indirection | +| test.cpp:150:20:150:29 | call to mk_array_p indirection [begin] | semmle.label | call to mk_array_p indirection [begin] | +| test.cpp:150:20:150:29 | call to mk_array_p indirection [end] | semmle.label | call to mk_array_p indirection [end] | +| test.cpp:152:20:152:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:152:25:152:29 | begin | semmle.label | begin | +| test.cpp:152:25:152:29 | begin indirection | semmle.label | begin indirection | +| test.cpp:152:49:152:49 | p | semmle.label | p | +| test.cpp:156:20:156:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:156:25:156:29 | begin | semmle.label | begin | +| test.cpp:156:25:156:29 | begin indirection | semmle.label | begin indirection | +| test.cpp:156:37:156:39 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:156:42:156:44 | end | semmle.label | end | +| test.cpp:156:42:156:44 | end indirection | semmle.label | end indirection | +| test.cpp:156:49:156:49 | p | semmle.label | p | +| test.cpp:157:9:157:14 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:160:20:160:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:160:25:160:29 | begin | semmle.label | begin | +| test.cpp:160:25:160:29 | begin indirection | semmle.label | begin indirection | +| test.cpp:160:48:160:48 | p | semmle.label | p | +| test.cpp:165:29:165:31 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:165:29:165:31 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:166:20:166:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:166:25:166:29 | begin | semmle.label | begin | +| test.cpp:166:25:166:29 | begin indirection | semmle.label | begin indirection | +| test.cpp:166:37:166:39 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:166:42:166:44 | end | semmle.label | end | +| test.cpp:166:42:166:44 | end indirection | semmle.label | end indirection | +| test.cpp:166:49:166:49 | p | semmle.label | p | +| test.cpp:170:20:170:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:170:25:170:29 | begin | semmle.label | begin | +| test.cpp:170:25:170:29 | begin indirection | semmle.label | begin indirection | +| test.cpp:170:37:170:39 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:170:42:170:44 | end | semmle.label | end | +| test.cpp:170:42:170:44 | end indirection | semmle.label | end indirection | +| test.cpp:170:49:170:49 | p | semmle.label | p | +| test.cpp:171:9:171:14 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:174:20:174:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | +| test.cpp:174:25:174:29 | begin | semmle.label | begin | +| test.cpp:174:25:174:29 | begin indirection | semmle.label | begin indirection | +| test.cpp:174:36:174:38 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:174:41:174:43 | end | semmle.label | end | +| test.cpp:174:41:174:43 | end indirection | semmle.label | end indirection | +| test.cpp:174:48:174:48 | p | semmle.label | p | +| test.cpp:180:19:180:28 | call to mk_array_p indirection [begin] | semmle.label | call to mk_array_p indirection [begin] | +| test.cpp:180:19:180:28 | call to mk_array_p indirection [end] | semmle.label | call to mk_array_p indirection [end] | +| test.cpp:188:15:188:20 | call to malloc | semmle.label | call to malloc | +| test.cpp:189:15:189:15 | p | semmle.label | p | +| test.cpp:194:23:194:28 | call to malloc | semmle.label | call to malloc | +| test.cpp:195:17:195:17 | p | semmle.label | p | +| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:197:8:197:8 | p | semmle.label | p | +| test.cpp:197:20:197:22 | end | semmle.label | end | +| test.cpp:201:5:201:5 | p | semmle.label | p | +| test.cpp:201:5:201:12 | access to array | semmle.label | access to array | +| test.cpp:201:5:201:19 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:205:23:205:28 | call to malloc | semmle.label | call to malloc | +| test.cpp:206:17:206:17 | p | semmle.label | p | +| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:208:15:208:15 | p | semmle.label | p | +| test.cpp:209:12:209:14 | end | semmle.label | end | +| test.cpp:213:5:213:6 | * ... | semmle.label | * ... | +| test.cpp:213:5:213:13 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:213:6:213:6 | q | semmle.label | q | +| test.cpp:213:6:213:6 | q | semmle.label | q | +| test.cpp:221:17:221:22 | call to malloc | semmle.label | call to malloc | +| test.cpp:222:5:222:5 | p | semmle.label | p | +| test.cpp:231:18:231:30 | new[] | semmle.label | new[] | +| test.cpp:232:3:232:9 | newname | semmle.label | newname | +| test.cpp:232:3:232:16 | access to array | semmle.label | access to array | +| test.cpp:232:3:232:20 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:238:20:238:32 | new[] | semmle.label | new[] | +| test.cpp:239:5:239:11 | newname | semmle.label | newname | +| test.cpp:239:5:239:18 | access to array | semmle.label | access to array | +| test.cpp:239:5:239:22 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:248:24:248:30 | call to realloc | semmle.label | call to realloc | +| test.cpp:249:9:249:9 | p | semmle.label | p | +| test.cpp:250:22:250:22 | p | semmle.label | p | +| test.cpp:254:9:254:9 | p | semmle.label | p | +| test.cpp:254:9:254:12 | access to array | semmle.label | access to array | +| test.cpp:254:9:254:16 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:260:13:260:24 | new[] | semmle.label | new[] | +| test.cpp:261:14:261:15 | xs | semmle.label | xs | +| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... | +| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... | +| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... | +| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... | +| test.cpp:262:26:262:28 | end | semmle.label | end | +| test.cpp:262:26:262:28 | end | semmle.label | end | +| test.cpp:262:31:262:31 | x | semmle.label | x | +| test.cpp:264:13:264:14 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:264:14:264:14 | x | semmle.label | x | +| test.cpp:264:14:264:14 | x | semmle.label | x | +| test.cpp:270:13:270:24 | new[] | semmle.label | new[] | +| test.cpp:271:14:271:15 | xs | semmle.label | xs | +| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... | +| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... | +| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... | +| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... | +| test.cpp:272:26:272:28 | end | semmle.label | end | +| test.cpp:272:26:272:28 | end | semmle.label | end | +| test.cpp:272:31:272:31 | x | semmle.label | x | +| test.cpp:272:31:272:31 | x | semmle.label | x | +| test.cpp:274:5:274:6 | * ... | semmle.label | * ... | +| test.cpp:274:5:274:10 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:274:6:274:6 | x | semmle.label | x | +| test.cpp:274:6:274:6 | x | semmle.label | x | +| test.cpp:280:13:280:24 | new[] | semmle.label | new[] | +| test.cpp:281:14:281:15 | xs | semmle.label | xs | +| test.cpp:290:13:290:24 | new[] | semmle.label | new[] | +| test.cpp:291:14:291:15 | xs | semmle.label | xs | +| test.cpp:292:30:292:30 | x | semmle.label | x | +| test.cpp:304:15:304:26 | new[] | semmle.label | new[] | +| test.cpp:307:5:307:6 | xs | semmle.label | xs | +| test.cpp:308:5:308:6 | xs | semmle.label | xs | +| test.cpp:308:5:308:11 | access to array | semmle.label | access to array | +| test.cpp:308:5:308:29 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:313:14:313:27 | new[] | semmle.label | new[] | +| test.cpp:314:15:314:16 | xs | semmle.label | xs | +| test.cpp:325:14:325:27 | new[] | semmle.label | new[] | +| test.cpp:326:15:326:16 | xs | semmle.label | xs | +| test.cpp:326:15:326:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:326:15:326:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:333:5:333:21 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:338:8:338:15 | * ... | semmle.label | * ... | +| test.cpp:341:5:341:21 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:341:8:341:17 | * ... | semmle.label | * ... | +| test.cpp:342:8:342:17 | * ... | semmle.label | * ... | +| test.cpp:347:14:347:27 | new[] | semmle.label | new[] | +| test.cpp:348:15:348:16 | xs | semmle.label | xs | +| test.cpp:350:15:350:19 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ | +| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ | +| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ | +| test.cpp:355:14:355:27 | new[] | semmle.label | new[] | +| test.cpp:356:15:356:16 | xs | semmle.label | xs | +| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:357:24:357:26 | end | semmle.label | end | +| test.cpp:357:24:357:30 | ... + ... | semmle.label | ... + ... | +| test.cpp:357:24:357:30 | ... + ... | semmle.label | ... + ... | +| test.cpp:357:24:357:30 | ... + ... | semmle.label | ... + ... | +| test.cpp:357:24:357:30 | ... + ... | semmle.label | ... + ... | +| test.cpp:358:14:358:26 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:358:15:358:26 | end_plus_one | semmle.label | end_plus_one | +| test.cpp:358:15:358:26 | end_plus_one | semmle.label | end_plus_one | +| test.cpp:359:14:359:32 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:359:16:359:27 | end_plus_one | semmle.label | end_plus_one | +| test.cpp:359:16:359:31 | ... + ... | semmle.label | ... + ... | subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | From 75f6355bd6950cff005897612d6b9ff518d0ba6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 May 2023 04:06:22 +0000 Subject: [PATCH 194/739] Bump chrono from 0.4.25 to 0.4.26 in /ql Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.25 to 0.4.26. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.25...v0.4.26) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> --- ql/Cargo.lock | Bin 31667 -> 31667 bytes ql/buramu/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/Cargo.lock b/ql/Cargo.lock index 76437a85e057d43e2bf6bd6efa08833e2d6e19f3..de833d37b96bcb4b4ef42188f3f137daa116c0b8 100644 GIT binary patch delta 84 zcmdn|opJMb#tpx@Co4My*rq017@H@W8ycIMCK*|znVFiJr6i@8npq|pn<p8k8Jig! oSQ;i9B&C=n8Ks&Vo0^%Mm>L--nIxO0rC3fDl$Y4NfJZnV0Gh5DegFUf delta 87 zcmWN<u?>JQ3<N+?P>~T>0g1>VhK><n1i$UH48st#NEwcT22NL>rasO6c4ut2wHTDx o{<8Q4^*J&Xk`%$w78KIV$=m@^7q!u00&~t@Fw(gXeZ4|BK3NPMyZ`_I diff --git a/ql/buramu/Cargo.toml b/ql/buramu/Cargo.toml index a84be37dbd7..13aaddaf989 100644 --- a/ql/buramu/Cargo.toml +++ b/ql/buramu/Cargo.toml @@ -7,6 +7,6 @@ edition = "2018" [dependencies] lazy_static = "1.4.0" -chrono = "0.4.25" +chrono = "0.4.26" rayon = "1.7.0" regex = "1.8.3" From b343dcaadd01e19b610269b2bbbb1e709e509f57 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 31 May 2023 08:06:04 +0200 Subject: [PATCH 195/739] put string/object in the alert-message for sql-injection --- .../ql/src/Security/CWE-089/SqlInjection.ql | 9 +- .../ql/src/Security/CWE-089/SqlInjection.ql | 12 +- .../CWE-089/typed/SqlInjection.expected | 6 +- .../CWE-089/untyped/SqlInjection.expected | 250 +++++++++--------- 4 files changed, 139 insertions(+), 138 deletions(-) diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.ql b/javascript/ql/src/Security/CWE-089/SqlInjection.ql index 6b0502f611f..f7a40bb91f9 100644 --- a/javascript/ql/src/Security/CWE-089/SqlInjection.ql +++ b/javascript/ql/src/Security/CWE-089/SqlInjection.ql @@ -18,12 +18,13 @@ import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection import DataFlow::PathGraph -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string type where ( - cfg instanceof SqlInjection::Configuration or - cfg instanceof NosqlInjection::Configuration + cfg instanceof SqlInjection::Configuration and type = "string" + or + cfg instanceof NosqlInjection::Configuration and type = "object" ) and cfg.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "This query depends on a $@.", source.getNode(), +select sink.getNode(), source, sink, "This query " + type + " depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-089/SqlInjection.ql b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-089/SqlInjection.ql index a2c4a4158bc..e82b9d40d5b 100644 --- a/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-089/SqlInjection.ql +++ b/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-089/SqlInjection.ql @@ -20,13 +20,13 @@ import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection import DataFlow::PathGraph import semmle.javascript.heuristics.AdditionalSources -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, string type where ( - cfg instanceof SqlInjection::Configuration or - cfg instanceof NosqlInjection::Configuration + cfg instanceof SqlInjection::Configuration and type = "string" + or + cfg instanceof NosqlInjection::Configuration and type = "object" ) and - cfg.hasFlowPath(source, sink) and - source.getNode() instanceof HeuristicSource -select sink.getNode(), source, sink, "This query depends on a $@.", source.getNode(), + cfg.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "This query " + type + " depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected index f6a8d8862f6..acf7e712ee2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected @@ -37,6 +37,6 @@ edges | typedClient.ts:23:33:23:33 | v | typedClient.ts:23:27:23:35 | { id: v } | | typedClient.ts:23:33:23:33 | v | typedClient.ts:23:27:23:35 | { id: v } | #select -| typedClient.ts:14:24:14:32 | { id: v } | typedClient.ts:13:22:13:29 | req.body | typedClient.ts:14:24:14:32 | { id: v } | This query depends on a $@. | typedClient.ts:13:22:13:29 | req.body | user-provided value | -| typedClient.ts:22:27:22:35 | { id: v } | typedClient.ts:21:22:21:29 | req.body | typedClient.ts:22:27:22:35 | { id: v } | This query depends on a $@. | typedClient.ts:21:22:21:29 | req.body | user-provided value | -| typedClient.ts:23:27:23:35 | { id: v } | typedClient.ts:21:22:21:29 | req.body | typedClient.ts:23:27:23:35 | { id: v } | This query depends on a $@. | typedClient.ts:21:22:21:29 | req.body | user-provided value | +| typedClient.ts:14:24:14:32 | { id: v } | typedClient.ts:13:22:13:29 | req.body | typedClient.ts:14:24:14:32 | { id: v } | This query object depends on a $@. | typedClient.ts:13:22:13:29 | req.body | user-provided value | +| typedClient.ts:22:27:22:35 | { id: v } | typedClient.ts:21:22:21:29 | req.body | typedClient.ts:22:27:22:35 | { id: v } | This query object depends on a $@. | typedClient.ts:21:22:21:29 | req.body | user-provided value | +| typedClient.ts:23:27:23:35 | { id: v } | typedClient.ts:21:22:21:29 | req.body | typedClient.ts:23:27:23:35 | { id: v } | This query object depends on a $@. | typedClient.ts:21:22:21:29 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index be40ab490ad..6eba7711032 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -928,128 +928,128 @@ edges | tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | | tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | #select -| graphql.js:10:34:20:5 | `\\n ... }\\n ` | graphql.js:8:16:8:28 | req.params.id | graphql.js:10:34:20:5 | `\\n ... }\\n ` | This query depends on a $@. | graphql.js:8:16:8:28 | req.params.id | user-provided value | -| graphql.js:27:30:27:40 | `foo ${id}` | graphql.js:26:16:26:28 | req.params.id | graphql.js:27:30:27:40 | `foo ${id}` | This query depends on a $@. | graphql.js:26:16:26:28 | req.params.id | user-provided value | -| graphql.js:30:32:30:42 | `foo ${id}` | graphql.js:26:16:26:28 | req.params.id | graphql.js:30:32:30:42 | `foo ${id}` | This query depends on a $@. | graphql.js:26:16:26:28 | req.params.id | user-provided value | -| graphql.js:33:18:33:28 | `foo ${id}` | graphql.js:26:16:26:28 | req.params.id | graphql.js:33:18:33:28 | `foo ${id}` | This query depends on a $@. | graphql.js:26:16:26:28 | req.params.id | user-provided value | -| graphql.js:44:14:44:24 | `foo ${id}` | graphql.js:39:16:39:28 | req.params.id | graphql.js:44:14:44:24 | `foo ${id}` | This query depends on a $@. | graphql.js:39:16:39:28 | req.params.id | user-provided value | -| graphql.js:48:44:48:54 | `foo ${id}` | graphql.js:39:16:39:28 | req.params.id | graphql.js:48:44:48:54 | `foo ${id}` | This query depends on a $@. | graphql.js:39:16:39:28 | req.params.id | user-provided value | -| graphql.js:56:39:56:49 | `foo ${id}` | graphql.js:55:16:55:28 | req.params.id | graphql.js:56:39:56:49 | `foo ${id}` | This query depends on a $@. | graphql.js:55:16:55:28 | req.params.id | user-provided value | -| graphql.js:58:66:58:76 | `foo ${id}` | graphql.js:55:16:55:28 | req.params.id | graphql.js:58:66:58:76 | `foo ${id}` | This query depends on a $@. | graphql.js:55:16:55:28 | req.params.id | user-provided value | -| graphql.js:75:46:75:64 | "{ foo" + id + " }" | graphql.js:74:14:74:25 | req.query.id | graphql.js:75:46:75:64 | "{ foo" + id + " }" | This query depends on a $@. | graphql.js:74:14:74:25 | req.query.id | user-provided value | -| graphql.js:84:14:90:8 | `{\\n ... }` | graphql.js:74:14:74:25 | req.query.id | graphql.js:84:14:90:8 | `{\\n ... }` | This query depends on a $@. | graphql.js:74:14:74:25 | req.query.id | user-provided value | -| graphql.js:120:38:120:48 | `foo ${id}` | graphql.js:119:16:119:28 | req.params.id | graphql.js:120:38:120:48 | `foo ${id}` | This query depends on a $@. | graphql.js:119:16:119:28 | req.params.id | user-provided value | -| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | This query depends on a $@. | html-sanitizer.js:13:39:13:44 | param1 | user-provided value | -| json-schema-validator.js:33:22:33:26 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:33:22:33:26 | query | This query depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value | -| json-schema-validator.js:35:18:35:22 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:35:18:35:22 | query | This query depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value | -| json-schema-validator.js:55:22:55:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:55:22:55:26 | query | This query depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | -| json-schema-validator.js:59:22:59:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:59:22:59:26 | query | This query depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | -| json-schema-validator.js:61:22:61:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:61:22:61:26 | query | This query depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | -| ldap.js:28:30:28:34 | opts1 | ldap.js:20:21:20:27 | req.url | ldap.js:28:30:28:34 | opts1 | This query depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | -| ldap.js:32:5:32:61 | { filte ... e}))` } | ldap.js:20:21:20:27 | req.url | ldap.js:32:5:32:61 | { filte ... e}))` } | This query depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | -| ldap.js:66:30:66:53 | { filte ... ilter } | ldap.js:20:21:20:27 | req.url | ldap.js:66:30:66:53 | { filte ... ilter } | This query depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | -| ldap.js:68:27:68:42 | `cn=${username}` | ldap.js:20:21:20:27 | req.url | ldap.js:68:27:68:42 | `cn=${username}` | This query depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | -| marsdb-flow-to.js:14:17:14:21 | query | marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:14:17:14:21 | query | This query depends on a $@. | marsdb-flow-to.js:11:17:11:24 | req.body | user-provided value | -| marsdb.js:16:12:16:16 | query | marsdb.js:13:17:13:24 | req.body | marsdb.js:16:12:16:16 | query | This query depends on a $@. | marsdb.js:13:17:13:24 | req.body | user-provided value | -| minimongo.js:18:12:18:16 | query | minimongo.js:15:17:15:24 | req.body | minimongo.js:18:12:18:16 | query | This query depends on a $@. | minimongo.js:15:17:15:24 | req.body | user-provided value | -| mongodb.js:18:16:18:20 | query | mongodb.js:13:19:13:26 | req.body | mongodb.js:18:16:18:20 | query | This query depends on a $@. | mongodb.js:13:19:13:26 | req.body | user-provided value | -| mongodb.js:32:18:32:45 | { title ... itle) } | mongodb.js:26:19:26:26 | req.body | mongodb.js:32:18:32:45 | { title ... itle) } | This query depends on a $@. | mongodb.js:26:19:26:26 | req.body | user-provided value | -| mongodb.js:54:16:54:20 | query | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | This query depends on a $@. | mongodb.js:49:19:49:33 | req.query.title | user-provided value | -| mongodb.js:65:12:65:16 | query | mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | This query depends on a $@. | mongodb.js:60:16:60:30 | req.query.title | user-provided value | -| mongodb.js:77:14:77:26 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:77:14:77:26 | { tags: tag } | This query depends on a $@. | mongodb.js:70:13:70:25 | req.query.tag | user-provided value | -| mongodb.js:85:12:85:24 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:85:12:85:24 | { tags: tag } | This query depends on a $@. | mongodb.js:70:13:70:25 | req.query.tag | user-provided value | -| mongodb.js:112:14:112:18 | query | mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | This query depends on a $@. | mongodb.js:107:17:107:29 | queries.title | user-provided value | -| mongodb_bodySafe.js:29:16:29:20 | query | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | This query depends on a $@. | mongodb_bodySafe.js:24:19:24:33 | req.query.title | user-provided value | -| mongoose.js:24:24:24:30 | [query] | mongoose.js:21:19:21:26 | req.body | mongoose.js:24:24:24:30 | [query] | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:27:20:27:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:27:20:27:24 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:30:25:30:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:30:25:30:29 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:33:24:33:28 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:33:24:33:28 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:36:31:36:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:36:31:36:35 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:39:19:39:23 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:39:19:39:23 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:42:22:42:26 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:42:22:42:26 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:45:31:45:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:45:31:45:35 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:48:31:48:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:48:31:48:35 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:51:31:51:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:51:31:51:35 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:54:25:54:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:54:25:54:29 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:57:21:57:25 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:57:21:57:25 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:60:25:60:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:60:25:60:29 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:63:21:63:25 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:63:21:63:25 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:65:32:65:36 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:65:32:65:36 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:67:27:67:31 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:67:27:67:31 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:68:8:68:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:68:8:68:12 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:71:20:71:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:71:20:71:24 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:72:16:72:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:72:16:72:20 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:73:8:73:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:73:8:73:12 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:74:7:74:11 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:74:7:74:11 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:75:16:75:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:75:16:75:20 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:77:10:77:14 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:77:10:77:14 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:82:46:82:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:82:46:82:50 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:83:47:83:51 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:83:47:83:51 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:85:46:85:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:85:46:85:50 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:87:51:87:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:87:51:87:55 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:89:46:89:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:89:46:89:50 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:92:46:92:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:92:46:92:50 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:94:51:94:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:94:51:94:55 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:96:46:96:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:96:46:96:50 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:111:14:111:18 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:111:14:111:18 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:113:31:113:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:113:31:113:35 | query | This query depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:116:22:116:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:116:22:116:25 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:117:21:117:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:117:21:117:24 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:118:21:118:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:118:21:118:24 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:119:18:119:21 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:119:18:119:21 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:120:22:120:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:120:22:120:25 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:121:16:121:19 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:121:16:121:19 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:122:19:122:22 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:122:19:122:22 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:123:20:123:21 | id | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:123:20:123:21 | id | This query depends on a $@. | mongoose.js:115:11:115:22 | req.query.id | user-provided value | -| mongoose.js:124:28:124:31 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:124:28:124:31 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:125:28:125:31 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:125:28:125:31 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:126:28:126:31 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:126:28:126:31 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:127:18:127:21 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:127:18:127:21 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:128:22:128:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:128:22:128:25 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:129:21:129:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:129:21:129:24 | cond | This query depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | -| mongoose.js:130:16:130:26 | { _id: id } | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:130:16:130:26 | { _id: id } | This query depends on a $@. | mongoose.js:115:11:115:22 | req.query.id | user-provided value | -| mongooseJsonParse.js:23:19:23:23 | query | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:23:19:23:23 | query | This query depends on a $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | user-provided value | -| mongooseModelClient.js:11:16:11:24 | { id: v } | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:11:16:11:24 | { id: v } | This query depends on a $@. | mongooseModelClient.js:10:22:10:29 | req.body | user-provided value | -| mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | This query depends on a $@. | mongooseModelClient.js:12:22:12:29 | req.body | user-provided value | -| mysql.js:15:18:15:65 | 'SELECT ... + temp | mysql.js:6:16:6:31 | req.params.value | mysql.js:15:18:15:65 | 'SELECT ... + temp | This query depends on a $@. | mysql.js:6:16:6:31 | req.params.value | user-provided value | -| mysql.js:19:26:19:73 | 'SELECT ... + temp | mysql.js:6:16:6:31 | req.params.value | mysql.js:19:26:19:73 | 'SELECT ... + temp | This query depends on a $@. | mysql.js:6:16:6:31 | req.params.value | user-provided value | -| pg-promise-types.ts:8:17:8:21 | taint | pg-promise-types.ts:7:17:7:28 | req.params.x | pg-promise-types.ts:8:17:8:21 | taint | This query depends on a $@. | pg-promise-types.ts:7:17:7:28 | req.params.x | user-provided value | -| pg-promise.js:9:10:9:14 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:9:10:9:14 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:10:11:10:15 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:10:11:10:15 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:11:17:11:21 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:11:17:11:21 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:12:10:12:14 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:12:10:12:14 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:13:12:13:16 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:13:12:13:16 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:14:18:14:22 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:14:18:14:22 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:15:11:15:15 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:15:11:15:15 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:16:10:16:14 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:16:10:16:14 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:17:16:17:20 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:17:16:17:20 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:18:12:18:16 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:18:12:18:16 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:19:13:19:17 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:19:13:19:17 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:22:11:22:15 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:22:11:22:15 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:30:13:30:25 | req.params.id | pg-promise.js:30:13:30:25 | req.params.id | pg-promise.js:30:13:30:25 | req.params.id | This query depends on a $@. | pg-promise.js:30:13:30:25 | req.params.id | user-provided value | -| pg-promise.js:34:13:34:25 | req.params.id | pg-promise.js:34:13:34:25 | req.params.id | pg-promise.js:34:13:34:25 | req.params.id | This query depends on a $@. | pg-promise.js:34:13:34:25 | req.params.id | user-provided value | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | This query depends on a $@. | pg-promise.js:39:7:39:19 | req.params.id | user-provided value | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | This query depends on a $@. | pg-promise.js:40:7:40:21 | req.params.name | user-provided value | -| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | This query depends on a $@. | pg-promise.js:41:7:41:20 | req.params.foo | user-provided value | -| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:39:7:39:19 | req.params.id | This query depends on a $@. | pg-promise.js:39:7:39:19 | req.params.id | user-provided value | -| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:40:7:40:21 | req.params.name | This query depends on a $@. | pg-promise.js:40:7:40:21 | req.params.name | user-provided value | -| pg-promise.js:47:11:47:23 | req.params.id | pg-promise.js:47:11:47:23 | req.params.id | pg-promise.js:47:11:47:23 | req.params.id | This query depends on a $@. | pg-promise.js:47:11:47:23 | req.params.id | user-provided value | -| pg-promise.js:54:11:54:23 | req.params.id | pg-promise.js:54:11:54:23 | req.params.id | pg-promise.js:54:11:54:23 | req.params.id | This query depends on a $@. | pg-promise.js:54:11:54:23 | req.params.id | user-provided value | -| pg-promise.js:56:14:56:29 | req.params.title | pg-promise.js:56:14:56:29 | req.params.title | pg-promise.js:56:14:56:29 | req.params.title | This query depends on a $@. | pg-promise.js:56:14:56:29 | req.params.title | user-provided value | -| pg-promise.js:60:20:60:24 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:60:20:60:24 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:63:23:63:27 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:63:23:63:27 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| pg-promise.js:64:16:64:20 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:64:16:64:20 | query | This query depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | -| redis.js:10:16:10:27 | req.body.key | redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | This query depends on a $@. | redis.js:10:16:10:23 | req.body | user-provided value | -| redis.js:18:16:18:18 | key | redis.js:12:15:12:22 | req.body | redis.js:18:16:18:18 | key | This query depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | -| redis.js:19:43:19:45 | key | redis.js:12:15:12:22 | req.body | redis.js:19:43:19:45 | key | This query depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | -| redis.js:25:14:25:16 | key | redis.js:12:15:12:22 | req.body | redis.js:25:14:25:16 | key | This query depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | -| redis.js:30:23:30:25 | key | redis.js:12:15:12:22 | req.body | redis.js:30:23:30:25 | key | This query depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | -| redis.js:32:28:32:30 | key | redis.js:12:15:12:22 | req.body | redis.js:32:28:32:30 | key | This query depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | -| redis.js:39:16:39:18 | key | redis.js:38:17:38:24 | req.body | redis.js:39:16:39:18 | key | This query depends on a $@. | redis.js:38:17:38:24 | req.body | user-provided value | -| redis.js:43:27:43:29 | key | redis.js:38:17:38:24 | req.body | redis.js:43:27:43:29 | key | This query depends on a $@. | redis.js:38:17:38:24 | req.body | user-provided value | -| redis.js:46:34:46:36 | key | redis.js:38:17:38:24 | req.body | redis.js:46:34:46:36 | key | This query depends on a $@. | redis.js:38:17:38:24 | req.body | user-provided value | -| socketio.js:11:12:11:53 | `INSERT ... andle}` | socketio.js:10:25:10:30 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | This query depends on a $@. | socketio.js:10:25:10:30 | handle | user-provided value | -| tst2.js:9:27:9:84 | "select ... d + "'" | tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | This query depends on a $@. | tst2.js:9:66:9:78 | req.params.id | user-provided value | -| tst3.js:9:14:9:19 | query1 | tst3.js:8:16:8:34 | req.params.category | tst3.js:9:14:9:19 | query1 | This query depends on a $@. | tst3.js:8:16:8:34 | req.params.category | user-provided value | -| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | This query depends on a $@. | tst4.js:8:46:8:60 | $routeParams.id | user-provided value | -| tst.js:10:10:10:64 | 'SELECT ... d + '"' | tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | This query depends on a $@. | tst.js:10:46:10:58 | req.params.id | user-provided value | +| graphql.js:10:34:20:5 | `\\n ... }\\n ` | graphql.js:8:16:8:28 | req.params.id | graphql.js:10:34:20:5 | `\\n ... }\\n ` | This query string depends on a $@. | graphql.js:8:16:8:28 | req.params.id | user-provided value | +| graphql.js:27:30:27:40 | `foo ${id}` | graphql.js:26:16:26:28 | req.params.id | graphql.js:27:30:27:40 | `foo ${id}` | This query string depends on a $@. | graphql.js:26:16:26:28 | req.params.id | user-provided value | +| graphql.js:30:32:30:42 | `foo ${id}` | graphql.js:26:16:26:28 | req.params.id | graphql.js:30:32:30:42 | `foo ${id}` | This query string depends on a $@. | graphql.js:26:16:26:28 | req.params.id | user-provided value | +| graphql.js:33:18:33:28 | `foo ${id}` | graphql.js:26:16:26:28 | req.params.id | graphql.js:33:18:33:28 | `foo ${id}` | This query string depends on a $@. | graphql.js:26:16:26:28 | req.params.id | user-provided value | +| graphql.js:44:14:44:24 | `foo ${id}` | graphql.js:39:16:39:28 | req.params.id | graphql.js:44:14:44:24 | `foo ${id}` | This query string depends on a $@. | graphql.js:39:16:39:28 | req.params.id | user-provided value | +| graphql.js:48:44:48:54 | `foo ${id}` | graphql.js:39:16:39:28 | req.params.id | graphql.js:48:44:48:54 | `foo ${id}` | This query string depends on a $@. | graphql.js:39:16:39:28 | req.params.id | user-provided value | +| graphql.js:56:39:56:49 | `foo ${id}` | graphql.js:55:16:55:28 | req.params.id | graphql.js:56:39:56:49 | `foo ${id}` | This query string depends on a $@. | graphql.js:55:16:55:28 | req.params.id | user-provided value | +| graphql.js:58:66:58:76 | `foo ${id}` | graphql.js:55:16:55:28 | req.params.id | graphql.js:58:66:58:76 | `foo ${id}` | This query string depends on a $@. | graphql.js:55:16:55:28 | req.params.id | user-provided value | +| graphql.js:75:46:75:64 | "{ foo" + id + " }" | graphql.js:74:14:74:25 | req.query.id | graphql.js:75:46:75:64 | "{ foo" + id + " }" | This query string depends on a $@. | graphql.js:74:14:74:25 | req.query.id | user-provided value | +| graphql.js:84:14:90:8 | `{\\n ... }` | graphql.js:74:14:74:25 | req.query.id | graphql.js:84:14:90:8 | `{\\n ... }` | This query string depends on a $@. | graphql.js:74:14:74:25 | req.query.id | user-provided value | +| graphql.js:120:38:120:48 | `foo ${id}` | graphql.js:119:16:119:28 | req.params.id | graphql.js:120:38:120:48 | `foo ${id}` | This query string depends on a $@. | graphql.js:119:16:119:28 | req.params.id | user-provided value | +| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | This query string depends on a $@. | html-sanitizer.js:13:39:13:44 | param1 | user-provided value | +| json-schema-validator.js:33:22:33:26 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:33:22:33:26 | query | This query object depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value | +| json-schema-validator.js:35:18:35:22 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:35:18:35:22 | query | This query object depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value | +| json-schema-validator.js:55:22:55:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:55:22:55:26 | query | This query object depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | +| json-schema-validator.js:59:22:59:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:59:22:59:26 | query | This query object depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | +| json-schema-validator.js:61:22:61:26 | query | json-schema-validator.js:50:34:50:47 | req.query.data | json-schema-validator.js:61:22:61:26 | query | This query object depends on a $@. | json-schema-validator.js:50:34:50:47 | req.query.data | user-provided value | +| ldap.js:28:30:28:34 | opts1 | ldap.js:20:21:20:27 | req.url | ldap.js:28:30:28:34 | opts1 | This query string depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | +| ldap.js:32:5:32:61 | { filte ... e}))` } | ldap.js:20:21:20:27 | req.url | ldap.js:32:5:32:61 | { filte ... e}))` } | This query string depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | +| ldap.js:66:30:66:53 | { filte ... ilter } | ldap.js:20:21:20:27 | req.url | ldap.js:66:30:66:53 | { filte ... ilter } | This query string depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | +| ldap.js:68:27:68:42 | `cn=${username}` | ldap.js:20:21:20:27 | req.url | ldap.js:68:27:68:42 | `cn=${username}` | This query string depends on a $@. | ldap.js:20:21:20:27 | req.url | user-provided value | +| marsdb-flow-to.js:14:17:14:21 | query | marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:14:17:14:21 | query | This query object depends on a $@. | marsdb-flow-to.js:11:17:11:24 | req.body | user-provided value | +| marsdb.js:16:12:16:16 | query | marsdb.js:13:17:13:24 | req.body | marsdb.js:16:12:16:16 | query | This query object depends on a $@. | marsdb.js:13:17:13:24 | req.body | user-provided value | +| minimongo.js:18:12:18:16 | query | minimongo.js:15:17:15:24 | req.body | minimongo.js:18:12:18:16 | query | This query object depends on a $@. | minimongo.js:15:17:15:24 | req.body | user-provided value | +| mongodb.js:18:16:18:20 | query | mongodb.js:13:19:13:26 | req.body | mongodb.js:18:16:18:20 | query | This query object depends on a $@. | mongodb.js:13:19:13:26 | req.body | user-provided value | +| mongodb.js:32:18:32:45 | { title ... itle) } | mongodb.js:26:19:26:26 | req.body | mongodb.js:32:18:32:45 | { title ... itle) } | This query object depends on a $@. | mongodb.js:26:19:26:26 | req.body | user-provided value | +| mongodb.js:54:16:54:20 | query | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | This query object depends on a $@. | mongodb.js:49:19:49:33 | req.query.title | user-provided value | +| mongodb.js:65:12:65:16 | query | mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | This query object depends on a $@. | mongodb.js:60:16:60:30 | req.query.title | user-provided value | +| mongodb.js:77:14:77:26 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:77:14:77:26 | { tags: tag } | This query object depends on a $@. | mongodb.js:70:13:70:25 | req.query.tag | user-provided value | +| mongodb.js:85:12:85:24 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:85:12:85:24 | { tags: tag } | This query object depends on a $@. | mongodb.js:70:13:70:25 | req.query.tag | user-provided value | +| mongodb.js:112:14:112:18 | query | mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | This query object depends on a $@. | mongodb.js:107:17:107:29 | queries.title | user-provided value | +| mongodb_bodySafe.js:29:16:29:20 | query | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | This query object depends on a $@. | mongodb_bodySafe.js:24:19:24:33 | req.query.title | user-provided value | +| mongoose.js:24:24:24:30 | [query] | mongoose.js:21:19:21:26 | req.body | mongoose.js:24:24:24:30 | [query] | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:27:20:27:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:27:20:27:24 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:30:25:30:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:30:25:30:29 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:33:24:33:28 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:33:24:33:28 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:36:31:36:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:36:31:36:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:39:19:39:23 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:39:19:39:23 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:42:22:42:26 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:42:22:42:26 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:45:31:45:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:45:31:45:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:48:31:48:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:48:31:48:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:51:31:51:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:51:31:51:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:54:25:54:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:54:25:54:29 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:57:21:57:25 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:57:21:57:25 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:60:25:60:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:60:25:60:29 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:63:21:63:25 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:63:21:63:25 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:65:32:65:36 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:65:32:65:36 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:67:27:67:31 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:67:27:67:31 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:68:8:68:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:68:8:68:12 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:71:20:71:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:71:20:71:24 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:72:16:72:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:72:16:72:20 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:73:8:73:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:73:8:73:12 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:74:7:74:11 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:74:7:74:11 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:75:16:75:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:75:16:75:20 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:77:10:77:14 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:77:10:77:14 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:82:46:82:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:82:46:82:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:83:47:83:51 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:83:47:83:51 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:85:46:85:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:85:46:85:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:87:51:87:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:87:51:87:55 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:89:46:89:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:89:46:89:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:92:46:92:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:92:46:92:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:94:51:94:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:94:51:94:55 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:96:46:96:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:96:46:96:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:111:14:111:18 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:111:14:111:18 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:113:31:113:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:113:31:113:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:116:22:116:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:116:22:116:25 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:117:21:117:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:117:21:117:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:118:21:118:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:118:21:118:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:119:18:119:21 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:119:18:119:21 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:120:22:120:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:120:22:120:25 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:121:16:121:19 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:121:16:121:19 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:122:19:122:22 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:122:19:122:22 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:123:20:123:21 | id | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:123:20:123:21 | id | This query object depends on a $@. | mongoose.js:115:11:115:22 | req.query.id | user-provided value | +| mongoose.js:124:28:124:31 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:124:28:124:31 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:125:28:125:31 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:125:28:125:31 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:126:28:126:31 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:126:28:126:31 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:127:18:127:21 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:127:18:127:21 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:128:22:128:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:128:22:128:25 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:129:21:129:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:129:21:129:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | +| mongoose.js:130:16:130:26 | { _id: id } | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:130:16:130:26 | { _id: id } | This query object depends on a $@. | mongoose.js:115:11:115:22 | req.query.id | user-provided value | +| mongooseJsonParse.js:23:19:23:23 | query | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:23:19:23:23 | query | This query object depends on a $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | user-provided value | +| mongooseModelClient.js:11:16:11:24 | { id: v } | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:11:16:11:24 | { id: v } | This query object depends on a $@. | mongooseModelClient.js:10:22:10:29 | req.body | user-provided value | +| mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | This query object depends on a $@. | mongooseModelClient.js:12:22:12:29 | req.body | user-provided value | +| mysql.js:15:18:15:65 | 'SELECT ... + temp | mysql.js:6:16:6:31 | req.params.value | mysql.js:15:18:15:65 | 'SELECT ... + temp | This query string depends on a $@. | mysql.js:6:16:6:31 | req.params.value | user-provided value | +| mysql.js:19:26:19:73 | 'SELECT ... + temp | mysql.js:6:16:6:31 | req.params.value | mysql.js:19:26:19:73 | 'SELECT ... + temp | This query string depends on a $@. | mysql.js:6:16:6:31 | req.params.value | user-provided value | +| pg-promise-types.ts:8:17:8:21 | taint | pg-promise-types.ts:7:17:7:28 | req.params.x | pg-promise-types.ts:8:17:8:21 | taint | This query string depends on a $@. | pg-promise-types.ts:7:17:7:28 | req.params.x | user-provided value | +| pg-promise.js:9:10:9:14 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:9:10:9:14 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:10:11:10:15 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:10:11:10:15 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:11:17:11:21 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:11:17:11:21 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:12:10:12:14 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:12:10:12:14 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:13:12:13:16 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:13:12:13:16 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:14:18:14:22 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:14:18:14:22 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:15:11:15:15 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:15:11:15:15 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:16:10:16:14 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:16:10:16:14 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:17:16:17:20 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:17:16:17:20 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:18:12:18:16 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:18:12:18:16 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:19:13:19:17 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:19:13:19:17 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:22:11:22:15 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:22:11:22:15 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:30:13:30:25 | req.params.id | pg-promise.js:30:13:30:25 | req.params.id | pg-promise.js:30:13:30:25 | req.params.id | This query string depends on a $@. | pg-promise.js:30:13:30:25 | req.params.id | user-provided value | +| pg-promise.js:34:13:34:25 | req.params.id | pg-promise.js:34:13:34:25 | req.params.id | pg-promise.js:34:13:34:25 | req.params.id | This query string depends on a $@. | pg-promise.js:34:13:34:25 | req.params.id | user-provided value | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | This query string depends on a $@. | pg-promise.js:39:7:39:19 | req.params.id | user-provided value | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | This query string depends on a $@. | pg-promise.js:40:7:40:21 | req.params.name | user-provided value | +| pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | pg-promise.js:41:7:41:20 | req.params.foo | pg-promise.js:38:13:42:5 | [\\n ... n\\n ] | This query string depends on a $@. | pg-promise.js:41:7:41:20 | req.params.foo | user-provided value | +| pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:39:7:39:19 | req.params.id | pg-promise.js:39:7:39:19 | req.params.id | This query string depends on a $@. | pg-promise.js:39:7:39:19 | req.params.id | user-provided value | +| pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:40:7:40:21 | req.params.name | pg-promise.js:40:7:40:21 | req.params.name | This query string depends on a $@. | pg-promise.js:40:7:40:21 | req.params.name | user-provided value | +| pg-promise.js:47:11:47:23 | req.params.id | pg-promise.js:47:11:47:23 | req.params.id | pg-promise.js:47:11:47:23 | req.params.id | This query string depends on a $@. | pg-promise.js:47:11:47:23 | req.params.id | user-provided value | +| pg-promise.js:54:11:54:23 | req.params.id | pg-promise.js:54:11:54:23 | req.params.id | pg-promise.js:54:11:54:23 | req.params.id | This query string depends on a $@. | pg-promise.js:54:11:54:23 | req.params.id | user-provided value | +| pg-promise.js:56:14:56:29 | req.params.title | pg-promise.js:56:14:56:29 | req.params.title | pg-promise.js:56:14:56:29 | req.params.title | This query string depends on a $@. | pg-promise.js:56:14:56:29 | req.params.title | user-provided value | +| pg-promise.js:60:20:60:24 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:60:20:60:24 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:63:23:63:27 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:63:23:63:27 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| pg-promise.js:64:16:64:20 | query | pg-promise.js:7:16:7:34 | req.params.category | pg-promise.js:64:16:64:20 | query | This query string depends on a $@. | pg-promise.js:7:16:7:34 | req.params.category | user-provided value | +| redis.js:10:16:10:27 | req.body.key | redis.js:10:16:10:23 | req.body | redis.js:10:16:10:27 | req.body.key | This query object depends on a $@. | redis.js:10:16:10:23 | req.body | user-provided value | +| redis.js:18:16:18:18 | key | redis.js:12:15:12:22 | req.body | redis.js:18:16:18:18 | key | This query object depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | +| redis.js:19:43:19:45 | key | redis.js:12:15:12:22 | req.body | redis.js:19:43:19:45 | key | This query object depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | +| redis.js:25:14:25:16 | key | redis.js:12:15:12:22 | req.body | redis.js:25:14:25:16 | key | This query object depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | +| redis.js:30:23:30:25 | key | redis.js:12:15:12:22 | req.body | redis.js:30:23:30:25 | key | This query object depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | +| redis.js:32:28:32:30 | key | redis.js:12:15:12:22 | req.body | redis.js:32:28:32:30 | key | This query object depends on a $@. | redis.js:12:15:12:22 | req.body | user-provided value | +| redis.js:39:16:39:18 | key | redis.js:38:17:38:24 | req.body | redis.js:39:16:39:18 | key | This query object depends on a $@. | redis.js:38:17:38:24 | req.body | user-provided value | +| redis.js:43:27:43:29 | key | redis.js:38:17:38:24 | req.body | redis.js:43:27:43:29 | key | This query object depends on a $@. | redis.js:38:17:38:24 | req.body | user-provided value | +| redis.js:46:34:46:36 | key | redis.js:38:17:38:24 | req.body | redis.js:46:34:46:36 | key | This query object depends on a $@. | redis.js:38:17:38:24 | req.body | user-provided value | +| socketio.js:11:12:11:53 | `INSERT ... andle}` | socketio.js:10:25:10:30 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | This query string depends on a $@. | socketio.js:10:25:10:30 | handle | user-provided value | +| tst2.js:9:27:9:84 | "select ... d + "'" | tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | This query string depends on a $@. | tst2.js:9:66:9:78 | req.params.id | user-provided value | +| tst3.js:9:14:9:19 | query1 | tst3.js:8:16:8:34 | req.params.category | tst3.js:9:14:9:19 | query1 | This query string depends on a $@. | tst3.js:8:16:8:34 | req.params.category | user-provided value | +| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | This query string depends on a $@. | tst4.js:8:46:8:60 | $routeParams.id | user-provided value | +| tst.js:10:10:10:64 | 'SELECT ... d + '"' | tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | This query string depends on a $@. | tst.js:10:46:10:58 | req.params.id | user-provided value | From fe26aca238ad02cd26198bca998a68066e581d94 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 31 May 2023 08:54:24 +0200 Subject: [PATCH 196/739] Remove non-ASCII character --- .../code/java/frameworks/google/GsonSerializability.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index dba25be7b22..1e41ad0c458 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -27,8 +27,8 @@ private class ExplicitlyReadGsonDeserializableType extends GsonDeserializableTyp ma.getMethod() instanceof GsonReadValueMethod and // ...where `this` is used in the final argument, indicating that this type will be deserialized. // TODO: find a way to get the type represented by java.lang.reflect.Type and com.google.gson.reflect.TypeToken - // fromJson​(String json, TypeToken<T> typeOfT) - // fromJson​(String json, Type typeOfT) + // fromJson(String json, TypeToken<T> typeOfT) + // fromJson(String json, Type typeOfT) usesType(ma.getArgument(1).getType(), this) and not this instanceof TypeClass and not this instanceof TypeObject From e24b45b4233724e6756057f87c04593bed583c5f Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 31 May 2023 09:57:38 +0200 Subject: [PATCH 197/739] elaborate on both SQL and NoSQL injection in the js/sql-injection qhelp --- .../Security/CWE-089/SqlInjection.inc.qhelp | 48 ++++++++++++++----- .../CWE-089/examples/NoSqlInjection.js | 18 +++++++ .../CWE-089/examples/NoSqlInjectionFix.js | 21 ++++++++ .../Security/CWE-089/examples/SqlInjection.js | 7 --- .../CWE-089/examples/SqlInjectionFix.js | 12 +++++ 5 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 javascript/ql/src/Security/CWE-089/examples/NoSqlInjection.js create mode 100644 javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js create mode 100644 javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp index 8cdc2419d47..1d99428b718 100644 --- a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp +++ b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp @@ -20,7 +20,13 @@ or prepared statements. <p> For NoSQL queries, make use of an operator like MongoDB's <code>$eq</code> to ensure that untrusted data is interpreted as a literal value and not as -a query object. +a query object. Alternatively, check that the untrusted data is a literal +value and not a query object before using it in a query. +</p> +<p> +For SQL queries, use query parameters or prepared statements to +embed untrusted data into the query string, or use a library like +<code>sqlstring</code> to escape untrusted data. </p> </recommendation> @@ -32,31 +38,47 @@ an HTTP request handler in a web application, whose parameter </p> <p> -The handler constructs two copies of the same SQL query involving -user input taken from the request object, once unsafely using -string concatenation, and once safely using query parameters. +The handler constructs constructs an SQL query string from user input +and executes it as a database query using the <code>pg</code> library. +THe user input may contain quote characters, so this code is vulnerable +to a SQL injection attack. </p> -<p> -In the first case, the query string <code>query1</code> is built by -directly concatenating a user-supplied request parameter with some -string literals. The parameter may include quote characters, so this -code is vulnerable to a SQL injection attack. -</p> +<sample src="examples/SqlInjection.js" /> <p> -In the second case, the parameter is embedded into the query string -<code>query2</code> using query parameters. In this example, we use +To fix this vulnerability, we can use query parameters to embed the +user input into the query string. In this example, we use the API offered by the <code>pg</code> Postgres database connector library, but other libraries offer similar features. This version is immune to injection attacks. </p> -<sample src="examples/SqlInjection.js" /> +<sample src="examples/SqlInjectionFix.js" /> +</example> + +<example> +<p> +In the following example an express handler attempts to delete +a single document from a MongoDB collection. The document to be +deleted is identified by its <code>_id</code> field, which is +constructed from user input. The user input may contain a query +object, so this code is vulnerable to a NoSQL injection attack. +</p> + +<sample src="examples/NoSqlInjection.js" /> + +<p> +To fix this vulnerability, we can check that the user input is a +literal value and not a query object before using it in a query. +</p> + +<sample src="examples/NoSqlInjectionFix.js" /> </example> <references> <li>Wikipedia: <a href="https://en.wikipedia.org/wiki/SQL_injection">SQL injection</a>.</li> <li>MongoDB: <a href="https://docs.mongodb.com/manual/reference/operator/query/eq">$eq operator</a>.</li> +<li>OWASP: <a href="https://owasp.org/www-pdf-archive/GOD16-NOSQL.pdf">NoSQL injection</a>.</li> </references> </qhelp> diff --git a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjection.js b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjection.js new file mode 100644 index 00000000000..8af7550aee4 --- /dev/null +++ b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjection.js @@ -0,0 +1,18 @@ +const express = require("express"); +const mongoose = require("mongoose"); +const Todo = mongoose.model( + "Todo", + new mongoose.Schema({ text: { type: String } }, { timestamps: true }) +); + +const app = express(); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); + +app.delete("/api/delete", async (req, res) => { + let id = req.body.id; + + await Todo.deleteOne({ _id: id }); // BAD: id might be an object with special properties + + res.json({ status: "ok" }); +}); diff --git a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js new file mode 100644 index 00000000000..fe982168be1 --- /dev/null +++ b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js @@ -0,0 +1,21 @@ +const express = require("express"); +const mongoose = require("mongoose"); +const Todo = mongoose.model( + "Todo", + new mongoose.Schema({ text: { type: String } }, { timestamps: true }) +); + +const app = express(); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); + +app.delete("/api/delete", async (req, res) => { + let id = req.body.id; + if (typeof id !== "string") { + res.status(400).json({ status: "error" }); + return; + } + await Todo.deleteOne({ _id: id }); // GOOD: id is guaranteed to be a string + + res.json({ status: "ok" }); +}); diff --git a/javascript/ql/src/Security/CWE-089/examples/SqlInjection.js b/javascript/ql/src/Security/CWE-089/examples/SqlInjection.js index 113a034219c..9c9197e6f58 100644 --- a/javascript/ql/src/Security/CWE-089/examples/SqlInjection.js +++ b/javascript/ql/src/Security/CWE-089/examples/SqlInjection.js @@ -11,11 +11,4 @@ app.get("search", function handler(req, res) { pool.query(query1, [], function(err, results) { // process results }); - - // GOOD: use parameters - var query2 = - "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=$1" + " ORDER BY PRICE"; - pool.query(query2, [req.params.category], function(err, results) { - // process results - }); }); diff --git a/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js b/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js new file mode 100644 index 00000000000..4391b83e391 --- /dev/null +++ b/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js @@ -0,0 +1,12 @@ +const app = require("express")(), + pg = require("pg"), + pool = new pg.Pool(config); + +app.get("search", function handler(req, res) { + // GOOD: use parameters + var query2 = + "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=$1" + " ORDER BY PRICE"; + pool.query(query2, [req.params.category], function(err, results) { + // process results + }); +}); From 96bae2d5ecd65111bd98b1c029422bf8b2987835 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 31 May 2023 10:34:58 +0200 Subject: [PATCH 198/739] Java: avoid downcasting to DollarAtString --- ...utomodelApplicationModeCharacteristics.qll | 4 ++-- ...tomodelApplicationModeExtractCandidates.ql | 17 ++++++++------- ...lApplicationModeExtractNegativeExamples.ql | 16 +++++++------- ...lApplicationModeExtractPositiveExamples.ql | 17 ++++++++------- .../AutomodelFrameworkModeCharacteristics.qll | 4 ++-- ...AutomodelFrameworkModeExtractCandidates.ql | 19 +++++++++-------- ...delFrameworkModeExtractNegativeExamples.ql | 21 ++++++++++--------- ...delFrameworkModeExtractPositiveExamples.ql | 19 +++++++++-------- 8 files changed, 61 insertions(+), 56 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 4e753a4479d..882c957f3a5 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -171,7 +171,7 @@ class ApplicationModeMetadataExtractor extends string { } predicate hasMetadata( - Endpoint e, string package, string type, boolean subtypes, string name, string signature, + Endpoint e, string package, string type, string subtypes, string name, string signature, string input ) { exists(Call call, Callable callable, int argIdx | @@ -184,7 +184,7 @@ class ApplicationModeMetadataExtractor extends string { input = AutomodelSharedUtil::getArgumentForIndex(argIdx) and package = callable.getDeclaringType().getPackage().getName() and type = callable.getDeclaringType().getErasure().(RefType).nestedName() and - subtypes = this.considerSubtypes(callable) and + subtypes = this.considerSubtypes(callable).toString() and name = callable.getName() and signature = ExternalFlow::paramsString(callable) ) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql index 40e0e307300..589a10ae663 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql @@ -16,8 +16,9 @@ private import AutomodelApplicationModeCharacteristics private import AutomodelSharedUtil from - Endpoint endpoint, string message, ApplicationModeMetadataExtractor meta, string package, - string type, boolean subtypes, string name, string signature, string input + Endpoint endpoint, string message, ApplicationModeMetadataExtractor meta, DollarAtString package, + DollarAtString type, DollarAtString subtypes, DollarAtString name, DollarAtString signature, + DollarAtString input where not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | u.appliesToEndpoint(endpoint) @@ -40,9 +41,9 @@ where ) select endpoint, message + "\nrelated locations: $@." + "\nmetadata: $@, $@, $@, $@, $@, $@.", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // - package.(DollarAtString), "package", // - type.(DollarAtString), "type", // - subtypes.toString().(DollarAtString), "subtypes", // - name.(DollarAtString), "name", // method name - signature.(DollarAtString), "signature", // - input.(DollarAtString), "input" // + package, "package", // + type, "type", // + subtypes, "subtypes", // + name, "name", // method name + signature, "signature", // + input, "input" // diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index d817d3a244a..7407be0be57 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -35,8 +35,8 @@ Endpoint getSampleForCharacteristic(EndpointCharacteristic c, int limit) { from Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string message, - ApplicationModeMetadataExtractor meta, string package, string type, boolean subtypes, string name, - string signature, string input + ApplicationModeMetadataExtractor meta, DollarAtString package, DollarAtString type, + DollarAtString subtypes, DollarAtString name, DollarAtString signature, DollarAtString input where endpoint = getSampleForCharacteristic(characteristic, 100) and confidence >= SharedCharacteristics::highConfidence() and @@ -58,9 +58,9 @@ where message = characteristic select endpoint, message + "\nrelated locations: $@." + "\nmetadata: $@, $@, $@, $@, $@, $@.", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // - package.(DollarAtString), "package", // - type.(DollarAtString), "type", // - subtypes.toString().(DollarAtString), "subtypes", // - name.(DollarAtString), "name", // - signature.(DollarAtString), "signature", // - input.(DollarAtString), "input" // + package, "package", // + type, "type", // + subtypes, "subtypes", // + name, "name", // + signature, "signature", // + input, "input" // diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql index 0a70b376c82..49be5c1d45f 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql @@ -13,8 +13,9 @@ private import AutomodelEndpointTypes private import AutomodelSharedUtil from - Endpoint endpoint, SinkType sinkType, ApplicationModeMetadataExtractor meta, string package, - string type, boolean subtypes, string name, string signature, string input + Endpoint endpoint, SinkType sinkType, ApplicationModeMetadataExtractor meta, + DollarAtString package, DollarAtString type, DollarAtString subtypes, DollarAtString name, + DollarAtString signature, DollarAtString input where // Exclude endpoints that have contradictory endpoint characteristics, because we only want examples we're highly // certain about in the prompt. @@ -24,9 +25,9 @@ where CharacteristicsImpl::isKnownSink(endpoint, sinkType) select endpoint, sinkType + "\nrelated locations: $@." + "\nmetadata: $@, $@, $@, $@, $@, $@.", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", // - package.(DollarAtString), "package", // - type.(DollarAtString), "type", // - subtypes.toString().(DollarAtString), "subtypes", // - name.(DollarAtString), "name", // - signature.(DollarAtString), "signature", // - input.(DollarAtString), "input" // + package, "package", // + type, "type", // + subtypes, "subtypes", // + name, "name", // + signature, "signature", // + input, "input" // diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index 85e28436df3..1a94d1a6338 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -129,7 +129,7 @@ class FrameworkModeMetadataExtractor extends string { } predicate hasMetadata( - Endpoint e, string package, string type, boolean subtypes, string name, string signature, + Endpoint e, string package, string type, string subtypes, string name, string signature, string input, string parameterName ) { exists(Callable callable, int paramIdx | @@ -137,7 +137,7 @@ class FrameworkModeMetadataExtractor extends string { input = AutomodelSharedUtil::getArgumentForIndex(paramIdx) and package = callable.getDeclaringType().getPackage().getName() and type = callable.getDeclaringType().getErasure().(RefType).nestedName() and - subtypes = this.considerSubtypes(callable) and + subtypes = this.considerSubtypes(callable).toString() and name = callable.getName() and parameterName = e.asParameter().getName() and signature = ExternalFlow::paramsString(callable) diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql index 7f7f050fac4..391105b9d56 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql @@ -16,8 +16,9 @@ private import AutomodelFrameworkModeCharacteristics private import AutomodelSharedUtil from - Endpoint endpoint, string message, FrameworkModeMetadataExtractor meta, string package, - string type, boolean subtypes, string name, string signature, string input, string parameterName + Endpoint endpoint, string message, FrameworkModeMetadataExtractor meta, DollarAtString package, + DollarAtString type, DollarAtString subtypes, DollarAtString name, DollarAtString signature, + DollarAtString input, DollarAtString parameterName where not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u | u.appliesToEndpoint(endpoint) @@ -42,10 +43,10 @@ select endpoint, message + "\nrelated locations: $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@.", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package.(DollarAtString), "package", // - type.(DollarAtString), "type", // - subtypes.toString().(DollarAtString), "subtypes", // - name.(DollarAtString), "name", // - signature.(DollarAtString), "signature", // - input.(DollarAtString), "input", // - parameterName.(DollarAtString), "parameterName" // + package, "package", // + type, "type", // + subtypes, "subtypes", // + name, "name", // + signature, "signature", // + input, "input", // + parameterName, "parameterName" // diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql index 9036d638c2b..fb4bbc0e675 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql @@ -13,9 +13,10 @@ private import AutomodelEndpointTypes private import AutomodelSharedUtil from - Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, string message, - FrameworkModeMetadataExtractor meta, string package, string type, boolean subtypes, string name, - string signature, string input, string parameterName + Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, + DollarAtString message, FrameworkModeMetadataExtractor meta, DollarAtString package, + DollarAtString type, DollarAtString subtypes, DollarAtString name, DollarAtString signature, + DollarAtString input, DollarAtString parameterName where characteristic.appliesToEndpoint(endpoint) and confidence >= SharedCharacteristics::highConfidence() and @@ -39,10 +40,10 @@ select endpoint, message + "\nrelated locations: $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@.", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package.(DollarAtString), "package", // - type.(DollarAtString), "type", // - subtypes.toString().(DollarAtString), "subtypes", // - name.(DollarAtString), "name", // - signature.(DollarAtString), "signature", // - input.(DollarAtString), "input", // - parameterName.(DollarAtString), "parameterName" // + package, "package", // + type, "type", // + subtypes, "subtypes", // + name, "name", // + signature, "signature", // + input, "input", // + parameterName, "parameterName" // diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql index eeaf7037a15..41cca592380 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql @@ -13,8 +13,9 @@ private import AutomodelEndpointTypes private import AutomodelSharedUtil from - Endpoint endpoint, SinkType sinkType, FrameworkModeMetadataExtractor meta, string package, - string type, boolean subtypes, string name, string signature, string input, string parameterName + Endpoint endpoint, SinkType sinkType, FrameworkModeMetadataExtractor meta, DollarAtString package, + DollarAtString type, DollarAtString subtypes, DollarAtString name, DollarAtString signature, + DollarAtString input, DollarAtString parameterName where // Exclude endpoints that have contradictory endpoint characteristics, because we only want examples we're highly // certain about in the prompt. @@ -26,10 +27,10 @@ select endpoint, sinkType + "\nrelated locations: $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@.", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", // CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", // - package.(DollarAtString), "package", // - type.(DollarAtString), "type", // - subtypes.toString().(DollarAtString), "subtypes", // - name.(DollarAtString), "name", // - signature.(DollarAtString), "signature", // - input.(DollarAtString), "input", // - parameterName.(DollarAtString), "parameterName" // + package, "package", // + type, "type", // + subtypes, "subtypes", // + name, "name", // + signature, "signature", // + input, "input", // + parameterName, "parameterName" // From 86559317d70eb3222a693457cd5e82acbb916995 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 31 May 2023 10:57:03 +0200 Subject: [PATCH 199/739] Java: update comments --- .../AutomodelApplicationModeCharacteristics.qll | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 882c957f3a5..2773e1f2cfc 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -32,9 +32,8 @@ private class ArgumentNode extends DataFlow::Node { * A candidates implementation. * * Some important notes: - * - This mode is using parameters as endpoints. - * - Sink- and neutral-information is being used from MaD models. - * - When available, we use method- and class-java-docs as related locations. + * - This mode is using arguments as endpoints. + * - We use the `CallContext` (the surrounding call expression) as related location. */ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig { // for documentation of the implementations here, see the QLDoc in the CandidateSig signature module. @@ -112,7 +111,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig } /** - * Returns the callable that contains the given endpoint. + * Returns the API callable being modelled. * * Each Java mode should implement this predicate. */ @@ -279,8 +278,10 @@ private class ClassQualifierCharacteristic extends CharacteristicsImpl::NotASink } /** - * A characteristic that limits candidates to parameters of methods that are recognized as `ModelApi`, iow., APIs that - * are considered worth modeling. + * A call to a method that's known locally will not be considered as a candidate to model. + * + * The reason is that we would expect data/taint flow into the method implementation to uncover + * any sinks that are present there. */ private class ArgumentToLocalCall extends CharacteristicsImpl::UninterestingToModelCharacteristic { ArgumentToLocalCall() { this = "argument to local call" } From 12ea5e0e90cdc6d2414af2aff7505d7ddb5fec11 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 31 May 2023 11:53:02 +0200 Subject: [PATCH 200/739] Java: fix sanitizer bug --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 2773e1f2cfc..6743eca3789 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -49,8 +49,8 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig // Sanitizers are currently not modeled in MaD. TODO: check if this has large negative impact. predicate isSanitizer(Endpoint e, EndpointType t) { + exists(t) and ( - exists(t) and e.getType() instanceof BoxedType or e.getType() instanceof PrimitiveType From a9811fe2c3c2fec4968f69e4a21ffa93ff213b6b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 31 May 2023 10:51:42 +0100 Subject: [PATCH 201/739] Swift: Make Macro.getName() more efficient. --- cpp/ql/lib/semmle/code/cpp/Macro.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/Macro.qll b/cpp/ql/lib/semmle/code/cpp/Macro.qll index 4378cec4857..bd916d4bc4e 100644 --- a/cpp/ql/lib/semmle/code/cpp/Macro.qll +++ b/cpp/ql/lib/semmle/code/cpp/Macro.qll @@ -34,7 +34,7 @@ class Macro extends PreprocessorDirective, @ppd_define { * Gets the name of the macro. For example, `MAX` in * `#define MAX(x,y) (((x)>(y))?(x):(y))`. */ - string getName() { result = this.getHead().splitAt("(", 0) } + string getName() { result = this.getHead().regexpCapture("([^(]*+).*", 1) } /** Holds if the macro has name `name`. */ predicate hasName(string name) { this.getName() = name } From ace7b6b7116bf5dea1cfcd3bc6cef3ca65feb83b Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Wed, 31 May 2023 11:49:00 +0200 Subject: [PATCH 202/739] C++: Add `cpp/invalid-pointer-deref` FP test case --- .../pointer-deref/InvalidPointerDeref.expected | 17 +++++++++++++++++ .../Security/CWE/CWE-193/pointer-deref/test.cpp | 14 ++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 6b4d039ee6b..09c75e7369c 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -723,6 +723,15 @@ edges | test.cpp:359:16:359:27 | end_plus_one | test.cpp:358:14:358:26 | Load: * ... | | test.cpp:359:16:359:27 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:359:16:359:31 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | +| test.cpp:363:14:363:27 | new[] | test.cpp:365:15:365:15 | p | +| test.cpp:365:15:365:15 | p | test.cpp:368:5:368:10 | ... += ... | +| test.cpp:365:15:365:15 | p | test.cpp:368:5:368:10 | ... += ... | +| test.cpp:368:5:368:10 | ... += ... | test.cpp:371:7:371:7 | p | +| test.cpp:368:5:368:10 | ... += ... | test.cpp:371:7:371:7 | p | +| test.cpp:368:5:368:10 | ... += ... | test.cpp:372:16:372:16 | p | +| test.cpp:368:5:368:10 | ... += ... | test.cpp:372:16:372:16 | p | +| test.cpp:371:7:371:7 | p | test.cpp:372:15:372:16 | Load: * ... | +| test.cpp:372:16:372:16 | p | test.cpp:372:15:372:16 | Load: * ... | nodes | test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc | | test.cpp:5:15:5:15 | p | semmle.label | p | @@ -1050,6 +1059,13 @@ nodes | test.cpp:359:14:359:32 | Load: * ... | semmle.label | Load: * ... | | test.cpp:359:16:359:27 | end_plus_one | semmle.label | end_plus_one | | test.cpp:359:16:359:31 | ... + ... | semmle.label | ... + ... | +| test.cpp:363:14:363:27 | new[] | semmle.label | new[] | +| test.cpp:365:15:365:15 | p | semmle.label | p | +| test.cpp:368:5:368:10 | ... += ... | semmle.label | ... += ... | +| test.cpp:368:5:368:10 | ... += ... | semmle.label | ... += ... | +| test.cpp:371:7:371:7 | p | semmle.label | p | +| test.cpp:372:15:372:16 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:372:16:372:16 | p | semmle.label | p | subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | @@ -1077,3 +1093,4 @@ subpaths | test.cpp:350:15:350:19 | Load: * ... | test.cpp:347:14:347:27 | new[] | test.cpp:350:15:350:19 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:347:14:347:27 | new[] | new[] | test.cpp:348:20:348:23 | size | size | | test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | +| test.cpp:372:15:372:16 | Load: * ... | test.cpp:363:14:363:27 | new[] | test.cpp:372:15:372:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:363:14:363:27 | new[] | new[] | test.cpp:365:19:365:22 | size | size | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index 3dfd8b89097..3711f272e76 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -358,3 +358,17 @@ void test25(unsigned size) { int val1 = *end_plus_one; // BAD int val2 = *(end_plus_one + 1); // BAD } + +void test26(unsigned size) { + char *xs = new char[size]; + char *p = xs; + char *end = p + size; + + if (p + 4 <= end) { + p += 4; + } + + if (p < end) { + int val = *p; // GOOD [FALSE POSITIVE] + } +} From 5981ce4cb1499480ba59a203dda82094c51aac49 Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Wed, 31 May 2023 12:15:21 +0200 Subject: [PATCH 203/739] Swift: accept test output from failed CFG consistency queries --- .../decl/enumdecl/CONSISTENCY/CfgConsistency.expected | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 swift/ql/test/library-tests/elements/decl/enumdecl/CONSISTENCY/CfgConsistency.expected diff --git a/swift/ql/test/library-tests/elements/decl/enumdecl/CONSISTENCY/CfgConsistency.expected b/swift/ql/test/library-tests/elements/decl/enumdecl/CONSISTENCY/CfgConsistency.expected new file mode 100644 index 00000000000..4de95c00602 --- /dev/null +++ b/swift/ql/test/library-tests/elements/decl/enumdecl/CONSISTENCY/CfgConsistency.expected @@ -0,0 +1,10 @@ +deadEnd +| file://:0:0:0:0 | ... = ... | +| file://:0:0:0:0 | ... = ... | +| file://:0:0:0:0 | ... = ... | +| file://:0:0:0:0 | ... = ... | +| file://:0:0:0:0 | ... = ... | +| file://:0:0:0:0 | ... = ... | +| file://:0:0:0:0 | ... = ... | +| file://:0:0:0:0 | ... = ... | +| file://:0:0:0:0 | ... = ... | From 282ee08ba9cf62db0b9fd911699bbedf4096ccb4 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 31 May 2023 13:26:35 +0200 Subject: [PATCH 204/739] Java: Fix GsonDeserializableField --- .../semmle/code/java/frameworks/google/GsonSerializability.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index 1e41ad0c458..f7de80daaf4 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -50,8 +50,7 @@ private class GsonDeserializableField extends DeserializableField { exists(GsonDeserializableType superType | superType = this.getDeclaringType().getAnAncestor() and not superType instanceof TypeObject and - //superType.fromSource() - not superType.(RefType).getPackage().getName().matches("java%") + superType.fromSource() ) } } From 5a9d09c49e1b09c20343e568a54977957aa4a944 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 31 May 2023 13:36:58 +0200 Subject: [PATCH 205/739] Java: docs update Co-authored-by: Aditya Sharad <6874315+adityasharad@users.noreply.github.com> --- java/ql/src/Telemetry/AutomodelSharedUtil.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelSharedUtil.qll b/java/ql/src/Telemetry/AutomodelSharedUtil.qll index 2ca38506160..11161f599be 100644 --- a/java/ql/src/Telemetry/AutomodelSharedUtil.qll +++ b/java/ql/src/Telemetry/AutomodelSharedUtil.qll @@ -50,7 +50,7 @@ predicate isKnownKind( type instanceof AutomodelEndpointTypes::CommandInjectionSinkType } -/** Gets the argument name for the argument with the index `index`. */ +/** Gets the models-as-data description for the method argument with the index `index`. */ bindingset[index] string getArgumentForIndex(int index) { index = -1 and result = "Argument[this]" From ea5c36491b3581e40ea56ca1a946ad93eefeced8 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Wed, 31 May 2023 11:39:20 +0000 Subject: [PATCH 206/739] Java: Improve documentation of sampling strategy --- ...AutomodelApplicationModeExtractNegativeExamples.ql | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index 7407be0be57..19beefad3d3 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -14,7 +14,10 @@ private import AutomodelEndpointTypes private import AutomodelSharedUtil /** - * Gets a sample of endpoints for which the given characteristic applies. + * Gets a sample of endpoints (of at most `limit` samples) for which the given characteristic applies. + * + * The main purpose of this helper predicate is to avoid selecting too many samples, as this may + * cause the SARIF file to exceed the maximum size limit. */ bindingset[limit] Endpoint getSampleForCharacteristic(EndpointCharacteristic c, int limit) { @@ -28,7 +31,11 @@ Endpoint getSampleForCharacteristic(EndpointCharacteristic c, int limit) { loc.getFile().getAbsolutePath(), loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn() ) and - // we order the endpoints by location, but (to avoid bias) we select the indices semi-randomly + // To avoid selecting samples that are too close together (as the ranking above goes by file + // path first), we select `limit` evenly spaced samples from the ranked list of endpoints. By + // default this would always include the first sample, so we add a random-chosen prime offset + // to the first sample index, and reduce modulo the number of endpoints. + // Finally, we add 1 to the result, as ranking results in a 1-indexed relation. n = 1 + (([0 .. limit - 1] * (num_endpoints / limit).floor() + 46337) % num_endpoints) ) } From daad2e1bd38756b3f6510f0939b6b0f4676d7707 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 31 May 2023 10:46:25 +0100 Subject: [PATCH 207/739] Swift: Use regexp for function name. --- swift/ql/lib/codeql/swift/elements/decl/Function.qll | 10 ++++++++++ swift/ql/lib/codeql/swift/security/SensitiveExprs.qll | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/Function.qll b/swift/ql/lib/codeql/swift/elements/decl/Function.qll index ad1fa957d94..7fc5b5b2155 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/Function.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/Function.qll @@ -6,6 +6,16 @@ private import codeql.swift.elements.decl.Method */ class Function extends Generated::Function, Callable { override string toString() { result = this.getName() } + + /** + * Gets the name of this function, without the argument list. For example + * a function with name `myFunction(arg:)` has short name `myFunction`. + */ + string getShortName() { + // match as many characters as possible that are not `(`. + // (`*+` is possessive matching) + result = this.getName().regexpCapture("([^(]*+).*", 1) + } } /** diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index d750e673121..a991f8e2c37 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -102,7 +102,7 @@ private class SensitiveFunction extends Function { string name; // name of the function, not including the argument list. SensitiveFunction() { - name = this.getName().splitAt("(", 0) and + name = this.getShortName() and name.regexpMatch(sensitiveType.getRegexp()) } From caf250cc1b18bc4000b3a2dd8353664c61b33450 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 31 May 2023 12:54:42 +0100 Subject: [PATCH 208/739] Swift: Update the QLdoc on Callable. --- swift/ql/.generated.list | 4 ++-- swift/ql/lib/codeql/swift/generated/Callable.qll | 2 ++ swift/ql/lib/codeql/swift/generated/Raw.qll | 2 ++ swift/schema.py | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 53847acba54..523796c28ad 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -369,7 +369,7 @@ lib/codeql/swift/elements.qll 3df0060edd2b2030f4e4d7d5518afe0073d798474d9b1d6185 lib/codeql/swift/generated/AstNode.qll 02ca56d82801f942ae6265c6079d92ccafdf6b532f6bcebd98a04029ddf696e4 6216fda240e45bd4302fa0cf0f08f5f945418b144659264cdda84622b0420aa2 lib/codeql/swift/generated/AvailabilityInfo.qll c648a66cf45414c85cf9cc69aa05b765a49d0c18cd9c101c34f99a9adc38a1ee 54ba7b07b4177d35e85d19363aa7adcda29cda185a5818e5fcb7c678c093e0ba lib/codeql/swift/generated/AvailabilitySpec.qll fb1255f91bb5e41ad4e9c675a2efbc50d0fb366ea2de68ab7eebd177b0795309 144e0c2e7d6c62ecee43325f7f26dcf437881edf0b75cc1bc898c6c4b61fdeaf -lib/codeql/swift/generated/Callable.qll 9dcf09a2f227dd6f569f007a07fb368d6b928ffd002535bb97118361430d948c 5c203f5f6b4f8b6748e61e09bb46c55442a2fb36f2d1fa950e6f81bdda562709 +lib/codeql/swift/generated/Callable.qll aaa3a8fbf04cb1be4c99de917353dd3a56ce1bce97af745e4c922957b7480e44 1896c0fb1690aef99accdaba0fd906549f5a971d9f663945e4ca6d6e2a21e2e4 lib/codeql/swift/generated/Comment.qll f58b49f6e68c21f87c51e2ff84c8a64b09286d733e86f70d67d3a98fe6260bd6 975bbb599a2a7adc35179f6ae06d9cbc56ea8a03b972ef2ee87604834bc6deb1 lib/codeql/swift/generated/DbFile.qll a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc lib/codeql/swift/generated/DbLocation.qll b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 @@ -384,7 +384,7 @@ lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d lib/codeql/swift/generated/ParentChild.qll 01b27b48a12955a45ea26d0f7888a160faac9fd5fb57a19e87365318e9b21a30 88090ef26a7ce63f4ba88fa735e2c8207fd1de00076532083d93a7a02553797e lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 13cf09f9b2f628831b6b715448779366959a4c44b1b5ffc97397654fc8620486 03d60bdb6543d87a83ca50a3977c98c08d936d435981ae0b373f98ecde7a142b +lib/codeql/swift/generated/Raw.qll 5715979160eac96fe4b54b73cdb88958617b9e3d66928c61029a12fab1c25902 5dbaaf2e03512107fc6e533d1388b7e6c8104ec5bcc43781256d67750d841ce8 lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 diff --git a/swift/ql/lib/codeql/swift/generated/Callable.qll b/swift/ql/lib/codeql/swift/generated/Callable.qll index db03af1dbd0..2cfcdeb5c11 100644 --- a/swift/ql/lib/codeql/swift/generated/Callable.qll +++ b/swift/ql/lib/codeql/swift/generated/Callable.qll @@ -10,6 +10,8 @@ module Generated { class Callable extends Synth::TCallable, Element { /** * Gets the name of this callable, if it exists. + * + * The name includes any arguments of the callable, for example `myFunction(arg:)`. */ string getName() { result = Synth::convertCallableToRaw(this).(Raw::Callable).getName() } diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index 8ebecc81a15..05e46d484b3 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -21,6 +21,8 @@ module Raw { class Callable extends @callable, Element { /** * Gets the name of this callable, if it exists. + * + * The name includes any arguments of the callable, for example `myFunction(arg:)`. */ string getName() { callable_names(this, result) } diff --git a/swift/schema.py b/swift/schema.py index ef2c357899f..0ca1e25a6a3 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -228,7 +228,8 @@ class ParamDecl(VarDecl): """) class Callable(Element): - name: optional[string] | doc("name of this callable") + name: optional[string] | doc("name of this callable") | desc("The name includes any arguments " + "of the callable, for example `myFunction(arg:)`.") self_param: optional[ParamDecl] | child params: list[ParamDecl] | child body: optional["BraceStmt"] | child | desc("The body is absent within protocol declarations.") From 03051dde7fae649a5c67301cb5476daca3cc502a Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 31 May 2023 12:40:21 +0200 Subject: [PATCH 209/739] Java: spelling --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 6743eca3789..bf8a0ac1274 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -111,7 +111,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig } /** - * Returns the API callable being modelled. + * Returns the API callable being modeled. * * Each Java mode should implement this predicate. */ From 5de56db3af741d1ce8104f9d9ddffa9e5f4fcf8f Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 31 May 2023 14:10:54 +0200 Subject: [PATCH 210/739] Java: QlDoc for isKnownKind --- java/ql/src/Telemetry/AutomodelSharedUtil.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/ql/src/Telemetry/AutomodelSharedUtil.qll b/java/ql/src/Telemetry/AutomodelSharedUtil.qll index 11161f599be..7b4a88c8243 100644 --- a/java/ql/src/Telemetry/AutomodelSharedUtil.qll +++ b/java/ql/src/Telemetry/AutomodelSharedUtil.qll @@ -22,6 +22,10 @@ class DollarAtString extends string { } } +/** + * Holds for all combinations of MaD kinds (`kind`) and their human readable + * descriptions. + */ predicate isKnownKind( string kind, string humanReadableKind, AutomodelEndpointTypes::EndpointType type ) { From 43d6bf04b5c07a0fe8214bfa02b0383b09a6f703 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 26 May 2023 11:32:12 +0200 Subject: [PATCH 211/739] C#: Make synthetic implicit casts when values are provided using the DefaultParameterValue attribute. --- .../Entities/Expression.cs | 5 ++ .../Entities/Expressions/ImplicitCast.cs | 74 +++++++++++++++---- .../SymbolExtensions.cs | 2 +- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs index 698be2e2c35..a77c0b30095 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs @@ -211,6 +211,11 @@ namespace Semmle.Extraction.CSharp.Entities return Default.CreateGenerated(cx, parent, childIndex, location, ValueAsString(null)); } + if (type.SpecialType is SpecialType.None) + { + return ImplicitCast.CreateGenerated(cx, parent, childIndex, type, defaultValue, location); + } + if (type.SpecialType is SpecialType.System_DateTime) { return DateTimeObjectCreation.CreateGenerated(cx, parent, childIndex, type, defaultValue, location); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs index 2d617cdb1b9..20daedc0ae8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs @@ -1,3 +1,4 @@ +using System.Linq; using Microsoft.CodeAnalysis; using Semmle.Extraction.Kinds; @@ -11,33 +12,74 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions private set; } - public ImplicitCast(ExpressionNodeInfo info) + private ImplicitCast(ExpressionNodeInfo info) : base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.CAST, info.Parent, info.Child, true, info.ExprValue)) { Expr = Factory.Create(new ExpressionNodeInfo(Context, info.Node, this, 0)); } - public ImplicitCast(ExpressionNodeInfo info, IMethodSymbol method) + private ImplicitCast(ExpressionNodeInfo info, IMethodSymbol method) : base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue)) { Expr = Factory.Create(info.SetParent(this, 0)); - var target = Method.Create(Context, method); - if (target is not null) - Context.TrapWriter.Writer.expr_call(this, target); - else - Context.ModelError(info.Node, "Failed to resolve target for operator invocation"); + AddOperatorCall(method); } - /// <summary> - /// Creates a new expression, adding casts as required. - /// </summary> - /// <param name="cx">The extraction context.</param> - /// <param name="node">The expression node.</param> - /// <param name="parent">The parent of the expression.</param> - /// <param name="child">The child number.</param> - /// <param name="type">A type hint.</param> - /// <returns>A new expression.</returns> + private ImplicitCast(ExpressionInfo info, IMethodSymbol method, object value) : base(info) + { + Expr = Literal.CreateGenerated(Context, this, 0, method.Parameters[0].Type, value, info.Location); + + AddOperatorCall(method); + } + + private void AddOperatorCall(IMethodSymbol method) + { + var target = Method.Create(Context, method); + Context.TrapWriter.Writer.expr_call(this, target); + } + + private static IMethodSymbol? GetImplicitConversionMethod(ITypeSymbol type, object value) => + type + .GetMembers() + .Where(m => + m is IMethodSymbol method && + method.GetName() == "op_Implicit" && + method.Parameters.Length == 1 && + method.Parameters[0].Type.Name == value.GetType().Name + ) + .Cast<IMethodSymbol>() + .FirstOrDefault(); + + // Creates a new generated expression with an implicit cast added, if needed. + public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, ITypeSymbol type, object value, + Extraction.Entities.Location location) + { + ExpressionInfo create(ExprKind kind, string? v) => + new ExpressionInfo( + cx, + AnnotatedTypeSymbol.CreateNotAnnotated(type), + location, + kind, + parent, + childIndex, + true, + v); + + var method = GetImplicitConversionMethod(type, value); + if (method is not null) + { + var info = create(ExprKind.OPERATOR_INVOCATION, null); + return new ImplicitCast(info, method, value); + } + else + { + cx.ModelError(location, "Failed to resolve target for implicit operator invocation for a parameter default."); + return new Expression(create(ExprKind.UNKNOWN, ValueAsString(value))); + } + } + + // Creates a new expression, adding casts as required. public static Expression Create(ExpressionNodeInfo info) { var resolvedType = info.ResolvedType; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs b/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs index cd182fe4640..aaef1702532 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs @@ -25,7 +25,7 @@ namespace Semmle.Extraction.CSharp Nullability = nullability; } - public static AnnotatedTypeSymbol? CreateNotAnnotated(ITypeSymbol symbol) => + public static AnnotatedTypeSymbol? CreateNotAnnotated(ITypeSymbol? symbol) => symbol is null ? (AnnotatedTypeSymbol?)null : new AnnotatedTypeSymbol(symbol, NullableAnnotation.None); } From 83a8e3bdbc1883f42ecc2a050d15315565c74824 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 26 May 2023 11:32:34 +0200 Subject: [PATCH 212/739] C#: Add some more testcases. --- .../library-tests/parameters/Parameters.cs | 9 ++++++- .../library-tests/parameters/Parameters.cs_ | 9 ++++++- .../library-tests/parameters/Parameters.dll | Bin 6144 -> 6144 bytes .../parameters/Parameters.expected | 13 +++++++++++ .../library-tests/parameters/Parameters.ql | 22 +++++++++++++----- 5 files changed, 45 insertions(+), 8 deletions(-) diff --git a/csharp/ql/test/library-tests/parameters/Parameters.cs b/csharp/ql/test/library-tests/parameters/Parameters.cs index ebe17322bad..ee62454b404 100644 --- a/csharp/ql/test/library-tests/parameters/Parameters.cs +++ b/csharp/ql/test/library-tests/parameters/Parameters.cs @@ -25,7 +25,14 @@ public class Parameters public void M17([Optional, DefaultParameterValue(null)] object arg7) => throw null; public void M18([Optional, DefaultParameterValue(3)] int? arg8) => throw null; public void M19([Optional, DecimalConstant(1, 0, 0, 0, 103)] decimal arg9) => throw null; + public void M20([Optional, DefaultParameterValue(7)] MyStruct arg10) => throw null; + public void M21([Optional, DefaultParameterValue("mystring")] MyStruct arg10) => throw null; - public struct MyStruct { } + public struct MyStruct + { + public static implicit operator MyStruct(int i) => new MyStruct(); + public static implicit operator MyStruct(string s) => new MyStruct(); + + } public enum MyEnum { A = 1, B = 2 } } \ No newline at end of file diff --git a/csharp/ql/test/library-tests/parameters/Parameters.cs_ b/csharp/ql/test/library-tests/parameters/Parameters.cs_ index 8fce6f198c3..136e7262b98 100644 --- a/csharp/ql/test/library-tests/parameters/Parameters.cs_ +++ b/csharp/ql/test/library-tests/parameters/Parameters.cs_ @@ -25,7 +25,14 @@ public class ParametersDll public void M17([Optional, DefaultParameterValue(null)] object arg7) => throw null; public void M18([Optional, DefaultParameterValue(3)] int? arg8) => throw null; public void M19([Optional, DecimalConstant(1, 0, 0, 0, 103)] decimal arg9) => throw null; + public void M20([Optional, DefaultParameterValue(7)] MyStruct arg10) => throw null; + public void M21([Optional, DefaultParameterValue("mystring")] MyStruct arg10) => throw null; - public struct MyStruct { } + public struct MyStruct + { + public static implicit operator MyStruct(int i) => new MyStruct(); + public static implicit operator MyStruct(string s) => new MyStruct(); + + } public enum MyEnum { A = 1, B = 2 } } \ No newline at end of file diff --git a/csharp/ql/test/library-tests/parameters/Parameters.dll b/csharp/ql/test/library-tests/parameters/Parameters.dll index b40c91369cbf75bb1c1296e3a7652ad3a7abc331..3358306fc8976442d42361e9615275591f8a928d 100644 GIT binary patch delta 2032 zcmZ{ld2Ccg9LK*iZ})Y3uzg!>>9$*J*+MNy+XYDxIV?wE15H{BXoFzdl{AHxqa~0c z^2(tB6heJU#6S=#S|M_XTIC2B&{Q!o0Tl#8AgF(MVS-mQA%16=R5Wpt`ONS8o#XxH z&FtHbvW~K?8+<E!qGvjvjmU|mo%?2s8=eqF{-1{fGra<NuU99E<g|2etymq7mO__l zq=X-l0^qYWKzQ{|xmPWp@lHwGyDXDO0R77ZQaDZkp$y#0OyU%K=>PlP*RrrSVgu3D zzy`Lx7USAwtxby>+tgF5xtfn{bXF~9GImrvbyj>b+sCPwNa~5riyNp_p%f4Al-?XG zFEfvNFsqsqVa;b1-bO3W{Yf%G78}2bv6hYJrQ#4#Y^CE-W?&;Bj!PR)$PoRLLUEPm zcFip9&(QHrsJY$pFOJ`8DF%h&ZXI8Micf0hXqL*cE+@qGBQNS{K0WkJ#ww{j3Vef1 zQ8>7Uc576h8pCvzQrmRUz%@oO<_n^_qWdhKkl>cDa!3VxY^1QSo12<K6@l8hD=Ftv z4#W^Fv|b>4<aRRI+5y`>j2)QWu^+q0H^}OImC)1KQKl_W*QdIuTKiNt)!II#`kw1k zYBPIoD-6H^mvXO>_u&8&={Bm8Dhd0IdIWFtHXSgkktz*`jarUl2;wcH*5U(%&|}mV zoJSUp8ub#@0Gu#NP`TMSWn?;23FEX;Ww?YKd}!1}TtzNEGHNFKBKX9p1pD&vsZp&Q zHxTEHT8-~;H$FFN6K)_M7meD6KTzP}vXQB{g+aJtRDY@{uH9Dpbr<3Xt+oXYTRu?; zUjbN@N)hU63%o~4z6-#@3FA19avVoFj-$r>+i~x-{)yFc!}ZV!dUB0kZm@RBwG$_O zm_z!pfD|}p{g?M>e~jh~UPOU;nl0LCS9I}|7M;3dr;h!GDv2-D^~NqM8Bt5{T-C)3 zlPM@B9mF*6*R0TtYu0GiY1WfA+R04pCUfyRnU5yYwXuecjR5XKIWmyRpGpAP7|Saa zMkV7s?HAAw@*9$%Q_MJn??;V{>3EdpIL!*}$2F@oYq&xHv(U_0b$ZNP&3aV0?3j<G z>}b+f3z@=Pm(zKYae(P9B{#z5<2PeHiZB%OWC>E?h!XTin9Rj!GKvav7+i8BHj@wF zMRF4MlGC+cOOE8)jdBtXuN>|qKCYa*QX*mE1dfY!+F7Tab?mt=y0p`!oh~(2p5}#p zN1Wzzhs1TphlC{*Pid~V79u8Jw$zwc7>}2QzBWwP2MYeQi{a})15fwPa)O_uq&tif z^lFvFuUCLom0TPovw1M8_3;OGkoSIy>Z*#Bp}w_|tQx@@i?KbDn*6>LP2SnmOT!i~ zc`V+tq`4{4v<&raZSz|in%mVpmJ9Dz_M8=~sy3W&TPb!Vukp^L75jZjA{6m{OsmQC zsjQq99!(pTp_RwA2#wyjehV`E`GSM^sSQN}nnCZiey{rc{L*>TgDbq=;Dce#9r0D- z97I($_s>%VCYP`}-oW%MyO&|F<Bdrl<edL_{P*A949B-Gx-xb2mi<S)=JXXM#@zU& zF}c)3zb`J@HzntrW4~0Ub`LOr%Ul()QZMA>$Y`lI-1+rLFyl{4PM&ZilyyUNmL>fS D+qg<0 delta 1875 zcmZ{leN2^A9LK-sdG5Vjke3IpAaCjg3_{_Kmxu~;A`y|Yfe6CT3egb*ti&Q6aW7tH zI4Py4Kbp=NVJ%-G8Eh4;rDIucHd!w#r?wWkx#ia8YAf4X-}B>vwzi(_e9rIt{hf2} zdCob{xuJqk!I42%?^yen!$avtV_^7nqcUx!a@?+bV3VC;<k`(C$Ji2U?^FFLr2)wE z7-_(bpZ$P88c=p!e5qY)9E!{|?zMm@thCe36~Re2kk!vN9^kCWxPJGpj-Bm2dXUSJ zfQxljLp^2~vm3Ii8mb>*{Uh~SgL+-pGux>3L#Z|&2O^Uw?y6$2Rt%F_ye#|)q_AYL z=&@3PAeJ-Gjphpn0p}qa_`%S=?s`k*nI0T4G?P_|8HWvQ=0SrRGd$=v6#a3fxl?#Z z=oNpB#5bY)9yNYp`;eGY(Rh)dA%xG-ACrDcaQ;TO{FH{nTAPwI6IPLxwr7QRM@ zS+bz=I9;vunpoJxF-jP7HK}GKXL5H`kP9)xHswrt5XIyhe5*>TROnZ~!`xO;*=RBM zA{(cSe)3Oa03OdM2GAHfj{W2bvevIBbRgNsX)81@s6nb-3+ffBeU1wHOr3mfA*tWy ztvQ8A*i>&jDx1oMcOCTrRRqpB>Tw+9i5hcMGgUOk9rZNcL@Xv9wHv1qj}IIb3gSba zk|{?HQ7yqIj#5;~IPWMf77x#~qcZU+SLmXn?!#wD!zD*O%3L}wJF0=XrMTj#?QFLU zUpeYo1h4P_e(T6Sd;>qechn$m@T6XwQ?jI)(7SzxH1Hm2;(f=lEbUm9b}UP``G4o% zEJxGlUpFn3&J{A;5^-|HDI;B|A>G(QDx5I?%T)36gll-76l#S}iqk3V6^6w>%#HP# zire5bgB~ub&x}GYX>l5w4+_hL)xtVqv#^!)U=Nvy5i$*@NIyEn9}s%67)3}xB3ARu zPev(EKnf4Jms_Fz4EnLS2TufP<x(UdUz!$5Tq1l}ST26Gutr$NA-rfnJ9{-to2|lD z$?iZG{SI-u$tX_sIXW*%c7WL&tVE#^z#_~d7=RDA5#X^{qyosoVsaHWlErw6EJG(* zffvd3;@6YK9PlBd0xg_M1%ILlZ4$RRaT^Y*usC6H!pxsjqvDK;GfL+>H627I{#Mf* zF05u5hn1-`&kOgPop2c^$#`Rhs|U+?8}L%#hvy2-MHJ36!h0iPUa-!^l&A>aD_$1; zq;bRab-Yw+7tdbY2+wk*&eaqauuOaudBL#zqOUG*?djRky{&7H&heSt*gX`!c(7_} z`wO>H{>b~>4#ni!V=;AhVr++fB=#M9b=>oAx4u2>b8+QGKV`M@nyIPfgn2IkP5iHF ziqiwlJ^C$tEIBOKnY$imXIq(8e(27H!+n2MANzP}Z`F;fFWXI4Z_&JY%`rK4%=(FA zuim_W?dA<<XIoY|e|dW3N*()$Gm?zbfSnTmyX{Z9JrSF5*EE{eOvESss)h?9{s9Te B9@YQ= diff --git a/csharp/ql/test/library-tests/parameters/Parameters.expected b/csharp/ql/test/library-tests/parameters/Parameters.expected index 4ac08438d3a..820ec37b9ab 100644 --- a/csharp/ql/test/library-tests/parameters/Parameters.expected +++ b/csharp/ql/test/library-tests/parameters/Parameters.expected @@ -5,12 +5,16 @@ noDefaultValue | Parameters.cs:8:17:8:18 | M2 | Parameters.cs:8:24:8:24 | a | 0 | | Parameters.cs:12:17:12:18 | M6 | Parameters.cs:12:29:12:30 | s1 | 0 | | Parameters.cs:13:17:13:18 | M7 | Parameters.cs:13:27:13:28 | e1 | 0 | +| Parameters.cs:33:32:33:39 | implicit conversion | Parameters.cs:33:54:33:54 | i | 0 | +| Parameters.cs:34:32:34:39 | implicit conversion | Parameters.cs:34:57:34:57 | s | 0 | | Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | a | 0 | | Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | b | 1 | | Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | c | 2 | | Parameters.dll:0:0:0:0 | M2 | Parameters.dll:0:0:0:0 | a | 0 | | Parameters.dll:0:0:0:0 | M6 | Parameters.dll:0:0:0:0 | s1 | 0 | | Parameters.dll:0:0:0:0 | M7 | Parameters.dll:0:0:0:0 | e1 | 0 | +| Parameters.dll:0:0:0:0 | implicit conversion | Parameters.dll:0:0:0:0 | i | 0 | +| Parameters.dll:0:0:0:0 | implicit conversion | Parameters.dll:0:0:0:0 | s | 0 | withDefaultValue | Parameters.cs:8:17:8:18 | M2 | Parameters.cs:8:34:8:34 | b | 1 | Parameters.cs:8:38:8:41 | null | null | | Parameters.cs:8:17:8:18 | M2 | Parameters.cs:8:51:8:51 | c | 2 | Parameters.cs:8:55:8:70 | "default string" | default string | @@ -39,6 +43,8 @@ withDefaultValue | Parameters.cs:25:17:25:19 | M17 | Parameters.cs:25:68:25:71 | arg7 | 0 | Parameters.cs:25:21:25:71 | default | null | | Parameters.cs:26:17:26:19 | M18 | Parameters.cs:26:63:26:66 | arg8 | 0 | Parameters.cs:26:21:26:66 | 3 | 3 | | Parameters.cs:27:17:27:19 | M19 | Parameters.cs:27:74:27:77 | arg9 | 0 | Parameters.cs:27:21:27:77 | 10.3 | 10.3 | +| Parameters.cs:28:17:28:19 | M20 | Parameters.cs:28:67:28:71 | arg10 | 0 | Parameters.cs:28:21:28:71 | call to operator implicit conversion | - | +| Parameters.cs:29:17:29:19 | M21 | Parameters.cs:29:76:29:80 | arg10 | 0 | Parameters.cs:29:21:29:80 | call to operator implicit conversion | - | | Parameters.dll:0:0:0:0 | M2 | Parameters.dll:0:0:0:0 | b | 1 | Parameters.dll:0:0:0:0 | default | null | | Parameters.dll:0:0:0:0 | M2 | Parameters.dll:0:0:0:0 | c | 2 | Parameters.dll:0:0:0:0 | "default string" | default string | | Parameters.dll:0:0:0:0 | M3 | Parameters.dll:0:0:0:0 | a | 0 | Parameters.dll:0:0:0:0 | 1 | 1 | @@ -66,8 +72,15 @@ withDefaultValue | Parameters.dll:0:0:0:0 | M17 | Parameters.dll:0:0:0:0 | arg7 | 0 | Parameters.dll:0:0:0:0 | default | null | | Parameters.dll:0:0:0:0 | M18 | Parameters.dll:0:0:0:0 | arg8 | 0 | Parameters.dll:0:0:0:0 | 3 | 3 | | Parameters.dll:0:0:0:0 | M19 | Parameters.dll:0:0:0:0 | arg9 | 0 | Parameters.dll:0:0:0:0 | 10.3 | 10.3 | +| Parameters.dll:0:0:0:0 | M20 | Parameters.dll:0:0:0:0 | arg10 | 0 | Parameters.dll:0:0:0:0 | call to operator implicit conversion | - | +| Parameters.dll:0:0:0:0 | M21 | Parameters.dll:0:0:0:0 | arg10 | 0 | Parameters.dll:0:0:0:0 | call to operator implicit conversion | - | dateTimeDefaults | Parameters.cs:22:17:22:19 | M14 | Parameters.cs:22:64:22:67 | arg4 | Parameters.cs:22:21:22:67 | object creation of type DateTime | DateTime(long) | 14 | | Parameters.cs:23:17:23:19 | M15 | Parameters.cs:23:68:23:71 | arg5 | Parameters.cs:23:21:23:71 | object creation of type DateTime | DateTime(long) | 10001 | | Parameters.dll:0:0:0:0 | M14 | Parameters.dll:0:0:0:0 | arg4 | Parameters.dll:0:0:0:0 | object creation of type DateTime | DateTime(long) | 14 | | Parameters.dll:0:0:0:0 | M15 | Parameters.dll:0:0:0:0 | arg5 | Parameters.dll:0:0:0:0 | object creation of type DateTime | DateTime(long) | 10001 | +implicitConversionDefaults +| Parameters.cs:28:17:28:19 | M20 | Parameters.cs:28:67:28:71 | arg10 | Parameters.cs:28:21:28:71 | call to operator implicit conversion | Parameters.cs:28:21:28:71 | 7 | Int32 | 7 | +| Parameters.cs:29:17:29:19 | M21 | Parameters.cs:29:76:29:80 | arg10 | Parameters.cs:29:21:29:80 | call to operator implicit conversion | Parameters.cs:29:21:29:80 | "mystring" | String | mystring | +| Parameters.dll:0:0:0:0 | M20 | Parameters.dll:0:0:0:0 | arg10 | Parameters.dll:0:0:0:0 | call to operator implicit conversion | Parameters.dll:0:0:0:0 | 7 | Int32 | 7 | +| Parameters.dll:0:0:0:0 | M21 | Parameters.dll:0:0:0:0 | arg10 | Parameters.dll:0:0:0:0 | call to operator implicit conversion | Parameters.dll:0:0:0:0 | "mystring" | String | mystring | diff --git a/csharp/ql/test/library-tests/parameters/Parameters.ql b/csharp/ql/test/library-tests/parameters/Parameters.ql index 09eadc693f0..209cdc12577 100644 --- a/csharp/ql/test/library-tests/parameters/Parameters.ql +++ b/csharp/ql/test/library-tests/parameters/Parameters.ql @@ -16,11 +16,15 @@ query predicate noDefaultValue(Parameterizable container, Parameter p, int i) { not compilerGeneratedAttribute(container) } -query predicate withDefaultValue(Parameterizable container, Parameter p, int i, Expr e, string value) { +private predicate defaultValue(Parameterizable container, Parameter p, int i, Expr e) { fromTestLocation(container) and p.hasDefaultValue() and container.getParameter(i) = p and - p.getDefaultValue() = e and + p.getDefaultValue() = e +} + +query predicate withDefaultValue(Parameterizable container, Parameter p, int i, Expr e, string value) { + defaultValue(container, p, i, e) and (if exists(e.getValue()) then value = e.getValue() else value = "-") and not compilerGeneratedAttribute(container) } @@ -28,11 +32,17 @@ query predicate withDefaultValue(Parameterizable container, Parameter p, int i, query predicate dateTimeDefaults( Parameterizable container, Parameter p, ObjectCreation o, string constructor, string value ) { - fromTestLocation(container) and - p.hasDefaultValue() and - container.getAParameter() = p and - p.getDefaultValue() = o and + defaultValue(container, p, _, o) and o.getTarget().toStringWithTypes() = constructor and o.getAnArgument().getValue() = value and not compilerGeneratedAttribute(container) } + +query predicate implicitConversionDefaults( + Parameterizable container, Parameter p, OperatorCall o, Expr e, string type, string value +) { + defaultValue(container, p, _, o) and + o.getAnArgument() = e and + type = e.getType().toString() and + value = e.getValue() +} From 7d801e05eefb3f5dab363934d4f1d1211d17d620 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 31 May 2023 13:08:20 +0200 Subject: [PATCH 213/739] add an example of using dollar eq --- .../Security/CWE-089/SqlInjection.inc.qhelp | 12 +++++++++-- .../CWE-089/examples/NoSqlInjectionFix.js | 8 ++----- .../CWE-089/examples/NoSqlInjectionFix2.js | 21 +++++++++++++++++++ 3 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix2.js diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp index 1d99428b718..a30569aaf2c 100644 --- a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp +++ b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp @@ -69,8 +69,16 @@ object, so this code is vulnerable to a NoSQL injection attack. <sample src="examples/NoSqlInjection.js" /> <p> -To fix this vulnerability, we can check that the user input is a -literal value and not a query object before using it in a query. +To fix this vulnerability we can use the <code>$eq</code> operator +to ensure that the user input is interpreted as a literal value +and not as a query object: +</p> + +<sample src="examples/NoSqlInjectionFix2.js" /> + +<p> +Alternatively check that the user input is a +literal value and not a query object before using it: </p> <sample src="examples/NoSqlInjectionFix.js" /> diff --git a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js index fe982168be1..83f7c255618 100644 --- a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js +++ b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js @@ -11,11 +11,7 @@ app.use(express.urlencoded({ extended: false })); app.delete("/api/delete", async (req, res) => { let id = req.body.id; - if (typeof id !== "string") { - res.status(400).json({ status: "error" }); - return; - } - await Todo.deleteOne({ _id: id }); // GOOD: id is guaranteed to be a string + await Todo.deleteOne({ _id: { $eq: id } }); // GOOD: using $eq operator for the comparison res.json({ status: "ok" }); -}); +}); \ No newline at end of file diff --git a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix2.js b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix2.js new file mode 100644 index 00000000000..fe982168be1 --- /dev/null +++ b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix2.js @@ -0,0 +1,21 @@ +const express = require("express"); +const mongoose = require("mongoose"); +const Todo = mongoose.model( + "Todo", + new mongoose.Schema({ text: { type: String } }, { timestamps: true }) +); + +const app = express(); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); + +app.delete("/api/delete", async (req, res) => { + let id = req.body.id; + if (typeof id !== "string") { + res.status(400).json({ status: "error" }); + return; + } + await Todo.deleteOne({ _id: id }); // GOOD: id is guaranteed to be a string + + res.json({ status: "ok" }); +}); From 98820780af90934baf54335aa428478c694c7496 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 31 May 2023 13:51:22 +0200 Subject: [PATCH 214/739] show how to use mysql.escape in the sql-injection qhelp --- .../src/Security/CWE-089/SqlInjection.inc.qhelp | 6 ++++++ .../Security/CWE-089/examples/SqlInjectionFix2.js | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix2.js diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp index a30569aaf2c..cdf090e6914 100644 --- a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp +++ b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp @@ -55,6 +55,12 @@ immune to injection attacks. </p> <sample src="examples/SqlInjectionFix.js" /> + +<p> +Alternatively, we can use a library like <code>sqlstring</code> to +escape the user input before embedding it into the query string: +</p> +<sample src="examples/SqlInjectionFix2.js" /> </example> <example> diff --git a/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix2.js b/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix2.js new file mode 100644 index 00000000000..843426cf732 --- /dev/null +++ b/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix2.js @@ -0,0 +1,15 @@ +const app = require("express")(), + pg = require("pg"), + SqlString = require('sqlstring'), + pool = new pg.Pool(config); + +app.get("search", function handler(req, res) { + // GOOD: the category is escaped using mysql.escape + var query1 = + "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + SqlString.escape(req.params.category) + + "' ORDER BY PRICE"; + pool.query(query1, [], function(err, results) { + // process results + }); +}); From 1e081058637d99a48f6714be43d891742995ee5c Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 31 May 2023 13:51:38 +0200 Subject: [PATCH 215/739] less duplicated headers in the sql-injection samples --- .../ql/src/Security/CWE-089/SqlInjection.inc.qhelp | 4 ++-- .../Security/CWE-089/examples/NoSqlInjectionFix.js | 11 ----------- .../Security/CWE-089/examples/NoSqlInjectionFix2.js | 11 ----------- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp index cdf090e6914..cdda5100ba3 100644 --- a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp +++ b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp @@ -80,14 +80,14 @@ to ensure that the user input is interpreted as a literal value and not as a query object: </p> -<sample src="examples/NoSqlInjectionFix2.js" /> +<sample src="examples/NoSqlInjectionFix.js" /> <p> Alternatively check that the user input is a literal value and not a query object before using it: </p> -<sample src="examples/NoSqlInjectionFix.js" /> +<sample src="examples/NoSqlInjectionFix2.js" /> </example> <references> diff --git a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js index 83f7c255618..b1a81344f46 100644 --- a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js +++ b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix.js @@ -1,14 +1,3 @@ -const express = require("express"); -const mongoose = require("mongoose"); -const Todo = mongoose.model( - "Todo", - new mongoose.Schema({ text: { type: String } }, { timestamps: true }) -); - -const app = express(); -app.use(express.json()); -app.use(express.urlencoded({ extended: false })); - app.delete("/api/delete", async (req, res) => { let id = req.body.id; await Todo.deleteOne({ _id: { $eq: id } }); // GOOD: using $eq operator for the comparison diff --git a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix2.js b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix2.js index fe982168be1..0063e73cdfd 100644 --- a/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix2.js +++ b/javascript/ql/src/Security/CWE-089/examples/NoSqlInjectionFix2.js @@ -1,14 +1,3 @@ -const express = require("express"); -const mongoose = require("mongoose"); -const Todo = mongoose.model( - "Todo", - new mongoose.Schema({ text: { type: String } }, { timestamps: true }) -); - -const app = express(); -app.use(express.json()); -app.use(express.urlencoded({ extended: false })); - app.delete("/api/delete", async (req, res) => { let id = req.body.id; if (typeof id !== "string") { From 52eb7aee5e8168e4fb95eda7f15f711dccf7d7d5 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 31 May 2023 11:26:09 -0700 Subject: [PATCH 216/739] Revert "Merge pull request #13207 from MathiasVP/use-equiv-class-in-getInstruction" This reverts commit 5bc844c4c643370d030edd1222e447c1d3954500, reversing changes made to b2fb2aa0d1f2d88acef53c6324caaa025c46f29e. --- .../ir/implementation/aliased_ssa/IRBlock.qll | 22 ++++--------------- .../cpp/ir/implementation/raw/IRBlock.qll | 22 ++++--------------- .../implementation/unaliased_ssa/IRBlock.qll | 22 ++++--------------- .../ir/implementation/raw/IRBlock.qll | 22 ++++--------------- .../implementation/unaliased_ssa/IRBlock.qll | 22 ++++--------------- 5 files changed, 20 insertions(+), 90 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll index 4de4279b54c..78008a6c69b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll @@ -255,28 +255,14 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Gets the index of `i` in its `IRBlock`. */ - private int getMemberIndex(Instruction i) { - startsBasicBlock(i) and - result = 0 - or - exists(Instruction iPrev | - adjacentInBlock(iPrev, i) and - result = getMemberIndex(iPrev) + 1 - ) - } - - private module BlockAdjacency = QlBuiltins::EquivalenceRelation<Instruction, adjacentInBlock/2>; + /** Holds if `i` is the `index`th instruction the block starting with `first`. */ + private Instruction getInstructionFromFirst(Instruction first, int index) = + shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | block = MkIRBlock(first) | - first = result and index = 0 - or - index = getMemberIndex(result) and - BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) - ) + result = getInstructionFromFirst(getFirstInstruction(block), index) } cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll index 4de4279b54c..78008a6c69b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll @@ -255,28 +255,14 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Gets the index of `i` in its `IRBlock`. */ - private int getMemberIndex(Instruction i) { - startsBasicBlock(i) and - result = 0 - or - exists(Instruction iPrev | - adjacentInBlock(iPrev, i) and - result = getMemberIndex(iPrev) + 1 - ) - } - - private module BlockAdjacency = QlBuiltins::EquivalenceRelation<Instruction, adjacentInBlock/2>; + /** Holds if `i` is the `index`th instruction the block starting with `first`. */ + private Instruction getInstructionFromFirst(Instruction first, int index) = + shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | block = MkIRBlock(first) | - first = result and index = 0 - or - index = getMemberIndex(result) and - BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) - ) + result = getInstructionFromFirst(getFirstInstruction(block), index) } cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll index 4de4279b54c..78008a6c69b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll @@ -255,28 +255,14 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Gets the index of `i` in its `IRBlock`. */ - private int getMemberIndex(Instruction i) { - startsBasicBlock(i) and - result = 0 - or - exists(Instruction iPrev | - adjacentInBlock(iPrev, i) and - result = getMemberIndex(iPrev) + 1 - ) - } - - private module BlockAdjacency = QlBuiltins::EquivalenceRelation<Instruction, adjacentInBlock/2>; + /** Holds if `i` is the `index`th instruction the block starting with `first`. */ + private Instruction getInstructionFromFirst(Instruction first, int index) = + shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | block = MkIRBlock(first) | - first = result and index = 0 - or - index = getMemberIndex(result) and - BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) - ) + result = getInstructionFromFirst(getFirstInstruction(block), index) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll index 4de4279b54c..78008a6c69b 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll @@ -255,28 +255,14 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Gets the index of `i` in its `IRBlock`. */ - private int getMemberIndex(Instruction i) { - startsBasicBlock(i) and - result = 0 - or - exists(Instruction iPrev | - adjacentInBlock(iPrev, i) and - result = getMemberIndex(iPrev) + 1 - ) - } - - private module BlockAdjacency = QlBuiltins::EquivalenceRelation<Instruction, adjacentInBlock/2>; + /** Holds if `i` is the `index`th instruction the block starting with `first`. */ + private Instruction getInstructionFromFirst(Instruction first, int index) = + shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | block = MkIRBlock(first) | - first = result and index = 0 - or - index = getMemberIndex(result) and - BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) - ) + result = getInstructionFromFirst(getFirstInstruction(block), index) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll index 4de4279b54c..78008a6c69b 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll @@ -255,28 +255,14 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Gets the index of `i` in its `IRBlock`. */ - private int getMemberIndex(Instruction i) { - startsBasicBlock(i) and - result = 0 - or - exists(Instruction iPrev | - adjacentInBlock(iPrev, i) and - result = getMemberIndex(iPrev) + 1 - ) - } - - private module BlockAdjacency = QlBuiltins::EquivalenceRelation<Instruction, adjacentInBlock/2>; + /** Holds if `i` is the `index`th instruction the block starting with `first`. */ + private Instruction getInstructionFromFirst(Instruction first, int index) = + shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - exists(Instruction first | block = MkIRBlock(first) | - first = result and index = 0 - or - index = getMemberIndex(result) and - BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) - ) + result = getInstructionFromFirst(getFirstInstruction(block), index) } cached From 0090429d5355797070c0839f854cda33dcce1fe1 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Wed, 24 May 2023 13:32:52 +0100 Subject: [PATCH 217/739] Kotlin: Support 1.9.0 --- docs/codeql/reusables/supported-versions-compilers.rst | 2 +- java/kotlin-extractor/kotlin_plugin_versions.py | 2 +- .../src/main/kotlin/KotlinFileExtractor.kt | 7 +++++-- java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md | 4 ++++ 4 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md diff --git a/docs/codeql/reusables/supported-versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst index 93b826a94dd..da873041fb9 100644 --- a/docs/codeql/reusables/supported-versions-compilers.rst +++ b/docs/codeql/reusables/supported-versions-compilers.rst @@ -20,7 +20,7 @@ Java,"Java 7 to 20 [4]_","javac (OpenJDK and Oracle JDK), Eclipse compiler for Java (ECJ) [5]_",``.java`` - Kotlin [6]_,"Kotlin 1.5.0 to 1.8.20","kotlinc",``.kt`` + Kotlin [6]_,"Kotlin 1.5.0 to 1.9.0","kotlinc",``.kt`` JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [7]_" Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11",Not applicable,``.py`` Ruby [9]_,"up to 3.2",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``" diff --git a/java/kotlin-extractor/kotlin_plugin_versions.py b/java/kotlin-extractor/kotlin_plugin_versions.py index 4583551e12d..c5d9e433613 100755 --- a/java/kotlin-extractor/kotlin_plugin_versions.py +++ b/java/kotlin-extractor/kotlin_plugin_versions.py @@ -25,7 +25,7 @@ def version_string_to_tuple(version): ci_version = '1.8.10' # Version numbers in the list need to be in semantically increasing order -many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20', '1.8.0' ] +many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20', '1.8.0', '1.9.0-Beta' ] many_versions_tuples = [version_string_to_tuple(v) for v in many_versions] diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index b93bfa369f5..a3bc20d9eda 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -366,7 +366,10 @@ open class KotlinFileExtractor( val typeArgs = removeOuterClassTypeArgs(c, argsIncludingOuterClasses) if (typeArgs != null) { - for ((idx, arg) in typeArgs.withIndex()) { + // From 1.9, the list might change when we call erase, + // so we make a copy that it is safe to iterate over. + val typeArgsCopy = typeArgs.toList() + for ((idx, arg) in typeArgsCopy.withIndex()) { val argId = getTypeArgumentLabel(arg).id tw.writeTypeArgs(argId, idx, id) } @@ -5531,7 +5534,7 @@ open class KotlinFileExtractor( return } - val typeOwner = e.typeOperandClassifier.owner + val typeOwner = e.typeOperand.classifierOrFail.owner if (typeOwner !is IrClass) { logger.errorElement("Expected to find SAM conversion to IrClass. Found '${typeOwner.javaClass}' instead. Can't implement SAM interface.", e) return diff --git a/java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md b/java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md new file mode 100644 index 00000000000..f3647cc5488 --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Kotlin versions up to 1.9.0 are now supported. From a13678c35ca56ac1ab7daecd26d55ddf0a0deb6e Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Thu, 25 May 2023 14:06:58 +0100 Subject: [PATCH 218/739] Kotlin: Update expected test output --- .../diagnostics/kotlin-version-too-new/diagnostics.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/diagnostics.expected b/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/diagnostics.expected index 3397ea1bdef..36f7d9d0718 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/diagnostics.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/diagnostics.expected @@ -1,5 +1,5 @@ { - "markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 1.8.30.", + "markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 1.9.10.", "severity": "error", "source": { "extractorName": "java", From 82578af3498e385d5f549997b796448e3359e63e Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Wed, 31 May 2023 12:56:29 +0100 Subject: [PATCH 219/739] Kotlin: Use @files for compiler arguments Avoids problems with large line lengths. --- java/kotlin-extractor/build.py | 40 ++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index b52ff05b00e..2735f6af1c1 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -80,25 +80,37 @@ def run_process(cmd, capture_output=False): errors='replace'), file=sys.stderr) raise e +def write_arg_file(arg_file, args): + with open(arg_file, 'w') as f: + for arg in args: + if "'" in arg: + raise Exception('Single quote in argument: ' + arg) + f.write("'" + arg.replace('\\', '/') + "'\n") -def compile_to_dir(srcs, classpath, java_classpath, output): +def compile_to_dir(build_dir, srcs, classpath, java_classpath, output): # Use kotlinc to compile .kt files: + kotlin_arg_file = build_dir + '/kotlin.args' + kotlin_args = ['-Werror', + '-opt-in=kotlin.RequiresOptIn', + '-d', output, + '-module-name', 'codeql-kotlin-extractor', + '-no-reflect', '-no-stdlib', + '-jvm-target', '1.8', + '-classpath', classpath] + srcs + write_arg_file(kotlin_arg_file, kotlin_args) run_process([kotlinc, - # kotlinc can default to 256M, which isn't enough when we are extracting the build - '-J-Xmx2G', - '-Werror', - '-opt-in=kotlin.RequiresOptIn', - '-d', output, - '-module-name', 'codeql-kotlin-extractor', - '-no-reflect', '-no-stdlib', - '-jvm-target', '1.8', - '-classpath', classpath] + srcs) + # kotlinc can default to 256M, which isn't enough when we are extracting the build + '-J-Xmx2G', + '@' + kotlin_arg_file]) # Use javac to compile .java files, referencing the Kotlin class files: - run_process([javac, - '-d', output, + java_arg_file = build_dir + '/java.args' + java_args = ['-d', output, '-source', '8', '-target', '8', - '-classpath', os.path.pathsep.join([output, classpath, java_classpath])] + [s for s in srcs if s.endswith(".java")]) + '-classpath', os.path.pathsep.join([output, classpath, java_classpath])] \ + + [s for s in srcs if s.endswith(".java")] + write_arg_file(java_arg_file, java_args) + run_process([javac, '@' + java_arg_file]) def compile_to_jar(build_dir, tmp_src_dir, srcs, classpath, java_classpath, output): @@ -108,7 +120,7 @@ def compile_to_jar(build_dir, tmp_src_dir, srcs, classpath, java_classpath, outp shutil.rmtree(class_dir) os.makedirs(class_dir) - compile_to_dir(srcs, classpath, java_classpath, class_dir) + compile_to_dir(build_dir, srcs, classpath, java_classpath, class_dir) run_process(['jar', 'cf', output, '-C', class_dir, '.', From d24d8b16266a1758d8e5ff86e7566865b5b02826 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 11:56:45 -0400 Subject: [PATCH 220/739] Java: update sql sink kind to sql-injection --- java/ql/lib/ext/android.content.model.yml | 16 +-- java/ql/lib/ext/android.database.model.yml | 14 +-- .../lib/ext/android.database.sqlite.model.yml | 104 +++++++++--------- java/ql/lib/ext/java.sql.model.yml | 18 +-- ...apache.hadoop.hive.metastore.api.model.yml | 3 +- ...org.apache.hadoop.hive.metastore.model.yml | 5 +- ...g.apache.hive.hcatalog.templeton.model.yml | 3 +- .../lib/ext/org.apache.ibatis.jdbc.model.yml | 12 +- java/ql/lib/ext/org.hibernate.model.yml | 8 +- java/ql/lib/ext/org.hibernate.query.model.yml | 6 +- java/ql/lib/ext/org.jooq.model.yml | 2 +- .../org.springframework.jdbc.core.model.yml | 20 ++-- .../org.springframework.jdbc.object.model.yml | 18 +-- .../code/java/dataflow/ExternalFlow.qll | 10 +- .../code/java/security/QueryInjection.qll | 2 +- 15 files changed, 119 insertions(+), 122 deletions(-) diff --git a/java/ql/lib/ext/android.content.model.yml b/java/ql/lib/ext/android.content.model.yml index 89368acc04e..bee6bae8d44 100644 --- a/java/ql/lib/ext/android.content.model.yml +++ b/java/ql/lib/ext/android.content.model.yml @@ -39,14 +39,14 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["android.content", "ContentProvider", True, "delete", "(Uri,String,String[])", "", "Argument[1]", "sql", "manual"] - - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql", "manual"] - - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] - - ["android.content", "ContentProvider", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] - - ["android.content", "ContentResolver", True, "delete", "(Uri,String,String[])", "", "Argument[1]", "sql", "manual"] - - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql", "manual"] - - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] - - ["android.content", "ContentResolver", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - ["android.content", "ContentProvider", True, "delete", "(Uri,String,String[])", "", "Argument[1]", "sql-injection", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.content", "ContentProvider", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.content", "ContentProvider", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql-injection", "manual"] + - ["android.content", "ContentResolver", True, "delete", "(Uri,String,String[])", "", "Argument[1]", "sql-injection", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.content", "ContentResolver", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql-injection", "manual"] - ["android.content", "Context", True, "sendBroadcast", "", "", "Argument[0]", "intent-start", "manual"] - ["android.content", "Context", True, "sendBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] - ["android.content", "Context", True, "sendBroadcastWithMultiplePermissions", "", "", "Argument[0]", "intent-start", "manual"] diff --git a/java/ql/lib/ext/android.database.model.yml b/java/ql/lib/ext/android.database.model.yml index 22157da6755..c0ff4dd5f39 100644 --- a/java/ql/lib/ext/android.database.model.yml +++ b/java/ql/lib/ext/android.database.model.yml @@ -3,13 +3,13 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["android.database", "DatabaseUtils", False, "blobFileDescriptorForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] - - ["android.database", "DatabaseUtils", False, "createDbFromSqlStatements", "(Context,String,int,String)", "", "Argument[3]", "sql", "manual"] - - ["android.database", "DatabaseUtils", False, "longForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] - - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String)", "", "Argument[1]", "sql", "manual"] - - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String,String)", "", "Argument[1..2]", "sql", "manual"] - - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String,String,String[])", "", "Argument[1..2]", "sql", "manual"] - - ["android.database", "DatabaseUtils", False, "stringForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] + - ["android.database", "DatabaseUtils", False, "blobFileDescriptorForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database", "DatabaseUtils", False, "createDbFromSqlStatements", "(Context,String,int,String)", "", "Argument[3]", "sql-injection", "manual"] + - ["android.database", "DatabaseUtils", False, "longForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String,String)", "", "Argument[1..2]", "sql-injection", "manual"] + - ["android.database", "DatabaseUtils", False, "queryNumEntries", "(SQLiteDatabase,String,String,String[])", "", "Argument[1..2]", "sql-injection", "manual"] + - ["android.database", "DatabaseUtils", False, "stringForQuery", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/android.database.sqlite.model.yml b/java/ql/lib/ext/android.database.sqlite.model.yml index 169c7870da4..d40ae8c1ee3 100644 --- a/java/ql/lib/ext/android.database.sqlite.model.yml +++ b/java/ql/lib/ext/android.database.sqlite.model.yml @@ -3,58 +3,58 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["android.database.sqlite", "SQLiteDatabase", False, "compileStatement", "(String)", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "delete", "(String,String,String[])", "", "Argument[0..1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "execPerConnectionSQL", "(String,Object[])", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "execSQL", "(String)", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "execSQL", "(String,Object[])", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String)", "", "Argument[0..2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String)", "", "Argument[4..6]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[4..7]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[3]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[5..8]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[3]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[5..8]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[3]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[4]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[6..9]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[3]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[4]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[6..9]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "rawQuery", "(String,String[])", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "rawQuery", "(String,String[],CancellationSignal)", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "rawQueryWithFactory", "(CursorFactory,String,String[],String)", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "rawQueryWithFactory", "(CursorFactory,String,String[],String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "update", "(String,ContentValues,String,String[])", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "update", "(String,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "updateWithOnConflict", "(String,ContentValues,String,String[],int)", "", "Argument[0]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteDatabase", False, "updateWithOnConflict", "(String,ContentValues,String,String[],int)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "delete", "(SQLiteDatabase,String,String[])", "", "Argument[this]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "delete", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "insert", "(SQLiteDatabase,ContentValues)", "", "Argument[this]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[this]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[4..6]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[this]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[4..7]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[this]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[1]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[4..7]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "update", "(SQLiteDatabase,ContentValues,String,String[])", "", "Argument[this]", "sql", "manual"] - - ["android.database.sqlite", "SQLiteQueryBuilder", True, "update", "(SQLiteDatabase,ContentValues,String,String[])", "", "Argument[2]", "sql", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "compileStatement", "(String)", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "delete", "(String,String,String[])", "", "Argument[0..1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execPerConnectionSQL", "(String,Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execSQL", "(String)", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "execSQL", "(String,Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String)", "", "Argument[0..2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String)", "", "Argument[4..6]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(String,String[],String,String[],String,String,String,String)", "", "Argument[4..7]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[3]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[5..8]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[3]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "query", "(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[5..8]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[3]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[4]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String)", "", "Argument[6..9]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[3]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[4]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "queryWithFactory", "(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[6..9]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQuery", "(String,String[])", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQuery", "(String,String[],CancellationSignal)", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQueryWithFactory", "(CursorFactory,String,String[],String)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "rawQueryWithFactory", "(CursorFactory,String,String[],String,CancellationSignal)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "update", "(String,ContentValues,String,String[])", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "update", "(String,ContentValues,String,String[])", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "updateWithOnConflict", "(String,ContentValues,String,String[],int)", "", "Argument[0]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteDatabase", False, "updateWithOnConflict", "(String,ContentValues,String,String[],int)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "delete", "(SQLiteDatabase,String,String[])", "", "Argument[this]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "delete", "(SQLiteDatabase,String,String[])", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "insert", "(SQLiteDatabase,ContentValues)", "", "Argument[this]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[this]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String)", "", "Argument[4..6]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[this]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String)", "", "Argument[4..7]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[this]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[1]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[2]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "query", "(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal)", "", "Argument[4..7]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "update", "(SQLiteDatabase,ContentValues,String,String[])", "", "Argument[this]", "sql-injection", "manual"] + - ["android.database.sqlite", "SQLiteQueryBuilder", True, "update", "(SQLiteDatabase,ContentValues,String,String[])", "", "Argument[2]", "sql-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index 87e0fca7f9b..ec0aa84fd21 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -3,19 +3,19 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.sql", "Connection", True, "prepareCall", "", "", "Argument[0]", "sql", "manual"] - - ["java.sql", "Connection", True, "prepareStatement", "", "", "Argument[0]", "sql", "manual"] - - ["java.sql", "DatabaseMetaData", True, "getColumns", "(String,String,String,String)", "", "Argument[2]", "sql", "ai-manual"] - - ["java.sql", "DatabaseMetaData", True, "getPrimaryKeys", "(String,String,String)", "", "Argument[2]", "sql", "ai-manual"] + - ["java.sql", "Connection", True, "prepareCall", "", "", "Argument[0]", "sql-injection", "manual"] + - ["java.sql", "Connection", True, "prepareStatement", "", "", "Argument[0]", "sql-injection", "manual"] + - ["java.sql", "DatabaseMetaData", True, "getColumns", "(String,String,String,String)", "", "Argument[2]", "sql-injection", "ai-manual"] + - ["java.sql", "DatabaseMetaData", True, "getPrimaryKeys", "(String,String,String)", "", "Argument[2]", "sql-injection", "ai-manual"] - ["java.sql", "Driver", False, "connect", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] - ["java.sql", "DriverManager", False, "getConnection", "(String)", "", "Argument[0]", "jdbc-url", "manual"] - ["java.sql", "DriverManager", False, "getConnection", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] - ["java.sql", "DriverManager", False, "getConnection", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] - - ["java.sql", "Statement", True, "addBatch", "", "", "Argument[0]", "sql", "manual"] - - ["java.sql", "Statement", True, "execute", "", "", "Argument[0]", "sql", "manual"] - - ["java.sql", "Statement", True, "executeLargeUpdate", "", "", "Argument[0]", "sql", "manual"] - - ["java.sql", "Statement", True, "executeQuery", "", "", "Argument[0]", "sql", "manual"] - - ["java.sql", "Statement", True, "executeUpdate", "", "", "Argument[0]", "sql", "manual"] + - ["java.sql", "Statement", True, "addBatch", "", "", "Argument[0]", "sql-injection", "manual"] + - ["java.sql", "Statement", True, "execute", "", "", "Argument[0]", "sql-injection", "manual"] + - ["java.sql", "Statement", True, "executeLargeUpdate", "", "", "Argument[0]", "sql-injection", "manual"] + - ["java.sql", "Statement", True, "executeQuery", "", "", "Argument[0]", "sql-injection", "manual"] + - ["java.sql", "Statement", True, "executeUpdate", "", "", "Argument[0]", "sql-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.apache.hadoop.hive.metastore.api.model.yml b/java/ql/lib/ext/org.apache.hadoop.hive.metastore.api.model.yml index 9189c6ab1fd..60d2d0c0153 100644 --- a/java/ql/lib/ext/org.apache.hadoop.hive.metastore.api.model.yml +++ b/java/ql/lib/ext/org.apache.hadoop.hive.metastore.api.model.yml @@ -3,5 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hadoop.hive.metastore.api", "DefaultConstraintsRequest", True, "DefaultConstraintsRequest", "(String,String,String)", "", "Argument[1]", "sql", "ai-manual"] - + - ["org.apache.hadoop.hive.metastore.api", "DefaultConstraintsRequest", True, "DefaultConstraintsRequest", "(String,String,String)", "", "Argument[1]", "sql-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.apache.hadoop.hive.metastore.model.yml b/java/ql/lib/ext/org.apache.hadoop.hive.metastore.model.yml index da335795194..bc902f548fd 100644 --- a/java/ql/lib/ext/org.apache.hadoop.hive.metastore.model.yml +++ b/java/ql/lib/ext/org.apache.hadoop.hive.metastore.model.yml @@ -3,6 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hadoop.hive.metastore", "ObjectStore", True, "updatePartitionColumnStatistics", "(ColumnStatistics,List,String,long)", "", "Argument[0]", "sql", "ai-manual"] - - ["org.apache.hadoop.hive.metastore", "ObjectStore", True, "updatePartitionColumnStatistics", "(ColumnStatistics,List)", "", "Argument[0]", "sql", "ai-manual"] - + - ["org.apache.hadoop.hive.metastore", "ObjectStore", True, "updatePartitionColumnStatistics", "(ColumnStatistics,List,String,long)", "", "Argument[0]", "sql-injection", "ai-manual"] + - ["org.apache.hadoop.hive.metastore", "ObjectStore", True, "updatePartitionColumnStatistics", "(ColumnStatistics,List)", "", "Argument[0]", "sql-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.apache.hive.hcatalog.templeton.model.yml b/java/ql/lib/ext/org.apache.hive.hcatalog.templeton.model.yml index 3f980bdbb3f..35c0e9f27a3 100644 --- a/java/ql/lib/ext/org.apache.hive.hcatalog.templeton.model.yml +++ b/java/ql/lib/ext/org.apache.hive.hcatalog.templeton.model.yml @@ -3,5 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hive.hcatalog.templeton", "HcatDelegator", True, "addOneColumn", "(String,String,String,ColumnDesc)", "", "Argument[3]", "sql", "ai-manual"] - + - ["org.apache.hive.hcatalog.templeton", "HcatDelegator", True, "addOneColumn", "(String,String,String,ColumnDesc)", "", "Argument[3]", "sql-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml b/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml index e966d7bd735..e1b37b8f851 100644 --- a/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml +++ b/java/ql/lib/ext/org.apache.ibatis.jdbc.model.yml @@ -3,12 +3,12 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.ibatis.jdbc", "SqlRunner", False, "delete", "(String,Object[])", "", "Argument[0]", "sql", "manual"] - - ["org.apache.ibatis.jdbc", "SqlRunner", False, "insert", "(String,Object[])", "", "Argument[0]", "sql", "manual"] - - ["org.apache.ibatis.jdbc", "SqlRunner", False, "run", "(String)", "", "Argument[0]", "sql", "manual"] - - ["org.apache.ibatis.jdbc", "SqlRunner", False, "selectAll", "(String,Object[])", "", "Argument[0]", "sql", "manual"] - - ["org.apache.ibatis.jdbc", "SqlRunner", False, "selectOne", "(String,Object[])", "", "Argument[0]", "sql", "manual"] - - ["org.apache.ibatis.jdbc", "SqlRunner", False, "update", "(String,Object[])", "", "Argument[0]", "sql", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "delete", "(String,Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "insert", "(String,Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "run", "(String)", "", "Argument[0]", "sql-injection", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "selectAll", "(String,Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "selectOne", "(String,Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["org.apache.ibatis.jdbc", "SqlRunner", False, "update", "(String,Object[])", "", "Argument[0]", "sql-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.hibernate.model.yml b/java/ql/lib/ext/org.hibernate.model.yml index ffa483ec742..c6a18bb1350 100644 --- a/java/ql/lib/ext/org.hibernate.model.yml +++ b/java/ql/lib/ext/org.hibernate.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.hibernate", "Session", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] - - ["org.hibernate", "Session", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] - - ["org.hibernate", "SharedSessionContract", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] - - ["org.hibernate", "SharedSessionContract", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate", "Session", True, "createQuery", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.hibernate", "Session", True, "createSQLQuery", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.hibernate", "SharedSessionContract", True, "createQuery", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.hibernate", "SharedSessionContract", True, "createSQLQuery", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/java/ql/lib/ext/org.hibernate.query.model.yml b/java/ql/lib/ext/org.hibernate.query.model.yml index 6281a33caa5..bb6232c1fcd 100644 --- a/java/ql/lib/ext/org.hibernate.query.model.yml +++ b/java/ql/lib/ext/org.hibernate.query.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.hibernate.query", "QueryProducer", True, "createNativeQuery", "", "", "Argument[0]", "sql", "manual"] - - ["org.hibernate.query", "QueryProducer", True, "createQuery", "", "", "Argument[0]", "sql", "manual"] - - ["org.hibernate.query", "QueryProducer", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"] + - ["org.hibernate.query", "QueryProducer", True, "createNativeQuery", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.hibernate.query", "QueryProducer", True, "createQuery", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.hibernate.query", "QueryProducer", True, "createSQLQuery", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/java/ql/lib/ext/org.jooq.model.yml b/java/ql/lib/ext/org.jooq.model.yml index cf7fc22a923..b7538263a31 100644 --- a/java/ql/lib/ext/org.jooq.model.yml +++ b/java/ql/lib/ext/org.jooq.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.jooq", "PlainSQL", False, "", "", "Annotated", "Argument[0]", "sql", "manual"] + - ["org.jooq", "PlainSQL", False, "", "", "Annotated", "Argument[0]", "sql-injection", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jdbc.core.model.yml b/java/ql/lib/ext/org.springframework.jdbc.core.model.yml index 9374293d0bb..38d91bb3090 100644 --- a/java/ql/lib/ext/org.springframework.jdbc.core.model.yml +++ b/java/ql/lib/ext/org.springframework.jdbc.core.model.yml @@ -3,13 +3,13 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "batchUpdate", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "batchUpdate", "(String[])", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "execute", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "query", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForList", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForMap", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForObject", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForRowSet", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForStream", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core", "JdbcTemplate", False, "update", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "batchUpdate", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "batchUpdate", "(String[])", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "execute", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForList", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForMap", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForObject", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForRowSet", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "queryForStream", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core", "JdbcTemplate", False, "update", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/java/ql/lib/ext/org.springframework.jdbc.object.model.yml b/java/ql/lib/ext/org.springframework.jdbc.object.model.yml index 413e29e2631..192e9263f0a 100644 --- a/java/ql/lib/ext/org.springframework.jdbc.object.model.yml +++ b/java/ql/lib/ext/org.springframework.jdbc.object.model.yml @@ -3,12 +3,12 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.jdbc.object", "BatchSqlUpdate", False, "BatchSqlUpdate", "", "", "Argument[1]", "sql", "manual"] - - ["org.springframework.jdbc.object", "MappingSqlQuery", False, "MappingSqlQuery", "", "", "Argument[1]", "sql", "manual"] - - ["org.springframework.jdbc.object", "MappingSqlQueryWithParameters", False, "MappingSqlQueryWithParameters", "", "", "Argument[1]", "sql", "manual"] - - ["org.springframework.jdbc.object", "RdbmsOperation", True, "setSql", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.object", "SqlCall", False, "SqlCall", "", "", "Argument[1]", "sql", "manual"] - - ["org.springframework.jdbc.object", "SqlFunction", False, "SqlFunction", "", "", "Argument[1]", "sql", "manual"] - - ["org.springframework.jdbc.object", "SqlQuery", False, "SqlQuery", "", "", "Argument[1]", "sql", "manual"] - - ["org.springframework.jdbc.object", "SqlUpdate", False, "SqlUpdate", "", "", "Argument[1]", "sql", "manual"] - - ["org.springframework.jdbc.object", "UpdatableSqlQuery", False, "UpdatableSqlQuery", "", "", "Argument[1]", "sql", "manual"] + - ["org.springframework.jdbc.object", "BatchSqlUpdate", False, "BatchSqlUpdate", "", "", "Argument[1]", "sql-injection", "manual"] + - ["org.springframework.jdbc.object", "MappingSqlQuery", False, "MappingSqlQuery", "", "", "Argument[1]", "sql-injection", "manual"] + - ["org.springframework.jdbc.object", "MappingSqlQueryWithParameters", False, "MappingSqlQueryWithParameters", "", "", "Argument[1]", "sql-injection", "manual"] + - ["org.springframework.jdbc.object", "RdbmsOperation", True, "setSql", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.object", "SqlCall", False, "SqlCall", "", "", "Argument[1]", "sql-injection", "manual"] + - ["org.springframework.jdbc.object", "SqlFunction", False, "SqlFunction", "", "", "Argument[1]", "sql-injection", "manual"] + - ["org.springframework.jdbc.object", "SqlQuery", False, "SqlQuery", "", "", "Argument[1]", "sql-injection", "manual"] + - ["org.springframework.jdbc.object", "SqlUpdate", False, "SqlUpdate", "", "", "Argument[1]", "sql-injection", "manual"] + - ["org.springframework.jdbc.object", "UpdatableSqlQuery", False, "UpdatableSqlQuery", "", "", "Argument[1]", "sql-injection", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 4cb21496f5f..d511d4da293 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -274,11 +274,11 @@ module ModelValidation { exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind = [ - "open-url", "jndi-injection", "ldap", "sql", "jdbc-url", "logging", "mvel", "xpath", - "groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-redirect", - "create-file", "read-file", "write-file", "set-hostname-verifier", "header-splitting", - "information-leak", "xslt", "jexl", "bean-validation", "ssti", "fragment-injection", - "command-injection" + "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "logging", "mvel", + "xpath", "groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", + "url-redirect", "create-file", "read-file", "write-file", "set-hostname-verifier", + "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "ssti", + "fragment-injection", "command-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and diff --git a/java/ql/lib/semmle/code/java/security/QueryInjection.qll b/java/ql/lib/semmle/code/java/security/QueryInjection.qll index fda91647bcd..217d80bf170 100644 --- a/java/ql/lib/semmle/code/java/security/QueryInjection.qll +++ b/java/ql/lib/semmle/code/java/security/QueryInjection.qll @@ -25,7 +25,7 @@ class AdditionalQueryInjectionTaintStep extends Unit { /** A sink for SQL injection vulnerabilities. */ private class SqlInjectionSink extends QueryInjectionSink { - SqlInjectionSink() { sinkNode(this, "sql") } + SqlInjectionSink() { sinkNode(this, "sql-injection") } } /** A sink for Java Persistence Query Language injection vulnerabilities. */ From 55be2e5b6766b8e21d5d05753ddeccd47075289a Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 11:58:07 -0400 Subject: [PATCH 221/739] Java: update url-redirect sink kind to url-redirection --- java/ql/lib/ext/jakarta.ws.rs.core.model.yml | 4 ++-- java/ql/lib/ext/javax.ws.rs.core.model.yml | 4 ++-- java/ql/lib/ext/org.geogebra.web.full.main.model.yml | 2 +- java/ql/lib/ext/org.kohsuke.stapler.model.yml | 2 +- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- java/ql/lib/semmle/code/java/security/UrlRedirect.qll | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/java/ql/lib/ext/jakarta.ws.rs.core.model.yml b/java/ql/lib/ext/jakarta.ws.rs.core.model.yml index a13bb2189d1..739f61df8b8 100644 --- a/java/ql/lib/ext/jakarta.ws.rs.core.model.yml +++ b/java/ql/lib/ext/jakarta.ws.rs.core.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["jakarta.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirect", "manual"] - - ["jakarta.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirect", "manual"] + - ["jakarta.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirection", "manual"] + - ["jakarta.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/javax.ws.rs.core.model.yml b/java/ql/lib/ext/javax.ws.rs.core.model.yml index b73078a5ae5..cf94b255176 100644 --- a/java/ql/lib/ext/javax.ws.rs.core.model.yml +++ b/java/ql/lib/ext/javax.ws.rs.core.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirect", "manual"] - - ["javax.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirect", "manual"] + - ["javax.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirection", "manual"] + - ["javax.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirection", "manual"] - ["javax.ws.rs.core", "ResponseBuilder", False, "header", "", "", "Argument[1]", "header-splitting", "manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/org.geogebra.web.full.main.model.yml b/java/ql/lib/ext/org.geogebra.web.full.main.model.yml index c6719b6a97e..914a60fe38a 100644 --- a/java/ql/lib/ext/org.geogebra.web.full.main.model.yml +++ b/java/ql/lib/ext/org.geogebra.web.full.main.model.yml @@ -4,4 +4,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.geogebra.web.full.main", "FileManager", True, "open", "(String,String)", "", "Argument[0]", "url-redirect", "ai-manual"] + - ["org.geogebra.web.full.main", "FileManager", True, "open", "(String,String)", "", "Argument[0]", "url-redirection", "ai-manual"] diff --git a/java/ql/lib/ext/org.kohsuke.stapler.model.yml b/java/ql/lib/ext/org.kohsuke.stapler.model.yml index a3ae44a683b..7b6dea2e669 100644 --- a/java/ql/lib/ext/org.kohsuke.stapler.model.yml +++ b/java/ql/lib/ext/org.kohsuke.stapler.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(String)", "", "Argument[0]", "url-redirect", "ai-manual"] + - ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(String)", "", "Argument[0]", "url-redirection", "ai-manual"] - ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL)", "", "Argument[0]", "open-url", "ai-manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index d511d4da293..48725115430 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -276,7 +276,7 @@ module ModelValidation { [ "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "logging", "mvel", "xpath", "groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", - "url-redirect", "create-file", "read-file", "write-file", "set-hostname-verifier", + "url-redirection", "create-file", "read-file", "write-file", "set-hostname-verifier", "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "ssti", "fragment-injection", "command-injection" ] and diff --git a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll index f4fc862ab53..fdd09fe8957 100644 --- a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll +++ b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll @@ -12,7 +12,7 @@ abstract class UrlRedirectSink extends DataFlow::Node { } /** A default sink represeting methods susceptible to URL redirection attacks. */ private class DefaultUrlRedirectSink extends UrlRedirectSink { - DefaultUrlRedirectSink() { sinkNode(this, "url-redirect") } + DefaultUrlRedirectSink() { sinkNode(this, "url-redirection") } } /** A Servlet URL redirection sink. */ From fc58d10a4e843564121391a340c4f104e7d5c3d1 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:00:28 -0400 Subject: [PATCH 222/739] Java: update xpath sink kind to xpath-injection --- java/ql/lib/ext/javax.xml.xpath.model.yml | 6 ++-- java/ql/lib/ext/org.dom4j.model.yml | 30 +++++++++---------- java/ql/lib/ext/org.dom4j.tree.model.yml | 4 +-- java/ql/lib/ext/org.dom4j.util.model.yml | 6 ++-- .../code/java/dataflow/ExternalFlow.qll | 8 ++--- .../lib/semmle/code/java/security/XPath.qll | 2 +- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/java/ql/lib/ext/javax.xml.xpath.model.yml b/java/ql/lib/ext/javax.xml.xpath.model.yml index 68f51a34a2e..6cad83433b6 100644 --- a/java/ql/lib/ext/javax.xml.xpath.model.yml +++ b/java/ql/lib/ext/javax.xml.xpath.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.xml.xpath", "XPath", True, "compile", "", "", "Argument[0]", "xpath", "manual"] - - ["javax.xml.xpath", "XPath", True, "evaluate", "", "", "Argument[0]", "xpath", "manual"] - - ["javax.xml.xpath", "XPath", True, "evaluateExpression", "", "", "Argument[0]", "xpath", "manual"] + - ["javax.xml.xpath", "XPath", True, "compile", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["javax.xml.xpath", "XPath", True, "evaluate", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["javax.xml.xpath", "XPath", True, "evaluateExpression", "", "", "Argument[0]", "xpath-injection", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.model.yml b/java/ql/lib/ext/org.dom4j.model.yml index b2e5c2ed379..f54c817d966 100644 --- a/java/ql/lib/ext/org.dom4j.model.yml +++ b/java/ql/lib/ext/org.dom4j.model.yml @@ -3,18 +3,18 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.dom4j", "DocumentFactory", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "DocumentFactory", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "DocumentFactory", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "DocumentHelper", False, "createPattern", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "DocumentHelper", False, "createXPath", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "DocumentHelper", False, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "DocumentHelper", False, "selectNodes", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "DocumentHelper", False, "sort", "", "", "Argument[1]", "xpath", "manual"] - - ["org.dom4j", "Node", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "Node", True, "matches", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "Node", True, "numberValueOf", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "Node", True, "selectNodes", "", "", "Argument[0..1]", "xpath", "manual"] - - ["org.dom4j", "Node", True, "selectObject", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "Node", True, "selectSingleNode", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j", "Node", True, "valueOf", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j", "DocumentFactory", True, "createPattern", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "DocumentFactory", True, "createXPath", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "DocumentFactory", True, "createXPathFilter", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createPattern", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createXPath", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "DocumentHelper", False, "createXPathFilter", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "DocumentHelper", False, "selectNodes", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "DocumentHelper", False, "sort", "", "", "Argument[1]", "xpath-injection", "manual"] + - ["org.dom4j", "Node", True, "createXPath", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "Node", True, "matches", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "Node", True, "numberValueOf", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "Node", True, "selectNodes", "", "", "Argument[0..1]", "xpath-injection", "manual"] + - ["org.dom4j", "Node", True, "selectObject", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "Node", True, "selectSingleNode", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j", "Node", True, "valueOf", "", "", "Argument[0]", "xpath-injection", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.tree.model.yml b/java/ql/lib/ext/org.dom4j.tree.model.yml index 0896937bb16..3117806aa6e 100644 --- a/java/ql/lib/ext/org.dom4j.tree.model.yml +++ b/java/ql/lib/ext/org.dom4j.tree.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.dom4j.tree", "AbstractNode", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j.tree", "AbstractNode", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j.tree", "AbstractNode", True, "createPattern", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j.tree", "AbstractNode", True, "createXPathFilter", "", "", "Argument[0]", "xpath-injection", "manual"] diff --git a/java/ql/lib/ext/org.dom4j.util.model.yml b/java/ql/lib/ext/org.dom4j.util.model.yml index d7dc55cd145..530652f2ede 100644 --- a/java/ql/lib/ext/org.dom4j.util.model.yml +++ b/java/ql/lib/ext/org.dom4j.util.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.dom4j.util", "ProxyDocumentFactory", True, "createPattern", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j.util", "ProxyDocumentFactory", True, "createXPath", "", "", "Argument[0]", "xpath", "manual"] - - ["org.dom4j.util", "ProxyDocumentFactory", True, "createXPathFilter", "", "", "Argument[0]", "xpath", "manual"] + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createPattern", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createXPath", "", "", "Argument[0]", "xpath-injection", "manual"] + - ["org.dom4j.util", "ProxyDocumentFactory", True, "createXPathFilter", "", "", "Argument[0]", "xpath-injection", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 48725115430..b61aa86f3d5 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -275,10 +275,10 @@ module ModelValidation { not kind = [ "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "logging", "mvel", - "xpath", "groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", - "url-redirection", "create-file", "read-file", "write-file", "set-hostname-verifier", - "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "ssti", - "fragment-injection", "command-injection" + "xpath-injection", "groovy", "xss", "ognl-injection", "intent-start", + "pending-intent-sent", "url-redirection", "create-file", "read-file", "write-file", + "set-hostname-verifier", "header-splitting", "information-leak", "xslt", "jexl", + "bean-validation", "ssti", "fragment-injection", "command-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and diff --git a/java/ql/lib/semmle/code/java/security/XPath.qll b/java/ql/lib/semmle/code/java/security/XPath.qll index c8b1077990d..573d6530b33 100644 --- a/java/ql/lib/semmle/code/java/security/XPath.qll +++ b/java/ql/lib/semmle/code/java/security/XPath.qll @@ -13,7 +13,7 @@ abstract class XPathInjectionSink extends DataFlow::Node { } /** A default sink representing methods susceptible to XPath Injection attacks. */ private class DefaultXPathInjectionSink extends XPathInjectionSink { DefaultXPathInjectionSink() { - sinkNode(this, "xpath") + sinkNode(this, "xpath-injection") or exists(ClassInstanceExpr constructor | constructor.getConstructedType().getASourceSupertype*().hasQualifiedName("org.dom4j", "XPath") From 8c4b394e1ab231f070ea05067593dd9fee864c02 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:01:24 -0400 Subject: [PATCH 223/739] Java: update ssti sink kind to template-injection --- java/ql/lib/ext/com.hubspot.jinjava.model.yml | 4 ++-- .../lib/ext/com.mitchellbosecke.pebble.model.yml | 4 ++-- java/ql/lib/ext/freemarker.cache.model.yml | 2 +- java/ql/lib/ext/freemarker.template.model.yml | 14 +++++++------- java/ql/lib/ext/org.apache.velocity.app.model.yml | 8 ++++---- .../lib/ext/org.apache.velocity.runtime.model.yml | 6 +++--- ...apache.velocity.runtime.resource.util.model.yml | 2 +- java/ql/lib/ext/org.thymeleaf.model.yml | 4 ++-- .../lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- .../code/java/security/TemplateInjection.qll | 2 +- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/java/ql/lib/ext/com.hubspot.jinjava.model.yml b/java/ql/lib/ext/com.hubspot.jinjava.model.yml index 2172da483f8..9c8866c9c14 100644 --- a/java/ql/lib/ext/com.hubspot.jinjava.model.yml +++ b/java/ql/lib/ext/com.hubspot.jinjava.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["com.hubspot.jinjava", "Jinjava", True, "render", "", "", "Argument[0]", "ssti", "manual"] - - ["com.hubspot.jinjava", "Jinjava", True, "renderForResult", "", "", "Argument[0]", "ssti", "manual"] + - ["com.hubspot.jinjava", "Jinjava", True, "render", "", "", "Argument[0]", "template-injection", "manual"] + - ["com.hubspot.jinjava", "Jinjava", True, "renderForResult", "", "", "Argument[0]", "template-injection", "manual"] diff --git a/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml b/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml index 74b227da1dd..72c466af08c 100644 --- a/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml +++ b/java/ql/lib/ext/com.mitchellbosecke.pebble.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["com.mitchellbosecke.pebble", "PebbleEngine", True, "getLiteralTemplate", "", "", "Argument[0]", "ssti", "manual"] - - ["com.mitchellbosecke.pebble", "PebbleEngine", True, "getTemplate", "", "", "Argument[0]", "ssti", "manual"] + - ["com.mitchellbosecke.pebble", "PebbleEngine", True, "getLiteralTemplate", "", "", "Argument[0]", "template-injection", "manual"] + - ["com.mitchellbosecke.pebble", "PebbleEngine", True, "getTemplate", "", "", "Argument[0]", "template-injection", "manual"] diff --git a/java/ql/lib/ext/freemarker.cache.model.yml b/java/ql/lib/ext/freemarker.cache.model.yml index b65e6386ad6..b09961f0686 100644 --- a/java/ql/lib/ext/freemarker.cache.model.yml +++ b/java/ql/lib/ext/freemarker.cache.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["freemarker.cache", "StringTemplateLoader", True, "putTemplate", "", "", "Argument[1]", "ssti", "manual"] + - ["freemarker.cache", "StringTemplateLoader", True, "putTemplate", "", "", "Argument[1]", "template-injection", "manual"] diff --git a/java/ql/lib/ext/freemarker.template.model.yml b/java/ql/lib/ext/freemarker.template.model.yml index 96087a2b9ba..afc9579719d 100644 --- a/java/ql/lib/ext/freemarker.template.model.yml +++ b/java/ql/lib/ext/freemarker.template.model.yml @@ -3,10 +3,10 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["freemarker.template", "Template", True, "Template", "(String,Reader)", "", "Argument[1]", "ssti", "manual"] - - ["freemarker.template", "Template", True, "Template", "(String,Reader,Configuration)", "", "Argument[1]", "ssti", "manual"] - - ["freemarker.template", "Template", True, "Template", "(String,Reader,Configuration,String)", "", "Argument[1]", "ssti", "manual"] - - ["freemarker.template", "Template", True, "Template", "(String,String,Configuration)", "", "Argument[1]", "ssti", "manual"] - - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration)", "", "Argument[2]", "ssti", "manual"] - - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration,ParserConfiguration,String)", "", "Argument[2]", "ssti", "manual"] - - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration,String)", "", "Argument[2]", "ssti", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,Reader)", "", "Argument[1]", "template-injection", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,Reader,Configuration)", "", "Argument[1]", "template-injection", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,Reader,Configuration,String)", "", "Argument[1]", "template-injection", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Configuration)", "", "Argument[1]", "template-injection", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration)", "", "Argument[2]", "template-injection", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration,ParserConfiguration,String)", "", "Argument[2]", "template-injection", "manual"] + - ["freemarker.template", "Template", True, "Template", "(String,String,Reader,Configuration,String)", "", "Argument[2]", "template-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.app.model.yml b/java/ql/lib/ext/org.apache.velocity.app.model.yml index 1afc328b882..307f534d3ea 100644 --- a/java/ql/lib/ext/org.apache.velocity.app.model.yml +++ b/java/ql/lib/ext/org.apache.velocity.app.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.velocity.app", "Velocity", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] - - ["org.apache.velocity.app", "Velocity", True, "mergeTemplate", "", "", "Argument[2]", "ssti", "manual"] - - ["org.apache.velocity.app", "VelocityEngine", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] - - ["org.apache.velocity.app", "VelocityEngine", True, "mergeTemplate", "", "", "Argument[2]", "ssti", "manual"] + - ["org.apache.velocity.app", "Velocity", True, "evaluate", "", "", "Argument[3]", "template-injection", "manual"] + - ["org.apache.velocity.app", "Velocity", True, "mergeTemplate", "", "", "Argument[2]", "template-injection", "manual"] + - ["org.apache.velocity.app", "VelocityEngine", True, "evaluate", "", "", "Argument[3]", "template-injection", "manual"] + - ["org.apache.velocity.app", "VelocityEngine", True, "mergeTemplate", "", "", "Argument[2]", "template-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.runtime.model.yml b/java/ql/lib/ext/org.apache.velocity.runtime.model.yml index a8f740a2301..68f4e16fc5a 100644 --- a/java/ql/lib/ext/org.apache.velocity.runtime.model.yml +++ b/java/ql/lib/ext/org.apache.velocity.runtime.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.velocity.runtime", "RuntimeServices", True, "evaluate", "", "", "Argument[3]", "ssti", "manual"] - - ["org.apache.velocity.runtime", "RuntimeServices", True, "parse", "", "", "Argument[0]", "ssti", "manual"] - - ["org.apache.velocity.runtime", "RuntimeSingleton", True, "parse", "", "", "Argument[0]", "ssti", "manual"] + - ["org.apache.velocity.runtime", "RuntimeServices", True, "evaluate", "", "", "Argument[3]", "template-injection", "manual"] + - ["org.apache.velocity.runtime", "RuntimeServices", True, "parse", "", "", "Argument[0]", "template-injection", "manual"] + - ["org.apache.velocity.runtime", "RuntimeSingleton", True, "parse", "", "", "Argument[0]", "template-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml b/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml index 4d3ce4c37ed..a204fb0711d 100644 --- a/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml +++ b/java/ql/lib/ext/org.apache.velocity.runtime.resource.util.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.velocity.runtime.resource.util", "StringResourceRepository", True, "putStringResource", "", "", "Argument[1]", "ssti", "manual"] + - ["org.apache.velocity.runtime.resource.util", "StringResourceRepository", True, "putStringResource", "", "", "Argument[1]", "template-injection", "manual"] diff --git a/java/ql/lib/ext/org.thymeleaf.model.yml b/java/ql/lib/ext/org.thymeleaf.model.yml index 66361b05836..2556cad8314 100644 --- a/java/ql/lib/ext/org.thymeleaf.model.yml +++ b/java/ql/lib/ext/org.thymeleaf.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.thymeleaf", "ITemplateEngine", True, "process", "", "", "Argument[0]", "ssti", "manual"] - - ["org.thymeleaf", "ITemplateEngine", True, "processThrottled", "", "", "Argument[0]", "ssti", "manual"] + - ["org.thymeleaf", "ITemplateEngine", True, "process", "", "", "Argument[0]", "template-injection", "manual"] + - ["org.thymeleaf", "ITemplateEngine", True, "processThrottled", "", "", "Argument[0]", "template-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index b61aa86f3d5..a22dbd6b5e8 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -278,7 +278,7 @@ module ModelValidation { "xpath-injection", "groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-redirection", "create-file", "read-file", "write-file", "set-hostname-verifier", "header-splitting", "information-leak", "xslt", "jexl", - "bean-validation", "ssti", "fragment-injection", "command-injection" + "bean-validation", "template-injection", "fragment-injection", "command-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and diff --git a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll index b8625556c7a..bd568355886 100644 --- a/java/ql/lib/semmle/code/java/security/TemplateInjection.qll +++ b/java/ql/lib/semmle/code/java/security/TemplateInjection.qll @@ -66,7 +66,7 @@ private class DefaultTemplateInjectionSource extends TemplateInjectionSource ins { } private class DefaultTemplateInjectionSink extends TemplateInjectionSink { - DefaultTemplateInjectionSink() { sinkNode(this, "ssti") } + DefaultTemplateInjectionSink() { sinkNode(this, "template-injection") } } private class DefaultTemplateInjectionSanitizer extends TemplateInjectionSanitizer { From 430010daa377832238ef4fea3805448c6e831107 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:02:09 -0400 Subject: [PATCH 224/739] Java: update logging sink kind to log-injection --- java/ql/lib/ext/android.util.model.yml | 12 +- .../ext/com.google.common.flogger.model.yml | 58 +- java/ql/lib/ext/java.lang.model.yml | 16 +- java/ql/lib/ext/java.util.logging.model.yml | 68 +- .../ext/org.apache.commons.logging.model.yml | 12 +- java/ql/lib/ext/org.apache.log4j.model.yml | 22 +- .../ext/org.apache.logging.log4j.model.yml | 718 +++++++++--------- java/ql/lib/ext/org.jboss.logging.model.yml | 648 ++++++++-------- java/ql/lib/ext/org.scijava.log.model.yml | 26 +- java/ql/lib/ext/org.slf4j.model.yml | 100 +-- java/ql/lib/ext/org.slf4j.spi.model.yml | 10 +- .../code/java/dataflow/ExternalFlow.qll | 4 +- .../code/java/security/LogInjection.qll | 2 +- .../java/security/SensitiveLoggingQuery.qll | 4 +- .../internal/CaptureModelsSpecific.qll | 2 +- 15 files changed, 851 insertions(+), 851 deletions(-) diff --git a/java/ql/lib/ext/android.util.model.yml b/java/ql/lib/ext/android.util.model.yml index b57ff4819a7..eaf9d142f54 100644 --- a/java/ql/lib/ext/android.util.model.yml +++ b/java/ql/lib/ext/android.util.model.yml @@ -23,9 +23,9 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["android.util", "Log", True, "d", "", "", "Argument[1]", "logging", "manual"] - - ["android.util", "Log", True, "e", "", "", "Argument[1]", "logging", "manual"] - - ["android.util", "Log", True, "i", "", "", "Argument[1]", "logging", "manual"] - - ["android.util", "Log", True, "v", "", "", "Argument[1]", "logging", "manual"] - - ["android.util", "Log", True, "w", "", "", "Argument[1]", "logging", "manual"] - - ["android.util", "Log", True, "wtf", "", "", "Argument[1]", "logging", "manual"] + - ["android.util", "Log", True, "d", "", "", "Argument[1]", "log-injection", "manual"] + - ["android.util", "Log", True, "e", "", "", "Argument[1]", "log-injection", "manual"] + - ["android.util", "Log", True, "i", "", "", "Argument[1]", "log-injection", "manual"] + - ["android.util", "Log", True, "v", "", "", "Argument[1]", "log-injection", "manual"] + - ["android.util", "Log", True, "w", "", "", "Argument[1]", "log-injection", "manual"] + - ["android.util", "Log", True, "wtf", "", "", "Argument[1]", "log-injection", "manual"] diff --git a/java/ql/lib/ext/com.google.common.flogger.model.yml b/java/ql/lib/ext/com.google.common.flogger.model.yml index b9a800b6210..23ae9236fd7 100644 --- a/java/ql/lib/ext/com.google.common.flogger.model.yml +++ b/java/ql/lib/ext/com.google.common.flogger.model.yml @@ -3,32 +3,32 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["com.google.common.flogger", "LoggingApi", True, "log", "", "", "Argument[0]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object[])", "", "Argument[1..11]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,boolean)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,byte)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,char)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,double)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,float)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,int)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,long)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,short)", "", "Argument[1]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,boolean,Object)", "", "Argument[2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,byte,Object)", "", "Argument[2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,char,Object)", "", "Argument[2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,double,Object)", "", "Argument[2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,float,Object)", "", "Argument[2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,int,Object)", "", "Argument[2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,long,Object)", "", "Argument[2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,short,Object)", "", "Argument[2]", "logging", "manual"] - - ["com.google.common.flogger", "LoggingApi", True, "logVarargs", "", "", "Argument[0..1]", "logging", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "", "", "Argument[0]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object[])", "", "Argument[1..11]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,boolean)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,byte)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,char)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,double)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,float)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,int)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,long)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,Object,short)", "", "Argument[1]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,boolean,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,byte,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,char,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,double,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,float,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,int,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,long,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "log", "(String,short,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["com.google.common.flogger", "LoggingApi", True, "logVarargs", "", "", "Argument[0..1]", "log-injection", "manual"] diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index bbb269b3d55..b5db4e60f58 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -29,14 +29,14 @@ extensions: # These are modeled in plain CodeQL. TODO: migrate them. # - ["java.lang", "System", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] # This is actually injecting a library. # - ["java.lang", "System", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] # This is actually injecting a library. - - ["java.lang", "System$Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] - - ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Object[])", "", "Argument[2..3]", "logging", "manual"] - - ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["java.lang", "System$Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] - - ["java.lang", "System$Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["java.lang", "System$Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["java.lang", "System$Logger", True, "log", "(Level,String,Supplier,Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["java.lang", "System$Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Object[])", "", "Argument[2..3]", "log-injection", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String)", "", "Argument[1]", "log-injection", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Supplier,Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["java.lang", "System$Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml index 05d7aa62a70..330a2d469a8 100644 --- a/java/ql/lib/ext/java.util.logging.model.yml +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -3,40 +3,40 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.util.logging", "Logger", True, "config", "", "", "Argument[0]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "entering", "(String,String)", "", "Argument[0..1]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "entering", "(String,String,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "entering", "(String,String,Object[])", "", "Argument[0..2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "exiting", "(String,String)", "", "Argument[0..1]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "exiting", "(String,String,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "fine", "", "", "Argument[0]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "finer", "", "", "Argument[0]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "finest", "", "", "Argument[0]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "info", "", "", "Argument[0]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "log", "(Level,Throwable,Supplier)", "", "Argument[2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "log", "(LogRecord)", "", "Argument[0]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String)", "", "Argument[1..3]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Object[])", "", "Argument[1..4]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Throwable)", "", "Argument[1..3]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Supplier)", "", "Argument[1..3]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Throwable,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Throwable,Supplier)", "", "Argument[4]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Object[])", "", "Argument[4..5]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Throwable)", "", "Argument[4]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String)", "", "Argument[1..4]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Object[])", "", "Argument[1..5]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Throwable)", "", "Argument[1..4]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "severe", "", "", "Argument[0]", "logging", "manual"] - - ["java.util.logging", "Logger", True, "warning", "", "", "Argument[0]", "logging", "manual"] + - ["java.util.logging", "Logger", True, "config", "", "", "Argument[0]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String)", "", "Argument[0..1]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "entering", "(String,String,Object[])", "", "Argument[0..2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "exiting", "(String,String)", "", "Argument[0..1]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "exiting", "(String,String,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "fine", "", "", "Argument[0]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "finer", "", "", "Argument[0]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "finest", "", "", "Argument[0]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "info", "", "", "Argument[0]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "log", "(Level,Throwable,Supplier)", "", "Argument[2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "log", "(LogRecord)", "", "Argument[0]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String)", "", "Argument[1..3]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Object[])", "", "Argument[1..4]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,String,Throwable)", "", "Argument[1..3]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Supplier)", "", "Argument[1..3]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Throwable,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logp", "(Level,String,String,Throwable,Supplier)", "", "Argument[4]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Object[])", "", "Argument[4..5]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,ResourceBundle,String,Throwable)", "", "Argument[4]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String)", "", "Argument[1..4]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Object[])", "", "Argument[1..5]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "logrb", "(Level,String,String,String,String,Throwable)", "", "Argument[1..4]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "severe", "", "", "Argument[0]", "log-injection", "manual"] + - ["java.util.logging", "Logger", True, "warning", "", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.apache.commons.logging.model.yml b/java/ql/lib/ext/org.apache.commons.logging.model.yml index 8f40e26f2a1..7e2be01c522 100644 --- a/java/ql/lib/ext/org.apache.commons.logging.model.yml +++ b/java/ql/lib/ext/org.apache.commons.logging.model.yml @@ -3,9 +3,9 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.commons.logging", "Log", True, "debug", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.commons.logging", "Log", True, "error", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.commons.logging", "Log", True, "fatal", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.commons.logging", "Log", True, "info", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.commons.logging", "Log", True, "trace", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.commons.logging", "Log", True, "warn", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.commons.logging", "Log", True, "debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.commons.logging", "Log", True, "error", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.commons.logging", "Log", True, "fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.commons.logging", "Log", True, "info", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.commons.logging", "Log", True, "trace", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.commons.logging", "Log", True, "warn", "", "", "Argument[0]", "log-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.log4j.model.yml b/java/ql/lib/ext/org.apache.log4j.model.yml index 309f238111b..e27bdef0fbf 100644 --- a/java/ql/lib/ext/org.apache.log4j.model.yml +++ b/java/ql/lib/ext/org.apache.log4j.model.yml @@ -3,14 +3,14 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.log4j", "Category", True, "assertLog", "", "", "Argument[1]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "debug", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "error", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "fatal", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "forcedLog", "", "", "Argument[2]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "info", "", "", "Argument[0]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "l7dlog", "(Priority,String,Object[],Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "log", "(Priority,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "log", "(Priority,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "log", "(String,Priority,Object,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.log4j", "Category", True, "warn", "", "", "Argument[0]", "logging", "manual"] + - ["org.apache.log4j", "Category", True, "assertLog", "", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "debug", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "error", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "fatal", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "forcedLog", "", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "info", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "l7dlog", "(Priority,String,Object[],Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(Priority,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(Priority,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "log", "(String,Priority,Object,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.log4j", "Category", True, "warn", "", "", "Argument[0]", "log-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.logging.log4j.model.yml b/java/ql/lib/ext/org.apache.logging.log4j.model.yml index 5ffe10450a0..2c48df24365 100644 --- a/java/ql/lib/ext/org.apache.logging.log4j.model.yml +++ b/java/ql/lib/ext/org.apache.logging.log4j.model.yml @@ -3,365 +3,365 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(CharSequence)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Message)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Supplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "entry", "(Object[])", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Message)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Message)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Message)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object)", "", "Argument[2..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object)", "", "Argument[2..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object)", "", "Argument[2..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object)", "", "Argument[2..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[2..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..11]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..12]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Supplier)", "", "Argument[2..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "logMessage", "(Level,Marker,String,StackTraceElement,Message,Throwable)", "", "Argument[4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Message)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Supplier[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Supplier[])", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Message,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Message)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Supplier)", "", "Argument[1..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Supplier)", "", "Argument[0..1]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier)", "", "Argument[0]", "logging", "manual"] - - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(CharSequence)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Message)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(String,Supplier)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "LogBuilder", True, "log", "(Supplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(CharSequence,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Message)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Message,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(MessageSupplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Supplier)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "debug", "(Supplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "entry", "(Object[])", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(CharSequence,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Message)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Message,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(MessageSupplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Supplier)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "error", "(Supplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(CharSequence,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Message)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Message,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(MessageSupplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Supplier)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "fatal", "(Supplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(CharSequence,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Message)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Message,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(MessageSupplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Supplier)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "info", "(Supplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,CharSequence,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,CharSequence,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Message)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,MessageSupplier,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Object,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object)", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object)", "", "Argument[2..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object)", "", "Argument[2..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object)", "", "Argument[2..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object)", "", "Argument[2..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[2..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..11]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[2..12]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Supplier)", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,String,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Marker,Supplier,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Message,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,MessageSupplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "log", "(Level,Supplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "logMessage", "(Level,Marker,String,StackTraceElement,Message,Throwable)", "", "Argument[4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,Marker,String,Object[])", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "printf", "(Level,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(CharSequence,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Message)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Message,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(MessageSupplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Supplier)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "trace", "(Supplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Message)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(String,Supplier[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceEntry", "(Supplier[])", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(EntryMessage,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Message,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "traceExit", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(CharSequence,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,CharSequence,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Message)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,MessageSupplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object)", "", "Argument[1..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object)", "", "Argument[1..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[1..11]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Supplier)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,String,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Marker,Supplier,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Message,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(MessageSupplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object)", "", "Argument[0..5]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object)", "", "Argument[0..6]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..7]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..8]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..9]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object,Object,Object,Object,Object,Object,Object,Object,Object,Object)", "", "Argument[0..10]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Supplier)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier)", "", "Argument[0]", "log-injection", "manual"] + - ["org.apache.logging.log4j", "Logger", True, "warn", "(Supplier,Throwable)", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.jboss.logging.model.yml b/java/ql/lib/ext/org.jboss.logging.model.yml index 069ae852b77..31636f1a6a3 100644 --- a/java/ql/lib/ext/org.jboss.logging.model.yml +++ b/java/ql/lib/ext/org.jboss.logging.model.yml @@ -3,327 +3,327 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debug", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debug", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "error", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "error", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatal", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatal", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "info", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "info", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,String,Object,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "log", "(String,Level,Object,Object[],Throwable)", "", "Argument[2..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "trace", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "trace", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warn", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warn", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debug", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debug", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debug", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debug", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "error", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "error", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "error", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "error", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatal", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatal", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "info", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "info", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "info", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "info", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infof", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infof", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infov", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infov", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "log", "(Level,String,Object,Throwable)", "", "Argument[2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "log", "(String,Level,Object,Object[],Throwable)", "", "Argument[2..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "trace", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "trace", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "trace", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "trace", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warn", "(Object,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warn", "(Object,Object[],Throwable)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warn", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warn", "(String,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object,Object)", "", "Argument[0..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "logging", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debug", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "debugv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "error", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "errorv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatal", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "fatalv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "info", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infof", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "infov", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(Level,String,Object,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "log", "(String,Level,Object,Object[],Throwable)", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logf", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "logv", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "trace", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracef", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "tracev", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warn", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "BasicLogger", True, "warnv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debug", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "debugv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "error", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "errorv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatal", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "fatalv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "info", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infof", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "infov", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(Level,String,Object,Throwable)", "", "Argument[2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "log", "(String,Level,Object,Object[],Throwable)", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logf", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object)", "", "Argument[2..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object,Object)", "", "Argument[2..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(Level,Throwable,String,Object,Object,Object)", "", "Argument[1..5]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object)", "", "Argument[3..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object,Object)", "", "Argument[3..5]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object,Object,Object)", "", "Argument[3..6]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "logv", "(String,Level,Throwable,String,Object[])", "", "Argument[3..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "trace", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracef", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "tracev", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Object[],Throwable)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(String,Object,Object[],Throwable)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warn", "(String,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnf", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object,Object)", "", "Argument[0..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.jboss.logging", "Logger", True, "warnv", "(Throwable,String,Object,Object,Object)", "", "Argument[0..4]", "log-injection", "manual"] diff --git a/java/ql/lib/ext/org.scijava.log.model.yml b/java/ql/lib/ext/org.scijava.log.model.yml index 303dbae27e2..ad53130cd07 100644 --- a/java/ql/lib/ext/org.scijava.log.model.yml +++ b/java/ql/lib/ext/org.scijava.log.model.yml @@ -3,16 +3,16 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.scijava.log", "Logger", True, "alwaysLog", "(int,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "debug", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "error", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "info", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "log", "(int,Object)", "", "Argument[1]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "log", "(int,Object,Throwable)", "", "Argument[1]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "trace", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "warn", "(Object)", "", "Argument[0]", "logging", "manual"] - - ["org.scijava.log", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.scijava.log", "Logger", True, "alwaysLog", "(int,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "debug", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "debug", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "error", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "error", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "info", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "info", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "log", "(int,Object)", "", "Argument[1]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "log", "(int,Object,Throwable)", "", "Argument[1]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "trace", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "trace", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "warn", "(Object)", "", "Argument[0]", "log-injection", "manual"] + - ["org.scijava.log", "Logger", True, "warn", "(Object,Throwable)", "", "Argument[0]", "log-injection", "manual"] diff --git a/java/ql/lib/ext/org.slf4j.model.yml b/java/ql/lib/ext/org.slf4j.model.yml index 6ff2f31847d..e714155b3f2 100644 --- a/java/ql/lib/ext/org.slf4j.model.yml +++ b/java/ql/lib/ext/org.slf4j.model.yml @@ -3,53 +3,53 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.slf4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "debug", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "error", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "info", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "trace", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String)", "", "Argument[1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object)", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object,Object)", "", "Argument[1..3]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object,Object,Object)", "", "Argument[1..4]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(Marker,String,Object[])", "", "Argument[1..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String)", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j", "Logger", True, "warn", "(String,Throwable)", "", "Argument[0]", "log-injection", "manual"] diff --git a/java/ql/lib/ext/org.slf4j.spi.model.yml b/java/ql/lib/ext/org.slf4j.spi.model.yml index 197131b6e17..a1d5c498c33 100644 --- a/java/ql/lib/ext/org.slf4j.spi.model.yml +++ b/java/ql/lib/ext/org.slf4j.spi.model.yml @@ -3,11 +3,11 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "", "", "Argument[0]", "logging", "manual"] - - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "logging", "manual"] - - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "logging", "manual"] - - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(Supplier)", "", "Argument[0]", "logging", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "", "", "Argument[0]", "log-injection", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object)", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object,Object)", "", "Argument[0..2]", "log-injection", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(String,Object[])", "", "Argument[0..1]", "log-injection", "manual"] + - ["org.slf4j.spi", "LoggingEventBuilder", True, "log", "(Supplier)", "", "Argument[0]", "log-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index a22dbd6b5e8..17a364b7e2e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -274,8 +274,8 @@ module ModelValidation { exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind = [ - "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "logging", "mvel", - "xpath-injection", "groovy", "xss", "ognl-injection", "intent-start", + "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "log-injection", + "mvel", "xpath-injection", "groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-redirection", "create-file", "read-file", "write-file", "set-hostname-verifier", "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "template-injection", "fragment-injection", "command-injection" diff --git a/java/ql/lib/semmle/code/java/security/LogInjection.qll b/java/ql/lib/semmle/code/java/security/LogInjection.qll index e60e6ed9a7f..2314d807a60 100644 --- a/java/ql/lib/semmle/code/java/security/LogInjection.qll +++ b/java/ql/lib/semmle/code/java/security/LogInjection.qll @@ -27,7 +27,7 @@ class LogInjectionAdditionalTaintStep extends Unit { } private class DefaultLogInjectionSink extends LogInjectionSink { - DefaultLogInjectionSink() { sinkNode(this, "logging") } + DefaultLogInjectionSink() { sinkNode(this, "log-injection") } } private class DefaultLogInjectionSanitizer extends LogInjectionSanitizer { diff --git a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll index d9ed2b970b0..984c9f6fcaa 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll @@ -35,7 +35,7 @@ deprecated class SensitiveLoggerConfiguration extends TaintTracking::Configurati override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr } - override predicate isSink(DataFlow::Node sink) { sinkNode(sink, "logging") } + override predicate isSink(DataFlow::Node sink) { sinkNode(sink, "log-injection") } override predicate isSanitizer(DataFlow::Node sanitizer) { sanitizer.asExpr() instanceof LiveLiteral or @@ -52,7 +52,7 @@ deprecated class SensitiveLoggerConfiguration extends TaintTracking::Configurati module SensitiveLoggerConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr } - predicate isSink(DataFlow::Node sink) { sinkNode(sink, "logging") } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "log-injection") } predicate isBarrier(DataFlow::Node sanitizer) { sanitizer.asExpr() instanceof LiveLiteral or diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index fcc1ef97ecc..8583e793fc9 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -250,7 +250,7 @@ string asInputArgumentSpecific(DataFlow::Node source) { */ bindingset[kind] predicate isRelevantSinkKind(string kind) { - not kind = "logging" and + not kind = "log-injection" and not kind.matches("regex-use%") and not kind = "write-file" } From 6431d370c1031bc1f682855a3b65e16533db56cc Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 30 May 2023 12:58:56 -0400 Subject: [PATCH 225/739] Java: update groovy sink kind to groovy-injection --- java/ql/lib/ext/groovy.lang.model.yml | 54 +++++++++---------- java/ql/lib/ext/groovy.util.model.yml | 10 ++-- .../ext/org.codehaus.groovy.control.model.yml | 2 +- .../code/java/dataflow/ExternalFlow.qll | 2 +- .../code/java/security/GroovyInjection.qll | 2 +- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/java/ql/lib/ext/groovy.lang.model.yml b/java/ql/lib/ext/groovy.lang.model.yml index 815beb99041..7c6ac81d1ab 100644 --- a/java/ql/lib/ext/groovy.lang.model.yml +++ b/java/ql/lib/ext/groovy.lang.model.yml @@ -3,30 +3,30 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(GroovyCodeSource)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(GroovyCodeSource,boolean)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(InputStream,String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(String,String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "evaluate", "(GroovyCodeSource)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "evaluate", "(Reader)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "evaluate", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "evaluate", "(String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "evaluate", "(String,String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "evaluate", "(String,String,String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "evaluate", "(URI)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "parse", "(Reader)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "parse", "(Reader,String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "parse", "(String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "parse", "(String,String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "parse", "(URI)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "run", "(GroovyCodeSource,List)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "run", "(GroovyCodeSource,String[])", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "run", "(Reader,String,List)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "run", "(Reader,String,String[])", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "run", "(String,String,List)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "run", "(String,String,String[])", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "run", "(URI,List)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.lang", "GroovyShell", False, "run", "(URI,String[])", "", "Argument[0]", "groovy", "manual"] - - ["groovy.text", "TemplateEngine", True, "createTemplate", "", "", "Argument[0]", "groovy", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(GroovyCodeSource)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(GroovyCodeSource,boolean)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(InputStream,String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(Reader,String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyClassLoader", False, "parseClass", "(String,String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(GroovyCodeSource)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(Reader)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(Reader,String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String,String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(String,String,String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "evaluate", "(URI)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(Reader)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(Reader,String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(String,String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "parse", "(URI)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(GroovyCodeSource,List)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(GroovyCodeSource,String[])", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(Reader,String,List)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(Reader,String,String[])", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(String,String,List)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(String,String,String[])", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(URI,List)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.lang", "GroovyShell", False, "run", "(URI,String[])", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.text", "TemplateEngine", True, "createTemplate", "", "", "Argument[0]", "groovy-injection", "manual"] diff --git a/java/ql/lib/ext/groovy.util.model.yml b/java/ql/lib/ext/groovy.util.model.yml index 61d1dbb6a05..f0a979e2ce8 100644 --- a/java/ql/lib/ext/groovy.util.model.yml +++ b/java/ql/lib/ext/groovy.util.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["groovy.util", "Eval", False, "me", "(String)", "", "Argument[0]", "groovy", "manual"] - - ["groovy.util", "Eval", False, "me", "(String,Object,String)", "", "Argument[2]", "groovy", "manual"] - - ["groovy.util", "Eval", False, "x", "(Object,String)", "", "Argument[1]", "groovy", "manual"] - - ["groovy.util", "Eval", False, "xy", "(Object,Object,String)", "", "Argument[2]", "groovy", "manual"] - - ["groovy.util", "Eval", False, "xyz", "(Object,Object,Object,String)", "", "Argument[3]", "groovy", "manual"] + - ["groovy.util", "Eval", False, "me", "(String)", "", "Argument[0]", "groovy-injection", "manual"] + - ["groovy.util", "Eval", False, "me", "(String,Object,String)", "", "Argument[2]", "groovy-injection", "manual"] + - ["groovy.util", "Eval", False, "x", "(Object,String)", "", "Argument[1]", "groovy-injection", "manual"] + - ["groovy.util", "Eval", False, "xy", "(Object,Object,String)", "", "Argument[2]", "groovy-injection", "manual"] + - ["groovy.util", "Eval", False, "xyz", "(Object,Object,Object,String)", "", "Argument[3]", "groovy-injection", "manual"] diff --git a/java/ql/lib/ext/org.codehaus.groovy.control.model.yml b/java/ql/lib/ext/org.codehaus.groovy.control.model.yml index 61ec26f4482..fdccc85e6a9 100644 --- a/java/ql/lib/ext/org.codehaus.groovy.control.model.yml +++ b/java/ql/lib/ext/org.codehaus.groovy.control.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.codehaus.groovy.control", "CompilationUnit", False, "compile", "", "", "Argument[this]", "groovy", "manual"] + - ["org.codehaus.groovy.control", "CompilationUnit", False, "compile", "", "", "Argument[this]", "groovy-injection", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 17a364b7e2e..cae2226cb68 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -275,7 +275,7 @@ module ModelValidation { not kind = [ "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "log-injection", - "mvel", "xpath-injection", "groovy", "xss", "ognl-injection", "intent-start", + "mvel", "xpath-injection", "groovy-injection", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-redirection", "create-file", "read-file", "write-file", "set-hostname-verifier", "header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "template-injection", "fragment-injection", "command-injection" diff --git a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll index 54ea8afce91..b4fe2fd5e84 100644 --- a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll +++ b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll @@ -21,7 +21,7 @@ class GroovyInjectionAdditionalTaintStep extends Unit { } private class DefaultGroovyInjectionSink extends GroovyInjectionSink { - DefaultGroovyInjectionSink() { sinkNode(this, "groovy") } + DefaultGroovyInjectionSink() { sinkNode(this, "groovy-injection") } } /** A set of additional taint steps to consider when taint tracking Groovy related data flows. */ From 6cee0c4c7553218ef3a6f15e3e7dc8fff0607bc1 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:04:39 -0400 Subject: [PATCH 226/739] Java: update jexl sink kind to jexl-injection --- .../ext/org.apache.commons.jexl2.model.yml | 30 +++++++++---------- .../ext/org.apache.commons.jexl3.model.yml | 30 +++++++++---------- .../code/java/dataflow/ExternalFlow.qll | 2 +- .../code/java/security/JexlInjectionQuery.qll | 2 +- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/java/ql/lib/ext/org.apache.commons.jexl2.model.yml b/java/ql/lib/ext/org.apache.commons.jexl2.model.yml index f7ad474114e..8e224f5f20f 100644 --- a/java/ql/lib/ext/org.apache.commons.jexl2.model.yml +++ b/java/ql/lib/ext/org.apache.commons.jexl2.model.yml @@ -3,18 +3,18 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.commons.jexl2", "Expression", False, "callable", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "Expression", False, "evaluate", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "JexlEngine", False, "getProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "JexlEngine", False, "getProperty", "(Object,String)", "", "Argument[1]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "JexlEngine", False, "setProperty", "(JexlContext,Object,String,Object)", "", "Argument[2]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "JexlEngine", False, "setProperty", "(Object,String,Object)", "", "Argument[1]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "JexlExpression", False, "callable", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "JexlExpression", False, "evaluate", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "JexlScript", False, "callable", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "JexlScript", False, "execute", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "Script", False, "callable", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "Script", False, "execute", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "UnifiedJEXL$Expression", False, "evaluate", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "UnifiedJEXL$Expression", False, "prepare", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl2", "UnifiedJEXL$Template", False, "evaluate", "", "", "Argument[this]", "jexl", "manual"] + - ["org.apache.commons.jexl2", "Expression", False, "callable", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "Expression", False, "evaluate", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "getProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "getProperty", "(Object,String)", "", "Argument[1]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "setProperty", "(JexlContext,Object,String,Object)", "", "Argument[2]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "JexlEngine", False, "setProperty", "(Object,String,Object)", "", "Argument[1]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "JexlExpression", False, "callable", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "JexlExpression", False, "evaluate", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "JexlScript", False, "callable", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "JexlScript", False, "execute", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "Script", False, "callable", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "Script", False, "execute", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Expression", False, "evaluate", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Expression", False, "prepare", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl2", "UnifiedJEXL$Template", False, "evaluate", "", "", "Argument[this]", "jexl-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.jexl3.model.yml b/java/ql/lib/ext/org.apache.commons.jexl3.model.yml index cbe04fc3e60..e2fee2fcb3d 100644 --- a/java/ql/lib/ext/org.apache.commons.jexl3.model.yml +++ b/java/ql/lib/ext/org.apache.commons.jexl3.model.yml @@ -3,18 +3,18 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.commons.jexl3", "Expression", False, "callable", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "Expression", False, "evaluate", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JexlEngine", False, "getProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JexlEngine", False, "getProperty", "(Object,String)", "", "Argument[1]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JexlEngine", False, "setProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JexlEngine", False, "setProperty", "(Object,String,Object)", "", "Argument[1]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JexlExpression", False, "callable", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JexlExpression", False, "evaluate", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JexlScript", False, "callable", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JexlScript", False, "execute", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JxltEngine$Expression", False, "evaluate", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JxltEngine$Expression", False, "prepare", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "JxltEngine$Template", False, "evaluate", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "Script", False, "callable", "", "", "Argument[this]", "jexl", "manual"] - - ["org.apache.commons.jexl3", "Script", False, "execute", "", "", "Argument[this]", "jexl", "manual"] + - ["org.apache.commons.jexl3", "Expression", False, "callable", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "Expression", False, "evaluate", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "getProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "getProperty", "(Object,String)", "", "Argument[1]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "setProperty", "(JexlContext,Object,String)", "", "Argument[2]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JexlEngine", False, "setProperty", "(Object,String,Object)", "", "Argument[1]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JexlExpression", False, "callable", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JexlExpression", False, "evaluate", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JexlScript", False, "callable", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JexlScript", False, "execute", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Expression", False, "evaluate", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Expression", False, "prepare", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "JxltEngine$Template", False, "evaluate", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "Script", False, "callable", "", "", "Argument[this]", "jexl-injection", "manual"] + - ["org.apache.commons.jexl3", "Script", False, "execute", "", "", "Argument[this]", "jexl-injection", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index cae2226cb68..78197f16ce3 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -277,7 +277,7 @@ module ModelValidation { "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "log-injection", "mvel", "xpath-injection", "groovy-injection", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-redirection", "create-file", "read-file", "write-file", - "set-hostname-verifier", "header-splitting", "information-leak", "xslt", "jexl", + "set-hostname-verifier", "header-splitting", "information-leak", "xslt", "jexl-injection", "bean-validation", "template-injection", "fragment-injection", "command-injection" ] and not kind.matches("regex-use%") and diff --git a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll index 4138b851e85..dd877720495 100644 --- a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll @@ -13,7 +13,7 @@ abstract class JexlEvaluationSink extends DataFlow::ExprNode { } /** Default sink for JXEL injection vulnerabilities. */ private class DefaultJexlEvaluationSink extends JexlEvaluationSink { - DefaultJexlEvaluationSink() { sinkNode(this, "jexl") } + DefaultJexlEvaluationSink() { sinkNode(this, "jexl-injection") } } /** From cea97b3f2a8f22bb9fd4b5bc3c16964676e58810 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:05:39 -0400 Subject: [PATCH 227/739] Java: update mvel sink kind to mvel-injection --- java/ql/lib/ext/javax.script.model.yml | 2 +- java/ql/lib/ext/org.mvel2.compiler.model.yml | 8 ++++---- java/ql/lib/ext/org.mvel2.jsr223.model.yml | 6 +++--- java/ql/lib/ext/org.mvel2.model.yml | 14 +++++++------- java/ql/lib/ext/org.mvel2.templates.model.yml | 4 ++-- .../lib/semmle/code/java/dataflow/ExternalFlow.qll | 9 +++++---- .../semmle/code/java/security/MvelInjection.qll | 2 +- 7 files changed, 23 insertions(+), 22 deletions(-) diff --git a/java/ql/lib/ext/javax.script.model.yml b/java/ql/lib/ext/javax.script.model.yml index 0dcc6adb3d7..dcec679640f 100644 --- a/java/ql/lib/ext/javax.script.model.yml +++ b/java/ql/lib/ext/javax.script.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.script", "CompiledScript", False, "eval", "", "", "Argument[this]", "mvel", "manual"] + - ["javax.script", "CompiledScript", False, "eval", "", "", "Argument[this]", "mvel-injection", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.compiler.model.yml b/java/ql/lib/ext/org.mvel2.compiler.model.yml index 6ca33c8cdb0..0b3535a6fcf 100644 --- a/java/ql/lib/ext/org.mvel2.compiler.model.yml +++ b/java/ql/lib/ext/org.mvel2.compiler.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.mvel2.compiler", "Accessor", False, "getValue", "", "", "Argument[this]", "mvel", "manual"] - - ["org.mvel2.compiler", "CompiledAccExpression", False, "getValue", "", "", "Argument[this]", "mvel", "manual"] - - ["org.mvel2.compiler", "CompiledExpression", False, "getDirectValue", "", "", "Argument[this]", "mvel", "manual"] - - ["org.mvel2.compiler", "ExecutableStatement", False, "getValue", "", "", "Argument[this]", "mvel", "manual"] + - ["org.mvel2.compiler", "Accessor", False, "getValue", "", "", "Argument[this]", "mvel-injection", "manual"] + - ["org.mvel2.compiler", "CompiledAccExpression", False, "getValue", "", "", "Argument[this]", "mvel-injection", "manual"] + - ["org.mvel2.compiler", "CompiledExpression", False, "getDirectValue", "", "", "Argument[this]", "mvel-injection", "manual"] + - ["org.mvel2.compiler", "ExecutableStatement", False, "getValue", "", "", "Argument[this]", "mvel-injection", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.jsr223.model.yml b/java/ql/lib/ext/org.mvel2.jsr223.model.yml index 6a63bbcf57c..7dff4964cf0 100644 --- a/java/ql/lib/ext/org.mvel2.jsr223.model.yml +++ b/java/ql/lib/ext/org.mvel2.jsr223.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.mvel2.jsr223", "MvelCompiledScript", False, "eval", "", "", "Argument[this]", "mvel", "manual"] - - ["org.mvel2.jsr223", "MvelScriptEngine", False, "eval", "", "", "Argument[0]", "mvel", "manual"] - - ["org.mvel2.jsr223", "MvelScriptEngine", False, "evaluate", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2.jsr223", "MvelCompiledScript", False, "eval", "", "", "Argument[this]", "mvel-injection", "manual"] + - ["org.mvel2.jsr223", "MvelScriptEngine", False, "eval", "", "", "Argument[0]", "mvel-injection", "manual"] + - ["org.mvel2.jsr223", "MvelScriptEngine", False, "evaluate", "", "", "Argument[0]", "mvel-injection", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.model.yml b/java/ql/lib/ext/org.mvel2.model.yml index fd7778c89a6..28a7154df90 100644 --- a/java/ql/lib/ext/org.mvel2.model.yml +++ b/java/ql/lib/ext/org.mvel2.model.yml @@ -3,10 +3,10 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.mvel2", "MVEL", False, "eval", "", "", "Argument[0]", "mvel", "manual"] - - ["org.mvel2", "MVEL", False, "evalToBoolean", "", "", "Argument[0]", "mvel", "manual"] - - ["org.mvel2", "MVEL", False, "evalToString", "", "", "Argument[0]", "mvel", "manual"] - - ["org.mvel2", "MVEL", False, "executeAllExpression", "", "", "Argument[0]", "mvel", "manual"] - - ["org.mvel2", "MVEL", False, "executeExpression", "", "", "Argument[0]", "mvel", "manual"] - - ["org.mvel2", "MVEL", False, "executeSetExpression", "", "", "Argument[0]", "mvel", "manual"] - - ["org.mvel2", "MVELRuntime", False, "execute", "", "", "Argument[1]", "mvel", "manual"] + - ["org.mvel2", "MVEL", False, "eval", "", "", "Argument[0]", "mvel-injection", "manual"] + - ["org.mvel2", "MVEL", False, "evalToBoolean", "", "", "Argument[0]", "mvel-injection", "manual"] + - ["org.mvel2", "MVEL", False, "evalToString", "", "", "Argument[0]", "mvel-injection", "manual"] + - ["org.mvel2", "MVEL", False, "executeAllExpression", "", "", "Argument[0]", "mvel-injection", "manual"] + - ["org.mvel2", "MVEL", False, "executeExpression", "", "", "Argument[0]", "mvel-injection", "manual"] + - ["org.mvel2", "MVEL", False, "executeSetExpression", "", "", "Argument[0]", "mvel-injection", "manual"] + - ["org.mvel2", "MVELRuntime", False, "execute", "", "", "Argument[1]", "mvel-injection", "manual"] diff --git a/java/ql/lib/ext/org.mvel2.templates.model.yml b/java/ql/lib/ext/org.mvel2.templates.model.yml index 0e31cee38b0..93fdbde10ed 100644 --- a/java/ql/lib/ext/org.mvel2.templates.model.yml +++ b/java/ql/lib/ext/org.mvel2.templates.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.mvel2.templates", "TemplateRuntime", False, "eval", "", "", "Argument[0]", "mvel", "manual"] - - ["org.mvel2.templates", "TemplateRuntime", False, "execute", "", "", "Argument[0]", "mvel", "manual"] + - ["org.mvel2.templates", "TemplateRuntime", False, "eval", "", "", "Argument[0]", "mvel-injection", "manual"] + - ["org.mvel2.templates", "TemplateRuntime", False, "execute", "", "", "Argument[0]", "mvel-injection", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 78197f16ce3..06097ce7271 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -275,10 +275,11 @@ module ModelValidation { not kind = [ "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "log-injection", - "mvel", "xpath-injection", "groovy-injection", "xss", "ognl-injection", "intent-start", - "pending-intent-sent", "url-redirection", "create-file", "read-file", "write-file", - "set-hostname-verifier", "header-splitting", "information-leak", "xslt", "jexl-injection", - "bean-validation", "template-injection", "fragment-injection", "command-injection" + "mvel-injection", "xpath-injection", "groovy-injection", "xss", "ognl-injection", + "intent-start", "pending-intent-sent", "url-redirection", "create-file", "read-file", + "write-file", "set-hostname-verifier", "header-splitting", "information-leak", "xslt", + "jexl-injection", "bean-validation", "template-injection", "fragment-injection", + "command-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and diff --git a/java/ql/lib/semmle/code/java/security/MvelInjection.qll b/java/ql/lib/semmle/code/java/security/MvelInjection.qll index a0ada3d91a1..803c6ad0cf9 100644 --- a/java/ql/lib/semmle/code/java/security/MvelInjection.qll +++ b/java/ql/lib/semmle/code/java/security/MvelInjection.qll @@ -25,7 +25,7 @@ class MvelInjectionAdditionalTaintStep extends Unit { /** Default sink for MVEL injection vulnerabilities. */ private class DefaultMvelEvaluationSink extends MvelEvaluationSink { - DefaultMvelEvaluationSink() { sinkNode(this, "mvel") } + DefaultMvelEvaluationSink() { sinkNode(this, "mvel-injection") } } /** A default sanitizer that considers numeric and boolean typed data safe for building MVEL expressions */ From 6d2d25406caec1acedd83a06f800a9b983b7f084 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:06:36 -0400 Subject: [PATCH 228/739] Java: update xslt sink kind to xslt-injection --- java/ql/lib/ext/javax.xml.transform.model.yml | 2 +- java/ql/lib/ext/net.sf.saxon.s9api.model.yml | 10 +++++----- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 6 +++--- .../ql/lib/semmle/code/java/security/XsltInjection.qll | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/java/ql/lib/ext/javax.xml.transform.model.yml b/java/ql/lib/ext/javax.xml.transform.model.yml index ffc321b004f..62a66a3d7ae 100644 --- a/java/ql/lib/ext/javax.xml.transform.model.yml +++ b/java/ql/lib/ext/javax.xml.transform.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.xml.transform", "Transformer", False, "transform", "", "", "Argument[this]", "xslt", "manual"] + - ["javax.xml.transform", "Transformer", False, "transform", "", "", "Argument[this]", "xslt-injection", "manual"] diff --git a/java/ql/lib/ext/net.sf.saxon.s9api.model.yml b/java/ql/lib/ext/net.sf.saxon.s9api.model.yml index 1559092f535..aa0e3eba5a9 100644 --- a/java/ql/lib/ext/net.sf.saxon.s9api.model.yml +++ b/java/ql/lib/ext/net.sf.saxon.s9api.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "applyTemplates", "", "", "Argument[this]", "xslt", "manual"] - - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "callFunction", "", "", "Argument[this]", "xslt", "manual"] - - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "callTemplate", "", "", "Argument[this]", "xslt", "manual"] - - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "transform", "", "", "Argument[this]", "xslt", "manual"] - - ["net.sf.saxon.s9api", "XsltTransformer", False, "transform", "", "", "Argument[this]", "xslt", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "applyTemplates", "", "", "Argument[this]", "xslt-injection", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "callFunction", "", "", "Argument[this]", "xslt-injection", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "callTemplate", "", "", "Argument[this]", "xslt-injection", "manual"] + - ["net.sf.saxon.s9api", "Xslt30Transformer", False, "transform", "", "", "Argument[this]", "xslt-injection", "manual"] + - ["net.sf.saxon.s9api", "XsltTransformer", False, "transform", "", "", "Argument[this]", "xslt-injection", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 06097ce7271..fbdd1ec4e2f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -277,9 +277,9 @@ module ModelValidation { "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "xss", "ognl-injection", "intent-start", "pending-intent-sent", "url-redirection", "create-file", "read-file", - "write-file", "set-hostname-verifier", "header-splitting", "information-leak", "xslt", - "jexl-injection", "bean-validation", "template-injection", "fragment-injection", - "command-injection" + "write-file", "set-hostname-verifier", "header-splitting", "information-leak", + "xslt-injection", "jexl-injection", "bean-validation", "template-injection", + "fragment-injection", "command-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and diff --git a/java/ql/lib/semmle/code/java/security/XsltInjection.qll b/java/ql/lib/semmle/code/java/security/XsltInjection.qll index f6953a09539..3d0782b6ace 100644 --- a/java/ql/lib/semmle/code/java/security/XsltInjection.qll +++ b/java/ql/lib/semmle/code/java/security/XsltInjection.qll @@ -12,7 +12,7 @@ abstract class XsltInjectionSink extends DataFlow::Node { } /** A default sink representing methods susceptible to XSLT Injection attacks. */ private class DefaultXsltInjectionSink extends XsltInjectionSink { - DefaultXsltInjectionSink() { sinkNode(this, "xslt") } + DefaultXsltInjectionSink() { sinkNode(this, "xslt-injection") } } /** From 3ff4c7de8f031c3744ba465d6f6d4e3ed0ad18ca Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:08:40 -0400 Subject: [PATCH 229/739] Java: update ldap sink kind to ldap-injection --- .../lib/ext/com.unboundid.ldap.sdk.model.yml | 34 +++++++++---------- .../lib/ext/javax.naming.directory.model.yml | 2 +- ...apache.directory.ldap.client.api.model.yml | 2 +- .../org.springframework.ldap.core.model.yml | 28 +++++++-------- .../code/java/dataflow/ExternalFlow.qll | 12 +++---- .../code/java/security/LdapInjection.qll | 2 +- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml b/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml index 57753bc31d0..d483d6d97e4 100644 --- a/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml +++ b/java/ql/lib/ext/com.unboundid.ldap.sdk.model.yml @@ -3,20 +3,20 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "asyncSearch", "", "", "Argument[0]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(ReadOnlySearchRequest)", "", "Argument[0]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchRequest)", "", "Argument[0]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[])", "", "Argument[0..7]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,String,String[])", "", "Argument[0..7]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,Filter,String[])", "", "Argument[0..3]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,String,String[])", "", "Argument[0..3]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[])", "", "Argument[0..6]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,DereferencePolicy,int,int,boolean,String,String[])", "", "Argument[0..6]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,Filter,String[])", "", "Argument[0..2]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,String,String[])", "", "Argument[0..2]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(ReadOnlySearchRequest)", "", "Argument[0]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(SearchRequest)", "", "Argument[0]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,DereferencePolicy,int,boolean,Filter,String[])", "", "Argument[0..5]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,DereferencePolicy,int,boolean,String,String[])", "", "Argument[0..5]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,Filter,String[])", "", "Argument[0..2]", "ldap", "manual"] - - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,String,String[])", "", "Argument[0..2]", "ldap", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "asyncSearch", "", "", "Argument[0]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(ReadOnlySearchRequest)", "", "Argument[0]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchRequest)", "", "Argument[0]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[])", "", "Argument[0..7]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,DereferencePolicy,int,int,boolean,String,String[])", "", "Argument[0..7]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,Filter,String[])", "", "Argument[0..3]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(SearchResultListener,String,SearchScope,String,String[])", "", "Argument[0..3]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,DereferencePolicy,int,int,boolean,Filter,String[])", "", "Argument[0..6]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,DereferencePolicy,int,int,boolean,String,String[])", "", "Argument[0..6]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,Filter,String[])", "", "Argument[0..2]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "search", "(String,SearchScope,String,String[])", "", "Argument[0..2]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(ReadOnlySearchRequest)", "", "Argument[0]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(SearchRequest)", "", "Argument[0]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,DereferencePolicy,int,boolean,Filter,String[])", "", "Argument[0..5]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,DereferencePolicy,int,boolean,String,String[])", "", "Argument[0..5]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,Filter,String[])", "", "Argument[0..2]", "ldap-injection", "manual"] + - ["com.unboundid.ldap.sdk", "LDAPConnection", False, "searchForEntry", "(String,SearchScope,String,String[])", "", "Argument[0..2]", "ldap-injection", "manual"] diff --git a/java/ql/lib/ext/javax.naming.directory.model.yml b/java/ql/lib/ext/javax.naming.directory.model.yml index bb350a084cb..6f60e7cf20d 100644 --- a/java/ql/lib/ext/javax.naming.directory.model.yml +++ b/java/ql/lib/ext/javax.naming.directory.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.naming.directory", "DirContext", True, "search", "", "", "Argument[0..1]", "ldap", "manual"] + - ["javax.naming.directory", "DirContext", True, "search", "", "", "Argument[0..1]", "ldap-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml b/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml index 14b580383d3..57b1655d944 100644 --- a/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml +++ b/java/ql/lib/ext/org.apache.directory.ldap.client.api.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.directory.ldap.client.api", "LdapConnection", True, "search", "", "", "Argument[0..2]", "ldap", "manual"] + - ["org.apache.directory.ldap.client.api", "LdapConnection", True, "search", "", "", "Argument[0..2]", "ldap-injection", "manual"] diff --git a/java/ql/lib/ext/org.springframework.ldap.core.model.yml b/java/ql/lib/ext/org.springframework.ldap.core.model.yml index 962dec40c59..ce4ef72e283 100644 --- a/java/ql/lib/ext/org.springframework.ldap.core.model.yml +++ b/java/ql/lib/ext/org.springframework.ldap.core.model.yml @@ -22,17 +22,17 @@ extensions: - ["org.springframework.ldap.core", "LdapOperations", True, "search", "(String,String,int,String[],ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] - ["org.springframework.ldap.core", "LdapOperations", True, "searchForObject", "(Name,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] - ["org.springframework.ldap.core", "LdapOperations", True, "searchForObject", "(String,String,ContextMapper)", "", "Argument[0]", "jndi-injection", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(LdapQuery,String)", "", "Argument[0]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String)", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticatedLdapEntryContextCallback)", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String)", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticatedLdapEntryContextCallback)", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "find", "", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "findOne", "", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "search", "", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "searchForContext", "", "", "Argument[0..1]", "ldap", "manual"] - - ["org.springframework.ldap.core", "LdapTemplate", False, "searchForObject", "", "", "Argument[0..1]", "ldap", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(LdapQuery,String)", "", "Argument[0]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String)", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticatedLdapEntryContextCallback)", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(Name,String,String,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String)", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticatedLdapEntryContextCallback)", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticatedLdapEntryContextCallback,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "authenticate", "(String,String,String,AuthenticationErrorCallback)", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "find", "", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "findOne", "", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "search", "", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "searchForContext", "", "", "Argument[0..1]", "ldap-injection", "manual"] + - ["org.springframework.ldap.core", "LdapTemplate", False, "searchForObject", "", "", "Argument[0..1]", "ldap-injection", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index fbdd1ec4e2f..af4f43004ad 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -274,12 +274,12 @@ module ModelValidation { exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind = [ - "open-url", "jndi-injection", "ldap", "sql-injection", "jdbc-url", "log-injection", - "mvel-injection", "xpath-injection", "groovy-injection", "xss", "ognl-injection", - "intent-start", "pending-intent-sent", "url-redirection", "create-file", "read-file", - "write-file", "set-hostname-verifier", "header-splitting", "information-leak", - "xslt-injection", "jexl-injection", "bean-validation", "template-injection", - "fragment-injection", "command-injection" + "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", + "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "xss", + "ognl-injection", "intent-start", "pending-intent-sent", "url-redirection", "create-file", + "read-file", "write-file", "set-hostname-verifier", "header-splitting", + "information-leak", "xslt-injection", "jexl-injection", "bean-validation", + "template-injection", "fragment-injection", "command-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and diff --git a/java/ql/lib/semmle/code/java/security/LdapInjection.qll b/java/ql/lib/semmle/code/java/security/LdapInjection.qll index d78bd2f7ae1..0e2a35c764e 100644 --- a/java/ql/lib/semmle/code/java/security/LdapInjection.qll +++ b/java/ql/lib/semmle/code/java/security/LdapInjection.qll @@ -29,7 +29,7 @@ class LdapInjectionAdditionalTaintStep extends Unit { /** Default sink for LDAP injection vulnerabilities. */ private class DefaultLdapInjectionSink extends LdapInjectionSink { - DefaultLdapInjectionSink() { sinkNode(this, "ldap") } + DefaultLdapInjectionSink() { sinkNode(this, "ldap-injection") } } /** A sanitizer that clears the taint on (boxed) primitive types. */ From 5aa3e57ff32f4fa3459939004cdfd626b1a0b884 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:09:37 -0400 Subject: [PATCH 230/739] Java: update pending-intent-sent sink kind to pending-intents --- java/ql/lib/ext/android.app.model.yml | 34 +++++++++---------- java/ql/lib/ext/androidx.core.app.model.yml | 12 +++---- java/ql/lib/ext/androidx.slice.model.yml | 4 +-- .../code/java/dataflow/ExternalFlow.qll | 2 +- .../java/security/ImplicitPendingIntents.qll | 2 +- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/java/ql/lib/ext/android.app.model.yml b/java/ql/lib/ext/android.app.model.yml index 861867d344c..c295293ee5a 100644 --- a/java/ql/lib/ext/android.app.model.yml +++ b/java/ql/lib/ext/android.app.model.yml @@ -5,20 +5,20 @@ extensions: data: - ["android.app", "Activity", True, "bindService", "", "", "Argument[0]", "intent-start", "manual"] - ["android.app", "Activity", True, "bindServiceAsUser", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.app", "Activity", True, "setResult", "(int,Intent)", "", "Argument[1]", "pending-intent-sent", "manual"] + - ["android.app", "Activity", True, "setResult", "(int,Intent)", "", "Argument[1]", "pending-intents", "manual"] - ["android.app", "Activity", True, "startActivityAsCaller", "", "", "Argument[0]", "intent-start", "manual"] - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int)", "", "Argument[0]", "intent-start", "manual"] - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int,Bundle)", "", "Argument[0]", "intent-start", "manual"] - ["android.app", "Activity", True, "startActivityForResult", "(String,Intent,int,Bundle)", "", "Argument[1]", "intent-start", "manual"] - ["android.app", "Activity", True, "startActivityForResultAsUser", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.app", "AlarmManager", True, "set", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "AlarmManager", True, "setAlarmClock", "", "", "Argument[1]", "pending-intent-sent", "manual"] - - ["android.app", "AlarmManager", True, "setAndAllowWhileIdle", "", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "AlarmManager", True, "setExact", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "AlarmManager", True, "setExactAndAllowWhileIdle", "", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "AlarmManager", True, "setInexactRepeating", "", "", "Argument[3]", "pending-intent-sent", "manual"] - - ["android.app", "AlarmManager", True, "setRepeating", "", "", "Argument[3]", "pending-intent-sent", "manual"] - - ["android.app", "AlarmManager", True, "setWindow", "(int,long,long,PendingIntent)", "", "Argument[3]", "pending-intent-sent", "manual"] + - ["android.app", "AlarmManager", True, "set", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "AlarmManager", True, "setAlarmClock", "", "", "Argument[1]", "pending-intents", "manual"] + - ["android.app", "AlarmManager", True, "setAndAllowWhileIdle", "", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "AlarmManager", True, "setExact", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "AlarmManager", True, "setExactAndAllowWhileIdle", "", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "AlarmManager", True, "setInexactRepeating", "", "", "Argument[3]", "pending-intents", "manual"] + - ["android.app", "AlarmManager", True, "setRepeating", "", "", "Argument[3]", "pending-intents", "manual"] + - ["android.app", "AlarmManager", True, "setWindow", "(int,long,long,PendingIntent)", "", "Argument[3]", "pending-intents", "manual"] - ["android.app", "FragmentTransaction", True, "add", "(Class,Bundle,String)", "", "Argument[0]", "fragment-injection", "manual"] - ["android.app", "FragmentTransaction", True, "add", "(Fragment,String)", "", "Argument[0]", "fragment-injection", "manual"] - ["android.app", "FragmentTransaction", True, "add", "(int,Class,Bundle)", "", "Argument[1]", "fragment-injection", "manual"] @@ -30,14 +30,14 @@ extensions: - ["android.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"] - ["android.app", "FragmentTransaction", True, "replace", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"] - ["android.app", "FragmentTransaction", True, "replace", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"] - - ["android.app", "NotificationManager", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "NotificationManager", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intent-sent", "manual"] - - ["android.app", "NotificationManager", True, "notifyAsPackage", "(String,String,int,Notification)", "", "Argument[3]", "pending-intent-sent", "manual"] - - ["android.app", "NotificationManager", True, "notifyAsUser", "(String,int,Notification,UserHandle)", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent)", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler)", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler,String)", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler,String,Bundle)", "", "Argument[2]", "pending-intent-sent", "manual"] + - ["android.app", "NotificationManager", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "NotificationManager", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intents", "manual"] + - ["android.app", "NotificationManager", True, "notifyAsPackage", "(String,String,int,Notification)", "", "Argument[3]", "pending-intents", "manual"] + - ["android.app", "NotificationManager", True, "notifyAsUser", "(String,int,Notification,UserHandle)", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent)", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler)", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler,String)", "", "Argument[2]", "pending-intents", "manual"] + - ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,OnFinished,Handler,String,Bundle)", "", "Argument[2]", "pending-intents", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/androidx.core.app.model.yml b/java/ql/lib/ext/androidx.core.app.model.yml index 2bb58605436..f24a67dbbe6 100644 --- a/java/ql/lib/ext/androidx.core.app.model.yml +++ b/java/ql/lib/ext/androidx.core.app.model.yml @@ -3,12 +3,12 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["androidx.core.app", "AlarmManagerCompat", True, "setAlarmClock", "", "", "Argument[2..3]", "pending-intent-sent", "manual"] - - ["androidx.core.app", "AlarmManagerCompat", True, "setAndAllowWhileIdle", "", "", "Argument[3]", "pending-intent-sent", "manual"] - - ["androidx.core.app", "AlarmManagerCompat", True, "setExact", "", "", "Argument[3]", "pending-intent-sent", "manual"] - - ["androidx.core.app", "AlarmManagerCompat", True, "setExactAndAllowWhileIdle", "", "", "Argument[3]", "pending-intent-sent", "manual"] - - ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intent-sent", "manual"] - - ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intent-sent", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setAlarmClock", "", "", "Argument[2..3]", "pending-intents", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setAndAllowWhileIdle", "", "", "Argument[3]", "pending-intents", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setExact", "", "", "Argument[3]", "pending-intents", "manual"] + - ["androidx.core.app", "AlarmManagerCompat", True, "setExactAndAllowWhileIdle", "", "", "Argument[3]", "pending-intents", "manual"] + - ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intents", "manual"] + - ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intents", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/androidx.slice.model.yml b/java/ql/lib/ext/androidx.slice.model.yml index 97481e886e5..1e4176e5d9a 100644 --- a/java/ql/lib/ext/androidx.slice.model.yml +++ b/java/ql/lib/ext/androidx.slice.model.yml @@ -12,5 +12,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["androidx.slice", "SliceProvider", True, "onBindSlice", "", "", "ReturnValue", "pending-intent-sent", "manual"] - - ["androidx.slice", "SliceProvider", True, "onCreatePermissionRequest", "", "", "ReturnValue", "pending-intent-sent", "manual"] + - ["androidx.slice", "SliceProvider", True, "onBindSlice", "", "", "ReturnValue", "pending-intents", "manual"] + - ["androidx.slice", "SliceProvider", True, "onCreatePermissionRequest", "", "", "ReturnValue", "pending-intents", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index af4f43004ad..3e6543297d1 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -276,7 +276,7 @@ module ModelValidation { [ "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "xss", - "ognl-injection", "intent-start", "pending-intent-sent", "url-redirection", "create-file", + "ognl-injection", "intent-start", "pending-intents", "url-redirection", "create-file", "read-file", "write-file", "set-hostname-verifier", "header-splitting", "information-leak", "xslt-injection", "jexl-injection", "bean-validation", "template-injection", "fragment-injection", "command-injection" diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 308b8037554..6511bf28685 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -63,7 +63,7 @@ private class SendPendingIntent extends ImplicitPendingIntentSink { this.asExpr() = ma.getArgument(0) ) or - sinkNode(this, "pending-intent-sent") + sinkNode(this, "pending-intents") } override predicate hasState(DataFlow::FlowState state) { state = "MutablePendingIntent" } From b23f384a50bd66943a02bd4f130028541878a475 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:10:57 -0400 Subject: [PATCH 231/739] Java: update intent-start sink kind to intent-redirection --- java/ql/lib/ext/android.app.model.yml | 14 ++++---- java/ql/lib/ext/android.content.model.yml | 32 +++++++++---------- .../code/java/dataflow/ExternalFlow.qll | 4 +-- .../security/AndroidIntentRedirection.qll | 2 +- .../java/security/ImplicitPendingIntents.qll | 3 +- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/java/ql/lib/ext/android.app.model.yml b/java/ql/lib/ext/android.app.model.yml index c295293ee5a..72591773436 100644 --- a/java/ql/lib/ext/android.app.model.yml +++ b/java/ql/lib/ext/android.app.model.yml @@ -3,14 +3,14 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["android.app", "Activity", True, "bindService", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.app", "Activity", True, "bindServiceAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "bindService", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.app", "Activity", True, "bindServiceAsUser", "", "", "Argument[0]", "intent-redirection", "manual"] - ["android.app", "Activity", True, "setResult", "(int,Intent)", "", "Argument[1]", "pending-intents", "manual"] - - ["android.app", "Activity", True, "startActivityAsCaller", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int)", "", "Argument[0]", "intent-start", "manual"] - - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int,Bundle)", "", "Argument[0]", "intent-start", "manual"] - - ["android.app", "Activity", True, "startActivityForResult", "(String,Intent,int,Bundle)", "", "Argument[1]", "intent-start", "manual"] - - ["android.app", "Activity", True, "startActivityForResultAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.app", "Activity", True, "startActivityAsCaller", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int)", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(Intent,int,Bundle)", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.app", "Activity", True, "startActivityForResult", "(String,Intent,int,Bundle)", "", "Argument[1]", "intent-redirection", "manual"] + - ["android.app", "Activity", True, "startActivityForResultAsUser", "", "", "Argument[0]", "intent-redirection", "manual"] - ["android.app", "AlarmManager", True, "set", "(int,long,PendingIntent)", "", "Argument[2]", "pending-intents", "manual"] - ["android.app", "AlarmManager", True, "setAlarmClock", "", "", "Argument[1]", "pending-intents", "manual"] - ["android.app", "AlarmManager", True, "setAndAllowWhileIdle", "", "", "Argument[2]", "pending-intents", "manual"] diff --git a/java/ql/lib/ext/android.content.model.yml b/java/ql/lib/ext/android.content.model.yml index bee6bae8d44..c42578c08cd 100644 --- a/java/ql/lib/ext/android.content.model.yml +++ b/java/ql/lib/ext/android.content.model.yml @@ -47,22 +47,22 @@ extensions: - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String)", "", "Argument[2]", "sql-injection", "manual"] - ["android.content", "ContentResolver", True, "query", "(Uri,String[],String,String[],String,CancellationSignal)", "", "Argument[2]", "sql-injection", "manual"] - ["android.content", "ContentResolver", True, "update", "(Uri,ContentValues,String,String[])", "", "Argument[2]", "sql-injection", "manual"] - - ["android.content", "Context", True, "sendBroadcast", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "sendBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "sendBroadcastWithMultiplePermissions", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "sendStickyBroadcast", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "sendStickyBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "sendStickyOrderedBroadcast", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "sendStickyOrderedBroadcastAsUser", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "startActivities", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "startActivity", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "startActivityAsUser", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "startActivityFromChild", "", "", "Argument[1]", "intent-start", "manual"] - - ["android.content", "Context", True, "startActivityFromFragment", "", "", "Argument[1]", "intent-start", "manual"] - - ["android.content", "Context", True, "startActivityIfNeeded", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "startForegroundService", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "startService", "", "", "Argument[0]", "intent-start", "manual"] - - ["android.content", "Context", True, "startServiceAsUser", "", "", "Argument[0]", "intent-start", "manual"] + - ["android.content", "Context", True, "sendBroadcast", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "sendBroadcastAsUser", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "sendBroadcastWithMultiplePermissions", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "sendStickyBroadcast", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "sendStickyBroadcastAsUser", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "sendStickyOrderedBroadcast", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "sendStickyOrderedBroadcastAsUser", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startActivities", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startActivity", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startActivityAsUser", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startActivityFromChild", "", "", "Argument[1]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startActivityFromFragment", "", "", "Argument[1]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startActivityIfNeeded", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startForegroundService", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startService", "", "", "Argument[0]", "intent-redirection", "manual"] + - ["android.content", "Context", True, "startServiceAsUser", "", "", "Argument[0]", "intent-redirection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 3e6543297d1..27bc65e8ee2 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -276,8 +276,8 @@ module ModelValidation { [ "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "xss", - "ognl-injection", "intent-start", "pending-intents", "url-redirection", "create-file", - "read-file", "write-file", "set-hostname-verifier", "header-splitting", + "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", + "create-file", "read-file", "write-file", "set-hostname-verifier", "header-splitting", "information-leak", "xslt-injection", "jexl-injection", "bean-validation", "template-injection", "fragment-injection", "command-injection" ] and diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll index 993c2941733..ef5f84001f0 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll @@ -30,7 +30,7 @@ class IntentRedirectionAdditionalTaintStep extends Unit { /** Default sink for Intent redirection vulnerabilities. */ private class DefaultIntentRedirectionSink extends IntentRedirectionSink { - DefaultIntentRedirectionSink() { sinkNode(this, "intent-start") } + DefaultIntentRedirectionSink() { sinkNode(this, "intent-redirection") } } /** diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 6511bf28685..41985affc0e 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -54,7 +54,8 @@ private class IntentCreationSource extends ImplicitPendingIntentSource { private class SendPendingIntent extends ImplicitPendingIntentSink { SendPendingIntent() { - sinkNode(this, "intent-start") and + // intent redirection sinks are method calls that start Android components + sinkNode(this, "intent-redirection") and // implicit intents can't be started as services since API 21 not exists(MethodAccess ma, Method m | ma.getMethod() = m and From 51df84ed1cdc973efbe4a287fffcbdf3a0c6bfc4 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:15:57 -0400 Subject: [PATCH 232/739] Java: update set-hostname-verifier sink kind to hostname-verification --- java/ql/lib/ext/javax.net.ssl.model.yml | 4 ++-- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- .../code/java/security/UnsafeHostnameVerificationQuery.qll | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/ext/javax.net.ssl.model.yml b/java/ql/lib/ext/javax.net.ssl.model.yml index 7cbed92c184..59085b8d120 100644 --- a/java/ql/lib/ext/javax.net.ssl.model.yml +++ b/java/ql/lib/ext/javax.net.ssl.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.net.ssl", "HttpsURLConnection", True, "setDefaultHostnameVerifier", "", "", "Argument[0]", "set-hostname-verifier", "manual"] - - ["javax.net.ssl", "HttpsURLConnection", True, "setHostnameVerifier", "", "", "Argument[0]", "set-hostname-verifier", "manual"] + - ["javax.net.ssl", "HttpsURLConnection", True, "setDefaultHostnameVerifier", "", "", "Argument[0]", "hostname-verification", "manual"] + - ["javax.net.ssl", "HttpsURLConnection", True, "setHostnameVerifier", "", "", "Argument[0]", "hostname-verification", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 27bc65e8ee2..78c98c07b04 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -277,7 +277,7 @@ module ModelValidation { "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "xss", "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", - "create-file", "read-file", "write-file", "set-hostname-verifier", "header-splitting", + "create-file", "read-file", "write-file", "hostname-verification", "header-splitting", "information-leak", "xslt-injection", "jexl-injection", "bean-validation", "template-injection", "fragment-injection", "command-injection" ] and diff --git a/java/ql/lib/semmle/code/java/security/UnsafeHostnameVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeHostnameVerificationQuery.qll index 1fc60e3494e..1b44121591c 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeHostnameVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeHostnameVerificationQuery.qll @@ -74,7 +74,7 @@ module TrustAllHostnameVerifierFlow = DataFlow::Global<TrustAllHostnameVerifierC * A sink that sets the `HostnameVerifier` on `HttpsURLConnection`. */ private class HostnameVerifierSink extends DataFlow::Node { - HostnameVerifierSink() { sinkNode(this, "set-hostname-verifier") } + HostnameVerifierSink() { sinkNode(this, "hostname-verification") } } /** From 041caa740558cc08b974b7df5a80bd3aa425d24a Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:17:08 -0400 Subject: [PATCH 233/739] Java: update header-splitting sink kind to response-splitting --- java/ql/lib/ext/javax.servlet.http.model.yml | 6 +++--- java/ql/lib/ext/javax.ws.rs.core.model.yml | 2 +- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- java/ql/lib/semmle/code/java/security/ResponseSplitting.qll | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/ext/javax.servlet.http.model.yml b/java/ql/lib/ext/javax.servlet.http.model.yml index e4c0a2b2332..6485ea22a2e 100644 --- a/java/ql/lib/ext/javax.servlet.http.model.yml +++ b/java/ql/lib/ext/javax.servlet.http.model.yml @@ -22,10 +22,10 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.servlet.http", "HttpServletResponse", False, "addCookie", "", "", "Argument[0]", "header-splitting", "manual"] - - ["javax.servlet.http", "HttpServletResponse", False, "addHeader", "", "", "Argument[0..1]", "header-splitting", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "addCookie", "", "", "Argument[0]", "response-splitting", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "addHeader", "", "", "Argument[0..1]", "response-splitting", "manual"] - ["javax.servlet.http", "HttpServletResponse", False, "sendError", "(int,String)", "", "Argument[1]", "information-leak", "manual"] - - ["javax.servlet.http", "HttpServletResponse", False, "setHeader", "", "", "Argument[0..1]", "header-splitting", "manual"] + - ["javax.servlet.http", "HttpServletResponse", False, "setHeader", "", "", "Argument[0..1]", "response-splitting", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/javax.ws.rs.core.model.yml b/java/ql/lib/ext/javax.ws.rs.core.model.yml index cf94b255176..dfdf2ee6fd0 100644 --- a/java/ql/lib/ext/javax.ws.rs.core.model.yml +++ b/java/ql/lib/ext/javax.ws.rs.core.model.yml @@ -5,7 +5,7 @@ extensions: data: - ["javax.ws.rs.core", "Response", True, "seeOther", "", "", "Argument[0]", "url-redirection", "manual"] - ["javax.ws.rs.core", "Response", True, "temporaryRedirect", "", "", "Argument[0]", "url-redirection", "manual"] - - ["javax.ws.rs.core", "ResponseBuilder", False, "header", "", "", "Argument[1]", "header-splitting", "manual"] + - ["javax.ws.rs.core", "ResponseBuilder", False, "header", "", "", "Argument[1]", "response-splitting", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 78c98c07b04..e264be4a83b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -277,7 +277,7 @@ module ModelValidation { "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "xss", "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", - "create-file", "read-file", "write-file", "hostname-verification", "header-splitting", + "create-file", "read-file", "write-file", "hostname-verification", "response-splitting", "information-leak", "xslt-injection", "jexl-injection", "bean-validation", "template-injection", "fragment-injection", "command-injection" ] and diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll index 916b6df4372..2e2033443a5 100644 --- a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll +++ b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll @@ -11,7 +11,7 @@ private import semmle.code.java.dataflow.ExternalFlow abstract class HeaderSplittingSink extends DataFlow::Node { } private class DefaultHeaderSplittingSink extends HeaderSplittingSink { - DefaultHeaderSplittingSink() { sinkNode(this, "header-splitting") } + DefaultHeaderSplittingSink() { sinkNode(this, "response-splitting") } } /** A source that introduces data considered safe to use by a header splitting source. */ From ac8d985a6397fb4eda24688dfa8e892d4b52e03b Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:18:11 -0400 Subject: [PATCH 234/739] Java: update xss sink kind to html-injection and js-injection --- java/ql/lib/ext/android.webkit.model.yml | 6 +++--- java/ql/lib/ext/jakarta.faces.context.model.yml | 4 ++-- java/ql/lib/ext/javax.faces.context.model.yml | 4 ++-- java/ql/lib/ext/org.apache.hc.core5.http.model.yml | 2 +- java/ql/lib/ext/org.apache.http.model.yml | 2 +- java/ql/lib/ext/org.apache.http.util.model.yml | 2 +- .../ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 11 ++++++----- java/ql/lib/semmle/code/java/security/XSS.qll | 2 +- 8 files changed, 17 insertions(+), 16 deletions(-) diff --git a/java/ql/lib/ext/android.webkit.model.yml b/java/ql/lib/ext/android.webkit.model.yml index 05058493fe1..d88199c04cb 100644 --- a/java/ql/lib/ext/android.webkit.model.yml +++ b/java/ql/lib/ext/android.webkit.model.yml @@ -10,6 +10,6 @@ extensions: extensible: sinkModel data: # Models representing methods susceptible to XSS attacks. - - ["android.webkit", "WebView", False, "evaluateJavascript", "", "", "Argument[0]", "xss", "manual"] - - ["android.webkit", "WebView", False, "loadData", "", "", "Argument[0]", "xss", "manual"] - - ["android.webkit", "WebView", False, "loadDataWithBaseURL", "", "", "Argument[1]", "xss", "manual"] + - ["android.webkit", "WebView", False, "evaluateJavascript", "", "", "Argument[0]", "js-injection", "manual"] + - ["android.webkit", "WebView", False, "loadData", "", "", "Argument[0]", "html-injection", "manual"] + - ["android.webkit", "WebView", False, "loadDataWithBaseURL", "", "", "Argument[1]", "html-injection", "manual"] diff --git a/java/ql/lib/ext/jakarta.faces.context.model.yml b/java/ql/lib/ext/jakarta.faces.context.model.yml index 84a0fd22710..468ef036c1a 100644 --- a/java/ql/lib/ext/jakarta.faces.context.model.yml +++ b/java/ql/lib/ext/jakarta.faces.context.model.yml @@ -14,5 +14,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["jakarta.faces.context", "ResponseStream", True, "write", "", "", "Argument[0]", "xss", "manual"] - - ["jakarta.faces.context", "ResponseWriter", True, "write", "", "", "Argument[0]", "xss", "manual"] + - ["jakarta.faces.context", "ResponseStream", True, "write", "", "", "Argument[0]", "html-injection", "manual"] + - ["jakarta.faces.context", "ResponseWriter", True, "write", "", "", "Argument[0]", "html-injection", "manual"] diff --git a/java/ql/lib/ext/javax.faces.context.model.yml b/java/ql/lib/ext/javax.faces.context.model.yml index ad33971c2c3..98f3e64ec6c 100644 --- a/java/ql/lib/ext/javax.faces.context.model.yml +++ b/java/ql/lib/ext/javax.faces.context.model.yml @@ -14,5 +14,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.faces.context", "ResponseStream", True, "write", "", "", "Argument[0]", "xss", "manual"] - - ["javax.faces.context", "ResponseWriter", True, "write", "", "", "Argument[0]", "xss", "manual"] + - ["javax.faces.context", "ResponseStream", True, "write", "", "", "Argument[0]", "html-injection", "manual"] + - ["javax.faces.context", "ResponseWriter", True, "write", "", "", "Argument[0]", "html-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.model.yml index 6c1c6d63efe..8922ce55637 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.core5.http", "HttpEntityContainer", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "xss", "manual"] + - ["org.apache.hc.core5.http", "HttpEntityContainer", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "html-injection", "manual"] - ["org.apache.hc.core5.http", "HttpRequest", True, "setUri", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - ["org.apache.hc.core5.http", "HttpRequestFactory", True, "newHttpRequest", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] - ["org.apache.hc.core5.http", "HttpRequestFactory", True, "newHttpRequest", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.http.model.yml b/java/ql/lib/ext/org.apache.http.model.yml index 466fe9d15a4..d03d2fa1a50 100644 --- a/java/ql/lib/ext/org.apache.http.model.yml +++ b/java/ql/lib/ext/org.apache.http.model.yml @@ -10,7 +10,7 @@ extensions: extensible: sinkModel data: - ["org.apache.http", "HttpRequestFactory", True, "newHttpRequest", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.http", "HttpResponse", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "xss", "manual"] + - ["org.apache.http", "HttpResponse", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "html-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.apache.http.util.model.yml b/java/ql/lib/ext/org.apache.http.util.model.yml index d5469664ab6..7e4fd9dde25 100644 --- a/java/ql/lib/ext/org.apache.http.util.model.yml +++ b/java/ql/lib/ext/org.apache.http.util.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.http.util", "EntityUtils", True, "updateEntity", "(HttpResponse,HttpEntity)", "", "Argument[1]", "xss", "manual"] + - ["org.apache.http.util", "EntityUtils", True, "updateEntity", "(HttpResponse,HttpEntity)", "", "Argument[1]", "html-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index e264be4a83b..5d9290fce9f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -275,11 +275,12 @@ module ModelValidation { not kind = [ "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", - "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "xss", - "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", - "create-file", "read-file", "write-file", "hostname-verification", "response-splitting", - "information-leak", "xslt-injection", "jexl-injection", "bean-validation", - "template-injection", "fragment-injection", "command-injection" + "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", + "html-injection", "js-injection", "ognl-injection", "intent-redirection", + "pending-intents", "url-redirection", "create-file", "read-file", "write-file", + "hostname-verification", "response-splitting", "information-leak", "xslt-injection", + "jexl-injection", "bean-validation", "template-injection", "fragment-injection", + "command-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index 2680631318f..bd968bd5fc3 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -39,7 +39,7 @@ class XssAdditionalTaintStep extends Unit { /** A default sink representing methods susceptible to XSS attacks. */ private class DefaultXssSink extends XssSink { DefaultXssSink() { - sinkNode(this, "xss") + sinkNode(this, ["html-injection", "js-injection"]) or exists(MethodAccess ma | ma.getMethod() instanceof WritingMethod and From eb1a8e21890a4f8490cec8ca475972059d881c85 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 30 May 2023 13:03:51 -0400 Subject: [PATCH 235/739] Java: update write-file sink kind to file-system-store --- .../ql/lib/ext/com.google.common.io.model.yml | 2 +- java/ql/lib/ext/hudson.model.yml | 2 +- java/ql/lib/ext/hudson.util.model.yml | 3 +- java/ql/lib/ext/java.io.model.yml | 44 +++++++++---------- java/ql/lib/ext/java.nio.file.model.yml | 6 +-- .../lib/ext/org.apache.commons.io.model.yml | 4 +- .../code/java/dataflow/ExternalFlow.qll | 2 +- ...CleartextStorageAndroidFilesystemQuery.qll | 2 +- .../internal/CaptureModelsSpecific.qll | 2 +- 9 files changed, 33 insertions(+), 34 deletions(-) diff --git a/java/ql/lib/ext/com.google.common.io.model.yml b/java/ql/lib/ext/com.google.common.io.model.yml index 230b596ad29..1158bc21274 100644 --- a/java/ql/lib/ext/com.google.common.io.model.yml +++ b/java/ql/lib/ext/com.google.common.io.model.yml @@ -9,7 +9,7 @@ extensions: - ["com.google.common.io", "Files", False, "readLines", "(File,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - ["com.google.common.io", "Files", False, "toByteArray", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - ["com.google.common.io", "Files", False, "toString", "(File,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - - ["com.google.common.io", "Files", False, "write", "(byte[],File)", "", "Argument[0]", "write-file", "ai-manual"] + - ["com.google.common.io", "Files", False, "write", "(byte[],File)", "", "Argument[0]", "file-content-store", "ai-manual"] - ["com.google.common.io", "Files", False, "write", "(byte[],File)", "", "Argument[1]", "create-file", "manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/hudson.model.yml b/java/ql/lib/ext/hudson.model.yml index 8fa6a8c0653..778094c1cad 100644 --- a/java/ql/lib/ext/hudson.model.yml +++ b/java/ql/lib/ext/hudson.model.yml @@ -7,7 +7,7 @@ extensions: - ["hudson", "FilePath", False, "copyFrom", "(URL)", "", "Argument[0]", "read-file", "manual"] - ["hudson", "FilePath", False, "copyFrom", "(FileItem)", "", "Argument[0]", "read-file", "ai-manual"] - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String,TarCompression)", "", "Argument[1]", "create-file", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String)", "", "Argument[1]", "write-file", "ai-manual"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String)", "", "Argument[1]", "file-content-store", "ai-manual"] - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,FilePath)", "", "Argument[1]", "create-file", "ai-manual"] - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "read-file", "ai-manual"] - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[2]", "create-file", "ai-manual"] diff --git a/java/ql/lib/ext/hudson.util.model.yml b/java/ql/lib/ext/hudson.util.model.yml index 0e34233e735..963783006d2 100644 --- a/java/ql/lib/ext/hudson.util.model.yml +++ b/java/ql/lib/ext/hudson.util.model.yml @@ -15,11 +15,10 @@ extensions: - ["hudson.util", "TextFile", True, "lines", "()", "", "Argument[this]", "read-file", "manual"] - ["hudson.util", "TextFile", True, "read", "()", "", "Argument[this]", "read-file", "manual"] - ["hudson.util", "TextFile", True, "readTrim", "()", "", "Argument[this]", "read-file", "manual"] - - ["hudson.util", "TextFile", True, "write", "(String)", "", "Argument[0]", "write-file", "manual"] + - ["hudson.util", "TextFile", True, "write", "(String)", "", "Argument[0]", "file-content-store", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel data: - ["hudson.util", "QuotedStringTokenizer", True, "tokenize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["hudson.util", "TextFile", True, "TextFile", "(File)", "", "Argument[0]", "Argument[this]", "taint", "ai-manual"] - diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index 2db99b7027e..73d0258f832 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -8,7 +8,7 @@ extensions: - ["java.io", "FileInputStream", True, "FileInputStream", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - ["java.io", "FileInputStream", True, "FileInputStream", "(String)", "", "Argument[0]", "read-file", "ai-manual"] - ["java.io", "FileOutputStream", False, "FileOutputStream", "", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "read-file", "ai-manual"] - ["java.io", "FileSystem", True, "createDirectory", "(File)", "", "Argument[0]", "create-file", "ai-manual"] @@ -19,34 +19,34 @@ extensions: - ["java.io", "PrintStream", False, "PrintStream", "(String)", "", "Argument[0]", "create-file", "manual"] - ["java.io", "PrintStream", False, "PrintStream", "(String,Charset)", "", "Argument[0]", "create-file", "manual"] - ["java.io", "PrintStream", False, "PrintStream", "(String,String)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintStream", True, "append", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "PrintStream", True, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] - - ["java.io", "PrintStream", True, "format", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] - - ["java.io", "PrintStream", True, "print", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "PrintStream", True, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] - - ["java.io", "PrintStream", True, "printf", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] - - ["java.io", "PrintStream", True, "println", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "PrintStream", True, "write", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "PrintStream", True, "writeBytes", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintStream", True, "append", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "PrintStream", True, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"] + - ["java.io", "PrintStream", True, "format", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"] + - ["java.io", "PrintStream", True, "print", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "PrintStream", True, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"] + - ["java.io", "PrintStream", True, "printf", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"] + - ["java.io", "PrintStream", True, "println", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "PrintStream", True, "write", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "PrintStream", True, "writeBytes", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "PrintWriter", False, "PrintWriter", "(File)", "", "Argument[0]", "create-file", "manual"] - ["java.io", "PrintWriter", False, "PrintWriter", "(File,Charset)", "", "Argument[0]", "create-file", "manual"] - ["java.io", "PrintWriter", False, "PrintWriter", "(File,String)", "", "Argument[0]", "create-file", "manual"] - ["java.io", "PrintWriter", False, "PrintWriter", "(String)", "", "Argument[0]", "create-file", "manual"] - ["java.io", "PrintWriter", False, "PrintWriter", "(String,Charset)", "", "Argument[0]", "create-file", "manual"] - ["java.io", "PrintWriter", False, "PrintWriter", "(String,String)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintWriter", False, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] - - ["java.io", "PrintWriter", False, "format", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] - - ["java.io", "PrintWriter", False, "print", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "PrintWriter", False, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "write-file", "manual"] - - ["java.io", "PrintWriter", False, "printf", "(String,Object[])", "", "Argument[0..1]", "write-file", "manual"] - - ["java.io", "PrintWriter", False, "println", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "PrintWriter", False, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"] + - ["java.io", "PrintWriter", False, "format", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"] + - ["java.io", "PrintWriter", False, "print", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "PrintWriter", False, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"] + - ["java.io", "PrintWriter", False, "printf", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"] + - ["java.io", "PrintWriter", False, "println", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "RandomAccessFile", False, "RandomAccessFile", "", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "RandomAccessFile", False, "write", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "RandomAccessFile", False, "writeBytes", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "RandomAccessFile", False, "writeChars", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "RandomAccessFile", False, "writeUTF", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "Writer", True, "append", "", "", "Argument[0]", "write-file", "manual"] - - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "write-file", "manual"] + - ["java.io", "RandomAccessFile", False, "write", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "RandomAccessFile", False, "writeBytes", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "RandomAccessFile", False, "writeChars", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "RandomAccessFile", False, "writeUTF", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "Writer", True, "append", "", "", "Argument[0]", "file-content-store", "manual"] + - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "file-content-store", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 42ae8b9052b..f6728654afe 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -6,7 +6,7 @@ extensions: - ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "read-file", "manual"] - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[0]", "read-file", "manual"] - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[1]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[0]", "write-file", "manual"] + - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[0]", "file-content-store", "manual"] - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[1]", "create-file", "manual"] - ["java.nio.file", "Files", False, "createDirectories", "", "", "Argument[0]", "create-file", "manual"] - ["java.nio.file", "Files", False, "createDirectory", "", "", "Argument[0]", "create-file", "manual"] @@ -32,9 +32,9 @@ extensions: - ["java.nio.file", "Files", False, "readString", "(Path,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - ["java.nio.file", "Files", False, "readString", "(Path)", "", "Argument[0]", "read-file", "ai-manual"] - ["java.nio.file", "Files", False, "write", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "write", "", "", "Argument[1]", "write-file", "manual"] + - ["java.nio.file", "Files", False, "write", "", "", "Argument[1]", "file-content-store", "manual"] - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[1]", "write-file", "manual"] + - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[1]", "file-content-store", "manual"] - ["java.nio.file", "Files", True, "move", "(Path,Path,CopyOption[])", "", "Argument[1]", "create-file", "ai-manual"] - ["java.nio.file", "Files", True, "move", "(Path,Path,CopyOption[])", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - ["java.nio.file", "Files", True, "delete", "(Path)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml index e23dd5fca44..c2892e9595e 100644 --- a/java/ql/lib/ext/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -16,8 +16,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[0]", "write-file", "ai-manual"] + - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[0]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "manual"] - - ["org.apache.commons.io", "FileUtils", True, "copyToFile", "(InputStream,File)", "", "Argument[0]", "write-file", "ai-manual"] + - ["org.apache.commons.io", "FileUtils", True, "copyToFile", "(InputStream,File)", "", "Argument[0]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", True, "copyToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "manual"] - ["org.apache.commons.io", "FileUtils", True, "openInputStream", "(File)", "", "Argument[0]", "read-file", "ai-manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 5d9290fce9f..7633f47c3bd 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -277,7 +277,7 @@ module ModelValidation { "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", "ognl-injection", "intent-redirection", - "pending-intents", "url-redirection", "create-file", "read-file", "write-file", + "pending-intents", "url-redirection", "create-file", "read-file", "file-content-store", "hostname-verification", "response-splitting", "information-leak", "xslt-injection", "jexl-injection", "bean-validation", "template-injection", "fragment-injection", "command-injection" diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index 2641a3ab0df..cf081085bab 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -40,7 +40,7 @@ class LocalFileOpenCall extends Storable { /** Holds if `input` is written into `file`. */ private predicate filesystemInput(DataFlow::Node file, Argument input) { - exists(DataFlow::Node write | sinkNode(write, "write-file") | + exists(DataFlow::Node write | sinkNode(write, "file-content-store") | input = write.asExpr() or isVarargs(input, write) ) and diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index 8583e793fc9..7877594519a 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -252,7 +252,7 @@ bindingset[kind] predicate isRelevantSinkKind(string kind) { not kind = "log-injection" and not kind.matches("regex-use%") and - not kind = "write-file" + not kind = "file-content-store" } /** From cb10f4976b260df51a82973804774475a079793d Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 30 May 2023 13:06:37 -0400 Subject: [PATCH 236/739] Java: update create/read-file sink kinds to path-injection --- .../ql/lib/ext/com.google.common.io.model.yml | 14 +- .../ext/com.thoughtworks.xstream.model.yml | 2 +- .../lib/ext/generated/kotlinstdlib.model.yml | 20 +- .../generated/org.apache.commons.io.model.yml | 184 +++++++++--------- java/ql/lib/ext/hudson.lifecycle.model.yml | 2 +- java/ql/lib/ext/hudson.model.model.yml | 8 +- java/ql/lib/ext/hudson.model.yml | 18 +- java/ql/lib/ext/hudson.scm.model.yml | 10 +- java/ql/lib/ext/hudson.util.io.model.yml | 4 +- java/ql/lib/ext/hudson.util.jna.model.yml | 6 +- java/ql/lib/ext/hudson.util.model.yml | 24 +-- ...tty.handler.codec.http.multipart.model.yml | 2 +- .../ql/lib/ext/io.netty.handler.ssl.model.yml | 4 +- .../lib/ext/io.netty.handler.stream.model.yml | 2 +- .../lib/ext/io.netty.util.internal.model.yml | 2 +- java/ql/lib/ext/java.io.model.yml | 44 ++--- java/ql/lib/ext/java.lang.model.yml | 10 +- java/ql/lib/ext/java.nio.file.model.yml | 72 +++---- java/ql/lib/ext/javax.servlet.model.yml | 2 +- .../ext/javax.xml.transform.stream.model.yml | 2 +- java/ql/lib/ext/kotlin.io.model.yml | 8 +- .../lib/ext/org.apache.commons.io.model.yml | 6 +- .../ql/lib/ext/org.apache.tools.ant.model.yml | 10 +- .../org.apache.tools.ant.taskdefs.model.yml | 12 +- ...dehaus.cargo.container.installer.model.yml | 4 +- ...org.kohsuke.stapler.framework.io.model.yml | 2 +- .../org.openjdk.jmh.runner.options.model.yml | 2 +- .../code/java/dataflow/ExternalFlow.qll | 2 +- ...CleartextStorageAndroidFilesystemQuery.qll | 2 +- .../code/java/security/TaintedPathQuery.qll | 4 +- .../code/java/security/ZipSlipQuery.qll | 2 +- .../CWE/CWE-200/AndroidFileIntentSink.qll | 2 +- 32 files changed, 243 insertions(+), 245 deletions(-) diff --git a/java/ql/lib/ext/com.google.common.io.model.yml b/java/ql/lib/ext/com.google.common.io.model.yml index 1158bc21274..9f3f3307462 100644 --- a/java/ql/lib/ext/com.google.common.io.model.yml +++ b/java/ql/lib/ext/com.google.common.io.model.yml @@ -3,14 +3,14 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["com.google.common.io", "Files", False, "asCharSink", "(File,Charset,FileWriteMode[])", "", "Argument[0]", "create-file", "ai-manual"] - - ["com.google.common.io", "Files", False, "asCharSource", "(File,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - - ["com.google.common.io", "Files", False, "copy", "(File,OutputStream)", "", "Argument[0]", "read-file", "ai-manual"] - - ["com.google.common.io", "Files", False, "readLines", "(File,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - - ["com.google.common.io", "Files", False, "toByteArray", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - - ["com.google.common.io", "Files", False, "toString", "(File,Charset)", "", "Argument[0]", "read-file", "ai-manual"] + - ["com.google.common.io", "Files", False, "asCharSink", "(File,Charset,FileWriteMode[])", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.google.common.io", "Files", False, "asCharSource", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.google.common.io", "Files", False, "copy", "(File,OutputStream)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.google.common.io", "Files", False, "readLines", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.google.common.io", "Files", False, "toByteArray", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.google.common.io", "Files", False, "toString", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - ["com.google.common.io", "Files", False, "write", "(byte[],File)", "", "Argument[0]", "file-content-store", "ai-manual"] - - ["com.google.common.io", "Files", False, "write", "(byte[],File)", "", "Argument[1]", "create-file", "manual"] + - ["com.google.common.io", "Files", False, "write", "(byte[],File)", "", "Argument[1]", "path-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/com.thoughtworks.xstream.model.yml b/java/ql/lib/ext/com.thoughtworks.xstream.model.yml index d73cc27e729..c34bb91d42c 100644 --- a/java/ql/lib/ext/com.thoughtworks.xstream.model.yml +++ b/java/ql/lib/ext/com.thoughtworks.xstream.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["com.thoughtworks.xstream", "XStream", True, "fromXML", "(File)", "", "Argument[0]", "read-file", "ai-manual"] + - ["com.thoughtworks.xstream", "XStream", True, "fromXML", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/generated/kotlinstdlib.model.yml b/java/ql/lib/ext/generated/kotlinstdlib.model.yml index bc296146214..16e0cc97420 100644 --- a/java/ql/lib/ext/generated/kotlinstdlib.model.yml +++ b/java/ql/lib/ext/generated/kotlinstdlib.model.yml @@ -6,16 +6,16 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["kotlin.io", "FilesKt", false, "appendBytes", "(File,byte[])", "", "Argument[0]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "appendText", "(File,String,Charset)", "", "Argument[0]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "bufferedWriter", "(File,Charset,int)", "", "Argument[0]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "copyRecursively", "(File,File,boolean,Function2)", "", "Argument[1]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "copyTo", "(File,File,boolean,int)", "", "Argument[1]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "outputStream", "(File)", "", "Argument[0]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "printWriter", "(File,Charset)", "", "Argument[0]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "writeBytes", "(File,byte[])", "", "Argument[0]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "writeText", "(File,String,Charset)", "", "Argument[0]", "create-file", "df-generated"] - - ["kotlin.io", "FilesKt", false, "writer", "(File,Charset)", "", "Argument[0]", "create-file", "df-generated"] + - ["kotlin.io", "FilesKt", false, "appendBytes", "(File,byte[])", "", "Argument[0]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "appendText", "(File,String,Charset)", "", "Argument[0]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "bufferedWriter", "(File,Charset,int)", "", "Argument[0]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "copyRecursively", "(File,File,boolean,Function2)", "", "Argument[1]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "copyTo", "(File,File,boolean,int)", "", "Argument[1]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "outputStream", "(File)", "", "Argument[0]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "printWriter", "(File,Charset)", "", "Argument[0]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "writeBytes", "(File,byte[])", "", "Argument[0]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "writeText", "(File,String,Charset)", "", "Argument[0]", "path-injection", "df-generated"] + - ["kotlin.io", "FilesKt", false, "writer", "(File,Charset)", "", "Argument[0]", "path-injection", "df-generated"] - ["kotlin.io", "TextStreamsKt", false, "readBytes", "(URL)", "", "Argument[0]", "open-url", "df-generated"] - ["kotlin.io", "TextStreamsKt", false, "readText", "(URL,Charset)", "", "Argument[0]", "open-url", "df-generated"] diff --git a/java/ql/lib/ext/generated/org.apache.commons.io.model.yml b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml index 3a40daa82ec..e43b2720252 100644 --- a/java/ql/lib/ext/generated/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml @@ -6,100 +6,100 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.commons.io.file", "PathFilter", true, "accept", "(Path,BasicFileAttributes)", "", "Argument[0]", "create-file", "df-generated"] + - ["org.apache.commons.io.file", "PathFilter", true, "accept", "(Path,BasicFileAttributes)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(Path,Path,CopyOption[])", "", "Argument[1]", "create-file", "df-generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(Path,Path,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io.file", "PathUtils", false, "newOutputStream", "(Path,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.file", "PathUtils", false, "writeString", "(Path,CharSequence,Charset,OpenOption[])", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filter", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterList", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterSet", "(IOFileFilter,File[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io.input", "Tailer$Tailable", true, "getRandomAccess", "(String)", "", "Argument[this]", "create-file", "df-generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "newOutputStream", "(Path,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "writeString", "(Path,CharSequence,Charset,OpenOption[])", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filter", "(IOFileFilter,File[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterList", "(IOFileFilter,File[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterSet", "(IOFileFilter,File[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io.input", "Tailer$Tailable", true, "getRandomAccess", "(String)", "", "Argument[this]", "path-injection", "df-generated"] - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(URL)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,CharsetEncoder)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,CharsetEncoder,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,String,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,Charset)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,Charset,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,CharsetEncoder)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,CharsetEncoder,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,String,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset,boolean,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String,boolean,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter,boolean)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter,boolean,CopyOption[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyDirectoryToDirectory", "(File,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,CopyOption[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,boolean)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,boolean,CopyOption[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyFileToDirectory", "(File,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyFileToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(File,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(Iterable,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "df-generated"] + - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,CharsetEncoder)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,CharsetEncoder,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,Charset)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,Charset,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,CharsetEncoder)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,CharsetEncoder,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(String,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,Charset,boolean,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,String,boolean,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(File,boolean,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "LockableFileWriter", true, "LockableFileWriter", "(String,boolean,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io.output", "XmlStreamWriter", true, "XmlStreamWriter", "(File,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter,boolean)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,FileFilter,boolean,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectory", "(File,File,boolean)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyDirectoryToDirectory", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,boolean)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFile", "(File,File,boolean,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFileToDirectory", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyFileToDirectory", "(File,File,boolean)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(Iterable,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyToFile", "(InputStream,File)", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[1]", "create-file", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "moveDirectory", "(File,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "moveDirectoryToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "moveFile", "(File,File)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "moveFile", "(File,File,CopyOption[])", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "moveFileToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "moveToDirectory", "(File,File,boolean)", "", "Argument[1]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "newOutputStream", "(File,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "openOutputStream", "(File)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "openOutputStream", "(File,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "touch", "(File)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,Charset)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,Charset,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,String,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[])", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],int,int)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],int,int,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,String,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,String,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,Charset)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,Charset,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String,boolean)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,boolean)", "", "Argument[0]", "create-file", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveDirectory", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveDirectoryToDirectory", "(File,File,boolean)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFile", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFile", "(File,File,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveFileToDirectory", "(File,File,boolean)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "moveToDirectory", "(File,File,boolean)", "", "Argument[1]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "newOutputStream", "(File,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "openOutputStream", "(File)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "openOutputStream", "(File,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "touch", "(File)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,Charset)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,Charset,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "write", "(File,CharSequence,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[])", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],int,int)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeByteArrayToFile", "(File,byte[],int,int,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,Collection,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeLines", "(File,String,Collection,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,Charset)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,Charset,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[1]", "create-file", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,OutputStream)", "", "Argument[0]", "open-url", "df-generated"] - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URI)", "", "Argument[0]", "open-url", "df-generated"] - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URL)", "", "Argument[0]", "open-url", "df-generated"] @@ -109,9 +109,9 @@ extensions: - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL)", "", "Argument[0]", "open-url", "df-generated"] - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,Charset)", "", "Argument[0]", "open-url", "df-generated"] - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,String)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(File)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(Path)", "", "Argument[0]", "create-file", "df-generated"] - - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(String)", "", "Argument[0]", "create-file", "df-generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(File)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(Path)", "", "Argument[0]", "path-injection", "df-generated"] + - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(String)", "", "Argument[0]", "path-injection", "df-generated"] - addsTo: @@ -1428,5 +1428,3 @@ extensions: - ["org.apache.commons.io", "UncheckedIOExceptions", "UncheckedIOExceptions", "()", "summary", "df-generated"] - ["org.apache.commons.io", "UncheckedIOExceptions", "create", "(Object)", "summary", "df-generated"] - ["org.apache.commons.io", "UncheckedIOExceptions", "wrap", "(IOException,Object)", "summary", "df-generated"] - - \ No newline at end of file diff --git a/java/ql/lib/ext/hudson.lifecycle.model.yml b/java/ql/lib/ext/hudson.lifecycle.model.yml index be8c5fe843a..fde691fe175 100644 --- a/java/ql/lib/ext/hudson.lifecycle.model.yml +++ b/java/ql/lib/ext/hudson.lifecycle.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.lifecycle", "Lifecycle", True, "rewriteHudsonWar", "(File)", "", "Argument[0]", "create-file", "ai-manual"] + - ["hudson.lifecycle", "Lifecycle", True, "rewriteHudsonWar", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/hudson.model.model.yml b/java/ql/lib/ext/hudson.model.model.yml index 04701194c06..2b5423961e3 100644 --- a/java/ql/lib/ext/hudson.model.model.yml +++ b/java/ql/lib/ext/hudson.model.model.yml @@ -5,11 +5,11 @@ extensions: data: - ["hudson.model", "DownloadService", True, "loadJSON", "(URL)", "", "Argument[0]", "open-url", "ai-manual"] - ["hudson.model", "DownloadService", True, "loadJSONHTML", "(URL)", "", "Argument[0]", "open-url", "ai-manual"] - - ["hudson.model", "DirectoryBrowserSupport", False, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[1]", "read-file", "ai-manual"] - - ["hudson.model", "Items", True, "load", "(ItemGroup,File)", "", "Argument[1]", "read-file", "ai-manual"] + - ["hudson.model", "DirectoryBrowserSupport", False, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["hudson.model", "Items", True, "load", "(ItemGroup,File)", "", "Argument[1]", "path-injection", "ai-manual"] - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "download", "(DownloadJob,URL)", "", "Argument[1]", "open-url", "ai-manual"] - - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "install", "(DownloadJob,File,File)", "", "Argument[1]", "create-file", "ai-manual"] # should be delete-file - - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "install", "(DownloadJob,File,File)", "", "Argument[2]", "create-file", "ai-manual"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "install", "(DownloadJob,File,File)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "install", "(DownloadJob,File,File)", "", "Argument[2]", "path-injection", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/hudson.model.yml b/java/ql/lib/ext/hudson.model.yml index 778094c1cad..43955cb22f0 100644 --- a/java/ql/lib/ext/hudson.model.yml +++ b/java/ql/lib/ext/hudson.model.yml @@ -3,17 +3,17 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson", "FilePath", False, "copyFrom", "(FilePath)", "", "Argument[0]", "read-file", "manual"] - - ["hudson", "FilePath", False, "copyFrom", "(URL)", "", "Argument[0]", "read-file", "manual"] - - ["hudson", "FilePath", False, "copyFrom", "(FileItem)", "", "Argument[0]", "read-file", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String,TarCompression)", "", "Argument[1]", "create-file", "ai-manual"] + - ["hudson", "FilePath", False, "copyFrom", "(FilePath)", "", "Argument[0]", "path-injection", "manual"] + - ["hudson", "FilePath", False, "copyFrom", "(URL)", "", "Argument[0]", "path-injection", "manual"] + - ["hudson", "FilePath", False, "copyFrom", "(FileItem)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String,TarCompression)", "", "Argument[1]", "path-injection", "ai-manual"] - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String)", "", "Argument[1]", "file-content-store", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,FilePath)", "", "Argument[1]", "create-file", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "read-file", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[2]", "create-file", "ai-manual"] - - ["hudson", "FilePath", False, "copyTo", "(FilePath)", "", "Argument[0]", "create-file", "ai-manual"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,FilePath)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", False, "copyTo", "(FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson", "FilePath", False, "installIfNecessaryFrom", "(URL,TaskListener,String)", "", "Argument[0]", "open-url", "ai-manual"] - - ["hudson", "FilePath", False, "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "", "Argument[0]", "read-file", "ai-manual"] + - ["hudson", "FilePath", False, "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/hudson.scm.model.yml b/java/ql/lib/ext/hudson.scm.model.yml index f37c3442532..dc6e0bfa5bb 100644 --- a/java/ql/lib/ext/hudson.scm.model.yml +++ b/java/ql/lib/ext/hudson.scm.model.yml @@ -3,11 +3,11 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.scm", "ChangeLogParser", True, "parse", "(AbstractBuild,File)", "", "Argument[1]", "read-file", "ai-manual"] - - ["hudson.scm", "ChangeLogParser", True, "parse", "(Run,RepositoryBrowser,File)", "", "Argument[2]", "read-file", "ai-manual"] - - ["hudson.scm", "SCM", True, "checkout", "(AbstractBuild,Launcher,FilePath,BuildListener,File)", "", "Argument[2]", "create-file", "ai-manual"] - - ["hudson.scm", "SCM", True, "checkout", "(Run,Launcher,FilePath,TaskListener,File,SCMRevisionState)", "", "Argument[2]", "create-file", "ai-manual"] - - ["hudson.scm", "SCM", True, "compareRemoteRevisionWith", "(Job,Launcher,FilePath,TaskListener,SCMRevisionState)", "", "Argument[2]", "read-file", "ai-manual"] + - ["hudson.scm", "ChangeLogParser", True, "parse", "(AbstractBuild,File)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["hudson.scm", "ChangeLogParser", True, "parse", "(Run,RepositoryBrowser,File)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["hudson.scm", "SCM", True, "checkout", "(AbstractBuild,Launcher,FilePath,BuildListener,File)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["hudson.scm", "SCM", True, "checkout", "(Run,Launcher,FilePath,TaskListener,File,SCMRevisionState)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["hudson.scm", "SCM", True, "compareRemoteRevisionWith", "(Job,Launcher,FilePath,TaskListener,SCMRevisionState)", "", "Argument[2]", "path-injection", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/hudson.util.io.model.yml b/java/ql/lib/ext/hudson.util.io.model.yml index 65e0f3efb27..3d29b93e20c 100644 --- a/java/ql/lib/ext/hudson.util.io.model.yml +++ b/java/ql/lib/ext/hudson.util.io.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.util.io", "ReopenableFileOutputStream", True, "ReopenableFileOutputStream", "(File)", "", "Argument[0]", "create-file", "ai-manual"] - - ["hudson.util.io", "RewindableFileOutputStream", True, "RewindableFileOutputStream", "(File)", "", "Argument[0]", "create-file", "ai-manual"] + - ["hudson.util.io", "ReopenableFileOutputStream", True, "ReopenableFileOutputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util.io", "RewindableFileOutputStream", True, "RewindableFileOutputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/hudson.util.jna.model.yml b/java/ql/lib/ext/hudson.util.jna.model.yml index c67d645f950..c840d0f4725 100644 --- a/java/ql/lib/ext/hudson.util.jna.model.yml +++ b/java/ql/lib/ext/hudson.util.jna.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.util.jna", "GNUCLibrary", True, "open", "(String,int)", "", "Argument[0]", "read-file", "ai-manual"] - - ["hudson.util.jna", "Kernel32", True, "MoveFileExA", "(String,String,int)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - - ["hudson.util.jna", "Kernel32", True, "MoveFileExA", "(String,String,int)", "", "Argument[1]", "create-file", "ai-manual"] + - ["hudson.util.jna", "GNUCLibrary", True, "open", "(String,int)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util.jna", "Kernel32", True, "MoveFileExA", "(String,String,int)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util.jna", "Kernel32", True, "MoveFileExA", "(String,String,int)", "", "Argument[1]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/hudson.util.model.yml b/java/ql/lib/ext/hudson.util.model.yml index 963783006d2..39c5b55f349 100644 --- a/java/ql/lib/ext/hudson.util.model.yml +++ b/java/ql/lib/ext/hudson.util.model.yml @@ -3,18 +3,18 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(File)", "", "Argument[0]", "create-file", "ai-manual"] - - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset,boolean,boolean)", "", "Argument[0]", "create-file", "ai-manual"] - - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset)", "", "Argument[0]", "create-file", "ai-manual"] - - ["hudson.util", "ClasspathBuilder", True, "add", "(FilePath)", "", "Argument[0]", "read-file", "ai-manual"] - - ["hudson.util", "IOUtils", True, "mkdirs", "(File)", "", "Argument[0]", "create-file", "ai-manual"] - - ["hudson.util", "StreamTaskListener", True, "StreamTaskListener", "(File,boolean,Charset)", "", "Argument[0]", "create-file", "ai-manual"] - - ["hudson.util", "TextFile", True, "delete", "()", "", "Argument[this]", "create-file", "manual"] - - ["hudson.util", "TextFile", True, "fastTail", "", "", "Argument[this]", "read-file", "manual"] - - ["hudson.util", "TextFile", True, "head", "", "", "Argument[this]", "read-file", "manual"] - - ["hudson.util", "TextFile", True, "lines", "()", "", "Argument[this]", "read-file", "manual"] - - ["hudson.util", "TextFile", True, "read", "()", "", "Argument[this]", "read-file", "manual"] - - ["hudson.util", "TextFile", True, "readTrim", "()", "", "Argument[this]", "read-file", "manual"] + - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset,boolean,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util", "ClasspathBuilder", True, "add", "(FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util", "IOUtils", True, "mkdirs", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util", "StreamTaskListener", True, "StreamTaskListener", "(File,boolean,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util", "TextFile", True, "delete", "()", "", "Argument[this]", "path-injection", "manual"] + - ["hudson.util", "TextFile", True, "fastTail", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson.util", "TextFile", True, "head", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson.util", "TextFile", True, "lines", "()", "", "Argument[this]", "path-injection", "manual"] + - ["hudson.util", "TextFile", True, "read", "()", "", "Argument[this]", "path-injection", "manual"] + - ["hudson.util", "TextFile", True, "readTrim", "()", "", "Argument[this]", "path-injection", "manual"] - ["hudson.util", "TextFile", True, "write", "(String)", "", "Argument[0]", "file-content-store", "manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml index 4090f6356bf..a44a2c6c400 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.handler.codec.http.multipart", "HttpPostRequestEncoder", True, "addBodyFileUpload", "(String,File,String,boolean)", "", "Argument[1]", "read-file", "ai-manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestEncoder", True, "addBodyFileUpload", "(String,File,String,boolean)", "", "Argument[1]", "path-injection", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/io.netty.handler.ssl.model.yml b/java/ql/lib/ext/io.netty.handler.ssl.model.yml index 63628323f49..42cf9892f81 100644 --- a/java/ql/lib/ext/io.netty.handler.ssl.model.yml +++ b/java/ql/lib/ext/io.netty.handler.ssl.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.handler.ssl", "OpenSslServerContext", False, "OpenSslServerContext", "(File,File)", "", "Argument[0]", "read-file", "ai-manual"] - - ["io.netty.handler.ssl", "SslContextBuilder", False, "forServer", "(File,File)", "", "Argument[0]", "read-file", "ai-manual"] + - ["io.netty.handler.ssl", "OpenSslServerContext", False, "OpenSslServerContext", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["io.netty.handler.ssl", "SslContextBuilder", False, "forServer", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/io.netty.handler.stream.model.yml b/java/ql/lib/ext/io.netty.handler.stream.model.yml index 1d305863f6c..f4e635f4437 100644 --- a/java/ql/lib/ext/io.netty.handler.stream.model.yml +++ b/java/ql/lib/ext/io.netty.handler.stream.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.handler.stream", "ChunkedFile", True, "ChunkedFile", "(RandomAccessFile,long,long,int)", "", "Argument[0]", "read-file", "ai-manual"] + - ["io.netty.handler.stream", "ChunkedFile", True, "ChunkedFile", "(RandomAccessFile,long,long,int)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/io.netty.util.internal.model.yml b/java/ql/lib/ext/io.netty.util.internal.model.yml index 477b8e88858..d705873cc55 100644 --- a/java/ql/lib/ext/io.netty.util.internal.model.yml +++ b/java/ql/lib/ext/io.netty.util.internal.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.util.internal", "PlatformDependent", False, "createTempFile", "(String,String,File)", "", "Argument[2]", "create-file", "ai-manual"] + - ["io.netty.util.internal", "PlatformDependent", False, "createTempFile", "(String,String,File)", "", "Argument[2]", "path-injection", "ai-manual"] - ["io.netty.util.internal", "SocketUtils", False, "connect", "(Socket,SocketAddress,int)", "", "Argument[1]", "open-url", "ai-manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index 73d0258f832..9d22122ae30 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -3,22 +3,22 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.io", "File", True, "createTempFile", "(String,String,File)", "", "Argument[2]", "create-file", "ai-manual"] - - ["java.io", "File", True, "renameTo", "(File)", "", "Argument[0]", "create-file", "ai-manual"] - - ["java.io", "FileInputStream", True, "FileInputStream", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.io", "FileInputStream", True, "FileInputStream", "(String)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.io", "FileOutputStream", False, "FileOutputStream", "", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "File", True, "createTempFile", "(String,String,File)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["java.io", "File", True, "renameTo", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.io", "FileInputStream", True, "FileInputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.io", "FileInputStream", True, "FileInputStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.io", "FileOutputStream", False, "FileOutputStream", "", "", "Argument[0]", "path-injection", "manual"] - ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "file-content-store", "manual"] - - ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.io", "FileSystem", True, "createDirectory", "(File)", "", "Argument[0]", "create-file", "ai-manual"] - - ["java.io", "FileWriter", False, "FileWriter", "", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintStream", False, "PrintStream", "(File)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintStream", False, "PrintStream", "(File,Charset)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintStream", False, "PrintStream", "(File,String)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintStream", False, "PrintStream", "(String)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintStream", False, "PrintStream", "(String,Charset)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintStream", False, "PrintStream", "(String,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.io", "FileSystem", True, "createDirectory", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.io", "FileWriter", False, "FileWriter", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File,Charset)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(File,String)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String,Charset)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintStream", False, "PrintStream", "(String,String)", "", "Argument[0]", "path-injection", "manual"] - ["java.io", "PrintStream", True, "append", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "PrintStream", True, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"] - ["java.io", "PrintStream", True, "format", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"] @@ -28,19 +28,19 @@ extensions: - ["java.io", "PrintStream", True, "println", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "PrintStream", True, "write", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "PrintStream", True, "writeBytes", "", "", "Argument[0]", "file-content-store", "manual"] - - ["java.io", "PrintWriter", False, "PrintWriter", "(File)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintWriter", False, "PrintWriter", "(File,Charset)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintWriter", False, "PrintWriter", "(File,String)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintWriter", False, "PrintWriter", "(String)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintWriter", False, "PrintWriter", "(String,Charset)", "", "Argument[0]", "create-file", "manual"] - - ["java.io", "PrintWriter", False, "PrintWriter", "(String,String)", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File,Charset)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(File,String)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String,Charset)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "PrintWriter", False, "PrintWriter", "(String,String)", "", "Argument[0]", "path-injection", "manual"] - ["java.io", "PrintWriter", False, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"] - ["java.io", "PrintWriter", False, "format", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"] - ["java.io", "PrintWriter", False, "print", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "PrintWriter", False, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"] - ["java.io", "PrintWriter", False, "printf", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"] - ["java.io", "PrintWriter", False, "println", "", "", "Argument[0]", "file-content-store", "manual"] - - ["java.io", "RandomAccessFile", False, "RandomAccessFile", "", "", "Argument[0]", "create-file", "manual"] + - ["java.io", "RandomAccessFile", False, "RandomAccessFile", "", "", "Argument[0]", "path-injection", "manual"] - ["java.io", "RandomAccessFile", False, "write", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "RandomAccessFile", False, "writeBytes", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "RandomAccessFile", False, "writeChars", "", "", "Argument[0]", "file-content-store", "manual"] diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index b5db4e60f58..ed14b2495a3 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -3,11 +3,11 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.lang", "Class", False, "getResource", "(String)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.lang", "Class", False, "getResourceAsStream", "(String)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.lang", "ClassLoader", True, "getSystemResource", "(String)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "read-file", "ai-manual"] + - ["java.lang", "Class", False, "getResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.lang", "Class", False, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.lang", "ClassLoader", True, "getSystemResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] # These are modeled in plain CodeQL. TODO: migrate them. # - ["java.lang", "ProcessBuilder", False, "command", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"] # - ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index f6728654afe..b6d161c00f4 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -3,45 +3,45 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "read-file", "manual"] - - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[0]", "read-file", "manual"] - - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[1]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[1]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[0]", "file-content-store", "manual"] - - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[1]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "createDirectories", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "createDirectory", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "createFile", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "createLink", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "createSymbolicLink", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "createTempDirectory", "(Path,String,FileAttribute[])", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "createTempFile", "(Path,String,String,FileAttribute[])", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "delete", "(Path)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - - ["java.nio.file", "Files", False, "lines", "(Path,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "lines", "(Path)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "move", "", "", "Argument[1]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "newBufferedReader", "(Path,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "newBufferedReader", "(Path)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "newBufferedWriter", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "newOutputStream", "", "", "Argument[0]", "create-file", "manual"] - - ["java.nio.file", "Files", False, "readAllBytes", "(Path)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "readAllLines", "(Path,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "readAllLines", "(Path)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "readString", "(Path,Charset)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "readString", "(Path)", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", False, "write", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[1]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "createDirectories", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "createDirectory", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "createFile", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "createLink", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "createSymbolicLink", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "createTempDirectory", "(Path,String,FileAttribute[])", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "createTempFile", "(Path,String,String,FileAttribute[])", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "delete", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "lines", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "lines", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "move", "", "", "Argument[1]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "newBufferedReader", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "newBufferedReader", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "newBufferedWriter", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "newOutputStream", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "readAllBytes", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "readAllLines", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "readAllLines", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "readString", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "readString", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "write", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "write", "", "", "Argument[1]", "file-content-store", "manual"] - - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[0]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[1]", "file-content-store", "manual"] - - ["java.nio.file", "Files", True, "move", "(Path,Path,CopyOption[])", "", "Argument[1]", "create-file", "ai-manual"] - - ["java.nio.file", "Files", True, "move", "(Path,Path,CopyOption[])", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - - ["java.nio.file", "Files", True, "delete", "(Path)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - - ["java.nio.file", "Files", True, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "read-file", "ai-manual"] - - ["java.nio.file", "Files", True, "newOutputStream", "(Path,OpenOption[])", "", "Argument[0]", "create-file", "ai-manual"] - - ["java.nio.file", "SecureDirectoryStream", True, "deleteDirectory", "(Path)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - - ["java.nio.file", "SecureDirectoryStream", True, "deleteFile", "(Path)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file + - ["java.nio.file", "Files", True, "move", "(Path,Path,CopyOption[])", "", "Argument[1]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", True, "move", "(Path,Path,CopyOption[])", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", True, "delete", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", True, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", True, "newOutputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "SecureDirectoryStream", True, "deleteDirectory", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "SecureDirectoryStream", True, "deleteFile", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/javax.servlet.model.yml b/java/ql/lib/ext/javax.servlet.model.yml index fae0bd6f2b3..7d7f432d2bd 100644 --- a/java/ql/lib/ext/javax.servlet.model.yml +++ b/java/ql/lib/ext/javax.servlet.model.yml @@ -14,4 +14,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.servlet", "ServletContext", True, "getResourceAsStream", "(String)", "", "Argument[0]", "read-file", "ai-manual"] + - ["javax.servlet", "ServletContext", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/javax.xml.transform.stream.model.yml b/java/ql/lib/ext/javax.xml.transform.stream.model.yml index c058a88f337..8cb96b4c775 100644 --- a/java/ql/lib/ext/javax.xml.transform.stream.model.yml +++ b/java/ql/lib/ext/javax.xml.transform.stream.model.yml @@ -9,4 +9,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.xml.transform.stream", "StreamResult", True, "StreamResult", "(File)", "", "Argument[0]", "create-file", "ai-manual"] + - ["javax.xml.transform.stream", "StreamResult", True, "StreamResult", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/kotlin.io.model.yml b/java/ql/lib/ext/kotlin.io.model.yml index 335457a48a0..98de45df9d6 100644 --- a/java/ql/lib/ext/kotlin.io.model.yml +++ b/java/ql/lib/ext/kotlin.io.model.yml @@ -3,10 +3,10 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["kotlin.io", "FilesKt", False, "deleteRecursively", "(File)", "", "Argument[0]", "create-file", "ai-manual"] # should be delete-file - - ["kotlin.io", "FilesKt", False, "inputStream", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - - ["kotlin.io", "FilesKt", False, "readBytes", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - - ["kotlin.io", "FilesKt", False, "readText", "(File,Charset)", "", "Argument[0]", "read-file", "ai-manual"] + - ["kotlin.io", "FilesKt", False, "deleteRecursively", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["kotlin.io", "FilesKt", False, "inputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["kotlin.io", "FilesKt", False, "readBytes", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["kotlin.io", "FilesKt", False, "readText", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml index c2892e9595e..e80bc525883 100644 --- a/java/ql/lib/ext/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -17,7 +17,7 @@ extensions: extensible: sinkModel data: - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[0]", "file-content-store", "ai-manual"] - - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "manual"] + - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[1]", "path-injection", "manual"] - ["org.apache.commons.io", "FileUtils", True, "copyToFile", "(InputStream,File)", "", "Argument[0]", "file-content-store", "ai-manual"] - - ["org.apache.commons.io", "FileUtils", True, "copyToFile", "(InputStream,File)", "", "Argument[1]", "create-file", "manual"] - - ["org.apache.commons.io", "FileUtils", True, "openInputStream", "(File)", "", "Argument[0]", "read-file", "ai-manual"] + - ["org.apache.commons.io", "FileUtils", True, "copyToFile", "(InputStream,File)", "", "Argument[1]", "path-injection", "manual"] + - ["org.apache.commons.io", "FileUtils", True, "openInputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.apache.tools.ant.model.yml b/java/ql/lib/ext/org.apache.tools.ant.model.yml index bee9b475ef7..474429db030 100644 --- a/java/ql/lib/ext/org.apache.tools.ant.model.yml +++ b/java/ql/lib/ext/org.apache.tools.ant.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.tools.ant", "AntClassLoader", True, "addPathComponent", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(ClassLoader,Project,Path,boolean)", "", "Argument[2]", "read-file", "ai-manual"] - - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(Project,Path,boolean)", "", "Argument[1]", "read-file", "ai-manual"] - - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(Project,Path)", "", "Argument[1]", "read-file", "ai-manual"] - - ["org.apache.tools.ant", "DirectoryScanner", True, "setBasedir", "(File)", "", "Argument[0]", "read-file", "ai-manual"] + - ["org.apache.tools.ant", "AntClassLoader", True, "addPathComponent", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(ClassLoader,Project,Path,boolean)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(Project,Path,boolean)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(Project,Path)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant", "DirectoryScanner", True, "setBasedir", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.apache.tools.ant.taskdefs.model.yml b/java/ql/lib/ext/org.apache.tools.ant.taskdefs.model.yml index 29b4ee0d16e..aaacf02d58c 100644 --- a/java/ql/lib/ext/org.apache.tools.ant.taskdefs.model.yml +++ b/java/ql/lib/ext/org.apache.tools.ant.taskdefs.model.yml @@ -3,9 +3,9 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.tools.ant.taskdefs", "Copy", True, "addFileset", "(FileSet)", "", "Argument[0]", "read-file", "ai-manual"] - - ["org.apache.tools.ant.taskdefs", "Copy", True, "setFile", "(File)", "", "Argument[0]", "read-file", "ai-manual"] - - ["org.apache.tools.ant.taskdefs", "Copy", True, "setTodir", "(File)", "", "Argument[0]", "create-file", "ai-manual"] - - ["org.apache.tools.ant.taskdefs", "Copy", True, "setTofile", "(File)", "", "Argument[0]", "create-file", "ai-manual"] - - ["org.apache.tools.ant.taskdefs", "Expand", True, "setDest", "(File)", "", "Argument[0]", "create-file", "ai-manual"] - - ["org.apache.tools.ant.taskdefs", "Expand", True, "setSrc", "(File)", "", "Argument[0]", "read-file", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Copy", True, "addFileset", "(FileSet)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Copy", True, "setFile", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Copy", True, "setTodir", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Copy", True, "setTofile", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Expand", True, "setDest", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Expand", True, "setSrc", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.codehaus.cargo.container.installer.model.yml b/java/ql/lib/ext/org.codehaus.cargo.container.installer.model.yml index dbb6ace53da..ddd4d24577e 100644 --- a/java/ql/lib/ext/org.codehaus.cargo.container.installer.model.yml +++ b/java/ql/lib/ext/org.codehaus.cargo.container.installer.model.yml @@ -4,5 +4,5 @@ extensions: extensible: sinkModel data: - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[0]", "open-url", "ai-manual"] - - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[1]", "create-file", "ai-manual"] - - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[2]", "create-file", "ai-manual"] + - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[2]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.kohsuke.stapler.framework.io.model.yml b/java/ql/lib/ext/org.kohsuke.stapler.framework.io.model.yml index 514b23a9958..49cd049cdfa 100644 --- a/java/ql/lib/ext/org.kohsuke.stapler.framework.io.model.yml +++ b/java/ql/lib/ext/org.kohsuke.stapler.framework.io.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.kohsuke.stapler.framework.io", "LargeText", True, "LargeText", "(File,Charset,boolean,boolean)", "", "Argument[0]", "read-file", "ai-manual"] + - ["org.kohsuke.stapler.framework.io", "LargeText", True, "LargeText", "(File,Charset,boolean,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.openjdk.jmh.runner.options.model.yml b/java/ql/lib/ext/org.openjdk.jmh.runner.options.model.yml index a4eb31084cc..1d2aa29efee 100644 --- a/java/ql/lib/ext/org.openjdk.jmh.runner.options.model.yml +++ b/java/ql/lib/ext/org.openjdk.jmh.runner.options.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.openjdk.jmh.runner.options", "ChainedOptionsBuilder", True, "result", "(String)", "", "Argument[0]", "create-file", "ai-manual"] + - ["org.openjdk.jmh.runner.options", "ChainedOptionsBuilder", True, "result", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 7633f47c3bd..b4d1e146312 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -277,7 +277,7 @@ module ModelValidation { "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", "ognl-injection", "intent-redirection", - "pending-intents", "url-redirection", "create-file", "read-file", "file-content-store", + "pending-intents", "url-redirection", "path-injection", "file-content-store", "hostname-verification", "response-splitting", "information-leak", "xslt-injection", "jexl-injection", "bean-validation", "template-injection", "fragment-injection", "command-injection" diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll index cf081085bab..d7097f1ecf2 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidFilesystemQuery.qll @@ -20,7 +20,7 @@ private class AndroidFilesystemCleartextStorageSink extends CleartextStorageSink /** A call to a method or constructor that may write to files to the local filesystem. */ class LocalFileOpenCall extends Storable { LocalFileOpenCall() { - this = any(DataFlow::Node sink | sinkNode(sink, "create-file")).asExpr().(Argument).getCall() + this = any(DataFlow::Node sink | sinkNode(sink, "path-injection")).asExpr().(Argument).getCall() } override Expr getAnInput() { diff --git a/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll b/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll index 27a54d0ecfa..4fa64846c91 100644 --- a/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll @@ -58,7 +58,7 @@ module TaintedPathConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(PathCreation p).getAnInput() or - sinkNode(sink, ["create-file", "read-file"]) + sinkNode(sink, "path-injection") } predicate isBarrier(DataFlow::Node sanitizer) { @@ -85,7 +85,7 @@ module TaintedPathLocalConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(PathCreation p).getAnInput() or - sinkNode(sink, "create-file") + sinkNode(sink, "path-injection") } predicate isBarrier(DataFlow::Node sanitizer) { diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 6eaa372075b..4fad191a3e4 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -40,5 +40,5 @@ module ZipSlipFlow = TaintTracking::Global<ZipSlipConfig>; * A sink that represents a file creation, such as a file write, copy or move operation. */ private class FileCreationSink extends DataFlow::Node { - FileCreationSink() { sinkNode(this, "create-file") } + FileCreationSink() { sinkNode(this, "path-injection") } } diff --git a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidFileIntentSink.qll b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidFileIntentSink.qll index e8795a25431..ba6c895dc8f 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidFileIntentSink.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidFileIntentSink.qll @@ -8,7 +8,7 @@ import semmle.code.java.frameworks.android.Intent /** A sink representing methods creating a file in Android. */ class AndroidFileSink extends DataFlow::Node { - AndroidFileSink() { sinkNode(this, "create-file") } + AndroidFileSink() { sinkNode(this, "path-injection") } } /** From 5dbb6984815bef54ca3d073a475ca3490dda92bf Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Wed, 31 May 2023 15:50:31 -0400 Subject: [PATCH 237/739] Java: update open/jdbc-url sink kinds to request-forgery --- java/ql/lib/ext/com.zaxxer.hikari.model.yml | 4 +- .../lib/ext/generated/kotlinstdlib.model.yml | 4 +- .../generated/org.apache.commons.io.model.yml | 30 ++-- java/ql/lib/ext/hudson.cli.model.yml | 4 +- java/ql/lib/ext/hudson.model.model.yml | 6 +- java/ql/lib/ext/hudson.model.yml | 2 +- java/ql/lib/ext/io.netty.bootstrap.model.yml | 6 +- java/ql/lib/ext/io.netty.channel.model.yml | 18 +- .../ext/io.netty.handler.codec.http.model.yml | 6 +- .../lib/ext/io.netty.util.internal.model.yml | 2 +- .../ql/lib/ext/jakarta.ws.rs.client.model.yml | 2 +- java/ql/lib/ext/java.net.http.model.yml | 4 +- java/ql/lib/ext/java.net.model.yml | 32 ++-- java/ql/lib/ext/java.sql.model.yml | 8 +- java/ql/lib/ext/javafx.scene.web.model.yml | 2 +- java/ql/lib/ext/javax.ws.rs.client.model.yml | 2 +- java/ql/lib/ext/okhttp3.model.yml | 8 +- .../ext/org.apache.commons.jelly.model.yml | 12 +- ...he.hc.client5.http.async.methods.model.yml | 168 +++++++++--------- ....hc.client5.http.classic.methods.model.yml | 74 ++++---- ...rg.apache.hc.client5.http.fluent.model.yml | 38 ++-- .../org.apache.hc.core5.benchmark.model.yml | 2 +- ...che.hc.core5.http.impl.bootstrap.model.yml | 4 +- ....apache.hc.core5.http.io.support.model.yml | 32 ++-- ...org.apache.hc.core5.http.message.model.yml | 16 +- .../ext/org.apache.hc.core5.http.model.yml | 6 +- ...apache.hc.core5.http.nio.support.model.yml | 48 ++--- ...org.apache.hc.core5.http.support.model.yml | 38 ++-- .../org.apache.http.client.fluent.model.yml | 32 ++-- .../org.apache.http.client.methods.model.yml | 38 ++-- .../lib/ext/org.apache.http.client.model.yml | 6 +- .../ext/org.apache.http.impl.client.model.yml | 2 +- .../lib/ext/org.apache.http.message.model.yml | 12 +- java/ql/lib/ext/org.apache.http.model.yml | 2 +- ...dehaus.cargo.container.installer.model.yml | 2 +- .../ext/org.eclipse.jetty.client.model.yml | 2 +- java/ql/lib/ext/org.jdbi.v3.core.model.yml | 12 +- java/ql/lib/ext/org.kohsuke.stapler.model.yml | 2 +- .../org.springframework.boot.jdbc.model.yml | 2 +- .../ext/org.springframework.http.model.yml | 28 +-- ....springframework.jdbc.datasource.model.yml | 8 +- .../org.springframework.web.client.model.yml | 26 +-- ...ork.web.reactive.function.client.model.yml | 4 +- java/ql/lib/ext/retrofit2.model.yml | 2 +- .../code/java/dataflow/ExternalFlow.qll | 13 +- .../semmle/code/java/security/HttpsUrls.qll | 2 +- .../code/java/security/RequestForgery.qll | 8 +- .../Security/CWE/CWE-552/UnsafeUrlForward.qll | 2 +- .../library-tests/frameworks/okhttp/test.ql | 4 +- .../library-tests/frameworks/retrofit/test.ql | 4 +- 50 files changed, 395 insertions(+), 396 deletions(-) diff --git a/java/ql/lib/ext/com.zaxxer.hikari.model.yml b/java/ql/lib/ext/com.zaxxer.hikari.model.yml index 5fcab32cc7e..5c048e7c3c0 100644 --- a/java/ql/lib/ext/com.zaxxer.hikari.model.yml +++ b/java/ql/lib/ext/com.zaxxer.hikari.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["com.zaxxer.hikari", "HikariConfig", False, "HikariConfig", "(Properties)", "", "Argument[0]", "jdbc-url", "manual"] - - ["com.zaxxer.hikari", "HikariConfig", False, "setJdbcUrl", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["com.zaxxer.hikari", "HikariConfig", False, "HikariConfig", "(Properties)", "", "Argument[0]", "request-forgery", "manual"] + - ["com.zaxxer.hikari", "HikariConfig", False, "setJdbcUrl", "(String)", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/generated/kotlinstdlib.model.yml b/java/ql/lib/ext/generated/kotlinstdlib.model.yml index 16e0cc97420..a4f310b20b9 100644 --- a/java/ql/lib/ext/generated/kotlinstdlib.model.yml +++ b/java/ql/lib/ext/generated/kotlinstdlib.model.yml @@ -16,8 +16,8 @@ extensions: - ["kotlin.io", "FilesKt", false, "writeBytes", "(File,byte[])", "", "Argument[0]", "path-injection", "df-generated"] - ["kotlin.io", "FilesKt", false, "writeText", "(File,String,Charset)", "", "Argument[0]", "path-injection", "df-generated"] - ["kotlin.io", "FilesKt", false, "writer", "(File,Charset)", "", "Argument[0]", "path-injection", "df-generated"] - - ["kotlin.io", "TextStreamsKt", false, "readBytes", "(URL)", "", "Argument[0]", "open-url", "df-generated"] - - ["kotlin.io", "TextStreamsKt", false, "readText", "(URL,Charset)", "", "Argument[0]", "open-url", "df-generated"] + - ["kotlin.io", "TextStreamsKt", false, "readBytes", "(URL)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["kotlin.io", "TextStreamsKt", false, "readText", "(URL,Charset)", "", "Argument[0]", "request-forgery", "df-generated"] - addsTo: diff --git a/java/ql/lib/ext/generated/org.apache.commons.io.model.yml b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml index e43b2720252..c220b8c82eb 100644 --- a/java/ql/lib/ext/generated/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/generated/org.apache.commons.io.model.yml @@ -7,10 +7,10 @@ extensions: extensible: sinkModel data: - ["org.apache.commons.io.file", "PathFilter", true, "accept", "(Path,BasicFileAttributes)", "", "Argument[0]", "path-injection", "df-generated"] - - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[0]", "open-url", "df-generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[0]", "request-forgery", "df-generated"] - ["org.apache.commons.io.file", "PathUtils", false, "copyFile", "(URL,Path,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(Path,Path,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] - - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[0]", "open-url", "df-generated"] + - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[0]", "request-forgery", "df-generated"] - ["org.apache.commons.io.file", "PathUtils", false, "copyFileToDirectory", "(URL,Path,CopyOption[])", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io.file", "PathUtils", false, "newOutputStream", "(Path,boolean)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io.file", "PathUtils", false, "writeString", "(Path,CharSequence,Charset,OpenOption[])", "", "Argument[0]", "path-injection", "df-generated"] @@ -18,7 +18,7 @@ extensions: - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterList", "(IOFileFilter,File[])", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io.filefilter", "FileFilterUtils", true, "filterSet", "(IOFileFilter,File[])", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io.input", "Tailer$Tailable", true, "getRandomAccess", "(String)", "", "Argument[this]", "path-injection", "df-generated"] - - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(URL)", "", "Argument[0]", "open-url", "df-generated"] + - ["org.apache.commons.io.input", "XmlStreamReader", true, "XmlStreamReader", "(URL)", "", "Argument[0]", "request-forgery", "df-generated"] - ["org.apache.commons.io.output", "DeferredFileOutputStream", true, "writeTo", "(OutputStream)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io.output", "FileWriterWithEncoding", true, "FileWriterWithEncoding", "(File,Charset,boolean)", "", "Argument[0]", "path-injection", "df-generated"] @@ -60,9 +60,9 @@ extensions: - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "copyToDirectory", "(Iterable,File)", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "copyToFile", "(InputStream,File)", "", "Argument[1]", "path-injection", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[0]", "open-url", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[0]", "request-forgery", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File)", "", "Argument[1]", "path-injection", "df-generated"] - - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[0]", "open-url", "df-generated"] + - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[0]", "request-forgery", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "copyURLToFile", "(URL,File,int,int)", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "moveDirectory", "(File,File)", "", "Argument[1]", "path-injection", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "moveDirectoryToDirectory", "(File,File,boolean)", "", "Argument[1]", "path-injection", "df-generated"] @@ -98,17 +98,17 @@ extensions: - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io", "FileUtils", true, "writeStringToFile", "(File,String,boolean)", "", "Argument[0]", "path-injection", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[0]", "open-url", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[0]", "request-forgery", "df-generated"] - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,File)", "", "Argument[1]", "path-injection", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,OutputStream)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URI)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URL)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI,Charset)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI,String)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,Charset)", "", "Argument[0]", "open-url", "df-generated"] - - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,String)", "", "Argument[0]", "open-url", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "copy", "(URL,OutputStream)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URI)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "toByteArray", "(URL)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI,Charset)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URI,String)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,Charset)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["org.apache.commons.io", "IOUtils", true, "toString", "(URL,String)", "", "Argument[0]", "request-forgery", "df-generated"] - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(File)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(Path)", "", "Argument[0]", "path-injection", "df-generated"] - ["org.apache.commons.io", "RandomAccessFileMode", false, "create", "(String)", "", "Argument[0]", "path-injection", "df-generated"] diff --git a/java/ql/lib/ext/hudson.cli.model.yml b/java/ql/lib/ext/hudson.cli.model.yml index b0d3d3a19ff..6b962143625 100644 --- a/java/ql/lib/ext/hudson.cli.model.yml +++ b/java/ql/lib/ext/hudson.cli.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.cli", "FullDuplexHttpStream", True, "FullDuplexHttpStream", "(URL,String,String)", "", "Argument[0]", "open-url", "ai-manual"] - - ["hudson.cli", "FullDuplexHttpStream", True, "FullDuplexHttpStream", "(URL,String,String)", "", "Argument[1]", "open-url", "manual"] + - ["hudson.cli", "FullDuplexHttpStream", True, "FullDuplexHttpStream", "(URL,String,String)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["hudson.cli", "FullDuplexHttpStream", True, "FullDuplexHttpStream", "(URL,String,String)", "", "Argument[1]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/hudson.model.model.yml b/java/ql/lib/ext/hudson.model.model.yml index 2b5423961e3..023265b2c3d 100644 --- a/java/ql/lib/ext/hudson.model.model.yml +++ b/java/ql/lib/ext/hudson.model.model.yml @@ -3,11 +3,11 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.model", "DownloadService", True, "loadJSON", "(URL)", "", "Argument[0]", "open-url", "ai-manual"] - - ["hudson.model", "DownloadService", True, "loadJSONHTML", "(URL)", "", "Argument[0]", "open-url", "ai-manual"] + - ["hudson.model", "DownloadService", True, "loadJSON", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["hudson.model", "DownloadService", True, "loadJSONHTML", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"] - ["hudson.model", "DirectoryBrowserSupport", False, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[1]", "path-injection", "ai-manual"] - ["hudson.model", "Items", True, "load", "(ItemGroup,File)", "", "Argument[1]", "path-injection", "ai-manual"] - - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "download", "(DownloadJob,URL)", "", "Argument[1]", "open-url", "ai-manual"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "download", "(DownloadJob,URL)", "", "Argument[1]", "request-forgery", "ai-manual"] - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "install", "(DownloadJob,File,File)", "", "Argument[1]", "path-injection", "ai-manual"] - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "install", "(DownloadJob,File,File)", "", "Argument[2]", "path-injection", "ai-manual"] - addsTo: diff --git a/java/ql/lib/ext/hudson.model.yml b/java/ql/lib/ext/hudson.model.yml index 43955cb22f0..5ba20fce0c6 100644 --- a/java/ql/lib/ext/hudson.model.yml +++ b/java/ql/lib/ext/hudson.model.yml @@ -12,7 +12,7 @@ extensions: - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[2]", "path-injection", "ai-manual"] - ["hudson", "FilePath", False, "copyTo", "(FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["hudson", "FilePath", False, "installIfNecessaryFrom", "(URL,TaskListener,String)", "", "Argument[0]", "open-url", "ai-manual"] + - ["hudson", "FilePath", False, "installIfNecessaryFrom", "(URL,TaskListener,String)", "", "Argument[0]", "request-forgery", "ai-manual"] - ["hudson", "FilePath", False, "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/io.netty.bootstrap.model.yml b/java/ql/lib/ext/io.netty.bootstrap.model.yml index f38329a8bad..e07853583f7 100644 --- a/java/ql/lib/ext/io.netty.bootstrap.model.yml +++ b/java/ql/lib/ext/io.netty.bootstrap.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.bootstrap", "Bootstrap", True, "connect", "(InetAddress,int)", "", "Argument[0]", "open-url", "ai-manual"] - - ["io.netty.bootstrap", "Bootstrap", True, "connect", "(SocketAddress)", "", "Argument[0]", "open-url", "ai-manual"] - - ["io.netty.bootstrap", "Bootstrap", True, "connect", "(String,int)", "", "Argument[0]", "open-url", "ai-manual"] + - ["io.netty.bootstrap", "Bootstrap", True, "connect", "(InetAddress,int)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["io.netty.bootstrap", "Bootstrap", True, "connect", "(SocketAddress)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["io.netty.bootstrap", "Bootstrap", True, "connect", "(String,int)", "", "Argument[0]", "request-forgery", "ai-manual"] diff --git a/java/ql/lib/ext/io.netty.channel.model.yml b/java/ql/lib/ext/io.netty.channel.model.yml index e06a3e0a582..38bdb84786a 100644 --- a/java/ql/lib/ext/io.netty.channel.model.yml +++ b/java/ql/lib/ext/io.netty.channel.model.yml @@ -3,15 +3,15 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.channel", "Channel$Unsafe", True, "connect", "(SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[0]", "open-url", "ai-manual"] - - ["io.netty.channel", "ChannelDuplexHandler", True, "connect", "(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[1]", "open-url", "ai-manual"] - - ["io.netty.channel", "ChannelOutboundHandlerAdapter", True, "connect", "(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[1]", "open-url", "ai-manual"] - - ["io.netty.channel", "ChannelOutboundInvoker", True, "connect", "(SocketAddress,ChannelPromise)", "", "Argument[0]", "open-url", "ai-manual"] - - ["io.netty.channel", "ChannelOutboundInvoker", True, "connect", "(SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[0]", "open-url", "ai-manual"] - - ["io.netty.channel", "ChannelOutboundInvoker", True, "connect", "(SocketAddress)", "", "Argument[0]", "open-url", "ai-manual"] - - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,ChannelPromise)", "", "Argument[0]", "open-url", "ai-manual"] - - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[0]", "open-url", "ai-manual"] - - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,SocketAddress)", "", "Argument[0]", "open-url", "ai-manual"] + - ["io.netty.channel", "Channel$Unsafe", True, "connect", "(SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["io.netty.channel", "ChannelDuplexHandler", True, "connect", "(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[1]", "request-forgery", "ai-manual"] + - ["io.netty.channel", "ChannelOutboundHandlerAdapter", True, "connect", "(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[1]", "request-forgery", "ai-manual"] + - ["io.netty.channel", "ChannelOutboundInvoker", True, "connect", "(SocketAddress,ChannelPromise)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["io.netty.channel", "ChannelOutboundInvoker", True, "connect", "(SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["io.netty.channel", "ChannelOutboundInvoker", True, "connect", "(SocketAddress)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,ChannelPromise)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,SocketAddress)", "", "Argument[0]", "request-forgery", "ai-manual"] - addsTo: pack: codeql/java-all extensible: sourceModel diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index 2912bdce85a..f9ec6702ff9 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -3,9 +3,9 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.handler.codec.http", "DefaultFullHttpRequest", True, "DefaultFullHttpRequest", "(HttpVersion,HttpMethod,String,ByteBuf)", "", "Argument[2]", "open-url", "ai-manual"] - - ["io.netty.handler.codec.http", "DefaultHttpRequest", True, "DefaultHttpRequest", "(HttpVersion,HttpMethod,String)", "", "Argument[2]", "open-url", "ai-manual"] - - ["io.netty.handler.codec.http", "HttpRequest", True, "setUri", "", "", "Argument[0]", "open-url", "manual"] + - ["io.netty.handler.codec.http", "DefaultFullHttpRequest", True, "DefaultFullHttpRequest", "(HttpVersion,HttpMethod,String,ByteBuf)", "", "Argument[2]", "request-forgery", "ai-manual"] + - ["io.netty.handler.codec.http", "DefaultHttpRequest", True, "DefaultHttpRequest", "(HttpVersion,HttpMethod,String)", "", "Argument[2]", "request-forgery", "ai-manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "setUri", "", "", "Argument[0]", "request-forgery", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/io.netty.util.internal.model.yml b/java/ql/lib/ext/io.netty.util.internal.model.yml index d705873cc55..7852b8b9e32 100644 --- a/java/ql/lib/ext/io.netty.util.internal.model.yml +++ b/java/ql/lib/ext/io.netty.util.internal.model.yml @@ -4,7 +4,7 @@ extensions: extensible: sinkModel data: - ["io.netty.util.internal", "PlatformDependent", False, "createTempFile", "(String,String,File)", "", "Argument[2]", "path-injection", "ai-manual"] - - ["io.netty.util.internal", "SocketUtils", False, "connect", "(Socket,SocketAddress,int)", "", "Argument[1]", "open-url", "ai-manual"] + - ["io.netty.util.internal", "SocketUtils", False, "connect", "(Socket,SocketAddress,int)", "", "Argument[1]", "request-forgery", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/jakarta.ws.rs.client.model.yml b/java/ql/lib/ext/jakarta.ws.rs.client.model.yml index 821ea0ad640..0460c09dc3c 100644 --- a/java/ql/lib/ext/jakarta.ws.rs.client.model.yml +++ b/java/ql/lib/ext/jakarta.ws.rs.client.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["jakarta.ws.rs.client", "Client", True, "target", "", "", "Argument[0]", "open-url", "manual"] + - ["jakarta.ws.rs.client", "Client", True, "target", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/java.net.http.model.yml b/java/ql/lib/ext/java.net.http.model.yml index d967f46494b..9fc18d2eaab 100644 --- a/java/ql/lib/ext/java.net.http.model.yml +++ b/java/ql/lib/ext/java.net.http.model.yml @@ -8,5 +8,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.net.http", "HttpRequest", False, "newBuilder", "", "", "Argument[0]", "open-url", "manual"] - - ["java.net.http", "HttpRequest$Builder", False, "uri", "", "", "Argument[0]", "open-url", "manual"] + - ["java.net.http", "HttpRequest", False, "newBuilder", "", "", "Argument[0]", "request-forgery", "manual"] + - ["java.net.http", "HttpRequest$Builder", False, "uri", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/java.net.model.yml b/java/ql/lib/ext/java.net.model.yml index 9ab8c663506..39a4c484112 100644 --- a/java/ql/lib/ext/java.net.model.yml +++ b/java/ql/lib/ext/java.net.model.yml @@ -9,22 +9,22 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.net", "DatagramSocket", True, "connect", "(SocketAddress)", "", "Argument[0]", "open-url", "ai-manual"] - - ["java.net", "Socket", True, "Socket", "(String,int)", "", "Argument[0]", "open-url", "ai-manual"] - - ["java.net", "URL", False, "openConnection", "", "", "Argument[this]", "open-url", "manual"] - - ["java.net", "URL", False, "openConnection", "(Proxy)", "", "Argument[0]", "open-url", "ai-manual"] - - ["java.net", "URL", False, "openStream", "", "", "Argument[this]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader)", "", "Argument[1]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[1]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[])", "", "Argument[0]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader)", "", "Argument[0]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[0]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "newInstance", "", "", "Argument[0]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[1]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader)", "", "Argument[1]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[0]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader)", "", "Argument[0]", "open-url", "manual"] - - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[])", "", "Argument[0]", "open-url", "manual"] + - ["java.net", "DatagramSocket", True, "connect", "(SocketAddress)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["java.net", "Socket", True, "Socket", "(String,int)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["java.net", "URL", False, "openConnection", "", "", "Argument[this]", "request-forgery", "manual"] + - ["java.net", "URL", False, "openConnection", "(Proxy)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["java.net", "URL", False, "openStream", "", "", "Argument[this]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader)", "", "Argument[1]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[1]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[])", "", "Argument[0]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader)", "", "Argument[0]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[0]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "newInstance", "", "", "Argument[0]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[1]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(String,URL[],ClassLoader)", "", "Argument[1]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader,URLStreamHandlerFactory)", "", "Argument[0]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[],ClassLoader)", "", "Argument[0]", "request-forgery", "manual"] + - ["java.net", "URLClassLoader", False, "URLClassLoader", "(URL[])", "", "Argument[0]", "request-forgery", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index ec0aa84fd21..c93a89cfd2c 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -7,10 +7,10 @@ extensions: - ["java.sql", "Connection", True, "prepareStatement", "", "", "Argument[0]", "sql-injection", "manual"] - ["java.sql", "DatabaseMetaData", True, "getColumns", "(String,String,String,String)", "", "Argument[2]", "sql-injection", "ai-manual"] - ["java.sql", "DatabaseMetaData", True, "getPrimaryKeys", "(String,String,String)", "", "Argument[2]", "sql-injection", "ai-manual"] - - ["java.sql", "Driver", False, "connect", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] - - ["java.sql", "DriverManager", False, "getConnection", "(String)", "", "Argument[0]", "jdbc-url", "manual"] - - ["java.sql", "DriverManager", False, "getConnection", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] - - ["java.sql", "DriverManager", False, "getConnection", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["java.sql", "Driver", False, "connect", "(String,Properties)", "", "Argument[0]", "request-forgery", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String)", "", "Argument[0]", "request-forgery", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String,Properties)", "", "Argument[0]", "request-forgery", "manual"] + - ["java.sql", "DriverManager", False, "getConnection", "(String,String,String)", "", "Argument[0]", "request-forgery", "manual"] - ["java.sql", "Statement", True, "addBatch", "", "", "Argument[0]", "sql-injection", "manual"] - ["java.sql", "Statement", True, "execute", "", "", "Argument[0]", "sql-injection", "manual"] - ["java.sql", "Statement", True, "executeLargeUpdate", "", "", "Argument[0]", "sql-injection", "manual"] diff --git a/java/ql/lib/ext/javafx.scene.web.model.yml b/java/ql/lib/ext/javafx.scene.web.model.yml index 64f8eea916b..78d1a00dfde 100644 --- a/java/ql/lib/ext/javafx.scene.web.model.yml +++ b/java/ql/lib/ext/javafx.scene.web.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javafx.scene.web", "WebEngine", False, "load", "(String)", "", "Argument[0]", "open-url", "ai-manual"] + - ["javafx.scene.web", "WebEngine", False, "load", "(String)", "", "Argument[0]", "request-forgery", "ai-manual"] diff --git a/java/ql/lib/ext/javax.ws.rs.client.model.yml b/java/ql/lib/ext/javax.ws.rs.client.model.yml index 0a5a01c3338..e9855623951 100644 --- a/java/ql/lib/ext/javax.ws.rs.client.model.yml +++ b/java/ql/lib/ext/javax.ws.rs.client.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.ws.rs.client", "Client", True, "target", "", "", "Argument[0]", "open-url", "manual"] + - ["javax.ws.rs.client", "Client", True, "target", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/okhttp3.model.yml b/java/ql/lib/ext/okhttp3.model.yml index d5f38bcee57..2368292dab7 100644 --- a/java/ql/lib/ext/okhttp3.model.yml +++ b/java/ql/lib/ext/okhttp3.model.yml @@ -3,10 +3,10 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["okhttp3", "OkHttpClient", True, "newCall", "(Request)", "", "Argument[0]", "open-url", "ai-manual"] - - ["okhttp3", "OkHttpClient", True, "newWebSocket", "(Request,WebSocketListener)", "", "Argument[0]", "open-url", "ai-manual"] - - ["okhttp3", "Request", True, "Request", "", "", "Argument[0]", "open-url", "manual"] - - ["okhttp3", "Request$Builder", True, "url", "", "", "Argument[0]", "open-url", "manual"] + - ["okhttp3", "OkHttpClient", True, "newCall", "(Request)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["okhttp3", "OkHttpClient", True, "newWebSocket", "(Request,WebSocketListener)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["okhttp3", "Request", True, "Request", "", "", "Argument[0]", "request-forgery", "manual"] + - ["okhttp3", "Request$Builder", True, "url", "", "", "Argument[0]", "request-forgery", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.apache.commons.jelly.model.yml b/java/ql/lib/ext/org.apache.commons.jelly.model.yml index 0669f6744b9..ef9e48d041a 100644 --- a/java/ql/lib/ext/org.apache.commons.jelly.model.yml +++ b/java/ql/lib/ext/org.apache.commons.jelly.model.yml @@ -3,9 +3,9 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(JellyContext,URL,URL)", "", "Argument[1]", "open-url", "ai-manual"] - - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(JellyContext,URL,URL)", "", "Argument[2]", "open-url", "ai-manual"] - - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(JellyContext,URL)", "", "Argument[1]", "open-url", "ai-manual"] - - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(URL,URL)", "", "Argument[0]", "open-url", "ai-manual"] - - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(URL,URL)", "", "Argument[1]", "open-url", "ai-manual"] - - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(URL)", "", "Argument[0]", "open-url", "ai-manual"] + - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(JellyContext,URL,URL)", "", "Argument[1]", "request-forgery", "ai-manual"] + - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(JellyContext,URL,URL)", "", "Argument[2]", "request-forgery", "ai-manual"] + - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(JellyContext,URL)", "", "Argument[1]", "request-forgery", "ai-manual"] + - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(URL,URL)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(URL,URL)", "", "Argument[1]", "request-forgery", "ai-manual"] + - ["org.apache.commons.jelly", "JellyContext", True, "JellyContext", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.async.methods.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.async.methods.model.yml index 0b0e040c054..17498977d8d 100644 --- a/java/ql/lib/ext/org.apache.hc.client5.http.async.methods.model.yml +++ b/java/ql/lib/ext/org.apache.hc.client5.http.async.methods.model.yml @@ -3,87 +3,87 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(Method,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(Method,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "delete", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "get", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "head", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "options", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "patch", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "post", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "put", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "trace", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "ConfigurableHttpRequest", True, "ConfigurableHttpRequest", "(String,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "ConfigurableHttpRequest", True, "ConfigurableHttpRequest", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "SimpleHttpRequest", "(Method,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "SimpleHttpRequest", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "SimpleHttpRequest", "(String,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "SimpleHttpRequest", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "create", "(Method,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "create", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "create", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "create", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(Method,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(Method,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "delete", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "get", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "head", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "options", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "patch", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "post", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "put", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "trace", "(HttpHost,String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(Method,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(Method,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(String,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "create", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "delete", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "get", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "head", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "options", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "patch", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "post", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "put", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "trace", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "BasicHttpRequests", True, "trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "ConfigurableHttpRequest", True, "ConfigurableHttpRequest", "(String,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "ConfigurableHttpRequest", True, "ConfigurableHttpRequest", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "SimpleHttpRequest", "(Method,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "SimpleHttpRequest", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "SimpleHttpRequest", "(String,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "SimpleHttpRequest", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "create", "(Method,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "create", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "create", "(String,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequest", True, "create", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(Method,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(Method,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(String,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "create", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "delete", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "get", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "head", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "options", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "patch", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "post", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "put", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "trace", "(HttpHost,String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleHttpRequests", True, "trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.async.methods", "SimpleRequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.classic.methods.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.classic.methods.model.yml index 513a4e7eb7a..8b360282cec 100644 --- a/java/ql/lib/ext/org.apache.hc.client5.http.classic.methods.model.yml +++ b/java/ql/lib/ext/org.apache.hc.client5.http.classic.methods.model.yml @@ -3,40 +3,40 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "create", "(Method,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "create", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "create", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "create", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpDelete", True, "HttpDelete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpDelete", True, "HttpDelete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpGet", True, "HttpGet", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpGet", True, "HttpGet", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpHead", True, "HttpHead", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpHead", True, "HttpHead", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpOptions", True, "HttpOptions", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpOptions", True, "HttpOptions", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpPatch", True, "HttpPatch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpPatch", True, "HttpPatch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpPost", True, "HttpPost", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpPost", True, "HttpPost", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpPut", True, "HttpPut", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpPut", True, "HttpPut", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpTrace", True, "HttpTrace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpTrace", True, "HttpTrace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.classic.methods", "HttpUriRequestBase", True, "HttpUriRequestBase", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "create", "(Method,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "create", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "create", "(String,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "create", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "ClassicHttpRequests", True, "trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpDelete", True, "HttpDelete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpDelete", True, "HttpDelete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpGet", True, "HttpGet", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpGet", True, "HttpGet", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpHead", True, "HttpHead", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpHead", True, "HttpHead", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpOptions", True, "HttpOptions", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpOptions", True, "HttpOptions", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpPatch", True, "HttpPatch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpPatch", True, "HttpPatch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpPost", True, "HttpPost", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpPost", True, "HttpPost", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpPut", True, "HttpPut", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpPut", True, "HttpPut", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpTrace", True, "HttpTrace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpTrace", True, "HttpTrace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.classic.methods", "HttpUriRequestBase", True, "HttpUriRequestBase", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.fluent.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.fluent.model.yml index ce3b5567b7b..ff25f6c43a3 100644 --- a/java/ql/lib/ext/org.apache.hc.client5.http.fluent.model.yml +++ b/java/ql/lib/ext/org.apache.hc.client5.http.fluent.model.yml @@ -3,22 +3,22 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.client5.http.fluent", "Request", True, "create", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "create", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "create", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.client5.http.fluent", "Request", True, "trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "create", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "create", "(String,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "create", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.client5.http.fluent", "Request", True, "trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.benchmark.model.yml b/java/ql/lib/ext/org.apache.hc.core5.benchmark.model.yml index 450a46cd1ec..0143a0a68ab 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.benchmark.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.benchmark.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.core5.benchmark", "BenchmarkConfig$Builder", True, "setUri", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] + - ["org.apache.hc.core5.benchmark", "BenchmarkConfig$Builder", True, "setUri", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml index c9515372645..280cf49b175 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.core5.http.impl.bootstrap", "HttpAsyncRequester", True, "connect", "(HttpHost,Timeout)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.impl.bootstrap", "HttpAsyncRequester", True, "connect", "(HttpHost,Timeout,Object,FutureCallback)", "", "Argument[0]", "open-url", "hq-manual"] + - ["org.apache.hc.core5.http.impl.bootstrap", "HttpAsyncRequester", True, "connect", "(HttpHost,Timeout)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.impl.bootstrap", "HttpAsyncRequester", True, "connect", "(HttpHost,Timeout,Object,FutureCallback)", "", "Argument[0]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.io.support.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.io.support.model.yml index 86d55853d8f..1f602d987cc 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.io.support.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.io.support.model.yml @@ -3,19 +3,19 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.io.support", "ClassicRequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml index e8cc56f35a5..44ed7ac03c1 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.message.model.yml @@ -3,14 +3,14 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.core5.http.message", "BasicClassicHttpRequest", True, "BasicClassicHttpRequest", "(Method,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.message", "BasicClassicHttpRequest", True, "BasicClassicHttpRequest", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.message", "BasicClassicHttpRequest", True, "BasicClassicHttpRequest", "(String,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.message", "BasicClassicHttpRequest", True, "BasicClassicHttpRequest", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.message", "BasicHttpRequest", True, "BasicHttpRequest", "(Method,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.message", "BasicHttpRequest", True, "BasicHttpRequest", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.message", "BasicHttpRequest", True, "BasicHttpRequest", "(String,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.message", "BasicHttpRequest", True, "BasicHttpRequest", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] + - ["org.apache.hc.core5.http.message", "BasicClassicHttpRequest", True, "BasicClassicHttpRequest", "(Method,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.message", "BasicClassicHttpRequest", True, "BasicClassicHttpRequest", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.message", "BasicClassicHttpRequest", True, "BasicClassicHttpRequest", "(String,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.message", "BasicClassicHttpRequest", True, "BasicClassicHttpRequest", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.message", "BasicHttpRequest", True, "BasicHttpRequest", "(Method,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.message", "BasicHttpRequest", True, "BasicHttpRequest", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.message", "BasicHttpRequest", True, "BasicHttpRequest", "(String,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.message", "BasicHttpRequest", True, "BasicHttpRequest", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.model.yml index 8922ce55637..321b4235ea8 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.model.yml @@ -4,9 +4,9 @@ extensions: extensible: sinkModel data: - ["org.apache.hc.core5.http", "HttpEntityContainer", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "html-injection", "manual"] - - ["org.apache.hc.core5.http", "HttpRequest", True, "setUri", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http", "HttpRequestFactory", True, "newHttpRequest", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http", "HttpRequestFactory", True, "newHttpRequest", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] + - ["org.apache.hc.core5.http", "HttpRequest", True, "setUri", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http", "HttpRequestFactory", True, "newHttpRequest", "(String,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http", "HttpRequestFactory", True, "newHttpRequest", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.nio.support.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.nio.support.model.yml index 263ca830720..9d896b593c9 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.nio.support.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.nio.support.model.yml @@ -3,27 +3,27 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(Method,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(Method,HttpHost,String,AsyncEntityProducer)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(Method,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(Method,URI,AsyncEntityProducer)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(String,HttpHost,String)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(String,HttpHost,String,AsyncEntityProducer)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(String,URI)", "", "Argument[1]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(String,URI,AsyncEntityProducer)", "", "Argument[1]", "open-url", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "AsyncRequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(Method,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(Method,HttpHost,String,AsyncEntityProducer)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(Method,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(Method,URI,AsyncEntityProducer)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(String,HttpHost,String)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(String,HttpHost,String,AsyncEntityProducer)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(String,URI)", "", "Argument[1]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.nio.support", "BasicRequestProducer", True, "BasicRequestProducer", "(String,URI,AsyncEntityProducer)", "", "Argument[1]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.support.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.support.model.yml index eee42d496f3..cb8d17d283a 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.support.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.support.model.yml @@ -3,22 +3,22 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.hc.core5.http.support", "AbstractRequestBuilder", True, "setHttpHost", "(HttpHost)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "AbstractRequestBuilder", True, "setUri", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "AbstractRequestBuilder", True, "setUri", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] + - ["org.apache.hc.core5.http.support", "AbstractRequestBuilder", True, "setHttpHost", "(HttpHost)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "AbstractRequestBuilder", True, "setUri", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "AbstractRequestBuilder", True, "setUri", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.hc.core5.http.support", "BasicRequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.http.client.fluent.model.yml b/java/ql/lib/ext/org.apache.http.client.fluent.model.yml index 924ab14fc5e..dad428e4d1a 100644 --- a/java/ql/lib/ext/org.apache.http.client.fluent.model.yml +++ b/java/ql/lib/ext/org.apache.http.client.fluent.model.yml @@ -3,19 +3,19 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.http.client.fluent", "Request", True, "Delete", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Delete", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Get", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Get", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Head", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Head", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Options", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Options", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Patch", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Patch", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Post", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Post", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Put", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Put", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Trace", "(String)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.fluent", "Request", True, "Trace", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Delete", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Delete", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Get", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Get", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Head", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Head", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Options", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Options", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Patch", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Patch", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Post", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Post", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Put", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Put", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Trace", "(String)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.fluent", "Request", True, "Trace", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.http.client.methods.model.yml b/java/ql/lib/ext/org.apache.http.client.methods.model.yml index 5db791422c8..4eccb08eb8c 100644 --- a/java/ql/lib/ext/org.apache.http.client.methods.model.yml +++ b/java/ql/lib/ext/org.apache.http.client.methods.model.yml @@ -3,22 +3,22 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.http.client.methods", "HttpDelete", False, "HttpDelete", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "HttpGet", False, "HttpGet", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "HttpHead", False, "HttpHead", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "HttpOptions", False, "HttpOptions", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "HttpPatch", False, "HttpPatch", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "HttpPost", False, "HttpPost", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "HttpPut", False, "HttpPut", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "HttpRequestBase", True, "setURI", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "HttpRequestWrapper", True, "setURI", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] - - ["org.apache.http.client.methods", "HttpTrace", False, "HttpTrace", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "delete", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "get", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "head", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "options", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "patch", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "post", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "put", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "setUri", "", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.client.methods", "RequestBuilder", False, "trace", "", "", "Argument[0]", "open-url", "manual"] + - ["org.apache.http.client.methods", "HttpDelete", False, "HttpDelete", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "HttpGet", False, "HttpGet", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "HttpHead", False, "HttpHead", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "HttpOptions", False, "HttpOptions", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "HttpPatch", False, "HttpPatch", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "HttpPost", False, "HttpPost", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "HttpPut", False, "HttpPut", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "HttpRequestBase", True, "setURI", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "HttpRequestWrapper", True, "setURI", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.methods", "HttpTrace", False, "HttpTrace", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "delete", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "get", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "head", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "options", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "patch", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "post", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "put", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "setUri", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.client.methods", "RequestBuilder", False, "trace", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/org.apache.http.client.model.yml b/java/ql/lib/ext/org.apache.http.client.model.yml index abdfb6ed91d..681efdf32e7 100644 --- a/java/ql/lib/ext/org.apache.http.client.model.yml +++ b/java/ql/lib/ext/org.apache.http.client.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,HttpContext)", "", "Argument[0]", "open-url", "ai-manual"] - - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,ResponseHandler,HttpContext)", "", "Argument[0]", "open-url", "ai-manual"] - - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest)", "", "Argument[0]", "open-url", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,HttpContext)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,ResponseHandler,HttpContext)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest)", "", "Argument[0]", "request-forgery", "ai-manual"] diff --git a/java/ql/lib/ext/org.apache.http.impl.client.model.yml b/java/ql/lib/ext/org.apache.http.impl.client.model.yml index 5cc1aca7498..be517e5344f 100644 --- a/java/ql/lib/ext/org.apache.http.impl.client.model.yml +++ b/java/ql/lib/ext/org.apache.http.impl.client.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.http.impl.client", "RequestWrapper", True, "setURI", "(URI)", "", "Argument[0]", "open-url", "hq-manual"] + - ["org.apache.http.impl.client", "RequestWrapper", True, "setURI", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.http.message.model.yml b/java/ql/lib/ext/org.apache.http.message.model.yml index c727b57b210..4ee0d13d8c1 100644 --- a/java/ql/lib/ext/org.apache.http.message.model.yml +++ b/java/ql/lib/ext/org.apache.http.message.model.yml @@ -3,12 +3,12 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(RequestLine)", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(String,String)", "", "Argument[1]", "open-url", "manual"] - - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(String,String,ProtocolVersion)", "", "Argument[1]", "open-url", "manual"] - - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(RequestLine)", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(String,String)", "", "Argument[1]", "open-url", "manual"] - - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(String,String,ProtocolVersion)", "", "Argument[1]", "open-url", "manual"] + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(RequestLine)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(String,String)", "", "Argument[1]", "request-forgery", "manual"] + - ["org.apache.http.message", "BasicHttpEntityEnclosingRequest", False, "BasicHttpEntityEnclosingRequest", "(String,String,ProtocolVersion)", "", "Argument[1]", "request-forgery", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(RequestLine)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(String,String)", "", "Argument[1]", "request-forgery", "manual"] + - ["org.apache.http.message", "BasicHttpRequest", False, "BasicHttpRequest", "(String,String,ProtocolVersion)", "", "Argument[1]", "request-forgery", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.apache.http.model.yml b/java/ql/lib/ext/org.apache.http.model.yml index d03d2fa1a50..ff0bd813d83 100644 --- a/java/ql/lib/ext/org.apache.http.model.yml +++ b/java/ql/lib/ext/org.apache.http.model.yml @@ -9,7 +9,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.http", "HttpRequestFactory", True, "newHttpRequest", "(String,String)", "", "Argument[1]", "open-url", "hq-manual"] + - ["org.apache.http", "HttpRequestFactory", True, "newHttpRequest", "(String,String)", "", "Argument[1]", "request-forgery", "hq-manual"] - ["org.apache.http", "HttpResponse", True, "setEntity", "(HttpEntity)", "", "Argument[0]", "html-injection", "manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/org.codehaus.cargo.container.installer.model.yml b/java/ql/lib/ext/org.codehaus.cargo.container.installer.model.yml index ddd4d24577e..602a6223fe8 100644 --- a/java/ql/lib/ext/org.codehaus.cargo.container.installer.model.yml +++ b/java/ql/lib/ext/org.codehaus.cargo.container.installer.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[0]", "open-url", "ai-manual"] + - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[0]", "request-forgery", "ai-manual"] - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[1]", "path-injection", "ai-manual"] - ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[2]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.eclipse.jetty.client.model.yml b/java/ql/lib/ext/org.eclipse.jetty.client.model.yml index 23f0e2a48a8..28c3430e818 100644 --- a/java/ql/lib/ext/org.eclipse.jetty.client.model.yml +++ b/java/ql/lib/ext/org.eclipse.jetty.client.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.eclipse.jetty.client", "HttpClient", True, "newRequest", "(String)", "", "Argument[0]", "open-url", "ai-manual"] + - ["org.eclipse.jetty.client", "HttpClient", True, "newRequest", "(String)", "", "Argument[0]", "request-forgery", "ai-manual"] diff --git a/java/ql/lib/ext/org.jdbi.v3.core.model.yml b/java/ql/lib/ext/org.jdbi.v3.core.model.yml index fd7f4e824ac..a80c0a3d90e 100644 --- a/java/ql/lib/ext/org.jdbi.v3.core.model.yml +++ b/java/ql/lib/ext/org.jdbi.v3.core.model.yml @@ -3,9 +3,9 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String)", "", "Argument[0]", "jdbc-url", "manual"] - - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] - - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] - - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String)", "", "Argument[0]", "jdbc-url", "manual"] - - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] - - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String,Properties)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "create", "(String,String,String)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String,Properties)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.jdbi.v3.core", "Jdbi", False, "open", "(String,String,String)", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/org.kohsuke.stapler.model.yml b/java/ql/lib/ext/org.kohsuke.stapler.model.yml index 7b6dea2e669..7a242051485 100644 --- a/java/ql/lib/ext/org.kohsuke.stapler.model.yml +++ b/java/ql/lib/ext/org.kohsuke.stapler.model.yml @@ -4,4 +4,4 @@ extensions: extensible: sinkModel data: - ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(String)", "", "Argument[0]", "url-redirection", "ai-manual"] - - ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL)", "", "Argument[0]", "open-url", "ai-manual"] + - ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"] diff --git a/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml b/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml index bd7c5d8c5c1..7d61e1431c9 100644 --- a/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml +++ b/java/ql/lib/ext/org.springframework.boot.jdbc.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.boot.jdbc", "DataSourceBuilder", False, "url", "(String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.springframework.boot.jdbc", "DataSourceBuilder", False, "url", "(String)", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/org.springframework.http.model.yml b/java/ql/lib/ext/org.springframework.http.model.yml index 8835a471c28..cb5f18a7732 100644 --- a/java/ql/lib/ext/org.springframework.http.model.yml +++ b/java/ql/lib/ext/org.springframework.http.model.yml @@ -3,20 +3,20 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(HttpMethod,URI)", "", "Argument[1]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(MultiValueMap,HttpMethod,URI)", "", "Argument[2]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,HttpMethod,URI)", "", "Argument[2]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,HttpMethod,URI,Type)", "", "Argument[2]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,MultiValueMap,HttpMethod,URI)", "", "Argument[3]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,MultiValueMap,HttpMethod,URI,Type)", "", "Argument[3]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "delete", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "get", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "head", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "method", "", "", "Argument[1]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "options", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "patch", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "post", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.http", "RequestEntity", False, "put", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(HttpMethod,URI)", "", "Argument[1]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(MultiValueMap,HttpMethod,URI)", "", "Argument[2]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,HttpMethod,URI)", "", "Argument[2]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,HttpMethod,URI,Type)", "", "Argument[2]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,MultiValueMap,HttpMethod,URI)", "", "Argument[3]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "RequestEntity", "(Object,MultiValueMap,HttpMethod,URI,Type)", "", "Argument[3]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "delete", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "get", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "head", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "method", "", "", "Argument[1]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "options", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "patch", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "post", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.http", "RequestEntity", False, "put", "", "", "Argument[0]", "request-forgery", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml b/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml index 7bb84c37e2c..3c274d264f9 100644 --- a/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml +++ b/java/ql/lib/ext/org.springframework.jdbc.datasource.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.jdbc.datasource", "AbstractDriverBasedDataSource", False, "setUrl", "(String)", "", "Argument[0]", "jdbc-url", "manual"] - - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String)", "", "Argument[0]", "jdbc-url", "manual"] - - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"] - - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String,String,String)", "", "Argument[0]", "jdbc-url", "manual"] + - ["org.springframework.jdbc.datasource", "AbstractDriverBasedDataSource", False, "setUrl", "(String)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String,Properties)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.jdbc.datasource", "DriverManagerDataSource", False, "DriverManagerDataSource", "(String,String,String)", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.client.model.yml b/java/ql/lib/ext/org.springframework.web.client.model.yml index 69f4cb64fc6..79a7f577c3d 100644 --- a/java/ql/lib/ext/org.springframework.web.client.model.yml +++ b/java/ql/lib/ext/org.springframework.web.client.model.yml @@ -10,16 +10,16 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.web.client", "RestTemplate", False, "delete", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "doExecute", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "exchange", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "execute", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "getForEntity", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "headForHeaders", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "optionsForAllow", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "patchForObject", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "postForEntity", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "postForLocation", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "postForObject", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.client", "RestTemplate", False, "put", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "delete", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "doExecute", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "exchange", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "execute", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForEntity", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "getForObject", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "headForHeaders", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "optionsForAllow", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "patchForObject", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForEntity", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForLocation", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "postForObject", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.client", "RestTemplate", False, "put", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml b/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml index cb2d1db4444..a76582b5e80 100644 --- a/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml +++ b/java/ql/lib/ext/org.springframework.web.reactive.function.client.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.web.reactive.function.client", "WebClient", False, "create", "", "", "Argument[0]", "open-url", "manual"] - - ["org.springframework.web.reactive.function.client", "WebClient$Builder", False, "baseUrl", "", "", "Argument[0]", "open-url", "manual"] + - ["org.springframework.web.reactive.function.client", "WebClient", False, "create", "", "", "Argument[0]", "request-forgery", "manual"] + - ["org.springframework.web.reactive.function.client", "WebClient$Builder", False, "baseUrl", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/ext/retrofit2.model.yml b/java/ql/lib/ext/retrofit2.model.yml index 51c4c0eed83..4ea997169a9 100644 --- a/java/ql/lib/ext/retrofit2.model.yml +++ b/java/ql/lib/ext/retrofit2.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["retrofit2", "Retrofit$Builder", True, "baseUrl", "", "", "Argument[0]", "open-url", "manual"] + - ["retrofit2", "Retrofit$Builder", True, "baseUrl", "", "", "Argument[0]", "request-forgery", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index b4d1e146312..5776d64f402 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -274,13 +274,12 @@ module ModelValidation { exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind = [ - "open-url", "jndi-injection", "ldap-injection", "sql-injection", "jdbc-url", - "log-injection", "mvel-injection", "xpath-injection", "groovy-injection", - "html-injection", "js-injection", "ognl-injection", "intent-redirection", - "pending-intents", "url-redirection", "path-injection", "file-content-store", - "hostname-verification", "response-splitting", "information-leak", "xslt-injection", - "jexl-injection", "bean-validation", "template-injection", "fragment-injection", - "command-injection" + "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", + "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", + "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", + "path-injection", "file-content-store", "hostname-verification", "response-splitting", + "information-leak", "xslt-injection", "jexl-injection", "bean-validation", + "template-injection", "fragment-injection", "command-injection" ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and diff --git a/java/ql/lib/semmle/code/java/security/HttpsUrls.qll b/java/ql/lib/semmle/code/java/security/HttpsUrls.qll index a2b144a3833..23ccb306a16 100644 --- a/java/ql/lib/semmle/code/java/security/HttpsUrls.qll +++ b/java/ql/lib/semmle/code/java/security/HttpsUrls.qll @@ -30,7 +30,7 @@ class HttpStringLiteral extends StringLiteral { abstract class UrlOpenSink extends DataFlow::Node { } private class DefaultUrlOpenSink extends UrlOpenSink { - DefaultUrlOpenSink() { sinkNode(this, "open-url") } + DefaultUrlOpenSink() { sinkNode(this, "request-forgery") } } /** diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index f9b98490dfa..0eeea1c2afd 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -52,12 +52,8 @@ private class TypePropertiesRequestForgeryAdditionalTaintStep extends RequestFor /** A data flow sink for server-side request forgery (SSRF) vulnerabilities. */ abstract class RequestForgerySink extends DataFlow::Node { } -private class UrlOpenSinkAsRequestForgerySink extends RequestForgerySink { - UrlOpenSinkAsRequestForgerySink() { sinkNode(this, "open-url") } -} - -private class JdbcUrlSinkAsRequestForgerySink extends RequestForgerySink { - JdbcUrlSinkAsRequestForgerySink() { sinkNode(this, "jdbc-url") } +private class DefaultRequestForgerySink extends RequestForgerySink { + DefaultRequestForgerySink() { sinkNode(this, "request-forgery") } } /** A sanitizer for request forgery vulnerabilities. */ diff --git a/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll b/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll index bff6a0a3893..3b5a8940239 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll @@ -89,7 +89,7 @@ class GetVirtualFileChildMethod extends Method { /** An argument to `getResource()` or `getResourceAsStream()`. */ private class GetResourceSink extends UnsafeUrlForwardSink { GetResourceSink() { - sinkNode(this, "open-url") + sinkNode(this, "request-forgery") or sinkNode(this, "get-resource") or diff --git a/java/ql/test/library-tests/frameworks/okhttp/test.ql b/java/ql/test/library-tests/frameworks/okhttp/test.ql index 2992a519e64..52e8a47132a 100644 --- a/java/ql/test/library-tests/frameworks/okhttp/test.ql +++ b/java/ql/test/library-tests/frameworks/okhttp/test.ql @@ -5,7 +5,9 @@ import TestUtilities.InlineFlowTest module OkHttpFlowConfig implements DataFlow::ConfigSig { predicate isSource = DefaultFlowConfig::isSource/1; - predicate isSink(DataFlow::Node n) { DefaultFlowConfig::isSink(n) or sinkNode(n, "open-url") } + predicate isSink(DataFlow::Node n) { + DefaultFlowConfig::isSink(n) or sinkNode(n, "request-forgery") + } } module OkHttpFlow = DataFlow::Global<OkHttpFlowConfig>; diff --git a/java/ql/test/library-tests/frameworks/retrofit/test.ql b/java/ql/test/library-tests/frameworks/retrofit/test.ql index 5db5201aad0..e09f1ed41d7 100644 --- a/java/ql/test/library-tests/frameworks/retrofit/test.ql +++ b/java/ql/test/library-tests/frameworks/retrofit/test.ql @@ -5,7 +5,9 @@ import TestUtilities.InlineFlowTest module FlowConfig implements DataFlow::ConfigSig { predicate isSource = DefaultFlowConfig::isSource/1; - predicate isSink(DataFlow::Node n) { DefaultFlowConfig::isSink(n) or sinkNode(n, "open-url") } + predicate isSink(DataFlow::Node n) { + DefaultFlowConfig::isSink(n) or sinkNode(n, "request-forgery") + } } module Flow = DataFlow::Global<FlowConfig>; From 0a8c0f58b2c3f12889cb64f55174c050abad21fd Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 12:30:14 -0400 Subject: [PATCH 238/739] Java: add sink kinds documentation --- .../customizing-library-models-for-java.rst | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index baa93e8eb0a..d45ce942964 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -327,18 +327,31 @@ Taint sink. As opposed to source kinds, there are many different kinds of sinks The following sink kinds are supported: -- **sql**: A SQL injection vulnerability sink. -- **xss**: A cross-site scripting vulnerability sink. -- **logging**: A log output sink. - -Below is an enumeration of the remaining sinks, but they are out of scope for this documentation: - -- **open-url**, **jndi-injection**, **ldap**, **jdbc-url** -- **mvel**, **xpath**, **groovy**, **ognl-injection** -- **intent-start**, **pending-intent-sent**, **url-redirect** -- **create-file**, **read-file**, **write-file**, **set-hostname-verifier** -- **header-splitting**, **information-leak**, **xslt**, **jexl** -- **bean-validation**, **ssti**, **fragment-injection**, **regex-use[**\ `arg`\ **]** +- **bean-validation**: A sink that can be used for insecure bean validation, such as in calls to **ConstraintValidatorContext.buildConstraintViolationWithTemplate**. +- **command-injection**: A sink that can be used to inject shell commands, such as in calls to **Runtime.exec**. +- **file-content-store**: A sink that can be used to control the contents of a file, such as in a **Files.write** call. +- **fragment-injection**: A sink that can be used for Android fragment injection, such as in a **FragmentTransaction.replace** call. +- **groovy-injection**: A sink that can be used for Groovy injection, such as in a **GroovyShell.evaluate** call. +- **hostname-verification**: A sink that can be used for unsafe hostname verification, such as in calls to **HttpsURLConnection.setHostnameVerifier**. +- **html-injection**: A sink that can be used for XSS via HTML injection, such as in a **ResponseStream.write** call. +- **information-leak**: A sink that can be used to leak information to an HTTP response, such as in calls to **HttpServletResponse.sendError**. +- **intent-redirection**: A sink that can be used for Android intent redirection, such as in a **Context.startActivity** call. +- **jexl-injection**: A sink that can be used for JEXL expression injection, such as in a **JexlExpression.evaluate** call. +- **jndi-injection**: A sink that can be used for JNDI injection, such as in a **Context.lookup** call. +- **js-injection**: A sink that can be used for XSS via JavaScript injection, such as in a **Webview.evaluateJavaScript** call. +- **ldap-injection**: A sink that can be used for LDAP injection, such as in a **DirContext.search** call. +- **log-injection**: A sink that can be used for log injection, such as in a **Logger.warn** call. +- **mvel-injection**: A sink that can be used for MVEL expression injection, such as in a **MVEL.eval** call. +- **ognl-injection**: A sink that can be used for OGNL injection, such as in an **Ognl.getValue** call. +- **path-injection**: A sink that can be used for path injection in a file system access, such as in calls to **new FileReader**. +- **pending-intents**: A sink that can be used to send an implicit and mutable `PendingIntent` to a third party, such as in an **Activity.setResult** call. +- **request-forgery**: A sink that controls the URL of a request, such as in an **HttpRequest.newBuilder** call. +- **response-splitting**: A sink that can be used for HTTP response splitting, such as in calls to **HttpServletResponse.setHeader**. +- **sql-injection**: A sink that can be used for SQL injection, such as in a **Statement.executeQuery** call. +- **template-injection**: A sink that can be used for server side template injection, such as in a **Velocity.evaluate** call. +- **url-redirection**: A sink that can be used to redirect the user to a malicious URL, such as in a **Response.temporaryRedirect** call. +- **xpath-injection**: A sink that can be used for XPath injection, such as in a **XPath.evaluate** call. +- **xslt-injection**: A sink that can be used for XSLT injection, such as in a **Transformer.transform** call. summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 36e467e74adba329b72c4e494bc0235b55363c9c Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 14:49:07 -0400 Subject: [PATCH 239/739] Java: update cwe-sink.csv --- java/documentation/library-coverage/cwe-sink.csv | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java/documentation/library-coverage/cwe-sink.csv b/java/documentation/library-coverage/cwe-sink.csv index a4e2f5b9af9..16fff1e653b 100644 --- a/java/documentation/library-coverage/cwe-sink.csv +++ b/java/documentation/library-coverage/cwe-sink.csv @@ -1,7 +1,7 @@ CWE,Sink identifier,Label -CWE‑089,sql,SQL injection -CWE‑022,create-file,Path injection +CWE‑089,sql-injection,SQL injection +CWE‑022,path-injection,Path injection CWE‑094,bean-validation,Code injection -CWE‑319,open-url,Cleartext transmission -CWE‑079,xss,Cross-site scripting -CWE‑090,ldap,LDAP injection +CWE‑918,request-forgery,Request Forgery +CWE‑079,html-injection js-injection,Cross-site scripting +CWE‑090,ldap-injection,LDAP injection From ad771984f12e8056f9958614b0c3c65a81b5aab0 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 15:09:49 -0400 Subject: [PATCH 240/739] Java: update recently added path-injection sinks --- java/ql/lib/ext/org.springframework.util.model.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/ext/org.springframework.util.model.yml b/java/ql/lib/ext/org.springframework.util.model.yml index a0203a0ce9e..a868638c4df 100644 --- a/java/ql/lib/ext/org.springframework.util.model.yml +++ b/java/ql/lib/ext/org.springframework.util.model.yml @@ -3,9 +3,9 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.util", "FileCopyUtils", False, "copy", "(byte[],File)", "", "Argument[1]", "create-file", "manual"] - - ["org.springframework.util", "FileCopyUtils", False, "copy", "(File,File)", "", "Argument[0]", "read-file", "manual"] - - ["org.springframework.util", "FileCopyUtils", False, "copy", "(File,File)", "", "Argument[1]", "create-file", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copy", "(byte[],File)", "", "Argument[1]", "path-injection", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copy", "(File,File)", "", "Argument[0]", "path-injection", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copy", "(File,File)", "", "Argument[1]", "path-injection", "manual"] - addsTo: pack: codeql/java-all From e28ce959a3168f01c5f879fbade26f88f9a149c1 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 15:10:32 -0400 Subject: [PATCH 241/739] Java: update CaptureSinkModels test case --- .../modelgenerator/dataflow/CaptureSinkModels.expected | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected index b0c363c1b4a..799a1a37dd4 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected @@ -1,5 +1,5 @@ -| p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];create-file;df-generated | -| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];read-file;df-generated | -| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];create-file;df-generated | -| p;Sinks;true;readUrl;(URL,Charset);;Argument[0];open-url;df-generated | -| p;Sources;true;readUrl;(URL);;Argument[0];open-url;df-generated | +| p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];path-injection;df-generated | +| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];path-injection;df-generated | +| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];path-injection;df-generated | +| p;Sinks;true;readUrl;(URL,Charset);;Argument[0];request-forgery;df-generated | +| p;Sources;true;readUrl;(URL);;Argument[0];request-forgery;df-generated | From 6bb6802fb8c90f831634e306ef9f974a78a7db04 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 9 May 2023 15:26:05 -0400 Subject: [PATCH 242/739] Java: add change note draft --- .../2023-05-05-java-sink-kind-revamp.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md diff --git a/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md b/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md new file mode 100644 index 00000000000..2ca5dedff2e --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md @@ -0,0 +1,22 @@ +--- +category: minorAnalysis +--- +* Updated the following Java sink kind names: + * `sql` to `sql-injection` + * `url-redirect` to `url-redirection` + * `xpath` to `xpath-injection` + * `ssti` to `template-injection` + * `logging` to `log-injection` + * `groovy` to `groovy-injection` + * `jexl` to `jexl-injection` + * `mvel` to `mvel-injection` + * `xslt` to `xslt-injection` + * `ldap` to `ldap-injection` + * `pending-intent-sent` to `pending-intents` + * `intent-start` to `intent-redirection` + * `set-hostname-verifier` to `hostname-verification` + * `header-splitting` to `response-splitting` + * `xss` to `html-injection` and `js-injection` + * `write-file` to `file-system-store` + * `create-file` and `read-file` to `path-injection` + * `open-url` and `jdbc-url` to `request-forgery` From 3e5dc28c0a64048b1c1a2d98d4632e20601589f5 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Wed, 10 May 2023 17:27:03 -0400 Subject: [PATCH 243/739] Java: update more recently added sinks: path-injection and request-forgery --- .../lib/ext/org.apache.commons.net.model.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/ext/org.apache.commons.net.model.yml b/java/ql/lib/ext/org.apache.commons.net.model.yml index 1ea8876a4e1..0a4c46e6a3c 100644 --- a/java/ql/lib/ext/org.apache.commons.net.model.yml +++ b/java/ql/lib/ext/org.apache.commons.net.model.yml @@ -3,15 +3,15 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.commons.net", "SocketClient", true, "connect", "(InetAddress)", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.commons.net", "SocketClient", true, "connect", "(InetAddress,int)", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.commons.net", "SocketClient", true, "connect", "(InetAddress,int,InetAddress,int)", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.commons.net", "SocketClient", true, "connect", "(String)", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.commons.net", "SocketClient", true, "connect", "(String,int)", "", "Argument[0]", "open-url", "df-manual"] - - ["org.apache.commons.net", "SocketClient", true, "connect", "(String,int,InetAddress,int)", "", "Argument[0]", "open-url", "manual"] - - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(File,String)", "", "Argument[0]", "read-file", "df-manual"] - - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(File,String,String)", "", "Argument[0]", "read-file", "df-manual"] - - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(String,File,String,String,String)", "", "Argument[1]", "read-file", "df-manual"] + - ["org.apache.commons.net", "SocketClient", true, "connect", "(InetAddress)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.commons.net", "SocketClient", true, "connect", "(InetAddress,int)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.commons.net", "SocketClient", true, "connect", "(InetAddress,int,InetAddress,int)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.commons.net", "SocketClient", true, "connect", "(String)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.commons.net", "SocketClient", true, "connect", "(String,int)", "", "Argument[0]", "request-forgery", "df-manual"] + - ["org.apache.commons.net", "SocketClient", true, "connect", "(String,int,InetAddress,int)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(File,String)", "", "Argument[0]", "path-injection", "df-manual"] + - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(File,String,String)", "", "Argument[0]", "path-injection", "df-manual"] + - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(String,File,String,String,String)", "", "Argument[1]", "path-injection", "df-manual"] - addsTo: pack: codeql/java-all extensible: sourceModel From 9853a66b327f871ce0ddd42cb97dd1e62153fa80 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 11 May 2023 12:20:23 -0400 Subject: [PATCH 244/739] Java: update change note --- java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md b/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md index 2ca5dedff2e..ef54f491051 100644 --- a/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md +++ b/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md @@ -1,7 +1,7 @@ --- category: minorAnalysis --- -* Updated the following Java sink kind names: +* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working. * `sql` to `sql-injection` * `url-redirect` to `url-redirection` * `xpath` to `xpath-injection` From ca8ac0c93fbd94aab092ee88e71c1d0f28472293 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 11 May 2023 12:40:29 -0400 Subject: [PATCH 245/739] Java: add comment about request-forgery sinks --- java/ql/lib/semmle/code/java/security/HttpsUrls.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/lib/semmle/code/java/security/HttpsUrls.qll b/java/ql/lib/semmle/code/java/security/HttpsUrls.qll index 23ccb306a16..07435889fd9 100644 --- a/java/ql/lib/semmle/code/java/security/HttpsUrls.qll +++ b/java/ql/lib/semmle/code/java/security/HttpsUrls.qll @@ -30,6 +30,7 @@ class HttpStringLiteral extends StringLiteral { abstract class UrlOpenSink extends DataFlow::Node { } private class DefaultUrlOpenSink extends UrlOpenSink { + // request-forgery sinks control the URL of a request DefaultUrlOpenSink() { sinkNode(this, "request-forgery") } } From 51f8f98118be37d62da93069c92ae3c235df9450 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 30 May 2023 14:39:20 -0400 Subject: [PATCH 246/739] Java: update recently added 'sql' sinks --- ...ingframework.jdbc.core.namedparam.model.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/ext/org.springframework.jdbc.core.namedparam.model.yml b/java/ql/lib/ext/org.springframework.jdbc.core.namedparam.model.yml index 9ecd0973558..a2ba27f6062 100644 --- a/java/ql/lib/ext/org.springframework.jdbc.core.namedparam.model.yml +++ b/java/ql/lib/ext/org.springframework.jdbc.core.namedparam.model.yml @@ -3,12 +3,12 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "batchUpdate", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "execute", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "query", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForList", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForMap", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForObject", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForRowSet", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForStream", "", "", "Argument[0]", "sql", "manual"] - - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "update", "", "", "Argument[0]", "sql", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "batchUpdate", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "execute", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "query", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForList", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForMap", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForObject", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForRowSet", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "queryForStream", "", "", "Argument[0]", "sql-injection", "manual"] + - ["org.springframework.jdbc.core.namedparam", "NamedParameterJdbcOperations", True, "update", "", "", "Argument[0]", "sql-injection", "manual"] From 82f208ca7a113ebd04276a1011ec6336307b6882 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Wed, 31 May 2023 17:47:36 -0400 Subject: [PATCH 247/739] Java: add isNeutralSink test case --- .../neutrals/neutralsinks/NeutralSinksTest.ql | 24 ++++++++- .../neutrals/neutralsinks/Test.java | 52 +++++++++---------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql index 422508f5711..224b03ea51c 100644 --- a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql +++ b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql @@ -2,9 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow +import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -class NeutralSinksTest extends InlineExpectationsTest { - NeutralSinksTest() { this = "NeutralSinksTest" } +class SinkTest extends InlineExpectationsTest { + SinkTest() { this = "SinkTest" } override string getARelevantTag() { result = "isSink" } @@ -18,3 +19,22 @@ class NeutralSinksTest extends InlineExpectationsTest { ) } } + +class NeutralSinkTest extends InlineExpectationsTest { + NeutralSinkTest() { this = "NeutralSinkTest" } + + override string getARelevantTag() { result = "isNeutralSink" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "isNeutralSink" and + exists(Call call, Callable callable | + call.getCallee() = callable and + neutralModel(callable.getDeclaringType().getCompilationUnit().getPackage().getName(), + callable.getDeclaringType().getSourceDeclaration().nestedName(), callable.getName(), + [paramsString(callable), ""], "sink", _) and + call.getLocation() = location and + element = call.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/Test.java b/java/ql/test/library-tests/neutrals/neutralsinks/Test.java index fee2cbbb7dd..a234132226f 100644 --- a/java/ql/test/library-tests/neutrals/neutralsinks/Test.java +++ b/java/ql/test/library-tests/neutrals/neutralsinks/Test.java @@ -14,48 +14,48 @@ public class Test { // java.io File file = null; - file.exists(); // Neutral Sink - file.compareTo(null); // Neutral Sink + file.exists(); // $ isNeutralSink + file.compareTo(null); // $ isNeutralSink // java.nio.file - Files.exists(null, (LinkOption[])null); // Neutral Sink - Files.getLastModifiedTime(null, (LinkOption[])null); // Neutral Sink - Files.getOwner(null, (LinkOption[])null); // Neutral Sink - Files.getPosixFilePermissions(null, (LinkOption[])null); // Neutral Sink - Files.isDirectory(null, (LinkOption[])null); // Neutral Sink - Files.isExecutable(null); // Neutral Sink - Files.isHidden(null); // Neutral Sink - Files.isReadable(null); // Neutral Sink - Files.isRegularFile(null, (LinkOption[])null); // Neutral Sink - Files.isSameFile(null, null); // Neutral Sink - Files.isSymbolicLink(null); // Neutral Sink - Files.isWritable(null); // Neutral Sink - Files.notExists(null, (LinkOption[])null); // Neutral Sink - Files.setLastModifiedTime(null, null); // Neutral Sink - Files.size(null); // Neutral Sink + Files.exists(null, (LinkOption[])null); // $ isNeutralSink + Files.getLastModifiedTime(null, (LinkOption[])null); // $ isNeutralSink + Files.getOwner(null, (LinkOption[])null); // $ isNeutralSink + Files.getPosixFilePermissions(null, (LinkOption[])null); // $ isNeutralSink + Files.isDirectory(null, (LinkOption[])null); // $ isNeutralSink + Files.isExecutable(null); // $ isNeutralSink + Files.isHidden(null); // $ isNeutralSink + Files.isReadable(null); // $ isNeutralSink + Files.isRegularFile(null, (LinkOption[])null); // $ isNeutralSink + Files.isSameFile(null, null); // $ isNeutralSink + Files.isSymbolicLink(null); // $ isNeutralSink + Files.isWritable(null); // $ isNeutralSink + Files.notExists(null, (LinkOption[])null); // $ isNeutralSink + Files.setLastModifiedTime(null, null); // $ isNeutralSink + Files.size(null); // $ isNeutralSink // java.nio.file.spi FileSystemProvider fsp = null; - fsp.isHidden(null); // Neutral Sink - fsp.isSameFile(null, null); // Neutral Sink + fsp.isHidden(null); // $ isNeutralSink + fsp.isSameFile(null, null); // $ isNeutralSink // java.text Collator c = null; - c.compare(null, null); // Neutral Sink - c.equals(null); // Neutral Sink - c.equals(null, null); // Neutral Sink + c.compare(null, null); // $ isNeutralSink + c.equals(null); // $ isNeutralSink + c.equals(null, null); // $ isNeutralSink RuleBasedCollator rbc = null; - rbc.compare(null, null); // Neutral Sink + rbc.compare(null, null); // $ isNeutralSink // java.util.prefs AbstractPreferences ap = null; - ap.nodeExists(null); // Neutral Sink + ap.nodeExists(null); // $ isNeutralSink Preferences p = null; - p.nodeExists(null); // Neutral Sink + p.nodeExists(null); // $ isNeutralSink // org.apache.hc.client5.http.protocol RedirectLocations rl = null; - rl.contains(null); // Neutral Sink + rl.contains(null); // $ isNeutralSink } } From 13ce6a6d8e9ef6a7285e9e47825100ae29187560 Mon Sep 17 00:00:00 2001 From: Maiky <76447395+maikypedia@users.noreply.github.com> Date: Thu, 1 Jun 2023 00:53:01 +0200 Subject: [PATCH 248/739] Update Frameworks.qll --- ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index d7b76c090b2..ffa6e8219a4 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -32,4 +32,5 @@ private import codeql.ruby.frameworks.Slim private import codeql.ruby.frameworks.Sinatra private import codeql.ruby.frameworks.Twirp private import codeql.ruby.frameworks.Sqlite3 +private import codeql.ruby.frameworks.Pg private import codeql.ruby.frameworks.Sequel From 3ef08d5baf25d1cfdef5c3f159b31aa360f8fb36 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 00:20:17 +0000 Subject: [PATCH 249/739] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 6 ++++-- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 48f5dd8ae41..0bd4f53a9a7 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -21,6 +21,7 @@ com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 com.google.common.flogger,29,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,,, com.google.common.io,8,,73,,2,,,,,,,,,,,,,,,5,,,,,,,,,,,,1,,,,,,,,72,1 +com.google.gson,,,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,14 com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,,, @@ -77,7 +78,7 @@ jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 kotlin,16,,1843,,11,,,,,,,,,,,,,2,,3,,,,,,,,,,,,,,,,,,,,1836,7 net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, ognl,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, -okhttp3,2,,47,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,22,25 +okhttp3,4,,47,,,,,,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,22,25 org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 @@ -152,7 +153,8 @@ org.springframework.web.util,,,165,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,140,25 org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,2, org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, +play.libs.ws,2,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,, +play.mvc,,13,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,24, ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index d89fce45524..b87eeb390fe 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -22,6 +22,6 @@ Java framework & library support Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,1,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1843,16,11,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,113,2,,28,14,,29 - Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",89,827,516,26,,18,18,,181 - Totals,,246,9119,1969,175,10,122,33,1,361 + Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,890,520,26,,18,18,,185 + Totals,,255,9182,1973,175,10,122,33,1,365 From 3862f8e3c0830b710a8322774f0d6fafd190d4e1 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 10 May 2023 11:41:26 +0200 Subject: [PATCH 250/739] C#: Expose synthetic globals for use in C#, allow printing of summaries that uses synthetic globals. --- csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll | 4 ++++ .../code/csharp/dataflow/internal/FlowSummaryImpl.qll | 5 +++++ .../csharp/dataflow/internal/FlowSummaryImplSpecific.qll | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll index 5d90a990979..98b95673b0f 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll @@ -72,6 +72,10 @@ module SummaryComponent { jrk.getTargetReturnKind() instanceof DataFlowDispatch::NormalReturnKind )) } + + predicate syntheticGlobal = SummaryComponentInternal::syntheticGlobal/1; + + class SyntheticGlobal = SummaryComponentInternal::SyntheticGlobal; } class SummaryComponentStack = Impl::Public::SummaryComponentStack; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..614c785440c 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -180,6 +180,11 @@ module Public { result = "Argument[" + getParameterPosition(pos) + "]" ) or + exists(string synthetic | + sc = TSyntheticGlobalSummaryComponent(synthetic) and + result = "SyntheticGlobal[" + synthetic + "]" + ) + or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index 97a27c65ef0..6bb3fb822c2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -19,6 +19,13 @@ class SummarizedCallableBase extends Callable { SummarizedCallableBase() { this.isUnboundDeclaration() } } +/** + * A module for importing frameworks that define synthetic globals. + */ +private module SyntheticGlobals { + private import semmle.code.csharp.frameworks.EntityFramework +} + DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c } /** Gets the parameter position of the instance parameter. */ From 06b02eb3ceebd9f238b2d1da23e3d79e11ee32b0 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 31 May 2023 08:46:40 +0200 Subject: [PATCH 251/739] Sync files. --- go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll | 5 +++++ .../semmle/code/java/dataflow/internal/FlowSummaryImpl.qll | 5 +++++ .../semmle/python/dataflow/new/internal/FlowSummaryImpl.qll | 5 +++++ .../ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll | 5 +++++ .../lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll | 5 +++++ 5 files changed, 25 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..614c785440c 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -180,6 +180,11 @@ module Public { result = "Argument[" + getParameterPosition(pos) + "]" ) or + exists(string synthetic | + sc = TSyntheticGlobalSummaryComponent(synthetic) and + result = "SyntheticGlobal[" + synthetic + "]" + ) + or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..614c785440c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -180,6 +180,11 @@ module Public { result = "Argument[" + getParameterPosition(pos) + "]" ) or + exists(string synthetic | + sc = TSyntheticGlobalSummaryComponent(synthetic) and + result = "SyntheticGlobal[" + synthetic + "]" + ) + or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index e6379f6a170..614c785440c 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -180,6 +180,11 @@ module Public { result = "Argument[" + getParameterPosition(pos) + "]" ) or + exists(string synthetic | + sc = TSyntheticGlobalSummaryComponent(synthetic) and + result = "SyntheticGlobal[" + synthetic + "]" + ) + or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..614c785440c 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -180,6 +180,11 @@ module Public { result = "Argument[" + getParameterPosition(pos) + "]" ) or + exists(string synthetic | + sc = TSyntheticGlobalSummaryComponent(synthetic) and + result = "SyntheticGlobal[" + synthetic + "]" + ) + or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..614c785440c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -180,6 +180,11 @@ module Public { result = "Argument[" + getParameterPosition(pos) + "]" ) or + exists(string synthetic | + sc = TSyntheticGlobalSummaryComponent(synthetic) and + result = "SyntheticGlobal[" + synthetic + "]" + ) + or sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue" } From 93d97839400b209bfa8f2886225d9c02b68850fe Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 12 May 2023 11:24:17 +0200 Subject: [PATCH 252/739] C#: Expose a synthetic global singleton stack. --- csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll index 98b95673b0f..b778e370d5c 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll @@ -116,6 +116,11 @@ module SummaryComponentStack { /** Gets a singleton stack representing a jump to `c`. */ SummaryComponentStack jump(Callable c) { result = singleton(SummaryComponent::jump(c)) } + + /** Gets a singleton stack representing a synthetic global with name `name`. */ + SummaryComponentStack syntheticGlobal(string synthetic) { + result = singleton(SummaryComponent::syntheticGlobal(synthetic)) + } } class SummarizedCallable = Impl::Public::SummarizedCallable; From cd251f4b369452111bdea78e38a9c51ff00f2a93 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 11 May 2023 13:41:10 +0200 Subject: [PATCH 253/739] C#: Make example classes public to allow printing of summaries in test. --- .../frameworks/EntityFramework/EntityFramework.cs | 8 ++++---- .../frameworks/EntityFramework/EntityFrameworkCore.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/EntityFramework.cs b/csharp/ql/test/library-tests/frameworks/EntityFramework/EntityFramework.cs index af51015b51c..d70369f6eaa 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/EntityFramework.cs +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/EntityFramework.cs @@ -5,7 +5,7 @@ using System.Linq; namespace EFTests { - class Person + public class Person { public virtual int Id { get; set; } public virtual string Name { get; set; } @@ -17,13 +17,13 @@ namespace EFTests public ICollection<Address> Addresses { get; set; } } - class Address + public class Address { public int Id { get; set; } public string Street { get; set; } } - class PersonAddressMap + public class PersonAddressMap { public int Id { get; set; } public int PersonId { get; set; } @@ -34,7 +34,7 @@ namespace EFTests public Address Address { get; set; } } - class MyContext : DbContext + public class MyContext : DbContext { public virtual DbSet<Person> Persons { get; set; } public virtual DbSet<Address> Addresses { get; set; } diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/EntityFrameworkCore.cs b/csharp/ql/test/library-tests/frameworks/EntityFramework/EntityFrameworkCore.cs index b45290dc799..1c7febb3398 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/EntityFrameworkCore.cs +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/EntityFrameworkCore.cs @@ -6,7 +6,7 @@ using System.Linq; namespace EFCoreTests { - class Person + public class Person { public virtual int Id { get; set; } public virtual string Name { get; set; } @@ -18,13 +18,13 @@ namespace EFCoreTests public ICollection<Address> Addresses { get; set; } } - class Address + public class Address { public int Id { get; set; } public string Street { get; set; } } - class PersonAddressMap + public class PersonAddressMap { public int Id { get; set; } public int PersonId { get; set; } @@ -35,7 +35,7 @@ namespace EFCoreTests public Address Address { get; set; } } - class MyContext : DbContext + public class MyContext : DbContext { public virtual DbSet<Person> Persons { get; set; } public virtual DbSet<Address> Addresses { get; set; } From d12dfabf9df4366bbba67ec6224ecdc9f638a7ce Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 12 May 2023 11:25:13 +0200 Subject: [PATCH 254/739] C#: Use synthetic globals instead of jump returns in the EntityFramework implementation. --- .../code/csharp/dataflow/FlowSummary.qll | 3 + .../csharp/frameworks/EntityFramework.qll | 159 +++++++++++++++--- 2 files changed, 136 insertions(+), 26 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll index b778e370d5c..fc4e68f2448 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll @@ -121,6 +121,9 @@ module SummaryComponentStack { SummaryComponentStack syntheticGlobal(string synthetic) { result = singleton(SummaryComponent::syntheticGlobal(synthetic)) } + + /** Gets a textual representation of this stack used for flow summaries. */ + string getComponentStack(SummaryComponentStack s) { result = Impl::Public::getComponentStack(s) } } class SummarizedCallable = Impl::Public::SummarizedCallable; diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index e0dfc0d542d..6e099a81fa2 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -4,6 +4,7 @@ import csharp private import DataFlow +private import semmle.code.csharp.commons.QualifiedName private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.data.Entity private import semmle.code.csharp.frameworks.system.collections.Generic @@ -236,7 +237,7 @@ module EntityFramework { * } * ``` */ - private Property getADbSetProperty(Class elementType) { + Property getADbSetProperty(Class elementType) { exists(ConstructedClass c | result.getType() = c and c.getUnboundDeclaration() instanceof DbSet and @@ -334,6 +335,18 @@ module EntityFramework { result.getName().matches("SaveChanges%") } + /** + * Gets the string representation for synthetic identifiers for SaveChanges methods + * on this. + */ + string getSyntheticNames() { + exists(string qualifier, string type, string name | + this.getASaveChanges().hasQualifiedName(qualifier, type, name) + | + result = getQualifiedName(qualifier, type, name) + ) + } + /** Holds if component stack `head :: tail` is required for the input specification. */ predicate requiresComponentStackIn( Content head, Type headType, SummaryComponentStack tail, int dist @@ -351,56 +364,150 @@ module EntityFramework { /** Holds if component stack `head :: tail` is required for the output specification. */ predicate requiresComponentStackOut( - Content head, Type headType, SummaryComponentStack tail, int dist + Content head, Type headType, SummaryComponentStack tail, int dist, + DbContextClassSetProperty dbSetProp ) { - exists(Property dbSetProp, PropertyContent c1 | + exists(PropertyContent c1 | dbSetProp = this.getADbSetProperty(headType) and this.stepRev(c1, _, head, headType, 0) and c1.getProperty() = dbSetProp and - tail = SummaryComponentStack::jump(dbSetProp.getGetter()) and + tail = SummaryComponentStack::return() and dist = 0 ) or exists(Content tailHead, SummaryComponentStack tailTail, Type tailType | - this.requiresComponentStackOut(tailHead, tailType, tailTail, dist - 1) and + this.requiresComponentStackOut(tailHead, tailType, tailTail, dist - 1, dbSetProp) and tail = SummaryComponentStack::push(SummaryComponent::content(tailHead), tailTail) and this.stepRev(tailHead, tailType, head, headType, dist) ) } } + private class DbContextClassSetProperty extends Property { + private DbContextClass c; + + DbContextClassSetProperty() { this = c.getADbSetProperty(_) } + + /** + * Gets the string representation for a synthetic identifier for this. + */ + string getSyntheticName() { + exists(string qualifier, string type, string name | + this.hasQualifiedName(qualifier, type, name) + | + result = getQualifiedName(qualifier, type, name) + ) + } + + /** + * Gets the context class where this is a Db set property. + */ + DbContextClass getDbContextClass() { result = c } + } + + /** + * Holds if `input` is a valid summary component stack for property `mapped` + * for the context class `c`. + */ + pragma[noinline] + predicate input(DbContextClass c, SummaryComponentStack input, Property mapped) { + exists(PropertyContent head, SummaryComponentStack tail | + c.requiresComponentStackIn(head, _, tail, _) and + head.getProperty() = mapped and + mapped = c.getAColumnProperty(_) and + input = SummaryComponentStack::push(SummaryComponent::content(head), tail) + ) + } + + /** + * Holds if `output` is a valid summary component stack for the getter of `dbSet` + * for property `mapped` for the context class `c`. + */ + pragma[noinline] + predicate output( + DbContextClass c, SummaryComponentStack output, Property mapped, DbContextClassSetProperty dbSet + ) { + exists(PropertyContent head, SummaryComponentStack tail | + c.requiresComponentStackOut(head, _, tail, _, dbSet) and + head.getProperty() = mapped and + mapped = c.getAColumnProperty(_) and + output = SummaryComponentStack::push(SummaryComponent::content(head), tail) + ) + } + + bindingset[save, prop, stack1, stack2] + private string getFullSyntheticName( + string save, string prop, SummaryComponentStack stack1, SummaryComponentStack stack2 + ) { + result = + save + "#" // + + prop + "#" // + + SummaryComponentStack::getComponentStack(stack1) + "#" // + + SummaryComponentStack::getComponentStack(stack2) + } + + private class DbContextClassSetPropertySynthetic extends EFSummarizedCallable { + private DbContextClassSetProperty p; + + DbContextClassSetPropertySynthetic() { this = p.getGetter() } + + override predicate propagatesFlow( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ) { + exists(SummaryComponentStack synthetic, string name, DbContextClass c, Property mapped | + preservesValue = true and + c = p.getDbContextClass() and + input(c, synthetic, mapped) and + output(c, output, mapped, p) and + name = getFullSyntheticName(c.getSyntheticNames(), p.getSyntheticName(), synthetic, output) and + input = SummaryComponentStack::syntheticGlobal(name) + ) + } + } + private class DbContextSaveChanges extends EFSummarizedCallable { private DbContextClass c; DbContextSaveChanges() { this = c.getASaveChanges() } - pragma[noinline] - private predicate input(SummaryComponentStack input, Property mapped) { - exists(PropertyContent head, SummaryComponentStack tail | - c.requiresComponentStackIn(head, _, tail, _) and - head.getProperty() = mapped and - mapped = c.getAColumnProperty(_) and - input = SummaryComponentStack::push(SummaryComponent::content(head), tail) - ) - } - - pragma[noinline] - private predicate output(SummaryComponentStack output, Property mapped) { - exists(PropertyContent head, SummaryComponentStack tail | - c.requiresComponentStackOut(head, _, tail, _) and - head.getProperty() = mapped and - mapped = c.getAColumnProperty(_) and - output = SummaryComponentStack::push(SummaryComponent::content(head), tail) + private string getSyntheticName() { + exists(string qualifier, string type, string name | + this.(Method).hasQualifiedName(qualifier, type, name) + | + result = getQualifiedName(qualifier, type, name) ) } override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - exists(Property mapped | + exists( + SummaryComponentStack synthetic, string name, Property mapped, + DbContextClassSetProperty dbSet + | preservesValue = true and - this.input(input, mapped) and - this.output(output, mapped) + input(c, input, mapped) and + output(c, synthetic, mapped, dbSet) and + name = + getFullSyntheticName(this.getSyntheticName(), dbSet.getSyntheticName(), input, synthetic) and + output = SummaryComponentStack::syntheticGlobal(name) + ) + } + } + + /** + * Add all `DbContext` property names as potential synthetic globals. + */ + private class EFSummarizedCallableSyntheticGlobal extends SummaryComponent::SyntheticGlobal { + EFSummarizedCallableSyntheticGlobal() { + exists( + DbContextClass c, SummaryComponentStack input, SummaryComponentStack output, + Property mapped, DbContextClassSetProperty dbSet + | + input(c, input, mapped) and + output(c, output, mapped, dbSet) + | + this = getFullSyntheticName(c.getSyntheticNames(), dbSet.getSyntheticName(), input, output) ) } } @@ -411,7 +518,7 @@ module EntityFramework { exists(Content c | head = SummaryComponent::content(c) | any(DbContextClass cls).requiresComponentStackIn(c, _, tail, _) or - any(DbContextClass cls).requiresComponentStackOut(c, _, tail, _) + any(DbContextClass cls).requiresComponentStackOut(c, _, tail, _, _) ) } } From d882fe1ea8cf519fd801f2962b0383a4d87436a6 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 12 May 2023 13:52:12 +0200 Subject: [PATCH 255/739] C#: Update expected test output. --- .../EntityFramework/FlowSummaries.expected | 348 ++++++++++++------ 1 file changed, 232 insertions(+), 116 deletions(-) diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected index 4698be24b8c..a07191d8fa0 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected @@ -1,120 +1,236 @@ summary -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Id];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Name];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Name];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Name];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Name];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Id];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | neutral sourceNode sinkNode From 9aeb2384f35db392daa1fe22d4dde8ec1bd2bb4c Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 1 Jun 2023 10:20:54 +0200 Subject: [PATCH 256/739] C#: Improve LINQ expression based on review comments. --- .../Entities/Expressions/ImplicitCast.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs index 20daedc0ae8..ebd7379ee67 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs @@ -42,13 +42,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions private static IMethodSymbol? GetImplicitConversionMethod(ITypeSymbol type, object value) => type .GetMembers() - .Where(m => - m is IMethodSymbol method && + .OfType<IMethodSymbol>() + .Where(method => method.GetName() == "op_Implicit" && method.Parameters.Length == 1 && method.Parameters[0].Type.Name == value.GetType().Name ) - .Cast<IMethodSymbol>() .FirstOrDefault(); // Creates a new generated expression with an implicit cast added, if needed. From 7579f182ad310d97c68c49f3cdceaace5724637c Mon Sep 17 00:00:00 2001 From: Maiky <76447395+maikypedia@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:00:35 +0200 Subject: [PATCH 257/739] Add requested changes --- ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll | 22 +++++++++++++++++ .../ql/lib/codeql/ruby/frameworks/Sqlite3.qll | 24 ++++++++++++++++++- .../security/SqlInjectionCustomizations.qll | 21 +++------------- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll index c1c74813b75..1b7c1cde61e 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.qll @@ -48,4 +48,26 @@ module Mysql2 { override DataFlow::Node getSql() { result = query } } + + /** + * A call to `Mysql2::Client.escape`, considered as a sanitizer for SQL statements. + */ + private class Mysql2EscapeSanitization extends SqlSanitization::Range { + Mysql2EscapeSanitization() { + this = API::getTopLevelMember("Mysql2").getMember("Client").getAMethodCall("escape") + } + } + + /** + * Flow summary for `Mysql2::Client.escape()`. + */ + private class EscapeSummary extends SummarizedCallable { + EscapeSummary() { this = "Mysql2::Client.escape()" } + + override MethodCall getACall() { result = any(Mysql2EscapeSanitization c).asExpr().getExpr() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and output = "ReturnValue" and preservesValue = false + } + } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.qll b/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.qll index e051a847993..8a07e211a21 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.qll @@ -77,4 +77,26 @@ module Sqlite3 { override DataFlow::Node getSql() { result = this.getArgument(0) } } -} + + /** + * A call to `SQLite3::Database.quote`, considered as a sanitizer for SQL statements. + */ + private class SQLite3QuoteSanitization extends SqlSanitization { + SQLite3QuoteSanitization() { + this = API::getTopLevelMember("SQLite3").getMember("Database").getAMethodCall("quote") + } + } + + /** + * Flow summary for `SQLite3::Database.quote()`. + */ + private class QuoteSummary extends SummarizedCallable { + QuoteSummary() { this = "SQLite3::Database.quote()" } + + override MethodCall getACall() { result = any(SQLite3QuoteSanitization c).asExpr().getExpr() } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and output = "ReturnValue" and preservesValue = false + } + } +} \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll index e1e1b630d9d..48358fe1d6b 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll @@ -52,23 +52,8 @@ module SqlInjection { * sanitizer-guard. */ class StringConstArrayInclusionCallAsSanitizer extends Sanitizer, - StringConstArrayInclusionCallBarrier { } + StringConstArrayInclusionCallBarrier + { } - /** - * A call to `Mysql2::Client.escape`, considered as a sanitizer. - */ - private class Mysql2EscapeSanitization extends Sanitizer { - Mysql2EscapeSanitization() { - this = API::getTopLevelMember("Mysql2").getMember("Client").getAMethodCall("escape") - } - } - - /** - * A call to `SQLite3::Database.quote`, considered as a sanitizer. - */ - private class SQLite3EscapeSanitization extends Sanitizer { - SQLite3EscapeSanitization() { - this = API::getTopLevelMember("SQLite3").getMember("Database").getAMethodCall("quote") - } - } + private class SqlSanitizationAsSanitizer extends Sanitizer, SqlSanitization { } } From edfdddb24af488d4e9199c6948aaad3e3ce0a79c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:47:05 +0100 Subject: [PATCH 258/739] Swift: Tweak and update the qldoc string. --- swift/ql/.generated.list | 4 ++-- swift/ql/lib/codeql/swift/generated/Callable.qll | 2 +- swift/ql/lib/codeql/swift/generated/Raw.qll | 2 +- swift/schema.py | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 6394bc951c9..3fac0083642 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -368,7 +368,7 @@ lib/codeql/swift/elements.qll 3df0060edd2b2030f4e4d7d5518afe0073d798474d9b1d6185 lib/codeql/swift/generated/AstNode.qll 02ca56d82801f942ae6265c6079d92ccafdf6b532f6bcebd98a04029ddf696e4 6216fda240e45bd4302fa0cf0f08f5f945418b144659264cdda84622b0420aa2 lib/codeql/swift/generated/AvailabilityInfo.qll 1e38e7f52ccbcecd4dd088eae15c482d87911682dabb426332cc0e207fc6bf2f 7c6640530cdbece90d4172e8d6cfd119656860da08bb61ed4ef3a6757723994f lib/codeql/swift/generated/AvailabilitySpec.qll fb1255f91bb5e41ad4e9c675a2efbc50d0fb366ea2de68ab7eebd177b0795309 144e0c2e7d6c62ecee43325f7f26dcf437881edf0b75cc1bc898c6c4b61fdeaf -lib/codeql/swift/generated/Callable.qll c1f214f5ea4da567d3cf2ac4915630ae1e19c939d2aa64cdd5ab06e76de059dc c43fd17a89d016a31584de10e4d4988f3ea10dc26d6b59b3151bb3196e9f0689 +lib/codeql/swift/generated/Callable.qll 5b6d79a4db8d98ea2255f0773d3512ad195e87fe47bab669d6e24668417ab96d 579506e89ad2385739384ab3fecfb1da699d862ee3a9e9a7225b095b0ec279ff lib/codeql/swift/generated/Comment.qll f58b49f6e68c21f87c51e2ff84c8a64b09286d733e86f70d67d3a98fe6260bd6 975bbb599a2a7adc35179f6ae06d9cbc56ea8a03b972ef2ee87604834bc6deb1 lib/codeql/swift/generated/DbFile.qll a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc a49b2a2cb2788cb49c861ebcd458b8daead7b15adb19c3a9f4db3bf39a0051fc lib/codeql/swift/generated/DbLocation.qll b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 b9baea963d9fa82068986512c0649d1050897654eee3df51dba17cf6b1170873 @@ -383,7 +383,7 @@ lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d lib/codeql/swift/generated/ParentChild.qll 5c5ff9812efbed0adf465d1c8b9108c893c77ff946f6feaaec7223ad38664079 94038dcd8a5e98b959ce9f09b7b54b745b0df49b91339b9396017a209abe8bb7 lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 87402f6b1a0173503a545b57b06c0e320459410834c9adc7a25b2ae53874075e 49e27ddf824decdf21c0531b1ebb3fa007a869ec63bde9f60d08a68fae12acc6 +lib/codeql/swift/generated/Raw.qll 991f95f30bde82ba43237bd9c1a68d3f450038ef828edb89219fbf583dd1956a e3e6c41caac09d532453c28167622fae7057d846f35750873eacd48cd128b957 lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 diff --git a/swift/ql/lib/codeql/swift/generated/Callable.qll b/swift/ql/lib/codeql/swift/generated/Callable.qll index 924614643f6..09105447736 100644 --- a/swift/ql/lib/codeql/swift/generated/Callable.qll +++ b/swift/ql/lib/codeql/swift/generated/Callable.qll @@ -11,7 +11,7 @@ module Generated { /** * Gets the name of this callable, if it exists. * - * The name includes any arguments of the callable, for example `myFunction(arg:)`. + * The name includes argument labels of the callable, for example `myFunction(arg:)`. */ string getName() { result = Synth::convertCallableToRaw(this).(Raw::Callable).getName() } diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index dc27ea87ef3..38e84cd3093 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -22,7 +22,7 @@ module Raw { /** * Gets the name of this callable, if it exists. * - * The name includes any arguments of the callable, for example `myFunction(arg:)`. + * The name includes argument labels of the callable, for example `myFunction(arg:)`. */ string getName() { callable_names(this, result) } diff --git a/swift/schema.py b/swift/schema.py index a752562f960..3af02367d8a 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -235,8 +235,8 @@ class ParamDecl(VarDecl): """) class Callable(Element): - name: optional[string] | doc("name of this callable") | desc("The name includes any arguments " - "of the callable, for example `myFunction(arg:)`.") + name: optional[string] | doc("name of this callable") | desc("The name includes argument " + "labels of the callable, for example `myFunction(arg:)`.") self_param: optional[ParamDecl] | child params: list[ParamDecl] | child body: optional["BraceStmt"] | child | desc("The body is absent within protocol declarations.") From baef99995d2b7990938fa367220416e1d62102ff Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Thu, 1 Jun 2023 14:08:34 +0200 Subject: [PATCH 259/739] JS: Change note --- .../2023-06-01-restrict-regex-search-function.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 javascript/ql/src/change-notes/2023-06-01-restrict-regex-search-function.md diff --git a/javascript/ql/src/change-notes/2023-06-01-restrict-regex-search-function.md b/javascript/ql/src/change-notes/2023-06-01-restrict-regex-search-function.md new file mode 100644 index 00000000000..a43aebff717 --- /dev/null +++ b/javascript/ql/src/change-notes/2023-06-01-restrict-regex-search-function.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Fixed an issue where calls to a method named `search` would lead to false positive alerts related to regular expressions. + This happened when the call was incorrectly seen as a call to `String.prototype.search`, since this function converts its first argument + to a regular expression. The analysis is now more restrictive about when to treat `search` calls as regular expression sinks. From 58845eca7ca785026f4e4fffd01e213806920c8d Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 1 Jun 2023 08:10:44 -0400 Subject: [PATCH 260/739] Java: update recently added 'open-url' sinks to 'request-forgery' --- java/ql/lib/ext/play.libs.ws.model.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/ext/play.libs.ws.model.yml b/java/ql/lib/ext/play.libs.ws.model.yml index ab905bc463a..3547414a7ad 100644 --- a/java/ql/lib/ext/play.libs.ws.model.yml +++ b/java/ql/lib/ext/play.libs.ws.model.yml @@ -3,5 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["play.libs.ws", "WSClient", True, "url", "", "", "Argument[0]", "open-url", "manual"] - - ["play.libs.ws", "StandaloneWSClient", True, "url", "", "", "Argument[0]", "open-url", "manual"] + - ["play.libs.ws", "WSClient", True, "url", "", "", "Argument[0]", "request-forgery", "manual"] + - ["play.libs.ws", "StandaloneWSClient", True, "url", "", "", "Argument[0]", "request-forgery", "manual"] From 7d943c7621e18abc88dcef65da64af6f5266c4c2 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 1 Jun 2023 13:50:32 +0100 Subject: [PATCH 261/739] Ruby: update test output --- .../dataflow/local/TaintStep.expected | 1 + .../frameworks/sequel/Sequel.expected | 42 +++++++++---------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index 76aeb7fc310..2bfe1e9a9ab 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -2815,6 +2815,7 @@ | file://:0:0:0:0 | parameter position 0 of File.realpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realpath | | file://:0:0:0:0 | parameter position 0 of Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] | | file://:0:0:0:0 | parameter position 0 of PG.new() | file://:0:0:0:0 | [summary] to write: return (return) in PG.new() | +| file://:0:0:0:0 | parameter position 0 of Sequel.connect | file://:0:0:0:0 | [summary] to write: return (return) in Sequel.connect | | file://:0:0:0:0 | parameter position 0 of String.try_convert | file://:0:0:0:0 | [summary] to write: return (return) in String.try_convert | | file://:0:0:0:0 | parameter position 0 of \| | file://:0:0:0:0 | [summary] read: argument position 0.any element in \| | | file://:0:0:0:0 | parameter position 1.. of File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join | diff --git a/ruby/ql/test/library-tests/frameworks/sequel/Sequel.expected b/ruby/ql/test/library-tests/frameworks/sequel/Sequel.expected index b44d06e6c19..dca651d9412 100644 --- a/ruby/ql/test/library-tests/frameworks/sequel/Sequel.expected +++ b/ruby/ql/test/library-tests/frameworks/sequel/Sequel.expected @@ -1,23 +1,23 @@ sequelSqlConstruction -| sequel.rb:63:29:63:49 | call to cast | sequel.rb:63:45:63:48 | name | -| sequel.rb:66:29:66:49 | call to function | sequel.rb:66:45:66:48 | name | +| sequel.rb:62:29:62:49 | call to cast | sequel.rb:62:45:62:48 | name | +| sequel.rb:65:29:65:49 | call to function | sequel.rb:65:45:65:48 | name | sequelSqlExecution -| sequel.rb:10:9:10:60 | ...[...] | sequel.rb:10:14:10:59 | "SELECT * FROM users WHERE use..." | -| sequel.rb:13:9:13:64 | call to run | sequel.rb:13:18:13:63 | "SELECT * FROM users WHERE use..." | -| sequel.rb:16:9:18:11 | call to fetch | sequel.rb:16:20:16:65 | "SELECT * FROM users WHERE use..." | -| sequel.rb:21:9:21:65 | ...[...] | sequel.rb:21:14:21:64 | "SELECT * FROM users WHERE use..." | -| sequel.rb:24:9:24:65 | call to execute | sequel.rb:24:22:24:65 | "SELECT * FROM users WHERE use..." | -| sequel.rb:27:9:27:71 | call to execute_ddl | sequel.rb:27:26:27:71 | "SELECT * FROM users WHERE use..." | -| sequel.rb:30:9:30:71 | call to execute_dui | sequel.rb:30:26:30:71 | "SELECT * FROM users WHERE use..." | -| sequel.rb:33:9:33:74 | call to execute_insert | sequel.rb:33:29:33:74 | "SELECT * FROM users WHERE use..." | -| sequel.rb:36:9:36:62 | ... << ... | sequel.rb:36:17:36:62 | "SELECT * FROM users WHERE use..." | -| sequel.rb:39:9:39:79 | call to fetch_rows | sequel.rb:39:25:39:70 | "SELECT * FROM users WHERE use..." | -| sequel.rb:42:9:42:81 | call to with_sql_all | sequel.rb:42:35:42:80 | "SELECT * FROM users WHERE use..." | -| sequel.rb:45:9:45:84 | call to with_sql_delete | sequel.rb:45:38:45:83 | "SELECT * FROM users WHERE use..." | -| sequel.rb:48:9:48:90 | call to with_sql_each | sequel.rb:48:36:48:81 | "SELECT * FROM users WHERE use..." | -| sequel.rb:51:9:51:83 | call to with_sql_first | sequel.rb:51:37:51:82 | "SELECT * FROM users WHERE use..." | -| sequel.rb:54:9:54:84 | call to with_sql_insert | sequel.rb:54:38:54:83 | "SELECT * FROM users WHERE use..." | -| sequel.rb:57:9:57:90 | call to with_sql_single_value | sequel.rb:57:44:57:89 | "SELECT * FROM users WHERE use..." | -| sequel.rb:60:9:60:84 | call to with_sql_update | sequel.rb:60:38:60:83 | "SELECT * FROM users WHERE use..." | -| sequel.rb:63:9:63:20 | ...[...] | sequel.rb:63:14:63:19 | :table | -| sequel.rb:66:9:66:20 | ...[...] | sequel.rb:66:14:66:19 | :table | +| sequel.rb:9:9:9:60 | ...[...] | sequel.rb:9:14:9:59 | "SELECT * FROM users WHERE use..." | +| sequel.rb:12:9:12:64 | call to run | sequel.rb:12:18:12:63 | "SELECT * FROM users WHERE use..." | +| sequel.rb:15:9:17:11 | call to fetch | sequel.rb:15:20:15:65 | "SELECT * FROM users WHERE use..." | +| sequel.rb:20:9:20:65 | ...[...] | sequel.rb:20:14:20:64 | "SELECT * FROM users WHERE use..." | +| sequel.rb:23:9:23:65 | call to execute | sequel.rb:23:22:23:65 | "SELECT * FROM users WHERE use..." | +| sequel.rb:26:9:26:71 | call to execute_ddl | sequel.rb:26:26:26:71 | "SELECT * FROM users WHERE use..." | +| sequel.rb:29:9:29:71 | call to execute_dui | sequel.rb:29:26:29:71 | "SELECT * FROM users WHERE use..." | +| sequel.rb:32:9:32:74 | call to execute_insert | sequel.rb:32:29:32:74 | "SELECT * FROM users WHERE use..." | +| sequel.rb:35:9:35:62 | ... << ... | sequel.rb:35:17:35:62 | "SELECT * FROM users WHERE use..." | +| sequel.rb:38:9:38:79 | call to fetch_rows | sequel.rb:38:25:38:70 | "SELECT * FROM users WHERE use..." | +| sequel.rb:41:9:41:81 | call to with_sql_all | sequel.rb:41:35:41:80 | "SELECT * FROM users WHERE use..." | +| sequel.rb:44:9:44:84 | call to with_sql_delete | sequel.rb:44:38:44:83 | "SELECT * FROM users WHERE use..." | +| sequel.rb:47:9:47:90 | call to with_sql_each | sequel.rb:47:36:47:81 | "SELECT * FROM users WHERE use..." | +| sequel.rb:50:9:50:83 | call to with_sql_first | sequel.rb:50:37:50:82 | "SELECT * FROM users WHERE use..." | +| sequel.rb:53:9:53:84 | call to with_sql_insert | sequel.rb:53:38:53:83 | "SELECT * FROM users WHERE use..." | +| sequel.rb:56:9:56:90 | call to with_sql_single_value | sequel.rb:56:44:56:89 | "SELECT * FROM users WHERE use..." | +| sequel.rb:59:9:59:84 | call to with_sql_update | sequel.rb:59:38:59:83 | "SELECT * FROM users WHERE use..." | +| sequel.rb:62:9:62:20 | ...[...] | sequel.rb:62:14:62:19 | :table | +| sequel.rb:65:9:65:20 | ...[...] | sequel.rb:65:14:65:19 | :table | From e7e0cf5cb3f21f04e45a4373141e0900ed0993ed Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 16 May 2023 14:45:59 +0100 Subject: [PATCH 262/739] ruby: add Rack::ResponseNode class --- .../codeql/ruby/dataflow/internal/DataFlowPublic.qll | 11 ++++++++--- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index 9d668e0b300..c076d6d6698 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -1279,13 +1279,18 @@ class HashLiteralNode extends LocalSourceNode, ExprNode { * into calls to `Array.[]`, so this includes both desugared calls as well as * explicit calls. */ -class ArrayLiteralNode extends LocalSourceNode, ExprNode { - ArrayLiteralNode() { super.getExprNode() instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode } +class ArrayLiteralNode extends LocalSourceNode, CallNode { + private CfgNodes::ExprNodes::ArrayLiteralCfgNode arrayNode; + + ArrayLiteralNode() { super.getExprNode() = arrayNode } /** * Gets an element of the array. */ - Node getAnElement() { result = this.(CallNode).getPositionalArgument(_) } + Node getAnElement() { result = this.getElement(_) } + + /** Gets the `i`th element of the array. */ + Node getElement(int i) { result = this.getPositionalArgument(i) } } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index 693cd4c197c..b5a6242c35a 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -30,14 +30,14 @@ module Rack { DataFlow::ParameterNode getEnv() { result = call.getParameter(0) } } - private predicate isRackResponse(DataFlow::Node r) { + class ResponseNode extends DataFlow::ArrayLiteralNode { // [status, headers, body] - r.asExpr().(ArrayLiteralCfgNode).getNumberOfArguments() = 3 + ResponseNode() { this.getNumberOfArguments() = 3 } } private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t) { t.start() and - isRackResponse(result) + result instanceof ResponseNode or exists(TypeTracker t2 | result = trackRackResponse(t2).track(t2, t)) } From c87c26687190a898edd0b65f5eb6acde8a2a87ab Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 16 May 2023 14:47:36 +0100 Subject: [PATCH 263/739] ruby: add Rack::ResponseNode#getAStatusCode --- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 16 ++++++++++++++++ .../library-tests/frameworks/rack/Rack.expected | 15 +++++++++++---- .../test/library-tests/frameworks/rack/Rack.ql | 4 ++++ .../test/library-tests/frameworks/rack/rack.rb | 6 +++++- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index b5a6242c35a..ec3673207ac 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -30,9 +30,25 @@ module Rack { DataFlow::ParameterNode getEnv() { result = call.getParameter(0) } } + private DataFlow::LocalSourceNode trackStatusCode(TypeTracker t, int i) { + t.start() and + result.getConstantValue().isInt(i) + or + exists(TypeTracker t2 | result = trackStatusCode(t2, i).track(t2, t)) + } + + private DataFlow::Node trackStatusCode(int i) { + trackStatusCode(TypeTracker::end(), i).flowsTo(result) + } + class ResponseNode extends DataFlow::ArrayLiteralNode { // [status, headers, body] ResponseNode() { this.getNumberOfArguments() = 3 } + + /** + * Gets an HTTP status code that may be returned in this response. + */ + int getAStatusCode() { this.getElement(0) = trackStatusCode(result) } } private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t) { diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index 5613aabd7a4..db76f4545b6 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -1,4 +1,11 @@ -| rack.rb:1:1:5:3 | HelloWorld | rack.rb:2:12:2:14 | env | -| rack.rb:7:1:16:3 | Proxy | rack.rb:12:12:12:18 | the_env | -| rack.rb:18:1:31:3 | Logger | rack.rb:24:12:24:14 | env | -| rack.rb:45:1:61:3 | Baz | rack.rb:46:12:46:14 | env | +rackApps +| rack.rb:1:1:9:3 | HelloWorld | rack.rb:2:12:2:14 | env | +| rack.rb:11:1:20:3 | Proxy | rack.rb:16:12:16:18 | the_env | +| rack.rb:22:1:35:3 | Logger | rack.rb:28:12:28:14 | env | +| rack.rb:49:1:65:3 | Baz | rack.rb:50:12:50:14 | env | +rackResponseStatusCodes +| rack.rb:7:5:7:63 | call to [] | 200 | +| rack.rb:7:5:7:63 | call to [] | 500 | +| rack.rb:39:5:39:13 | call to [] | 1 | +| rack.rb:56:7:56:22 | call to [] | 200 | +| rack.rb:63:5:63:21 | call to [] | 400 | diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 560b81c3839..25c8303853d 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -2,3 +2,7 @@ private import codeql.ruby.frameworks.Rack private import codeql.ruby.DataFlow query predicate rackApps(Rack::AppCandidate c, DataFlow::ParameterNode env) { env = c.getEnv() } + +query predicate rackResponseStatusCodes(Rack::ResponseNode resp, int status) { + status = resp.getAStatusCode() +} diff --git a/ruby/ql/test/library-tests/frameworks/rack/rack.rb b/ruby/ql/test/library-tests/frameworks/rack/rack.rb index 03955455787..c3b7729812b 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/rack.rb +++ b/ruby/ql/test/library-tests/frameworks/rack/rack.rb @@ -1,6 +1,10 @@ class HelloWorld def call(env) - [200, {'Content-Type' => 'text/plain'}, ['Hello World']] + status = 200 + if something_goes_wrong(env) + status = 500 + end + [status, {'Content-Type' => 'text/plain'}, ['Hello World']] end end From f8d2cbbe7932c11bd97c7bbd7fb064427cc8f601 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 16 May 2023 16:40:41 +0100 Subject: [PATCH 264/739] ruby: rack responses implement are HTTP responses --- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 44 +++++++++++++------ .../frameworks/rack/Rack.expected | 3 +- .../library-tests/frameworks/rack/Rack.ql | 6 ++- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index ec3673207ac..503af8e8533 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -2,6 +2,7 @@ * Provides modeling for the Rack library. */ +private import codeql.ruby.Concepts private import codeql.ruby.controlflow.CfgNodes::ExprNodes private import codeql.ruby.DataFlow private import codeql.ruby.typetracking.TypeTracker @@ -17,48 +18,63 @@ module Rack { */ class AppCandidate extends DataFlow::ClassNode { private DataFlow::MethodNode call; + private PotentialResponseNode resp; AppCandidate() { call = this.getInstanceMethod("call") and call.getNumberOfParameters() = 1 and - call.getReturn() = trackRackResponse() + call.getReturn() = trackRackResponse(resp) } /** * Gets the environment of the request, which is the lone parameter to the `call` method. */ DataFlow::ParameterNode getEnv() { result = call.getParameter(0) } + + /** Gets the response returned from the request. */ + PotentialResponseNode getResponse() { result = resp } } - private DataFlow::LocalSourceNode trackStatusCode(TypeTracker t, int i) { + private DataFlow::LocalSourceNode trackInt(TypeTracker t, int i) { t.start() and result.getConstantValue().isInt(i) or - exists(TypeTracker t2 | result = trackStatusCode(t2, i).track(t2, t)) + exists(TypeTracker t2 | result = trackInt(t2, i).track(t2, t)) } - private DataFlow::Node trackStatusCode(int i) { - trackStatusCode(TypeTracker::end(), i).flowsTo(result) - } + private DataFlow::Node trackInt(int i) { trackInt(TypeTracker::end(), i).flowsTo(result) } - class ResponseNode extends DataFlow::ArrayLiteralNode { + private class PotentialResponseNode extends DataFlow::ArrayLiteralNode { // [status, headers, body] - ResponseNode() { this.getNumberOfArguments() = 3 } + PotentialResponseNode() { this.getNumberOfArguments() = 3 } /** * Gets an HTTP status code that may be returned in this response. */ - int getAStatusCode() { this.getElement(0) = trackStatusCode(result) } + int getAStatusCode() { this.getElement(0) = trackInt(result) } } - private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t) { + private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t, PotentialResponseNode n) { t.start() and - result instanceof ResponseNode + result = n or - exists(TypeTracker t2 | result = trackRackResponse(t2).track(t2, t)) + exists(TypeTracker t2 | result = trackRackResponse(t2, n).track(t2, t)) } - private DataFlow::Node trackRackResponse() { - trackRackResponse(TypeTracker::end()).flowsTo(result) + private DataFlow::Node trackRackResponse(PotentialResponseNode n) { + trackRackResponse(TypeTracker::end(), n).flowsTo(result) + } + + /** A `DataFlow::Node` returned from a rack request. */ + class ResponseNode extends PotentialResponseNode, Http::Server::HttpResponse::Range { + ResponseNode() { this = any(AppCandidate app).getResponse() } + + override DataFlow::Node getBody() { result = this.getElement(2) } + + // TODO + override DataFlow::Node getMimetypeOrContentTypeArg() { none() } + + // TODO + override string getMimetypeDefault() { none() } } } diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index db76f4545b6..23fec9a8266 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -6,6 +6,7 @@ rackApps rackResponseStatusCodes | rack.rb:7:5:7:63 | call to [] | 200 | | rack.rb:7:5:7:63 | call to [] | 500 | -| rack.rb:39:5:39:13 | call to [] | 1 | +| rack.rb:18:5:18:27 | call to [] | <unknown> | +| rack.rb:33:5:33:26 | call to [] | <unknown> | | rack.rb:56:7:56:22 | call to [] | 200 | | rack.rb:63:5:63:21 | call to [] | 400 | diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 25c8303853d..6e18162a5e1 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -3,6 +3,8 @@ private import codeql.ruby.DataFlow query predicate rackApps(Rack::AppCandidate c, DataFlow::ParameterNode env) { env = c.getEnv() } -query predicate rackResponseStatusCodes(Rack::ResponseNode resp, int status) { - status = resp.getAStatusCode() +query predicate rackResponseStatusCodes(Rack::ResponseNode resp, string status) { + if exists(resp.getAStatusCode()) + then status = resp.getAStatusCode().toString() + else status = "<unknown>" } From c3ab867595b79920a4ccbcfd183864831c6aa114 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Mon, 22 May 2023 09:32:40 +0100 Subject: [PATCH 265/739] ruby: start restructuring rack --- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 76 +- .../lib/codeql/ruby/frameworks/rack/Rack.qll | 120 ++ .../frameworks/rack/internal/MimeTypes.qll | 1285 +++++++++++++++++ .../library-tests/frameworks/rack/Rack.ql | 7 + .../library-tests/frameworks/rack/rack.rb | 4 +- 5 files changed, 1416 insertions(+), 76 deletions(-) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/rack/internal/MimeTypes.qll diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index 503af8e8533..ba969ae4c45 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -1,80 +1,6 @@ -/** - * Provides modeling for the Rack library. - */ - -private import codeql.ruby.Concepts -private import codeql.ruby.controlflow.CfgNodes::ExprNodes -private import codeql.ruby.DataFlow -private import codeql.ruby.typetracking.TypeTracker - /** * Provides modeling for the Rack library. */ module Rack { - /** - * A class that may be a rack application. - * This is a class that has a `call` method that takes a single argument - * (traditionally called `env`) and returns a rack-compatible response. - */ - class AppCandidate extends DataFlow::ClassNode { - private DataFlow::MethodNode call; - private PotentialResponseNode resp; - - AppCandidate() { - call = this.getInstanceMethod("call") and - call.getNumberOfParameters() = 1 and - call.getReturn() = trackRackResponse(resp) - } - - /** - * Gets the environment of the request, which is the lone parameter to the `call` method. - */ - DataFlow::ParameterNode getEnv() { result = call.getParameter(0) } - - /** Gets the response returned from the request. */ - PotentialResponseNode getResponse() { result = resp } - } - - private DataFlow::LocalSourceNode trackInt(TypeTracker t, int i) { - t.start() and - result.getConstantValue().isInt(i) - or - exists(TypeTracker t2 | result = trackInt(t2, i).track(t2, t)) - } - - private DataFlow::Node trackInt(int i) { trackInt(TypeTracker::end(), i).flowsTo(result) } - - private class PotentialResponseNode extends DataFlow::ArrayLiteralNode { - // [status, headers, body] - PotentialResponseNode() { this.getNumberOfArguments() = 3 } - - /** - * Gets an HTTP status code that may be returned in this response. - */ - int getAStatusCode() { this.getElement(0) = trackInt(result) } - } - - private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t, PotentialResponseNode n) { - t.start() and - result = n - or - exists(TypeTracker t2 | result = trackRackResponse(t2, n).track(t2, t)) - } - - private DataFlow::Node trackRackResponse(PotentialResponseNode n) { - trackRackResponse(TypeTracker::end(), n).flowsTo(result) - } - - /** A `DataFlow::Node` returned from a rack request. */ - class ResponseNode extends PotentialResponseNode, Http::Server::HttpResponse::Range { - ResponseNode() { this = any(AppCandidate app).getResponse() } - - override DataFlow::Node getBody() { result = this.getElement(2) } - - // TODO - override DataFlow::Node getMimetypeOrContentTypeArg() { none() } - - // TODO - override string getMimetypeDefault() { none() } - } + import rack.Rack } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll new file mode 100644 index 00000000000..b570f276c51 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll @@ -0,0 +1,120 @@ +/** + * Provides modeling for the Rack library. + */ + +private import codeql.ruby.AST +private import codeql.ruby.ApiGraphs +private import codeql.ruby.Concepts +private import codeql.ruby.controlflow.CfgNodes::ExprNodes +private import codeql.ruby.DataFlow +private import codeql.ruby.typetracking.TypeTracker +private import internal.MimeTypes + +/** + * A class that may be a rack application. + * This is a class that has a `call` method that takes a single argument + * (traditionally called `env`) and returns a rack-compatible response. + */ +class AppCandidate extends DataFlow::ClassNode { + private DataFlow::MethodNode call; + private PotentialResponseNode resp; + + AppCandidate() { + call = this.getInstanceMethod("call") and + call.getNumberOfParameters() = 1 and + call.getReturn() = trackRackResponse(resp) + } + + /** + * Gets the environment of the request, which is the lone parameter to the `call` method. + */ + DataFlow::ParameterNode getEnv() { result = call.getParameter(0) } + + /** Gets the response returned from the request. */ + PotentialResponseNode getResponse() { result = resp } +} + +private DataFlow::LocalSourceNode trackInt(TypeTracker t, int i) { + t.start() and + result.getConstantValue().isInt(i) + or + exists(TypeTracker t2 | result = trackInt(t2, i).track(t2, t)) +} + +private DataFlow::Node trackInt(int i) { trackInt(TypeTracker::end(), i).flowsTo(result) } + +private class PotentialResponseNode extends DataFlow::ArrayLiteralNode { + // [status, headers, body] + PotentialResponseNode() { this.getNumberOfArguments() = 3 } + + /** + * Gets an HTTP status code that may be returned in this response. + */ + int getAStatusCode() { this.getElement(0) = trackInt(result) } + + /** Gets the headers returned with this response. */ + DataFlow::Node getHeaders() { result = this.getElement(1) } + + /** Gets the body of this response. */ + DataFlow::Node getBody() { result = this.getElement(2) } +} + +private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t, PotentialResponseNode n) { + t.start() and + result = n + or + exists(TypeTracker t2 | result = trackRackResponse(t2, n).track(t2, t)) +} + +private DataFlow::Node trackRackResponse(PotentialResponseNode n) { + trackRackResponse(TypeTracker::end(), n).flowsTo(result) +} + +class MimetypeCall extends DataFlow::CallNode { + MimetypeCall() { + this = API::getTopLevelMember("Rack").getMember("Mime").getAMethodCall("mime_type") + } + + private string getExtension() { + result = this.getArgument(0).getConstantValue().getStringlikeValue() + } + + string getMimeType() { mimeTypeMatches(this.getExtension(), result) } +} + +/** A `DataFlow::Node` returned from a rack request. */ +class ResponseNode extends PotentialResponseNode, Http::Server::HttpResponse::Range { + ResponseNode() { this = any(AppCandidate app).getResponse() } + + override DataFlow::Node getBody() { result = this.getElement(2) } + + override DataFlow::Node getMimetypeOrContentTypeArg() { + exists(DataFlow::Node headers | headers = this.getHeaders() | + // set via `headers.content_type=` + exists( + DataFlow::CallNode contentTypeAssignment, Assignment assignment, + DataFlow::PostUpdateNode postUpdateHeaders + | + contentTypeAssignment.getMethodName() = "content_type=" and + assignment = + contentTypeAssignment.getArgument(0).(DataFlow::OperationNode).asOperationAstNode() and + postUpdateHeaders.(DataFlow::LocalSourceNode).flowsTo(headers) and + postUpdateHeaders.getPreUpdateNode() = contentTypeAssignment.getReceiver() + | + result.asExpr().getExpr() = assignment.getRightOperand() + ) + or + // set within a hash + exists(DataFlow::HashLiteralNode headersHash | headersHash.flowsTo(headers) | + result = + headersHash + .getElementFromKey(any(ConstantValue v | + v.getStringlikeValue().toLowerCase() = "content-type" + )) + ) + ) + } + + // TODO + override string getMimetypeDefault() { none() } +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/MimeTypes.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/MimeTypes.qll new file mode 100644 index 00000000000..ed5bad4b8a6 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/MimeTypes.qll @@ -0,0 +1,1285 @@ +predicate mimeTypeMatches(string ext, string mimeType) { + ext = ".123" and mimeType = "application/vnd.lotus-1-2-3" + or + ext = ".3dml" and mimeType = "text/vnd.in3d.3dml" + or + ext = ".3g2" and mimeType = "video/3gpp2" + or + ext = ".3gp" and mimeType = "video/3gpp" + or + ext = ".a" and mimeType = "application/octet-stream" + or + ext = ".acc" and mimeType = "application/vnd.americandynamics.acc" + or + ext = ".ace" and mimeType = "application/x-ace-compressed" + or + ext = ".acu" and mimeType = "application/vnd.acucobol" + or + ext = ".aep" and mimeType = "application/vnd.audiograph" + or + ext = ".afp" and mimeType = "application/vnd.ibm.modcap" + or + ext = ".ai" and mimeType = "application/postscript" + or + ext = ".aif" and mimeType = "audio/x-aiff" + or + ext = ".aiff" and mimeType = "audio/x-aiff" + or + ext = ".ami" and mimeType = "application/vnd.amiga.ami" + or + ext = ".apng" and mimeType = "image/apng" + or + ext = ".appcache" and mimeType = "text/cache-manifest" + or + ext = ".apr" and mimeType = "application/vnd.lotus-approach" + or + ext = ".asc" and mimeType = "application/pgp-signature" + or + ext = ".asf" and mimeType = "video/x-ms-asf" + or + ext = ".asm" and mimeType = "text/x-asm" + or + ext = ".aso" and mimeType = "application/vnd.accpac.simply.aso" + or + ext = ".asx" and mimeType = "video/x-ms-asf" + or + ext = ".atc" and mimeType = "application/vnd.acucorp" + or + ext = ".atom" and mimeType = "application/atom+xml" + or + ext = ".atomcat" and mimeType = "application/atomcat+xml" + or + ext = ".atomsvc" and mimeType = "application/atomsvc+xml" + or + ext = ".atx" and mimeType = "application/vnd.antix.game-component" + or + ext = ".au" and mimeType = "audio/basic" + or + ext = ".avi" and mimeType = "video/x-msvideo" + or + ext = ".avif" and mimeType = "image/avif" + or + ext = ".bat" and mimeType = "application/x-msdownload" + or + ext = ".bcpio" and mimeType = "application/x-bcpio" + or + ext = ".bdm" and mimeType = "application/vnd.syncml.dm+wbxml" + or + ext = ".bh2" and mimeType = "application/vnd.fujitsu.oasysprs" + or + ext = ".bin" and mimeType = "application/octet-stream" + or + ext = ".bmi" and mimeType = "application/vnd.bmi" + or + ext = ".bmp" and mimeType = "image/bmp" + or + ext = ".box" and mimeType = "application/vnd.previewsystems.box" + or + ext = ".btif" and mimeType = "image/prs.btif" + or + ext = ".bz" and mimeType = "application/x-bzip" + or + ext = ".bz2" and mimeType = "application/x-bzip2" + or + ext = ".c" and mimeType = "text/x-c" + or + ext = ".c4g" and mimeType = "application/vnd.clonk.c4group" + or + ext = ".cab" and mimeType = "application/vnd.ms-cab-compressed" + or + ext = ".cc" and mimeType = "text/x-c" + or + ext = ".ccxml" and mimeType = "application/ccxml+xml" + or + ext = ".cdbcmsg" and mimeType = "application/vnd.contact.cmsg" + or + ext = ".cdkey" and mimeType = "application/vnd.mediastation.cdkey" + or + ext = ".cdx" and mimeType = "chemical/x-cdx" + or + ext = ".cdxml" and mimeType = "application/vnd.chemdraw+xml" + or + ext = ".cdy" and mimeType = "application/vnd.cinderella" + or + ext = ".cer" and mimeType = "application/pkix-cert" + or + ext = ".cgm" and mimeType = "image/cgm" + or + ext = ".chat" and mimeType = "application/x-chat" + or + ext = ".chm" and mimeType = "application/vnd.ms-htmlhelp" + or + ext = ".chrt" and mimeType = "application/vnd.kde.kchart" + or + ext = ".cif" and mimeType = "chemical/x-cif" + or + ext = ".cii" and mimeType = "application/vnd.anser-web-certificate-issue-initiation" + or + ext = ".cil" and mimeType = "application/vnd.ms-artgalry" + or + ext = ".cla" and mimeType = "application/vnd.claymore" + or + ext = ".class" and mimeType = "application/octet-stream" + or + ext = ".clkk" and mimeType = "application/vnd.crick.clicker.keyboard" + or + ext = ".clkp" and mimeType = "application/vnd.crick.clicker.palette" + or + ext = ".clkt" and mimeType = "application/vnd.crick.clicker.template" + or + ext = ".clkw" and mimeType = "application/vnd.crick.clicker.wordbank" + or + ext = ".clkx" and mimeType = "application/vnd.crick.clicker" + or + ext = ".clp" and mimeType = "application/x-msclip" + or + ext = ".cmc" and mimeType = "application/vnd.cosmocaller" + or + ext = ".cmdf" and mimeType = "chemical/x-cmdf" + or + ext = ".cml" and mimeType = "chemical/x-cml" + or + ext = ".cmp" and mimeType = "application/vnd.yellowriver-custom-menu" + or + ext = ".cmx" and mimeType = "image/x-cmx" + or + ext = ".com" and mimeType = "application/x-msdownload" + or + ext = ".conf" and mimeType = "text/plain" + or + ext = ".cpio" and mimeType = "application/x-cpio" + or + ext = ".cpp" and mimeType = "text/x-c" + or + ext = ".cpt" and mimeType = "application/mac-compactpro" + or + ext = ".crd" and mimeType = "application/x-mscardfile" + or + ext = ".crl" and mimeType = "application/pkix-crl" + or + ext = ".crt" and mimeType = "application/x-x509-ca-cert" + or + ext = ".csh" and mimeType = "application/x-csh" + or + ext = ".csml" and mimeType = "chemical/x-csml" + or + ext = ".csp" and mimeType = "application/vnd.commonspace" + or + ext = ".css" and mimeType = "text/css" + or + ext = ".csv" and mimeType = "text/csv" + or + ext = ".curl" and mimeType = "application/vnd.curl" + or + ext = ".cww" and mimeType = "application/prs.cww" + or + ext = ".cxx" and mimeType = "text/x-c" + or + ext = ".daf" and mimeType = "application/vnd.mobius.daf" + or + ext = ".davmount" and mimeType = "application/davmount+xml" + or + ext = ".dcr" and mimeType = "application/x-director" + or + ext = ".dd2" and mimeType = "application/vnd.oma.dd2+xml" + or + ext = ".ddd" and mimeType = "application/vnd.fujixerox.ddd" + or + ext = ".deb" and mimeType = "application/x-debian-package" + or + ext = ".der" and mimeType = "application/x-x509-ca-cert" + or + ext = ".dfac" and mimeType = "application/vnd.dreamfactory" + or + ext = ".diff" and mimeType = "text/x-diff" + or + ext = ".dis" and mimeType = "application/vnd.mobius.dis" + or + ext = ".djv" and mimeType = "image/vnd.djvu" + or + ext = ".djvu" and mimeType = "image/vnd.djvu" + or + ext = ".dll" and mimeType = "application/x-msdownload" + or + ext = ".dmg" and mimeType = "application/octet-stream" + or + ext = ".dna" and mimeType = "application/vnd.dna" + or + ext = ".doc" and mimeType = "application/msword" + or + ext = ".docm" and mimeType = "application/vnd.ms-word.document.macroEnabled.12" + or + ext = ".docx" and + mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + or + ext = ".dot" and mimeType = "application/msword" + or + ext = ".dotm" and mimeType = "application/vnd.ms-word.template.macroEnabled.12" + or + ext = ".dotx" and + mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template" + or + ext = ".dp" and mimeType = "application/vnd.osgi.dp" + or + ext = ".dpg" and mimeType = "application/vnd.dpgraph" + or + ext = ".dsc" and mimeType = "text/prs.lines.tag" + or + ext = ".dtd" and mimeType = "application/xml-dtd" + or + ext = ".dts" and mimeType = "audio/vnd.dts" + or + ext = ".dtshd" and mimeType = "audio/vnd.dts.hd" + or + ext = ".dv" and mimeType = "video/x-dv" + or + ext = ".dvi" and mimeType = "application/x-dvi" + or + ext = ".dwf" and mimeType = "model/vnd.dwf" + or + ext = ".dwg" and mimeType = "image/vnd.dwg" + or + ext = ".dxf" and mimeType = "image/vnd.dxf" + or + ext = ".dxp" and mimeType = "application/vnd.spotfire.dxp" + or + ext = ".ear" and mimeType = "application/java-archive" + or + ext = ".ecelp4800" and mimeType = "audio/vnd.nuera.ecelp4800" + or + ext = ".ecelp7470" and mimeType = "audio/vnd.nuera.ecelp7470" + or + ext = ".ecelp9600" and mimeType = "audio/vnd.nuera.ecelp9600" + or + ext = ".ecma" and mimeType = "application/ecmascript" + or + ext = ".edm" and mimeType = "application/vnd.novadigm.edm" + or + ext = ".edx" and mimeType = "application/vnd.novadigm.edx" + or + ext = ".efif" and mimeType = "application/vnd.picsel" + or + ext = ".ei6" and mimeType = "application/vnd.pg.osasli" + or + ext = ".eml" and mimeType = "message/rfc822" + or + ext = ".eol" and mimeType = "audio/vnd.digital-winds" + or + ext = ".eot" and mimeType = "application/vnd.ms-fontobject" + or + ext = ".eps" and mimeType = "application/postscript" + or + ext = ".es3" and mimeType = "application/vnd.eszigno3+xml" + or + ext = ".esf" and mimeType = "application/vnd.epson.esf" + or + ext = ".etx" and mimeType = "text/x-setext" + or + ext = ".exe" and mimeType = "application/x-msdownload" + or + ext = ".ext" and mimeType = "application/vnd.novadigm.ext" + or + ext = ".ez" and mimeType = "application/andrew-inset" + or + ext = ".ez2" and mimeType = "application/vnd.ezpix-album" + or + ext = ".ez3" and mimeType = "application/vnd.ezpix-package" + or + ext = ".f" and mimeType = "text/x-fortran" + or + ext = ".f77" and mimeType = "text/x-fortran" + or + ext = ".f90" and mimeType = "text/x-fortran" + or + ext = ".fbs" and mimeType = "image/vnd.fastbidsheet" + or + ext = ".fdf" and mimeType = "application/vnd.fdf" + or + ext = ".fe_launch" and mimeType = "application/vnd.denovo.fcselayout-link" + or + ext = ".fg5" and mimeType = "application/vnd.fujitsu.oasysgp" + or + ext = ".fli" and mimeType = "video/x-fli" + or + ext = ".flif" and mimeType = "image/flif" + or + ext = ".flo" and mimeType = "application/vnd.micrografx.flo" + or + ext = ".flv" and mimeType = "video/x-flv" + or + ext = ".flw" and mimeType = "application/vnd.kde.kivio" + or + ext = ".flx" and mimeType = "text/vnd.fmi.flexstor" + or + ext = ".fly" and mimeType = "text/vnd.fly" + or + ext = ".fm" and mimeType = "application/vnd.framemaker" + or + ext = ".fnc" and mimeType = "application/vnd.frogans.fnc" + or + ext = ".for" and mimeType = "text/x-fortran" + or + ext = ".fpx" and mimeType = "image/vnd.fpx" + or + ext = ".fsc" and mimeType = "application/vnd.fsc.weblaunch" + or + ext = ".fst" and mimeType = "image/vnd.fst" + or + ext = ".ftc" and mimeType = "application/vnd.fluxtime.clip" + or + ext = ".fti" and mimeType = "application/vnd.anser-web-funds-transfer-initiation" + or + ext = ".fvt" and mimeType = "video/vnd.fvt" + or + ext = ".fzs" and mimeType = "application/vnd.fuzzysheet" + or + ext = ".g3" and mimeType = "image/g3fax" + or + ext = ".gac" and mimeType = "application/vnd.groove-account" + or + ext = ".gdl" and mimeType = "model/vnd.gdl" + or + ext = ".gem" and mimeType = "application/octet-stream" + or + ext = ".gemspec" and mimeType = "text/x-script.ruby" + or + ext = ".ghf" and mimeType = "application/vnd.groove-help" + or + ext = ".gif" and mimeType = "image/gif" + or + ext = ".gim" and mimeType = "application/vnd.groove-identity-message" + or + ext = ".gmx" and mimeType = "application/vnd.gmx" + or + ext = ".gph" and mimeType = "application/vnd.flographit" + or + ext = ".gqf" and mimeType = "application/vnd.grafeq" + or + ext = ".gram" and mimeType = "application/srgs" + or + ext = ".grv" and mimeType = "application/vnd.groove-injector" + or + ext = ".grxml" and mimeType = "application/srgs+xml" + or + ext = ".gtar" and mimeType = "application/x-gtar" + or + ext = ".gtm" and mimeType = "application/vnd.groove-tool-message" + or + ext = ".gtw" and mimeType = "model/vnd.gtw" + or + ext = ".gv" and mimeType = "text/vnd.graphviz" + or + ext = ".gz" and mimeType = "application/x-gzip" + or + ext = ".h" and mimeType = "text/x-c" + or + ext = ".h261" and mimeType = "video/h261" + or + ext = ".h263" and mimeType = "video/h263" + or + ext = ".h264" and mimeType = "video/h264" + or + ext = ".hbci" and mimeType = "application/vnd.hbci" + or + ext = ".hdf" and mimeType = "application/x-hdf" + or + ext = ".heic" and mimeType = "image/heic" + or + ext = ".heics" and mimeType = "image/heic-sequence" + or + ext = ".heif" and mimeType = "image/heif" + or + ext = ".heifs" and mimeType = "image/heif-sequence" + or + ext = ".hh" and mimeType = "text/x-c" + or + ext = ".hlp" and mimeType = "application/winhlp" + or + ext = ".hpgl" and mimeType = "application/vnd.hp-hpgl" + or + ext = ".hpid" and mimeType = "application/vnd.hp-hpid" + or + ext = ".hps" and mimeType = "application/vnd.hp-hps" + or + ext = ".hqx" and mimeType = "application/mac-binhex40" + or + ext = ".htc" and mimeType = "text/x-component" + or + ext = ".htke" and mimeType = "application/vnd.kenameaapp" + or + ext = ".htm" and mimeType = "text/html" + or + ext = ".html" and mimeType = "text/html" + or + ext = ".hvd" and mimeType = "application/vnd.yamaha.hv-dic" + or + ext = ".hvp" and mimeType = "application/vnd.yamaha.hv-voice" + or + ext = ".hvs" and mimeType = "application/vnd.yamaha.hv-script" + or + ext = ".icc" and mimeType = "application/vnd.iccprofile" + or + ext = ".ice" and mimeType = "x-conference/x-cooltalk" + or + ext = ".ico" and mimeType = "image/vnd.microsoft.icon" + or + ext = ".ics" and mimeType = "text/calendar" + or + ext = ".ief" and mimeType = "image/ief" + or + ext = ".ifb" and mimeType = "text/calendar" + or + ext = ".ifm" and mimeType = "application/vnd.shana.informed.formdata" + or + ext = ".igl" and mimeType = "application/vnd.igloader" + or + ext = ".igs" and mimeType = "model/iges" + or + ext = ".igx" and mimeType = "application/vnd.micrografx.igx" + or + ext = ".iif" and mimeType = "application/vnd.shana.informed.interchange" + or + ext = ".imp" and mimeType = "application/vnd.accpac.simply.imp" + or + ext = ".ims" and mimeType = "application/vnd.ms-ims" + or + ext = ".ipk" and mimeType = "application/vnd.shana.informed.package" + or + ext = ".irm" and mimeType = "application/vnd.ibm.rights-management" + or + ext = ".irp" and mimeType = "application/vnd.irepository.package+xml" + or + ext = ".iso" and mimeType = "application/octet-stream" + or + ext = ".itp" and mimeType = "application/vnd.shana.informed.formtemplate" + or + ext = ".ivp" and mimeType = "application/vnd.immervision-ivp" + or + ext = ".ivu" and mimeType = "application/vnd.immervision-ivu" + or + ext = ".jad" and mimeType = "text/vnd.sun.j2me.app-descriptor" + or + ext = ".jam" and mimeType = "application/vnd.jam" + or + ext = ".jar" and mimeType = "application/java-archive" + or + ext = ".java" and mimeType = "text/x-java-source" + or + ext = ".jisp" and mimeType = "application/vnd.jisp" + or + ext = ".jlt" and mimeType = "application/vnd.hp-jlyt" + or + ext = ".jnlp" and mimeType = "application/x-java-jnlp-file" + or + ext = ".joda" and mimeType = "application/vnd.joost.joda-archive" + or + ext = ".jp2" and mimeType = "image/jp2" + or + ext = ".jpeg" and mimeType = "image/jpeg" + or + ext = ".jpg" and mimeType = "image/jpeg" + or + ext = ".jpgv" and mimeType = "video/jpeg" + or + ext = ".jpm" and mimeType = "video/jpm" + or + ext = ".js" and mimeType = "application/javascript" + or + ext = ".json" and mimeType = "application/json" + or + ext = ".karbon" and mimeType = "application/vnd.kde.karbon" + or + ext = ".kfo" and mimeType = "application/vnd.kde.kformula" + or + ext = ".kia" and mimeType = "application/vnd.kidspiration" + or + ext = ".kml" and mimeType = "application/vnd.google-earth.kml+xml" + or + ext = ".kmz" and mimeType = "application/vnd.google-earth.kmz" + or + ext = ".kne" and mimeType = "application/vnd.kinar" + or + ext = ".kon" and mimeType = "application/vnd.kde.kontour" + or + ext = ".kpr" and mimeType = "application/vnd.kde.kpresenter" + or + ext = ".ksp" and mimeType = "application/vnd.kde.kspread" + or + ext = ".ktz" and mimeType = "application/vnd.kahootz" + or + ext = ".kwd" and mimeType = "application/vnd.kde.kword" + or + ext = ".latex" and mimeType = "application/x-latex" + or + ext = ".lbd" and mimeType = "application/vnd.llamagraphics.life-balance.desktop" + or + ext = ".lbe" and mimeType = "application/vnd.llamagraphics.life-balance.exchange+xml" + or + ext = ".les" and mimeType = "application/vnd.hhe.lesson-player" + or + ext = ".link66" and mimeType = "application/vnd.route66.link66+xml" + or + ext = ".log" and mimeType = "text/plain" + or + ext = ".lostxml" and mimeType = "application/lost+xml" + or + ext = ".lrm" and mimeType = "application/vnd.ms-lrm" + or + ext = ".ltf" and mimeType = "application/vnd.frogans.ltf" + or + ext = ".lvp" and mimeType = "audio/vnd.lucent.voice" + or + ext = ".lwp" and mimeType = "application/vnd.lotus-wordpro" + or + ext = ".m3u" and mimeType = "audio/x-mpegurl" + or + ext = ".m3u8" and mimeType = "application/x-mpegurl" + or + ext = ".m4a" and mimeType = "audio/mp4a-latm" + or + ext = ".m4v" and mimeType = "video/mp4" + or + ext = ".ma" and mimeType = "application/mathematica" + or + ext = ".mag" and mimeType = "application/vnd.ecowin.chart" + or + ext = ".man" and mimeType = "text/troff" + or + ext = ".manifest" and mimeType = "text/cache-manifest" + or + ext = ".mathml" and mimeType = "application/mathml+xml" + or + ext = ".mbk" and mimeType = "application/vnd.mobius.mbk" + or + ext = ".mbox" and mimeType = "application/mbox" + or + ext = ".mc1" and mimeType = "application/vnd.medcalcdata" + or + ext = ".mcd" and mimeType = "application/vnd.mcd" + or + ext = ".mdb" and mimeType = "application/x-msaccess" + or + ext = ".mdi" and mimeType = "image/vnd.ms-modi" + or + ext = ".mdoc" and mimeType = "text/troff" + or + ext = ".me" and mimeType = "text/troff" + or + ext = ".mfm" and mimeType = "application/vnd.mfmp" + or + ext = ".mgz" and mimeType = "application/vnd.proteus.magazine" + or + ext = ".mid" and mimeType = "audio/midi" + or + ext = ".midi" and mimeType = "audio/midi" + or + ext = ".mif" and mimeType = "application/vnd.mif" + or + ext = ".mime" and mimeType = "message/rfc822" + or + ext = ".mj2" and mimeType = "video/mj2" + or + ext = ".mlp" and mimeType = "application/vnd.dolby.mlp" + or + ext = ".mmd" and mimeType = "application/vnd.chipnuts.karaoke-mmd" + or + ext = ".mmf" and mimeType = "application/vnd.smaf" + or + ext = ".mml" and mimeType = "application/mathml+xml" + or + ext = ".mmr" and mimeType = "image/vnd.fujixerox.edmics-mmr" + or + ext = ".mng" and mimeType = "video/x-mng" + or + ext = ".mny" and mimeType = "application/x-msmoney" + or + ext = ".mov" and mimeType = "video/quicktime" + or + ext = ".movie" and mimeType = "video/x-sgi-movie" + or + ext = ".mp3" and mimeType = "audio/mpeg" + or + ext = ".mp4" and mimeType = "video/mp4" + or + ext = ".mp4a" and mimeType = "audio/mp4" + or + ext = ".mp4s" and mimeType = "application/mp4" + or + ext = ".mp4v" and mimeType = "video/mp4" + or + ext = ".mpc" and mimeType = "application/vnd.mophun.certificate" + or + ext = ".mpd" and mimeType = "application/dash+xml" + or + ext = ".mpeg" and mimeType = "video/mpeg" + or + ext = ".mpg" and mimeType = "video/mpeg" + or + ext = ".mpga" and mimeType = "audio/mpeg" + or + ext = ".mpkg" and mimeType = "application/vnd.apple.installer+xml" + or + ext = ".mpm" and mimeType = "application/vnd.blueice.multipass" + or + ext = ".mpn" and mimeType = "application/vnd.mophun.application" + or + ext = ".mpp" and mimeType = "application/vnd.ms-project" + or + ext = ".mpy" and mimeType = "application/vnd.ibm.minipay" + or + ext = ".mqy" and mimeType = "application/vnd.mobius.mqy" + or + ext = ".mrc" and mimeType = "application/marc" + or + ext = ".ms" and mimeType = "text/troff" + or + ext = ".mscml" and mimeType = "application/mediaservercontrol+xml" + or + ext = ".mseq" and mimeType = "application/vnd.mseq" + or + ext = ".msf" and mimeType = "application/vnd.epson.msf" + or + ext = ".msh" and mimeType = "model/mesh" + or + ext = ".msi" and mimeType = "application/x-msdownload" + or + ext = ".msl" and mimeType = "application/vnd.mobius.msl" + or + ext = ".msty" and mimeType = "application/vnd.muvee.style" + or + ext = ".mts" and mimeType = "model/vnd.mts" + or + ext = ".mus" and mimeType = "application/vnd.musician" + or + ext = ".mvb" and mimeType = "application/x-msmediaview" + or + ext = ".mwf" and mimeType = "application/vnd.mfer" + or + ext = ".mxf" and mimeType = "application/mxf" + or + ext = ".mxl" and mimeType = "application/vnd.recordare.musicxml" + or + ext = ".mxml" and mimeType = "application/xv+xml" + or + ext = ".mxs" and mimeType = "application/vnd.triscape.mxs" + or + ext = ".mxu" and mimeType = "video/vnd.mpegurl" + or + ext = ".n" and mimeType = "application/vnd.nokia.n-gage.symbian.install" + or + ext = ".nc" and mimeType = "application/x-netcdf" + or + ext = ".ngdat" and mimeType = "application/vnd.nokia.n-gage.data" + or + ext = ".nlu" and mimeType = "application/vnd.neurolanguage.nlu" + or + ext = ".nml" and mimeType = "application/vnd.enliven" + or + ext = ".nnd" and mimeType = "application/vnd.noblenet-directory" + or + ext = ".nns" and mimeType = "application/vnd.noblenet-sealer" + or + ext = ".nnw" and mimeType = "application/vnd.noblenet-web" + or + ext = ".npx" and mimeType = "image/vnd.net-fpx" + or + ext = ".nsf" and mimeType = "application/vnd.lotus-notes" + or + ext = ".oa2" and mimeType = "application/vnd.fujitsu.oasys2" + or + ext = ".oa3" and mimeType = "application/vnd.fujitsu.oasys3" + or + ext = ".oas" and mimeType = "application/vnd.fujitsu.oasys" + or + ext = ".obd" and mimeType = "application/x-msbinder" + or + ext = ".oda" and mimeType = "application/oda" + or + ext = ".odc" and mimeType = "application/vnd.oasis.opendocument.chart" + or + ext = ".odf" and mimeType = "application/vnd.oasis.opendocument.formula" + or + ext = ".odg" and mimeType = "application/vnd.oasis.opendocument.graphics" + or + ext = ".odi" and mimeType = "application/vnd.oasis.opendocument.image" + or + ext = ".odp" and mimeType = "application/vnd.oasis.opendocument.presentation" + or + ext = ".ods" and mimeType = "application/vnd.oasis.opendocument.spreadsheet" + or + ext = ".odt" and mimeType = "application/vnd.oasis.opendocument.text" + or + ext = ".oga" and mimeType = "audio/ogg" + or + ext = ".ogg" and mimeType = "application/ogg" + or + ext = ".ogv" and mimeType = "video/ogg" + or + ext = ".ogx" and mimeType = "application/ogg" + or + ext = ".org" and mimeType = "application/vnd.lotus-organizer" + or + ext = ".otc" and mimeType = "application/vnd.oasis.opendocument.chart-template" + or + ext = ".otf" and mimeType = "application/vnd.oasis.opendocument.formula-template" + or + ext = ".otg" and mimeType = "application/vnd.oasis.opendocument.graphics-template" + or + ext = ".oth" and mimeType = "application/vnd.oasis.opendocument.text-web" + or + ext = ".oti" and mimeType = "application/vnd.oasis.opendocument.image-template" + or + ext = ".otm" and mimeType = "application/vnd.oasis.opendocument.text-master" + or + ext = ".ots" and mimeType = "application/vnd.oasis.opendocument.spreadsheet-template" + or + ext = ".ott" and mimeType = "application/vnd.oasis.opendocument.text-template" + or + ext = ".oxt" and mimeType = "application/vnd.openofficeorg.extension" + or + ext = ".p" and mimeType = "text/x-pascal" + or + ext = ".p10" and mimeType = "application/pkcs10" + or + ext = ".p12" and mimeType = "application/x-pkcs12" + or + ext = ".p7b" and mimeType = "application/x-pkcs7-certificates" + or + ext = ".p7m" and mimeType = "application/pkcs7-mime" + or + ext = ".p7r" and mimeType = "application/x-pkcs7-certreqresp" + or + ext = ".p7s" and mimeType = "application/pkcs7-signature" + or + ext = ".pas" and mimeType = "text/x-pascal" + or + ext = ".pbd" and mimeType = "application/vnd.powerbuilder6" + or + ext = ".pbm" and mimeType = "image/x-portable-bitmap" + or + ext = ".pcl" and mimeType = "application/vnd.hp-pcl" + or + ext = ".pclxl" and mimeType = "application/vnd.hp-pclxl" + or + ext = ".pcx" and mimeType = "image/x-pcx" + or + ext = ".pdb" and mimeType = "chemical/x-pdb" + or + ext = ".pdf" and mimeType = "application/pdf" + or + ext = ".pem" and mimeType = "application/x-x509-ca-cert" + or + ext = ".pfr" and mimeType = "application/font-tdpfr" + or + ext = ".pgm" and mimeType = "image/x-portable-graymap" + or + ext = ".pgn" and mimeType = "application/x-chess-pgn" + or + ext = ".pgp" and mimeType = "application/pgp-encrypted" + or + ext = ".pic" and mimeType = "image/x-pict" + or + ext = ".pict" and mimeType = "image/pict" + or + ext = ".pkg" and mimeType = "application/octet-stream" + or + ext = ".pki" and mimeType = "application/pkixcmp" + or + ext = ".pkipath" and mimeType = "application/pkix-pkipath" + or + ext = ".pl" and mimeType = "text/x-script.perl" + or + ext = ".plb" and mimeType = "application/vnd.3gpp.pic-bw-large" + or + ext = ".plc" and mimeType = "application/vnd.mobius.plc" + or + ext = ".plf" and mimeType = "application/vnd.pocketlearn" + or + ext = ".pls" and mimeType = "application/pls+xml" + or + ext = ".pm" and mimeType = "text/x-script.perl-module" + or + ext = ".pml" and mimeType = "application/vnd.ctc-posml" + or + ext = ".png" and mimeType = "image/png" + or + ext = ".pnm" and mimeType = "image/x-portable-anymap" + or + ext = ".pntg" and mimeType = "image/x-macpaint" + or + ext = ".portpkg" and mimeType = "application/vnd.macports.portpkg" + or + ext = ".pot" and mimeType = "application/vnd.ms-powerpoint" + or + ext = ".potm" and mimeType = "application/vnd.ms-powerpoint.template.macroEnabled.12" + or + ext = ".potx" and + mimeType = "application/vnd.openxmlformats-officedocument.presentationml.template" + or + ext = ".ppa" and mimeType = "application/vnd.ms-powerpoint" + or + ext = ".ppam" and mimeType = "application/vnd.ms-powerpoint.addin.macroEnabled.12" + or + ext = ".ppd" and mimeType = "application/vnd.cups-ppd" + or + ext = ".ppm" and mimeType = "image/x-portable-pixmap" + or + ext = ".pps" and mimeType = "application/vnd.ms-powerpoint" + or + ext = ".ppsm" and mimeType = "application/vnd.ms-powerpoint.slideshow.macroEnabled.12" + or + ext = ".ppsx" and + mimeType = "application/vnd.openxmlformats-officedocument.presentationml.slideshow" + or + ext = ".ppt" and mimeType = "application/vnd.ms-powerpoint" + or + ext = ".pptm" and mimeType = "application/vnd.ms-powerpoint.presentation.macroEnabled.12" + or + ext = ".pptx" and + mimeType = "application/vnd.openxmlformats-officedocument.presentationml.presentation" + or + ext = ".prc" and mimeType = "application/vnd.palm" + or + ext = ".pre" and mimeType = "application/vnd.lotus-freelance" + or + ext = ".prf" and mimeType = "application/pics-rules" + or + ext = ".ps" and mimeType = "application/postscript" + or + ext = ".psb" and mimeType = "application/vnd.3gpp.pic-bw-small" + or + ext = ".psd" and mimeType = "image/vnd.adobe.photoshop" + or + ext = ".ptid" and mimeType = "application/vnd.pvi.ptid1" + or + ext = ".pub" and mimeType = "application/x-mspublisher" + or + ext = ".pvb" and mimeType = "application/vnd.3gpp.pic-bw-var" + or + ext = ".pwn" and mimeType = "application/vnd.3m.post-it-notes" + or + ext = ".py" and mimeType = "text/x-script.python" + or + ext = ".pya" and mimeType = "audio/vnd.ms-playready.media.pya" + or + ext = ".pyv" and mimeType = "video/vnd.ms-playready.media.pyv" + or + ext = ".qam" and mimeType = "application/vnd.epson.quickanime" + or + ext = ".qbo" and mimeType = "application/vnd.intu.qbo" + or + ext = ".qfx" and mimeType = "application/vnd.intu.qfx" + or + ext = ".qps" and mimeType = "application/vnd.publishare-delta-tree" + or + ext = ".qt" and mimeType = "video/quicktime" + or + ext = ".qtif" and mimeType = "image/x-quicktime" + or + ext = ".qxd" and mimeType = "application/vnd.quark.quarkxpress" + or + ext = ".ra" and mimeType = "audio/x-pn-realaudio" + or + ext = ".rake" and mimeType = "text/x-script.ruby" + or + ext = ".ram" and mimeType = "audio/x-pn-realaudio" + or + ext = ".rar" and mimeType = "application/x-rar-compressed" + or + ext = ".ras" and mimeType = "image/x-cmu-raster" + or + ext = ".rb" and mimeType = "text/x-script.ruby" + or + ext = ".rcprofile" and mimeType = "application/vnd.ipunplugged.rcprofile" + or + ext = ".rdf" and mimeType = "application/rdf+xml" + or + ext = ".rdz" and mimeType = "application/vnd.data-vision.rdz" + or + ext = ".rep" and mimeType = "application/vnd.businessobjects" + or + ext = ".rgb" and mimeType = "image/x-rgb" + or + ext = ".rif" and mimeType = "application/reginfo+xml" + or + ext = ".rl" and mimeType = "application/resource-lists+xml" + or + ext = ".rlc" and mimeType = "image/vnd.fujixerox.edmics-rlc" + or + ext = ".rld" and mimeType = "application/resource-lists-diff+xml" + or + ext = ".rm" and mimeType = "application/vnd.rn-realmedia" + or + ext = ".rmp" and mimeType = "audio/x-pn-realaudio-plugin" + or + ext = ".rms" and mimeType = "application/vnd.jcp.javame.midlet-rms" + or + ext = ".rnc" and mimeType = "application/relax-ng-compact-syntax" + or + ext = ".roff" and mimeType = "text/troff" + or + ext = ".rpm" and mimeType = "application/x-redhat-package-manager" + or + ext = ".rpss" and mimeType = "application/vnd.nokia.radio-presets" + or + ext = ".rpst" and mimeType = "application/vnd.nokia.radio-preset" + or + ext = ".rq" and mimeType = "application/sparql-query" + or + ext = ".rs" and mimeType = "application/rls-services+xml" + or + ext = ".rsd" and mimeType = "application/rsd+xml" + or + ext = ".rss" and mimeType = "application/rss+xml" + or + ext = ".rtf" and mimeType = "application/rtf" + or + ext = ".rtx" and mimeType = "text/richtext" + or + ext = ".ru" and mimeType = "text/x-script.ruby" + or + ext = ".s" and mimeType = "text/x-asm" + or + ext = ".saf" and mimeType = "application/vnd.yamaha.smaf-audio" + or + ext = ".sbml" and mimeType = "application/sbml+xml" + or + ext = ".sc" and mimeType = "application/vnd.ibm.secure-container" + or + ext = ".scd" and mimeType = "application/x-msschedule" + or + ext = ".scm" and mimeType = "application/vnd.lotus-screencam" + or + ext = ".scq" and mimeType = "application/scvp-cv-request" + or + ext = ".scs" and mimeType = "application/scvp-cv-response" + or + ext = ".sdkm" and mimeType = "application/vnd.solent.sdkm+xml" + or + ext = ".sdp" and mimeType = "application/sdp" + or + ext = ".see" and mimeType = "application/vnd.seemail" + or + ext = ".sema" and mimeType = "application/vnd.sema" + or + ext = ".semd" and mimeType = "application/vnd.semd" + or + ext = ".semf" and mimeType = "application/vnd.semf" + or + ext = ".setpay" and mimeType = "application/set-payment-initiation" + or + ext = ".setreg" and mimeType = "application/set-registration-initiation" + or + ext = ".sfd" and mimeType = "application/vnd.hydrostatix.sof-data" + or + ext = ".sfs" and mimeType = "application/vnd.spotfire.sfs" + or + ext = ".sgm" and mimeType = "text/sgml" + or + ext = ".sgml" and mimeType = "text/sgml" + or + ext = ".sh" and mimeType = "application/x-sh" + or + ext = ".shar" and mimeType = "application/x-shar" + or + ext = ".shf" and mimeType = "application/shf+xml" + or + ext = ".sig" and mimeType = "application/pgp-signature" + or + ext = ".sit" and mimeType = "application/x-stuffit" + or + ext = ".sitx" and mimeType = "application/x-stuffitx" + or + ext = ".skp" and mimeType = "application/vnd.koan" + or + ext = ".slt" and mimeType = "application/vnd.epson.salt" + or + ext = ".smi" and mimeType = "application/smil+xml" + or + ext = ".snd" and mimeType = "audio/basic" + or + ext = ".so" and mimeType = "application/octet-stream" + or + ext = ".spf" and mimeType = "application/vnd.yamaha.smaf-phrase" + or + ext = ".spl" and mimeType = "application/x-futuresplash" + or + ext = ".spot" and mimeType = "text/vnd.in3d.spot" + or + ext = ".spp" and mimeType = "application/scvp-vp-response" + or + ext = ".spq" and mimeType = "application/scvp-vp-request" + or + ext = ".src" and mimeType = "application/x-wais-source" + or + ext = ".srt" and mimeType = "text/srt" + or + ext = ".srx" and mimeType = "application/sparql-results+xml" + or + ext = ".sse" and mimeType = "application/vnd.kodak-descriptor" + or + ext = ".ssf" and mimeType = "application/vnd.epson.ssf" + or + ext = ".ssml" and mimeType = "application/ssml+xml" + or + ext = ".stf" and mimeType = "application/vnd.wt.stf" + or + ext = ".stk" and mimeType = "application/hyperstudio" + or + ext = ".str" and mimeType = "application/vnd.pg.format" + or + ext = ".sus" and mimeType = "application/vnd.sus-calendar" + or + ext = ".sv4cpio" and mimeType = "application/x-sv4cpio" + or + ext = ".sv4crc" and mimeType = "application/x-sv4crc" + or + ext = ".svd" and mimeType = "application/vnd.svd" + or + ext = ".svg" and mimeType = "image/svg+xml" + or + ext = ".svgz" and mimeType = "image/svg+xml" + or + ext = ".swf" and mimeType = "application/x-shockwave-flash" + or + ext = ".swi" and mimeType = "application/vnd.arastra.swi" + or + ext = ".t" and mimeType = "text/troff" + or + ext = ".tao" and mimeType = "application/vnd.tao.intent-module-archive" + or + ext = ".tar" and mimeType = "application/x-tar" + or + ext = ".tbz" and mimeType = "application/x-bzip-compressed-tar" + or + ext = ".tcap" and mimeType = "application/vnd.3gpp2.tcap" + or + ext = ".tcl" and mimeType = "application/x-tcl" + or + ext = ".tex" and mimeType = "application/x-tex" + or + ext = ".texi" and mimeType = "application/x-texinfo" + or + ext = ".texinfo" and mimeType = "application/x-texinfo" + or + ext = ".text" and mimeType = "text/plain" + or + ext = ".tif" and mimeType = "image/tiff" + or + ext = ".tiff" and mimeType = "image/tiff" + or + ext = ".tmo" and mimeType = "application/vnd.tmobile-livetv" + or + ext = ".torrent" and mimeType = "application/x-bittorrent" + or + ext = ".tpl" and mimeType = "application/vnd.groove-tool-template" + or + ext = ".tpt" and mimeType = "application/vnd.trid.tpt" + or + ext = ".tr" and mimeType = "text/troff" + or + ext = ".tra" and mimeType = "application/vnd.trueapp" + or + ext = ".trm" and mimeType = "application/x-msterminal" + or + ext = ".ts" and mimeType = "video/mp2t" + or + ext = ".tsv" and mimeType = "text/tab-separated-values" + or + ext = ".ttf" and mimeType = "application/octet-stream" + or + ext = ".twd" and mimeType = "application/vnd.simtech-mindmapper" + or + ext = ".txd" and mimeType = "application/vnd.genomatix.tuxedo" + or + ext = ".txf" and mimeType = "application/vnd.mobius.txf" + or + ext = ".txt" and mimeType = "text/plain" + or + ext = ".ufd" and mimeType = "application/vnd.ufdl" + or + ext = ".umj" and mimeType = "application/vnd.umajin" + or + ext = ".unityweb" and mimeType = "application/vnd.unity" + or + ext = ".uoml" and mimeType = "application/vnd.uoml+xml" + or + ext = ".uri" and mimeType = "text/uri-list" + or + ext = ".ustar" and mimeType = "application/x-ustar" + or + ext = ".utz" and mimeType = "application/vnd.uiq.theme" + or + ext = ".uu" and mimeType = "text/x-uuencode" + or + ext = ".vcd" and mimeType = "application/x-cdlink" + or + ext = ".vcf" and mimeType = "text/x-vcard" + or + ext = ".vcg" and mimeType = "application/vnd.groove-vcard" + or + ext = ".vcs" and mimeType = "text/x-vcalendar" + or + ext = ".vcx" and mimeType = "application/vnd.vcx" + or + ext = ".vis" and mimeType = "application/vnd.visionary" + or + ext = ".viv" and mimeType = "video/vnd.vivo" + or + ext = ".vrml" and mimeType = "model/vrml" + or + ext = ".vsd" and mimeType = "application/vnd.visio" + or + ext = ".vsf" and mimeType = "application/vnd.vsf" + or + ext = ".vtt" and mimeType = "text/vtt" + or + ext = ".vtu" and mimeType = "model/vnd.vtu" + or + ext = ".vxml" and mimeType = "application/voicexml+xml" + or + ext = ".war" and mimeType = "application/java-archive" + or + ext = ".wasm" and mimeType = "application/wasm" + or + ext = ".wav" and mimeType = "audio/x-wav" + or + ext = ".wax" and mimeType = "audio/x-ms-wax" + or + ext = ".wbmp" and mimeType = "image/vnd.wap.wbmp" + or + ext = ".wbs" and mimeType = "application/vnd.criticaltools.wbs+xml" + or + ext = ".wbxml" and mimeType = "application/vnd.wap.wbxml" + or + ext = ".webm" and mimeType = "video/webm" + or + ext = ".webp" and mimeType = "image/webp" + or + ext = ".wm" and mimeType = "video/x-ms-wm" + or + ext = ".wma" and mimeType = "audio/x-ms-wma" + or + ext = ".wmd" and mimeType = "application/x-ms-wmd" + or + ext = ".wmf" and mimeType = "application/x-msmetafile" + or + ext = ".wml" and mimeType = "text/vnd.wap.wml" + or + ext = ".wmlc" and mimeType = "application/vnd.wap.wmlc" + or + ext = ".wmls" and mimeType = "text/vnd.wap.wmlscript" + or + ext = ".wmlsc" and mimeType = "application/vnd.wap.wmlscriptc" + or + ext = ".wmv" and mimeType = "video/x-ms-wmv" + or + ext = ".wmx" and mimeType = "video/x-ms-wmx" + or + ext = ".wmz" and mimeType = "application/x-ms-wmz" + or + ext = ".woff" and mimeType = "application/font-woff" + or + ext = ".woff2" and mimeType = "application/font-woff2" + or + ext = ".wpd" and mimeType = "application/vnd.wordperfect" + or + ext = ".wpl" and mimeType = "application/vnd.ms-wpl" + or + ext = ".wps" and mimeType = "application/vnd.ms-works" + or + ext = ".wqd" and mimeType = "application/vnd.wqd" + or + ext = ".wri" and mimeType = "application/x-mswrite" + or + ext = ".wrl" and mimeType = "model/vrml" + or + ext = ".wsdl" and mimeType = "application/wsdl+xml" + or + ext = ".wspolicy" and mimeType = "application/wspolicy+xml" + or + ext = ".wtb" and mimeType = "application/vnd.webturbo" + or + ext = ".wvx" and mimeType = "video/x-ms-wvx" + or + ext = ".x3d" and mimeType = "application/vnd.hzn-3d-crossword" + or + ext = ".xar" and mimeType = "application/vnd.xara" + or + ext = ".xbd" and mimeType = "application/vnd.fujixerox.docuworks.binder" + or + ext = ".xbm" and mimeType = "image/x-xbitmap" + or + ext = ".xdm" and mimeType = "application/vnd.syncml.dm+xml" + or + ext = ".xdp" and mimeType = "application/vnd.adobe.xdp+xml" + or + ext = ".xdw" and mimeType = "application/vnd.fujixerox.docuworks" + or + ext = ".xenc" and mimeType = "application/xenc+xml" + or + ext = ".xer" and mimeType = "application/patch-ops-error+xml" + or + ext = ".xfdf" and mimeType = "application/vnd.adobe.xfdf" + or + ext = ".xfdl" and mimeType = "application/vnd.xfdl" + or + ext = ".xhtml" and mimeType = "application/xhtml+xml" + or + ext = ".xif" and mimeType = "image/vnd.xiff" + or + ext = ".xla" and mimeType = "application/vnd.ms-excel" + or + ext = ".xlam" and mimeType = "application/vnd.ms-excel.addin.macroEnabled.12" + or + ext = ".xls" and mimeType = "application/vnd.ms-excel" + or + ext = ".xlsb" and mimeType = "application/vnd.ms-excel.sheet.binary.macroEnabled.12" + or + ext = ".xlsx" and mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + or + ext = ".xlsm" and mimeType = "application/vnd.ms-excel.sheet.macroEnabled.12" + or + ext = ".xlt" and mimeType = "application/vnd.ms-excel" + or + ext = ".xltx" and + mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.template" + or + ext = ".xml" and mimeType = "application/xml" + or + ext = ".xo" and mimeType = "application/vnd.olpc-sugar" + or + ext = ".xop" and mimeType = "application/xop+xml" + or + ext = ".xpm" and mimeType = "image/x-xpixmap" + or + ext = ".xpr" and mimeType = "application/vnd.is-xpr" + or + ext = ".xps" and mimeType = "application/vnd.ms-xpsdocument" + or + ext = ".xpw" and mimeType = "application/vnd.intercon.formnet" + or + ext = ".xsl" and mimeType = "application/xml" + or + ext = ".xslt" and mimeType = "application/xslt+xml" + or + ext = ".xsm" and mimeType = "application/vnd.syncml+xml" + or + ext = ".xspf" and mimeType = "application/xspf+xml" + or + ext = ".xul" and mimeType = "application/vnd.mozilla.xul+xml" + or + ext = ".xwd" and mimeType = "image/x-xwindowdump" + or + ext = ".xyz" and mimeType = "chemical/x-xyz" + or + ext = ".yaml" and mimeType = "text/yaml" + or + ext = ".yml" and mimeType = "text/yaml" + or + ext = ".zaz" and mimeType = "application/vnd.zzazz.deck+xml" + or + ext = ".zip" and mimeType = "application/zip" + or + ext = ".zmm" and mimeType = "application/vnd.handheld-entertainment+xml" +} diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 6e18162a5e1..489531bdba4 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -1,3 +1,4 @@ +private import codeql.ruby.AST private import codeql.ruby.frameworks.Rack private import codeql.ruby.DataFlow @@ -8,3 +9,9 @@ query predicate rackResponseStatusCodes(Rack::ResponseNode resp, string status) then status = resp.getAStatusCode().toString() else status = "<unknown>" } + +query predicate rackResponseContentTypes(Rack::ResponseNode resp, DataFlow::Node contentType) { + contentType = resp.getMimetypeOrContentTypeArg() +} + +query predicate mimetypeCalls(Rack::MimetypeCall c, string mimetype) { mimetype = c.getMimeType() } diff --git a/ruby/ql/test/library-tests/frameworks/rack/rack.rb b/ruby/ql/test/library-tests/frameworks/rack/rack.rb index c3b7729812b..2478faee3fc 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/rack.rb +++ b/ruby/ql/test/library-tests/frameworks/rack/rack.rb @@ -4,7 +4,8 @@ class HelloWorld if something_goes_wrong(env) status = 500 end - [status, {'Content-Type' => 'text/plain'}, ['Hello World']] + headers = {'Content-Type' => 'text/plain'} + [status, headers, ['Hello World']] end end @@ -15,6 +16,7 @@ class Proxy def call(the_env) status, headers, body = @app.call(the_env) + headers.content_type = Rack::Mime.mime_type(".gz") [status, headers, body] end end From b2958f87b2e7bdde32f182030888befffb872bdf Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Mon, 22 May 2023 13:56:53 +0100 Subject: [PATCH 266/739] ruby: rack - add redirect responses --- .../lib/codeql/ruby/frameworks/rack/Rack.qll | 59 +++++++++++-------- .../library-tests/frameworks/rack/Rack.ql | 4 ++ .../library-tests/frameworks/rack/rack.rb | 8 +++ 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll index b570f276c51..a36c4ba043f 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll @@ -82,6 +82,34 @@ class MimetypeCall extends DataFlow::CallNode { string getMimeType() { mimeTypeMatches(this.getExtension(), result) } } +bindingset[headerName] +private DataFlow::Node getHeaderValue(ResponseNode resp, string headerName) { + exists(DataFlow::Node headers | headers = resp.getHeaders() | + // set via `headers.<header_name>=` + exists( + DataFlow::CallNode contentTypeAssignment, Assignment assignment, + DataFlow::PostUpdateNode postUpdateHeaders + | + contentTypeAssignment.getMethodName() = headerName.replaceAll("-", "_").toLowerCase() + "=" and + assignment = + contentTypeAssignment.getArgument(0).(DataFlow::OperationNode).asOperationAstNode() and + postUpdateHeaders.(DataFlow::LocalSourceNode).flowsTo(headers) and + postUpdateHeaders.getPreUpdateNode() = contentTypeAssignment.getReceiver() + | + result.asExpr().getExpr() = assignment.getRightOperand() + ) + or + // set within a hash + exists(DataFlow::HashLiteralNode headersHash | headersHash.flowsTo(headers) | + result = + headersHash + .getElementFromKey(any(ConstantValue v | + v.getStringlikeValue().toLowerCase() = headerName.toLowerCase() + )) + ) + ) +} + /** A `DataFlow::Node` returned from a rack request. */ class ResponseNode extends PotentialResponseNode, Http::Server::HttpResponse::Range { ResponseNode() { this = any(AppCandidate app).getResponse() } @@ -89,32 +117,15 @@ class ResponseNode extends PotentialResponseNode, Http::Server::HttpResponse::Ra override DataFlow::Node getBody() { result = this.getElement(2) } override DataFlow::Node getMimetypeOrContentTypeArg() { - exists(DataFlow::Node headers | headers = this.getHeaders() | - // set via `headers.content_type=` - exists( - DataFlow::CallNode contentTypeAssignment, Assignment assignment, - DataFlow::PostUpdateNode postUpdateHeaders - | - contentTypeAssignment.getMethodName() = "content_type=" and - assignment = - contentTypeAssignment.getArgument(0).(DataFlow::OperationNode).asOperationAstNode() and - postUpdateHeaders.(DataFlow::LocalSourceNode).flowsTo(headers) and - postUpdateHeaders.getPreUpdateNode() = contentTypeAssignment.getReceiver() - | - result.asExpr().getExpr() = assignment.getRightOperand() - ) - or - // set within a hash - exists(DataFlow::HashLiteralNode headersHash | headersHash.flowsTo(headers) | - result = - headersHash - .getElementFromKey(any(ConstantValue v | - v.getStringlikeValue().toLowerCase() = "content-type" - )) - ) - ) + result = getHeaderValue(this, "content-type") } // TODO override string getMimetypeDefault() { none() } } + +class RedirectResponse extends ResponseNode, Http::Server::HttpRedirectResponse::Range { + RedirectResponse() { this.getAStatusCode() = [300, 301, 302, 303, 307, 308] } + + override DataFlow::Node getRedirectLocation() { result = getHeaderValue(this, "location") } +} diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 489531bdba4..b4299d9d6f9 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -15,3 +15,7 @@ query predicate rackResponseContentTypes(Rack::ResponseNode resp, DataFlow::Node } query predicate mimetypeCalls(Rack::MimetypeCall c, string mimetype) { mimetype = c.getMimeType() } + +query predicate redirectResponses(Rack::RedirectResponse resp, DataFlow::Node location) { + location = resp.getRedirectLocation() +} diff --git a/ruby/ql/test/library-tests/frameworks/rack/rack.rb b/ruby/ql/test/library-tests/frameworks/rack/rack.rb index 2478faee3fc..c2e2598e5ec 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/rack.rb +++ b/ruby/ql/test/library-tests/frameworks/rack/rack.rb @@ -36,6 +36,14 @@ class Logger end end +class Redirector + def call(env) + status = 302 + headers = {'location' => '/foo.html'} + [status, headers, ['this is a redirect']] + end +end + class Foo def not_call(env) [1, 2, 3] From a5a15f380400c4999057ec13cbf2a1d69443d960 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Wed, 24 May 2023 15:49:59 +0100 Subject: [PATCH 267/739] Ruby: restructure rack model --- .../ruby/frameworks/ActionController.qll | 2 +- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 7 +- .../lib/codeql/ruby/frameworks/rack/Rack.qll | 131 ------------------ .../ruby/frameworks/rack/internal/App.qll | 41 ++++++ .../rack/internal/{MimeTypes.qll => Mime.qll} | 17 +++ .../frameworks/rack/internal/Response.qll | 84 +++++++++++ .../library-tests/frameworks/rack/Rack.ql | 16 ++- 7 files changed, 160 insertions(+), 138 deletions(-) delete mode 100644 ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll rename ruby/ql/lib/codeql/ruby/frameworks/rack/internal/{MimeTypes.qll => Mime.qll} (98%) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll index 480a1f78035..5899f38411d 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll @@ -326,7 +326,7 @@ private module Request { private import codeql.ruby.frameworks.Rack private class RackEnv extends Env { - RackEnv() { this = any(Rack::AppCandidate app).getEnv().getALocalUse() } + RackEnv() { this = any(Rack::App::AppCandidate app).getEnv().getALocalUse() } } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index ba969ae4c45..64ca7cc0b60 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -2,5 +2,10 @@ * Provides modeling for the Rack library. */ module Rack { - import rack.Rack + import rack.internal.App + import rack.internal.Mime + import rack.internal.Response::Public as Response + + /** DEPRECATED: Alias for App::AppCandidate */ + deprecated class AppCandidate = App::AppCandidate; } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll deleted file mode 100644 index a36c4ba043f..00000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/Rack.qll +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Provides modeling for the Rack library. - */ - -private import codeql.ruby.AST -private import codeql.ruby.ApiGraphs -private import codeql.ruby.Concepts -private import codeql.ruby.controlflow.CfgNodes::ExprNodes -private import codeql.ruby.DataFlow -private import codeql.ruby.typetracking.TypeTracker -private import internal.MimeTypes - -/** - * A class that may be a rack application. - * This is a class that has a `call` method that takes a single argument - * (traditionally called `env`) and returns a rack-compatible response. - */ -class AppCandidate extends DataFlow::ClassNode { - private DataFlow::MethodNode call; - private PotentialResponseNode resp; - - AppCandidate() { - call = this.getInstanceMethod("call") and - call.getNumberOfParameters() = 1 and - call.getReturn() = trackRackResponse(resp) - } - - /** - * Gets the environment of the request, which is the lone parameter to the `call` method. - */ - DataFlow::ParameterNode getEnv() { result = call.getParameter(0) } - - /** Gets the response returned from the request. */ - PotentialResponseNode getResponse() { result = resp } -} - -private DataFlow::LocalSourceNode trackInt(TypeTracker t, int i) { - t.start() and - result.getConstantValue().isInt(i) - or - exists(TypeTracker t2 | result = trackInt(t2, i).track(t2, t)) -} - -private DataFlow::Node trackInt(int i) { trackInt(TypeTracker::end(), i).flowsTo(result) } - -private class PotentialResponseNode extends DataFlow::ArrayLiteralNode { - // [status, headers, body] - PotentialResponseNode() { this.getNumberOfArguments() = 3 } - - /** - * Gets an HTTP status code that may be returned in this response. - */ - int getAStatusCode() { this.getElement(0) = trackInt(result) } - - /** Gets the headers returned with this response. */ - DataFlow::Node getHeaders() { result = this.getElement(1) } - - /** Gets the body of this response. */ - DataFlow::Node getBody() { result = this.getElement(2) } -} - -private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t, PotentialResponseNode n) { - t.start() and - result = n - or - exists(TypeTracker t2 | result = trackRackResponse(t2, n).track(t2, t)) -} - -private DataFlow::Node trackRackResponse(PotentialResponseNode n) { - trackRackResponse(TypeTracker::end(), n).flowsTo(result) -} - -class MimetypeCall extends DataFlow::CallNode { - MimetypeCall() { - this = API::getTopLevelMember("Rack").getMember("Mime").getAMethodCall("mime_type") - } - - private string getExtension() { - result = this.getArgument(0).getConstantValue().getStringlikeValue() - } - - string getMimeType() { mimeTypeMatches(this.getExtension(), result) } -} - -bindingset[headerName] -private DataFlow::Node getHeaderValue(ResponseNode resp, string headerName) { - exists(DataFlow::Node headers | headers = resp.getHeaders() | - // set via `headers.<header_name>=` - exists( - DataFlow::CallNode contentTypeAssignment, Assignment assignment, - DataFlow::PostUpdateNode postUpdateHeaders - | - contentTypeAssignment.getMethodName() = headerName.replaceAll("-", "_").toLowerCase() + "=" and - assignment = - contentTypeAssignment.getArgument(0).(DataFlow::OperationNode).asOperationAstNode() and - postUpdateHeaders.(DataFlow::LocalSourceNode).flowsTo(headers) and - postUpdateHeaders.getPreUpdateNode() = contentTypeAssignment.getReceiver() - | - result.asExpr().getExpr() = assignment.getRightOperand() - ) - or - // set within a hash - exists(DataFlow::HashLiteralNode headersHash | headersHash.flowsTo(headers) | - result = - headersHash - .getElementFromKey(any(ConstantValue v | - v.getStringlikeValue().toLowerCase() = headerName.toLowerCase() - )) - ) - ) -} - -/** A `DataFlow::Node` returned from a rack request. */ -class ResponseNode extends PotentialResponseNode, Http::Server::HttpResponse::Range { - ResponseNode() { this = any(AppCandidate app).getResponse() } - - override DataFlow::Node getBody() { result = this.getElement(2) } - - override DataFlow::Node getMimetypeOrContentTypeArg() { - result = getHeaderValue(this, "content-type") - } - - // TODO - override string getMimetypeDefault() { none() } -} - -class RedirectResponse extends ResponseNode, Http::Server::HttpRedirectResponse::Range { - RedirectResponse() { this.getAStatusCode() = [300, 301, 302, 303, 307, 308] } - - override DataFlow::Node getRedirectLocation() { result = getHeaderValue(this, "location") } -} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll new file mode 100644 index 00000000000..7dbd7c7a840 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -0,0 +1,41 @@ +private import codeql.ruby.ApiGraphs +private import codeql.ruby.DataFlow +private import codeql.ruby.typetracking.TypeTracker +private import Response::Private as RP + +private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t, RP::PotentialResponseNode n) { + t.start() and + result = n + or + exists(TypeTracker t2 | result = trackRackResponse(t2, n).track(t2, t)) +} + +private DataFlow::Node trackRackResponse(RP::PotentialResponseNode n) { + trackRackResponse(TypeTracker::end(), n).flowsTo(result) +} + +module App { + /** + * A class that may be a rack application. + * This is a class that has a `call` method that takes a single argument + * (traditionally called `env`) and returns a rack-compatible response. + */ + class AppCandidate extends DataFlow::ClassNode { + private DataFlow::MethodNode call; + private RP::PotentialResponseNode resp; + + AppCandidate() { + call = this.getInstanceMethod("call") and + call.getNumberOfParameters() = 1 and + call.getReturn() = trackRackResponse(resp) + } + + /** + * Gets the environment of the request, which is the lone parameter to the `call` method. + */ + DataFlow::ParameterNode getEnv() { result = call.getParameter(0) } + + /** Gets the response returned from the request. */ + RP::PotentialResponseNode getResponse() { result = resp } + } +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/MimeTypes.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll similarity index 98% rename from ruby/ql/lib/codeql/ruby/frameworks/rack/internal/MimeTypes.qll rename to ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll index ed5bad4b8a6..502fe72fa51 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/MimeTypes.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll @@ -1,3 +1,6 @@ +private import codeql.ruby.ApiGraphs +private import codeql.ruby.DataFlow + predicate mimeTypeMatches(string ext, string mimeType) { ext = ".123" and mimeType = "application/vnd.lotus-1-2-3" or @@ -1283,3 +1286,17 @@ predicate mimeTypeMatches(string ext, string mimeType) { or ext = ".zmm" and mimeType = "application/vnd.handheld-entertainment+xml" } + +module Mime { + class MimetypeCall extends DataFlow::CallNode { + MimetypeCall() { + this = API::getTopLevelMember("Rack").getMember("Mime").getAMethodCall("mime_type") + } + + private string getExtension() { + result = this.getArgument(0).getConstantValue().getStringlikeValue() + } + + string getMimeType() { mimeTypeMatches(this.getExtension(), result) } + } +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll new file mode 100644 index 00000000000..f7fb1d31177 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -0,0 +1,84 @@ +private import codeql.ruby.AST +private import codeql.ruby.ApiGraphs +private import codeql.ruby.Concepts +private import codeql.ruby.controlflow.CfgNodes::ExprNodes +private import codeql.ruby.DataFlow +private import codeql.ruby.typetracking.TypeTracker +private import App as A + +module Private { + private DataFlow::LocalSourceNode trackInt(TypeTracker t, int i) { + t.start() and + result.getConstantValue().isInt(i) + or + exists(TypeTracker t2 | result = trackInt(t2, i).track(t2, t)) + } + + private DataFlow::Node trackInt(int i) { trackInt(TypeTracker::end(), i).flowsTo(result) } + + class PotentialResponseNode extends DataFlow::ArrayLiteralNode { + // [status, headers, body] + PotentialResponseNode() { this.getNumberOfArguments() = 3 } + + /** + * Gets an HTTP status code that may be returned in this response. + */ + int getAStatusCode() { this.getElement(0) = trackInt(result) } + + /** Gets the headers returned with this response. */ + DataFlow::Node getHeaders() { result = this.getElement(1) } + + /** Gets the body of this response. */ + DataFlow::Node getBody() { result = this.getElement(2) } + } +} + +module Public { + bindingset[headerName] + private DataFlow::Node getHeaderValue(ResponseNode resp, string headerName) { + exists(DataFlow::Node headers | headers = resp.getHeaders() | + // set via `headers.<header_name>=` + exists( + DataFlow::CallNode contentTypeAssignment, Assignment assignment, + DataFlow::PostUpdateNode postUpdateHeaders + | + contentTypeAssignment.getMethodName() = headerName.replaceAll("-", "_").toLowerCase() + "=" and + assignment = + contentTypeAssignment.getArgument(0).(DataFlow::OperationNode).asOperationAstNode() and + postUpdateHeaders.(DataFlow::LocalSourceNode).flowsTo(headers) and + postUpdateHeaders.getPreUpdateNode() = contentTypeAssignment.getReceiver() + | + result.asExpr().getExpr() = assignment.getRightOperand() + ) + or + // set within a hash + exists(DataFlow::HashLiteralNode headersHash | headersHash.flowsTo(headers) | + result = + headersHash + .getElementFromKey(any(ConstantValue v | + v.getStringlikeValue().toLowerCase() = headerName.toLowerCase() + )) + ) + ) + } + + /** A `DataFlow::Node` returned from a rack request. */ + class ResponseNode extends Private::PotentialResponseNode, Http::Server::HttpResponse::Range { + ResponseNode() { this = any(A::App::AppCandidate app).getResponse() } + + override DataFlow::Node getBody() { result = this.getElement(2) } + + override DataFlow::Node getMimetypeOrContentTypeArg() { + result = getHeaderValue(this, "content-type") + } + + // TODO + override string getMimetypeDefault() { none() } + } + + class RedirectResponse extends ResponseNode, Http::Server::HttpRedirectResponse::Range { + RedirectResponse() { this.getAStatusCode() = [300, 301, 302, 303, 307, 308] } + + override DataFlow::Node getRedirectLocation() { result = getHeaderValue(this, "location") } + } +} diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index b4299d9d6f9..8e0bcee4244 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -2,20 +2,26 @@ private import codeql.ruby.AST private import codeql.ruby.frameworks.Rack private import codeql.ruby.DataFlow -query predicate rackApps(Rack::AppCandidate c, DataFlow::ParameterNode env) { env = c.getEnv() } +query predicate rackApps(Rack::App::AppCandidate c, DataFlow::ParameterNode env) { + env = c.getEnv() +} -query predicate rackResponseStatusCodes(Rack::ResponseNode resp, string status) { +query predicate rackResponseStatusCodes(Rack::Response::ResponseNode resp, string status) { if exists(resp.getAStatusCode()) then status = resp.getAStatusCode().toString() else status = "<unknown>" } -query predicate rackResponseContentTypes(Rack::ResponseNode resp, DataFlow::Node contentType) { +query predicate rackResponseContentTypes( + Rack::Response::ResponseNode resp, DataFlow::Node contentType +) { contentType = resp.getMimetypeOrContentTypeArg() } -query predicate mimetypeCalls(Rack::MimetypeCall c, string mimetype) { mimetype = c.getMimeType() } +query predicate mimetypeCalls(Rack::Mime::MimetypeCall c, string mimetype) { + mimetype = c.getMimeType() +} -query predicate redirectResponses(Rack::RedirectResponse resp, DataFlow::Node location) { +query predicate redirectResponses(Rack::Response::RedirectResponse resp, DataFlow::Node location) { location = resp.getRedirectLocation() } From 19664879c877f61630525ce287f115778b1c5732 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 25 May 2023 14:18:09 +0100 Subject: [PATCH 268/739] ruby: slightly expand a TODO --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index f7fb1d31177..c5d5b197382 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -72,7 +72,7 @@ module Public { result = getHeaderValue(this, "content-type") } - // TODO + // TODO: is there a sensible value for this? override string getMimetypeDefault() { none() } } From 4905a70e21271fe2c7ffabf63173ccf979b01207 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 25 May 2023 14:18:51 +0100 Subject: [PATCH 269/739] Ruby: update rack test output --- .../frameworks/rack/Rack.expected | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index 23fec9a8266..157168f0bd8 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -1,12 +1,21 @@ rackApps -| rack.rb:1:1:9:3 | HelloWorld | rack.rb:2:12:2:14 | env | -| rack.rb:11:1:20:3 | Proxy | rack.rb:16:12:16:18 | the_env | -| rack.rb:22:1:35:3 | Logger | rack.rb:28:12:28:14 | env | -| rack.rb:49:1:65:3 | Baz | rack.rb:50:12:50:14 | env | +| rack.rb:1:1:10:3 | HelloWorld | rack.rb:2:12:2:14 | env | +| rack.rb:12:1:22:3 | Proxy | rack.rb:17:12:17:18 | the_env | +| rack.rb:24:1:37:3 | Logger | rack.rb:30:12:30:14 | env | +| rack.rb:39:1:45:3 | Redirector | rack.rb:40:12:40:14 | env | +| rack.rb:59:1:75:3 | Baz | rack.rb:60:12:60:14 | env | rackResponseStatusCodes -| rack.rb:7:5:7:63 | call to [] | 200 | -| rack.rb:7:5:7:63 | call to [] | 500 | -| rack.rb:18:5:18:27 | call to [] | <unknown> | -| rack.rb:33:5:33:26 | call to [] | <unknown> | -| rack.rb:56:7:56:22 | call to [] | 200 | -| rack.rb:63:5:63:21 | call to [] | 400 | +| rack.rb:8:5:8:38 | call to [] | 200 | +| rack.rb:8:5:8:38 | call to [] | 500 | +| rack.rb:20:5:20:27 | call to [] | <unknown> | +| rack.rb:35:5:35:26 | call to [] | <unknown> | +| rack.rb:43:5:43:45 | call to [] | 302 | +| rack.rb:66:7:66:22 | call to [] | 200 | +| rack.rb:73:5:73:21 | call to [] | 400 | +rackResponseContentTypes +| rack.rb:8:5:8:38 | call to [] | rack.rb:7:34:7:45 | "text/plain" | +| rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:54 | call to mime_type | +mimetypeCalls +| rack.rb:19:28:19:54 | call to mime_type | application/x-gzip | +redirectResponses +| rack.rb:43:5:43:45 | call to [] | rack.rb:42:30:42:40 | "/foo.html" | From 40da7d45c2c127045ddc94fa98d9523d57a1d7af Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 25 May 2023 14:20:55 +0100 Subject: [PATCH 270/739] ruby: make a predicate private --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll index 502fe72fa51..df09146c315 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll @@ -1,7 +1,7 @@ private import codeql.ruby.ApiGraphs private import codeql.ruby.DataFlow -predicate mimeTypeMatches(string ext, string mimeType) { +private predicate mimeTypeMatches(string ext, string mimeType) { ext = ".123" and mimeType = "application/vnd.lotus-1-2-3" or ext = ".3dml" and mimeType = "text/vnd.in3d.3dml" From 24635df1a363c2685fb4e6be1a79bff322922921 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 25 May 2023 14:21:45 +0100 Subject: [PATCH 271/739] ruby: add some qldoc for rack --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll | 3 +++ ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll | 3 +++ ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 7dbd7c7a840..78666b7fe1d 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -14,6 +14,9 @@ private DataFlow::Node trackRackResponse(RP::PotentialResponseNode n) { trackRackResponse(TypeTracker::end(), n).flowsTo(result) } +/** + * Provides modeling for Rack applications. + */ module App { /** * A class that may be a rack application. diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll index df09146c315..d40895a2f13 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll @@ -1287,6 +1287,9 @@ private predicate mimeTypeMatches(string ext, string mimeType) { ext = ".zmm" and mimeType = "application/vnd.handheld-entertainment+xml" } +/** + * Provides modeling for the `Response` component of the `Rack` library. + */ module Mime { class MimetypeCall extends DataFlow::CallNode { MimetypeCall() { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index c5d5b197382..4cb3e99c639 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -6,6 +6,7 @@ private import codeql.ruby.DataFlow private import codeql.ruby.typetracking.TypeTracker private import App as A +/** Contains implementation details for modelling `Rack::Response`. */ module Private { private DataFlow::LocalSourceNode trackInt(TypeTracker t, int i) { t.start() and @@ -33,6 +34,9 @@ module Private { } } +/** + * Provides modeling for the `Response` component of the `Rack` library. + */ module Public { bindingset[headerName] private DataFlow::Node getHeaderValue(ResponseNode resp, string headerName) { From 23e22799a9fe0c65a6a8da4cf64d3de806f1279a Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Fri, 26 May 2023 11:38:32 +0100 Subject: [PATCH 272/739] ruby: rack - modelling -> modeling --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index 4cb3e99c639..65322dbac05 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -6,7 +6,7 @@ private import codeql.ruby.DataFlow private import codeql.ruby.typetracking.TypeTracker private import App as A -/** Contains implementation details for modelling `Rack::Response`. */ +/** Contains implementation details for modeling `Rack::Response`. */ module Private { private DataFlow::LocalSourceNode trackInt(TypeTracker t, int i) { t.start() and From b62a02f0ad38682d7fd1550484aae6d0dd3f997e Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Fri, 26 May 2023 11:39:59 +0100 Subject: [PATCH 273/739] ruby: remove unused field --- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index c076d6d6698..f995bc5af44 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -1280,9 +1280,7 @@ class HashLiteralNode extends LocalSourceNode, ExprNode { * explicit calls. */ class ArrayLiteralNode extends LocalSourceNode, CallNode { - private CfgNodes::ExprNodes::ArrayLiteralCfgNode arrayNode; - - ArrayLiteralNode() { super.getExprNode() = arrayNode } + ArrayLiteralNode() { super.getExprNode() instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode } /** * Gets an element of the array. From 6755bb32fbc6e4a48b263b59aad7aefeec5c9473 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Thu, 1 Jun 2023 15:18:05 +0200 Subject: [PATCH 274/739] Python: do not add read steps for collections --- .../dataflow/new/internal/TaintTrackingPrivate.qll | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 423ba24e432..78fb529b05a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -202,19 +202,6 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { obj = nodeTo.(DataFlow::PostUpdateNode).getPreUpdateNode() and call.getArg(0) = nodeFrom ) - or - // Although flow through collections is modeled precisely using stores/reads, we still - // allow flow out of a _tainted_ collection. This is needed in order to support taint- - // tracking configurations where the source is a collection. - exists(DataFlow::Content c | DataFlowPrivate::readStep(nodeFrom, c, nodeTo) | - // c instanceof DataFlow::ListElementContent - // or - // c instanceof DataFlow::SetElementContent - // or - c instanceof DataFlow::DictionaryElementContent - // or - // c instanceof DataFlow::DictionaryElementAnyContent - ) } /** From 9aeba4f31edcaaa88263f4b8039452581d944ff4 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 17:24:44 +0200 Subject: [PATCH 275/739] changes based on review --- javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp | 2 +- javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp index cdda5100ba3..9ee5158bf99 100644 --- a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp +++ b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp @@ -40,7 +40,7 @@ an HTTP request handler in a web application, whose parameter <p> The handler constructs constructs an SQL query string from user input and executes it as a database query using the <code>pg</code> library. -THe user input may contain quote characters, so this code is vulnerable +The user input may contain quote characters, so this code is vulnerable to a SQL injection attack. </p> diff --git a/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js b/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js index 4391b83e391..dbe5c4e369a 100644 --- a/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js +++ b/javascript/ql/src/Security/CWE-089/examples/SqlInjectionFix.js @@ -5,7 +5,7 @@ const app = require("express")(), app.get("search", function handler(req, res) { // GOOD: use parameters var query2 = - "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=$1" + " ORDER BY PRICE"; + "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=$1 ORDER BY PRICE"; pool.query(query2, [req.params.category], function(err, results) { // process results }); From 606d601923897f423b6fe7bd5c1590935c649d58 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 1 Jun 2023 16:26:05 +0100 Subject: [PATCH 276/739] qlformat --- ruby/ql/lib/codeql/ruby/Concepts.qll | 22 +++++++++---------- .../ql/lib/codeql/ruby/frameworks/Sqlite3.qll | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/Concepts.qll b/ruby/ql/lib/codeql/ruby/Concepts.qll index 0a403734512..d74947482f8 100644 --- a/ruby/ql/lib/codeql/ruby/Concepts.qll +++ b/ruby/ql/lib/codeql/ruby/Concepts.qll @@ -78,18 +78,18 @@ module SqlExecution { } } - /** - * A data-flow node that performs SQL sanitization. - */ - class SqlSanitization extends DataFlow::Node instanceof SqlSanitization::Range { } +/** + * A data-flow node that performs SQL sanitization. + */ +class SqlSanitization extends DataFlow::Node instanceof SqlSanitization::Range { } - /** Provides a class for modeling new SQL sanitization APIs. */ - module SqlSanitization { - /** - * A data-flow node that performs SQL sanitization. - */ - abstract class Range extends DataFlow::Node { } - } +/** Provides a class for modeling new SQL sanitization APIs. */ +module SqlSanitization { + /** + * A data-flow node that performs SQL sanitization. + */ + abstract class Range extends DataFlow::Node { } +} /** * A data-flow node that executes a regular expression. diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.qll b/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.qll index 8a07e211a21..70744d6fcc8 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.qll @@ -99,4 +99,4 @@ module Sqlite3 { input = "Argument[0]" and output = "ReturnValue" and preservesValue = false } } -} \ No newline at end of file +} From 6fa9e13a2e76a15fbed57180fe49c9cd8f3fe1c4 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 1 Jun 2023 16:27:20 +0100 Subject: [PATCH 277/739] Ruby: update TaintStep output --- ruby/ql/test/library-tests/dataflow/local/TaintStep.expected | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index 2bfe1e9a9ab..e75c17e818e 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -2814,7 +2814,10 @@ | file://:0:0:0:0 | parameter position 0 of File.realdirpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realdirpath | | file://:0:0:0:0 | parameter position 0 of File.realpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realpath | | file://:0:0:0:0 | parameter position 0 of Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] | +| file://:0:0:0:0 | parameter position 0 of Mysql2::Client.escape() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.escape() | +| file://:0:0:0:0 | parameter position 0 of Mysql2::Client.new() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.new() | | file://:0:0:0:0 | parameter position 0 of PG.new() | file://:0:0:0:0 | [summary] to write: return (return) in PG.new() | +| file://:0:0:0:0 | parameter position 0 of SQLite3::Database.quote() | file://:0:0:0:0 | [summary] to write: return (return) in SQLite3::Database.quote() | | file://:0:0:0:0 | parameter position 0 of Sequel.connect | file://:0:0:0:0 | [summary] to write: return (return) in Sequel.connect | | file://:0:0:0:0 | parameter position 0 of String.try_convert | file://:0:0:0:0 | [summary] to write: return (return) in String.try_convert | | file://:0:0:0:0 | parameter position 0 of \| | file://:0:0:0:0 | [summary] read: argument position 0.any element in \| | From 7290e2bfd9cb2e469ef152864588530801ff1192 Mon Sep 17 00:00:00 2001 From: Nick Rolfe <nickrolfe@github.com> Date: Thu, 1 Jun 2023 17:06:34 +0100 Subject: [PATCH 278/739] Java: avoid call to Location.toString() --- .../Implementation Hiding/ExposeRepresentation.ql | 2 +- .../ExposeRepresentation.expected | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql b/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql index 9f24744fa0c..2889de0b5cf 100644 --- a/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql +++ b/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql @@ -128,4 +128,4 @@ where not exists(Property p | p.getBackingField() = f) select c, c.getName() + " exposes the internal representation stored in field " + f.getName() + - ". The value may be modified $@.", why.getLocation(), whyText + ". The value may be modified $@.", why, whyText diff --git a/java/ql/test/query-tests/ExposeRepresentation/ExposeRepresentation.expected b/java/ql/test/query-tests/ExposeRepresentation/ExposeRepresentation.expected index 0056c25bb53..3162056ab42 100644 --- a/java/ql/test/query-tests/ExposeRepresentation/ExposeRepresentation.expected +++ b/java/ql/test/query-tests/ExposeRepresentation/ExposeRepresentation.expected @@ -1,7 +1,7 @@ -| ExposesRep.java:11:19:11:28 | getStrings | getStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.java:5:5:5:19 | User.java:5:5:5:19 | after this call to getStrings | -| ExposesRep.java:11:19:11:28 | getStrings | getStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.java:13:12:13:26 | User.java:13:12:13:26 | after this call to getStrings | -| ExposesRep.java:11:19:11:28 | getStrings | getStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.java:38:12:38:26 | User.java:38:12:38:26 | after this call to getStrings | -| ExposesRep.java:13:30:13:41 | getStringMap | getStringMap exposes the internal representation stored in field stringMap. The value may be modified $@. | User.java:9:5:9:21 | User.java:9:5:9:21 | after this call to getStringMap | -| ExposesRep.java:17:15:17:24 | setStrings | setStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.java:22:5:22:6 | User.java:22:5:22:6 | through the variable ss | -| ExposesRep.java:21:15:21:26 | setStringMap | setStringMap exposes the internal representation stored in field stringMap. The value may be modified $@. | User.java:27:5:27:5 | User.java:27:5:27:5 | through the variable m | -| ExposesRep.java:29:14:29:21 | getArray | getArray exposes the internal representation stored in field array. The value may be modified $@. | User.java:31:5:31:18 | User.java:31:5:31:18 | after this call to getArray | +| ExposesRep.java:11:19:11:28 | getStrings | getStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.java:5:5:5:19 | getStrings(...) | after this call to getStrings | +| ExposesRep.java:11:19:11:28 | getStrings | getStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.java:13:12:13:26 | getStrings(...) | after this call to getStrings | +| ExposesRep.java:11:19:11:28 | getStrings | getStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.java:38:12:38:26 | getStrings(...) | after this call to getStrings | +| ExposesRep.java:13:30:13:41 | getStringMap | getStringMap exposes the internal representation stored in field stringMap. The value may be modified $@. | User.java:9:5:9:21 | getStringMap(...) | after this call to getStringMap | +| ExposesRep.java:17:15:17:24 | setStrings | setStrings exposes the internal representation stored in field strings. The value may be modified $@. | User.java:22:5:22:6 | ss | through the variable ss | +| ExposesRep.java:21:15:21:26 | setStringMap | setStringMap exposes the internal representation stored in field stringMap. The value may be modified $@. | User.java:27:5:27:5 | m | through the variable m | +| ExposesRep.java:29:14:29:21 | getArray | getArray exposes the internal representation stored in field array. The value may be modified $@. | User.java:31:5:31:18 | getArray(...) | after this call to getArray | From 6722892828f03977688a0f157854dfa6879d322c Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 12 May 2023 09:02:56 -0400 Subject: [PATCH 279/739] Java: switch 'android-widget' source kind to 'remote' --- java/ql/lib/ext/android.widget.model.yml | 2 +- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- java/ql/lib/semmle/code/java/frameworks/android/Widget.qll | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/ext/android.widget.model.yml b/java/ql/lib/ext/android.widget.model.yml index ef4b015700a..aa6222c77d2 100644 --- a/java/ql/lib/ext/android.widget.model.yml +++ b/java/ql/lib/ext/android.widget.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sourceModel data: - - ["android.widget", "EditText", True, "getText", "", "", "ReturnValue", "android-widget", "manual"] + - ["android.widget", "EditText", True, "getText", "", "", "ReturnValue", "remote", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 4cb21496f5f..629b7140f19 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -286,7 +286,7 @@ module ModelValidation { ) or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and + not kind = ["remote", "contentprovider", "android-external-storage-dir"] and not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." ) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll index 81c34179c15..506f11a9112 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll @@ -5,7 +5,7 @@ private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources private class DefaultAndroidWidgetSources extends RemoteFlowSource { - DefaultAndroidWidgetSources() { sourceNode(this, "android-widget") } + DefaultAndroidWidgetSources() { sourceNode(this, "remote") } override string getSourceType() { result = "Android widget source" } } From d035a29b4dcd99591463c1c5e54900069c05d302 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 12 May 2023 09:23:42 -0400 Subject: [PATCH 280/739] Java: update source kind documentation --- .../customizing-library-models-for-java.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index baa93e8eb0a..262a608f391 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -315,7 +315,7 @@ The following source kinds are supported: Below is an enumeration of the remaining source kinds, but they are out of scope for this documentation: -- **contentprovider**, **android-widget**, **android-external-storage-dir**. +- **contentprovider**, **android-external-storage-dir**. sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 119b446dbcf0114d570caa458f6d707d9654df4f Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 12 May 2023 09:29:37 -0400 Subject: [PATCH 281/739] Java: add change note --- .../2023-05-12-androidwidget-source-kind-to-remote.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-05-12-androidwidget-source-kind-to-remote.md diff --git a/java/ql/lib/change-notes/2023-05-12-androidwidget-source-kind-to-remote.md b/java/ql/lib/change-notes/2023-05-12-androidwidget-source-kind-to-remote.md new file mode 100644 index 00000000000..7a2714a6527 --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-12-androidwidget-source-kind-to-remote.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working. From 5700a6eea4b9ffff98e929714e1f7ffafcf4cc5b Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 12 May 2023 09:48:50 -0400 Subject: [PATCH 282/739] Java: remove DefaultAndroidWidgetSources class --- java/ql/lib/semmle/code/java/frameworks/android/Widget.qll | 6 ------ 1 file changed, 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll index 506f11a9112..9cb39ed83a7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll @@ -4,12 +4,6 @@ import java private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSources -private class DefaultAndroidWidgetSources extends RemoteFlowSource { - DefaultAndroidWidgetSources() { sourceNode(this, "remote") } - - override string getSourceType() { result = "Android widget source" } -} - private class EditableToStringStep extends AdditionalTaintStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { exists(MethodAccess ma | From de15013715b39f2c4e9c05680601bc2d09c81f43 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 12 May 2023 09:49:58 -0400 Subject: [PATCH 283/739] Java: remove RemoteFlowSources module --- java/ql/lib/semmle/code/java/dataflow/FlowSources.qll | 7 ------- 1 file changed, 7 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index e10cd0db708..d26aa5d35f6 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -36,13 +36,6 @@ abstract class RemoteFlowSource extends DataFlow::Node { abstract string getSourceType(); } -/** - * A module for importing frameworks that define remote flow sources. - */ -private module RemoteFlowSources { - private import semmle.code.java.frameworks.android.Widget -} - private class ExternalRemoteFlowSource extends RemoteFlowSource { ExternalRemoteFlowSource() { sourceNode(this, "remote") } From 06c83ee14da3b7c764fa044e8b6dc7157247f9e3 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 19 May 2023 11:18:10 -0400 Subject: [PATCH 284/739] Java: add error message for deprecated sink kinds to 'getInvalidModelKind' --- .../code/java/dataflow/ExternalFlow.qll | 66 ++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 5776d64f402..f933a615c83 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -265,13 +265,72 @@ module ModelValidation { ) } + private class DeprecatedSinkKind extends string { + DeprecatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", + "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", + "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", + "jdbc-url" + ] + } + + private string replacementKind() { + this = "sql" and result = "\"sql-injection\"" + or + this = "url-redirect" and result = "\"url-redirection\"" + or + this = "xpath" and result = "\"xpath-injection\"" + or + this = "ssti" and result = "\"template-injection\"" + or + this = "logging" and result = "\"log-injection\"" + or + this = "groovy" and result = "\"groovy-injection\"" + or + this = "jexl" and result = "\"jexl-injection\"" + or + this = "mvel" and result = "\"mvel-injection\"" + or + this = "xslt" and result = "\"xslt-injection\"" + or + this = "ldap" and result = "\"ldap-injection\"" + or + this = "pending-intent-sent" and result = "\"pending-intents\"" + or + this = "intent-start" and result = "\"intent-redirection\"" + or + this = "set-hostname-verifier" and result = "\"hostname-verification\"" + or + this = "header-splitting" and result = "\"response-splitting\"" + or + this = "xss" and result = "\"html-injection\" or \"js-injection\"" + or + this = "write-file" and result = "\"file-content-store\"" + or + this = "create-file" and result = "\"path-injection\"" + or + this = "read-file" and result = "\"path-injection\"" + or + this = "open-url" and result = "\"request-forgery\"" + or + this = "jdbc-url" and result = "\"request-forgery\"" + } + + string deprecationMessage() { + result = + "The kind \"" + this + "\" is deprecated. Use " + this.replacementKind() + " instead." + } + } + private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | + exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind = [ "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", @@ -283,7 +342,10 @@ module ModelValidation { ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and - result = "Invalid kind \"" + kind + "\" in sink model." + msg = "Invalid kind \"" + kind + "\" in sink model." and + if kind instanceof DeprecatedSinkKind + then result = msg + " " + kind.(DeprecatedSinkKind).deprecationMessage() + else result = msg ) or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | From b3d218a50322041d2c4eb275a66afe188e53c702 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 22 May 2023 10:15:34 -0400 Subject: [PATCH 285/739] Java: condense 'replacementKind' code --- .../code/java/dataflow/ExternalFlow.qll | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index f933a615c83..1b0ce54af38 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -277,50 +277,35 @@ module ModelValidation { } private string replacementKind() { - this = "sql" and result = "\"sql-injection\"" + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap"] and + result = this + "-injection" or - this = "url-redirect" and result = "\"url-redirection\"" + this = "url-redirect" and result = "url-redirection" or - this = "xpath" and result = "\"xpath-injection\"" + this = "ssti" and result = "template-injection" or - this = "ssti" and result = "\"template-injection\"" + this = "logging" and result = "log-injection" or - this = "logging" and result = "\"log-injection\"" + this = "pending-intent-sent" and result = "pending-intents" or - this = "groovy" and result = "\"groovy-injection\"" + this = "intent-start" and result = "intent-redirection" or - this = "jexl" and result = "\"jexl-injection\"" + this = "set-hostname-verifier" and result = "hostname-verification" or - this = "mvel" and result = "\"mvel-injection\"" + this = "header-splitting" and result = "response-splitting" or - this = "xslt" and result = "\"xslt-injection\"" + this = "xss" and result = "html-injection\" or \"js-injection" or - this = "ldap" and result = "\"ldap-injection\"" + this = "write-file" and result = "file-content-store" or - this = "pending-intent-sent" and result = "\"pending-intents\"" + this = ["create-file", "read-file"] and result = "path-injection" or - this = "intent-start" and result = "\"intent-redirection\"" - or - this = "set-hostname-verifier" and result = "\"hostname-verification\"" - or - this = "header-splitting" and result = "\"response-splitting\"" - or - this = "xss" and result = "\"html-injection\" or \"js-injection\"" - or - this = "write-file" and result = "\"file-content-store\"" - or - this = "create-file" and result = "\"path-injection\"" - or - this = "read-file" and result = "\"path-injection\"" - or - this = "open-url" and result = "\"request-forgery\"" - or - this = "jdbc-url" and result = "\"request-forgery\"" + this = ["open-url", "jdbc-url"] and result = "request-forgery" } string deprecationMessage() { result = - "The kind \"" + this + "\" is deprecated. Use " + this.replacementKind() + " instead." + "The kind \"" + this + "\" is deprecated. Use \"" + this.replacementKind() + "\" instead." } } From 0355b78f13845ab90ce109dae58f5f5ce4a9bd83 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 22 May 2023 10:34:56 -0400 Subject: [PATCH 286/739] Java: add deprecation deletion comment --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 1b0ce54af38..0304e64398f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -247,6 +247,8 @@ module ModelValidation { ) } + /** + */ private string getInvalidModelOutput() { exists(string pred, AccessPath output, AccessPathToken part | sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source" @@ -328,6 +330,7 @@ module ModelValidation { not kind.matches("regex-use%") and not kind.matches("qltest%") and msg = "Invalid kind \"" + kind + "\" in sink model." and + // The deprecation part of this message can be deleted after June 1st, 2024. if kind instanceof DeprecatedSinkKind then result = msg + " " + kind.(DeprecatedSinkKind).deprecationMessage() else result = msg From d10857fbdb8991bd7630fb7eae85e67089a1f47a Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 22 May 2023 10:39:59 -0400 Subject: [PATCH 287/739] Java: fix typo blank qldoc --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 0304e64398f..cebf330c8e4 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -247,8 +247,6 @@ module ModelValidation { ) } - /** - */ private string getInvalidModelOutput() { exists(string pred, AccessPath output, AccessPathToken part | sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source" From b8cedfa817b6b4bc8d56cad8d3cf6faf4da69b01 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 1 Jun 2023 13:30:27 -0400 Subject: [PATCH 288/739] Java: switch 'deprecated' to 'outdated' --- .../lib/semmle/code/java/dataflow/ExternalFlow.qll | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index cebf330c8e4..ca662ee5610 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -265,8 +265,8 @@ module ModelValidation { ) } - private class DeprecatedSinkKind extends string { - DeprecatedSinkKind() { + private class OutdatedSinkKind extends string { + OutdatedSinkKind() { this = [ "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", @@ -303,9 +303,9 @@ module ModelValidation { this = ["open-url", "jdbc-url"] and result = "request-forgery" } - string deprecationMessage() { + string outdatedMessage() { result = - "The kind \"" + this + "\" is deprecated. Use \"" + this.replacementKind() + "\" instead." + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." } } @@ -328,9 +328,9 @@ module ModelValidation { not kind.matches("regex-use%") and not kind.matches("qltest%") and msg = "Invalid kind \"" + kind + "\" in sink model." and - // The deprecation part of this message can be deleted after June 1st, 2024. - if kind instanceof DeprecatedSinkKind - then result = msg + " " + kind.(DeprecatedSinkKind).deprecationMessage() + // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. + if kind instanceof OutdatedSinkKind + then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() else result = msg ) or From f4b68fb8c3c7c821770d99c7966e6421a2754986 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 21:51:43 +0200 Subject: [PATCH 289/739] bump TypeScript to stable version --- javascript/extractor/lib/typescript/package.json | 2 +- javascript/extractor/lib/typescript/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index cb053bb0e6f..3190b683d34 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "5.1.1-rc" + "typescript": "5.1.3" }, "scripts": { "build": "tsc --project tsconfig.json", diff --git a/javascript/extractor/lib/typescript/yarn.lock b/javascript/extractor/lib/typescript/yarn.lock index 3b0a9476df6..355c257cf69 100644 --- a/javascript/extractor/lib/typescript/yarn.lock +++ b/javascript/extractor/lib/typescript/yarn.lock @@ -7,7 +7,7 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.3.tgz#f0b991c32cfc6a4e7f3399d6cb4b8cf9a0315014" integrity sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw== -typescript@5.1.1-rc: - version "5.1.1-rc" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.1-rc.tgz#7be6e85bb4ad36e07e0125e501eb08ed3a6e3769" - integrity sha512-+yHTPe5QCxw5cgN+B81z+k65xTHcwNCRwJN7OGVUe3srPULTZHF7J9QCgrptL7F8mrO7gmsert7XrMksAjutRw== +typescript@5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" + integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== From 97afa5733b86ba10066cec4a5507b08c39d9a772 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 21:52:14 +0200 Subject: [PATCH 290/739] add support for namespaced JSX attributes --- .../ts/extractor/TypeScriptASTConverter.java | 7 +- .../test/library-tests/JSX/printAst.expected | 104 ++++++++++++++++++ .../ql/test/library-tests/JSX/tests.expected | 9 ++ .../ql/test/library-tests/JSX/tstest.tsx | 12 ++ 4 files changed, 131 insertions(+), 1 deletion(-) diff --git a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java index e34d552b777..7b68106bb3f 100644 --- a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java @@ -1552,8 +1552,13 @@ public class TypeScriptASTConverter { } private Node convertJsxAttribute(JsonObject node, SourceLocation loc) throws ParseError { + JsonObject nameNode = node.get("name").getAsJsonObject(); + if (nameNode.get("name") != null) { + // it's a namespaced attribute + nameNode = nameNode.get("name").getAsJsonObject(); + } return new JSXAttribute( - loc, convertJSXName(convertChild(node, "name")), convertChild(node, "initializer")); + loc, convertJSXName(((Expression)convertNode(nameNode, null))), convertChild(node, "initializer")); // 2 } private Node convertJsxClosingElement(JsonObject node, SourceLocation loc) throws ParseError { diff --git a/javascript/ql/test/library-tests/JSX/printAst.expected b/javascript/ql/test/library-tests/JSX/printAst.expected index 11bf254a890..a34e194cca8 100644 --- a/javascript/ql/test/library-tests/JSX/printAst.expected +++ b/javascript/ql/test/library-tests/JSX/printAst.expected @@ -3,10 +3,14 @@ nodes | file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | | file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | | file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | +| file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | +| file://:0:0:0:0 | (Attributes) | semmle.label | (Attributes) | | file://:0:0:0:0 | (Body) | semmle.label | (Body) | | file://:0:0:0:0 | (Body) | semmle.label | (Body) | | file://:0:0:0:0 | (Body) | semmle.label | (Body) | | file://:0:0:0:0 | (Body) | semmle.label | (Body) | +| file://:0:0:0:0 | (Body) | semmle.label | (Body) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | tst.js:1:1:1:32 | [DeclStmt] var href = ... | semmle.label | [DeclStmt] var href = ... | | tst.js:1:1:1:32 | [DeclStmt] var href = ... | semmle.order | 1 | | tst.js:1:5:1:8 | [VarDecl] href | semmle.label | [VarDecl] href | @@ -119,6 +123,42 @@ nodes | tstest.tsx:7:33:7:38 | [JsxElement] <Foo/> | semmle.label | [JsxElement] <Foo/> | | tstest.tsx:7:34:7:36 | [VarRef] Foo | semmle.label | [VarRef] Foo | | tstest.tsx:7:40:7:49 | [Literal] more text | semmle.label | [Literal] more text | +| tstest.tsx:10:1:10:30 | [DeclStmt] const x = ... | semmle.label | [DeclStmt] const x = ... | +| tstest.tsx:10:1:10:30 | [DeclStmt] const x = ... | semmle.order | 15 | +| tstest.tsx:10:7:10:7 | [VarDecl] x | semmle.label | [VarDecl] x | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = <Ba ... llo" /> | semmle.label | [VariableDeclarator] x = <Ba ... llo" /> | +| tstest.tsx:10:11:10:29 | [JsxElement] <Bar a:b="hello" /> | semmle.label | [JsxElement] <Bar a:b="hello" /> | +| tstest.tsx:10:12:10:14 | [VarRef] Bar | semmle.label | [VarRef] Bar | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | semmle.label | [JsxAttribute] a:b="hello" | +| tstest.tsx:10:18:10:18 | [Label] b | semmle.label | [Label] b | +| tstest.tsx:10:20:10:26 | [Literal] "hello" | semmle.label | [Literal] "hello" | +| tstest.tsx:11:1:11:32 | [DeclStmt] const y = ... | semmle.label | [DeclStmt] const y = ... | +| tstest.tsx:11:1:11:32 | [DeclStmt] const y = ... | semmle.order | 16 | +| tstest.tsx:11:7:11:7 | [VarDecl] y | semmle.label | [VarDecl] y | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = <Ba ... llo" /> | semmle.label | [VariableDeclarator] y = <Ba ... llo" /> | +| tstest.tsx:11:11:11:31 | [JsxElement] <Bar a ... llo" /> | semmle.label | [JsxElement] <Bar a ... llo" /> | +| tstest.tsx:11:12:11:14 | [VarRef] Bar | semmle.label | [VarRef] Bar | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | semmle.label | [JsxAttribute] a : b="hello" | +| tstest.tsx:11:20:11:20 | [Label] b | semmle.label | [Label] b | +| tstest.tsx:11:22:11:28 | [Literal] "hello" | semmle.label | [Literal] "hello" | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | semmle.order | 17 | +| tstest.tsx:13:11:13:18 | [Identifier] BarProps | semmle.label | [Identifier] BarProps | +| tstest.tsx:14:5:14:9 | [Literal] "a:b" | semmle.label | [Literal] "a:b" | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | semmle.label | [FieldDeclaration] "a:b": string; | +| tstest.tsx:14:12:14:17 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | semmle.label | [FunctionDeclStmt] functio ... div>; } | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | semmle.order | 18 | +| tstest.tsx:17:10:17:12 | [VarDecl] Bar | semmle.label | [VarDecl] Bar | +| tstest.tsx:17:14:17:18 | [SimpleParameter] props | semmle.label | [SimpleParameter] props | +| tstest.tsx:17:21:17:28 | [LocalTypeAccess] BarProps | semmle.label | [LocalTypeAccess] BarProps | +| tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | semmle.label | [BlockStmt] { r ... div>; } | +| tstest.tsx:18:5:18:37 | [ReturnStmt] return ... </div>; | semmle.label | [ReturnStmt] return ... </div>; | +| tstest.tsx:18:12:18:36 | [JsxElement] <div>{p ... }</div> | semmle.label | [JsxElement] <div>{p ... }</div> | +| tstest.tsx:18:13:18:15 | [Label] div | semmle.label | [Label] div | +| tstest.tsx:18:18:18:22 | [VarRef] props | semmle.label | [VarRef] props | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | semmle.label | [IndexExpr] props["a:b"] | +| tstest.tsx:18:24:18:28 | [Literal] "a:b" | semmle.label | [Literal] "a:b" | edges | file://:0:0:0:0 | (Attributes) | tst.js:3:4:3:14 | [JsxAttribute] href={href} | semmle.label | 0 | | file://:0:0:0:0 | (Attributes) | tst.js:3:4:3:14 | [JsxAttribute] href={href} | semmle.order | 0 | @@ -136,6 +176,10 @@ edges | file://:0:0:0:0 | (Attributes) | tstest.tsx:3:32:3:45 | [JsxAttribute] {...linkTypes} | semmle.order | 2 | | file://:0:0:0:0 | (Attributes) | tstest.tsx:4:25:4:33 | [JsxAttribute] foo="bar" | semmle.label | 0 | | file://:0:0:0:0 | (Attributes) | tstest.tsx:4:25:4:33 | [JsxAttribute] foo="bar" | semmle.order | 0 | +| file://:0:0:0:0 | (Attributes) | tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | semmle.label | 0 | +| file://:0:0:0:0 | (Attributes) | tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | semmle.order | 0 | +| file://:0:0:0:0 | (Attributes) | tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | semmle.label | 0 | +| file://:0:0:0:0 | (Attributes) | tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | semmle.order | 0 | | file://:0:0:0:0 | (Body) | tst.js:3:47:3:54 | [Literal] Link to | semmle.label | 0 | | file://:0:0:0:0 | (Body) | tst.js:3:47:3:54 | [Literal] Link to | semmle.order | 0 | | file://:0:0:0:0 | (Body) | tst.js:3:56:3:59 | [VarRef] href | semmle.label | 1 | @@ -164,6 +208,10 @@ edges | file://:0:0:0:0 | (Body) | tstest.tsx:7:33:7:38 | [JsxElement] <Foo/> | semmle.order | 1 | | file://:0:0:0:0 | (Body) | tstest.tsx:7:40:7:49 | [Literal] more text | semmle.label | 2 | | file://:0:0:0:0 | (Body) | tstest.tsx:7:40:7:49 | [Literal] more text | semmle.order | 2 | +| file://:0:0:0:0 | (Body) | tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | semmle.label | 0 | +| file://:0:0:0:0 | (Body) | tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tstest.tsx:17:14:17:18 | [SimpleParameter] props | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tstest.tsx:17:14:17:18 | [SimpleParameter] props | semmle.order | 0 | | tst.js:1:1:1:32 | [DeclStmt] var href = ... | tst.js:1:5:1:31 | [VariableDeclarator] href = ... le.com" | semmle.label | 1 | | tst.js:1:1:1:32 | [DeclStmt] var href = ... | tst.js:1:5:1:31 | [VariableDeclarator] href = ... le.com" | semmle.order | 1 | | tst.js:1:5:1:31 | [VariableDeclarator] href = ... le.com" | tst.js:1:5:1:8 | [VarDecl] href | semmle.label | 1 | @@ -304,5 +352,61 @@ edges | tstest.tsx:7:16:7:52 | [JsxFragment] <> frag ... ext </> | file://:0:0:0:0 | (Body) | semmle.order | 1 | | tstest.tsx:7:33:7:38 | [JsxElement] <Foo/> | tstest.tsx:7:34:7:36 | [VarRef] Foo | semmle.label | 0 | | tstest.tsx:7:33:7:38 | [JsxElement] <Foo/> | tstest.tsx:7:34:7:36 | [VarRef] Foo | semmle.order | 0 | +| tstest.tsx:10:1:10:30 | [DeclStmt] const x = ... | tstest.tsx:10:7:10:29 | [VariableDeclarator] x = <Ba ... llo" /> | semmle.label | 1 | +| tstest.tsx:10:1:10:30 | [DeclStmt] const x = ... | tstest.tsx:10:7:10:29 | [VariableDeclarator] x = <Ba ... llo" /> | semmle.order | 1 | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = <Ba ... llo" /> | tstest.tsx:10:7:10:7 | [VarDecl] x | semmle.label | 1 | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = <Ba ... llo" /> | tstest.tsx:10:7:10:7 | [VarDecl] x | semmle.order | 1 | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = <Ba ... llo" /> | tstest.tsx:10:11:10:29 | [JsxElement] <Bar a:b="hello" /> | semmle.label | 2 | +| tstest.tsx:10:7:10:29 | [VariableDeclarator] x = <Ba ... llo" /> | tstest.tsx:10:11:10:29 | [JsxElement] <Bar a:b="hello" /> | semmle.order | 2 | +| tstest.tsx:10:11:10:29 | [JsxElement] <Bar a:b="hello" /> | file://:0:0:0:0 | (Attributes) | semmle.label | 2 | +| tstest.tsx:10:11:10:29 | [JsxElement] <Bar a:b="hello" /> | file://:0:0:0:0 | (Attributes) | semmle.order | 2 | +| tstest.tsx:10:11:10:29 | [JsxElement] <Bar a:b="hello" /> | tstest.tsx:10:12:10:14 | [VarRef] Bar | semmle.label | 0 | +| tstest.tsx:10:11:10:29 | [JsxElement] <Bar a:b="hello" /> | tstest.tsx:10:12:10:14 | [VarRef] Bar | semmle.order | 0 | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | tstest.tsx:10:18:10:18 | [Label] b | semmle.label | 1 | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | tstest.tsx:10:18:10:18 | [Label] b | semmle.order | 1 | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | tstest.tsx:10:20:10:26 | [Literal] "hello" | semmle.label | 2 | +| tstest.tsx:10:16:10:26 | [JsxAttribute] a:b="hello" | tstest.tsx:10:20:10:26 | [Literal] "hello" | semmle.order | 2 | +| tstest.tsx:11:1:11:32 | [DeclStmt] const y = ... | tstest.tsx:11:7:11:31 | [VariableDeclarator] y = <Ba ... llo" /> | semmle.label | 1 | +| tstest.tsx:11:1:11:32 | [DeclStmt] const y = ... | tstest.tsx:11:7:11:31 | [VariableDeclarator] y = <Ba ... llo" /> | semmle.order | 1 | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = <Ba ... llo" /> | tstest.tsx:11:7:11:7 | [VarDecl] y | semmle.label | 1 | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = <Ba ... llo" /> | tstest.tsx:11:7:11:7 | [VarDecl] y | semmle.order | 1 | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = <Ba ... llo" /> | tstest.tsx:11:11:11:31 | [JsxElement] <Bar a ... llo" /> | semmle.label | 2 | +| tstest.tsx:11:7:11:31 | [VariableDeclarator] y = <Ba ... llo" /> | tstest.tsx:11:11:11:31 | [JsxElement] <Bar a ... llo" /> | semmle.order | 2 | +| tstest.tsx:11:11:11:31 | [JsxElement] <Bar a ... llo" /> | file://:0:0:0:0 | (Attributes) | semmle.label | 2 | +| tstest.tsx:11:11:11:31 | [JsxElement] <Bar a ... llo" /> | file://:0:0:0:0 | (Attributes) | semmle.order | 2 | +| tstest.tsx:11:11:11:31 | [JsxElement] <Bar a ... llo" /> | tstest.tsx:11:12:11:14 | [VarRef] Bar | semmle.label | 0 | +| tstest.tsx:11:11:11:31 | [JsxElement] <Bar a ... llo" /> | tstest.tsx:11:12:11:14 | [VarRef] Bar | semmle.order | 0 | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | tstest.tsx:11:20:11:20 | [Label] b | semmle.label | 1 | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | tstest.tsx:11:20:11:20 | [Label] b | semmle.order | 1 | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | tstest.tsx:11:22:11:28 | [Literal] "hello" | semmle.label | 2 | +| tstest.tsx:11:16:11:28 | [JsxAttribute] a : b="hello" | tstest.tsx:11:22:11:28 | [Literal] "hello" | semmle.order | 2 | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | tstest.tsx:13:11:13:18 | [Identifier] BarProps | semmle.label | 1 | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | tstest.tsx:13:11:13:18 | [Identifier] BarProps | semmle.order | 1 | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | semmle.label | 2 | +| tstest.tsx:13:1:15:1 | [InterfaceDeclaration,TypeDefinition] interfa ... ring; } | tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | semmle.order | 2 | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | tstest.tsx:14:5:14:9 | [Literal] "a:b" | semmle.label | 1 | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | tstest.tsx:14:5:14:9 | [Literal] "a:b" | semmle.order | 1 | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | tstest.tsx:14:12:14:17 | [KeywordTypeExpr] string | semmle.label | 2 | +| tstest.tsx:14:5:14:18 | [FieldDeclaration] "a:b": string; | tstest.tsx:14:12:14:17 | [KeywordTypeExpr] string | semmle.order | 2 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | tstest.tsx:17:10:17:12 | [VarDecl] Bar | semmle.label | 0 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | tstest.tsx:17:10:17:12 | [VarDecl] Bar | semmle.order | 0 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | semmle.label | 5 | +| tstest.tsx:17:1:19:1 | [FunctionDeclStmt] functio ... div>; } | tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | semmle.order | 5 | +| tstest.tsx:17:14:17:18 | [SimpleParameter] props | tstest.tsx:17:21:17:28 | [LocalTypeAccess] BarProps | semmle.label | -2 | +| tstest.tsx:17:14:17:18 | [SimpleParameter] props | tstest.tsx:17:21:17:28 | [LocalTypeAccess] BarProps | semmle.order | -2 | +| tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | tstest.tsx:18:5:18:37 | [ReturnStmt] return ... </div>; | semmle.label | 1 | +| tstest.tsx:17:31:19:1 | [BlockStmt] { r ... div>; } | tstest.tsx:18:5:18:37 | [ReturnStmt] return ... </div>; | semmle.order | 1 | +| tstest.tsx:18:5:18:37 | [ReturnStmt] return ... </div>; | tstest.tsx:18:12:18:36 | [JsxElement] <div>{p ... }</div> | semmle.label | 1 | +| tstest.tsx:18:5:18:37 | [ReturnStmt] return ... </div>; | tstest.tsx:18:12:18:36 | [JsxElement] <div>{p ... }</div> | semmle.order | 1 | +| tstest.tsx:18:12:18:36 | [JsxElement] <div>{p ... }</div> | file://:0:0:0:0 | (Body) | semmle.label | 1 | +| tstest.tsx:18:12:18:36 | [JsxElement] <div>{p ... }</div> | file://:0:0:0:0 | (Body) | semmle.order | 1 | +| tstest.tsx:18:12:18:36 | [JsxElement] <div>{p ... }</div> | tstest.tsx:18:13:18:15 | [Label] div | semmle.label | 0 | +| tstest.tsx:18:12:18:36 | [JsxElement] <div>{p ... }</div> | tstest.tsx:18:13:18:15 | [Label] div | semmle.order | 0 | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | tstest.tsx:18:18:18:22 | [VarRef] props | semmle.label | 1 | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | tstest.tsx:18:18:18:22 | [VarRef] props | semmle.order | 1 | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | tstest.tsx:18:24:18:28 | [Literal] "a:b" | semmle.label | 2 | +| tstest.tsx:18:18:18:29 | [IndexExpr] props["a:b"] | tstest.tsx:18:24:18:28 | [Literal] "a:b" | semmle.order | 2 | graphProperties | semmle.graphKind | tree | diff --git a/javascript/ql/test/library-tests/JSX/tests.expected b/javascript/ql/test/library-tests/JSX/tests.expected index 974d5608802..50b00601fbe 100644 --- a/javascript/ql/test/library-tests/JSX/tests.expected +++ b/javascript/ql/test/library-tests/JSX/tests.expected @@ -3,6 +3,7 @@ htmlElements | tst.js:6:1:6:10 | <Foo-Bar/> | | tstest.tsx:3:1:3:106 | <a href ... */}</a> | | tstest.tsx:6:1:6:10 | <Foo-Bar/> | +| tstest.tsx:18:12:18:36 | <div>{p ... }</div> | jsxElementAttribute | tst.js:3:1:3:106 | <a href ... */}</a> | 0 | tst.js:3:4:3:14 | href={href} | | tst.js:3:1:3:106 | <a href ... */}</a> | 1 | tst.js:3:16:3:30 | target="_blank" | @@ -12,6 +13,8 @@ jsxElementAttribute | tstest.tsx:3:1:3:106 | <a href ... */}</a> | 1 | tstest.tsx:3:16:3:30 | target="_blank" | | tstest.tsx:3:1:3:106 | <a href ... */}</a> | 2 | tstest.tsx:3:32:3:45 | {...linkTypes} | | tstest.tsx:4:1:4:35 | <MyComp ... "bar"/> | 0 | tstest.tsx:4:25:4:33 | foo="bar" | +| tstest.tsx:10:11:10:29 | <Bar a:b="hello" /> | 0 | tstest.tsx:10:16:10:26 | a:b="hello" | +| tstest.tsx:11:11:11:31 | <Bar a ... llo" /> | 0 | tstest.tsx:11:16:11:28 | a : b="hello" | jsxElementAttributeName | tst.js:3:1:3:106 | <a href ... */}</a> | 0 | href | | tst.js:3:1:3:106 | <a href ... */}</a> | 1 | target | @@ -19,6 +22,8 @@ jsxElementAttributeName | tstest.tsx:3:1:3:106 | <a href ... */}</a> | 0 | href | | tstest.tsx:3:1:3:106 | <a href ... */}</a> | 1 | target | | tstest.tsx:4:1:4:35 | <MyComp ... "bar"/> | 0 | foo | +| tstest.tsx:10:11:10:29 | <Bar a:b="hello" /> | 0 | b | +| tstest.tsx:11:11:11:31 | <Bar a ... llo" /> | 0 | b | jsxElementBody | tst.js:3:1:3:106 | <a href ... */}</a> | 0 | tst.js:3:47:3:54 | Link to | | tst.js:3:1:3:106 | <a href ... */}</a> | 1 | tst.js:3:56:3:59 | href | @@ -28,6 +33,7 @@ jsxElementBody | tstest.tsx:3:1:3:106 | <a href ... */}</a> | 1 | tstest.tsx:3:56:3:59 | href | | tstest.tsx:3:1:3:106 | <a href ... */}</a> | 2 | tstest.tsx:3:61:3:62 | . | | tstest.tsx:3:1:3:106 | <a href ... */}</a> | 3 | tstest.tsx:3:63:3:102 | {/*TODO ... text*/} | +| tstest.tsx:18:12:18:36 | <div>{p ... }</div> | 0 | tstest.tsx:18:18:18:29 | props["a:b"] | jsxElementName | tst.js:3:1:3:106 | <a href ... */}</a> | tst.js:3:2:3:2 | a | a | | tst.js:4:1:4:35 | <MyComp ... "bar"/> | tst.js:4:2:4:23 | MyCompo ... ncyLink | MyComponents.FancyLink | @@ -39,6 +45,9 @@ jsxElementName | tstest.tsx:5:1:5:6 | <Foo/> | tstest.tsx:5:2:5:4 | Foo | Foo | | tstest.tsx:6:1:6:10 | <Foo-Bar/> | tstest.tsx:6:2:6:8 | Foo-Bar | Foo-Bar | | tstest.tsx:7:33:7:38 | <Foo/> | tstest.tsx:7:34:7:36 | Foo | Foo | +| tstest.tsx:10:11:10:29 | <Bar a:b="hello" /> | tstest.tsx:10:12:10:14 | Bar | Bar | +| tstest.tsx:11:11:11:31 | <Bar a ... llo" /> | tstest.tsx:11:12:11:14 | Bar | Bar | +| tstest.tsx:18:12:18:36 | <div>{p ... }</div> | tstest.tsx:18:13:18:15 | div | div | jsxFragments | tst.js:7:16:7:52 | <> frag ... ext </> | 0 | tst.js:7:18:7:32 | fragment text | | tst.js:7:16:7:52 | <> frag ... ext </> | 1 | tst.js:7:33:7:38 | <Foo/> | diff --git a/javascript/ql/test/library-tests/JSX/tstest.tsx b/javascript/ql/test/library-tests/JSX/tstest.tsx index c1011712e19..966d6ced2fd 100644 --- a/javascript/ql/test/library-tests/JSX/tstest.tsx +++ b/javascript/ql/test/library-tests/JSX/tstest.tsx @@ -5,3 +5,15 @@ var linkTypes = { rel: "noopener noreferrer" }; <Foo/>; // interpreted as a custom component because of capitalisation <Foo-Bar/>; // interpreted as an HTML element because of the dash var fragment = <> fragment text <Foo/> more text </> + +// Both of these are equivalent: +const x = <Bar a:b="hello" />; +const y = <Bar a : b="hello" />; + +interface BarProps { + "a:b": string; +} + +function Bar(props: BarProps) { + return <div>{props["a:b"]}</div>; +} \ No newline at end of file From 8eed1a95f638496442695bb584dd2a8e4aa42d6f Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 23:16:52 +0200 Subject: [PATCH 291/739] stop recursive fromRhs related to getLaterBaseAccess --- javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll index e9828e5bf25..35ba8cfe601 100644 --- a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll +++ b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll @@ -234,7 +234,8 @@ module AccessPath { or baseName = fromRhs(write.getBase(), root) or - baseName = fromRhs(GetLaterAccess::getLaterBaseAccess(write), root) + baseName = fromRhs(GetLaterAccess::getLaterBaseAccess(write), root) and + not baseName.matches("%.%") ) or exists(GlobalVariable var | From 1b44b59842d0d5d4d2d297b1cea94771584a3491 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 23:20:23 +0200 Subject: [PATCH 292/739] add stress test --- .../library-tests/GlobalAccessPaths/stress.js | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 javascript/ql/test/library-tests/GlobalAccessPaths/stress.js diff --git a/javascript/ql/test/library-tests/GlobalAccessPaths/stress.js b/javascript/ql/test/library-tests/GlobalAccessPaths/stress.js new file mode 100644 index 00000000000..198ccf6e8e2 --- /dev/null +++ b/javascript/ql/test/library-tests/GlobalAccessPaths/stress.js @@ -0,0 +1,33 @@ + +// stress test for global access path computation +var MyObject = {} +MyObject.Foo1 = { inner: MyObject }; +MyObject.Foo2 = { inner: MyObject }; +MyObject.Foo3 = { inner: MyObject }; +MyObject.Foo4 = { inner: MyObject }; +MyObject.Foo5 = { inner: MyObject }; +MyObject.Foo6 = { inner: MyObject }; +MyObject.Foo7 = { inner: MyObject }; +MyObject.Foo8 = { inner: MyObject }; +MyObject.Foo9 = { inner: MyObject }; +MyObject.Fooa = { inner: MyObject }; +MyObject.Foob = { inner: MyObject }; +MyObject.Fooc = { inner: MyObject }; +MyObject.Food = { inner: MyObject }; +MyObject.Fooe = { inner: MyObject }; +MyObject.Foof = { inner: MyObject }; +MyObject.Foog = { inner: MyObject }; +MyObject.Fooh = { inner: MyObject }; +MyObject.Fooi = { inner: MyObject }; +MyObject.Fooj = { inner: MyObject }; +MyObject.Fook = { inner: MyObject }; +MyObject.Fool = { inner: MyObject }; +MyObject.Foom = { inner: MyObject }; +MyObject.Foon = { inner: MyObject }; +MyObject.Fooo = { inner: MyObject }; +MyObject.Foop = { inner: MyObject }; +MyObject.Fooq = { inner: MyObject }; +MyObject.Foor = { inner: MyObject }; +MyObject.Foos = { inner: MyObject }; +MyObject.Foot = { inner: MyObject }; +exports.MyObject = MyObject; \ No newline at end of file From ef7e9a674c034721562b2d5a996b879fe67a1108 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Jun 2023 00:16:55 +0000 Subject: [PATCH 293/739] Add changed framework coverage reports --- .../library-coverage/coverage.csv | 334 +++++++++--------- .../library-coverage/coverage.rst | 18 +- 2 files changed, 176 insertions(+), 176 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 0bd4f53a9a7..4e4b1ab7e1f 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -1,167 +1,167 @@ -package,sink,source,summary,sink:bean-validation,sink:create-file,sink:fragment-injection,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:read-file,sink:regex-use,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:ssti,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value -android.app,35,,103,,,11,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,18,85 -android.content,24,31,154,,,,,,,16,,,,,,,,,,,,,,,,,,,8,,,,,,,4,,27,,63,91 -android.database,59,,41,,,,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,41, -android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 -android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 -android.support.v4.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -android.util,6,16,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, -android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, -androidx.core.app,6,,95,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,12,83 -androidx.fragment.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -androidx.slice,2,5,88,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,5,,27,61 -cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -com.google.common.base,4,,87,,,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,63,24 -com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 -com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 -com.google.common.flogger,29,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,,, -com.google.common.io,8,,73,,2,,,,,,,,,,,,,,,5,,,,,,,,,,,,1,,,,,,,,72,1 -com.google.gson,,,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,14 -com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, -com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, -com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,,, -com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, -com.thoughtworks.xstream,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, -com.unboundid.ldap.sdk,17,,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,, -com.zaxxer.hikari,2,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,, -groovy.lang,26,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.text,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.util,5,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hudson,44,,16,,19,,,,,,,,,,,,,6,,17,,,,,,,,,,,,2,,,,,,,,16, -io.jsonwebtoken,,2,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,4, -io.netty.bootstrap,3,,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,, -io.netty.buffer,,,207,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,130,77 -io.netty.channel,9,2,,,,,,,,,,,,,,,,9,,,,,,,,,,,,,,,,,,,,,2,, -io.netty.handler.codec,4,13,259,,,,,,,,,,,,,,,3,,1,,,,,,,,,,,,,,,,,,,13,143,116 -io.netty.handler.ssl,2,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,, -io.netty.handler.stream,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, -io.netty.resolver,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -io.netty.util,2,,23,,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,21,2 -jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, -jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, -jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 -java.awt,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3 -java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,44,,45,,18,,,,,,,,,,,,,,,4,,,,,,,,,,,,22,,,,,,,,43,2 -java.lang,18,,92,,,,,,,,,,,,8,,,,,5,,4,,,1,,,,,,,,,,,,,,,56,36 -java.net,13,3,20,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,3,20, -java.nio,38,,31,,22,,,,,,,,,,,,,,,13,,,,,,,,,,,,3,,,,,,,,31, -java.sql,13,,3,,,,,,,,4,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,2,1 -java.util,44,,484,,,,,,,,,,,,34,,,,,,,,5,2,,1,2,,,,,,,,,,,,,44,440 -javafx.scene.web,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, -javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, -javax.imageio.stream,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, -javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -javax.management.remote,2,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.naming,7,,1,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,,1, -javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,, -javax.script,1,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, -javax.servlet,5,21,2,,,,,3,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, -javax.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, -javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -javax.ws.rs.core,3,,149,,,,,1,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 -javax.xml.transform,2,,6,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, -javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, -jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -kotlin,16,,1843,,11,,,,,,,,,,,,,2,,3,,,,,,,,,,,,,,,,,,,,1836,7 -net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, -ognl,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, -okhttp3,4,,47,,,,,,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,22,25 -org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.compress.archivers.tar,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4, -org.apache.commons.httpclient.util,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.commons.io,111,,560,,93,,,,,,,,,,,,,15,,1,,,,,,,,,,,,2,,,,,,,,546,14 -org.apache.commons.jelly,6,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl2,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl3,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,293,131 -org.apache.commons.logging,6,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.net,9,12,,,,,,,,,,,,,,,,6,,3,,,,,,,,,,,,,,,,,,,12,, -org.apache.commons.ognl,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 -org.apache.directory.ldap.client.api,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hadoop.fs,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10, -org.apache.hadoop.hive.metastore,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,,,,, -org.apache.hc.client5.http.async.methods,84,,,,,,,,,,,,,,,,,84,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.client5.http.classic.methods,37,,,,,,,,,,,,,,,,,37,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.client5.http.fluent,19,,,,,,,,,,,,,,,,,19,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.core5.benchmark,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.hc.core5.http,73,2,45,,,,,,,,,,,,,,,72,,,,,,,,,,,,,,,,,1,,,,2,45, -org.apache.hc.core5.net,,,18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18, -org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 -org.apache.hive.hcatalog.templeton,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, -org.apache.http,48,3,94,,,,,,,,,,,,,,,46,,,,,,,,,,,,,,,,,2,,,,3,86,8 -org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,57, -org.apache.log4j,11,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.logging.log4j,359,,8,,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,,,4,4 -org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.shiro.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.tools.ant,11,,,,3,,,,,,,,,,,,,,,8,,,,,,,,,,,,,,,,,,,,, -org.apache.tools.zip,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,, -org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,, -org.codehaus.cargo.container.installer,3,,,,2,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, -org.codehaus.groovy.control,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, -org.eclipse.jetty.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, -org.geogebra.web.full.main,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,, -org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, -org.jboss.logging,324,,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,,, -org.jdbi.v3.core,6,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, -org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.kohsuke.stapler,3,,1,,,,,,,,,,,,,,,1,,1,,,,,,,,,,,1,,,,,,,,,1, -org.mvel2,16,,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,,, -org.openjdk.jmh.runner.options,1,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.scijava.log,13,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,,, -org.slf4j,55,,6,,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,,,2,4 -org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 -org.springframework.boot.jdbc,1,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 -org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -org.springframework.http,14,,71,,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,,,61,10 -org.springframework.jdbc.core,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,,, -org.springframework.jdbc.datasource,4,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,, -org.springframework.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.ldap,47,,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, -org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 -org.springframework.util,3,,142,,2,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,90,52 -org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, -org.springframework.web.client,13,3,,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, -org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.web.util,,,165,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,140,25 -org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,2, -org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -play.libs.ws,2,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,, -play.mvc,,13,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,24, -ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 -ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -retrofit2,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +package,sink,source,summary,sink:bean-validation,sink:file-content-store,sink:fragment-injection,sink:groovy-injection,sink:hostname-verification,sink:html-injection,sink:information-leak,sink:intent-redirection,sink:jexl-injection,sink:jndi-injection,sink:js-injection,sink:ldap-injection,sink:log-injection,sink:mvel-injection,sink:ognl-injection,sink:path-injection,sink:pending-intents,sink:regex-use,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:request-forgery,sink:response-splitting,sink:sql-injection,sink:template-injection,sink:url-redirection,sink:xpath-injection,sink:xslt-injection,source:android-external-storage-dir,source:contentprovider,source:remote,summary:taint,summary:value +android.app,35,,103,,,11,,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,18,85 +android.content,24,31,154,,,,,,,,16,,,,,,,,,,,,,,,,,,,8,,,,,4,27,,63,91 +android.database,59,,41,,,,,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,41, +android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 +android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,41,81 +android.support.v4.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +android.util,6,16,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,2,,,,,1,,,,,,,,,,,,,,,,,,,,,,,2,, +android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1, +androidx.core.app,6,,95,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,12,83 +androidx.fragment.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +androidx.slice,2,5,88,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,5,,27,61 +cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +com.google.common.base,4,,87,,,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,63,24 +com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 +com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 +com.google.common.flogger,29,,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,, +com.google.common.io,8,,73,,1,,,,,,,,,,,,,,7,,,,,,,,,,,,,,,,,,,72,1 +com.google.gson,,,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,14 +com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, +com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, +com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,, +com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, +com.thoughtworks.xstream,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +com.unboundid.ldap.sdk,17,,,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,, +com.zaxxer.hikari,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, +flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,, +freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,, +groovy.lang,26,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.text,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.util,5,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hudson,44,,16,,2,,,,,,,,,,,,,,36,,,,,,,,,6,,,,,,,,,,16, +io.jsonwebtoken,,2,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,4, +io.netty.bootstrap,3,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,,,, +io.netty.buffer,,,207,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,130,77 +io.netty.channel,9,2,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,2,, +io.netty.handler.codec,4,13,259,,,,,,,,,,,,,,,,1,,,,,,,,,3,,,,,,,,,13,143,116 +io.netty.handler.ssl,2,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,, +io.netty.handler.stream,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +io.netty.resolver,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +io.netty.util,2,,23,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,,,,,,,21,2 +jakarta.faces.context,2,7,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,, +jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,94,55 +java.awt,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3 +java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +java.io,44,,45,,22,,,,,,,,,,,,,,22,,,,,,,,,,,,,,,,,,,43,2 +java.lang,18,,92,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36 +java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20, +java.nio,38,,31,,3,,,,,,,,,,,,,,35,,,,,,,,,,,,,,,,,,,31, +java.sql,13,,3,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,1 +java.util,44,,484,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440 +javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +javax.faces.context,2,7,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,, +javax.imageio.stream,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, +javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +javax.management.remote,2,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.naming,7,,1,,,,,,,,,,6,,1,,,,,,,,,,,,,,,,,,,,,,,1, +javax.net.ssl,2,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.script,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, +javax.servlet,5,21,2,,,,,,,1,,,,,,,,,1,,,,,,,,,,3,,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, +javax.ws.rs.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +javax.ws.rs.core,3,,149,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,2,,,,,,94,55 +javax.xml.transform,2,,6,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,1,,,,6, +javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,, +jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 +kotlin,16,,1843,,,,,,,,,,,,,,,,14,,,,,,,,,2,,,,,,,,,,1836,7 +net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,, +ognl,6,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, +okhttp3,4,,47,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,22,25 +org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.compress.archivers.tar,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4, +org.apache.commons.httpclient.util,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.commons.io,111,,560,,2,,,,,,,,,,,,,,94,,,,,,,,,15,,,,,,,,,,546,14 +org.apache.commons.jelly,6,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, +org.apache.commons.jexl2,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.jexl3,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,293,131 +org.apache.commons.logging,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.net,9,12,,,,,,,,,,,,,,,,,3,,,,,,,,,6,,,,,,,,,12,, +org.apache.commons.ognl,6,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 +org.apache.directory.ldap.client.api,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.hadoop.fs,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10, +org.apache.hadoop.hive.metastore,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,, +org.apache.hc.client5.http.async.methods,84,,,,,,,,,,,,,,,,,,,,,,,,,,,84,,,,,,,,,,, +org.apache.hc.client5.http.classic.methods,37,,,,,,,,,,,,,,,,,,,,,,,,,,,37,,,,,,,,,,, +org.apache.hc.client5.http.fluent,19,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,, +org.apache.hc.core5.benchmark,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.hc.core5.http,73,2,45,,,,,,1,,,,,,,,,,,,,,,,,,,72,,,,,,,,,2,45, +org.apache.hc.core5.net,,,18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18, +org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 +org.apache.hive.hcatalog.templeton,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,, +org.apache.http,48,3,94,,,,,,2,,,,,,,,,,,,,,,,,,,46,,,,,,,,,3,86,8 +org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,57, +org.apache.log4j,11,,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,, +org.apache.logging.log4j,359,,8,,,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,4,4 +org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.shiro.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.tools.ant,11,,,,,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,, +org.apache.tools.zip,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,, +org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,, +org.codehaus.cargo.container.installer,3,,,,,,,,,,,,,,,,,,2,,,,,,,,,1,,,,,,,,,,, +org.codehaus.groovy.control,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,, +org.eclipse.jetty.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.geogebra.web.full.main,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,, +org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,, +org.jboss.logging,324,,,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,, +org.jdbi.v3.core,6,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, +org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,, +org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 +org.kohsuke.stapler,3,,1,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,1,,,,,,1, +org.mvel2,16,,,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,, +org.openjdk.jmh.runner.options,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +org.scijava.log,13,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,, +org.slf4j,55,,6,,,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,2,4 +org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 +org.springframework.boot.jdbc,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 +org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +org.springframework.http,14,,71,,,,,,,,,,,,,,,,,,,,,,,,,14,,,,,,,,,,61,10 +org.springframework.jdbc.core,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,, +org.springframework.jdbc.datasource,4,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,, +org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,, +org.springframework.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.ldap,47,,,,,,,,,,,,33,,14,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, +org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 +org.springframework.util,3,,142,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,90,52 +org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, +org.springframework.web.client,13,3,,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, +org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, +org.springframework.web.util,,,165,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,140,25 +org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,2, +org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +play.libs.ws,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, +play.mvc,,13,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,24, +ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 +ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +retrofit2,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index b87eeb390fe..644b4aaef6a 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -6,22 +6,22 @@ Java framework & library support :class: fullWidthTable :widths: auto - Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission` + Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑918` :sub:`Request Forgery` Android,``android.*``,52,481,138,,3,67,,, Android extensions,``androidx.*``,5,183,19,,,,,, `Apache Commons Collections <https://commons.apache.org/proper/commons-collections/>`_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,, - `Apache Commons IO <https://commons.apache.org/proper/commons-io/>`_,``org.apache.commons.io``,,560,111,93,,,,,15 + `Apache Commons IO <https://commons.apache.org/proper/commons-io/>`_,``org.apache.commons.io``,,560,111,94,,,,,15 `Apache Commons Lang <https://commons.apache.org/proper/commons-lang/>`_,``org.apache.commons.lang3``,,424,6,,,,,, `Apache Commons Text <https://commons.apache.org/proper/commons-text/>`_,``org.apache.commons.text``,,272,,,,,,, `Apache HttpComponents <https://hc.apache.org/>`_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,182,122,,3,,,,119 `Apache Log4j 2 <https://logging.apache.org/log4j/2.0/>`_,``org.apache.logging.log4j``,,8,359,,,,,, - `Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,41,2,,,,, + `Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,41,7,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,, `JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,, - Java Standard Library,``java.*``,3,679,170,40,,9,,,13 - Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,1,4,,1,1,2 - Kotlin Standard Library,``kotlin*``,,1843,16,11,,,,,2 - `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,113,2,,28,14,,29 - Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,890,520,26,,18,18,,185 - Totals,,255,9182,1973,175,10,122,33,1,365 + Java Standard Library,``java.*``,3,679,170,62,,9,,,17 + Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2 + Kotlin Standard Library,``kotlin*``,,1843,16,14,,,,,2 + `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,113,3,,28,14,,34 + Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,890,520,60,,18,18,,193 + Totals,,255,9182,1973,242,10,122,33,1,382 From 527fe523a88be1283039ef3cd51091db57b16fb0 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Fri, 19 May 2023 16:42:08 +0200 Subject: [PATCH 294/739] Add PathCreation.qll sinks to models-as-data The old PathCreation sinks can't be removed because doing so would cause alert wobble in the path injection queries. See their getReportingNode predicates. --- .../2023-05-19-path-injection-sinks-mad.md | 4 ++++ java/ql/lib/ext/java.io.model.yml | 5 +++++ java/ql/lib/ext/java.nio.file.model.yml | 13 +++++++++---- java/ql/lib/ext/java.nio.model.yml | 1 + .../semmle/code/java/security/TaintedPathQuery.qll | 13 ++----------- java/ql/src/Security/CWE/CWE-022/TaintedPath.ql | 1 + .../ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql | 1 + .../Security/CWE/CWE-073/FilePathInjection.ql | 3 +-- .../security/CWE-073/FilePathInjection.expected | 11 +++++++++++ .../SupportedExternalSinks.expected | 1 + 10 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md diff --git a/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md b/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md new file mode 100644 index 00000000000..5f666a0de4f --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kinds `create-file` and `read-file`. diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index e0920d7df16..83e57a68c74 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -3,6 +3,10 @@ extensions: pack: codeql/java-all extensible: sinkModel data: + - ["java.io", "File", False, "File", "(File,String)", "", "Argument[1]", "path-injection", "manual"] # old PathCreation + - ["java.io", "File", False, "File", "(String)", "", "Argument[0]", "path-injection", "manual"] # old PathCreation + - ["java.io", "File", False, "File", "(String,String)", "", "Argument[0..1]", "path-injection", "manual"] # old PathCreation + - ["java.io", "File", False, "File", "(URI)", "", "Argument[0]", "path-injection", "manual"] # old PathCreation - ["java.io", "File", True, "createTempFile", "(String,String,File)", "", "Argument[2]", "path-injection", "ai-manual"] - ["java.io", "File", True, "renameTo", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.io", "FileInputStream", True, "FileInputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] @@ -11,6 +15,7 @@ extensions: - ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "file-content-store", "manual"] - ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.io", "FileReader", True, "FileReader", "(String,Charset)", "", "Argument[0]", "path-injection", "manual"] - ["java.io", "FileSystem", True, "createDirectory", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.io", "FileWriter", False, "FileWriter", "", "", "Argument[0]", "path-injection", "manual"] - ["java.io", "PrintStream", False, "PrintStream", "(File)", "", "Argument[0]", "path-injection", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index e4519fbc071..475ddc43eef 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -3,11 +3,9 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "path-injection", "manual"] - - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[0]", "path-injection", "manual"] - - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[1]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[0]", "file-content-store", "manual"] - - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[1]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "", "", "Argument[1]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "createDirectories", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "createDirectory", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "createFile", "", "", "Argument[0]", "path-injection", "manual"] @@ -40,6 +38,13 @@ extensions: - ["java.nio.file", "Files", True, "delete", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", True, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", True, "newOutputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "FileSystem", False, "getPath", "", "", "Argument[0..1]", "path-injection", "manual"] # old PathCreation + - ["java.nio.file", "Path", False, "of", "(String,String[])", "", "Argument[0..1]", "path-injection", "manual"] # old PathCreation + - ["java.nio.file", "Path", False, "of", "(URI)", "", "Argument[0]", "path-injection", "manual"] # old PathCreation + - ["java.nio.file", "Path", False, "resolve", "(String)", "", "Argument[0]", "path-injection", "manual"] # old PathCreation + - ["java.nio.file", "Path", False, "resolveSibling", "(String)", "", "Argument[0]", "path-injection", "manual"] # old PathCreation + - ["java.nio.file", "Paths", False, "get", "(String,String[])", "", "Argument[0..1]", "path-injection", "manual"] # old PathCreation + - ["java.nio.file", "Paths", False, "get", "(URI)", "", "Argument[0]", "path-injection", "manual"] # old PathCreation - ["java.nio.file", "SecureDirectoryStream", True, "deleteDirectory", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "SecureDirectoryStream", True, "deleteFile", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - addsTo: diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml index 1548dc2c649..9fbe1b253ec 100644 --- a/java/ql/lib/ext/java.nio.model.yml +++ b/java/ql/lib/ext/java.nio.model.yml @@ -6,6 +6,7 @@ extensions: - ["java.nio", "ByteBuffer", False, "array", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio", "ByteBuffer", False, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio", "ByteBuffer", False, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio", "Paths", False, "get", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # old PathCreation - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll b/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll index 4fa64846c91..a90a23c2165 100644 --- a/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll @@ -5,7 +5,6 @@ import semmle.code.java.frameworks.Networking import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.ExternalFlow -import semmle.code.java.security.PathCreation import semmle.code.java.security.PathSanitizer /** @@ -55,11 +54,7 @@ private class TaintPreservingUriCtorParam extends Parameter { module TaintedPathConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(PathCreation p).getAnInput() - or - sinkNode(sink, "path-injection") - } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "path-injection") } predicate isBarrier(DataFlow::Node sanitizer) { sanitizer.getType() instanceof BoxedType or @@ -82,11 +77,7 @@ module TaintedPathFlow = TaintTracking::Global<TaintedPathConfig>; module TaintedPathLocalConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } - predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(PathCreation p).getAnInput() - or - sinkNode(sink, "path-injection") - } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "path-injection") } predicate isBarrier(DataFlow::Node sanitizer) { sanitizer.getType() instanceof BoxedType or diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 2d73514d97b..96e8e66c7cd 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -14,6 +14,7 @@ */ import java +import semmle.code.java.security.PathCreation import semmle.code.java.security.TaintedPathQuery import TaintedPathFlow::PathGraph diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql b/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql index c017b8a3aa9..8e56121883f 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql @@ -14,6 +14,7 @@ */ import java +import semmle.code.java.security.PathCreation import semmle.code.java.security.TaintedPathQuery import TaintedPathLocalFlow::PathGraph diff --git a/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql index 8e113837bca..ba3411e4da2 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql @@ -16,7 +16,6 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.FlowSources -import semmle.code.java.security.PathCreation import JFinalController import semmle.code.java.security.PathSanitizer import InjectFilePathFlow::PathGraph @@ -52,7 +51,7 @@ module InjectFilePathConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(PathCreation p).getAnInput() and + sinkNode(sink, "path-injection") and not sink instanceof NormalizedPathNode } diff --git a/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected index 5720de5c4b9..cd2b49f28c1 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected @@ -2,7 +2,12 @@ edges | FilePathInjection.java:21:21:21:34 | getPara(...) : String | FilePathInjection.java:26:47:26:59 | finalFilePath | | FilePathInjection.java:64:21:64:34 | getPara(...) : String | FilePathInjection.java:72:47:72:59 | finalFilePath | | FilePathInjection.java:87:21:87:34 | getPara(...) : String | FilePathInjection.java:95:47:95:59 | finalFilePath | +| FilePathInjection.java:177:50:177:58 | file : File | FilePathInjection.java:182:30:182:33 | file | | FilePathInjection.java:205:17:205:44 | getParameter(...) : String | FilePathInjection.java:209:24:209:31 | filePath | +| FilePathInjection.java:205:17:205:44 | getParameter(...) : String | FilePathInjection.java:209:24:209:31 | filePath : String | +| FilePathInjection.java:209:15:209:32 | new File(...) : File | FilePathInjection.java:217:19:217:22 | file : File | +| FilePathInjection.java:209:24:209:31 | filePath : String | FilePathInjection.java:209:15:209:32 | new File(...) : File | +| FilePathInjection.java:217:19:217:22 | file : File | FilePathInjection.java:177:50:177:58 | file : File | nodes | FilePathInjection.java:21:21:21:34 | getPara(...) : String | semmle.label | getPara(...) : String | | FilePathInjection.java:26:47:26:59 | finalFilePath | semmle.label | finalFilePath | @@ -10,11 +15,17 @@ nodes | FilePathInjection.java:72:47:72:59 | finalFilePath | semmle.label | finalFilePath | | FilePathInjection.java:87:21:87:34 | getPara(...) : String | semmle.label | getPara(...) : String | | FilePathInjection.java:95:47:95:59 | finalFilePath | semmle.label | finalFilePath | +| FilePathInjection.java:177:50:177:58 | file : File | semmle.label | file : File | +| FilePathInjection.java:182:30:182:33 | file | semmle.label | file | | FilePathInjection.java:205:17:205:44 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| FilePathInjection.java:209:15:209:32 | new File(...) : File | semmle.label | new File(...) : File | | FilePathInjection.java:209:24:209:31 | filePath | semmle.label | filePath | +| FilePathInjection.java:209:24:209:31 | filePath : String | semmle.label | filePath : String | +| FilePathInjection.java:217:19:217:22 | file : File | semmle.label | file : File | subpaths #select | FilePathInjection.java:26:47:26:59 | finalFilePath | FilePathInjection.java:21:21:21:34 | getPara(...) : String | FilePathInjection.java:26:47:26:59 | finalFilePath | External control of file name or path due to $@. | FilePathInjection.java:21:21:21:34 | getPara(...) | user-provided value | | FilePathInjection.java:72:47:72:59 | finalFilePath | FilePathInjection.java:64:21:64:34 | getPara(...) : String | FilePathInjection.java:72:47:72:59 | finalFilePath | External control of file name or path due to $@. | FilePathInjection.java:64:21:64:34 | getPara(...) | user-provided value | | FilePathInjection.java:95:47:95:59 | finalFilePath | FilePathInjection.java:87:21:87:34 | getPara(...) : String | FilePathInjection.java:95:47:95:59 | finalFilePath | External control of file name or path due to $@. | FilePathInjection.java:87:21:87:34 | getPara(...) | user-provided value | +| FilePathInjection.java:182:30:182:33 | file | FilePathInjection.java:205:17:205:44 | getParameter(...) : String | FilePathInjection.java:182:30:182:33 | file | External control of file name or path due to $@. | FilePathInjection.java:205:17:205:44 | getParameter(...) | user-provided value | | FilePathInjection.java:209:24:209:31 | filePath | FilePathInjection.java:205:17:205:44 | getParameter(...) : String | FilePathInjection.java:209:24:209:31 | filePath | External control of file name or path due to $@. | FilePathInjection.java:205:17:205:44 | getParameter(...) | user-provided value | diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalSinks/SupportedExternalSinks.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalSinks/SupportedExternalSinks.expected index 6cb849601d5..5f0ed7d05df 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalSinks/SupportedExternalSinks.expected +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalSinks/SupportedExternalSinks.expected @@ -1,2 +1,3 @@ +| java.io.File#File(String) | 1 | | java.io.FileWriter#FileWriter(File) | 1 | | java.net.URL#openStream() | 1 | From 77d27992784255876a01f66b8dda07ad974d925d Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 2 Jun 2023 10:33:44 +0200 Subject: [PATCH 295/739] Update javascript/ql/lib/semmle/javascript/Regexp.qll Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com> --- javascript/ql/lib/semmle/javascript/Regexp.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/Regexp.qll b/javascript/ql/lib/semmle/javascript/Regexp.qll index a20f5343428..de1a3f0d98f 100644 --- a/javascript/ql/lib/semmle/javascript/Regexp.qll +++ b/javascript/ql/lib/semmle/javascript/Regexp.qll @@ -959,7 +959,7 @@ private predicate isUsedAsNonMatchObject(DataFlow::MethodCallNode call) { } /** - * Holds if `call` is a call to `search` whose result is used in a way that suggests it returns a number. + * Holds if `value` is used in a way that suggests it returns a number. */ pragma[inline] private predicate isUsedAsNumber(DataFlow::LocalSourceNode value) { From 7b17b92aca4b703c09530d3beb776f28fa34aca9 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 2 Jun 2023 10:36:11 +0200 Subject: [PATCH 296/739] Fix typo in spelling of expectation --- csharp/ql/test/TestUtilities/InlineFlowTest.qll | 2 +- go/ql/test/TestUtilities/InlineFlowTest.qll | 2 +- java/ql/test/TestUtilities/InlineFlowTest.qll | 2 +- python/ql/test/experimental/meta/ConceptsTest.qll | 2 +- ruby/ql/test/TestUtilities/InlineFlowTest.qll | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/csharp/ql/test/TestUtilities/InlineFlowTest.qll b/csharp/ql/test/TestUtilities/InlineFlowTest.qll index f69b81caf64..a31d531e1b6 100644 --- a/csharp/ql/test/TestUtilities/InlineFlowTest.qll +++ b/csharp/ql/test/TestUtilities/InlineFlowTest.qll @@ -13,7 +13,7 @@ * * ``` * - * To declare expecations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. + * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. * Example of the corresponding test file, e.g. Test.cs * ```csharp * public class Test diff --git a/go/ql/test/TestUtilities/InlineFlowTest.qll b/go/ql/test/TestUtilities/InlineFlowTest.qll index f080de86e16..0726265699f 100644 --- a/go/ql/test/TestUtilities/InlineFlowTest.qll +++ b/go/ql/test/TestUtilities/InlineFlowTest.qll @@ -7,7 +7,7 @@ * import TestUtilities.InlineFlowTest * ``` * - * To declare expecations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. + * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. * Example of the corresponding test file, e.g. Test.java * ```go * public class Test { diff --git a/java/ql/test/TestUtilities/InlineFlowTest.qll b/java/ql/test/TestUtilities/InlineFlowTest.qll index 1731b73f24e..5e37770a279 100644 --- a/java/ql/test/TestUtilities/InlineFlowTest.qll +++ b/java/ql/test/TestUtilities/InlineFlowTest.qll @@ -7,7 +7,7 @@ * import TestUtilities.InlineFlowTest * ``` * - * To declare expecations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. + * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. * Example of the corresponding test file, e.g. Test.java * ```java * public class Test { diff --git a/python/ql/test/experimental/meta/ConceptsTest.qll b/python/ql/test/experimental/meta/ConceptsTest.qll index 3f76315e8b1..27c8cb99ab4 100644 --- a/python/ql/test/experimental/meta/ConceptsTest.qll +++ b/python/ql/test/experimental/meta/ConceptsTest.qll @@ -317,7 +317,7 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest { location = response.getLocation() and element = response.toString() and // Ensure that an expectation value such as "mimetype=text/html; charset=utf-8" is parsed as a - // single expectation with tag mimetype, and not as two expecations with tags mimetype and + // single expectation with tag mimetype, and not as two expectations with tags mimetype and // charset. ( if exists(response.getMimetype().indexOf(" ")) diff --git a/ruby/ql/test/TestUtilities/InlineFlowTest.qll b/ruby/ql/test/TestUtilities/InlineFlowTest.qll index dbac70ede0a..d653a3e414e 100644 --- a/ruby/ql/test/TestUtilities/InlineFlowTest.qll +++ b/ruby/ql/test/TestUtilities/InlineFlowTest.qll @@ -11,7 +11,7 @@ * select sink, source, sink, "$@", source, source.toString() * ``` * - * To declare expecations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. + * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. * Example of the corresponding test file, e.g. test.rb * ```rb * s = source(1) From ad2f558002def0a9b621b3a6428d1230ba233af9 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 22 May 2023 12:23:27 +0200 Subject: [PATCH 297/739] Add Hudson models Includes models-as-data rows, flow sources, and XSS sanitizers. Tests for models-as-data rows not included. --- .../change-notes/2023-05-22-hudson-models.md | 4 + java/ql/lib/ext/hudson.model.model.yml | 6 ++ java/ql/lib/ext/hudson.model.yml | 78 +++++++++++++++---- java/ql/lib/ext/hudson.util.model.yml | 22 ++++++ .../semmle/code/java/dataflow/FlowSources.qll | 7 ++ .../code/java/frameworks/hudson/Hudson.qll | 29 +++++++ java/ql/lib/semmle/code/java/security/XSS.qll | 1 + .../dataflow/taintsources/Hudson.java | 16 ++++ .../dataflow/taintsources/options | 2 +- .../security/CWE-079/semmle/tests/XSS.java | 32 +++----- .../security/CWE-079/semmle/tests/options | 2 +- .../test/stubs/jenkins/hudson/FilePath.java | 34 ++++++++ java/ql/test/stubs/jenkins/hudson/Util.java | 7 ++ 13 files changed, 201 insertions(+), 39 deletions(-) create mode 100644 java/ql/lib/change-notes/2023-05-22-hudson-models.md create mode 100644 java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll create mode 100644 java/ql/test/library-tests/dataflow/taintsources/Hudson.java create mode 100644 java/ql/test/stubs/jenkins/hudson/FilePath.java create mode 100644 java/ql/test/stubs/jenkins/hudson/Util.java diff --git a/java/ql/lib/change-notes/2023-05-22-hudson-models.md b/java/ql/lib/change-notes/2023-05-22-hudson-models.md new file mode 100644 index 00000000000..55e2acae00e --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-22-hudson-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added more models for the Hudson framework. \ No newline at end of file diff --git a/java/ql/lib/ext/hudson.model.model.yml b/java/ql/lib/ext/hudson.model.model.yml index 023265b2c3d..95aebc69028 100644 --- a/java/ql/lib/ext/hudson.model.model.yml +++ b/java/ql/lib/ext/hudson.model.model.yml @@ -16,3 +16,9 @@ extensions: data: - ["hudson.model", "Node", True, "createPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["hudson.model", "DirectoryBrowserSupport$Path", False, "Path", "(String,String,boolean,long,boolean,long)", "", "Argument[0]", "Argument[this].SyntheticField[hudson.model.DirectoryBrowserSupport$Path.href]", "taint", "ai-manual"] + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["hudson.model", "Descriptor", True, "configure", "", "", "Parameter", "remote", "manual"] + - ["hudson.model", "Descriptor", True, "newInstance", "", "", "Parameter", "remote", "manual"] diff --git a/java/ql/lib/ext/hudson.model.yml b/java/ql/lib/ext/hudson.model.yml index 5ba20fce0c6..08d56be275e 100644 --- a/java/ql/lib/ext/hudson.model.yml +++ b/java/ql/lib/ext/hudson.model.yml @@ -3,24 +3,68 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson", "FilePath", False, "copyFrom", "(FilePath)", "", "Argument[0]", "path-injection", "manual"] - - ["hudson", "FilePath", False, "copyFrom", "(URL)", "", "Argument[0]", "path-injection", "manual"] - - ["hudson", "FilePath", False, "copyFrom", "(FileItem)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String,TarCompression)", "", "Argument[1]", "path-injection", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String)", "", "Argument[1]", "file-content-store", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,FilePath)", "", "Argument[1]", "path-injection", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[2]", "path-injection", "ai-manual"] - - ["hudson", "FilePath", False, "copyTo", "(FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["hudson", "FilePath", False, "installIfNecessaryFrom", "(URL,TaskListener,String)", "", "Argument[0]", "request-forgery", "ai-manual"] - - ["hudson", "FilePath", False, "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyFrom", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "copyFrom", "(FilePath)", "", "Argument[0]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "copyFrom", "(URL)", "", "Argument[0]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "copyFrom", "(FileItem)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyRecursiveTo", "", "", "Argument[this]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyRecursiveTo", "(DirScanner,FilePath,String,TarCompression)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyRecursiveTo", "(DirScanner,FilePath,String)", "", "Argument[1]", "file-content-store", "ai-manual"] + - ["hudson", "FilePath", True, "copyRecursiveTo", "(String,FilePath)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyTo", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "copyTo", "(FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyToWithPermission", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "copyToWithPermission", "(FilePath)", "", "Argument[0]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "installIfNecessaryFrom", "(URL,TaskListener,String)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["hudson", "FilePath", True, "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "openInputStream", "(File,OpenOption[])", "", "Argument[0]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "read", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "read", "(FilePath,OpenOption[])", "", "Argument[0]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "readFromOffset", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "readToString", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "renameTo", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "renameTo", "", "", "Argument[0]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "write", "", "", "Argument[this]", "path-injection", "manual"] + - ["hudson", "FilePath", True, "write", "(String,String)", "", "Argument[0]", "file-content-store", "manual"] + - ["hudson", "Launcher$ProcStarter", False, "cmds", "", "", "Argument[0]", "command-injection", "manual"] + - ["hudson", "Launcher$ProcStarter", False, "cmdAsSingleString", "", "", "Argument[0]", "command-injection", "manual"] + - ["hudson", "Launcher", True, "launch", "", "", "Argument[0]", "command-injection", "manual"] + - ["hudson", "Launcher", True, "launchChannel", "", "", "Argument[0]", "command-injection", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["hudson", "Plugin", True, "configure", "", "", "Parameter", "remote", "manual"] + - ["hudson", "Plugin", True, "newInstance", "", "", "Parameter", "remote", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel data: - - ["hudson", "FilePath", False, "child", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - - ["hudson", "FilePath", False, "list", "(String,String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] - - ["hudson", "FilePath", False, "list", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] - - ["hudson", "FilePath", False, "list", "(String)", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] - - ["hudson", "FilePath", False, "normalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - - ["hudson", "FilePath", False, "sibling", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["hudson", "FilePath", True, "FilePath", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["hudson", "FilePath", True, "FilePath", "(FilePath,String)", "", "Argument[0..1]", "Argument[this]", "taint", "manual"] + - ["hudson", "FilePath", True, "FilePath", "(VirtualChannel,String)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["hudson", "FilePath", True, "child", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["hudson", "FilePath", True, "list", "(String,String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] + - ["hudson", "FilePath", True, "list", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] + - ["hudson", "FilePath", True, "list", "(String)", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] + - ["hudson", "FilePath", True, "normalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["hudson", "FilePath", True, "sibling", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["hudson", "Util", True, "nullify", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "fixNull", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "fixEmpty", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "fixEmptyAndTrim", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "getFileName", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "join", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "encodeRFC2396", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "wrapToErrorSpan", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "fileToPath", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "xmlEscape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "escape", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "singleQuote", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "rawEncode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "fromHexString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "toHexString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["hudson", "Util", True, "tokenize", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/hudson.util.model.yml b/java/ql/lib/ext/hudson.util.model.yml index 39c5b55f349..1ac3aa8c10a 100644 --- a/java/ql/lib/ext/hudson.util.model.yml +++ b/java/ql/lib/ext/hudson.util.model.yml @@ -7,6 +7,10 @@ extensions: - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset,boolean,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util", "ClasspathBuilder", True, "add", "(FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util", "FormValidation", True, "errorWithMarkup", "", "", "Argument[0]", "html-injection", "manual"] + - ["hudson.util", "FormValidation", True, "okWithMarkup", "", "", "Argument[0]", "html-injection", "manual"] + - ["hudson.util", "FormValidation", True, "respond", "", "", "Argument[1]", "html-injection", "manual"] + - ["hudson.util", "FormValidation", True, "warningWithMarkup", "", "", "Argument[0]", "html-injection", "manual"] - ["hudson.util", "IOUtils", True, "mkdirs", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util", "StreamTaskListener", True, "StreamTaskListener", "(File,boolean,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util", "TextFile", True, "delete", "()", "", "Argument[this]", "path-injection", "manual"] @@ -15,10 +19,28 @@ extensions: - ["hudson.util", "TextFile", True, "lines", "()", "", "Argument[this]", "path-injection", "manual"] - ["hudson.util", "TextFile", True, "read", "()", "", "Argument[this]", "path-injection", "manual"] - ["hudson.util", "TextFile", True, "readTrim", "()", "", "Argument[this]", "path-injection", "manual"] + - ["hudson.util", "TextFile", True, "write", "(String)", "", "Argument[this]", "path-injection", "manual"] - ["hudson.util", "TextFile", True, "write", "(String)", "", "Argument[0]", "file-content-store", "manual"] + - ["hudson.util", "HttpResponses", True, "staticResource", "(File)", "", "Argument[0]", "path-injection", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel data: + - ["hudson.util", "ArgumentListBuilder", True, "ArgumentListBuilder", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "add", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "clone", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "prepend", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "toCommandArray", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "toList", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "toWindowsCommand", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + # ArgumentListBuilder fluent methods + - ["hudson.util", "ArgumentListBuilder", True, "add", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "addKeyValuePair", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "addKeyValuePairs", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "addKeyValuePairsFromPropertyString", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "addMasked", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "addQuoted", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "addTokenized", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["hudson.util", "ArgumentListBuilder", True, "prepend", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["hudson.util", "QuotedStringTokenizer", True, "tokenize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["hudson.util", "TextFile", True, "TextFile", "(File)", "", "Argument[0]", "Argument[this]", "taint", "ai-manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index d26aa5d35f6..1a009c1f2e6 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -36,6 +36,13 @@ abstract class RemoteFlowSource extends DataFlow::Node { abstract string getSourceType(); } +/** + * A module for importing frameworks that define flow sources. + */ +private module FlowSources { + private import semmle.code.java.frameworks.hudson.Hudson +} + private class ExternalRemoteFlowSource extends RemoteFlowSource { ExternalRemoteFlowSource() { sourceNode(this, "remote") } diff --git a/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll b/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll new file mode 100644 index 00000000000..aab962e65aa --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll @@ -0,0 +1,29 @@ +/** Provides classes and predicates related to the Hudson framework. */ + +import java +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.security.XSS + +private class FilePathRead extends LocalUserInput { + FilePathRead() { + this.asExpr() + .(MethodAccess) + .getMethod() + .hasQualifiedName("hudson", "FilePath", + [ + "newInputStreamDenyingSymlinkAsNeeded", "openInputStream", "read", "readFromOffset", + "readToString" + ]) + } +} + +private class HudsonUtilXssSanitizer extends XssSanitizer { + HudsonUtilXssSanitizer() { + this.asExpr() + .(MethodAccess) + .getMethod() + // Not including xmlEscape because it only accounts for >, <, and &. + // It does not account for ", or ', which makes it an incomplete XSS sanitizer. + .hasQualifiedName("hudson", "Util", "escape") + } +} diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index bd968bd5fc3..163696e4489 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -6,6 +6,7 @@ import semmle.code.java.frameworks.android.WebView import semmle.code.java.frameworks.spring.SpringController import semmle.code.java.frameworks.spring.SpringHttp import semmle.code.java.frameworks.javaee.jsf.JSFRenderer +private import semmle.code.java.frameworks.hudson.Hudson import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.dataflow.ExternalFlow diff --git a/java/ql/test/library-tests/dataflow/taintsources/Hudson.java b/java/ql/test/library-tests/dataflow/taintsources/Hudson.java new file mode 100644 index 00000000000..2a180eeb5fb --- /dev/null +++ b/java/ql/test/library-tests/dataflow/taintsources/Hudson.java @@ -0,0 +1,16 @@ +import hudson.FilePath; + +public class Hudson { + + private static void sink(Object o) {} + + public static void test() throws Exception { + FilePath fp = null; + sink(FilePath.newInputStreamDenyingSymlinkAsNeeded(null, null, null)); // $hasLocalValueFlow + sink(FilePath.openInputStream(null, null)); // $hasLocalValueFlow + sink(fp.read()); // $hasLocalValueFlow + sink(fp.read(null)); // $hasLocalValueFlow + sink(fp.readFromOffset(-1)); // $hasLocalValueFlow + sink(fp.readToString()); // $hasLocalValueFlow + } +} diff --git a/java/ql/test/library-tests/dataflow/taintsources/options b/java/ql/test/library-tests/dataflow/taintsources/options index c19a2aa5fb3..bd30b3e8c95 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/options +++ b/java/ql/test/library-tests/dataflow/taintsources/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/akka-2.6.x:${testdir}/../../../stubs/jwtk-jjwt-0.11.2 \ No newline at end of file +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/akka-2.6.x:${testdir}/../../../stubs/jwtk-jjwt-0.11.2:${testdir}/../../../stubs/jenkins \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java index 2854ffe30b7..1ffa72c4c0d 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java @@ -4,9 +4,6 @@ package test.cwe079.cwe.examples; - - - import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; @@ -14,13 +11,12 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - public class XSS extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { + throws ServletException, IOException { // BAD: a request parameter is written directly to the Servlet response stream - response.getWriter().print( - "The page \"" + request.getParameter("page") + "\" was not found."); // $xss + response.getWriter() + .print("The page \"" + request.getParameter("page") + "\" was not found."); // $xss // GOOD: servlet API encodes the error message HTML for the HTML context response.sendError(HttpServletResponse.SC_NOT_FOUND, @@ -29,35 +25,31 @@ public class XSS extends HttpServlet { // GOOD: escape HTML characters first response.sendError(HttpServletResponse.SC_NOT_FOUND, "The page \"" + encodeForHtml(request.getParameter("page")) + "\" was not found."); - + // GOOD: servlet API encodes the error message HTML for the HTML context response.sendError(HttpServletResponse.SC_NOT_FOUND, "The page \"" + capitalizeName(request.getParameter("page")) + "\" was not found."); - + // BAD: outputting the path of the resource response.getWriter().print("The path section of the URL was " + request.getPathInfo()); // $xss - // BAD: typical XSS, this time written to an OutputStream instead of a Writer + // BAD: typical XSS, this time written to an OutputStream instead of a Writer response.getOutputStream().write(request.getPathInfo().getBytes()); // $xss + + // GOOD: sanitizer + response.getOutputStream().write(hudson.Util.escape(request.getPathInfo()).getBytes()); // safe } - - - - - - /** - * Replace special characters in the given text such that it can - * be inserted into an HTML file and not be interpreted as including - * any HTML tags. + * Replace special characters in the given text such that it can be inserted into an HTML file + * and not be interpreted as including any HTML tags. */ static String encodeForHtml(String text) { // This is just a stub. For an example of a real implementation, see // the OWASP Java Encoder Project. return text.replace("<", "<"); } - + static String capitalizeName(String text) { return text.replace("foo inc", "Foo, Inc."); } diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/options b/java/ql/test/query-tests/security/CWE-079/semmle/tests/options index 62fc56e6792..78c431eb683 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/options +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/javax-faces-2.3/:${testdir}/../../../../../stubs/google-android-9.0.0 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/javax-faces-2.3/:${testdir}/../../../../../stubs/google-android-9.0.0:${testdir}/../../../../../stubs/jenkins diff --git a/java/ql/test/stubs/jenkins/hudson/FilePath.java b/java/ql/test/stubs/jenkins/hudson/FilePath.java new file mode 100644 index 00000000000..24a35901e35 --- /dev/null +++ b/java/ql/test/stubs/jenkins/hudson/FilePath.java @@ -0,0 +1,34 @@ +package hudson; + +import java.io.File; +import java.io.InputStream; +import java.nio.file.OpenOption; + +public class FilePath { + + public static InputStream newInputStreamDenyingSymlinkAsNeeded(File file, + String verificationRoot, OpenOption... openOption) { + return null; + } + + public static InputStream openInputStream(File file, OpenOption[] openOptions) { + return null; + } + + public InputStream read() { + return null; + } + + public InputStream read(FilePath rootPath, OpenOption... openOptions) { + return null; + } + + public InputStream readFromOffset(long offset) { + return null; + } + + public String readToString() { + return null; + } +} + diff --git a/java/ql/test/stubs/jenkins/hudson/Util.java b/java/ql/test/stubs/jenkins/hudson/Util.java new file mode 100644 index 00000000000..61e357abb52 --- /dev/null +++ b/java/ql/test/stubs/jenkins/hudson/Util.java @@ -0,0 +1,7 @@ +package hudson; + +public class Util { + public static String escape(String text) { + return null; + } +} From cc8aac5435b73b4b7ecf805c2ed12e6607b9cd6e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 30 May 2023 15:14:03 -0700 Subject: [PATCH 298/739] C++: Use the 'shortestDistances' HOP to count indirections instead of manual recursion. This avoids cyclic problems when we have invalid types. --- .../dataflow/internal/SsaInternalsCommon.qll | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 84cdefe7823..8f6b581edcf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -139,6 +139,20 @@ class AllocationInstruction extends CallInstruction { AllocationInstruction() { this.getStaticCallTarget() instanceof Cpp::AllocationFunction } } +private predicate isIndirectionType(Type t) { t instanceof Indirection } + +private predicate hasUnspecifiedBaseType(Indirection t, Type base) { + base = t.getBaseType().getUnspecifiedType() +} + +/** + * Holds if `t2` is the same type as `t1`, but after stripping away `result` number + * of indirections. + * Furthermore, specifies in `t2` been deeply stripped and typedefs has been resolved. + */ +private int getNumberOfIndirectionsImpl(Type t1, Type t2) = + shortestDistances(isIndirectionType/1, hasUnspecifiedBaseType/2)(t1, t2, result) + /** * An abstract class for handling indirections. * @@ -157,7 +171,10 @@ abstract class Indirection extends Type { * For example, the number of indirections of a variable `p` of type * `int**` is `3` (i.e., `p`, `*p` and `**p`). */ - abstract int getNumberOfIndirections(); + final int getNumberOfIndirections() { + result = + getNumberOfIndirectionsImpl(this.getType(), any(Type end | not end instanceof Indirection)) + } /** * Holds if `deref` is an instruction that behaves as a `LoadInstruction` @@ -195,19 +212,11 @@ private class PointerOrArrayOrReferenceTypeIndirection extends Indirection insta PointerOrArrayOrReferenceTypeIndirection() { baseType = PointerOrArrayOrReferenceType.super.getBaseType() } - - override int getNumberOfIndirections() { - result = 1 + countIndirections(this.getBaseType().getUnspecifiedType()) - } } private class PointerWrapperTypeIndirection extends Indirection instanceof PointerWrapper { PointerWrapperTypeIndirection() { baseType = PointerWrapper.super.getBaseType() } - override int getNumberOfIndirections() { - result = 1 + countIndirections(this.getBaseType().getUnspecifiedType()) - } - override predicate isAdditionalDereference(Instruction deref, Operand address) { exists(CallInstruction call | operandForFullyConvertedCall(getAUse(deref), call) and @@ -228,10 +237,6 @@ private module IteratorIndirections { baseType = super.getValueType() } - override int getNumberOfIndirections() { - result = 1 + countIndirections(this.getBaseType().getUnspecifiedType()) - } - override predicate isAdditionalDereference(Instruction deref, Operand address) { exists(CallInstruction call | operandForFullyConvertedCall(getAUse(deref), call) and From 44b6366586d4ae2fb54f847c709a4ca46590a59c Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 09:44:30 +0200 Subject: [PATCH 299/739] delete old deprecations --- csharp/ql/lib/semmle/code/asp/WebConfig.qll | 21 ---- csharp/ql/lib/semmle/code/cil/Types.qll | 5 - csharp/ql/lib/semmle/code/csharp/Type.qll | 10 -- .../csharp/commons/StructuralComparison.qll | 42 -------- .../dataflow/internal/DataFlowPublic.qll | 10 -- .../security/dataflow/ExternalAPIsQuery.qll | 15 --- .../security/dataflow/LDAPInjectionQuery.qll | 3 - .../implementation/internal/TInstruction.qll | 6 -- .../ir/implementation/internal/TOperand.qll | 11 --- .../ir/implementation/raw/Instruction.qll | 6 -- .../raw/internal/IRConstruction.qll | 6 -- .../raw/internal/TranslatedCondition.qll | 3 - .../raw/internal/TranslatedDeclaration.qll | 3 - .../raw/internal/TranslatedElement.qll | 3 - .../raw/internal/TranslatedExpr.qll | 3 - .../raw/internal/TranslatedFunction.qll | 6 -- .../raw/internal/TranslatedInitialization.qll | 9 -- .../raw/internal/TranslatedStmt.qll | 3 - .../unaliased_ssa/Instruction.qll | 6 -- .../internal/SSAConstruction.qll | 12 --- .../unaliased_ssa/internal/SimpleSSA.qll | 6 -- java/ql/lib/semmle/code/java/Expr.qll | 3 - .../controlflow/internal/Preconditions.qll | 9 -- java/ql/lib/semmle/code/java/dataflow/SSA.qll | 3 - .../code/java/dataflow/internal/BaseSSA.qll | 3 - .../semmle/code/java/deadcode/EntryPoints.qll | 3 - .../code/java/frameworks/Networking.qll | 3 - .../semmle/code/java/frameworks/Servlets.qll | 6 -- .../semmle/code/java/frameworks/UnboundId.qll | 14 --- .../jackson/JacksonSerializability.qll | 3 - .../java/frameworks/javaee/PersistenceXML.qll | 3 - .../java/frameworks/javaee/ejb/EJBJarXML.qll | 3 - .../javaee/jsf/JSFFacesContextXML.qll | 6 -- .../java/frameworks/spring/SpringAutowire.qll | 3 - .../java/frameworks/spring/SpringCamel.qll | 24 ----- .../frameworks/spring/SpringComponentScan.qll | 3 - .../java/frameworks/spring/SpringFlex.qll | 5 - .../frameworks/spring/SpringXMLElement.qll | 3 - .../frameworks/struts/StrutsConventions.qll | 3 - .../code/java/frameworks/struts/StrutsXML.qll | 24 ----- .../semmle/code/java/security/Encryption.qll | 3 - .../code/java/security/ExternalAPIs.qll | 15 --- .../semmle/code/java/security/XmlParsers.qll | 87 ----------------- java/ql/lib/semmle/code/xml/WebXML.qll | 9 -- .../Security/CWE/CWE-089/MyBatisCommonLib.qll | 3 - .../semmle/code/xml/StrutsXML.qll | 6 -- .../src/semmle/code/xml/MyBatisMapperXML.qll | 6 -- .../adaptivethreatmodeling/ATMConfig.qll | 3 - .../FunctionBodyFeatures.qll | 6 -- .../ql/lib/Expressions/DOMProperties.qll | 6 -- javascript/ql/lib/semmle/javascript/AST.qll | 6 -- .../ql/lib/semmle/javascript/ApiGraphs.qll | 3 - .../ql/lib/semmle/javascript/DefUse.qll | 68 ------------- javascript/ql/lib/semmle/javascript/E4X.qll | 15 --- javascript/ql/lib/semmle/javascript/JSON.qll | 27 ------ javascript/ql/lib/semmle/javascript/JSX.qll | 27 ------ .../semmle/javascript/JsonStringifiers.qll | 3 - javascript/ql/lib/semmle/javascript/NPM.qll | 9 -- .../ql/lib/semmle/javascript/PrintAst.qll | 51 ---------- .../semmle/javascript/dataflow/DataFlow.qll | 2 - .../javascript/dataflow/TaintTracking.qll | 19 ---- .../javascript/dependencies/Dependencies.qll | 18 ---- .../dependencies/FrameworkLibraries.qll | 21 ---- .../javascript/frameworks/ClientRequests.qll | 6 -- .../semmle/javascript/frameworks/Files.qll | 6 -- .../semmle/javascript/frameworks/Markdown.qll | 3 - .../lib/semmle/javascript/frameworks/Next.qll | 3 - .../semmle/javascript/frameworks/NoSQL.qll | 3 - .../javascript/frameworks/UriLibraries.qll | 24 ----- .../javascript/frameworks/WebSocket.qll | 3 - .../javascript/internal/CachedStages.qll | 3 - .../dataflow/CodeInjectionCustomizations.qll | 6 -- .../javascript/security/dataflow/DOM.qll | 27 ------ .../security/dataflow/DomBasedXssQuery.qll | 6 -- .../ExternalAPIUsedWithUntrustedData.qll | 3 - ...APIUsedWithUntrustedDataCustomizations.qll | 9 -- .../ExternalAPIUsedWithUntrustedDataQuery.qll | 9 -- ...ImproperCodeSanitizationCustomizations.qll | 3 - .../InsecureDownloadCustomizations.qll | 9 -- .../UnsafeHtmlConstructionCustomizations.qll | 6 -- .../javascript/security/dataflow/Xss.qll | 3 - .../dataflow/XssThroughDomCustomizations.qll | 3 - .../ql/src/Declarations/Definitions.qll | 12 --- .../frameworks/ReactJS/ReactName.qll | 3 - .../Validating RAML-based APIs/Osprey.qll | 6 -- .../Validating RAML-based APIs/RAML.qll | 9 -- ruby/ql/lib/codeql/ruby/Concepts.qll | 8 -- ruby/ql/lib/codeql/ruby/ast/Expr.qll | 7 -- ruby/ql/lib/codeql/ruby/ast/Literal.qll | 12 --- ruby/ql/lib/codeql/ruby/ast/Pattern.qll | 16 --- .../lib/codeql/ruby/controlflow/CfgNodes.qll | 7 -- .../ruby/frameworks/StandardLibrary.qll | 97 ------------------- .../ruby/security/ReflectedXSSQuery.qll | 3 - .../codeql/ruby/security/StoredXSSQuery.qll | 3 - ruby/ql/lib/codeql/ruby/security/XSS.qll | 15 --- 95 files changed, 1059 deletions(-) delete mode 100644 ruby/ql/lib/codeql/ruby/frameworks/StandardLibrary.qll diff --git a/csharp/ql/lib/semmle/code/asp/WebConfig.qll b/csharp/ql/lib/semmle/code/asp/WebConfig.qll index 49e42fce5c1..fdc251b4242 100644 --- a/csharp/ql/lib/semmle/code/asp/WebConfig.qll +++ b/csharp/ql/lib/semmle/code/asp/WebConfig.qll @@ -18,9 +18,6 @@ class WebConfigReleaseTransformXml extends XmlFile { WebConfigReleaseTransformXml() { this.getName().matches("%Web.Release.config") } } -/** DEPRECATED: Alias for WebConfigXml */ -deprecated class WebConfigXML = WebConfigXml; - /** A `<configuration>` tag in an ASP.NET configuration file. */ class ConfigurationXmlElement extends XmlElement { ConfigurationXmlElement() { this.getName().toLowerCase() = "configuration" } @@ -31,9 +28,6 @@ class CompilationXmlElement extends XmlElement { CompilationXmlElement() { this.getName().toLowerCase() = "compilation" } } -/** DEPRECATED: Alias for ConfigurationXmlElement */ -deprecated class ConfigurationXMLElement = ConfigurationXmlElement; - /** A `<location>` tag in an ASP.NET configuration file. */ class LocationXmlElement extends XmlElement { LocationXmlElement() { @@ -42,9 +36,6 @@ class LocationXmlElement extends XmlElement { } } -/** DEPRECATED: Alias for LocationXmlElement */ -deprecated class LocationXMLElement = LocationXmlElement; - /** A `<system.web>` tag in an ASP.NET configuration file. */ class SystemWebXmlElement extends XmlElement { SystemWebXmlElement() { @@ -57,9 +48,6 @@ class SystemWebXmlElement extends XmlElement { } } -/** DEPRECATED: Alias for SystemWebXmlElement */ -deprecated class SystemWebXMLElement = SystemWebXmlElement; - /** A `<system.webServer>` tag in an ASP.NET configuration file. */ class SystemWebServerXmlElement extends XmlElement { SystemWebServerXmlElement() { @@ -72,9 +60,6 @@ class SystemWebServerXmlElement extends XmlElement { } } -/** DEPRECATED: Alias for SystemWebServerXmlElement */ -deprecated class SystemWebServerXMLElement = SystemWebServerXmlElement; - /** A `<customErrors>` tag in an ASP.NET configuration file. */ class CustomErrorsXmlElement extends XmlElement { CustomErrorsXmlElement() { @@ -83,9 +68,6 @@ class CustomErrorsXmlElement extends XmlElement { } } -/** DEPRECATED: Alias for CustomErrorsXmlElement */ -deprecated class CustomErrorsXMLElement = CustomErrorsXmlElement; - /** A `<httpRuntime>` tag in an ASP.NET configuration file. */ class HttpRuntimeXmlElement extends XmlElement { HttpRuntimeXmlElement() { @@ -94,9 +76,6 @@ class HttpRuntimeXmlElement extends XmlElement { } } -/** DEPRECATED: Alias for HttpRuntimeXmlElement */ -deprecated class HttpRuntimeXMLElement = HttpRuntimeXmlElement; - /** A `<forms>` tag under `<system.web><authentication>` in an ASP.NET configuration file. */ class FormsElement extends XmlElement { FormsElement() { diff --git a/csharp/ql/lib/semmle/code/cil/Types.qll b/csharp/ql/lib/semmle/code/cil/Types.qll index 0e41fe748f4..2cfc09daf99 100644 --- a/csharp/ql/lib/semmle/code/cil/Types.qll +++ b/csharp/ql/lib/semmle/code/cil/Types.qll @@ -60,11 +60,6 @@ class Class extends ValueOrRefType { Class() { this.isClass() } } -/** A `record`. */ -deprecated class Record extends Class { - Record() { this.isRecord() } -} - /** An `interface`. */ class Interface extends ValueOrRefType { Interface() { this.isInterface() } diff --git a/csharp/ql/lib/semmle/code/csharp/Type.qll b/csharp/ql/lib/semmle/code/csharp/Type.qll index 8bb92c8c86a..85fde20e07d 100644 --- a/csharp/ql/lib/semmle/code/csharp/Type.qll +++ b/csharp/ql/lib/semmle/code/csharp/Type.qll @@ -780,16 +780,6 @@ class Class extends RefType, @class_type { override string getAPrimaryQlClass() { result = "Class" } } -/** - * DEPRECATED: Use `RecordClass` instead. - */ -deprecated class Record extends Class { - Record() { this.isRecord() } - - /** Gets the clone method of this record. */ - RecordCloneMethod getCloneMethod() { result = this.getAMember() } -} - /** * A `record`, for example * diff --git a/csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll b/csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll index 21102edb755..ca009448c10 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/StructuralComparison.qll @@ -200,45 +200,3 @@ predicate sameGvn(ControlFlowElement x, ControlFlowElement y) { pragma[only_bind_into](toGvn(pragma[only_bind_out](x))) = pragma[only_bind_into](toGvn(pragma[only_bind_out](y))) } - -/** - * DEPRECATED: Use `sameGvn` instead. - * - * A configuration for performing structural comparisons of program elements - * (expressions and statements). - * - * The predicate `candidate()` must be overridden, in order to identify the - * elements for which to perform structural comparison. - * - * Each use of the library is identified by a unique string value. - */ -abstract deprecated class StructuralComparisonConfiguration extends string { - bindingset[this] - StructuralComparisonConfiguration() { any() } - - /** - * Holds if elements `x` and `y` are candidates for testing structural - * equality. - * - * Subclasses are expected to override this predicate to identify the - * top-level elements which they want to compare. Care should be - * taken to avoid identifying too many pairs of elements, as in general - * there are very many structurally equal subtrees in a program, and - * in order to keep the computation feasible we must focus attention. - * - * Note that this relation is not expected to be symmetric -- it's - * fine to include a pair `(x, y)` but not `(y, x)`. - * In fact, not including the symmetrically implied fact will save - * half the computation time on the structural comparison. - */ - abstract predicate candidate(ControlFlowElement x, ControlFlowElement y); - - /** - * Holds if elements `x` and `y` structurally equal. `x` and `y` must be - * flagged as candidates for structural equality, that is, - * `candidate(x, y)` must hold. - */ - predicate same(ControlFlowElement x, ControlFlowElement y) { - this.candidate(x, y) and sameGvn(x, y) - } -} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index b22712087f2..b3599e3404e 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -106,16 +106,6 @@ class ParameterNode extends Node instanceof ParameterNodeImpl { result = c.asCallable().getParameter(ppos.getPosition()) ) } - - /** - * DEPRECATED - * - * Holds if this node is the parameter of callable `c` at the specified - * (zero-based) position. - */ - deprecated predicate isParameterOf(DataFlowCallable c, int i) { - super.isParameterOf(c, any(ParameterPosition pos | i = pos.getPosition())) - } } /** A definition, viewed as a node in a data flow graph. */ diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll index 235897f0742..975dae84fcb 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll @@ -14,9 +14,6 @@ private import semmle.code.csharp.dataflow.FlowSummary */ abstract class SafeExternalApiCallable extends Callable { } -/** DEPRECATED: Alias for SafeExternalApiCallable */ -deprecated class SafeExternalAPICallable = SafeExternalApiCallable; - private class SummarizedCallableSafe extends SafeExternalApiCallable instanceof SummarizedCallable { } @@ -87,9 +84,6 @@ class ExternalApiDataNode extends DataFlow::Node { } } -/** DEPRECATED: Alias for ExternalApiDataNode */ -deprecated class ExternalAPIDataNode = ExternalApiDataNode; - /** * DEPRECATED: Use `RemoteSourceToExternalApi` instead. * @@ -113,9 +107,6 @@ private module RemoteSourceToExternalApiConfig implements DataFlow::ConfigSig { /** A module for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ module RemoteSourceToExternalApi = TaintTracking::Global<RemoteSourceToExternalApiConfig>; -/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ -deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; - /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { UntrustedExternalApiDataNode() { RemoteSourceToExternalApi::flow(_, this) } @@ -124,9 +115,6 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode { DataFlow::Node getAnUntrustedSource() { RemoteSourceToExternalApi::flow(result, this) } } -/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ -deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; - /** An external API which is used with untrusted data. */ private newtype TExternalApi = /** An untrusted API method `m` where untrusted data is passed at `index`. */ @@ -161,6 +149,3 @@ class ExternalApiUsedWithUntrustedData extends TExternalApi { ) } } - -/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ -deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll index 9171bae41b4..3f9c5947b68 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/LDAPInjectionQuery.qll @@ -149,9 +149,6 @@ class LdapEncodeSanitizer extends Sanitizer { } } -/** DEPRECATED: Alias for LdapEncodeSanitizer */ -deprecated class LDAPEncodeSanitizer = LdapEncodeSanitizer; - private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { } diff --git a/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll b/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll index 169de03c2dc..bb3eb683653 100644 --- a/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll @@ -73,9 +73,6 @@ module UnaliasedSsaInstructions { } } -/** DEPRECATED: Alias for UnaliasedSsaInstructions */ -deprecated module UnaliasedSSAInstructions = UnaliasedSsaInstructions; - /** * Provides wrappers for the constructors of each branch of `TInstruction` that is used by the * aliased SSA stage. @@ -107,6 +104,3 @@ module AliasedSsaInstructions { result = TAliasedSsaUnreachedInstruction(irFunc) } } - -/** DEPRECATED: Alias for AliasedSsaInstructions */ -deprecated module AliasedSSAInstructions = AliasedSsaInstructions; diff --git a/csharp/ql/src/experimental/ir/implementation/internal/TOperand.qll b/csharp/ql/src/experimental/ir/implementation/internal/TOperand.qll index 6327c603901..cf8a6a9b7b1 100644 --- a/csharp/ql/src/experimental/ir/implementation/internal/TOperand.qll +++ b/csharp/ql/src/experimental/ir/implementation/internal/TOperand.qll @@ -59,20 +59,12 @@ private module Shared { class TNonSsaMemoryOperand = Internal::TNonSsaMemoryOperand; - /** DEPRECATED: Alias for TNonSsaMemoryOperand */ - deprecated class TNonSSAMemoryOperand = TNonSsaMemoryOperand; - /** * Returns the non-Phi memory operand with the specified parameters. */ TNonSsaMemoryOperand nonSsaMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { result = Internal::TNonSsaMemoryOperand(useInstr, tag) } - - /** DEPRECATED: Alias for nonSsaMemoryOperand */ - deprecated TNonSSAMemoryOperand nonSSAMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { - result = nonSsaMemoryOperand(useInstr, tag) - } } /** @@ -156,6 +148,3 @@ module UnaliasedSsaOperands { */ TChiOperand chiOperand(Unaliased::Instruction useInstr, ChiOperandTag tag) { none() } } - -/** DEPRECATED: Alias for UnaliasedSsaOperands */ -deprecated module UnaliasedSSAOperands = UnaliasedSsaOperands; diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll index 0aa7c552638..1b5ea432946 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -210,9 +210,6 @@ class Instruction extends Construction::TStageInstruction { */ final Language::AST getAst() { result = Construction::getInstructionAst(this) } - /** DEPRECATED: Alias for getAst */ - deprecated Language::AST getAST() { result = this.getAst() } - /** * Gets the location of the source code for this instruction. */ @@ -463,9 +460,6 @@ class VariableInstruction extends Instruction { * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } - - /** DEPRECATED: Alias for getAstVariable */ - deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll index c75c279226d..8297fedb28e 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/IRConstruction.qll @@ -378,12 +378,6 @@ private module Cached { result = getInstructionTranslatedElement(instruction).getAst() } - /** DEPRECATED: Alias for getInstructionAst */ - cached - deprecated Language::AST getInstructionAST(Instruction instruction) { - result = getInstructionAst(instruction) - } - cached CSharpType getInstructionResultType(Instruction instruction) { getInstructionTranslatedElement(instruction) diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll index 43db3c90065..afe98fdb410 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll @@ -17,9 +17,6 @@ abstract class TranslatedCondition extends ConditionBase { final override Language::AST getAst() { result = expr } - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } - final Expr getExpr() { result = expr } final override Callable getFunction() { result = expr.getEnclosingCallable() } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll index 20d2b1e3459..23242c75c74 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll @@ -30,9 +30,6 @@ abstract class TranslatedLocalDeclaration extends TranslatedElement, TTranslated final override string toString() { result = expr.toString() } final override Language::AST getAst() { result = expr } - - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } } /** diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll index 4c5ab431dd5..c314d79e3ea 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll @@ -366,9 +366,6 @@ abstract class TranslatedElement extends TTranslatedElement { */ abstract Language::AST getAst(); - /** DEPRECATED: Alias for getAst */ - deprecated Language::AST getAST() { result = this.getAst() } - /** * Get the first instruction to be executed in the evaluation of this element. */ diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll index 67ebf19b766..68070261227 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll @@ -63,9 +63,6 @@ abstract class TranslatedExpr extends TranslatedExprBase { final override Language::AST getAst() { result = expr } - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } - final override Callable getFunction() { result = expr.getEnclosingCallable() } /** diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll index 24f340a8718..f0970984d46 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll @@ -30,9 +30,6 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { final override Language::AST getAst() { result = callable } - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } - /** * Gets the function being translated. */ @@ -287,9 +284,6 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter { final override Language::AST getAst() { result = param } - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } - final override Callable getFunction() { result = param.getCallable() } final override Instruction getFirstInstruction() { diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll index bc127680ca4..c7cb9232d55 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll @@ -52,9 +52,6 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn final override Language::AST getAst() { result = expr } - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } - /** * Gets the expression that is doing the initialization. */ @@ -210,9 +207,6 @@ abstract class TranslatedElementInitialization extends TranslatedElement { final override Language::AST getAst() { result = initList } - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } - final override Callable getFunction() { result = initList.getEnclosingCallable() } final override Instruction getFirstInstruction() { @@ -319,9 +313,6 @@ abstract class TranslatedConstructorCallFromConstructor extends TranslatedElemen final override Language::AST getAst() { result = call } - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } - final override TranslatedElement getChild(int id) { id = 0 and result = this.getConstructorCall() } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll index 1afc48d0409..71d8c42e170 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll @@ -26,9 +26,6 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt { final override Language::AST getAst() { result = stmt } - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } - final override Callable getFunction() { result = stmt.getEnclosingCallable() } } diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll index 0aa7c552638..1b5ea432946 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll @@ -210,9 +210,6 @@ class Instruction extends Construction::TStageInstruction { */ final Language::AST getAst() { result = Construction::getInstructionAst(this) } - /** DEPRECATED: Alias for getAst */ - deprecated Language::AST getAST() { result = this.getAst() } - /** * Gets the location of the source code for this instruction. */ @@ -463,9 +460,6 @@ class VariableInstruction extends Instruction { * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } - - /** DEPRECATED: Alias for getAstVariable */ - deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index dc785f3e0b1..63dc4142a13 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -422,12 +422,6 @@ private module Cached { ) } - /** DEPRECATED: Alias for getInstructionAst */ - cached - deprecated Language::AST getInstructionAST(Instruction instr) { - result = getInstructionAst(instr) - } - cached Language::LanguageType getInstructionResultType(Instruction instr) { result = instr.(RawIR::Instruction).getResultLanguageType() @@ -993,9 +987,6 @@ predicate canReuseSsaForMemoryResult(Instruction instruction) { // We don't support reusing SSA for any location that could create a `Chi` instruction. } -/** DEPRECATED: Alias for canReuseSsaForMemoryResult */ -deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1; - /** * Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the * `DebugSsa` module, which is then imported by PrintSSA. @@ -1005,9 +996,6 @@ module DebugSsa { import DefUse } -/** DEPRECATED: Alias for DebugSsa */ -deprecated module DebugSSA = DebugSsa; - import CachedForDebugging cached diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll index f5b0b3af930..5c33ecf5f99 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll @@ -46,9 +46,6 @@ predicate canReuseSsaForVariable(IRAutomaticVariable var) { not allocationEscapes(var) } -/** DEPRECATED: Alias for canReuseSsaForVariable */ -deprecated predicate canReuseSSAForVariable = canReuseSsaForVariable/1; - private newtype TMemoryLocation = MkMemoryLocation(Allocation var) { isVariableModeled(var) } private MemoryLocation getMemoryLocation(Allocation var) { result.getAllocation() = var } @@ -80,9 +77,6 @@ class MemoryLocation extends TMemoryLocation { predicate canReuseSsaForOldResult(Instruction instr) { none() } -/** DEPRECATED: Alias for canReuseSsaForOldResult */ -deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1; - /** * Represents a set of `MemoryLocation`s that cannot overlap with * `MemoryLocation`s outside of the set. The `VirtualVariable` will be diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index 0e0d0acea3f..92c81650bc3 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -1809,9 +1809,6 @@ class LValue extends VarAccess { * are source expressions of the assignment. */ Expr getRhs() { exists(Assignment e | e.getDest() = this and e.getSource() = result) } - - /** DEPRECATED: Alias for getRhs */ - deprecated Expr getRHS() { result = this.getRhs() } } /** diff --git a/java/ql/lib/semmle/code/java/controlflow/internal/Preconditions.qll b/java/ql/lib/semmle/code/java/controlflow/internal/Preconditions.qll index 6b7736cb70d..3563176f4b0 100644 --- a/java/ql/lib/semmle/code/java/controlflow/internal/Preconditions.qll +++ b/java/ql/lib/semmle/code/java/controlflow/internal/Preconditions.qll @@ -6,15 +6,6 @@ import java -/** - * DEPRECATED: Use `conditionCheckMethodArgument` instead. - * Holds if `m` is a non-overridable method that checks that its first argument - * is equal to `checkTrue` and throws otherwise. - */ -deprecated predicate conditionCheckMethod(Method m, boolean checkTrue) { - conditionCheckMethodArgument(m, 0, checkTrue) -} - /** * Holds if `m` is a non-overridable method that checks that its zero-indexed `argument` * is equal to `checkTrue` and throws otherwise. diff --git a/java/ql/lib/semmle/code/java/dataflow/SSA.qll b/java/ql/lib/semmle/code/java/dataflow/SSA.qll index d4ff7ed0ac7..dd478b2a869 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SSA.qll @@ -931,9 +931,6 @@ class SsaVariable extends TSsaVariable { this = TSsaUntracked(_, result) } - /** DEPRECATED: Alias for getCfgNode */ - deprecated ControlFlowNode getCFGNode() { result = this.getCfgNode() } - /** Gets a textual representation of this SSA variable. */ string toString() { none() } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll index 6f53dbd02c1..6e41c803553 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll @@ -483,9 +483,6 @@ class BaseSsaVariable extends TBaseSsaVariable { this = TSsaEntryDef(_, result) } - /** DEPRECATED: Alias for getCfgNode */ - deprecated ControlFlowNode getCFGNode() { result = this.getCfgNode() } - string toString() { none() } Location getLocation() { result = this.getCfgNode().getLocation() } diff --git a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll index 2213960222e..5c037258309 100644 --- a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll @@ -456,9 +456,6 @@ class ArbitraryXmlEntryPoint extends ReflectivelyConstructedClass { } } -/** DEPRECATED: Alias for ArbitraryXmlEntryPoint */ -deprecated class ArbitraryXMLEntryPoint = ArbitraryXmlEntryPoint; - /** A Selenium PageObject, created by a call to PageFactory.initElements(..). */ class SeleniumPageObjectEntryPoint extends ReflectivelyConstructedClass instanceof SeleniumPageObject { } diff --git a/java/ql/lib/semmle/code/java/frameworks/Networking.qll b/java/ql/lib/semmle/code/java/frameworks/Networking.qll index 8f86c8f75e7..c473cc9fc09 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Networking.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Networking.qll @@ -38,9 +38,6 @@ class UrlConnectionGetInputStreamMethod extends Method { } } -/** DEPRECATED: Alias for UrlConnectionGetInputStreamMethod */ -deprecated class URLConnectionGetInputStreamMethod = UrlConnectionGetInputStreamMethod; - /** The method `java.net.Socket::getInputStream`. */ class SocketGetInputStreamMethod extends Method { SocketGetInputStreamMethod() { diff --git a/java/ql/lib/semmle/code/java/frameworks/Servlets.qll b/java/ql/lib/semmle/code/java/frameworks/Servlets.qll index 82e837862be..f2de51b2aab 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Servlets.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Servlets.qll @@ -128,9 +128,6 @@ class HttpServletRequestGetRequestUrlMethod extends Method { } } -/** DEPRECATED: Alias for HttpServletRequestGetRequestUrlMethod */ -deprecated class HttpServletRequestGetRequestURLMethod = HttpServletRequestGetRequestUrlMethod; - /** * The method `getRequestURI()` declared in `javax.servlet.http.HttpServletRequest`. */ @@ -339,9 +336,6 @@ class ServletWebXmlListenerType extends RefType { } } -/** DEPRECATED: Alias for ServletWebXmlListenerType */ -deprecated class ServletWebXMLListenerType = ServletWebXmlListenerType; - /** Holds if `m` is a request handler method (for example `doGet` or `doPost`). */ predicate isServletRequestMethod(Method m) { m.getDeclaringType() instanceof ServletClass and diff --git a/java/ql/lib/semmle/code/java/frameworks/UnboundId.qll b/java/ql/lib/semmle/code/java/frameworks/UnboundId.qll index e19a6b43019..8bab6dfe581 100644 --- a/java/ql/lib/semmle/code/java/frameworks/UnboundId.qll +++ b/java/ql/lib/semmle/code/java/frameworks/UnboundId.qll @@ -29,9 +29,6 @@ class TypeUnboundIdLdapConnection extends Class { } } -/** DEPRECATED: Alias for TypeUnboundIdLdapConnection */ -deprecated class TypeUnboundIdLDAPConnection = TypeUnboundIdLdapConnection; - /*--- Methods ---*/ /** A method with the name `setBaseDN` declared in `com.unboundid.ldap.sdk.SearchRequest`. */ class MethodUnboundIdSearchRequestSetBaseDN extends Method { @@ -103,9 +100,6 @@ class MethodUnboundIdLdapConnectionSearch extends Method { } } -/** DEPRECATED: Alias for MethodUnboundIdLdapConnectionSearch */ -deprecated class MethodUnboundIdLDAPConnectionSearch = MethodUnboundIdLdapConnectionSearch; - /** A method with the name `asyncSearch` declared in `com.unboundid.ldap.sdk.LDAPConnection`. */ class MethodUnboundIdLdapConnectionAsyncSearch extends Method { MethodUnboundIdLdapConnectionAsyncSearch() { @@ -114,10 +108,6 @@ class MethodUnboundIdLdapConnectionAsyncSearch extends Method { } } -/** DEPRECATED: Alias for MethodUnboundIdLdapConnectionAsyncSearch */ -deprecated class MethodUnboundIdLDAPConnectionAsyncSearch = - MethodUnboundIdLdapConnectionAsyncSearch; - /** A method with the name `searchForEntry` declared in `com.unboundid.ldap.sdk.LDAPConnection`. */ class MethodUnboundIdLdapConnectionSearchForEntry extends Method { MethodUnboundIdLdapConnectionSearchForEntry() { @@ -125,7 +115,3 @@ class MethodUnboundIdLdapConnectionSearchForEntry extends Method { this.hasName("searchForEntry") } } - -/** DEPRECATED: Alias for MethodUnboundIdLdapConnectionSearchForEntry */ -deprecated class MethodUnboundIdLDAPConnectionSearchForEntry = - MethodUnboundIdLdapConnectionSearchForEntry; diff --git a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll index 79fd19f4ef2..f1395431a3c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -20,9 +20,6 @@ class JacksonJsonIgnoreAnnotation extends NonReflectiveAnnotation { } } -/** DEPRECATED: Alias for JacksonJsonIgnoreAnnotation */ -deprecated class JacksonJSONIgnoreAnnotation = JacksonJsonIgnoreAnnotation; - /** A type whose values may be serialized using the Jackson JSON framework. */ abstract class JacksonSerializableType extends Type { } diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/PersistenceXML.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/PersistenceXML.qll index faca537d171..7564dafa37e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/PersistenceXML.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/PersistenceXML.qll @@ -26,9 +26,6 @@ class PersistenceXmlFile extends XmlFile { } } -/** DEPRECATED: Alias for PersistenceXmlFile */ -deprecated class PersistenceXMLFile = PersistenceXmlFile; - /** The root `persistence` XML element in a `persistence.xml` file. */ class PersistenceXmlRoot extends XmlElement { PersistenceXmlRoot() { diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBJarXML.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBJarXML.qll index 9323b3852b4..f44d77d89bd 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBJarXML.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBJarXML.qll @@ -35,9 +35,6 @@ class EjbJarXmlFile extends XmlFile { } } -/** DEPRECATED: Alias for EjbJarXmlFile */ -deprecated class EjbJarXMLFile = EjbJarXmlFile; - /** The root `ejb-jar` XML element in an `ejb-jar.xml` file. */ class EjbJarRootElement extends XmlElement { EjbJarRootElement() { diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFFacesContextXML.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFFacesContextXML.qll index f85f36c37a3..13ed765638d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFFacesContextXML.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/jsf/JSFFacesContextXML.qll @@ -16,9 +16,6 @@ class FacesConfigXmlFile extends XmlFile { } } -/** DEPRECATED: Alias for FacesConfigXmlFile */ -deprecated class FacesConfigXMLFile = FacesConfigXmlFile; - /** * An XML element in a `FacesConfigXMLFile`. */ @@ -31,9 +28,6 @@ class FacesConfigXmlElement extends XmlElement { string getValue() { result = this.allCharactersString().trim() } } -/** DEPRECATED: Alias for FacesConfigXmlElement */ -deprecated class FacesConfigXMLElement = FacesConfigXmlElement; - /** * An element in a JSF config file that declares a managed bean. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAutowire.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAutowire.qll index 1dd6dfd292f..966db95afce 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringAutowire.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringAutowire.qll @@ -100,9 +100,6 @@ class SpringBeanXmlAutowiredSetterMethod extends Method { } } -/** DEPRECATED: Alias for SpringBeanXmlAutowiredSetterMethod */ -deprecated class SpringBeanXMLAutowiredSetterMethod = SpringBeanXmlAutowiredSetterMethod; - /** * A callable that is annotated with `@Autowired`. * diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringCamel.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringCamel.qll index 9bbdaad9687..985565255b6 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringCamel.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringCamel.qll @@ -13,9 +13,6 @@ class SpringCamelXmlElement extends SpringXmlElement { SpringCamelXmlElement() { this.getNamespace().getUri() = "http://camel.apache.org/schema/spring" } } -/** DEPRECATED: Alias for SpringCamelXmlElement */ -deprecated class SpringCamelXMLElement = SpringCamelXmlElement; - /** * An element in a Spring beans file that defines an Apache Camel context. * @@ -25,9 +22,6 @@ class SpringCamelXmlContext extends SpringCamelXmlElement { SpringCamelXmlContext() { this.getName() = "camelContext" } } -/** DEPRECATED: Alias for SpringCamelXmlContext */ -deprecated class SpringCamelXMLContext = SpringCamelXmlContext; - /** * An element in a Spring beans file that defines an Apache Camel route context. * @@ -38,9 +32,6 @@ class SpringCamelXmlRouteContext extends SpringCamelXmlElement { SpringCamelXmlRouteContext() { this.getName() = "routeContext" } } -/** DEPRECATED: Alias for SpringCamelXmlRouteContext */ -deprecated class SpringCamelXMLRouteContext = SpringCamelXmlRouteContext; - /** * An element in a Spring beans files that defines an Apache Camel route. * @@ -58,9 +49,6 @@ class SpringCamelXmlRoute extends SpringCamelXmlElement { } } -/** DEPRECATED: Alias for SpringCamelXmlRoute */ -deprecated class SpringCamelXMLRoute = SpringCamelXmlRoute; - /** * An element in a Spring bean file that is logically contained in an Apache Camel route. */ @@ -71,9 +59,6 @@ class SpringCamelXmlRouteElement extends SpringCamelXmlElement { } } -/** DEPRECATED: Alias for SpringCamelXmlRouteElement */ -deprecated class SpringCamelXMLRouteElement = SpringCamelXmlRouteElement; - /** * A reference to a Spring bean in an Apache Camel route defined in a Spring beans file. * @@ -98,9 +83,6 @@ class SpringCamelXmlBeanRef extends SpringCamelXmlRouteElement { RefType getBeanType() { result.getQualifiedName() = this.getAttribute("beanType").getValue() } } -/** DEPRECATED: Alias for SpringCamelXmlBeanRef */ -deprecated class SpringCamelXMLBeanRef = SpringCamelXmlBeanRef; - /** * A declaration of a target in an Apache Camel route defined in a Spring beans file. * @@ -120,9 +102,6 @@ class SpringCamelXmlToElement extends SpringCamelXmlRouteElement { deprecated string getURI() { result = this.getUri() } } -/** DEPRECATED: Alias for SpringCamelXmlToElement */ -deprecated class SpringCamelXMLToElement = SpringCamelXmlToElement; - /** * A declaration of a Apache Camel "method" expression defined in a Spring beans file. * @@ -147,6 +126,3 @@ class SpringCamelXmlMethodElement extends SpringCamelXmlElement { */ RefType getBeanType() { result.getQualifiedName() = this.getAttribute("beanType").getValue() } } - -/** DEPRECATED: Alias for SpringCamelXmlMethodElement */ -deprecated class SpringCamelXMLMethodElement = SpringCamelXmlMethodElement; diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringComponentScan.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringComponentScan.qll index f3380c45458..d285e9d0e6a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringComponentScan.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringComponentScan.qll @@ -23,9 +23,6 @@ class SpringXmlComponentScan extends SpringXmlElement { string getAProfileExpr() { result = this.getSpringBeanFile().getAProfileExpr() } } -/** DEPRECATED: Alias for SpringXmlComponentScan */ -deprecated class SpringXMLComponentScan = SpringXmlComponentScan; - /** * An annotation of a class that configures which packages are considered to be "base" packages * when performing the Spring component scan. diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringFlex.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringFlex.qll index 0d18749a63e..af0afa91f4c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringFlex.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringFlex.qll @@ -57,11 +57,6 @@ class SpringRemotingDestinationClass extends Class { */ SpringRemotingDestination getRemotingDestinationXml() { this = result.getSpringBean().getClass() } - /** DEPRECATED: Alias for getRemotingDestinationXml */ - deprecated SpringRemotingDestination getRemotingDestinationXML() { - result = this.getRemotingDestinationXml() - } - /** * Holds if the class is operating on an "include" or "exclude" basis. * diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringXMLElement.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringXMLElement.qll index efc7dfdaaf2..312cd659b39 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringXMLElement.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringXMLElement.qll @@ -37,6 +37,3 @@ class SpringXmlElement extends XmlElement { string getContentString() { result = this.allCharactersString() } } - -/** DEPRECATED: Alias for SpringXmlElement */ -deprecated class SpringXMLElement = SpringXmlElement; diff --git a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsConventions.qll b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsConventions.qll index fd9f14d4c6f..b3adfa8d80e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsConventions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsConventions.qll @@ -77,9 +77,6 @@ StrutsXmlFile getRootXmlFile(RefType refType) { ) } -/** DEPRECATED: Alias for getRootXmlFile */ -deprecated StrutsXMLFile getRootXMLFile(RefType refType) { result = getRootXmlFile(refType) } - /** * Gets the suffix used for automatically identifying actions when using the convention plugin. * diff --git a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsXML.qll b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsXML.qll index 3009056cce3..273034978d1 100644 --- a/java/ql/lib/semmle/code/java/frameworks/struts/StrutsXML.qll +++ b/java/ql/lib/semmle/code/java/frameworks/struts/StrutsXML.qll @@ -5,9 +5,6 @@ import java */ predicate isStrutsXmlIncluded() { exists(StrutsXmlFile strutsXml) } -/** DEPRECATED: Alias for isStrutsXmlIncluded */ -deprecated predicate isStrutsXMLIncluded = isStrutsXmlIncluded/0; - /** * A struts 2 configuration file. */ @@ -51,9 +48,6 @@ abstract class StrutsXmlFile extends XmlFile { } } -/** DEPRECATED: Alias for StrutsXmlFile */ -deprecated class StrutsXMLFile = StrutsXmlFile; - /** * A Struts 2 "root" configuration XML file directly read by struts. * @@ -66,9 +60,6 @@ class StrutsRootXmlFile extends StrutsXmlFile { } } -/** DEPRECATED: Alias for StrutsRootXmlFile */ -deprecated class StrutsRootXMLFile = StrutsRootXmlFile; - /** * A Struts 2 configuration XML file included, directly or indirectly, by a root Struts configuration. */ @@ -76,9 +67,6 @@ class StrutsIncludedXmlFile extends StrutsXmlFile { StrutsIncludedXmlFile() { exists(StrutsXmlInclude include | this = include.getIncludedFile()) } } -/** DEPRECATED: Alias for StrutsIncludedXmlFile */ -deprecated class StrutsIncludedXMLFile = StrutsIncludedXmlFile; - /** * A Folder which has one or more Struts 2 root configurations. */ @@ -116,9 +104,6 @@ class StrutsXmlElement extends XmlElement { string getValue() { result = this.allCharactersString().trim() } } -/** DEPRECATED: Alias for StrutsXmlElement */ -deprecated class StrutsXMLElement = StrutsXmlElement; - /** * A `<include>` element within a `struts.xml` file. * @@ -141,9 +126,6 @@ class StrutsXmlInclude extends StrutsXmlElement { } } -/** DEPRECATED: Alias for StrutsXmlInclude */ -deprecated class StrutsXMLInclude = StrutsXmlInclude; - /** * Escape a string for use as the matcher in a string.match(..) call. */ @@ -192,9 +174,6 @@ class StrutsXmlAction extends StrutsXmlElement { } } -/** DEPRECATED: Alias for StrutsXmlAction */ -deprecated class StrutsXMLAction = StrutsXmlAction; - /** * A `<constant>` property, representing a configuration parameter to struts. */ @@ -205,6 +184,3 @@ class StrutsXmlConstant extends StrutsXmlElement { string getConstantValue() { result = this.getAttribute("value").getValue() } } - -/** DEPRECATED: Alias for StrutsXmlConstant */ -deprecated class StrutsXMLConstant = StrutsXmlConstant; diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index c0c35103331..88a1996ffd9 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -25,9 +25,6 @@ class HttpsUrlConnection extends RefType { HttpsUrlConnection() { this.hasQualifiedName("javax.net.ssl", "HttpsURLConnection") } } -/** DEPRECATED: Alias for HttpsUrlConnection */ -deprecated class HttpsURLConnection = HttpsUrlConnection; - class SslSocketFactory extends RefType { SslSocketFactory() { this.hasQualifiedName("javax.net.ssl", "SSLSocketFactory") } } diff --git a/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll b/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll index 89b24006475..beef024eb15 100644 --- a/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll +++ b/java/ql/lib/semmle/code/java/security/ExternalAPIs.qll @@ -12,9 +12,6 @@ import semmle.code.java.dataflow.TaintTracking */ abstract class SafeExternalApiMethod extends Method { } -/** DEPRECATED: Alias for SafeExternalApiMethod */ -deprecated class SafeExternalAPIMethod = SafeExternalApiMethod; - /** The default set of "safe" external APIs. */ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod { DefaultSafeExternalApiMethod() { @@ -95,9 +92,6 @@ class ExternalApiDataNode extends DataFlow::Node { string getMethodDescription() { result = this.getMethod().getQualifiedName() } } -/** DEPRECATED: Alias for ExternalApiDataNode */ -deprecated class ExternalAPIDataNode = ExternalApiDataNode; - /** * DEPRECATED: Use `UntrustedDataToExternalApiFlow` instead. * @@ -125,9 +119,6 @@ module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { */ module UntrustedDataToExternalApiFlow = TaintTracking::Global<UntrustedDataToExternalApiConfig>; -/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ -deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; - /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flowTo(this) } @@ -136,9 +127,6 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode { DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } } -/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ -deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; - /** An external API which is used with untrusted data. */ private newtype TExternalApi = /** An untrusted API method `m` where untrusted data is passed at `index`. */ @@ -172,6 +160,3 @@ class ExternalApiUsedWithUntrustedData extends TExternalApi { ) } } - -/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ -deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/java/ql/lib/semmle/code/java/security/XmlParsers.qll b/java/ql/lib/semmle/code/java/security/XmlParsers.qll index a079267b131..ded513ec656 100644 --- a/java/ql/lib/semmle/code/java/security/XmlParsers.qll +++ b/java/ql/lib/semmle/code/java/security/XmlParsers.qll @@ -337,9 +337,6 @@ class SaxBuilder extends RefType { } } -/** DEPRECATED: Alias for SaxBuilder */ -deprecated class SAXBuilder = SaxBuilder; - /** * A call to `SAXBuilder.build.` */ @@ -359,9 +356,6 @@ class SaxBuilderParse extends XmlParserCall { } } -/** DEPRECATED: Alias for SaxBuilderParse */ -deprecated class SAXBuilderParse = SaxBuilderParse; - private module SafeSaxBuilderToSaxBuilderParseFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxBuilder } @@ -386,9 +380,6 @@ class SaxBuilderConfig extends ParserConfig { } } -/** DEPRECATED: Alias for SaxBuilderConfig */ -deprecated class SAXBuilderConfig = SaxBuilderConfig; - /** A safely configured `SaxBuilder`. */ class SafeSaxBuilder extends VarAccess { SafeSaxBuilder() { @@ -404,9 +395,6 @@ class SafeSaxBuilder extends VarAccess { } } -/** DEPRECATED: Alias for SafeSaxBuilder */ -deprecated class SafeSAXBuilder = SafeSaxBuilder; - /* * The case in * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxb-unmarshaller @@ -420,17 +408,11 @@ class SaxParser extends RefType { SaxParser() { this.hasQualifiedName("javax.xml.parsers", "SAXParser") } } -/** DEPRECATED: Alias for SaxParser */ -deprecated class SAXParser = SaxParser; - /** The class `javax.xml.parsers.SAXParserFactory`. */ class SaxParserFactory extends RefType { SaxParserFactory() { this.hasQualifiedName("javax.xml.parsers", "SAXParserFactory") } } -/** DEPRECATED: Alias for SaxParserFactory */ -deprecated class SAXParserFactory = SaxParserFactory; - /** A call to `SAXParser.parse`. */ class SaxParserParse extends XmlParserCall { SaxParserParse() { @@ -446,9 +428,6 @@ class SaxParserParse extends XmlParserCall { override predicate isSafe() { SafeSaxParserFlow::flowToExpr(this.getQualifier()) } } -/** DEPRECATED: Alias for SaxParserParse */ -deprecated class SAXParserParse = SaxParserParse; - /** A `ParserConfig` that is specific to `SaxParserFactory`. */ class SaxParserFactoryConfig extends ParserConfig { SaxParserFactoryConfig() { @@ -460,9 +439,6 @@ class SaxParserFactoryConfig extends ParserConfig { } } -/** DEPRECATED: Alias for SaxParserFactoryConfig */ -deprecated class SAXParserFactoryConfig = SaxParserFactoryConfig; - /** * A safely configured `SAXParserFactory`. */ @@ -496,9 +472,6 @@ class SafeSaxParserFactory extends VarAccess { } } -/** DEPRECATED: Alias for SafeSaxParserFactory */ -deprecated class SafeSAXParserFactory = SafeSaxParserFactory; - private module SafeSaxParserFactoryToNewSaxParserFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxParserFactory } @@ -540,9 +513,6 @@ class SafeSaxParser extends MethodAccess { } } -/** DEPRECATED: Alias for SafeSaxParser */ -deprecated class SafeSAXParser = SafeSaxParser; - /* SAXReader: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#saxreader */ /** * The class `org.dom4j.io.SAXReader`. @@ -551,9 +521,6 @@ class SaxReader extends RefType { SaxReader() { this.hasQualifiedName("org.dom4j.io", "SAXReader") } } -/** DEPRECATED: Alias for SaxReader */ -deprecated class SAXReader = SaxReader; - /** A call to `SAXReader.read`. */ class SaxReaderRead extends XmlParserCall { SaxReaderRead() { @@ -569,9 +536,6 @@ class SaxReaderRead extends XmlParserCall { override predicate isSafe() { SafeSaxReaderFlow::flowToExpr(this.getQualifier()) } } -/** DEPRECATED: Alias for SaxReaderRead */ -deprecated class SAXReaderRead = SaxReaderRead; - /** A `ParserConfig` specific to `SaxReader`. */ class SaxReaderConfig extends ParserConfig { SaxReaderConfig() { @@ -583,9 +547,6 @@ class SaxReaderConfig extends ParserConfig { } } -/** DEPRECATED: Alias for SaxReaderConfig */ -deprecated class SAXReaderConfig = SaxReaderConfig; - private module SafeSaxReaderFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSaxReader } @@ -626,9 +587,6 @@ class SafeSaxReader extends VarAccess { } } -/** DEPRECATED: Alias for SafeSaxReader */ -deprecated class SafeSAXReader = SafeSaxReader; - /* https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xmlreader */ /** The class `org.xml.sax.XMLReader`. */ class XmlReader extends RefType { @@ -640,9 +598,6 @@ class InputSource extends Class { InputSource() { this.hasQualifiedName("org.xml.sax", "InputSource") } } -/** DEPRECATED: Alias for XmlReader */ -deprecated class XMLReader = XmlReader; - /** A call to `XMLReader.read`. */ class XmlReaderParse extends XmlParserCall { XmlReaderParse() { @@ -661,9 +616,6 @@ class XmlReaderParse extends XmlParserCall { } } -/** DEPRECATED: Alias for XmlReaderParse */ -deprecated class XMLReaderParse = XmlReaderParse; - /** A `ParserConfig` specific to the `XmlReader`. */ class XmlReaderConfig extends ParserConfig { XmlReaderConfig() { @@ -675,9 +627,6 @@ class XmlReaderConfig extends ParserConfig { } } -/** DEPRECATED: Alias for XmlReaderConfig */ -deprecated class XMLReaderConfig = XmlReaderConfig; - private module ExplicitlySafeXmlReaderFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ExplicitlySafeXmlReader } @@ -697,9 +646,6 @@ class SafeXmlReaderFlowSink extends Expr { } } -/** DEPRECATED: Alias for SafeXmlReaderFlowSink */ -deprecated class SafeXMLReaderFlowSink = SafeXmlReaderFlowSink; - /** An `XmlReader` that is explicitly configured to be safe. */ class ExplicitlySafeXmlReader extends VarAccess { ExplicitlySafeXmlReader() { @@ -739,9 +685,6 @@ class ExplicitlySafeXmlReader extends VarAccess { } } -/** DEPRECATED: Alias for ExplicitlySafeXmlReader */ -deprecated class ExplicitlySafeXMLReader = ExplicitlySafeXmlReader; - private module CreatedSafeXmlReaderFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof CreatedSafeXmlReader } @@ -778,9 +721,6 @@ class CreatedSafeXmlReader extends Call { } } -/** DEPRECATED: Alias for CreatedSafeXmlReader */ -deprecated class CreatedSafeXMLReader = CreatedSafeXmlReader; - /* * SAXSource in * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxb-unmarshaller @@ -791,9 +731,6 @@ class SaxSource extends RefType { SaxSource() { this.hasQualifiedName("javax.xml.transform.sax", "SAXSource") } } -/** DEPRECATED: Alias for SaxSource */ -deprecated class SAXSource = SaxSource; - /** A call to the constructor of `SAXSource` with `XmlReader` and `InputSource`. */ class ConstructedSaxSource extends ClassInstanceExpr { ConstructedSaxSource() { @@ -814,9 +751,6 @@ class ConstructedSaxSource extends ClassInstanceExpr { } } -/** DEPRECATED: Alias for ConstructedSaxSource */ -deprecated class ConstructedSAXSource = ConstructedSaxSource; - /** A call to the `SAXSource.setXMLReader` method. */ class SaxSourceSetReader extends MethodAccess { SaxSourceSetReader() { @@ -828,9 +762,6 @@ class SaxSourceSetReader extends MethodAccess { } } -/** DEPRECATED: Alias for SaxSourceSetReader */ -deprecated class SAXSourceSetReader = SaxSourceSetReader; - /** A `SaxSource` that is safe to use. */ class SafeSaxSource extends Expr { SafeSaxSource() { @@ -847,9 +778,6 @@ class SafeSaxSource extends Expr { } } -/** DEPRECATED: Alias for SafeSaxSource */ -deprecated class SafeSAXSource = SafeSaxSource; - /* Transformer: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#transformerfactory */ /** An access to a method use for configuring a transformer or schema. */ abstract class TransformerConfig extends MethodAccess { @@ -1063,9 +991,6 @@ class SaxTransformerFactoryNewXmlFilter extends XmlParserCall { override predicate isSafe() { SafeTransformerFactoryFlow::flowToExpr(this.getQualifier()) } } -/** DEPRECATED: Alias for SaxTransformerFactoryNewXmlFilter */ -deprecated class SAXTransformerFactoryNewXMLFilter = SaxTransformerFactoryNewXmlFilter; - /* Schema: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#schemafactory */ /** The class `javax.xml.validation.SchemaFactory`. */ class SchemaFactory extends RefType { @@ -1197,9 +1122,6 @@ class SimpleXmlPersisterCall extends XmlParserCall { override predicate isSafe() { none() } } -/** DEPRECATED: Alias for SimpleXmlPersisterCall */ -deprecated class SimpleXMLPersisterCall = SimpleXmlPersisterCall; - /** A call to `provide` in `Provider`. */ class SimpleXmlProviderCall extends XmlParserCall { SimpleXmlProviderCall() { @@ -1218,9 +1140,6 @@ class SimpleXmlProviderCall extends XmlParserCall { override predicate isSafe() { none() } } -/** DEPRECATED: Alias for SimpleXmlProviderCall */ -deprecated class SimpleXMLProviderCall = SimpleXmlProviderCall; - /** A call to `read` in `NodeBuilder`. */ class SimpleXmlNodeBuilderCall extends XmlParserCall { SimpleXmlNodeBuilderCall() { @@ -1236,9 +1155,6 @@ class SimpleXmlNodeBuilderCall extends XmlParserCall { override predicate isSafe() { none() } } -/** DEPRECATED: Alias for SimpleXmlNodeBuilderCall */ -deprecated class SimpleXMLNodeBuilderCall = SimpleXmlNodeBuilderCall; - /** A call to the `format` method of the `Formatter`. */ class SimpleXmlFormatterCall extends XmlParserCall { SimpleXmlFormatterCall() { @@ -1254,9 +1170,6 @@ class SimpleXmlFormatterCall extends XmlParserCall { override predicate isSafe() { none() } } -/** DEPRECATED: Alias for SimpleXmlFormatterCall */ -deprecated class SimpleXMLFormatterCall = SimpleXmlFormatterCall; - /** A configuration for secure processing. */ Expr configSecureProcessing() { result.(ConstantStringExpr).getStringValue() = diff --git a/java/ql/lib/semmle/code/xml/WebXML.qll b/java/ql/lib/semmle/code/xml/WebXML.qll index c15793b58a4..c356081c95f 100644 --- a/java/ql/lib/semmle/code/xml/WebXML.qll +++ b/java/ql/lib/semmle/code/xml/WebXML.qll @@ -5,9 +5,6 @@ import java */ predicate isWebXmlIncluded() { exists(WebXmlFile webXml) } -/** DEPRECATED: Alias for isWebXmlIncluded */ -deprecated predicate isWebXMLIncluded = isWebXmlIncluded/0; - /** * A deployment descriptor file, typically called `web.xml`. */ @@ -31,9 +28,6 @@ class WebXmlFile extends XmlFile { } } -/** DEPRECATED: Alias for WebXmlFile */ -deprecated class WebXMLFile = WebXmlFile; - /** * An XML element in a `WebXMLFile`. */ @@ -46,9 +40,6 @@ class WebXmlElement extends XmlElement { string getValue() { result = this.allCharactersString().trim() } } -/** DEPRECATED: Alias for WebXmlElement */ -deprecated class WebXMLElement = WebXmlElement; - /** * A `<context-param>` element in a `web.xml` file. */ diff --git a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll index 85d3f36dfdf..377c7f74bd4 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisCommonLib.qll @@ -56,9 +56,6 @@ predicate myBatisMapperXmlElementFromMethod(Method method, MyBatisMapperXmlEleme ) } -/** DEPRECATED: Alias for myBatisMapperXmlElementFromMethod */ -deprecated predicate myBatisMapperXMLElementFromMethod = myBatisMapperXmlElementFromMethod/2; - /** Holds if the specified `method` has Ibatis Sql operation annotation `isoa`. */ predicate myBatisSqlOperationAnnotationFromMethod(Method method, IbatisSqlOperationAnnotation isoa) { exists(MyBatisSqlOperationAnnotationMethod msoam | diff --git a/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll b/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll index 874d8448640..8d829612d95 100644 --- a/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll +++ b/java/ql/src/experimental/semmle/code/xml/StrutsXML.qll @@ -10,9 +10,6 @@ class StrutsXmlFile extends XmlFile { } } -/** DEPRECATED: Alias for StrutsXmlFile */ -deprecated class StrutsXMLFile = StrutsXmlFile; - /** * An XML element in a `StrutsXMLFile`. */ @@ -25,9 +22,6 @@ class StrutsXmlElement extends XmlElement { string getValue() { result = this.allCharactersString().trim() } } -/** DEPRECATED: Alias for StrutsXmlElement */ -deprecated class StrutsXMLElement = StrutsXmlElement; - /** * A `<constant>` element in a `StrutsXMLFile`. */ diff --git a/java/ql/src/semmle/code/xml/MyBatisMapperXML.qll b/java/ql/src/semmle/code/xml/MyBatisMapperXML.qll index c7de1b8b945..529a627e96f 100644 --- a/java/ql/src/semmle/code/xml/MyBatisMapperXML.qll +++ b/java/ql/src/semmle/code/xml/MyBatisMapperXML.qll @@ -14,9 +14,6 @@ class MyBatisMapperXmlFile extends XmlFile { } } -/** DEPRECATED: Alias for MyBatisMapperXmlFile */ -deprecated class MyBatisMapperXMLFile = MyBatisMapperXmlFile; - /** * An XML element in a `MyBatisMapperXMLFile`. */ @@ -36,9 +33,6 @@ class MyBatisMapperXmlElement extends XmlElement { } } -/** DEPRECATED: Alias for MyBatisMapperXmlElement */ -deprecated class MyBatisMapperXMLElement = MyBatisMapperXmlElement; - /** * An MyBatis Mapper sql operation element. */ diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll index 5532c8d4726..6836e14e72c 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/ATMConfig.qll @@ -166,6 +166,3 @@ abstract class AtmConfig extends JS::TaintTracking::Configuration { ) } } - -/** DEPRECATED: Alias for AtmConfig */ -deprecated class ATMConfig = AtmConfig; diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll index 62531a9d423..0fc660796c4 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/FunctionBodyFeatures.qll @@ -41,9 +41,6 @@ AstNode getAnAstNodeToFeaturize(Function f) { not result = f.getIdentifier() } -/** DEPRECATED: Alias for getAnAstNodeToFeaturize */ -deprecated ASTNode getAnASTNodeToFeaturize(Function f) { result = getAnAstNodeToFeaturize(f) } - /** * Gets a function that contains the endpoint. * @@ -130,9 +127,6 @@ AstNode getAnAstNodeWithAFeature(Function f) { result = getAnAstNodeToFeaturize(f) } -/** DEPRECATED: Alias for getAnAstNodeWithAFeature */ -deprecated ASTNode getAnASTNodeWithAFeature(Function f) { result = getAnAstNodeWithAFeature(f) } - /** Returns the number of source-code characters in a function. */ int getNumCharsInFunction(Function f) { result = diff --git a/javascript/ql/lib/Expressions/DOMProperties.qll b/javascript/ql/lib/Expressions/DOMProperties.qll index 17f53f8a366..fdb7e6024c2 100644 --- a/javascript/ql/lib/Expressions/DOMProperties.qll +++ b/javascript/ql/lib/Expressions/DOMProperties.qll @@ -4,9 +4,6 @@ import semmle.javascript.Externs -/** DEPRECATED: Alias for isDomRootType */ -deprecated predicate isDOMRootType = isDomRootType/1; - /** Holds if `p` is declared as a property of a DOM class or interface. */ pragma[nomagic] predicate isDomProperty(string p) { @@ -14,6 +11,3 @@ predicate isDomProperty(string p) { isDomRootType(emd.getDeclaringType().getASupertype*()) ) } - -/** DEPRECATED: Alias for isDomProperty */ -deprecated predicate isDOMProperty = isDomProperty/1; diff --git a/javascript/ql/lib/semmle/javascript/AST.qll b/javascript/ql/lib/semmle/javascript/AST.qll index 895922f952f..e4a1cf944c4 100644 --- a/javascript/ql/lib/semmle/javascript/AST.qll +++ b/javascript/ql/lib/semmle/javascript/AST.qll @@ -184,9 +184,6 @@ class AstNode extends @ast_node, NodeInStmtContainer { } } -/** DEPRECATED: Alias for AstNode */ -deprecated class ASTNode = AstNode; - /** * Holds if the given file is a `.d.ts` file. */ @@ -339,9 +336,6 @@ class EventHandlerCode extends @event_handler, CodeInAttribute { } */ class JavaScriptUrl extends @javascript_url, CodeInAttribute { } -/** DEPRECATED: Alias for JavaScriptUrl */ -deprecated class JavaScriptURL = JavaScriptUrl; - /** * A toplevel syntactic entity containing Closure-style externs definitions. * diff --git a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll index c543607e73f..080a1bc1209 100644 --- a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll +++ b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll @@ -636,9 +636,6 @@ module API { /** Gets an API-node for this entry point. */ API::Node getANode() { result = root().getASuccessor(Label::entryPoint(this)) } - - /** DEPRECATED. Use `getANode()` instead. */ - deprecated API::Node getNode() { result = this.getANode() } } /** diff --git a/javascript/ql/lib/semmle/javascript/DefUse.qll b/javascript/ql/lib/semmle/javascript/DefUse.qll index 8ad710fdc57..a9d021f939e 100644 --- a/javascript/ql/lib/semmle/javascript/DefUse.qll +++ b/javascript/ql/lib/semmle/javascript/DefUse.qll @@ -243,71 +243,3 @@ class VarUse extends ControlFlowNode, @varref instanceof RValue { */ SsaVariable getSsaVariable() { result.getAUse() = this } } - -/** - * Holds if the definition of `v` in `def` reaches `use` along some control flow path - * without crossing another definition of `v`. - * DEPRECATED: Use the `SSA.qll` library instead. - */ -deprecated predicate definitionReaches(Variable v, VarDef def, VarUse use) { - v = use.getVariable() and - exists(BasicBlock bb, int i, int next | next = nextDefAfter(bb, v, i, def) | - exists(int j | j in [i + 1 .. next - 1] | bb.useAt(j, v, use)) - or - exists(BasicBlock succ | succ = bb.getASuccessor() | - succ.isLiveAtEntry(v, use) and - next = bb.length() - ) - ) -} - -/** - * Holds if the definition of local variable `v` in `def` reaches `use` along some control flow path - * without crossing another definition of `v`. - * DEPRECATED: Use the `SSA.qll` library instead. - */ -deprecated predicate localDefinitionReaches(LocalVariable v, VarDef def, VarUse use) { - exists(SsaExplicitDefinition ssa | - ssa.defines(def, v) and - ssa = getAPseudoDefinitionInput*(use.getSsaVariable().getDefinition()) - ) -} - -/** - * Holds if `nd` is a pseudo-definition and the result is one of its inputs. - * DEPRECATED: Use the `SSA.qll` library instead. - */ -deprecated private SsaDefinition getAPseudoDefinitionInput(SsaDefinition nd) { - result = nd.(SsaPseudoDefinition).getAnInput() -} - -/** - * Holds if `d` is a definition of `v` at index `i` in `bb`, and the result is the next index - * in `bb` after `i` at which the same variable is defined, or `bb.length()` if there is none. - */ -deprecated private int nextDefAfter(BasicBlock bb, Variable v, int i, VarDef d) { - bb.defAt(i, v, d) and - result = - min(int jj | - (bb.defAt(jj, v, _) or jj = bb.length()) and - jj > i - ) -} - -/** - * Holds if the `later` definition of `v` could overwrite its `earlier` definition. - * - * This is the case if there is a path from `earlier` to `later` that does not cross - * another definition of `v`. - * DEPRECATED: Use the `SSA.qll` library instead. - */ -deprecated predicate localDefinitionOverwrites(LocalVariable v, VarDef earlier, VarDef later) { - exists(BasicBlock bb, int next | next = nextDefAfter(bb, v, _, earlier) | - bb.defAt(next, v, later) - or - exists(BasicBlock succ | succ = bb.getASuccessor() | - succ.localMayBeOverwritten(v, later) and - next = bb.length() - ) - ) -} diff --git a/javascript/ql/lib/semmle/javascript/E4X.qll b/javascript/ql/lib/semmle/javascript/E4X.qll index 47f1b8e4189..cd112d60664 100644 --- a/javascript/ql/lib/semmle/javascript/E4X.qll +++ b/javascript/ql/lib/semmle/javascript/E4X.qll @@ -16,9 +16,6 @@ module E4X { */ class XmlAnyName extends Expr, @e4x_xml_anyname { } - /** DEPRECATED: Alias for XmlAnyName */ - deprecated class XMLAnyName = XmlAnyName; - /** * An E4X qualified identifier. * @@ -57,9 +54,6 @@ module E4X { } } - /** DEPRECATED: Alias for XmlQualifiedIdentifier */ - deprecated class XMLQualifiedIdentifier = XmlQualifiedIdentifier; - /** * An E4X attribute selector. * @@ -89,9 +83,6 @@ module E4X { } } - /** DEPRECATED: Alias for XmlAttributeSelector */ - deprecated class XMLAttributeSelector = XmlAttributeSelector; - /** * An E4X filter expression. * @@ -117,9 +108,6 @@ module E4X { } } - /** DEPRECATED: Alias for XmlFilterExpression */ - deprecated class XMLFilterExpression = XmlFilterExpression; - /** * An E4X "dot-dot" expression. * @@ -144,7 +132,4 @@ module E4X { result = this.getBase().getFirstControlFlowNode() } } - - /** DEPRECATED: Alias for XmlDotDotExpression */ - deprecated class XMLDotDotExpression = XmlDotDotExpression; } diff --git a/javascript/ql/lib/semmle/javascript/JSON.qll b/javascript/ql/lib/semmle/javascript/JSON.qll index c0d78c078da..1e56fc00657 100644 --- a/javascript/ql/lib/semmle/javascript/JSON.qll +++ b/javascript/ql/lib/semmle/javascript/JSON.qll @@ -61,9 +61,6 @@ class JsonValue extends @json_value, Locatable { override string getAPrimaryQlClass() { result = "JsonValue" } } -/** DEPRECATED: Alias for JsonValue */ -deprecated class JSONValue = JsonValue; - /** * A JSON-encoded primitive value. * @@ -85,9 +82,6 @@ abstract class JsonPrimitiveValue extends JsonValue { string getRawValue() { json_literals(_, result, this) } } -/** DEPRECATED: Alias for JsonPrimitiveValue */ -deprecated class JSONPrimitiveValue = JsonPrimitiveValue; - /** * A JSON-encoded null value. * @@ -101,9 +95,6 @@ class JsonNull extends @json_null, JsonPrimitiveValue { override string getAPrimaryQlClass() { result = "JsonNull" } } -/** DEPRECATED: Alias for JsonNull */ -deprecated class JSONNull = JsonNull; - /** * A JSON-encoded Boolean value. * @@ -118,9 +109,6 @@ class JsonBoolean extends @json_boolean, JsonPrimitiveValue { override string getAPrimaryQlClass() { result = "JsonBoolean" } } -/** DEPRECATED: Alias for JsonBoolean */ -deprecated class JSONBoolean = JsonBoolean; - /** * A JSON-encoded number. * @@ -135,9 +123,6 @@ class JsonNumber extends @json_number, JsonPrimitiveValue { override string getAPrimaryQlClass() { result = "JsonNumber" } } -/** DEPRECATED: Alias for JsonNumber */ -deprecated class JSONNumber = JsonNumber; - /** * A JSON-encoded string value. * @@ -151,9 +136,6 @@ class JsonString extends @json_string, JsonPrimitiveValue { override string getAPrimaryQlClass() { result = "JsonString" } } -/** DEPRECATED: Alias for JsonString */ -deprecated class JSONString = JsonString; - /** * A JSON-encoded array. * @@ -170,9 +152,6 @@ class JsonArray extends @json_array, JsonValue { string getElementStringValue(int i) { result = this.getElementValue(i).getStringValue() } } -/** DEPRECATED: Alias for JsonArray */ -deprecated class JSONArray = JsonArray; - /** * A JSON-encoded object. * @@ -189,9 +168,6 @@ class JsonObject extends @json_object, JsonValue { string getPropStringValue(string name) { result = this.getPropValue(name).getStringValue() } } -/** DEPRECATED: Alias for JsonObject */ -deprecated class JSONObject = JsonObject; - /** * An error reported by the JSON parser. */ @@ -200,6 +176,3 @@ class JsonParseError extends @json_parse_error, Error { override string getMessage() { json_errors(this, result) } } - -/** DEPRECATED: Alias for JsonParseError */ -deprecated class JSONParseError = JsonParseError; diff --git a/javascript/ql/lib/semmle/javascript/JSX.qll b/javascript/ql/lib/semmle/javascript/JSX.qll index fa8f79fb2bb..6fd7c775d4e 100644 --- a/javascript/ql/lib/semmle/javascript/JSX.qll +++ b/javascript/ql/lib/semmle/javascript/JSX.qll @@ -30,9 +30,6 @@ class JsxNode extends Expr, @jsx_element { override string getAPrimaryQlClass() { result = "JsxNode" } } -/** DEPRECATED: Alias for JsxNode */ -deprecated class JSXNode = JsxNode; - /** * A JSX element. * @@ -81,9 +78,6 @@ class JsxElement extends JsxNode { deprecated predicate isHTMLElement() { this.isHtmlElement() } } -/** DEPRECATED: Alias for JsxElement */ -deprecated class JSXElement = JsxElement; - /** * A JSX fragment. * @@ -105,9 +99,6 @@ class JsxFragment extends JsxNode { override string getAPrimaryQlClass() { result = "JsxFragment" } } -/** DEPRECATED: Alias for JsxFragment */ -deprecated class JSXFragment = JsxFragment; - /** * An attribute of a JSX element, including spread attributes. * @@ -154,9 +145,6 @@ class JsxAttribute extends AstNode, @jsx_attribute { override string getAPrimaryQlClass() { result = "JsxAttribute" } } -/** DEPRECATED: Alias for JsxAttribute */ -deprecated class JSXAttribute = JsxAttribute; - /** * A spread attribute of a JSX element. * @@ -175,9 +163,6 @@ class JsxSpreadAttribute extends JsxAttribute { } } -/** DEPRECATED: Alias for JsxSpreadAttribute */ -deprecated class JSXSpreadAttribute = JsxSpreadAttribute; - /** * A namespace-qualified name such as `n:a`. * @@ -201,9 +186,6 @@ class JsxQualifiedName extends Expr, @jsx_qualified_name { override string getAPrimaryQlClass() { result = "JsxQualifiedName" } } -/** DEPRECATED: Alias for JsxQualifiedName */ -deprecated class JSXQualifiedName = JsxQualifiedName; - /** * A name of an JSX element or attribute (which is * always an identifier, a dot expression, or a qualified @@ -244,9 +226,6 @@ class JsxName extends Expr { } } -/** DEPRECATED: Alias for JsxName */ -deprecated class JSXName = JsxName; - /** * An interpolating expression that interpolates nothing. * @@ -260,9 +239,6 @@ class JsxEmptyExpr extends Expr, @jsx_empty_expr { override string getAPrimaryQlClass() { result = "JsxEmptyExpr" } } -/** DEPRECATED: Alias for JsxEmptyExpr */ -deprecated class JSXEmptyExpr = JsxEmptyExpr; - /** * A legacy `@jsx` pragma. * @@ -284,6 +260,3 @@ class JsxPragma extends JSDocTag { /** DEPRECATED: Alias for getDomName */ deprecated string getDOMName() { result = this.getDomName() } } - -/** DEPRECATED: Alias for JsxPragma */ -deprecated class JSXPragma = JsxPragma; diff --git a/javascript/ql/lib/semmle/javascript/JsonStringifiers.qll b/javascript/ql/lib/semmle/javascript/JsonStringifiers.qll index 0ca2ec2ac2e..d128dd9a653 100644 --- a/javascript/ql/lib/semmle/javascript/JsonStringifiers.qll +++ b/javascript/ql/lib/semmle/javascript/JsonStringifiers.qll @@ -77,6 +77,3 @@ class PrettyJsonTaintStep extends TaintTracking::SharedTaintStep { ) } } - -/** DEPRECATED: Alias for PrettyJsonTaintStep */ -deprecated class PrettyJSONTaintStep = PrettyJsonTaintStep; diff --git a/javascript/ql/lib/semmle/javascript/NPM.qll b/javascript/ql/lib/semmle/javascript/NPM.qll index e1059d94930..0bf92c5d29a 100644 --- a/javascript/ql/lib/semmle/javascript/NPM.qll +++ b/javascript/ql/lib/semmle/javascript/NPM.qll @@ -262,9 +262,6 @@ class PackageJson extends JsonObject { Module getTypingsModule() { result.getFile() = this.getTypingsFile() } } -/** DEPRECATED: Alias for PackageJson */ -deprecated class PackageJSON = PackageJson; - /** * A representation of bug tracker information for an NPM package. */ @@ -370,9 +367,6 @@ class NpmPackage extends @folder { /** Gets the `package.json` object of this package. */ PackageJson getPackageJson() { result = pkg } - /** DEPRECATED: Alias for getPackageJson */ - deprecated PackageJSON getPackageJSON() { result = this.getPackageJson() } - /** Gets the name of this package. */ string getPackageName() { result = this.getPackageJson().getPackageName() } @@ -411,9 +405,6 @@ class NpmPackage extends @folder { predicate declaresDependency(string p, string v) { pkg.declaresDependency(p, v) } } -/** DEPRECATED: Alias for NpmPackage */ -deprecated class NPMPackage = NpmPackage; - /** * Gets the parent folder of `c`, provided that they belong to the same NPM * package; that is, `c` must not be a `node_modules` folder. diff --git a/javascript/ql/lib/semmle/javascript/PrintAst.qll b/javascript/ql/lib/semmle/javascript/PrintAst.qll index 5c4960e041c..0defda1dc6b 100644 --- a/javascript/ql/lib/semmle/javascript/PrintAst.qll +++ b/javascript/ql/lib/semmle/javascript/PrintAst.qll @@ -391,9 +391,6 @@ private module PrintJavaScript { } } - /** DEPRECATED: Alias for JsxNodeNode */ - deprecated class JSXNodeNode = JsxNodeNode; - /** * An aggregate node representing all the attributes in a `JSXNode`. */ @@ -409,17 +406,11 @@ private module PrintJavaScript { */ JsxElement getJsxElement() { result = n } - /** DEPRECATED: Alias for getJsxElement */ - deprecated JSXElement getJSXElement() { result = this.getJsxElement() } - override PrintAstNode getChild(int childIndex) { result.(ElementNode).getElement() = n.getAttribute(childIndex) } } - /** DEPRECATED: Alias for JsxAttributesNode */ - deprecated class JSXAttributesNode = JsxAttributesNode; - /** * An aggregate node representing all the body elements in a `JSXNode`. */ @@ -435,17 +426,11 @@ private module PrintJavaScript { */ JsxNode getJsxNode() { result = n } - /** DEPRECATED: Alias for getJsxNode */ - deprecated JSXNode getJSXNode() { result = this.getJsxNode() } - override PrintAstNode getChild(int childIndex) { result.(ElementNode).getElement() = n.getBodyElement(childIndex) } } - /** DEPRECATED: Alias for JsxBodyElementsNode */ - deprecated class JSXBodyElementsNode = JsxBodyElementsNode; - /** * A node representing any `ASTNode` that has type-parameters. * @@ -582,9 +567,6 @@ private module PrintJson { } } - /** DEPRECATED: Alias for JsonNode */ - deprecated class JSONNode = JsonNode; - /** Provied predicates for pretty printing JSON. */ private module PrettyPrinting { /** @@ -655,9 +637,6 @@ module PrintYaml { } } - /** DEPRECATED: Alias for YamlNodeNode */ - deprecated class YAMLNodeNode = YamlNodeNode; - /** * A print node representing a `YAMLMapping`. * @@ -671,9 +650,6 @@ module PrintYaml { } } - /** DEPRECATED: Alias for YamlMappingNode */ - deprecated class YAMLMappingNode = YamlMappingNode; - /** * A print node representing the `i`th mapping in `mapping`. */ @@ -703,14 +679,8 @@ module PrintYaml { childIndex = 1 and result.(YamlNodeNode).getValue() = mapping.getValueNode(i) } } - - /** DEPRECATED: Alias for YamlMappingMapNode */ - deprecated class YAMLMappingMapNode = YamlMappingMapNode; } -/** DEPRECATED: Alias for PrintYaml */ -deprecated module PrintYAML = PrintYaml; - /** * Classes for printing HTML AST. */ @@ -741,9 +711,6 @@ module PrintHtml { } } - /** DEPRECATED: Alias for HtmlElementNode */ - deprecated class HTMLElementNode = HtmlElementNode; - /** * A print node representing an HTML node in a .html file. */ @@ -757,9 +724,6 @@ module PrintHtml { } } - /** DEPRECATED: Alias for HtmlScriptElementNode */ - deprecated class HTMLScriptElementNode = HtmlScriptElementNode; - /** * A print node representing the code inside a `<script>` element. */ @@ -785,9 +749,6 @@ module PrintHtml { } } - /** DEPRECATED: Alias for HtmlScript */ - deprecated class HTMLScript = HtmlScript; - /** * A print node representing the code inside an attribute. */ @@ -813,9 +774,6 @@ module PrintHtml { } } - /** DEPRECATED: Alias for HtmlCodeInAttr */ - deprecated class HTMLCodeInAttr = HtmlCodeInAttr; - /** * An aggregate node representing all the attributes of an HTMLElement. */ @@ -838,9 +796,6 @@ module PrintHtml { } } - /** DEPRECATED: Alias for HtmlAttributesNodes */ - deprecated class HTMLAttributesNodes = HtmlAttributesNodes; - /** * A print node representing an HTML attribute in a .html file. */ @@ -862,14 +817,8 @@ module PrintHtml { childIndex = 0 and result.(HtmlCodeInAttr).getCode() = attr.getCodeInAttribute() } } - - /** DEPRECATED: Alias for HtmlAttributeNode */ - deprecated class HTMLAttributeNode = HtmlAttributeNode; } -/** DEPRECATED: Alias for PrintHtml */ -deprecated module PrintHTML = PrintHtml; - /** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */ query predicate nodes(PrintAstNode node, string key, string value) { value = node.getProperty(key) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index c013dab3680..e8c2b563c92 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1817,6 +1817,4 @@ module DataFlow { import Configuration import TypeTracking import internal.FunctionWrapperSteps - - deprecated predicate localTaintStep = TaintTracking::localTaintStep/2; } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 2e80990ac13..96d97a270c6 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -419,16 +419,6 @@ module TaintTracking { import Cached::Public - /** - * Holds if `pred -> succ` is a taint propagating data flow edge through a string operation. - * DEPRECATED: Use `stringConcatenationStep` and `stringManipulationStep` instead. - */ - pragma[inline] - deprecated predicate stringStep(DataFlow::Node pred, DataFlow::Node succ) { - stringConcatenationStep(pred, succ) or - stringManipulationStep(pred, succ) - } - /** * Holds if `pred -> succ` is an edge used by all taint-tracking configurations. */ @@ -1241,13 +1231,4 @@ module TaintTracking { override predicate appliesTo(Configuration cfg) { any() } } - - /** - * Holds if taint propagates from `pred` to `succ` in one local (intra-procedural) step. - * DEPRECATED: Use `TaintTracking::sharedTaintStep` and `DataFlow::Node::getALocalSource()` instead. - */ - deprecated predicate localTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - DataFlow::localFlowStep(pred, succ) or - sharedTaintStep(pred, succ) - } } diff --git a/javascript/ql/lib/semmle/javascript/dependencies/Dependencies.qll b/javascript/ql/lib/semmle/javascript/dependencies/Dependencies.qll index 76a285ccd8c..948b8c9aff2 100644 --- a/javascript/ql/lib/semmle/javascript/dependencies/Dependencies.qll +++ b/javascript/ql/lib/semmle/javascript/dependencies/Dependencies.qll @@ -39,9 +39,6 @@ abstract class NpmDependency extends Dependency { /** Gets the name of the NPM package this module belongs to. */ abstract string getNpmPackageName(); - /** DEPRECATED: Alias for getNpmPackageName */ - deprecated string getNPMPackageName() { result = this.getNpmPackageName() } - /** Gets the version of the NPM package this module belongs to. */ abstract string getVersion(); @@ -62,9 +59,6 @@ abstract class NpmDependency extends Dependency { } } -/** DEPRECATED: Alias for NpmDependency */ -deprecated class NPMDependency = NpmDependency; - /** * Gets a variable into which something is imported by `i`. */ @@ -105,9 +99,6 @@ class BundledNpmDependency extends NpmDependency { override string getNpmPackageName() { result = this.getPackageJson().getPackageName() } - /** DEPRECATED: Alias for getNpmPackageName */ - deprecated override string getNPMPackageName() { result = this.getNpmPackageName() } - override string getVersion() { result = this.getPackageJson().getVersion() } override Import getAnImport() { @@ -117,9 +108,6 @@ class BundledNpmDependency extends NpmDependency { } } -/** DEPRECATED: Alias for BundledNpmDependency */ -deprecated class BundledNPMDependency = BundledNpmDependency; - /** * An NPM package referenced in a `package.json` file. */ @@ -139,9 +127,6 @@ class ExternalNpmDependency extends NpmDependency { exists(PackageDependencies pkgdeps | this = pkgdeps.getPropValue(result)) } - /** DEPRECATED: Alias for getNpmPackageName */ - deprecated override string getNPMPackageName() { result = this.getNpmPackageName() } - private string getVersionNumber() { exists(string versionRange | versionRange = this.(JsonString).getValue() | // extract a concrete version from the version range; currently, @@ -166,9 +151,6 @@ class ExternalNpmDependency extends NpmDependency { } } -/** DEPRECATED: Alias for ExternalNpmDependency */ -deprecated class ExternalNPMDependency = ExternalNpmDependency; - /** * Holds if import `i` may refer to the declared dependency `dep` of package `pkg`, * where the result value is the nesting depth of the file containing `i` within `pkg`. diff --git a/javascript/ql/lib/semmle/javascript/dependencies/FrameworkLibraries.qll b/javascript/ql/lib/semmle/javascript/dependencies/FrameworkLibraries.qll index 32a2941c1ab..9ff96a58fdc 100644 --- a/javascript/ql/lib/semmle/javascript/dependencies/FrameworkLibraries.qll +++ b/javascript/ql/lib/semmle/javascript/dependencies/FrameworkLibraries.qll @@ -137,14 +137,8 @@ abstract class FrameworkLibraryWithUrlRegex extends FrameworkLibrary { * the version number. */ abstract string getAUrlRegex(); - - /** DEPRECATED: Alias for getAUrlRegex */ - deprecated string getAURLRegex() { result = this.getAUrlRegex() } } -/** DEPRECATED: Alias for FrameworkLibraryWithUrlRegex */ -deprecated class FrameworkLibraryWithURLRegex = FrameworkLibraryWithUrlRegex; - /** * A framework library that is referenced by URLs containing the name * of the framework (or an alias) and a version string. @@ -175,14 +169,8 @@ abstract class FrameworkLibraryWithGenericUrl extends FrameworkLibraryWithUrlReg "\\.js" ) } - - /** DEPRECATED: Alias for getAUrlRegex */ - deprecated override string getAURLRegex() { result = this.getAUrlRegex() } } -/** DEPRECATED: Alias for FrameworkLibraryWithGenericUrl */ -deprecated class FrameworkLibraryWithGenericURL = FrameworkLibraryWithGenericUrl; - /** * Gets a regular expression identifying suffixes that are commonly appended * to the name of a library to distinguish minor variants. @@ -282,9 +270,6 @@ class FrameworkLibraryReferenceWithUrl extends FrameworkLibraryReference { override predicate info(FrameworkLibrary fl, string v) { matchUrl(this, fl, v) } } -/** DEPRECATED: Alias for FrameworkLibraryReferenceWithUrl */ -deprecated class FrameworkLibraryReferenceWithURL = FrameworkLibraryReferenceWithUrl; - /** * Holds if the value of `src` attribute `attr` matches the URL pattern of library * `fl` at `version`. @@ -953,9 +938,6 @@ private class ApplicationInsights extends FrameworkLibraryWithUrlRegex { ApplicationInsights() { this = "ApplicationInsights" } override string getAUrlRegex() { result = ".*(?:^|/)ai\\.(" + semverRegex() + ")-build\\d+\\.js" } - - /** DEPRECATED: Alias for getAUrlRegex */ - deprecated override string getAURLRegex() { result = this.getAUrlRegex() } } /** @@ -974,9 +956,6 @@ private class TwitterTextClassic extends FrameworkLibraryWithUrlRegex { TwitterTextClassic() { this = "twitter-text" } override string getAUrlRegex() { result = ".*(?:^|/)twitter_text" + variantRegex() + "\\.js" } - - /** DEPRECATED: Alias for getAUrlRegex */ - deprecated override string getAURLRegex() { result = this.getAUrlRegex() } } /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index 73e3308329a..13879fda3e7 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -631,9 +631,6 @@ module ClientRequest { } } - /** DEPRECATED: Alias for XmlHttpRequest */ - deprecated class XMLHttpRequest = XmlHttpRequest; - /** * A model of a URL request made using the `XhrIo` class from the closure library. */ @@ -814,9 +811,6 @@ module ClientRequest { override DataFlow::Node getADataNode() { none() } } - /** DEPRECATED: Alias for JSDomFromUrl */ - deprecated class JSDOMFromUrl = JSDomFromUrl; - /** * Classes and predicates modeling the `apollo-client` library. */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Files.qll b/javascript/ql/lib/semmle/javascript/frameworks/Files.qll index 244c9c502c2..853d122b301 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Files.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Files.qll @@ -250,9 +250,6 @@ private module JsonFile { } } - /** DEPRECATED: Alias for JsonFileReader */ - deprecated class JSONFileReader = JsonFileReader; - /** * A writer for JSON files. */ @@ -267,9 +264,6 @@ private module JsonFile { override DataFlow::Node getADataNode() { result = this.getArgument(1) } } - - /** DEPRECATED: Alias for JsonFileWriter */ - deprecated class JSONFileWriter = JsonFileWriter; } /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Markdown.qll b/javascript/ql/lib/semmle/javascript/frameworks/Markdown.qll index 5a60a8ac84d..fa8fd4da565 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Markdown.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Markdown.qll @@ -22,9 +22,6 @@ module Markdown { * Holds if the taint-step preserves HTML. */ predicate preservesHtml() { any() } - - /** DEPRECATED: Alias for preservesHtml */ - deprecated predicate preservesHTML() { this.preservesHtml() } } private class MarkdownStepAsTaintStep extends TaintTracking::SharedTaintStep { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Next.qll b/javascript/ql/lib/semmle/javascript/frameworks/Next.qll index 5ed808456d3..913753ff9da 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Next.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Next.qll @@ -241,9 +241,6 @@ module NextJS { } } - /** DEPRECATED: Alias for NextApiRouteHandler */ - deprecated class NextAPIRouteHandler = NextApiRouteHandler; - /** * Gets a reference to a [Next.js router](https://nextjs.org/docs/api-reference/next/router). */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll index 56e9c6f4406..2525f1d0c3d 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll @@ -17,9 +17,6 @@ module NoSql { } } -/** DEPRECATED: Alias for NoSql */ -deprecated module NoSQL = NoSql; - /** * Provides classes modeling the `mongodb` and `mongoose` libraries. */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/UriLibraries.qll b/javascript/ql/lib/semmle/javascript/frameworks/UriLibraries.qll index f10bb58b8fc..0a262d154b2 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/UriLibraries.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/UriLibraries.qll @@ -4,9 +4,6 @@ import javascript -/** DEPRECATED: Alias for `Urijs` */ -deprecated module urijs = Urijs; - /** * Provides classes for working with [urijs](http://medialize.github.io/URI.js/) code. */ @@ -73,9 +70,6 @@ module Urijs { } } -/** DEPRECATED: Alias for `Uridashjs` */ -deprecated module uridashjs = Uridashjs; - /** * Provides classes for working with [uri-js](https://github.com/garycourt/uri-js) code. */ @@ -101,9 +95,6 @@ module Uridashjs { } } -/** DEPRECATED: Alias for `Punycode` */ -deprecated module punycode = Punycode; - /** * Provides classes for working with [punycode](https://github.com/bestiejs/punycode.js) code. */ @@ -129,9 +120,6 @@ module Punycode { } } -/** DEPRECATED: Alias for `UrlParse` */ -deprecated module urlParse = UrlParse; - /** * Provides classes for working with [url-parse](https://github.com/unshiftio/url-parse) code. */ @@ -169,9 +157,6 @@ module UrlParse { } } -/** DEPRECATED: Alias for `Querystringify` */ -deprecated module querystringify = Querystringify; - /** * Provides classes for working with [querystringify](https://github.com/unshiftio/querystringify) code. */ @@ -202,9 +187,6 @@ module Querystringify { } } -/** DEPRECATED: Alias for `Querydashstring` */ -deprecated module querydashstring = Querydashstring; - /** * Provides classes for working with [query-string](https://github.com/sindresorhus/query-string) code. */ @@ -230,9 +212,6 @@ module Querydashstring { } } -/** DEPRECATED: Alias for `Url` */ -deprecated module url = Url; - /** * Provides classes for working with [url](https://nodejs.org/api/url.html) code. */ @@ -256,9 +235,6 @@ module Url { } } -/** DEPRECATED: Alias for `Querystring` */ -deprecated module querystring = Querystring; - /** * Provides classes for working with [querystring](https://nodejs.org/api/querystring.html) code. */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/WebSocket.qll b/javascript/ql/lib/semmle/javascript/frameworks/WebSocket.qll index abdfe3bc445..d2fc69751d6 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/WebSocket.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/WebSocket.qll @@ -249,9 +249,6 @@ module ServerWebSocket { override Http::RouteHandler getRouteHandler() { result = handler } } - /** DEPRECATED: Alias for ServerHttpRequest */ - deprecated class ServerHTTPRequest = ServerHttpRequest; - /** * An access user-controlled HTTP request input in a request to a WebSocket server. */ diff --git a/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll b/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll index cc1404e34e7..59639f3d904 100644 --- a/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll +++ b/javascript/ql/lib/semmle/javascript/internal/CachedStages.qll @@ -286,9 +286,6 @@ module Stages { } } - /** DEPRECATED: Alias for ApiStage */ - deprecated module APIStage = ApiStage; - /** * The `taint` stage. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index e68a0b604b0..5d658b23b59 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -255,9 +255,6 @@ module CodeInjection { NoSqlCodeInjectionSink() { any(NoSql::Query q).getACodeOperator() = this } } - /** DEPRECATED: Alias for NoSqlCodeInjectionSink */ - deprecated class NoSQLCodeInjectionSink = NoSqlCodeInjectionSink; - /** * The first argument to `Module.prototype._compile`, considered as a code-injection sink. */ @@ -427,9 +424,6 @@ module CodeInjection { */ class JsonStringifySanitizer extends Sanitizer, JsonStringifyCall { } - /** DEPRECATED: Alias for JsonStringifySanitizer */ - deprecated class JSONStringifySanitizer = JsonStringifySanitizer; - private class SinkFromModel extends Sink { SinkFromModel() { this = ModelOutput::getASinkNode("code-injection").asSink() } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll index 21fb6f785af..e007bdd8ede 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll @@ -18,9 +18,6 @@ class DomGlobalVariable extends GlobalVariable { } } -/** DEPRECATED: Alias for DomGlobalVariable */ -deprecated class DOMGlobalVariable = DomGlobalVariable; - /** * DEPRECATED: Use `isDomNode` instead. * Holds if `e` could hold a value that comes from the DOM. @@ -45,27 +42,6 @@ predicate isLocationNode(DataFlow::Node e) { e = DataFlow::globalVarRef("location") } -/** - * DEPRECATED: Use DOM::documentRef() instead. - * Gets a reference to the 'document' object. - */ -deprecated DataFlow::SourceNode document() { result = DOM::documentRef() } - -/** - * DEPRECATED: Use DOM::documentRef() instead. - * Holds if `e` could refer to the `document` object. - */ -deprecated predicate isDocument(Expr e) { DOM::documentRef().flowsToExpr(e) } - -/** - * DEPRECATED: Use DOM::locationSource() instead. - * Holds if `e` could refer to the document URL. - */ -deprecated predicate isDocumentUrl(Expr e) { e.flow() = DOM::locationSource() } - -/** DEPRECATED: Alias for isDocumentUrl */ -deprecated predicate isDocumentURL = isDocumentUrl/1; - /** * DEPRECATED. In most cases, a sanitizer based on this predicate can be removed, as * taint tracking no longer step through the properties of the location object by default. @@ -179,9 +155,6 @@ deprecated class DomPropWriteNode extends Assignment { */ predicate interpretsValueAsHtml() { node.interpretsValueAsHtml() } - /** DEPRECATED: Alias for interpretsValueAsHtml */ - deprecated predicate interpretsValueAsHTML() { this.interpretsValueAsHtml() } - /** * Holds if the assigned value is interpreted as JavaScript via javascript: protocol. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll index e26b4eea8c8..fa64b7300b0 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll @@ -8,12 +8,6 @@ private import semmle.javascript.security.TaintedUrlSuffix import DomBasedXssCustomizations::DomBasedXss private import Xss::Shared as Shared -/** DEPRECATED. Use `Configuration`. */ -deprecated class HtmlInjectionConfiguration = Configuration; - -/** DEPRECATED. Use `Configuration`. */ -deprecated class JQueryHtmlOrSelectorInjectionConfiguration = Configuration; - /** * A sink that is not a URL write or a JQuery selector, * assumed to be a value that is interpreted as HTML. diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedData.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedData.qll index 31963b6843e..c070fdff662 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedData.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedData.qll @@ -5,6 +5,3 @@ private import ExternalAPIUsedWithUntrustedDataQuery as ExternalApiUsedWithUntru /** DEPRECATED. Import `ExternalApiUsedWithUntrustedDataQuery` instead. */ deprecated module ExternalApiUsedWithUntrustedData = ExternalApiUsedWithUntrustedDataQuery; - -/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ -deprecated module ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataCustomizations.qll index f17eab628ff..fac7b95fe80 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataCustomizations.qll @@ -64,9 +64,6 @@ module ExternalApiUsedWithUntrustedData { SafeExternalApiPackage() { exists(API::moduleImport(this)) } } - /** DEPRECATED: Alias for SafeExternalApiPackage */ - deprecated class SafeExternalAPIPackage = SafeExternalApiPackage; - private class DefaultSafeExternalApiPackage extends SafeExternalApiPackage { DefaultSafeExternalApiPackage() { // Promise libraries are safe and generate too much noise if included @@ -83,9 +80,6 @@ module ExternalApiUsedWithUntrustedData { */ abstract class SafeExternalApiFunction extends API::Node { } - /** DEPRECATED: Alias for SafeExternalApiFunction */ - deprecated class SafeExternalAPIFunction = SafeExternalApiFunction; - /** Holds if data read from a use of `f` may originate from an imported package. */ private predicate mayComeFromLibrary(API::Node f) { // base case: import @@ -371,6 +365,3 @@ module ExternalApiUsedWithUntrustedData { } } } - -/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ -deprecated module ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll index 9335098af37..857cf837de2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll @@ -61,9 +61,6 @@ class Configuration extends TaintTracking::Configuration { /** A node representing data being passed to an external API. */ class ExternalApiDataNode extends DataFlow::Node instanceof Sink { } -/** DEPRECATED: Alias for ExternalApiDataNode */ -deprecated class ExternalAPIDataNode = ExternalApiDataNode; - /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { UntrustedExternalApiDataNode() { any(Configuration c).hasFlow(_, this) } @@ -72,9 +69,6 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode { DataFlow::Node getAnUntrustedSource() { any(Configuration c).hasFlow(result, this) } } -/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ -deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; - /** * Name of an external API sink, boxed in a newtype for consistency with other languages. */ @@ -102,6 +96,3 @@ class ExternalApiUsedWithUntrustedData extends TExternalApi { /** Gets a textual representation of this element. */ string toString() { this = MkExternalApiNode(result) } } - -/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ -deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitizationCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitizationCustomizations.qll index 8968360d636..4bf212b90d2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitizationCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ImproperCodeSanitizationCustomizations.qll @@ -35,9 +35,6 @@ module ImproperCodeSanitization { */ class JsonStringifyAsSource extends Source instanceof JsonStringifyCall { } - /** DEPRECATED: Alias for JsonStringifyAsSource */ - deprecated class JSONStringifyAsSource = JsonStringifyAsSource; - /** * A leaf in a string-concatenation, where the string-concatenation constructs code that looks like a function. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownloadCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownloadCustomizations.qll index 0a34642ffd8..dc383df448c 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownloadCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/InsecureDownloadCustomizations.qll @@ -51,18 +51,12 @@ module InsecureDownload { SensitiveInsecureUrl() { this = "sensitiveInsecure" } } - /** DEPRECATED: Alias for SensitiveInsecureUrl */ - deprecated class SensitiveInsecureURL = SensitiveInsecureUrl; - /** * A flow-label for a URL that is downloaded over an insecure connection. */ class InsecureUrl extends DataFlow::FlowLabel { InsecureUrl() { this = "insecure" } } - - /** DEPRECATED: Alias for InsecureUrl */ - deprecated class InsecureURL = InsecureUrl; } /** @@ -127,9 +121,6 @@ module InsecureDownload { } } - /** DEPRECATED: Alias for ClientRequestUrl */ - deprecated class ClientRequestURL = ClientRequestUrl; - /** * Gets a node for the response from `request`, type-tracked using `t`. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll index 5c309b07727..90579211a3f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll @@ -145,9 +145,6 @@ module UnsafeHtmlConstruction { override string describe() { result = "HTML construction" } } - /** DEPRECATED: Alias for HtmlConcatenationSink */ - deprecated class HTMLConcatenationSink = HtmlConcatenationSink; - /** * A string parsed as XML, which is later used in an XSS sink. */ @@ -162,9 +159,6 @@ module UnsafeHtmlConstruction { override string describe() { result = "XML parsing" } } - /** DEPRECATED: Alias for XmlParsedSink */ - deprecated class XMLParsedSink = XmlParsedSink; - /** * A string rendered as markdown, where the rendering preserves HTML. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll index 216243fb8a5..8c881e49226 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/Xss.qll @@ -97,9 +97,6 @@ module Shared { } } - /** DEPRECATED: Alias for ContainsHtmlGuard */ - deprecated class ContainsHTMLGuard = ContainsHtmlGuard; - /** * Holds if `str` is used in a switch-case that has cases matching HTML escaping. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll index bd3aa65aa4d..a1074e49eb2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll @@ -137,9 +137,6 @@ module XssThroughDom { override string getPropertyName() { result = prop } } - /** DEPRECATED: Alias for DomTextSource */ - deprecated class DOMTextSource = DomTextSource; - /** The `files` property of an `<input />` element */ class FilesSource extends Source { FilesSource() { this = DOM::domValueRef().getAPropertyRead("files") } diff --git a/javascript/ql/src/Declarations/Definitions.qll b/javascript/ql/src/Declarations/Definitions.qll index a7034ad5093..7046b14f09d 100644 --- a/javascript/ql/src/Declarations/Definitions.qll +++ b/javascript/ql/src/Declarations/Definitions.qll @@ -1,13 +1 @@ import javascript - -/** - * DEPRECATED: Use `SsaDefinition` from `SSA.qll` instead. - * An identifier appearing in a defining position. - */ -deprecated class DefiningIdentifier extends Identifier { - DefiningIdentifier() { - this instanceof VarDecl or - exists(Assignment assgn | this = assgn.getLhs()) or - exists(UpdateExpr upd | this = upd.getOperand()) - } -} diff --git a/javascript/ql/test/library-tests/frameworks/ReactJS/ReactName.qll b/javascript/ql/test/library-tests/frameworks/ReactJS/ReactName.qll index 940332693a7..885f1f38a57 100644 --- a/javascript/ql/test/library-tests/frameworks/ReactJS/ReactName.qll +++ b/javascript/ql/test/library-tests/frameworks/ReactJS/ReactName.qll @@ -15,6 +15,3 @@ query predicate test_JSXname(JsxElement element, JsxName jsxname, string name, s } query ThisExpr test_JsxName_this(JsxElement element) { result.getParentExpr+() = element } - -/** DEPRECATED: Alias for test_JsxName_this */ -deprecated ThisExpr test_JSXName_this(JSXElement element) { result = test_JsxName_this(element) } diff --git a/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll b/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll index 385e3b8e7dd..02375976126 100644 --- a/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll +++ b/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll @@ -30,9 +30,6 @@ class OspreyCreateApiCall extends MethodCallExpr { } } -/** DEPRECATED: Alias for OspreyCreateApiCall */ -deprecated class OspreyCreateAPICall = OspreyCreateApiCall; - /** A variable in which an Osprey API object is stored. */ class OspreyApi extends Variable { OspreyApi() { this.getAnAssignedExpr() instanceof OspreyCreateApiCall } @@ -40,9 +37,6 @@ class OspreyApi extends Variable { File getSpecFile() { result = this.getAnAssignedExpr().(OspreyCreateApiCall).getSpecFile() } } -/** DEPRECATED: Alias for OspreyApi */ -deprecated class OspreyAPI = OspreyApi; - /** An Osprey REST method definition. */ class OspreyMethodDefinition extends MethodCallExpr { OspreyMethodDefinition() { diff --git a/javascript/ql/test/tutorials/Validating RAML-based APIs/RAML.qll b/javascript/ql/test/tutorials/Validating RAML-based APIs/RAML.qll index 5c22bf65ab9..50bd4a6ed03 100644 --- a/javascript/ql/test/tutorials/Validating RAML-based APIs/RAML.qll +++ b/javascript/ql/test/tutorials/Validating RAML-based APIs/RAML.qll @@ -8,9 +8,6 @@ class RamlSpec extends YamlDocument, YamlMapping { RamlSpec() { getLocation().getFile().getExtension() = "raml" } } -/** DEPRECATED: Alias for RamlSpec */ -deprecated class RAMLSpec = RamlSpec; - /** A RAML resource specification. */ class RamlResource extends YamlMapping { RamlResource() { @@ -38,9 +35,6 @@ class RamlResource extends YamlMapping { } } -/** DEPRECATED: Alias for RamlResource */ -deprecated class RAMLResource = RamlResource; - /** A RAML method specification. */ class RamlMethod extends YamlValue { RamlMethod() { @@ -57,6 +51,3 @@ class RamlMethod extends YamlValue { ) } } - -/** DEPRECATED: Alias for RamlMethod */ -deprecated class RAMLMethod = RamlMethod; diff --git a/ruby/ql/lib/codeql/ruby/Concepts.qll b/ruby/ql/lib/codeql/ruby/Concepts.qll index ec27694581f..28d5990e76a 100644 --- a/ruby/ql/lib/codeql/ruby/Concepts.qll +++ b/ruby/ql/lib/codeql/ruby/Concepts.qll @@ -715,14 +715,6 @@ module Http { /** Gets a node which returns the body of the response */ abstract DataFlow::Node getResponseBody(); - /** - * DEPRECATED: overwrite `getAUrlPart` instead. - * - * Gets a node that contributes to the URL of the request. - * Depending on the framework, a request may have multiple nodes which contribute to the URL. - */ - deprecated DataFlow::Node getURL() { none() } - /** * DEPRECATED: override `disablesCertificateValidation/2` instead. * diff --git a/ruby/ql/lib/codeql/ruby/ast/Expr.qll b/ruby/ql/lib/codeql/ruby/ast/Expr.qll index 99d955b3400..3e17c573b50 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Expr.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Expr.qll @@ -11,13 +11,6 @@ private import internal.TreeSitter * This is the root QL class for all expressions. */ class Expr extends Stmt, TExpr { - /** - * DEPRECATED: Use `getConstantValue` instead. - * - * Gets the textual (constant) value of this expression, if any. - */ - deprecated string getValueText() { result = this.getConstantValue().toString() } - /** Gets the constant value of this expression, if any. */ ConstantValue getConstantValue() { result = getConstantValueExpr(this) } } diff --git a/ruby/ql/lib/codeql/ruby/ast/Literal.qll b/ruby/ql/lib/codeql/ruby/ast/Literal.qll index f860cbe5c2b..059db251fc4 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Literal.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Literal.qll @@ -165,14 +165,6 @@ class FileLiteral extends Literal instanceof FileLiteralImpl { * `StringEscapeSequenceComponent`, or `StringInterpolationComponent`. */ class StringComponent extends AstNode instanceof StringComponentImpl { - /** - * DEPRECATED: Use `getConstantValue` instead. - * - * Gets the source text for this string component. Has no result if this is - * a `StringInterpolationComponent`. - */ - deprecated string getValueText() { result = this.getConstantValue().toString() } - /** Gets the constant value of this string component, if any. */ ConstantValue::ConstantStringValue getConstantValue() { result = TString(super.getValue()) } } @@ -218,8 +210,6 @@ class StringInterpolationComponent extends StringComponent, StmtSequence instanc final override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) } - deprecated final override string getValueText() { none() } - final override ConstantValue::ConstantStringValue getConstantValue() { result = StmtSequence.super.getConstantValue() } @@ -267,8 +257,6 @@ class RegExpInterpolationComponent extends RegExpComponent, StmtSequence instanc final override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) } - deprecated final override string getValueText() { none() } - final override ConstantValue::ConstantStringValue getConstantValue() { result = StmtSequence.super.getConstantValue() } diff --git a/ruby/ql/lib/codeql/ruby/ast/Pattern.qll b/ruby/ql/lib/codeql/ruby/ast/Pattern.qll index 439881535da..ef778664031 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Pattern.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Pattern.qll @@ -363,19 +363,3 @@ class ReferencePattern extends CasePattern, TReferencePattern { pred = "getExpr" and result = this.getExpr() } } - -/** - * DEPRECATED: Use `ReferencePattern` instead. - * - * A variable reference in a pattern, i.e. `^x` in the following example: - * ```rb - * x = 10 - * case expr - * in ^x then puts "ok" - * end - * ``` - */ -deprecated class VariableReferencePattern extends ReferencePattern, TVariableReferencePattern { - /** Gets the variable access corresponding to this variable reference pattern. */ - final VariableReadAccess getVariableAccess() { result = this.getExpr() } -} diff --git a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll index 96c015a6a4a..507b37b6a8f 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll @@ -113,13 +113,6 @@ class ExprCfgNode extends AstCfgNode { /** Gets the underlying expression. */ Expr getExpr() { result = e } - /** - * DEPRECATED: Use `getConstantValue` instead. - * - * Gets the textual (constant) value of this expression, if any. - */ - deprecated string getValueText() { result = this.getConstantValue().toString() } - /** Gets the constant value of this expression, if any. */ ConstantValue getConstantValue() { result = getConstantValue(this) } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/StandardLibrary.qll b/ruby/ql/lib/codeql/ruby/frameworks/StandardLibrary.qll deleted file mode 100644 index d97cdd89dd4..00000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/StandardLibrary.qll +++ /dev/null @@ -1,97 +0,0 @@ -/** - * This module is deprecated, and exists as a shim to support any existing code that relies on it. - * New code should use `codeql.ruby.frameworks.Core` and `codeql.ruby.frameworks.Stdlib` instead. - */ - -private import codeql.ruby.frameworks.Core as Core -private import codeql.ruby.frameworks.Stdlib as Stdlib - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class SubshellLiteralExecution = Core::SubshellLiteralExecution; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class SubshellHeredocExecution = Core::SubshellHeredocExecution; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class BasicObjectInstanceMethodCall = Core::BasicObjectInstanceMethodCall; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated predicate basicObjectInstanceMethodName = Core::basicObjectInstanceMethodName/0; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class InstanceEvalCallCodeExecution = Core::InstanceEvalCallCodeExecution; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class ObjectInstanceMethodCall = Core::ObjectInstanceMethodCall; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated predicate objectInstanceMethodName = Core::objectInstanceMethodName/0; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class KernelMethodCall = Core::KernelMethodCall; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class KernelSystemCall = Core::KernelSystemCall; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class KernelExecCall = Core::KernelExecCall; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class KernelSpawnCall = Core::KernelSpawnCall; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class EvalCallCodeExecution = Core::EvalCallCodeExecution; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated class SendCallCodeExecution = Core::SendCallCodeExecution; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated module Module = Core::Module; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Core` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated module Array = Core::Array; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Stdlib` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated module Regexp = Core::Regexp; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Stdlib` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated module Open3 = Stdlib::Open3; - -/** - * DEPRECATED: Import `codeql.ruby.frameworks.Stdlib` instead of `codeql.ruby.frameworks.StandardLibrary`. - */ -deprecated module Logger = Stdlib::Logger; diff --git a/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll b/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll index e94ddf45d3e..02b0c4b36f9 100644 --- a/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ReflectedXSSQuery.qll @@ -37,6 +37,3 @@ module ReflectedXss { } } } - -/** DEPRECATED: Alias for ReflectedXss */ -deprecated module ReflectedXSS = ReflectedXss; diff --git a/ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll b/ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll index f08529988c7..74b43195ce6 100644 --- a/ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll @@ -58,6 +58,3 @@ module StoredXss { import TaintTracking::Global<Config> } - -/** DEPRECATED: Alias for StoredXss */ -deprecated module StoredXSS = StoredXss; diff --git a/ruby/ql/lib/codeql/ruby/security/XSS.qll b/ruby/ql/lib/codeql/ruby/security/XSS.qll index d4b99766a58..8196f508b55 100644 --- a/ruby/ql/lib/codeql/ruby/security/XSS.qll +++ b/ruby/ql/lib/codeql/ruby/security/XSS.qll @@ -243,9 +243,6 @@ private module Shared { or isFlowFromHelperMethod(node1, node2) } - - /** DEPRECATED: Alias for isAdditionalXssFlowStep */ - deprecated predicate isAdditionalXSSFlowStep = isAdditionalXssFlowStep/2; } /** @@ -275,9 +272,6 @@ module ReflectedXss { */ predicate isAdditionalXssTaintStep = Shared::isAdditionalXssFlowStep/2; - /** DEPRECATED: Alias for isAdditionalXssTaintStep */ - deprecated predicate isAdditionalXSSTaintStep = isAdditionalXssTaintStep/2; - /** * A HTTP request input, considered as a flow source. */ @@ -286,9 +280,6 @@ module ReflectedXss { } } -/** DEPRECATED: Alias for ReflectedXss */ -deprecated module ReflectedXSS = ReflectedXss; - private module OrmTracking { /** * A data flow configuration to track flow from finder calls to field accesses. @@ -330,9 +321,6 @@ module StoredXss { */ predicate isAdditionalXssTaintStep = Shared::isAdditionalXssFlowStep/2; - /** DEPRECATED: Alias for isAdditionalXssTaintStep */ - deprecated predicate isAdditionalXSSTaintStep = isAdditionalXssTaintStep/2; - private class OrmFieldAsSource extends Source instanceof DataFlow::CallNode { OrmFieldAsSource() { exists(DataFlow::CallNode subSrc | @@ -346,6 +334,3 @@ module StoredXss { private class FileSystemReadAccessAsSource extends Source instanceof FileSystemReadAccess { } // TODO: Consider `FileNameSource` flowing to script tag `src` attributes and similar } - -/** DEPRECATED: Alias for StoredXss */ -deprecated module StoredXSS = StoredXss; From 9000243828a1018b7ee9f316c58c2334178a6048 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 09:45:30 +0200 Subject: [PATCH 300/739] JS: fix compilation --- .../ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll b/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll index 468d31c2c02..7231143ed55 100644 --- a/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll +++ b/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll @@ -198,7 +198,7 @@ class MainModulePath extends PathExpr, @json_string { } /** DEPRECATED: Alias for getPackageJson */ - deprecated PackageJSON getPackageJSON() { result = this.getPackageJson() } + deprecated PackageJson getPackageJSON() { result = this.getPackageJson() } override string getValue() { result = this.(JsonString).getValue() } @@ -259,7 +259,7 @@ private class FilesPath extends PathExpr, @json_string { PackageJson getPackageJson() { result = pkg } /** DEPRECATED: Alias for getPackageJson */ - deprecated PackageJSON getPackageJSON() { result = this.getPackageJson() } + deprecated PackageJson getPackageJSON() { result = this.getPackageJson() } override string getValue() { result = this.(JsonString).getValue() } From c3e57382f7fffaa200e7c6f4fd9a5f18ba3eb5cf Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 09:50:33 +0200 Subject: [PATCH 301/739] Ruby: fix compilation --- ruby/ql/lib/codeql/ruby/Concepts.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/Concepts.qll b/ruby/ql/lib/codeql/ruby/Concepts.qll index 28d5990e76a..920c99c9034 100644 --- a/ruby/ql/lib/codeql/ruby/Concepts.qll +++ b/ruby/ql/lib/codeql/ruby/Concepts.qll @@ -687,9 +687,7 @@ module Http { * Gets a node that contributes to the URL of the request. * Depending on the framework, a request may have multiple nodes which contribute to the URL. */ - deprecated DataFlow::Node getURL() { - result = super.getURL() or result = Request::Range.super.getAUrlPart() - } + deprecated DataFlow::Node getURL() { result = Request::Range.super.getAUrlPart() } /** * Holds if this request is made using a mode that disables SSL/TLS From 3dfe2b30b161e22cf51cebdf30061bd7614fadcc Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 10:37:32 +0200 Subject: [PATCH 302/739] C#: delete override where the parent predicate no longer existed --- .../desugar/internal/TranslatedCompilerGeneratedElement.qll | 3 --- 1 file changed, 3 deletions(-) diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/internal/TranslatedCompilerGeneratedElement.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/internal/TranslatedCompilerGeneratedElement.qll index 30440235443..2e5908b8194 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/internal/TranslatedCompilerGeneratedElement.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/internal/TranslatedCompilerGeneratedElement.qll @@ -20,7 +20,4 @@ abstract class TranslatedCompilerGeneratedElement extends TranslatedElement, final override Callable getFunction() { result = generatedBy.getEnclosingCallable() } final override Language::AST getAst() { result = generatedBy } - - /** DEPRECATED: Alias for getAst */ - deprecated override Language::AST getAST() { result = this.getAst() } } From 3584e85fe8d707b9c679eaa49851854f459c7393 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Fri, 2 Jun 2023 07:47:15 +0200 Subject: [PATCH 303/739] JS: fix tutorial --- .../ql/test/tutorials/Validating RAML-based APIs/Osprey.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll b/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll index 02375976126..140bf59c4e6 100644 --- a/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll +++ b/javascript/ql/test/tutorials/Validating RAML-based APIs/Osprey.qll @@ -48,7 +48,7 @@ class OspreyMethodDefinition extends MethodCallExpr { OspreyApi getApi() { this.getReceiver() = result.getAnAccess() } /** DEPRECATED: Alias for getApi */ - deprecated OspreyAPI getAPI() { result = this.getApi() } + deprecated OspreyApi getAPI() { result = this.getApi() } /** Get the verb which this method implements. */ string getVerb() { result = this.getMethodName() } From 5cbe6db37dc00dce86ebd8badf342cbb04e51361 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Fri, 2 Jun 2023 07:51:14 +0200 Subject: [PATCH 304/739] C++: sync files from C# --- .../ir/implementation/aliased_ssa/Instruction.qll | 6 ------ .../aliased_ssa/internal/SSAConstruction.qll | 12 ------------ .../cpp/ir/implementation/internal/TInstruction.qll | 6 ------ .../code/cpp/ir/implementation/raw/Instruction.qll | 6 ------ .../ir/implementation/unaliased_ssa/Instruction.qll | 6 ------ .../unaliased_ssa/internal/SSAConstruction.qll | 12 ------------ .../unaliased_ssa/internal/SimpleSSA.qll | 6 ------ 7 files changed, 54 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 0aa7c552638..1b5ea432946 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -210,9 +210,6 @@ class Instruction extends Construction::TStageInstruction { */ final Language::AST getAst() { result = Construction::getInstructionAst(this) } - /** DEPRECATED: Alias for getAst */ - deprecated Language::AST getAST() { result = this.getAst() } - /** * Gets the location of the source code for this instruction. */ @@ -463,9 +460,6 @@ class VariableInstruction extends Instruction { * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } - - /** DEPRECATED: Alias for getAstVariable */ - deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll index dc785f3e0b1..63dc4142a13 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll @@ -422,12 +422,6 @@ private module Cached { ) } - /** DEPRECATED: Alias for getInstructionAst */ - cached - deprecated Language::AST getInstructionAST(Instruction instr) { - result = getInstructionAst(instr) - } - cached Language::LanguageType getInstructionResultType(Instruction instr) { result = instr.(RawIR::Instruction).getResultLanguageType() @@ -993,9 +987,6 @@ predicate canReuseSsaForMemoryResult(Instruction instruction) { // We don't support reusing SSA for any location that could create a `Chi` instruction. } -/** DEPRECATED: Alias for canReuseSsaForMemoryResult */ -deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1; - /** * Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the * `DebugSsa` module, which is then imported by PrintSSA. @@ -1005,9 +996,6 @@ module DebugSsa { import DefUse } -/** DEPRECATED: Alias for DebugSsa */ -deprecated module DebugSSA = DebugSsa; - import CachedForDebugging cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll index 169de03c2dc..bb3eb683653 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll @@ -73,9 +73,6 @@ module UnaliasedSsaInstructions { } } -/** DEPRECATED: Alias for UnaliasedSsaInstructions */ -deprecated module UnaliasedSSAInstructions = UnaliasedSsaInstructions; - /** * Provides wrappers for the constructors of each branch of `TInstruction` that is used by the * aliased SSA stage. @@ -107,6 +104,3 @@ module AliasedSsaInstructions { result = TAliasedSsaUnreachedInstruction(irFunc) } } - -/** DEPRECATED: Alias for AliasedSsaInstructions */ -deprecated module AliasedSSAInstructions = AliasedSsaInstructions; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 0aa7c552638..1b5ea432946 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -210,9 +210,6 @@ class Instruction extends Construction::TStageInstruction { */ final Language::AST getAst() { result = Construction::getInstructionAst(this) } - /** DEPRECATED: Alias for getAst */ - deprecated Language::AST getAST() { result = this.getAst() } - /** * Gets the location of the source code for this instruction. */ @@ -463,9 +460,6 @@ class VariableInstruction extends Instruction { * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } - - /** DEPRECATED: Alias for getAstVariable */ - deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 0aa7c552638..1b5ea432946 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -210,9 +210,6 @@ class Instruction extends Construction::TStageInstruction { */ final Language::AST getAst() { result = Construction::getInstructionAst(this) } - /** DEPRECATED: Alias for getAst */ - deprecated Language::AST getAST() { result = this.getAst() } - /** * Gets the location of the source code for this instruction. */ @@ -463,9 +460,6 @@ class VariableInstruction extends Instruction { * Gets the AST variable that this instruction's IR variable refers to, if one exists. */ final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() } - - /** DEPRECATED: Alias for getAstVariable */ - deprecated Language::Variable getASTVariable() { result = this.getAstVariable() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index dc785f3e0b1..63dc4142a13 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -422,12 +422,6 @@ private module Cached { ) } - /** DEPRECATED: Alias for getInstructionAst */ - cached - deprecated Language::AST getInstructionAST(Instruction instr) { - result = getInstructionAst(instr) - } - cached Language::LanguageType getInstructionResultType(Instruction instr) { result = instr.(RawIR::Instruction).getResultLanguageType() @@ -993,9 +987,6 @@ predicate canReuseSsaForMemoryResult(Instruction instruction) { // We don't support reusing SSA for any location that could create a `Chi` instruction. } -/** DEPRECATED: Alias for canReuseSsaForMemoryResult */ -deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1; - /** * Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the * `DebugSsa` module, which is then imported by PrintSSA. @@ -1005,9 +996,6 @@ module DebugSsa { import DefUse } -/** DEPRECATED: Alias for DebugSsa */ -deprecated module DebugSSA = DebugSsa; - import CachedForDebugging cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll index f5b0b3af930..5c33ecf5f99 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll @@ -46,9 +46,6 @@ predicate canReuseSsaForVariable(IRAutomaticVariable var) { not allocationEscapes(var) } -/** DEPRECATED: Alias for canReuseSsaForVariable */ -deprecated predicate canReuseSSAForVariable = canReuseSsaForVariable/1; - private newtype TMemoryLocation = MkMemoryLocation(Allocation var) { isVariableModeled(var) } private MemoryLocation getMemoryLocation(Allocation var) { result.getAllocation() = var } @@ -80,9 +77,6 @@ class MemoryLocation extends TMemoryLocation { predicate canReuseSsaForOldResult(Instruction instr) { none() } -/** DEPRECATED: Alias for canReuseSsaForOldResult */ -deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1; - /** * Represents a set of `MemoryLocation`s that cannot overlap with * `MemoryLocation`s outside of the set. The `VirtualVariable` will be From f61b781386bf5a8c761ba4fd81e51a41305c61a9 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Fri, 2 Jun 2023 11:49:26 +0200 Subject: [PATCH 305/739] JS: delete effectively empty file --- javascript/ql/src/Declarations/ArgumentsRedefined.ql | 1 - javascript/ql/src/Declarations/Definitions.qll | 1 - 2 files changed, 2 deletions(-) delete mode 100644 javascript/ql/src/Declarations/Definitions.qll diff --git a/javascript/ql/src/Declarations/ArgumentsRedefined.ql b/javascript/ql/src/Declarations/ArgumentsRedefined.ql index fdd70ac1479..dc1ca153062 100644 --- a/javascript/ql/src/Declarations/ArgumentsRedefined.ql +++ b/javascript/ql/src/Declarations/ArgumentsRedefined.ql @@ -12,7 +12,6 @@ */ import javascript -import Definitions from VarRef d where diff --git a/javascript/ql/src/Declarations/Definitions.qll b/javascript/ql/src/Declarations/Definitions.qll deleted file mode 100644 index 7046b14f09d..00000000000 --- a/javascript/ql/src/Declarations/Definitions.qll +++ /dev/null @@ -1 +0,0 @@ -import javascript From ac9ede4ec0d18d30f953216212aaf54d7a3eda26 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Fri, 2 Jun 2023 11:54:04 +0200 Subject: [PATCH 306/739] add change-notes --- csharp/ql/lib/change-notes/2023-06-02-delete-deps.md | 8 ++++++++ java/ql/lib/change-notes/2023-06-02-delete-deps.md | 6 ++++++ .../ql/lib/change-notes/2023-06-02-delete-deps.md | 10 ++++++++++ ruby/ql/lib/change-notes/2023-06-02-delete-deps.md | 7 +++++++ 4 files changed, 31 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2023-06-02-delete-deps.md create mode 100644 java/ql/lib/change-notes/2023-06-02-delete-deps.md create mode 100644 javascript/ql/lib/change-notes/2023-06-02-delete-deps.md create mode 100644 ruby/ql/lib/change-notes/2023-06-02-delete-deps.md diff --git a/csharp/ql/lib/change-notes/2023-06-02-delete-deps.md b/csharp/ql/lib/change-notes/2023-06-02-delete-deps.md new file mode 100644 index 00000000000..13402f08147 --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-06-02-delete-deps.md @@ -0,0 +1,8 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `WebConfigXML`, `ConfigurationXMLElement`, `LocationXMLElement`, `SystemWebXMLElement`, `SystemWebServerXMLElement`, `CustomErrorsXMLElement`, and `HttpRuntimeXMLElement` classes from `WebConfig.qll`. The non-deprecated names with PascalCased Xml suffixes should be used instead. +* Deleted the deprecated `Record` class from both `Types.qll` and `Type.qll`. +* Deleted the deprecated `StructuralComparisonConfiguration` class from `StructuralComparison.qll`, use `sameGvn` instead. +* Deleted the deprecated `isParameterOf` predicate from the `ParameterNode` class. +* Deleted the deprecated `SafeExternalAPICallable`, `ExternalAPIDataNode`, `UntrustedDataToExternalAPIConfig`, `UntrustedExternalAPIDataNode`, and `ExternalAPIUsedWithUntrustedData` classes from `ExternalAPIsQuery.qll`. The non-deprecated names with PascalCased Api suffixes should be used instead. diff --git a/java/ql/lib/change-notes/2023-06-02-delete-deps.md b/java/ql/lib/change-notes/2023-06-02-delete-deps.md new file mode 100644 index 00000000000..01b2fd5a457 --- /dev/null +++ b/java/ql/lib/change-notes/2023-06-02-delete-deps.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead. +* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead. +* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead. \ No newline at end of file diff --git a/javascript/ql/lib/change-notes/2023-06-02-delete-deps.md b/javascript/ql/lib/change-notes/2023-06-02-delete-deps.md new file mode 100644 index 00000000000..9edbce9771e --- /dev/null +++ b/javascript/ql/lib/change-notes/2023-06-02-delete-deps.md @@ -0,0 +1,10 @@ +--- +category: minorAnalysis +--- +* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead. +* Deleted the deprecated `localTaintStep` predicate from `DataFlow.qll`. +* Deleted the deprecated `stringStep`, and `localTaintStep` predicates from `TaintTracking.qll`. +* Deleted many modules that started with a lowercase letter. Use the versions that start with an uppercase letter instead. +* Deleted the deprecated `HtmlInjectionConfiguration` and `JQueryHtmlOrSelectorInjectionConfiguration` classes from `DomBasedXssQuery.qll`, use `Configuration` instead. +* Deleted the deprecated `DefiningIdentifier` class and the `Definitions.qll` file it was in. Use `SsaDefinition` instead. +* Deleted the deprecated `definitionReaches`, `localDefinitionReaches`, `getAPseudoDefinitionInput`, `nextDefAfter`, and `localDefinitionOverwrites` predicates from `DefUse.qll`. \ No newline at end of file diff --git a/ruby/ql/lib/change-notes/2023-06-02-delete-deps.md b/ruby/ql/lib/change-notes/2023-06-02-delete-deps.md new file mode 100644 index 00000000000..f4df20530dc --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-06-02-delete-deps.md @@ -0,0 +1,7 @@ +--- +category: minorAnalysis +--- +* Deleted many deprecated predicates and classes with uppercase `URL`, `XSS`, etc. in their names. Use the PascalCased versions instead. +* Deleted the deprecated `getValueText` predicate from the `Expr`, `StringComponent`, and `ExprCfgNode` classes. Use `getConstantValue` instead. +* Deleted the deprecated `VariableReferencePattern` class, use `ReferencePattern` instead. +* Deleted all deprecated aliases in `StandardLibrary.qll`, use `codeql.ruby.frameworks.Core` and `codeql.ruby.frameworks.Stdlib` instead. \ No newline at end of file From 5bf82aeddfa36d7cfbb520e2c71f454439c7a229 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 2 Jun 2023 11:13:57 +0100 Subject: [PATCH 307/739] Swift: Add FieldDecl.hasQualifiedName. --- .../codeql/swift/elements/decl/VarDecl.qll | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/VarDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/VarDecl.qll index ca650d12407..f7fd03bf906 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/VarDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/VarDecl.qll @@ -9,8 +9,32 @@ class VarDecl extends Generated::VarDecl { } /** - * A field declaration. + * A field declaration. That is, a variable declaration that is a member of a + * class, struct, enum or protocol. */ class FieldDecl extends VarDecl { FieldDecl() { this = any(Decl ctx).getAMember() } + + /** + * Holds if this field is called `fieldName` and is a member of a + * class, struct, extension, enum or protocol called `typeName`. + */ + cached + predicate hasQualifiedName(string typeName, string fieldName) { + this.getName() = fieldName and + exists(Decl d | + d.asNominalTypeDecl().getFullName() = typeName and + d.getAMember() = this + ) + } + + /** + * Holds if this field is called `fieldName` and is a member of a + * class, struct, extension, enum or protocol called `typeName` in a module + * called `moduleName`. + */ + predicate hasQualifiedName(string moduleName, string typeName, string fieldName) { + this.hasQualifiedName(typeName, fieldName) and + this.getModule().getFullName() = moduleName + } } From ac4933a9cc714809d0877eb99d983d77881796e2 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 2 Jun 2023 12:32:38 +0200 Subject: [PATCH 308/739] C++: Ensure that the sink instruction occurs last in `cpp/invalid-pointer-deref` This avoids some counter-intuitive paths where we would seemingly jump back to an earlier instruction, which might actually have been in bounds. --- .../CWE/CWE-193/InvalidPointerDeref.ql | 19 +- .../InvalidPointerDeref.expected | 296 ------------------ .../CWE/CWE-193/pointer-deref/test.cpp | 4 +- 3 files changed, 20 insertions(+), 299 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 610eb572d8c..dbbe398ff7d 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -179,6 +179,22 @@ predicate isSinkImpl( pointerAddInstructionHasBounds(pai, sink1, sink2, delta) } +/** + * Yields any instruction that is control-flow reachable from `instr`. + */ +Instruction getASuccessor(Instruction instr) { + exists(IRBlock b, int instrIndex, int resultIndex | + result.getBlock() = b and + instr.getBlock() = b and + b.getInstruction(instrIndex) = instr and + b.getInstruction(resultIndex) = result + | + resultIndex >= instrIndex + ) + or + instr.getBlock().getASuccessor+() = result.getBlock() +} + /** * Holds if `sink` is a sink for `InvalidPointerToDerefConfig` and `i` is a `StoreInstruction` that * writes to an address that non-strictly upper-bounds `sink`, or `i` is a `LoadInstruction` that @@ -189,7 +205,8 @@ predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string o exists(AddressOperand addr | bounded1(addr.getDef(), sink.asInstruction(), delta) and delta >= 0 and - i.getAnOperand() = addr + i.getAnOperand() = addr and + i = getASuccessor(sink.asInstruction()) | i instanceof StoreInstruction and operation = "write" diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 09c75e7369c..418251cf6db 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -9,15 +9,7 @@ edges | test.cpp:5:15:5:15 | p | test.cpp:7:16:7:16 | q | | test.cpp:5:15:5:15 | p | test.cpp:7:16:7:16 | q | | test.cpp:5:15:5:15 | p | test.cpp:8:16:8:16 | q | -| test.cpp:5:15:5:15 | p | test.cpp:8:16:8:16 | q | | test.cpp:5:15:5:15 | p | test.cpp:8:16:8:20 | ... + ... | -| test.cpp:5:15:5:15 | p | test.cpp:9:16:9:16 | q | -| test.cpp:5:15:5:15 | p | test.cpp:9:16:9:16 | q | -| test.cpp:5:15:5:15 | p | test.cpp:10:16:10:16 | q | -| test.cpp:5:15:5:15 | p | test.cpp:10:16:10:16 | q | -| test.cpp:5:15:5:15 | p | test.cpp:11:16:11:16 | q | -| test.cpp:5:15:5:15 | p | test.cpp:11:16:11:16 | q | -| test.cpp:5:15:5:15 | p | test.cpp:12:16:12:16 | q | | test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | ... + ... | | test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | ... + ... | | test.cpp:5:15:5:22 | ... + ... | test.cpp:6:14:6:15 | Load: * ... | @@ -38,22 +30,6 @@ edges | test.cpp:5:15:5:22 | ... + ... | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:5:15:5:22 | ... + ... | test.cpp:8:16:8:16 | q | | test.cpp:5:15:5:22 | ... + ... | test.cpp:8:16:8:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:8:16:8:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:8:16:8:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:9:16:9:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:9:16:9:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:9:16:9:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:9:16:9:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:10:16:10:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:10:16:10:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:10:16:10:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:10:16:10:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:11:16:11:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:11:16:11:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:11:16:11:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:11:16:11:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:12:16:12:16 | q | -| test.cpp:5:15:5:22 | ... + ... | test.cpp:12:16:12:16 | q | | test.cpp:6:15:6:15 | q | test.cpp:6:14:6:15 | Load: * ... | | test.cpp:6:15:6:15 | q | test.cpp:6:14:6:15 | Load: * ... | | test.cpp:6:15:6:15 | q | test.cpp:7:16:7:16 | q | @@ -61,62 +37,11 @@ edges | test.cpp:6:15:6:15 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:6:15:6:15 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:6:15:6:15 | q | test.cpp:8:16:8:16 | q | -| test.cpp:6:15:6:15 | q | test.cpp:8:16:8:16 | q | -| test.cpp:6:15:6:15 | q | test.cpp:9:16:9:16 | q | -| test.cpp:6:15:6:15 | q | test.cpp:9:16:9:16 | q | -| test.cpp:6:15:6:15 | q | test.cpp:10:16:10:16 | q | -| test.cpp:6:15:6:15 | q | test.cpp:10:16:10:16 | q | -| test.cpp:6:15:6:15 | q | test.cpp:11:16:11:16 | q | -| test.cpp:6:15:6:15 | q | test.cpp:11:16:11:16 | q | -| test.cpp:6:15:6:15 | q | test.cpp:12:16:12:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:7:16:7:16 | q | test.cpp:6:14:6:15 | Load: * ... | | test.cpp:7:16:7:16 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:7:16:7:16 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:7:16:7:16 | q | test.cpp:8:16:8:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:8:16:8:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:9:16:9:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:9:16:9:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:10:16:10:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:10:16:10:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:11:16:11:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:11:16:11:16 | q | -| test.cpp:7:16:7:16 | q | test.cpp:12:16:12:16 | q | -| test.cpp:8:16:8:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:8:16:8:16 | q | test.cpp:6:14:6:15 | Load: * ... | | test.cpp:8:16:8:16 | q | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:8:16:8:16 | q | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:8:16:8:16 | q | test.cpp:9:16:9:16 | q | -| test.cpp:8:16:8:16 | q | test.cpp:9:16:9:16 | q | -| test.cpp:8:16:8:16 | q | test.cpp:10:16:10:16 | q | -| test.cpp:8:16:8:16 | q | test.cpp:10:16:10:16 | q | -| test.cpp:8:16:8:16 | q | test.cpp:11:16:11:16 | q | -| test.cpp:8:16:8:16 | q | test.cpp:11:16:11:16 | q | -| test.cpp:8:16:8:16 | q | test.cpp:12:16:12:16 | q | | test.cpp:8:16:8:20 | ... + ... | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:9:16:9:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:9:16:9:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:9:16:9:16 | q | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:9:16:9:16 | q | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:9:16:9:16 | q | test.cpp:10:16:10:16 | q | -| test.cpp:9:16:9:16 | q | test.cpp:10:16:10:16 | q | -| test.cpp:9:16:9:16 | q | test.cpp:11:16:11:16 | q | -| test.cpp:9:16:9:16 | q | test.cpp:11:16:11:16 | q | -| test.cpp:9:16:9:16 | q | test.cpp:12:16:12:16 | q | -| test.cpp:10:16:10:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:10:16:10:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:10:16:10:16 | q | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:10:16:10:16 | q | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:10:16:10:16 | q | test.cpp:11:16:11:16 | q | -| test.cpp:10:16:10:16 | q | test.cpp:11:16:11:16 | q | -| test.cpp:10:16:10:16 | q | test.cpp:12:16:12:16 | q | -| test.cpp:11:16:11:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:11:16:11:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:11:16:11:16 | q | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:11:16:11:16 | q | test.cpp:8:14:8:21 | Load: * ... | -| test.cpp:11:16:11:16 | q | test.cpp:12:16:12:16 | q | -| test.cpp:12:16:12:16 | q | test.cpp:6:14:6:15 | Load: * ... | -| test.cpp:12:16:12:16 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:16:15:16:20 | call to malloc | test.cpp:17:15:17:15 | p | | test.cpp:17:15:17:15 | p | test.cpp:17:15:17:22 | ... + ... | | test.cpp:17:15:17:15 | p | test.cpp:20:16:20:20 | ... + ... | @@ -132,15 +57,7 @@ edges | test.cpp:29:15:29:15 | p | test.cpp:31:16:31:16 | q | | test.cpp:29:15:29:15 | p | test.cpp:31:16:31:16 | q | | test.cpp:29:15:29:15 | p | test.cpp:32:16:32:16 | q | -| test.cpp:29:15:29:15 | p | test.cpp:32:16:32:16 | q | | test.cpp:29:15:29:15 | p | test.cpp:32:16:32:20 | ... + ... | -| test.cpp:29:15:29:15 | p | test.cpp:33:16:33:16 | q | -| test.cpp:29:15:29:15 | p | test.cpp:33:16:33:16 | q | -| test.cpp:29:15:29:15 | p | test.cpp:34:16:34:16 | q | -| test.cpp:29:15:29:15 | p | test.cpp:34:16:34:16 | q | -| test.cpp:29:15:29:15 | p | test.cpp:35:16:35:16 | q | -| test.cpp:29:15:29:15 | p | test.cpp:35:16:35:16 | q | -| test.cpp:29:15:29:15 | p | test.cpp:36:16:36:16 | q | | test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | ... + ... | | test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | ... + ... | | test.cpp:29:15:29:28 | ... + ... | test.cpp:30:14:30:15 | Load: * ... | @@ -161,22 +78,6 @@ edges | test.cpp:29:15:29:28 | ... + ... | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:29:15:29:28 | ... + ... | test.cpp:32:16:32:16 | q | | test.cpp:29:15:29:28 | ... + ... | test.cpp:32:16:32:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:32:16:32:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:32:16:32:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:33:16:33:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:33:16:33:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:33:16:33:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:33:16:33:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:34:16:34:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:34:16:34:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:34:16:34:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:34:16:34:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:35:16:35:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:35:16:35:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:35:16:35:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:35:16:35:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:36:16:36:16 | q | -| test.cpp:29:15:29:28 | ... + ... | test.cpp:36:16:36:16 | q | | test.cpp:30:15:30:15 | q | test.cpp:30:14:30:15 | Load: * ... | | test.cpp:30:15:30:15 | q | test.cpp:30:14:30:15 | Load: * ... | | test.cpp:30:15:30:15 | q | test.cpp:31:16:31:16 | q | @@ -184,62 +85,11 @@ edges | test.cpp:30:15:30:15 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:30:15:30:15 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:30:15:30:15 | q | test.cpp:32:16:32:16 | q | -| test.cpp:30:15:30:15 | q | test.cpp:32:16:32:16 | q | -| test.cpp:30:15:30:15 | q | test.cpp:33:16:33:16 | q | -| test.cpp:30:15:30:15 | q | test.cpp:33:16:33:16 | q | -| test.cpp:30:15:30:15 | q | test.cpp:34:16:34:16 | q | -| test.cpp:30:15:30:15 | q | test.cpp:34:16:34:16 | q | -| test.cpp:30:15:30:15 | q | test.cpp:35:16:35:16 | q | -| test.cpp:30:15:30:15 | q | test.cpp:35:16:35:16 | q | -| test.cpp:30:15:30:15 | q | test.cpp:36:16:36:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:31:16:31:16 | q | test.cpp:30:14:30:15 | Load: * ... | | test.cpp:31:16:31:16 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:31:16:31:16 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:31:16:31:16 | q | test.cpp:32:16:32:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:32:16:32:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:33:16:33:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:33:16:33:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:34:16:34:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:34:16:34:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:35:16:35:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:35:16:35:16 | q | -| test.cpp:31:16:31:16 | q | test.cpp:36:16:36:16 | q | -| test.cpp:32:16:32:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:32:16:32:16 | q | test.cpp:30:14:30:15 | Load: * ... | | test.cpp:32:16:32:16 | q | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:32:16:32:16 | q | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:32:16:32:16 | q | test.cpp:33:16:33:16 | q | -| test.cpp:32:16:32:16 | q | test.cpp:33:16:33:16 | q | -| test.cpp:32:16:32:16 | q | test.cpp:34:16:34:16 | q | -| test.cpp:32:16:32:16 | q | test.cpp:34:16:34:16 | q | -| test.cpp:32:16:32:16 | q | test.cpp:35:16:35:16 | q | -| test.cpp:32:16:32:16 | q | test.cpp:35:16:35:16 | q | -| test.cpp:32:16:32:16 | q | test.cpp:36:16:36:16 | q | | test.cpp:32:16:32:20 | ... + ... | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:33:16:33:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:33:16:33:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:33:16:33:16 | q | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:33:16:33:16 | q | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:33:16:33:16 | q | test.cpp:34:16:34:16 | q | -| test.cpp:33:16:33:16 | q | test.cpp:34:16:34:16 | q | -| test.cpp:33:16:33:16 | q | test.cpp:35:16:35:16 | q | -| test.cpp:33:16:33:16 | q | test.cpp:35:16:35:16 | q | -| test.cpp:33:16:33:16 | q | test.cpp:36:16:36:16 | q | -| test.cpp:34:16:34:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:34:16:34:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:34:16:34:16 | q | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:34:16:34:16 | q | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:34:16:34:16 | q | test.cpp:35:16:35:16 | q | -| test.cpp:34:16:34:16 | q | test.cpp:35:16:35:16 | q | -| test.cpp:34:16:34:16 | q | test.cpp:36:16:36:16 | q | -| test.cpp:35:16:35:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:35:16:35:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:35:16:35:16 | q | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:35:16:35:16 | q | test.cpp:32:14:32:21 | Load: * ... | -| test.cpp:35:16:35:16 | q | test.cpp:36:16:36:16 | q | -| test.cpp:36:16:36:16 | q | test.cpp:30:14:30:15 | Load: * ... | -| test.cpp:36:16:36:16 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:40:15:40:20 | call to malloc | test.cpp:41:15:41:15 | p | | test.cpp:41:15:41:15 | p | test.cpp:41:15:41:28 | ... + ... | | test.cpp:41:15:41:15 | p | test.cpp:41:15:41:28 | ... + ... | @@ -250,15 +100,7 @@ edges | test.cpp:41:15:41:15 | p | test.cpp:43:16:43:16 | q | | test.cpp:41:15:41:15 | p | test.cpp:43:16:43:16 | q | | test.cpp:41:15:41:15 | p | test.cpp:44:16:44:16 | q | -| test.cpp:41:15:41:15 | p | test.cpp:44:16:44:16 | q | | test.cpp:41:15:41:15 | p | test.cpp:44:16:44:20 | ... + ... | -| test.cpp:41:15:41:15 | p | test.cpp:45:16:45:16 | q | -| test.cpp:41:15:41:15 | p | test.cpp:45:16:45:16 | q | -| test.cpp:41:15:41:15 | p | test.cpp:46:16:46:16 | q | -| test.cpp:41:15:41:15 | p | test.cpp:46:16:46:16 | q | -| test.cpp:41:15:41:15 | p | test.cpp:47:16:47:16 | q | -| test.cpp:41:15:41:15 | p | test.cpp:47:16:47:16 | q | -| test.cpp:41:15:41:15 | p | test.cpp:48:16:48:16 | q | | test.cpp:41:15:41:28 | ... + ... | test.cpp:41:15:41:28 | ... + ... | | test.cpp:41:15:41:28 | ... + ... | test.cpp:41:15:41:28 | ... + ... | | test.cpp:41:15:41:28 | ... + ... | test.cpp:42:14:42:15 | Load: * ... | @@ -279,22 +121,6 @@ edges | test.cpp:41:15:41:28 | ... + ... | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:41:15:41:28 | ... + ... | test.cpp:44:16:44:16 | q | | test.cpp:41:15:41:28 | ... + ... | test.cpp:44:16:44:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:44:16:44:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:44:16:44:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:45:16:45:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:45:16:45:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:45:16:45:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:45:16:45:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:46:16:46:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:46:16:46:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:46:16:46:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:46:16:46:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:47:16:47:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:47:16:47:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:47:16:47:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:47:16:47:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:48:16:48:16 | q | -| test.cpp:41:15:41:28 | ... + ... | test.cpp:48:16:48:16 | q | | test.cpp:42:15:42:15 | q | test.cpp:42:14:42:15 | Load: * ... | | test.cpp:42:15:42:15 | q | test.cpp:42:14:42:15 | Load: * ... | | test.cpp:42:15:42:15 | q | test.cpp:43:16:43:16 | q | @@ -302,62 +128,11 @@ edges | test.cpp:42:15:42:15 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:42:15:42:15 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:42:15:42:15 | q | test.cpp:44:16:44:16 | q | -| test.cpp:42:15:42:15 | q | test.cpp:44:16:44:16 | q | -| test.cpp:42:15:42:15 | q | test.cpp:45:16:45:16 | q | -| test.cpp:42:15:42:15 | q | test.cpp:45:16:45:16 | q | -| test.cpp:42:15:42:15 | q | test.cpp:46:16:46:16 | q | -| test.cpp:42:15:42:15 | q | test.cpp:46:16:46:16 | q | -| test.cpp:42:15:42:15 | q | test.cpp:47:16:47:16 | q | -| test.cpp:42:15:42:15 | q | test.cpp:47:16:47:16 | q | -| test.cpp:42:15:42:15 | q | test.cpp:48:16:48:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:43:16:43:16 | q | test.cpp:42:14:42:15 | Load: * ... | | test.cpp:43:16:43:16 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:43:16:43:16 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:43:16:43:16 | q | test.cpp:44:16:44:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:44:16:44:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:45:16:45:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:45:16:45:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:46:16:46:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:46:16:46:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:47:16:47:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:47:16:47:16 | q | -| test.cpp:43:16:43:16 | q | test.cpp:48:16:48:16 | q | -| test.cpp:44:16:44:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:44:16:44:16 | q | test.cpp:42:14:42:15 | Load: * ... | | test.cpp:44:16:44:16 | q | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:44:16:44:16 | q | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:44:16:44:16 | q | test.cpp:45:16:45:16 | q | -| test.cpp:44:16:44:16 | q | test.cpp:45:16:45:16 | q | -| test.cpp:44:16:44:16 | q | test.cpp:46:16:46:16 | q | -| test.cpp:44:16:44:16 | q | test.cpp:46:16:46:16 | q | -| test.cpp:44:16:44:16 | q | test.cpp:47:16:47:16 | q | -| test.cpp:44:16:44:16 | q | test.cpp:47:16:47:16 | q | -| test.cpp:44:16:44:16 | q | test.cpp:48:16:48:16 | q | | test.cpp:44:16:44:20 | ... + ... | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:45:16:45:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:45:16:45:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:45:16:45:16 | q | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:45:16:45:16 | q | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:45:16:45:16 | q | test.cpp:46:16:46:16 | q | -| test.cpp:45:16:45:16 | q | test.cpp:46:16:46:16 | q | -| test.cpp:45:16:45:16 | q | test.cpp:47:16:47:16 | q | -| test.cpp:45:16:45:16 | q | test.cpp:47:16:47:16 | q | -| test.cpp:45:16:45:16 | q | test.cpp:48:16:48:16 | q | -| test.cpp:46:16:46:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:46:16:46:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:46:16:46:16 | q | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:46:16:46:16 | q | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:46:16:46:16 | q | test.cpp:47:16:47:16 | q | -| test.cpp:46:16:46:16 | q | test.cpp:47:16:47:16 | q | -| test.cpp:46:16:46:16 | q | test.cpp:48:16:48:16 | q | -| test.cpp:47:16:47:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:47:16:47:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:47:16:47:16 | q | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:47:16:47:16 | q | test.cpp:44:14:44:21 | Load: * ... | -| test.cpp:47:16:47:16 | q | test.cpp:48:16:48:16 | q | -| test.cpp:48:16:48:16 | q | test.cpp:42:14:42:15 | Load: * ... | -| test.cpp:48:16:48:16 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:51:7:51:14 | mk_array indirection | test.cpp:60:19:60:26 | call to mk_array | | test.cpp:51:33:51:35 | end | test.cpp:60:34:60:37 | mk_array output argument | | test.cpp:52:19:52:24 | call to malloc | test.cpp:51:7:51:14 | mk_array indirection | @@ -371,10 +146,8 @@ edges | test.cpp:60:19:60:26 | call to mk_array | test.cpp:70:38:70:38 | p | | test.cpp:60:34:60:37 | mk_array output argument | test.cpp:62:32:62:34 | end | | test.cpp:60:34:60:37 | mk_array output argument | test.cpp:66:32:66:34 | end | -| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:70:31:70:33 | end | | test.cpp:62:32:62:34 | end | test.cpp:67:9:67:14 | Store: ... = ... | | test.cpp:66:32:66:34 | end | test.cpp:67:9:67:14 | Store: ... = ... | -| test.cpp:70:31:70:33 | end | test.cpp:67:9:67:14 | Store: ... = ... | | test.cpp:80:9:80:16 | mk_array indirection [begin] | test.cpp:89:19:89:26 | call to mk_array [begin] | | test.cpp:80:9:80:16 | mk_array indirection [begin] | test.cpp:119:18:119:25 | call to mk_array [begin] | | test.cpp:80:9:80:16 | mk_array indirection [end] | test.cpp:89:19:89:26 | call to mk_array [end] | @@ -395,7 +168,6 @@ edges | test.cpp:89:19:89:26 | call to mk_array [begin] | test.cpp:99:20:99:22 | arr indirection [begin] | | test.cpp:89:19:89:26 | call to mk_array [end] | test.cpp:91:36:91:38 | arr indirection [end] | | test.cpp:89:19:89:26 | call to mk_array [end] | test.cpp:95:36:95:38 | arr indirection [end] | -| test.cpp:89:19:89:26 | call to mk_array [end] | test.cpp:99:35:99:37 | arr indirection [end] | | test.cpp:91:20:91:22 | arr indirection [begin] | test.cpp:91:24:91:28 | begin | | test.cpp:91:20:91:22 | arr indirection [begin] | test.cpp:91:24:91:28 | begin indirection | | test.cpp:91:24:91:28 | begin | test.cpp:91:47:91:47 | p | @@ -416,16 +188,11 @@ edges | test.cpp:99:20:99:22 | arr indirection [begin] | test.cpp:99:24:99:28 | begin indirection | | test.cpp:99:24:99:28 | begin | test.cpp:99:46:99:46 | p | | test.cpp:99:24:99:28 | begin indirection | test.cpp:99:46:99:46 | p | -| test.cpp:99:35:99:37 | arr indirection [end] | test.cpp:99:39:99:41 | end | -| test.cpp:99:35:99:37 | arr indirection [end] | test.cpp:99:39:99:41 | end indirection | -| test.cpp:99:39:99:41 | end | test.cpp:96:9:96:14 | Store: ... = ... | -| test.cpp:99:39:99:41 | end indirection | test.cpp:99:39:99:41 | end | | test.cpp:104:27:104:29 | arr [begin] | test.cpp:105:20:105:22 | arr indirection [begin] | | test.cpp:104:27:104:29 | arr [begin] | test.cpp:109:20:109:22 | arr indirection [begin] | | test.cpp:104:27:104:29 | arr [begin] | test.cpp:113:20:113:22 | arr indirection [begin] | | test.cpp:104:27:104:29 | arr [end] | test.cpp:105:36:105:38 | arr indirection [end] | | test.cpp:104:27:104:29 | arr [end] | test.cpp:109:36:109:38 | arr indirection [end] | -| test.cpp:104:27:104:29 | arr [end] | test.cpp:113:35:113:37 | arr indirection [end] | | test.cpp:105:20:105:22 | arr indirection [begin] | test.cpp:105:24:105:28 | begin | | test.cpp:105:20:105:22 | arr indirection [begin] | test.cpp:105:24:105:28 | begin indirection | | test.cpp:105:24:105:28 | begin | test.cpp:105:47:105:47 | p | @@ -446,10 +213,6 @@ edges | test.cpp:113:20:113:22 | arr indirection [begin] | test.cpp:113:24:113:28 | begin indirection | | test.cpp:113:24:113:28 | begin | test.cpp:113:46:113:46 | p | | test.cpp:113:24:113:28 | begin indirection | test.cpp:113:46:113:46 | p | -| test.cpp:113:35:113:37 | arr indirection [end] | test.cpp:113:39:113:41 | end | -| test.cpp:113:35:113:37 | arr indirection [end] | test.cpp:113:39:113:41 | end indirection | -| test.cpp:113:39:113:41 | end | test.cpp:110:9:110:14 | Store: ... = ... | -| test.cpp:113:39:113:41 | end indirection | test.cpp:113:39:113:41 | end | | test.cpp:119:18:119:25 | call to mk_array [begin] | test.cpp:104:27:104:29 | arr [begin] | | test.cpp:119:18:119:25 | call to mk_array [end] | test.cpp:104:27:104:29 | arr [end] | | test.cpp:124:15:124:20 | call to malloc | test.cpp:125:5:125:17 | ... = ... | @@ -504,7 +267,6 @@ edges | test.cpp:165:29:165:31 | arr indirection [begin] | test.cpp:174:20:174:22 | arr indirection [begin] | | test.cpp:165:29:165:31 | arr indirection [end] | test.cpp:166:37:166:39 | arr indirection [end] | | test.cpp:165:29:165:31 | arr indirection [end] | test.cpp:170:37:170:39 | arr indirection [end] | -| test.cpp:165:29:165:31 | arr indirection [end] | test.cpp:174:36:174:38 | arr indirection [end] | | test.cpp:166:20:166:22 | arr indirection [begin] | test.cpp:166:25:166:29 | begin | | test.cpp:166:20:166:22 | arr indirection [begin] | test.cpp:166:25:166:29 | begin indirection | | test.cpp:166:25:166:29 | begin | test.cpp:166:49:166:49 | p | @@ -525,10 +287,6 @@ edges | test.cpp:174:20:174:22 | arr indirection [begin] | test.cpp:174:25:174:29 | begin indirection | | test.cpp:174:25:174:29 | begin | test.cpp:174:48:174:48 | p | | test.cpp:174:25:174:29 | begin indirection | test.cpp:174:48:174:48 | p | -| test.cpp:174:36:174:38 | arr indirection [end] | test.cpp:174:41:174:43 | end | -| test.cpp:174:36:174:38 | arr indirection [end] | test.cpp:174:41:174:43 | end indirection | -| test.cpp:174:41:174:43 | end | test.cpp:171:9:171:14 | Store: ... = ... | -| test.cpp:174:41:174:43 | end indirection | test.cpp:174:41:174:43 | end | | test.cpp:180:19:180:28 | call to mk_array_p indirection [begin] | test.cpp:165:29:165:31 | arr indirection [begin] | | test.cpp:180:19:180:28 | call to mk_array_p indirection [end] | test.cpp:165:29:165:31 | arr indirection [end] | | test.cpp:188:15:188:20 | call to malloc | test.cpp:189:15:189:15 | p | @@ -655,16 +413,6 @@ edges | test.cpp:308:5:308:11 | access to array | test.cpp:308:5:308:29 | Store: ... = ... | | test.cpp:313:14:313:27 | new[] | test.cpp:314:15:314:16 | xs | | test.cpp:325:14:325:27 | new[] | test.cpp:326:15:326:16 | xs | -| test.cpp:326:15:326:16 | xs | test.cpp:326:15:326:23 | ... + ... | -| test.cpp:326:15:326:16 | xs | test.cpp:326:15:326:23 | ... + ... | -| test.cpp:326:15:326:16 | xs | test.cpp:338:8:338:15 | * ... | -| test.cpp:326:15:326:16 | xs | test.cpp:341:8:341:17 | * ... | -| test.cpp:326:15:326:23 | ... + ... | test.cpp:342:8:342:17 | * ... | -| test.cpp:326:15:326:23 | ... + ... | test.cpp:342:8:342:17 | * ... | -| test.cpp:338:8:338:15 | * ... | test.cpp:342:8:342:17 | * ... | -| test.cpp:341:8:341:17 | * ... | test.cpp:342:8:342:17 | * ... | -| test.cpp:342:8:342:17 | * ... | test.cpp:333:5:333:21 | Store: ... = ... | -| test.cpp:342:8:342:17 | * ... | test.cpp:341:5:341:21 | Store: ... = ... | | test.cpp:347:14:347:27 | new[] | test.cpp:348:15:348:16 | xs | | test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ | | test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ | @@ -720,7 +468,6 @@ edges | test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:16:359:27 | end_plus_one | -| test.cpp:359:16:359:27 | end_plus_one | test.cpp:358:14:358:26 | Load: * ... | | test.cpp:359:16:359:27 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:359:16:359:31 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:363:14:363:27 | new[] | test.cpp:365:15:365:15 | p | @@ -746,15 +493,7 @@ nodes | test.cpp:7:16:7:16 | q | semmle.label | q | | test.cpp:8:14:8:21 | Load: * ... | semmle.label | Load: * ... | | test.cpp:8:16:8:16 | q | semmle.label | q | -| test.cpp:8:16:8:16 | q | semmle.label | q | | test.cpp:8:16:8:20 | ... + ... | semmle.label | ... + ... | -| test.cpp:9:16:9:16 | q | semmle.label | q | -| test.cpp:9:16:9:16 | q | semmle.label | q | -| test.cpp:10:16:10:16 | q | semmle.label | q | -| test.cpp:10:16:10:16 | q | semmle.label | q | -| test.cpp:11:16:11:16 | q | semmle.label | q | -| test.cpp:11:16:11:16 | q | semmle.label | q | -| test.cpp:12:16:12:16 | q | semmle.label | q | | test.cpp:16:15:16:20 | call to malloc | semmle.label | call to malloc | | test.cpp:17:15:17:15 | p | semmle.label | p | | test.cpp:17:15:17:22 | ... + ... | semmle.label | ... + ... | @@ -773,15 +512,7 @@ nodes | test.cpp:31:16:31:16 | q | semmle.label | q | | test.cpp:32:14:32:21 | Load: * ... | semmle.label | Load: * ... | | test.cpp:32:16:32:16 | q | semmle.label | q | -| test.cpp:32:16:32:16 | q | semmle.label | q | | test.cpp:32:16:32:20 | ... + ... | semmle.label | ... + ... | -| test.cpp:33:16:33:16 | q | semmle.label | q | -| test.cpp:33:16:33:16 | q | semmle.label | q | -| test.cpp:34:16:34:16 | q | semmle.label | q | -| test.cpp:34:16:34:16 | q | semmle.label | q | -| test.cpp:35:16:35:16 | q | semmle.label | q | -| test.cpp:35:16:35:16 | q | semmle.label | q | -| test.cpp:36:16:36:16 | q | semmle.label | q | | test.cpp:40:15:40:20 | call to malloc | semmle.label | call to malloc | | test.cpp:41:15:41:15 | p | semmle.label | p | | test.cpp:41:15:41:28 | ... + ... | semmle.label | ... + ... | @@ -795,15 +526,7 @@ nodes | test.cpp:43:16:43:16 | q | semmle.label | q | | test.cpp:44:14:44:21 | Load: * ... | semmle.label | Load: * ... | | test.cpp:44:16:44:16 | q | semmle.label | q | -| test.cpp:44:16:44:16 | q | semmle.label | q | | test.cpp:44:16:44:20 | ... + ... | semmle.label | ... + ... | -| test.cpp:45:16:45:16 | q | semmle.label | q | -| test.cpp:45:16:45:16 | q | semmle.label | q | -| test.cpp:46:16:46:16 | q | semmle.label | q | -| test.cpp:46:16:46:16 | q | semmle.label | q | -| test.cpp:47:16:47:16 | q | semmle.label | q | -| test.cpp:47:16:47:16 | q | semmle.label | q | -| test.cpp:48:16:48:16 | q | semmle.label | q | | test.cpp:51:7:51:14 | mk_array indirection | semmle.label | mk_array indirection | | test.cpp:51:33:51:35 | end | semmle.label | end | | test.cpp:52:19:52:24 | call to malloc | semmle.label | call to malloc | @@ -817,7 +540,6 @@ nodes | test.cpp:66:32:66:34 | end | semmle.label | end | | test.cpp:66:39:66:39 | p | semmle.label | p | | test.cpp:67:9:67:14 | Store: ... = ... | semmle.label | Store: ... = ... | -| test.cpp:70:31:70:33 | end | semmle.label | end | | test.cpp:70:38:70:38 | p | semmle.label | p | | test.cpp:80:9:80:16 | mk_array indirection [begin] | semmle.label | mk_array indirection [begin] | | test.cpp:80:9:80:16 | mk_array indirection [end] | semmle.label | mk_array indirection [end] | @@ -850,9 +572,6 @@ nodes | test.cpp:99:20:99:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | | test.cpp:99:24:99:28 | begin | semmle.label | begin | | test.cpp:99:24:99:28 | begin indirection | semmle.label | begin indirection | -| test.cpp:99:35:99:37 | arr indirection [end] | semmle.label | arr indirection [end] | -| test.cpp:99:39:99:41 | end | semmle.label | end | -| test.cpp:99:39:99:41 | end indirection | semmle.label | end indirection | | test.cpp:99:46:99:46 | p | semmle.label | p | | test.cpp:104:27:104:29 | arr [begin] | semmle.label | arr [begin] | | test.cpp:104:27:104:29 | arr [end] | semmle.label | arr [end] | @@ -874,9 +593,6 @@ nodes | test.cpp:113:20:113:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | | test.cpp:113:24:113:28 | begin | semmle.label | begin | | test.cpp:113:24:113:28 | begin indirection | semmle.label | begin indirection | -| test.cpp:113:35:113:37 | arr indirection [end] | semmle.label | arr indirection [end] | -| test.cpp:113:39:113:41 | end | semmle.label | end | -| test.cpp:113:39:113:41 | end indirection | semmle.label | end indirection | | test.cpp:113:46:113:46 | p | semmle.label | p | | test.cpp:119:18:119:25 | call to mk_array [begin] | semmle.label | call to mk_array [begin] | | test.cpp:119:18:119:25 | call to mk_array [end] | semmle.label | call to mk_array [end] | @@ -942,9 +658,6 @@ nodes | test.cpp:174:20:174:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | | test.cpp:174:25:174:29 | begin | semmle.label | begin | | test.cpp:174:25:174:29 | begin indirection | semmle.label | begin indirection | -| test.cpp:174:36:174:38 | arr indirection [end] | semmle.label | arr indirection [end] | -| test.cpp:174:41:174:43 | end | semmle.label | end | -| test.cpp:174:41:174:43 | end indirection | semmle.label | end indirection | | test.cpp:174:48:174:48 | p | semmle.label | p | | test.cpp:180:19:180:28 | call to mk_array_p indirection [begin] | semmle.label | call to mk_array_p indirection [begin] | | test.cpp:180:19:180:28 | call to mk_array_p indirection [end] | semmle.label | call to mk_array_p indirection [end] | @@ -1029,13 +742,6 @@ nodes | test.cpp:314:15:314:16 | xs | semmle.label | xs | | test.cpp:325:14:325:27 | new[] | semmle.label | new[] | | test.cpp:326:15:326:16 | xs | semmle.label | xs | -| test.cpp:326:15:326:23 | ... + ... | semmle.label | ... + ... | -| test.cpp:326:15:326:23 | ... + ... | semmle.label | ... + ... | -| test.cpp:333:5:333:21 | Store: ... = ... | semmle.label | Store: ... = ... | -| test.cpp:338:8:338:15 | * ... | semmle.label | * ... | -| test.cpp:341:5:341:21 | Store: ... = ... | semmle.label | Store: ... = ... | -| test.cpp:341:8:341:17 | * ... | semmle.label | * ... | -| test.cpp:342:8:342:17 | * ... | semmle.label | * ... | | test.cpp:347:14:347:27 | new[] | semmle.label | new[] | | test.cpp:348:15:348:16 | xs | semmle.label | xs | | test.cpp:350:15:350:19 | Load: * ... | semmle.label | Load: * ... | @@ -1088,8 +794,6 @@ subpaths | test.cpp:264:13:264:14 | Load: * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len | | test.cpp:274:5:274:10 | Store: ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len | | test.cpp:308:5:308:29 | Store: ... = ... | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:304:15:304:26 | new[] | new[] | test.cpp:308:8:308:10 | ... + ... | ... + ... | -| test.cpp:333:5:333:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:333:5:333:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size | -| test.cpp:341:5:341:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:341:5:341:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size | | test.cpp:350:15:350:19 | Load: * ... | test.cpp:347:14:347:27 | new[] | test.cpp:350:15:350:19 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:347:14:347:27 | new[] | new[] | test.cpp:348:20:348:23 | size | size | | test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index 3711f272e76..5e79aaa4bd9 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -330,7 +330,7 @@ void test23(unsigned size, int val) { if(*current - xs < 1) return; - *--(*current) = 0; // GOOD [FALSE POSITIVE] + *--(*current) = 0; // GOOD return; } @@ -338,7 +338,7 @@ void test23(unsigned size, int val) { if(*current - xs < 2) return; - *--(*current) = 0; // GOOD [FALSE POSITIVE] + *--(*current) = 0; // GOOD *--(*current) = 0; // GOOD } } From c7c8807f40b4c5e864a4a2d05e15e2d1f4744ad9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 2 Jun 2023 11:44:47 +0100 Subject: [PATCH 309/739] Swift: Use FieldDecl.hasQualifiedName. --- .../frameworks/StandardLibrary/Collection.qll | 7 ++--- .../frameworks/StandardLibrary/NsString.qll | 29 +++++++++---------- .../frameworks/StandardLibrary/Sequence.qll | 7 +---- .../frameworks/StandardLibrary/String.qll | 22 +++++++------- .../frameworks/StandardLibrary/WebView.qll | 7 +---- .../security/CleartextLoggingExtensions.qll | 7 +---- 6 files changed, 31 insertions(+), 48 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll index fcbd418f6b9..cf3ff748d48 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll @@ -47,9 +47,8 @@ private class CollectionFieldsInheritTaint extends TaintInheritingContent, DataFlow::Content::FieldContent { CollectionFieldsInheritTaint() { - exists(FieldDecl f | this.getField() = f | - f.getEnclosingDecl().asNominalTypeDecl().getName() = ["Collection", "BidirectionalCollection"] and - f.getName() = ["first", "last"] - ) + this.getField() + .(FieldDecl) + .hasQualifiedName(["Collection", "BidirectionalCollection"], ["first", "last"]) } } diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NsString.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NsString.qll index ce8b959fffe..d9743140c34 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NsString.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NsString.qll @@ -132,20 +132,19 @@ private class NsStringFieldsInheritTaint extends TaintInheritingContent, DataFlow::Content::FieldContent { NsStringFieldsInheritTaint() { - exists(FieldDecl f | this.getField() = f | - f.getEnclosingDecl().asNominalTypeDecl().getName() = "NSString" and - f.getName() = - [ - "utf8String", "lowercased", "localizedLowedCase", "uppercased", "localizedUppercase", - "capitalized", "localizedCapitalized", "decomposedStringWithCanonicalMapping", - "decomposedStringWithCompatibilityMapping", "precomposedStringWithCanonicalMapping", - "precomposedStringWithCompatibilityMapping", "doubleValue", "floatValue", "intValue", - "integerValue", "longLongValue", "boolValue", "description", "pathComponents", - "fileSystemRepresentation", "lastPathComponent", "pathExtension", - "abbreviatingWithTildeInPath", "deletingLastPathComponent", "deletingPathExtension", - "expandingTildeInPath", "resolvingSymlinksInPath", "standardizingPath", - "removingPercentEncoding" - ] - ) + this.getField() + .(FieldDecl) + .hasQualifiedName("NSString", + [ + "utf8String", "lowercased", "localizedLowedCase", "uppercased", "localizedUppercase", + "capitalized", "localizedCapitalized", "decomposedStringWithCanonicalMapping", + "decomposedStringWithCompatibilityMapping", "precomposedStringWithCanonicalMapping", + "precomposedStringWithCompatibilityMapping", "doubleValue", "floatValue", "intValue", + "integerValue", "longLongValue", "boolValue", "description", "pathComponents", + "fileSystemRepresentation", "lastPathComponent", "pathExtension", + "abbreviatingWithTildeInPath", "deletingLastPathComponent", "deletingPathExtension", + "expandingTildeInPath", "resolvingSymlinksInPath", "standardizingPath", + "removingPercentEncoding" + ]) } } diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll index 8d4eb9eb39d..b4e68513c1d 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll @@ -36,10 +36,5 @@ private class SequenceSummaries extends SummaryModelCsv { private class SequenceFieldsInheritTaint extends TaintInheritingContent, DataFlow::Content::FieldContent { - SequenceFieldsInheritTaint() { - exists(FieldDecl f | this.getField() = f | - f.getEnclosingDecl().asNominalTypeDecl().getName() = "Sequence" and - f.getName() = "lazy" - ) - } + SequenceFieldsInheritTaint() { this.getField().(FieldDecl).hasQualifiedName("Sequence", "lazy") } } diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll index 2df33a0f0f4..51424e2d042 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll @@ -124,16 +124,16 @@ private class StringFieldsInheritTaint extends TaintInheritingContent, DataFlow::Content::FieldContent { StringFieldsInheritTaint() { - exists(FieldDecl f | this.getField() = f | - f.getEnclosingDecl().asNominalTypeDecl().getName() = ["String", "StringProtocol"] and - f.getName() = - [ - "unicodeScalars", "utf8", "utf16", "lazy", "utf8CString", "description", - "debugDescription", "dataValue", "identifierValue", "capitalized", "localizedCapitalized", - "localizedLowercase", "localizedUppercase", "decomposedStringWithCanonicalMapping", - "decomposedStringWithCompatibilityMapping", "precomposedStringWithCanonicalMapping", - "precomposedStringWithCompatibilityMapping", "removingPercentEncoding" - ] - ) + this.getField() + .(FieldDecl) + .hasQualifiedName(["String", "StringProtocol"], + [ + "unicodeScalars", "utf8", "utf16", "lazy", "utf8CString", "description", + "debugDescription", "dataValue", "identifierValue", "capitalized", + "localizedCapitalized", "localizedLowercase", "localizedUppercase", + "decomposedStringWithCanonicalMapping", "decomposedStringWithCompatibilityMapping", + "precomposedStringWithCanonicalMapping", "precomposedStringWithCompatibilityMapping", + "removingPercentEncoding" + ]) } } diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll index 6dd8321388a..b845ee81104 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/WebView.qll @@ -208,10 +208,5 @@ private class WKUserScriptSummaries extends SummaryModelCsv { private class WKUserScriptInheritsTaint extends TaintInheritingContent, DataFlow::Content::FieldContent { - WKUserScriptInheritsTaint() { - exists(FieldDecl f | this.getField() = f | - f.getEnclosingDecl().asNominalTypeDecl().getName() = "WKUserScript" and - f.getName() = "source" - ) - } + WKUserScriptInheritsTaint() { this.getField().hasQualifiedName("WKUserScript", "source") } } diff --git a/swift/ql/lib/codeql/swift/security/CleartextLoggingExtensions.qll b/swift/ql/lib/codeql/swift/security/CleartextLoggingExtensions.qll index 935da6a232e..21bf855d1fc 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextLoggingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextLoggingExtensions.qll @@ -74,12 +74,7 @@ private class OsLogNonRedactedType extends Type { private class OsLogPrivacyRef extends MemberRefExpr { string optionName; - OsLogPrivacyRef() { - exists(FieldDecl f | this.getMember() = f | - f.getEnclosingDecl().asNominalTypeDecl().getName() = "OSLogPrivacy" and - optionName = f.getName() - ) - } + OsLogPrivacyRef() { this.getMember().(FieldDecl).hasQualifiedName("OSLogPrivacy", optionName) } /** Holds if this is a safe privacy option (private or sensitive). */ predicate isSafe() { optionName = ["private", "sensitive"] } From 4c8225724b45a85178b9800402a008a69a9cc3e9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:21:17 +0100 Subject: [PATCH 310/739] Swift: Fix QL-for-QL warnings. --- .../codeql/swift/frameworks/StandardLibrary/Collection.qll | 4 +--- .../lib/codeql/swift/frameworks/StandardLibrary/NsString.qll | 1 - .../lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll | 2 +- .../ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll | 1 - 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll index cf3ff748d48..6022d4b767a 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Collection.qll @@ -47,8 +47,6 @@ private class CollectionFieldsInheritTaint extends TaintInheritingContent, DataFlow::Content::FieldContent { CollectionFieldsInheritTaint() { - this.getField() - .(FieldDecl) - .hasQualifiedName(["Collection", "BidirectionalCollection"], ["first", "last"]) + this.getField().hasQualifiedName(["Collection", "BidirectionalCollection"], ["first", "last"]) } } diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NsString.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NsString.qll index d9743140c34..f866ba23a17 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NsString.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/NsString.qll @@ -133,7 +133,6 @@ private class NsStringFieldsInheritTaint extends TaintInheritingContent, { NsStringFieldsInheritTaint() { this.getField() - .(FieldDecl) .hasQualifiedName("NSString", [ "utf8String", "lowercased", "localizedLowedCase", "uppercased", "localizedUppercase", diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll index b4e68513c1d..e830b6cc1a4 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Sequence.qll @@ -36,5 +36,5 @@ private class SequenceSummaries extends SummaryModelCsv { private class SequenceFieldsInheritTaint extends TaintInheritingContent, DataFlow::Content::FieldContent { - SequenceFieldsInheritTaint() { this.getField().(FieldDecl).hasQualifiedName("Sequence", "lazy") } + SequenceFieldsInheritTaint() { this.getField().hasQualifiedName("Sequence", "lazy") } } diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll index 51424e2d042..4768521322f 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll @@ -125,7 +125,6 @@ private class StringFieldsInheritTaint extends TaintInheritingContent, { StringFieldsInheritTaint() { this.getField() - .(FieldDecl) .hasQualifiedName(["String", "StringProtocol"], [ "unicodeScalars", "utf8", "utf16", "lazy", "utf8CString", "description", From 8ac1d56a7f880ad5348b93765db0e83a0a17a7be Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 2 Jun 2023 16:37:35 +0200 Subject: [PATCH 311/739] C++: Fix join order in `cpp/invalid-pointer-deref` --- .../Security/CWE/CWE-193/InvalidPointerDeref.ql | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index dbbe398ff7d..88d483dbebc 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -182,6 +182,8 @@ predicate isSinkImpl( /** * Yields any instruction that is control-flow reachable from `instr`. */ +bindingset[instr, result] +pragma[inline_late] Instruction getASuccessor(Instruction instr) { exists(IRBlock b, int instrIndex, int resultIndex | result.getBlock() = b and @@ -202,11 +204,12 @@ Instruction getASuccessor(Instruction instr) { */ pragma[inline] predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string operation, int delta) { - exists(AddressOperand addr | - bounded1(addr.getDef(), sink.asInstruction(), delta) and + exists(AddressOperand addr, Instruction s | + s = sink.asInstruction() and + bounded1(addr.getDef(), s, delta) and delta >= 0 and i.getAnOperand() = addr and - i = getASuccessor(sink.asInstruction()) + i = getASuccessor(s) | i instanceof StoreInstruction and operation = "write" From 5608082f356c8a027f66b12e02983801898d122f Mon Sep 17 00:00:00 2001 From: jorgectf <jorgectf@github.com> Date: Fri, 2 Jun 2023 17:57:24 +0200 Subject: [PATCH 312/739] Update `py/unsafe-deserialization` name --- python/ql/src/Security/CWE-502/UnsafeDeserialization.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql b/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql index 0ef54275827..a15838cdabd 100644 --- a/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql +++ b/python/ql/src/Security/CWE-502/UnsafeDeserialization.ql @@ -1,5 +1,5 @@ /** - * @name Deserializing untrusted input + * @name Deserialization of user-controlled data * @description Deserializing user-controlled data may allow attackers to execute arbitrary code. * @kind path-problem * @id py/unsafe-deserialization From 3e8c7f72b668188981f1f469788109b458d6d26b Mon Sep 17 00:00:00 2001 From: jorgectf <jorgectf@github.com> Date: Fri, 2 Jun 2023 18:20:55 +0200 Subject: [PATCH 313/739] Add changenote --- .../2023-06-02-unsafe-deserialization-name-update.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/src/change-notes/2023-06-02-unsafe-deserialization-name-update.md diff --git a/python/ql/src/change-notes/2023-06-02-unsafe-deserialization-name-update.md b/python/ql/src/change-notes/2023-06-02-unsafe-deserialization-name-update.md new file mode 100644 index 00000000000..d786e9dc14d --- /dev/null +++ b/python/ql/src/change-notes/2023-06-02-unsafe-deserialization-name-update.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* The display name (`@name`) of the `py/unsafe-deserialization` query has been updated in favor of consistency with other languages. \ No newline at end of file From 79b3a8c955fc1a70b482af756ffee1d723be5b62 Mon Sep 17 00:00:00 2001 From: Nick Rolfe <nickrolfe@github.com> Date: Fri, 2 Jun 2023 19:39:24 +0100 Subject: [PATCH 314/739] C#: avoid call to Location::toString() --- csharp/ql/src/Complexity/ComplexCondition.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/src/Complexity/ComplexCondition.ql b/csharp/ql/src/Complexity/ComplexCondition.ql index 2ebbaa8a362..2813db1cda5 100644 --- a/csharp/ql/src/Complexity/ComplexCondition.ql +++ b/csharp/ql/src/Complexity/ComplexCondition.ql @@ -26,4 +26,4 @@ where operators = count(BinaryLogicalOperation op | logicalParent*(op, e) and nontrivialLogicalOperator(op)) and operators > 3 -select e.getLocation(), "Complex condition: too many logical operations in this expression." +select e, "Complex condition: too many logical operations in this expression." From 5d89b0739b8cfc41120727eb4265e7fda3660ccf Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" <mbg@github.com> Date: Mon, 5 Jun 2023 09:12:21 +0100 Subject: [PATCH 315/739] Swift: Remove .cmd script --- swift/tools/identify-environment.cmd | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 swift/tools/identify-environment.cmd diff --git a/swift/tools/identify-environment.cmd b/swift/tools/identify-environment.cmd deleted file mode 100644 index 7fd1786f31f..00000000000 --- a/swift/tools/identify-environment.cmd +++ /dev/null @@ -1,6 +0,0 @@ -@echo off -SETLOCAL EnableDelayedExpansion - -echo { "swift": { "os": { "name": "macOS" } } } - -ENDLOCAL From 400176f677d90700bef9689db8907271ef92d549 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Mon, 5 Jun 2023 11:12:11 +0200 Subject: [PATCH 316/739] Swift: fix cmake generation The bazel -> cmake generator is currently not capable of handling separate included generated cmake files making use of common C/C++ dependencies. To work around this limitation, a single generated cmake is now in place. Long-term, we should either: * make the cmake generator handle common dependencies gracefully, or * make the cmake generation aspect travel up `pkg_` rules `srcs` attributes so to avoid having to list the targets to be generated in the top-level `BUILD` file. Other things fixed: * removed some warning spam about redefined `BAZEL_CURRENT_REPOSITORY` * fixed the final link step, that was failing because `libswiftCore.so` was not being linked. --- misc/bazel/cmake/cmake.bzl | 35 +++++++------------ swift/BUILD.bazel | 13 +++++++ swift/CMakeLists.txt | 5 +-- swift/extractor/BUILD.bazel | 7 +--- .../tests/assertion-diagnostics/BUILD.bazel | 13 +++---- .../tools/autobuilder-diagnostics/BUILD.bazel | 7 ---- swift/xcode-autobuilder/BUILD.bazel | 11 ++---- 7 files changed, 34 insertions(+), 57 deletions(-) diff --git a/misc/bazel/cmake/cmake.bzl b/misc/bazel/cmake/cmake.bzl index d3c6581677b..85760de476c 100644 --- a/misc/bazel/cmake/cmake.bzl +++ b/misc/bazel/cmake/cmake.bzl @@ -11,8 +11,7 @@ CmakeInfo = provider( "includes": "", "quote_includes": "", "stripped_includes": "", - "imported_static_libs": "", - "imported_dynamic_libs": "", + "imported_libs": "", "copts": "", "linkopts": "", "force_cxx_compilation": "", @@ -41,10 +40,8 @@ def _file_kind(file): return "src" if ext in ("h", "hh", "hpp", "def", "inc"): return "hdr" - if ext == "a": - return "static_lib" - if ext in ("so", "dylib"): - return "dynamic_lib" + if ext in ("a", "so", "dylib"): + return "lib" return None def _get_includes(includes): @@ -70,8 +67,7 @@ def _cmake_aspect_impl(target, ctx): by_kind.setdefault(_file_kind(f), []).append(_cmake_file(f)) hdrs = by_kind.get("hdr", []) srcs = by_kind.get("src", []) - static_libs = by_kind.get("static_lib", []) - dynamic_libs = by_kind.get("dynamic_lib", []) + libs = by_kind.get("lib", []) if not srcs and is_binary: empty = ctx.actions.declare_file(name + "_empty.cpp") ctx.actions.write(empty, "") @@ -134,12 +130,15 @@ def _cmake_aspect_impl(target, ctx): system_includes = system_includes, quote_includes = quote_includes, stripped_includes = stripped_includes, - imported_static_libs = static_libs, - imported_dynamic_libs = dynamic_libs, + imported_libs = libs, copts = copts, linkopts = linkopts, defines = compilation_ctx.defines.to_list(), - local_defines = compilation_ctx.local_defines.to_list(), + local_defines = [ + d + for d in compilation_ctx.local_defines.to_list() + if not d.startswith("BAZEL_CURRENT_REPOSITORY") + ], force_cxx_compilation = force_cxx_compilation, transitive_deps = depset(deps, transitive = [dep.transitive_deps for dep in deps]), ), @@ -156,20 +155,10 @@ def _map_cmake_info(info, is_windows): commands = [ "add_%s(%s)" % (info.kind, args), ] - if info.imported_static_libs and info.imported_dynamic_libs: - commands += [ - "if(BUILD_SHARED_LIBS)", - " target_link_libraries(%s %s %s)" % - (info.name, info.modifier or "PUBLIC", " ".join(info.imported_dynamic_libs)), - "else()", - " target_link_libraries(%s %s %s)" % - (info.name, info.modifier or "PUBLIC", " ".join(info.imported_static_libs)), - "endif()", - ] - elif info.imported_static_libs or info.imported_dynamic_libs: + if info.imported_libs: commands += [ "target_link_libraries(%s %s %s)" % - (info.name, info.modifier or "PUBLIC", " ".join(info.imported_dynamic_lib + info.imported_static_libs)), + (info.name, info.modifier or "PUBLIC", " ".join(info.imported_libs)), ] if info.deps: libs = {} diff --git a/swift/BUILD.bazel b/swift/BUILD.bazel index c4e41bb0817..59cafbba609 100644 --- a/swift/BUILD.bazel +++ b/swift/BUILD.bazel @@ -2,6 +2,7 @@ load("@rules_pkg//:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files" load("@rules_pkg//:install.bzl", "pkg_install") load("//:defs.bzl", "codeql_platform") load("//misc/bazel:pkg_runfiles.bzl", "pkg_runfiles") +load("//misc/bazel/cmake:cmake.bzl", "generate_cmake") filegroup( name = "schema", @@ -106,3 +107,15 @@ py_binary( main = "create_extractor_pack.py", deps = [":_create_extractor_pack"], ) + +generate_cmake( + name = "cmake", + targets = [ + "//swift/extractor:extractor.real", + "//swift/logging/tests/assertion-diagnostics:assert-false", + ] + select({ + "@platforms//os:linux": ["//swift/tools/autobuilder-diagnostics:incompatible-os"], + "@platforms//os:macos": ["//swift/xcode-autobuilder"], + }), + visibility = ["//visibility:public"], +) diff --git a/swift/CMakeLists.txt b/swift/CMakeLists.txt index fbc55187567..ba4a30d5c4a 100644 --- a/swift/CMakeLists.txt +++ b/swift/CMakeLists.txt @@ -17,7 +17,4 @@ project(codeql) include(../misc/bazel/cmake/setup.cmake) -include_generated(//swift/extractor:cmake) -if (APPLE) - include_generated(//swift/xcode-autobuilder:cmake) -endif () +include_generated(//swift:cmake) diff --git a/swift/extractor/BUILD.bazel b/swift/extractor/BUILD.bazel index 26077dadbd8..984c205d97b 100644 --- a/swift/extractor/BUILD.bazel +++ b/swift/extractor/BUILD.bazel @@ -8,6 +8,7 @@ swift_cc_binary( "*.h", "*.cpp", ]), + visibility = ["//swift:__pkg__"], deps = [ "//swift/extractor/config", "//swift/extractor/infra", @@ -19,12 +20,6 @@ swift_cc_binary( ], ) -generate_cmake( - name = "cmake", - targets = [":extractor.real"], - visibility = ["//visibility:public"], -) - sh_binary( name = "extractor", srcs = ["extractor.sh"], diff --git a/swift/logging/tests/assertion-diagnostics/BUILD.bazel b/swift/logging/tests/assertion-diagnostics/BUILD.bazel index 52c3125a567..e51459e1e17 100644 --- a/swift/logging/tests/assertion-diagnostics/BUILD.bazel +++ b/swift/logging/tests/assertion-diagnostics/BUILD.bazel @@ -4,7 +4,7 @@ load("//misc/bazel/cmake:cmake.bzl", "generate_cmake") swift_cc_binary( name = "assert-false", srcs = ["AssertFalse.cpp"], - visibility = ["//visibility:private"], + visibility = ["//swift:__pkg__"], deps = [ "//swift/logging", ], @@ -14,12 +14,9 @@ py_test( name = "test", size = "small", srcs = ["test.py"], + data = [ + "diagnostics.expected", + ":assert-false", + ], deps = ["//swift/integration-tests:integration_tests"], - data = [":assert-false", "diagnostics.expected"], -) - -generate_cmake( - name = "cmake", - targets = [":assert-false"], - visibility = ["//visibility:public"], ) diff --git a/swift/tools/autobuilder-diagnostics/BUILD.bazel b/swift/tools/autobuilder-diagnostics/BUILD.bazel index 77d90121155..32d6ce703e9 100644 --- a/swift/tools/autobuilder-diagnostics/BUILD.bazel +++ b/swift/tools/autobuilder-diagnostics/BUILD.bazel @@ -1,5 +1,4 @@ load("//swift:rules.bzl", "swift_cc_binary") -load("//misc/bazel/cmake:cmake.bzl", "generate_cmake") swift_cc_binary( name = "incompatible-os", @@ -9,9 +8,3 @@ swift_cc_binary( "//swift/logging", ], ) - -generate_cmake( - name = "cmake", - targets = [":incompatible-os"], - visibility = ["//visibility:public"], -) diff --git a/swift/xcode-autobuilder/BUILD.bazel b/swift/xcode-autobuilder/BUILD.bazel index d497666f3e2..13d6e9818ff 100644 --- a/swift/xcode-autobuilder/BUILD.bazel +++ b/swift/xcode-autobuilder/BUILD.bazel @@ -1,5 +1,4 @@ load("//swift:rules.bzl", "swift_cc_binary") -load("//misc/bazel/cmake:cmake.bzl", "generate_cmake") swift_cc_binary( name = "xcode-autobuilder", @@ -7,20 +6,14 @@ swift_cc_binary( "*.cpp", "*.h", ]), - visibility = ["//swift:__subpackages__"], linkopts = [ "-lxml2", "-framework CoreFoundation", ], target_compatible_with = ["@platforms//os:macos"], + visibility = ["//swift:__subpackages__"], deps = [ - "@absl//absl/strings", "//swift/logging", + "@absl//absl/strings", ], ) - -generate_cmake( - name = "cmake", - targets = [":xcode-autobuilder"], - visibility = ["//visibility:public"], -) From dadb5b34e69fadd5d9bcef12656f382a4f5db38d Mon Sep 17 00:00:00 2001 From: Nick Rolfe <nickrolfe@github.com> Date: Mon, 5 Jun 2023 10:19:27 +0100 Subject: [PATCH 317/739] C#: avoid call to Location::toString() in cs/expose-implementation --- .../Implementation Hiding/ExposeRepresentation.ql | 2 +- .../ExposeRepresentation/ExposeRepresentation.expected | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/ql/src/Bad Practices/Implementation Hiding/ExposeRepresentation.ql b/csharp/ql/src/Bad Practices/Implementation Hiding/ExposeRepresentation.ql index e9f9b6cb8c6..3aec796daf7 100644 --- a/csharp/ql/src/Bad Practices/Implementation Hiding/ExposeRepresentation.ql +++ b/csharp/ql/src/Bad Practices/Implementation Hiding/ExposeRepresentation.ql @@ -78,4 +78,4 @@ where exposesByStore(c, f, why, whyText) select c, "'" + c.getName() + "' exposes the internal representation stored in field '" + f.getName() + - "'. The value may be modified $@.", why.getLocation(), whyText + "'. The value may be modified $@.", why, whyText diff --git a/csharp/ql/test/query-tests/Bad Practices/Implementation Hiding/ExposeRepresentation/ExposeRepresentation.expected b/csharp/ql/test/query-tests/Bad Practices/Implementation Hiding/ExposeRepresentation/ExposeRepresentation.expected index 92f7365adeb..f4b2fcbf837 100644 --- a/csharp/ql/test/query-tests/Bad Practices/Implementation Hiding/ExposeRepresentation/ExposeRepresentation.expected +++ b/csharp/ql/test/query-tests/Bad Practices/Implementation Hiding/ExposeRepresentation/ExposeRepresentation.expected @@ -1,2 +1,2 @@ -| ExposeRepresentation.cs:8:21:8:23 | Set | 'Set' exposes the internal representation stored in field 'rarray'. The value may be modified $@. | ExposeRepresentation.cs:16:9:16:9 | ExposeRepresentation.cs:16:9:16:9 | through the variable a | -| ExposeRepresentationBad.cs:18:22:18:24 | Get | 'Get' exposes the internal representation stored in field 'rarray'. The value may be modified $@. | ExposeRepresentationBad.cs:24:23:24:29 | ExposeRepresentationBad.cs:24:23:24:29 | after this call to Get | +| ExposeRepresentation.cs:8:21:8:23 | Set | 'Set' exposes the internal representation stored in field 'rarray'. The value may be modified $@. | ExposeRepresentation.cs:16:9:16:9 | access to local variable a | through the variable a | +| ExposeRepresentationBad.cs:18:22:18:24 | Get | 'Get' exposes the internal representation stored in field 'rarray'. The value may be modified $@. | ExposeRepresentationBad.cs:24:23:24:29 | call to method Get | after this call to Get | From be9d32a6c1bbcbfb13d3fb604a1e81bbaff385b7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Mon, 5 Jun 2023 11:43:48 +0200 Subject: [PATCH 318/739] Bazel/CMake: make include not use cmake include ...but rather just pass along targets. This is required to fix CMake generation in the internal repository. --- misc/bazel/cmake/cmake.bzl | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/misc/bazel/cmake/cmake.bzl b/misc/bazel/cmake/cmake.bzl index 85760de476c..653725e5641 100644 --- a/misc/bazel/cmake/cmake.bzl +++ b/misc/bazel/cmake/cmake.bzl @@ -212,7 +212,7 @@ def _map_cmake_info(info, is_windows): GeneratedCmakeFiles = provider( fields = { - "files": "", + "targets": "", }, ) @@ -221,7 +221,11 @@ def _generate_cmake_impl(ctx): inputs = [] infos = {} - for dep in ctx.attr.targets: + targets = list(ctx.attr.targets) + for include in ctx.attr.includes: + targets += include[GeneratedCmakeFiles].targets.to_list() + + for dep in targets: for info in [dep[CmakeInfo]] + dep[CmakeInfo].transitive_deps.to_list(): if info.name != None: inputs += info.inputs @@ -233,11 +237,6 @@ def _generate_cmake_impl(ctx): commands += _map_cmake_info(info, is_windows) commands.append("") - for include in ctx.attr.includes: - for file in include[GeneratedCmakeFiles].files.to_list(): - inputs.append(file) - commands.append("include(${BAZEL_EXEC_ROOT}/%s)" % file.path) - # we want to use a run or run_shell action to register a bunch of files like inputs, but we cannot write all # in a shell command as we would hit the command size limit. So we first write the file and then copy it with # the dummy inputs @@ -248,7 +247,7 @@ def _generate_cmake_impl(ctx): return [ DefaultInfo(files = depset([output])), - GeneratedCmakeFiles(files = depset([output])), + GeneratedCmakeFiles(targets = depset(ctx.attr.targets)), ] generate_cmake = rule( From c67a350e366671a46b737a30a594fb44515aad7a Mon Sep 17 00:00:00 2001 From: Nick Rolfe <nickrolfe@github.com> Date: Mon, 5 Jun 2023 10:44:22 +0100 Subject: [PATCH 319/739] Python: avoid selecting getLocation() in py/unnecessary-delete --- python/ql/src/Statements/UnnecessaryDelete.ql | 4 ++-- .../query-tests/Statements/general/UnnecessaryDelete.expected | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/src/Statements/UnnecessaryDelete.ql b/python/ql/src/Statements/UnnecessaryDelete.ql index 429e245fea7..808a3f3a0d3 100644 --- a/python/ql/src/Statements/UnnecessaryDelete.ql +++ b/python/ql/src/Statements/UnnecessaryDelete.ql @@ -36,5 +36,5 @@ where ex = Value::named("sys.exc_info") and ex.getACall().getScope() = f ) -select del, "Unnecessary deletion of local variable $@ in function $@.", e.getLocation(), - e.toString(), f.getLocation(), f.getName() +select del, "Unnecessary deletion of local variable $@ in function $@.", e, e.toString(), f, + f.getName() diff --git a/python/ql/test/query-tests/Statements/general/UnnecessaryDelete.expected b/python/ql/test/query-tests/Statements/general/UnnecessaryDelete.expected index d7dda673775..137ee59e4f2 100644 --- a/python/ql/test/query-tests/Statements/general/UnnecessaryDelete.expected +++ b/python/ql/test/query-tests/Statements/general/UnnecessaryDelete.expected @@ -1 +1 @@ -| statements_test.py:187:5:187:9 | Delete | Unnecessary deletion of local variable $@ in function $@. | statements_test.py:187:9:187:9 | statements_test.py:187 | x | statements_test.py:185:1:185:31 | statements_test.py:185 | error_unnecessary_delete | +| statements_test.py:187:5:187:9 | Delete | Unnecessary deletion of local variable $@ in function $@. | statements_test.py:187:9:187:9 | x | x | statements_test.py:185:1:185:31 | Function error_unnecessary_delete | error_unnecessary_delete | From 11182e4ee4d0313efb99c84050c0ba82319c3f40 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 5 Jun 2023 12:36:25 +0200 Subject: [PATCH 320/739] C++: Move location where `getASuccessor` is used to avoid join order problems --- .../Security/CWE/CWE-193/InvalidPointerDeref.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 88d483dbebc..4e5e06775bb 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -208,8 +208,7 @@ predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string o s = sink.asInstruction() and bounded1(addr.getDef(), s, delta) and delta >= 0 and - i.getAnOperand() = addr and - i = getASuccessor(s) + i.getAnOperand() = addr | i instanceof StoreInstruction and operation = "write" @@ -267,7 +266,8 @@ newtype TMergedPathNode = TPathNodeSink(Instruction i) { exists(DataFlow::Node n | InvalidPointerToDerefFlow::flowTo(n) and - isInvalidPointerDerefSink(n, i, _, _) + isInvalidPointerDerefSink(n, i, _, _) and + i = getASuccessor(n.asInstruction()) ) } From 02395867c8ce76f80905e71a38bdf2f0db45ccd0 Mon Sep 17 00:00:00 2001 From: Nick Rolfe <nickrolfe@github.com> Date: Mon, 5 Jun 2023 11:14:43 +0100 Subject: [PATCH 321/739] Python: avoid selecting getLocation() in py/truncated-division --- python/ql/src/Expressions/TruncatedDivision.ql | 2 +- .../test/2/query-tests/Expressions/TruncatedDivision.expected | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/src/Expressions/TruncatedDivision.ql b/python/ql/src/Expressions/TruncatedDivision.ql index 0904081f5ff..54758b4b78e 100644 --- a/python/ql/src/Expressions/TruncatedDivision.ql +++ b/python/ql/src/Expressions/TruncatedDivision.ql @@ -34,4 +34,4 @@ where ) ) select div, "Result of division may be truncated as its $@ and $@ arguments may both be integers.", - left.getLocation(), "left", right.getLocation(), "right" + left, "left", right, "right" diff --git a/python/ql/test/2/query-tests/Expressions/TruncatedDivision.expected b/python/ql/test/2/query-tests/Expressions/TruncatedDivision.expected index b22b9b5a2f2..b6407cdca12 100644 --- a/python/ql/test/2/query-tests/Expressions/TruncatedDivision.expected +++ b/python/ql/test/2/query-tests/Expressions/TruncatedDivision.expected @@ -1,2 +1,2 @@ -| TruncatedDivision_test.py:65:7:65:11 | BinaryExpr | Result of division may be truncated as its $@ and $@ arguments may both be integers. | TruncatedDivision_test.py:65:7:65:7 | TruncatedDivision_test.py:65 | left | TruncatedDivision_test.py:65:11:65:11 | TruncatedDivision_test.py:65 | right | -| TruncatedDivision_test.py:72:7:72:35 | BinaryExpr | Result of division may be truncated as its $@ and $@ arguments may both be integers. | TruncatedDivision_test.py:25:12:25:12 | TruncatedDivision_test.py:25 | left | TruncatedDivision_test.py:28:12:28:12 | TruncatedDivision_test.py:28 | right | +| TruncatedDivision_test.py:65:7:65:11 | BinaryExpr | Result of division may be truncated as its $@ and $@ arguments may both be integers. | TruncatedDivision_test.py:65:7:65:7 | ControlFlowNode for IntegerLiteral | left | TruncatedDivision_test.py:65:11:65:11 | ControlFlowNode for IntegerLiteral | right | +| TruncatedDivision_test.py:72:7:72:35 | BinaryExpr | Result of division may be truncated as its $@ and $@ arguments may both be integers. | TruncatedDivision_test.py:25:12:25:12 | ControlFlowNode for IntegerLiteral | left | TruncatedDivision_test.py:28:12:28:12 | ControlFlowNode for IntegerLiteral | right | From a4a7ad8f99f23c3a5be4602030e6d6acea27eb75 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Mon, 5 Jun 2023 13:20:14 +0100 Subject: [PATCH 322/739] Java/Kotlin: Split lines of code by language We were giving the sum of all lines for both languages, but labelling it as "Total lines of Java code in the database", which was confusing. Now we give separate sums for Kotlin and Java lines. --- java/ql/src/Metrics/Summaries/LinesOfCode.ql | 6 +++--- .../src/Metrics/Summaries/LinesOfCodeKotlin.ql | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 java/ql/src/Metrics/Summaries/LinesOfCodeKotlin.ql diff --git a/java/ql/src/Metrics/Summaries/LinesOfCode.ql b/java/ql/src/Metrics/Summaries/LinesOfCode.ql index c1b43c2a3d9..62c19d1b932 100644 --- a/java/ql/src/Metrics/Summaries/LinesOfCode.ql +++ b/java/ql/src/Metrics/Summaries/LinesOfCode.ql @@ -1,8 +1,8 @@ /** * @id java/summary/lines-of-code * @name Total lines of Java code in the database - * @description The total number of lines of code across all files. This is a useful metric of the size of a database. - * For all files that were seen during the build, this query counts the lines of code, excluding whitespace + * @description The total number of lines of code across all Java files. This is a useful metric of the size of a database. + * For all Java files that were seen during the build, this query counts the lines of code, excluding whitespace * or comments. * @kind metric * @tags summary @@ -11,4 +11,4 @@ import java -select sum(CompilationUnit f | f.fromSource() | f.getNumberOfLinesOfCode()) +select sum(CompilationUnit f | f.fromSource() and f.isJavaSourceFile() | f.getNumberOfLinesOfCode()) diff --git a/java/ql/src/Metrics/Summaries/LinesOfCodeKotlin.ql b/java/ql/src/Metrics/Summaries/LinesOfCodeKotlin.ql new file mode 100644 index 00000000000..0093bc0a98f --- /dev/null +++ b/java/ql/src/Metrics/Summaries/LinesOfCodeKotlin.ql @@ -0,0 +1,18 @@ +/** + * @id java/summary/lines-of-code-kotlin + * @name Total lines of Kotlin code in the database + * @description The total number of lines of code across all Kotlin files. This is a useful metric of the size of a database. + * For all Kotlin files that were seen during the build, this query counts the lines of code, excluding whitespace + * or comments. + * @kind metric + * @tags summary + * lines-of-code + */ + +import java + +select sum(CompilationUnit f | + f.fromSource() and f.isKotlinSourceFile() + | + f.getNumberOfLinesOfCode() + ) From 7f7b048f50d2a22dd22e3b3a163b5b97fc842805 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 5 Jun 2023 15:00:11 +0200 Subject: [PATCH 323/739] C++: Update expected test results --- .../InvalidPointerDeref.expected | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 418251cf6db..7cb0738c580 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -9,7 +9,15 @@ edges | test.cpp:5:15:5:15 | p | test.cpp:7:16:7:16 | q | | test.cpp:5:15:5:15 | p | test.cpp:7:16:7:16 | q | | test.cpp:5:15:5:15 | p | test.cpp:8:16:8:16 | q | +| test.cpp:5:15:5:15 | p | test.cpp:8:16:8:16 | q | | test.cpp:5:15:5:15 | p | test.cpp:8:16:8:20 | ... + ... | +| test.cpp:5:15:5:15 | p | test.cpp:9:16:9:16 | q | +| test.cpp:5:15:5:15 | p | test.cpp:9:16:9:16 | q | +| test.cpp:5:15:5:15 | p | test.cpp:10:16:10:16 | q | +| test.cpp:5:15:5:15 | p | test.cpp:10:16:10:16 | q | +| test.cpp:5:15:5:15 | p | test.cpp:11:16:11:16 | q | +| test.cpp:5:15:5:15 | p | test.cpp:11:16:11:16 | q | +| test.cpp:5:15:5:15 | p | test.cpp:12:16:12:16 | q | | test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | ... + ... | | test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | ... + ... | | test.cpp:5:15:5:22 | ... + ... | test.cpp:6:14:6:15 | Load: * ... | @@ -30,6 +38,22 @@ edges | test.cpp:5:15:5:22 | ... + ... | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:5:15:5:22 | ... + ... | test.cpp:8:16:8:16 | q | | test.cpp:5:15:5:22 | ... + ... | test.cpp:8:16:8:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:8:16:8:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:8:16:8:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:9:16:9:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:9:16:9:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:9:16:9:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:9:16:9:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:10:16:10:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:10:16:10:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:10:16:10:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:10:16:10:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:11:16:11:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:11:16:11:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:11:16:11:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:11:16:11:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:12:16:12:16 | q | +| test.cpp:5:15:5:22 | ... + ... | test.cpp:12:16:12:16 | q | | test.cpp:6:15:6:15 | q | test.cpp:6:14:6:15 | Load: * ... | | test.cpp:6:15:6:15 | q | test.cpp:6:14:6:15 | Load: * ... | | test.cpp:6:15:6:15 | q | test.cpp:7:16:7:16 | q | @@ -37,11 +61,62 @@ edges | test.cpp:6:15:6:15 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:6:15:6:15 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:6:15:6:15 | q | test.cpp:8:16:8:16 | q | +| test.cpp:6:15:6:15 | q | test.cpp:8:16:8:16 | q | +| test.cpp:6:15:6:15 | q | test.cpp:9:16:9:16 | q | +| test.cpp:6:15:6:15 | q | test.cpp:9:16:9:16 | q | +| test.cpp:6:15:6:15 | q | test.cpp:10:16:10:16 | q | +| test.cpp:6:15:6:15 | q | test.cpp:10:16:10:16 | q | +| test.cpp:6:15:6:15 | q | test.cpp:11:16:11:16 | q | +| test.cpp:6:15:6:15 | q | test.cpp:11:16:11:16 | q | +| test.cpp:6:15:6:15 | q | test.cpp:12:16:12:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:7:16:7:16 | q | test.cpp:6:14:6:15 | Load: * ... | | test.cpp:7:16:7:16 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:7:16:7:16 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:7:16:7:16 | q | test.cpp:8:16:8:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:8:16:8:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:9:16:9:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:9:16:9:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:10:16:10:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:10:16:10:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:11:16:11:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:11:16:11:16 | q | +| test.cpp:7:16:7:16 | q | test.cpp:12:16:12:16 | q | +| test.cpp:8:16:8:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:8:16:8:16 | q | test.cpp:6:14:6:15 | Load: * ... | | test.cpp:8:16:8:16 | q | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:8:16:8:16 | q | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:8:16:8:16 | q | test.cpp:9:16:9:16 | q | +| test.cpp:8:16:8:16 | q | test.cpp:9:16:9:16 | q | +| test.cpp:8:16:8:16 | q | test.cpp:10:16:10:16 | q | +| test.cpp:8:16:8:16 | q | test.cpp:10:16:10:16 | q | +| test.cpp:8:16:8:16 | q | test.cpp:11:16:11:16 | q | +| test.cpp:8:16:8:16 | q | test.cpp:11:16:11:16 | q | +| test.cpp:8:16:8:16 | q | test.cpp:12:16:12:16 | q | | test.cpp:8:16:8:20 | ... + ... | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:9:16:9:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:9:16:9:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:9:16:9:16 | q | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:9:16:9:16 | q | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:9:16:9:16 | q | test.cpp:10:16:10:16 | q | +| test.cpp:9:16:9:16 | q | test.cpp:10:16:10:16 | q | +| test.cpp:9:16:9:16 | q | test.cpp:11:16:11:16 | q | +| test.cpp:9:16:9:16 | q | test.cpp:11:16:11:16 | q | +| test.cpp:9:16:9:16 | q | test.cpp:12:16:12:16 | q | +| test.cpp:10:16:10:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:10:16:10:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:10:16:10:16 | q | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:10:16:10:16 | q | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:10:16:10:16 | q | test.cpp:11:16:11:16 | q | +| test.cpp:10:16:10:16 | q | test.cpp:11:16:11:16 | q | +| test.cpp:10:16:10:16 | q | test.cpp:12:16:12:16 | q | +| test.cpp:11:16:11:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:11:16:11:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:11:16:11:16 | q | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:11:16:11:16 | q | test.cpp:8:14:8:21 | Load: * ... | +| test.cpp:11:16:11:16 | q | test.cpp:12:16:12:16 | q | +| test.cpp:12:16:12:16 | q | test.cpp:6:14:6:15 | Load: * ... | +| test.cpp:12:16:12:16 | q | test.cpp:8:14:8:21 | Load: * ... | | test.cpp:16:15:16:20 | call to malloc | test.cpp:17:15:17:15 | p | | test.cpp:17:15:17:15 | p | test.cpp:17:15:17:22 | ... + ... | | test.cpp:17:15:17:15 | p | test.cpp:20:16:20:20 | ... + ... | @@ -57,7 +132,15 @@ edges | test.cpp:29:15:29:15 | p | test.cpp:31:16:31:16 | q | | test.cpp:29:15:29:15 | p | test.cpp:31:16:31:16 | q | | test.cpp:29:15:29:15 | p | test.cpp:32:16:32:16 | q | +| test.cpp:29:15:29:15 | p | test.cpp:32:16:32:16 | q | | test.cpp:29:15:29:15 | p | test.cpp:32:16:32:20 | ... + ... | +| test.cpp:29:15:29:15 | p | test.cpp:33:16:33:16 | q | +| test.cpp:29:15:29:15 | p | test.cpp:33:16:33:16 | q | +| test.cpp:29:15:29:15 | p | test.cpp:34:16:34:16 | q | +| test.cpp:29:15:29:15 | p | test.cpp:34:16:34:16 | q | +| test.cpp:29:15:29:15 | p | test.cpp:35:16:35:16 | q | +| test.cpp:29:15:29:15 | p | test.cpp:35:16:35:16 | q | +| test.cpp:29:15:29:15 | p | test.cpp:36:16:36:16 | q | | test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | ... + ... | | test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | ... + ... | | test.cpp:29:15:29:28 | ... + ... | test.cpp:30:14:30:15 | Load: * ... | @@ -78,6 +161,22 @@ edges | test.cpp:29:15:29:28 | ... + ... | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:29:15:29:28 | ... + ... | test.cpp:32:16:32:16 | q | | test.cpp:29:15:29:28 | ... + ... | test.cpp:32:16:32:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:32:16:32:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:32:16:32:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:33:16:33:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:33:16:33:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:33:16:33:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:33:16:33:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:34:16:34:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:34:16:34:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:34:16:34:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:34:16:34:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:35:16:35:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:35:16:35:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:35:16:35:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:35:16:35:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:36:16:36:16 | q | +| test.cpp:29:15:29:28 | ... + ... | test.cpp:36:16:36:16 | q | | test.cpp:30:15:30:15 | q | test.cpp:30:14:30:15 | Load: * ... | | test.cpp:30:15:30:15 | q | test.cpp:30:14:30:15 | Load: * ... | | test.cpp:30:15:30:15 | q | test.cpp:31:16:31:16 | q | @@ -85,11 +184,62 @@ edges | test.cpp:30:15:30:15 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:30:15:30:15 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:30:15:30:15 | q | test.cpp:32:16:32:16 | q | +| test.cpp:30:15:30:15 | q | test.cpp:32:16:32:16 | q | +| test.cpp:30:15:30:15 | q | test.cpp:33:16:33:16 | q | +| test.cpp:30:15:30:15 | q | test.cpp:33:16:33:16 | q | +| test.cpp:30:15:30:15 | q | test.cpp:34:16:34:16 | q | +| test.cpp:30:15:30:15 | q | test.cpp:34:16:34:16 | q | +| test.cpp:30:15:30:15 | q | test.cpp:35:16:35:16 | q | +| test.cpp:30:15:30:15 | q | test.cpp:35:16:35:16 | q | +| test.cpp:30:15:30:15 | q | test.cpp:36:16:36:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:31:16:31:16 | q | test.cpp:30:14:30:15 | Load: * ... | | test.cpp:31:16:31:16 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:31:16:31:16 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:31:16:31:16 | q | test.cpp:32:16:32:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:32:16:32:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:33:16:33:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:33:16:33:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:34:16:34:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:34:16:34:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:35:16:35:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:35:16:35:16 | q | +| test.cpp:31:16:31:16 | q | test.cpp:36:16:36:16 | q | +| test.cpp:32:16:32:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:32:16:32:16 | q | test.cpp:30:14:30:15 | Load: * ... | | test.cpp:32:16:32:16 | q | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:32:16:32:16 | q | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:32:16:32:16 | q | test.cpp:33:16:33:16 | q | +| test.cpp:32:16:32:16 | q | test.cpp:33:16:33:16 | q | +| test.cpp:32:16:32:16 | q | test.cpp:34:16:34:16 | q | +| test.cpp:32:16:32:16 | q | test.cpp:34:16:34:16 | q | +| test.cpp:32:16:32:16 | q | test.cpp:35:16:35:16 | q | +| test.cpp:32:16:32:16 | q | test.cpp:35:16:35:16 | q | +| test.cpp:32:16:32:16 | q | test.cpp:36:16:36:16 | q | | test.cpp:32:16:32:20 | ... + ... | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:33:16:33:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:33:16:33:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:33:16:33:16 | q | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:33:16:33:16 | q | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:33:16:33:16 | q | test.cpp:34:16:34:16 | q | +| test.cpp:33:16:33:16 | q | test.cpp:34:16:34:16 | q | +| test.cpp:33:16:33:16 | q | test.cpp:35:16:35:16 | q | +| test.cpp:33:16:33:16 | q | test.cpp:35:16:35:16 | q | +| test.cpp:33:16:33:16 | q | test.cpp:36:16:36:16 | q | +| test.cpp:34:16:34:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:34:16:34:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:34:16:34:16 | q | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:34:16:34:16 | q | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:34:16:34:16 | q | test.cpp:35:16:35:16 | q | +| test.cpp:34:16:34:16 | q | test.cpp:35:16:35:16 | q | +| test.cpp:34:16:34:16 | q | test.cpp:36:16:36:16 | q | +| test.cpp:35:16:35:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:35:16:35:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:35:16:35:16 | q | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:35:16:35:16 | q | test.cpp:32:14:32:21 | Load: * ... | +| test.cpp:35:16:35:16 | q | test.cpp:36:16:36:16 | q | +| test.cpp:36:16:36:16 | q | test.cpp:30:14:30:15 | Load: * ... | +| test.cpp:36:16:36:16 | q | test.cpp:32:14:32:21 | Load: * ... | | test.cpp:40:15:40:20 | call to malloc | test.cpp:41:15:41:15 | p | | test.cpp:41:15:41:15 | p | test.cpp:41:15:41:28 | ... + ... | | test.cpp:41:15:41:15 | p | test.cpp:41:15:41:28 | ... + ... | @@ -100,7 +250,15 @@ edges | test.cpp:41:15:41:15 | p | test.cpp:43:16:43:16 | q | | test.cpp:41:15:41:15 | p | test.cpp:43:16:43:16 | q | | test.cpp:41:15:41:15 | p | test.cpp:44:16:44:16 | q | +| test.cpp:41:15:41:15 | p | test.cpp:44:16:44:16 | q | | test.cpp:41:15:41:15 | p | test.cpp:44:16:44:20 | ... + ... | +| test.cpp:41:15:41:15 | p | test.cpp:45:16:45:16 | q | +| test.cpp:41:15:41:15 | p | test.cpp:45:16:45:16 | q | +| test.cpp:41:15:41:15 | p | test.cpp:46:16:46:16 | q | +| test.cpp:41:15:41:15 | p | test.cpp:46:16:46:16 | q | +| test.cpp:41:15:41:15 | p | test.cpp:47:16:47:16 | q | +| test.cpp:41:15:41:15 | p | test.cpp:47:16:47:16 | q | +| test.cpp:41:15:41:15 | p | test.cpp:48:16:48:16 | q | | test.cpp:41:15:41:28 | ... + ... | test.cpp:41:15:41:28 | ... + ... | | test.cpp:41:15:41:28 | ... + ... | test.cpp:41:15:41:28 | ... + ... | | test.cpp:41:15:41:28 | ... + ... | test.cpp:42:14:42:15 | Load: * ... | @@ -121,6 +279,22 @@ edges | test.cpp:41:15:41:28 | ... + ... | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:41:15:41:28 | ... + ... | test.cpp:44:16:44:16 | q | | test.cpp:41:15:41:28 | ... + ... | test.cpp:44:16:44:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:44:16:44:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:44:16:44:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:45:16:45:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:45:16:45:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:45:16:45:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:45:16:45:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:46:16:46:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:46:16:46:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:46:16:46:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:46:16:46:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:47:16:47:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:47:16:47:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:47:16:47:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:47:16:47:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:48:16:48:16 | q | +| test.cpp:41:15:41:28 | ... + ... | test.cpp:48:16:48:16 | q | | test.cpp:42:15:42:15 | q | test.cpp:42:14:42:15 | Load: * ... | | test.cpp:42:15:42:15 | q | test.cpp:42:14:42:15 | Load: * ... | | test.cpp:42:15:42:15 | q | test.cpp:43:16:43:16 | q | @@ -128,11 +302,62 @@ edges | test.cpp:42:15:42:15 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:42:15:42:15 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:42:15:42:15 | q | test.cpp:44:16:44:16 | q | +| test.cpp:42:15:42:15 | q | test.cpp:44:16:44:16 | q | +| test.cpp:42:15:42:15 | q | test.cpp:45:16:45:16 | q | +| test.cpp:42:15:42:15 | q | test.cpp:45:16:45:16 | q | +| test.cpp:42:15:42:15 | q | test.cpp:46:16:46:16 | q | +| test.cpp:42:15:42:15 | q | test.cpp:46:16:46:16 | q | +| test.cpp:42:15:42:15 | q | test.cpp:47:16:47:16 | q | +| test.cpp:42:15:42:15 | q | test.cpp:47:16:47:16 | q | +| test.cpp:42:15:42:15 | q | test.cpp:48:16:48:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:43:16:43:16 | q | test.cpp:42:14:42:15 | Load: * ... | | test.cpp:43:16:43:16 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:43:16:43:16 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:43:16:43:16 | q | test.cpp:44:16:44:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:44:16:44:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:45:16:45:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:45:16:45:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:46:16:46:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:46:16:46:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:47:16:47:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:47:16:47:16 | q | +| test.cpp:43:16:43:16 | q | test.cpp:48:16:48:16 | q | +| test.cpp:44:16:44:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:44:16:44:16 | q | test.cpp:42:14:42:15 | Load: * ... | | test.cpp:44:16:44:16 | q | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:44:16:44:16 | q | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:44:16:44:16 | q | test.cpp:45:16:45:16 | q | +| test.cpp:44:16:44:16 | q | test.cpp:45:16:45:16 | q | +| test.cpp:44:16:44:16 | q | test.cpp:46:16:46:16 | q | +| test.cpp:44:16:44:16 | q | test.cpp:46:16:46:16 | q | +| test.cpp:44:16:44:16 | q | test.cpp:47:16:47:16 | q | +| test.cpp:44:16:44:16 | q | test.cpp:47:16:47:16 | q | +| test.cpp:44:16:44:16 | q | test.cpp:48:16:48:16 | q | | test.cpp:44:16:44:20 | ... + ... | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:45:16:45:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:45:16:45:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:45:16:45:16 | q | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:45:16:45:16 | q | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:45:16:45:16 | q | test.cpp:46:16:46:16 | q | +| test.cpp:45:16:45:16 | q | test.cpp:46:16:46:16 | q | +| test.cpp:45:16:45:16 | q | test.cpp:47:16:47:16 | q | +| test.cpp:45:16:45:16 | q | test.cpp:47:16:47:16 | q | +| test.cpp:45:16:45:16 | q | test.cpp:48:16:48:16 | q | +| test.cpp:46:16:46:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:46:16:46:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:46:16:46:16 | q | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:46:16:46:16 | q | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:46:16:46:16 | q | test.cpp:47:16:47:16 | q | +| test.cpp:46:16:46:16 | q | test.cpp:47:16:47:16 | q | +| test.cpp:46:16:46:16 | q | test.cpp:48:16:48:16 | q | +| test.cpp:47:16:47:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:47:16:47:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:47:16:47:16 | q | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:47:16:47:16 | q | test.cpp:44:14:44:21 | Load: * ... | +| test.cpp:47:16:47:16 | q | test.cpp:48:16:48:16 | q | +| test.cpp:48:16:48:16 | q | test.cpp:42:14:42:15 | Load: * ... | +| test.cpp:48:16:48:16 | q | test.cpp:44:14:44:21 | Load: * ... | | test.cpp:51:7:51:14 | mk_array indirection | test.cpp:60:19:60:26 | call to mk_array | | test.cpp:51:33:51:35 | end | test.cpp:60:34:60:37 | mk_array output argument | | test.cpp:52:19:52:24 | call to malloc | test.cpp:51:7:51:14 | mk_array indirection | @@ -146,8 +371,10 @@ edges | test.cpp:60:19:60:26 | call to mk_array | test.cpp:70:38:70:38 | p | | test.cpp:60:34:60:37 | mk_array output argument | test.cpp:62:32:62:34 | end | | test.cpp:60:34:60:37 | mk_array output argument | test.cpp:66:32:66:34 | end | +| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:70:31:70:33 | end | | test.cpp:62:32:62:34 | end | test.cpp:67:9:67:14 | Store: ... = ... | | test.cpp:66:32:66:34 | end | test.cpp:67:9:67:14 | Store: ... = ... | +| test.cpp:70:31:70:33 | end | test.cpp:67:9:67:14 | Store: ... = ... | | test.cpp:80:9:80:16 | mk_array indirection [begin] | test.cpp:89:19:89:26 | call to mk_array [begin] | | test.cpp:80:9:80:16 | mk_array indirection [begin] | test.cpp:119:18:119:25 | call to mk_array [begin] | | test.cpp:80:9:80:16 | mk_array indirection [end] | test.cpp:89:19:89:26 | call to mk_array [end] | @@ -168,6 +395,7 @@ edges | test.cpp:89:19:89:26 | call to mk_array [begin] | test.cpp:99:20:99:22 | arr indirection [begin] | | test.cpp:89:19:89:26 | call to mk_array [end] | test.cpp:91:36:91:38 | arr indirection [end] | | test.cpp:89:19:89:26 | call to mk_array [end] | test.cpp:95:36:95:38 | arr indirection [end] | +| test.cpp:89:19:89:26 | call to mk_array [end] | test.cpp:99:35:99:37 | arr indirection [end] | | test.cpp:91:20:91:22 | arr indirection [begin] | test.cpp:91:24:91:28 | begin | | test.cpp:91:20:91:22 | arr indirection [begin] | test.cpp:91:24:91:28 | begin indirection | | test.cpp:91:24:91:28 | begin | test.cpp:91:47:91:47 | p | @@ -188,11 +416,16 @@ edges | test.cpp:99:20:99:22 | arr indirection [begin] | test.cpp:99:24:99:28 | begin indirection | | test.cpp:99:24:99:28 | begin | test.cpp:99:46:99:46 | p | | test.cpp:99:24:99:28 | begin indirection | test.cpp:99:46:99:46 | p | +| test.cpp:99:35:99:37 | arr indirection [end] | test.cpp:99:39:99:41 | end | +| test.cpp:99:35:99:37 | arr indirection [end] | test.cpp:99:39:99:41 | end indirection | +| test.cpp:99:39:99:41 | end | test.cpp:96:9:96:14 | Store: ... = ... | +| test.cpp:99:39:99:41 | end indirection | test.cpp:99:39:99:41 | end | | test.cpp:104:27:104:29 | arr [begin] | test.cpp:105:20:105:22 | arr indirection [begin] | | test.cpp:104:27:104:29 | arr [begin] | test.cpp:109:20:109:22 | arr indirection [begin] | | test.cpp:104:27:104:29 | arr [begin] | test.cpp:113:20:113:22 | arr indirection [begin] | | test.cpp:104:27:104:29 | arr [end] | test.cpp:105:36:105:38 | arr indirection [end] | | test.cpp:104:27:104:29 | arr [end] | test.cpp:109:36:109:38 | arr indirection [end] | +| test.cpp:104:27:104:29 | arr [end] | test.cpp:113:35:113:37 | arr indirection [end] | | test.cpp:105:20:105:22 | arr indirection [begin] | test.cpp:105:24:105:28 | begin | | test.cpp:105:20:105:22 | arr indirection [begin] | test.cpp:105:24:105:28 | begin indirection | | test.cpp:105:24:105:28 | begin | test.cpp:105:47:105:47 | p | @@ -213,6 +446,10 @@ edges | test.cpp:113:20:113:22 | arr indirection [begin] | test.cpp:113:24:113:28 | begin indirection | | test.cpp:113:24:113:28 | begin | test.cpp:113:46:113:46 | p | | test.cpp:113:24:113:28 | begin indirection | test.cpp:113:46:113:46 | p | +| test.cpp:113:35:113:37 | arr indirection [end] | test.cpp:113:39:113:41 | end | +| test.cpp:113:35:113:37 | arr indirection [end] | test.cpp:113:39:113:41 | end indirection | +| test.cpp:113:39:113:41 | end | test.cpp:110:9:110:14 | Store: ... = ... | +| test.cpp:113:39:113:41 | end indirection | test.cpp:113:39:113:41 | end | | test.cpp:119:18:119:25 | call to mk_array [begin] | test.cpp:104:27:104:29 | arr [begin] | | test.cpp:119:18:119:25 | call to mk_array [end] | test.cpp:104:27:104:29 | arr [end] | | test.cpp:124:15:124:20 | call to malloc | test.cpp:125:5:125:17 | ... = ... | @@ -267,6 +504,7 @@ edges | test.cpp:165:29:165:31 | arr indirection [begin] | test.cpp:174:20:174:22 | arr indirection [begin] | | test.cpp:165:29:165:31 | arr indirection [end] | test.cpp:166:37:166:39 | arr indirection [end] | | test.cpp:165:29:165:31 | arr indirection [end] | test.cpp:170:37:170:39 | arr indirection [end] | +| test.cpp:165:29:165:31 | arr indirection [end] | test.cpp:174:36:174:38 | arr indirection [end] | | test.cpp:166:20:166:22 | arr indirection [begin] | test.cpp:166:25:166:29 | begin | | test.cpp:166:20:166:22 | arr indirection [begin] | test.cpp:166:25:166:29 | begin indirection | | test.cpp:166:25:166:29 | begin | test.cpp:166:49:166:49 | p | @@ -287,6 +525,10 @@ edges | test.cpp:174:20:174:22 | arr indirection [begin] | test.cpp:174:25:174:29 | begin indirection | | test.cpp:174:25:174:29 | begin | test.cpp:174:48:174:48 | p | | test.cpp:174:25:174:29 | begin indirection | test.cpp:174:48:174:48 | p | +| test.cpp:174:36:174:38 | arr indirection [end] | test.cpp:174:41:174:43 | end | +| test.cpp:174:36:174:38 | arr indirection [end] | test.cpp:174:41:174:43 | end indirection | +| test.cpp:174:41:174:43 | end | test.cpp:171:9:171:14 | Store: ... = ... | +| test.cpp:174:41:174:43 | end indirection | test.cpp:174:41:174:43 | end | | test.cpp:180:19:180:28 | call to mk_array_p indirection [begin] | test.cpp:165:29:165:31 | arr indirection [begin] | | test.cpp:180:19:180:28 | call to mk_array_p indirection [end] | test.cpp:165:29:165:31 | arr indirection [end] | | test.cpp:188:15:188:20 | call to malloc | test.cpp:189:15:189:15 | p | @@ -413,6 +655,14 @@ edges | test.cpp:308:5:308:11 | access to array | test.cpp:308:5:308:29 | Store: ... = ... | | test.cpp:313:14:313:27 | new[] | test.cpp:314:15:314:16 | xs | | test.cpp:325:14:325:27 | new[] | test.cpp:326:15:326:16 | xs | +| test.cpp:326:15:326:16 | xs | test.cpp:326:15:326:23 | ... + ... | +| test.cpp:326:15:326:16 | xs | test.cpp:326:15:326:23 | ... + ... | +| test.cpp:326:15:326:16 | xs | test.cpp:338:8:338:15 | * ... | +| test.cpp:326:15:326:16 | xs | test.cpp:341:8:341:17 | * ... | +| test.cpp:326:15:326:23 | ... + ... | test.cpp:342:8:342:17 | * ... | +| test.cpp:326:15:326:23 | ... + ... | test.cpp:342:8:342:17 | * ... | +| test.cpp:338:8:338:15 | * ... | test.cpp:342:8:342:17 | * ... | +| test.cpp:341:8:341:17 | * ... | test.cpp:342:8:342:17 | * ... | | test.cpp:347:14:347:27 | new[] | test.cpp:348:15:348:16 | xs | | test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ | | test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ | @@ -468,6 +718,7 @@ edges | test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:358:15:358:26 | end_plus_one | test.cpp:359:16:359:27 | end_plus_one | +| test.cpp:359:16:359:27 | end_plus_one | test.cpp:358:14:358:26 | Load: * ... | | test.cpp:359:16:359:27 | end_plus_one | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:359:16:359:31 | ... + ... | test.cpp:359:14:359:32 | Load: * ... | | test.cpp:363:14:363:27 | new[] | test.cpp:365:15:365:15 | p | @@ -493,7 +744,15 @@ nodes | test.cpp:7:16:7:16 | q | semmle.label | q | | test.cpp:8:14:8:21 | Load: * ... | semmle.label | Load: * ... | | test.cpp:8:16:8:16 | q | semmle.label | q | +| test.cpp:8:16:8:16 | q | semmle.label | q | | test.cpp:8:16:8:20 | ... + ... | semmle.label | ... + ... | +| test.cpp:9:16:9:16 | q | semmle.label | q | +| test.cpp:9:16:9:16 | q | semmle.label | q | +| test.cpp:10:16:10:16 | q | semmle.label | q | +| test.cpp:10:16:10:16 | q | semmle.label | q | +| test.cpp:11:16:11:16 | q | semmle.label | q | +| test.cpp:11:16:11:16 | q | semmle.label | q | +| test.cpp:12:16:12:16 | q | semmle.label | q | | test.cpp:16:15:16:20 | call to malloc | semmle.label | call to malloc | | test.cpp:17:15:17:15 | p | semmle.label | p | | test.cpp:17:15:17:22 | ... + ... | semmle.label | ... + ... | @@ -512,7 +771,15 @@ nodes | test.cpp:31:16:31:16 | q | semmle.label | q | | test.cpp:32:14:32:21 | Load: * ... | semmle.label | Load: * ... | | test.cpp:32:16:32:16 | q | semmle.label | q | +| test.cpp:32:16:32:16 | q | semmle.label | q | | test.cpp:32:16:32:20 | ... + ... | semmle.label | ... + ... | +| test.cpp:33:16:33:16 | q | semmle.label | q | +| test.cpp:33:16:33:16 | q | semmle.label | q | +| test.cpp:34:16:34:16 | q | semmle.label | q | +| test.cpp:34:16:34:16 | q | semmle.label | q | +| test.cpp:35:16:35:16 | q | semmle.label | q | +| test.cpp:35:16:35:16 | q | semmle.label | q | +| test.cpp:36:16:36:16 | q | semmle.label | q | | test.cpp:40:15:40:20 | call to malloc | semmle.label | call to malloc | | test.cpp:41:15:41:15 | p | semmle.label | p | | test.cpp:41:15:41:28 | ... + ... | semmle.label | ... + ... | @@ -526,7 +793,15 @@ nodes | test.cpp:43:16:43:16 | q | semmle.label | q | | test.cpp:44:14:44:21 | Load: * ... | semmle.label | Load: * ... | | test.cpp:44:16:44:16 | q | semmle.label | q | +| test.cpp:44:16:44:16 | q | semmle.label | q | | test.cpp:44:16:44:20 | ... + ... | semmle.label | ... + ... | +| test.cpp:45:16:45:16 | q | semmle.label | q | +| test.cpp:45:16:45:16 | q | semmle.label | q | +| test.cpp:46:16:46:16 | q | semmle.label | q | +| test.cpp:46:16:46:16 | q | semmle.label | q | +| test.cpp:47:16:47:16 | q | semmle.label | q | +| test.cpp:47:16:47:16 | q | semmle.label | q | +| test.cpp:48:16:48:16 | q | semmle.label | q | | test.cpp:51:7:51:14 | mk_array indirection | semmle.label | mk_array indirection | | test.cpp:51:33:51:35 | end | semmle.label | end | | test.cpp:52:19:52:24 | call to malloc | semmle.label | call to malloc | @@ -540,6 +815,7 @@ nodes | test.cpp:66:32:66:34 | end | semmle.label | end | | test.cpp:66:39:66:39 | p | semmle.label | p | | test.cpp:67:9:67:14 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:70:31:70:33 | end | semmle.label | end | | test.cpp:70:38:70:38 | p | semmle.label | p | | test.cpp:80:9:80:16 | mk_array indirection [begin] | semmle.label | mk_array indirection [begin] | | test.cpp:80:9:80:16 | mk_array indirection [end] | semmle.label | mk_array indirection [end] | @@ -572,6 +848,9 @@ nodes | test.cpp:99:20:99:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | | test.cpp:99:24:99:28 | begin | semmle.label | begin | | test.cpp:99:24:99:28 | begin indirection | semmle.label | begin indirection | +| test.cpp:99:35:99:37 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:99:39:99:41 | end | semmle.label | end | +| test.cpp:99:39:99:41 | end indirection | semmle.label | end indirection | | test.cpp:99:46:99:46 | p | semmle.label | p | | test.cpp:104:27:104:29 | arr [begin] | semmle.label | arr [begin] | | test.cpp:104:27:104:29 | arr [end] | semmle.label | arr [end] | @@ -593,6 +872,9 @@ nodes | test.cpp:113:20:113:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | | test.cpp:113:24:113:28 | begin | semmle.label | begin | | test.cpp:113:24:113:28 | begin indirection | semmle.label | begin indirection | +| test.cpp:113:35:113:37 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:113:39:113:41 | end | semmle.label | end | +| test.cpp:113:39:113:41 | end indirection | semmle.label | end indirection | | test.cpp:113:46:113:46 | p | semmle.label | p | | test.cpp:119:18:119:25 | call to mk_array [begin] | semmle.label | call to mk_array [begin] | | test.cpp:119:18:119:25 | call to mk_array [end] | semmle.label | call to mk_array [end] | @@ -658,6 +940,9 @@ nodes | test.cpp:174:20:174:22 | arr indirection [begin] | semmle.label | arr indirection [begin] | | test.cpp:174:25:174:29 | begin | semmle.label | begin | | test.cpp:174:25:174:29 | begin indirection | semmle.label | begin indirection | +| test.cpp:174:36:174:38 | arr indirection [end] | semmle.label | arr indirection [end] | +| test.cpp:174:41:174:43 | end | semmle.label | end | +| test.cpp:174:41:174:43 | end indirection | semmle.label | end indirection | | test.cpp:174:48:174:48 | p | semmle.label | p | | test.cpp:180:19:180:28 | call to mk_array_p indirection [begin] | semmle.label | call to mk_array_p indirection [begin] | | test.cpp:180:19:180:28 | call to mk_array_p indirection [end] | semmle.label | call to mk_array_p indirection [end] | @@ -742,6 +1027,11 @@ nodes | test.cpp:314:15:314:16 | xs | semmle.label | xs | | test.cpp:325:14:325:27 | new[] | semmle.label | new[] | | test.cpp:326:15:326:16 | xs | semmle.label | xs | +| test.cpp:326:15:326:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:326:15:326:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:338:8:338:15 | * ... | semmle.label | * ... | +| test.cpp:341:8:341:17 | * ... | semmle.label | * ... | +| test.cpp:342:8:342:17 | * ... | semmle.label | * ... | | test.cpp:347:14:347:27 | new[] | semmle.label | new[] | | test.cpp:348:15:348:16 | xs | semmle.label | xs | | test.cpp:350:15:350:19 | Load: * ... | semmle.label | Load: * ... | From 90f0209095943c7d1c9b1887a682cab03a8b5d95 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 5 Jun 2023 14:53:01 +0200 Subject: [PATCH 324/739] C++: Add `cpp/invalid-pointer-deref` test case with almost duplicated results --- .../InvalidPointerDeref.expected | 36 +++++++++++++++++++ .../CWE/CWE-193/pointer-deref/test.cpp | 11 ++++++ 2 files changed, 47 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 09c75e7369c..f13d7fbf86a 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -732,6 +732,29 @@ edges | test.cpp:368:5:368:10 | ... += ... | test.cpp:372:16:372:16 | p | | test.cpp:371:7:371:7 | p | test.cpp:372:15:372:16 | Load: * ... | | test.cpp:372:16:372:16 | p | test.cpp:372:15:372:16 | Load: * ... | +| test.cpp:377:14:377:27 | new[] | test.cpp:378:15:378:16 | xs | +| test.cpp:378:15:378:16 | xs | test.cpp:378:15:378:23 | ... + ... | +| test.cpp:378:15:378:16 | xs | test.cpp:378:15:378:23 | ... + ... | +| test.cpp:378:15:378:16 | xs | test.cpp:378:15:378:23 | ... + ... | +| test.cpp:378:15:378:16 | xs | test.cpp:378:15:378:23 | ... + ... | +| test.cpp:378:15:378:16 | xs | test.cpp:381:5:381:7 | end | +| test.cpp:378:15:378:16 | xs | test.cpp:381:5:381:9 | ... ++ | +| test.cpp:378:15:378:16 | xs | test.cpp:381:5:381:9 | ... ++ | +| test.cpp:378:15:378:16 | xs | test.cpp:384:14:384:16 | end | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:378:15:378:23 | ... + ... | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:378:15:378:23 | ... + ... | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:381:5:381:7 | end | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:381:5:381:7 | end | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | Load: * ... | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | Load: * ... | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | Load: * ... | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | Load: * ... | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:14:384:16 | end | +| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:14:384:16 | end | +| test.cpp:381:5:381:7 | end | test.cpp:384:13:384:16 | Load: * ... | +| test.cpp:381:5:381:9 | ... ++ | test.cpp:384:14:384:16 | end | +| test.cpp:381:5:381:9 | ... ++ | test.cpp:384:14:384:16 | end | +| test.cpp:384:14:384:16 | end | test.cpp:384:13:384:16 | Load: * ... | nodes | test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc | | test.cpp:5:15:5:15 | p | semmle.label | p | @@ -1066,6 +1089,17 @@ nodes | test.cpp:371:7:371:7 | p | semmle.label | p | | test.cpp:372:15:372:16 | Load: * ... | semmle.label | Load: * ... | | test.cpp:372:16:372:16 | p | semmle.label | p | +| test.cpp:377:14:377:27 | new[] | semmle.label | new[] | +| test.cpp:378:15:378:16 | xs | semmle.label | xs | +| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... | +| test.cpp:381:5:381:7 | end | semmle.label | end | +| test.cpp:381:5:381:9 | ... ++ | semmle.label | ... ++ | +| test.cpp:381:5:381:9 | ... ++ | semmle.label | ... ++ | +| test.cpp:384:13:384:16 | Load: * ... | semmle.label | Load: * ... | +| test.cpp:384:14:384:16 | end | semmle.label | end | subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | @@ -1094,3 +1128,5 @@ subpaths | test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:372:15:372:16 | Load: * ... | test.cpp:363:14:363:27 | new[] | test.cpp:372:15:372:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:363:14:363:27 | new[] | new[] | test.cpp:365:19:365:22 | size | size | +| test.cpp:384:13:384:16 | Load: * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size | +| test.cpp:384:13:384:16 | Load: * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index 3711f272e76..3465affbc6e 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -372,3 +372,14 @@ void test26(unsigned size) { int val = *p; // GOOD [FALSE POSITIVE] } } + +void test27(unsigned size, bool b) { + char *xs = new char[size]; + char *end = xs + size; + + if (b) { + end++; + } + + int val = *end; // BAD +} From 4a27028768a8639fe2f5f3d57b9cc5513b26faf9 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 5 Jun 2023 14:55:08 +0200 Subject: [PATCH 325/739] C++: Remove `cpp/invalid-pointer-deref` results duplicating ones with smaller `k` --- .../Security/CWE/CWE-193/InvalidPointerDeref.ql | 16 ++++++++++------ .../pointer-deref/InvalidPointerDeref.expected | 1 - 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 610eb572d8c..20f2e934fed 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -377,15 +377,19 @@ predicate hasFlowPath( } from - MergedPathNode source, MergedPathNode sink, int k2, int k3, string kstr, - InvalidPointerToDerefFlow::PathNode source3, PointerArithmeticInstruction pai, string operation, - Expr offset, DataFlow::Node n + MergedPathNode source, MergedPathNode sink, int k, string kstr, PointerArithmeticInstruction pai, + string operation, Expr offset, DataFlow::Node n where - hasFlowPath(source, sink, source3, pai, operation, k3) and - invalidPointerToDerefSource(pai, source3.getNode(), k2) and + k = + min(int k2, int k3, InvalidPointerToDerefFlow::PathNode source3 | + hasFlowPath(source, sink, source3, pai, operation, k3) and + invalidPointerToDerefSource(pai, source3.getNode(), k2) + | + k2 + k3 + ) and offset = pai.getRight().getUnconvertedResultExpression() and n = source.asPathNode1().getNode() and - if (k2 + k3) = 0 then kstr = "" else kstr = " + " + (k2 + k3) + if k = 0 then kstr = "" else kstr = " + " + k select sink, source, sink, "This " + operation + " might be out of bounds, as the pointer might be equal to $@ + $@" + kstr + ".", n, n.toString(), offset, offset.toString() diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index f13d7fbf86a..056e088658b 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -1128,5 +1128,4 @@ subpaths | test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:372:15:372:16 | Load: * ... | test.cpp:363:14:363:27 | new[] | test.cpp:372:15:372:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:363:14:363:27 | new[] | new[] | test.cpp:365:19:365:22 | size | size | -| test.cpp:384:13:384:16 | Load: * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size | | test.cpp:384:13:384:16 | Load: * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size | From 86df424fca6400a16a4c0a4d8979a9f828e76ac4 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 5 Jun 2023 15:10:54 +0200 Subject: [PATCH 326/739] C++: Fix query formatting --- .../experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 20f2e934fed..18c9c0f2185 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -385,7 +385,7 @@ where hasFlowPath(source, sink, source3, pai, operation, k3) and invalidPointerToDerefSource(pai, source3.getNode(), k2) | - k2 + k3 + k2 + k3 ) and offset = pai.getRight().getUnconvertedResultExpression() and n = source.asPathNode1().getNode() and From e49b278d614dc6a2e20ce2eb07966ae455b18681 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Mon, 5 Jun 2023 16:33:12 +0100 Subject: [PATCH 327/739] Java/Kotlin: Add a changenote for the lines-of-code changes. --- java/ql/src/change-notes/2023-06-05-lines-of-code.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/src/change-notes/2023-06-05-lines-of-code.md diff --git a/java/ql/src/change-notes/2023-06-05-lines-of-code.md b/java/ql/src/change-notes/2023-06-05-lines-of-code.md new file mode 100644 index 00000000000..a96c891e506 --- /dev/null +++ b/java/ql/src/change-notes/2023-06-05-lines-of-code.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `java/summary/lines-of-code` query now only counts lines of Java code. The new `java/summary/lines-of-code-kotlin` counts lines of Kotlin code. From 7ad860fc98c1a19720a9cf4dd6f277da0c2de87a Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Mon, 5 Jun 2023 18:00:40 +0200 Subject: [PATCH 328/739] Java: Update MaD declarations after triage Co-authored-by: Stephan Brandauer <kaeluka@github.com> --- java/ql/lib/change-notes/2023-06-01-new-models.md | 7 +++++++ java/ql/lib/ext/java.lang.model.yml | 2 ++ java/ql/lib/ext/java.nio.file.model.yml | 6 ++++++ 3 files changed, 15 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-06-01-new-models.md diff --git a/java/ql/lib/change-notes/2023-06-01-new-models.md b/java/ql/lib/change-notes/2023-06-01-new-models.md new file mode 100644 index 00000000000..d05b3d4d59d --- /dev/null +++ b/java/ql/lib/change-notes/2023-06-01-new-models.md @@ -0,0 +1,7 @@ +--- +category: minorAnalysis +--- +* Added models for the following packages: + + * java.lang + * java.nio.file diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index ed14b2495a3..a0dc4947fc6 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -8,6 +8,8 @@ extensions: - ["java.lang", "ClassLoader", True, "getSystemResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.lang", "Runtime", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] + - ["java.lang", "Runtime", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] # These are modeled in plain CodeQL. TODO: migrate them. # - ["java.lang", "ProcessBuilder", False, "command", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"] # - ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index e4519fbc071..d14ae993388 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -18,6 +18,7 @@ extensions: - ["java.nio.file", "Files", False, "delete", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "getFileStore", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] # the FileStore class is unlikely to be used for later sanitization - ["java.nio.file", "Files", False, "lines", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "lines", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "move", "", "", "Argument[1]", "path-injection", "manual"] @@ -26,6 +27,7 @@ extensions: - ["java.nio.file", "Files", False, "newBufferedWriter", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "newOutputStream", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "probeContentType", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] # accesses the file based on user input, but only reads its content type from it - ["java.nio.file", "Files", False, "readAllBytes", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "readAllLines", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "readAllLines", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] @@ -46,6 +48,10 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["java.nio.file", "Files", False, "find", "(Path,int,BiPredicate,FileVisitOption[])", "", "Argument[0]", "ReturnValue.Element", "taint", "ai-manual"] + - ["java.nio.file", "Files", False, "find", "(Path,int,BiPredicate,FileVisitOption[])", "", "Argument[2]", "ReturnValue.Element", "taint", "ai-manual"] + - ["java.nio.file", "Files", False, "list", "(Path)", "", "Argument[0]", "ReturnValue.Element", "taint", "ai-manual"] + - ["java.nio.file", "Files", False, "readSymbolicLink", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] # this can be used to enumerate a file system - ["java.nio.file", "Files", True, "newBufferedReader", "(Path,Charset)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["java.nio.file", "Files", True, "newBufferedReader", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["java.nio.file", "Files", True, "newByteChannel", "(Path,OpenOption[])", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] From e24e3a61150307a252098153a377046e4412088a Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 30 May 2023 18:39:14 -0400 Subject: [PATCH 329/739] JS/Python/Ruby: add getInvalidModelKind as experiment --- .../data/internal/ApiGraphModels.qll | 20 +++++++++++++++++++ .../data/internal/ApiGraphModels.qll | 20 +++++++++++++++++++ .../data/internal/ApiGraphModels.qll | 20 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index 227f4ea22fb..e08c4d00932 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -654,6 +654,23 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific + private string getInvalidModelKind() { + exists(string kind | sinkModel(_, _, kind) | + not kind = + [ + "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", + "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", + "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", + "path-injection", "file-content-store", "hostname-verification", "response-splitting", + "information-leak", "xslt-injection", "jexl-injection", "bean-validation", + "template-injection", "fragment-injection", "command-injection" + ] and + not kind.matches("credentials-%") and + not kind.matches("test-%") and + result = "Invalid kind \"" + kind + "\" in sink model." + ) + } + /** * Gets an error message relating to an invalid CSV row in a model. */ @@ -698,5 +715,8 @@ module ModelOutput { not isValidNoArgumentTokenInIdentifyingAccessPath(token.getName()) and result = "Invalid token '" + token + "' is missing its arguments, in access path: " + path ) + or + // Check for valid model kinds + result = getInvalidModelKind() } } diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index 227f4ea22fb..e08c4d00932 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -654,6 +654,23 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific + private string getInvalidModelKind() { + exists(string kind | sinkModel(_, _, kind) | + not kind = + [ + "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", + "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", + "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", + "path-injection", "file-content-store", "hostname-verification", "response-splitting", + "information-leak", "xslt-injection", "jexl-injection", "bean-validation", + "template-injection", "fragment-injection", "command-injection" + ] and + not kind.matches("credentials-%") and + not kind.matches("test-%") and + result = "Invalid kind \"" + kind + "\" in sink model." + ) + } + /** * Gets an error message relating to an invalid CSV row in a model. */ @@ -698,5 +715,8 @@ module ModelOutput { not isValidNoArgumentTokenInIdentifyingAccessPath(token.getName()) and result = "Invalid token '" + token + "' is missing its arguments, in access path: " + path ) + or + // Check for valid model kinds + result = getInvalidModelKind() } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index 227f4ea22fb..e08c4d00932 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -654,6 +654,23 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific + private string getInvalidModelKind() { + exists(string kind | sinkModel(_, _, kind) | + not kind = + [ + "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", + "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", + "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", + "path-injection", "file-content-store", "hostname-verification", "response-splitting", + "information-leak", "xslt-injection", "jexl-injection", "bean-validation", + "template-injection", "fragment-injection", "command-injection" + ] and + not kind.matches("credentials-%") and + not kind.matches("test-%") and + result = "Invalid kind \"" + kind + "\" in sink model." + ) + } + /** * Gets an error message relating to an invalid CSV row in a model. */ @@ -698,5 +715,8 @@ module ModelOutput { not isValidNoArgumentTokenInIdentifyingAccessPath(token.getName()) and result = "Invalid token '" + token + "' is missing its arguments, in access path: " + path ) + or + // Check for valid model kinds + result = getInvalidModelKind() } } From 869f820fcfc38b2c22d83e20ec442f7e15e432e8 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 30 May 2023 18:40:05 -0400 Subject: [PATCH 330/739] Shared: add 'SharedModelValidation' file as experiment --- config/identical-files.json | 9 ++++++ .../csharp/dataflow/SharedModelValidation.qll | 30 +++++++++++++++++++ .../go/dataflow/SharedModelValidation.qll | 30 +++++++++++++++++++ .../java/dataflow/SharedModelValidation.qll | 30 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 30 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 30 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 30 +++++++++++++++++++ .../swift/dataflow/SharedModelValidation.qll | 30 +++++++++++++++++++ 8 files changed, 219 insertions(+) create mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll create mode 100644 go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll create mode 100644 java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll create mode 100644 javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll create mode 100644 python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll create mode 100644 swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll diff --git a/config/identical-files.json b/config/identical-files.json index 3c16c953129..cdda39b041a 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -598,5 +598,14 @@ "EncryptionKeySizes Python/Java": [ "python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll", "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" + ], + "SharedModelValidation Java/C#/Go/JS/Python/Ruby/Swift (C++ is problematic for now)": [ + "java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll", + "csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll", + "go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll", + "swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll", + "javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll", + "python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll", + "ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll" ] } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll new file mode 100644 index 00000000000..948b361e4ad --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll @@ -0,0 +1,30 @@ +/** + * INTERNAL: Do not use. + * + * Provides classes for validating kinds in models as data rows. + * Such that we can share this logic across our CodeQL analysis of different languages. + */ +class ValidSinkKind extends string { + ValidSinkKind() { + this = + [ + // shared ALL languages + "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", + "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", + "file-content-store", "hostname-verification", "response-splitting", "information-leak", + "xslt-injection", "template-injection", "fragment-injection", "command-injection", + "unsafe-deserialization", "xxe", "database-store", "format-string", + // .matches("credentials-%"), .matches("regex-use%")" + // shared MOST languages + "code-injection", // .matches("encryption-%"), + // Java only + "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", + "bean-validation", "intent-redirection", "pending-intents", + // JS only + "mongodb.sink", + // Swift only + "preferences-store", "transmission", "predicate-injection", "webview-fetch", + "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + ] + } +} diff --git a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll new file mode 100644 index 00000000000..948b361e4ad --- /dev/null +++ b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll @@ -0,0 +1,30 @@ +/** + * INTERNAL: Do not use. + * + * Provides classes for validating kinds in models as data rows. + * Such that we can share this logic across our CodeQL analysis of different languages. + */ +class ValidSinkKind extends string { + ValidSinkKind() { + this = + [ + // shared ALL languages + "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", + "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", + "file-content-store", "hostname-verification", "response-splitting", "information-leak", + "xslt-injection", "template-injection", "fragment-injection", "command-injection", + "unsafe-deserialization", "xxe", "database-store", "format-string", + // .matches("credentials-%"), .matches("regex-use%")" + // shared MOST languages + "code-injection", // .matches("encryption-%"), + // Java only + "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", + "bean-validation", "intent-redirection", "pending-intents", + // JS only + "mongodb.sink", + // Swift only + "preferences-store", "transmission", "predicate-injection", "webview-fetch", + "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + ] + } +} diff --git a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll new file mode 100644 index 00000000000..948b361e4ad --- /dev/null +++ b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll @@ -0,0 +1,30 @@ +/** + * INTERNAL: Do not use. + * + * Provides classes for validating kinds in models as data rows. + * Such that we can share this logic across our CodeQL analysis of different languages. + */ +class ValidSinkKind extends string { + ValidSinkKind() { + this = + [ + // shared ALL languages + "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", + "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", + "file-content-store", "hostname-verification", "response-splitting", "information-leak", + "xslt-injection", "template-injection", "fragment-injection", "command-injection", + "unsafe-deserialization", "xxe", "database-store", "format-string", + // .matches("credentials-%"), .matches("regex-use%")" + // shared MOST languages + "code-injection", // .matches("encryption-%"), + // Java only + "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", + "bean-validation", "intent-redirection", "pending-intents", + // JS only + "mongodb.sink", + // Swift only + "preferences-store", "transmission", "predicate-injection", "webview-fetch", + "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + ] + } +} diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll new file mode 100644 index 00000000000..948b361e4ad --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll @@ -0,0 +1,30 @@ +/** + * INTERNAL: Do not use. + * + * Provides classes for validating kinds in models as data rows. + * Such that we can share this logic across our CodeQL analysis of different languages. + */ +class ValidSinkKind extends string { + ValidSinkKind() { + this = + [ + // shared ALL languages + "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", + "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", + "file-content-store", "hostname-verification", "response-splitting", "information-leak", + "xslt-injection", "template-injection", "fragment-injection", "command-injection", + "unsafe-deserialization", "xxe", "database-store", "format-string", + // .matches("credentials-%"), .matches("regex-use%")" + // shared MOST languages + "code-injection", // .matches("encryption-%"), + // Java only + "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", + "bean-validation", "intent-redirection", "pending-intents", + // JS only + "mongodb.sink", + // Swift only + "preferences-store", "transmission", "predicate-injection", "webview-fetch", + "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + ] + } +} diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll new file mode 100644 index 00000000000..948b361e4ad --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll @@ -0,0 +1,30 @@ +/** + * INTERNAL: Do not use. + * + * Provides classes for validating kinds in models as data rows. + * Such that we can share this logic across our CodeQL analysis of different languages. + */ +class ValidSinkKind extends string { + ValidSinkKind() { + this = + [ + // shared ALL languages + "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", + "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", + "file-content-store", "hostname-verification", "response-splitting", "information-leak", + "xslt-injection", "template-injection", "fragment-injection", "command-injection", + "unsafe-deserialization", "xxe", "database-store", "format-string", + // .matches("credentials-%"), .matches("regex-use%")" + // shared MOST languages + "code-injection", // .matches("encryption-%"), + // Java only + "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", + "bean-validation", "intent-redirection", "pending-intents", + // JS only + "mongodb.sink", + // Swift only + "preferences-store", "transmission", "predicate-injection", "webview-fetch", + "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + ] + } +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll new file mode 100644 index 00000000000..948b361e4ad --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll @@ -0,0 +1,30 @@ +/** + * INTERNAL: Do not use. + * + * Provides classes for validating kinds in models as data rows. + * Such that we can share this logic across our CodeQL analysis of different languages. + */ +class ValidSinkKind extends string { + ValidSinkKind() { + this = + [ + // shared ALL languages + "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", + "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", + "file-content-store", "hostname-verification", "response-splitting", "information-leak", + "xslt-injection", "template-injection", "fragment-injection", "command-injection", + "unsafe-deserialization", "xxe", "database-store", "format-string", + // .matches("credentials-%"), .matches("regex-use%")" + // shared MOST languages + "code-injection", // .matches("encryption-%"), + // Java only + "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", + "bean-validation", "intent-redirection", "pending-intents", + // JS only + "mongodb.sink", + // Swift only + "preferences-store", "transmission", "predicate-injection", "webview-fetch", + "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + ] + } +} diff --git a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll new file mode 100644 index 00000000000..948b361e4ad --- /dev/null +++ b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll @@ -0,0 +1,30 @@ +/** + * INTERNAL: Do not use. + * + * Provides classes for validating kinds in models as data rows. + * Such that we can share this logic across our CodeQL analysis of different languages. + */ +class ValidSinkKind extends string { + ValidSinkKind() { + this = + [ + // shared ALL languages + "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", + "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", + "file-content-store", "hostname-verification", "response-splitting", "information-leak", + "xslt-injection", "template-injection", "fragment-injection", "command-injection", + "unsafe-deserialization", "xxe", "database-store", "format-string", + // .matches("credentials-%"), .matches("regex-use%")" + // shared MOST languages + "code-injection", // .matches("encryption-%"), + // Java only + "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", + "bean-validation", "intent-redirection", "pending-intents", + // JS only + "mongodb.sink", + // Swift only + "preferences-store", "transmission", "predicate-injection", "webview-fetch", + "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + ] + } +} From ddb5d92ef8a854711eb35ff6cef90963adfd412d Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 30 May 2023 19:01:27 -0400 Subject: [PATCH 331/739] Shared: add source, summary, and neutral shared valid kinds --- .../csharp/dataflow/SharedModelValidation.qll | 35 +++++++++++++++++++ .../go/dataflow/SharedModelValidation.qll | 35 +++++++++++++++++++ .../java/dataflow/SharedModelValidation.qll | 35 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 35 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 35 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 35 +++++++++++++++++++ .../swift/dataflow/SharedModelValidation.qll | 35 +++++++++++++++++++ 7 files changed, 245 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll index 948b361e4ad..8178dcf13d3 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll @@ -4,6 +4,8 @@ * Provides classes for validating kinds in models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ + +/** A valid models-as-data sink kind. */ class ValidSinkKind extends string { ValidSinkKind() { this = @@ -28,3 +30,36 @@ class ValidSinkKind extends string { ] } } + +/** A valid models-as-data source kind. */ +class ValidSourceKind extends string { + ValidSourceKind() { + this = + [ + // shared ALL languages + "remote", "local" + ] + } +} + +/** A valid models-as-data summary kind. */ +class ValidSummaryKind extends string { + ValidSummaryKind() { + this = + [ + // shared ALL languages + "taint", "value" + ] + } +} + +/** A valid models-as-data neutral kind. */ +class ValidNeutralKind extends string { + ValidNeutralKind() { + this = + [ + // shared ALL languages + "summary", "source", "sink" + ] + } +} diff --git a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll index 948b361e4ad..8178dcf13d3 100644 --- a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll +++ b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll @@ -4,6 +4,8 @@ * Provides classes for validating kinds in models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ + +/** A valid models-as-data sink kind. */ class ValidSinkKind extends string { ValidSinkKind() { this = @@ -28,3 +30,36 @@ class ValidSinkKind extends string { ] } } + +/** A valid models-as-data source kind. */ +class ValidSourceKind extends string { + ValidSourceKind() { + this = + [ + // shared ALL languages + "remote", "local" + ] + } +} + +/** A valid models-as-data summary kind. */ +class ValidSummaryKind extends string { + ValidSummaryKind() { + this = + [ + // shared ALL languages + "taint", "value" + ] + } +} + +/** A valid models-as-data neutral kind. */ +class ValidNeutralKind extends string { + ValidNeutralKind() { + this = + [ + // shared ALL languages + "summary", "source", "sink" + ] + } +} diff --git a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll index 948b361e4ad..8178dcf13d3 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll @@ -4,6 +4,8 @@ * Provides classes for validating kinds in models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ + +/** A valid models-as-data sink kind. */ class ValidSinkKind extends string { ValidSinkKind() { this = @@ -28,3 +30,36 @@ class ValidSinkKind extends string { ] } } + +/** A valid models-as-data source kind. */ +class ValidSourceKind extends string { + ValidSourceKind() { + this = + [ + // shared ALL languages + "remote", "local" + ] + } +} + +/** A valid models-as-data summary kind. */ +class ValidSummaryKind extends string { + ValidSummaryKind() { + this = + [ + // shared ALL languages + "taint", "value" + ] + } +} + +/** A valid models-as-data neutral kind. */ +class ValidNeutralKind extends string { + ValidNeutralKind() { + this = + [ + // shared ALL languages + "summary", "source", "sink" + ] + } +} diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll index 948b361e4ad..8178dcf13d3 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll @@ -4,6 +4,8 @@ * Provides classes for validating kinds in models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ + +/** A valid models-as-data sink kind. */ class ValidSinkKind extends string { ValidSinkKind() { this = @@ -28,3 +30,36 @@ class ValidSinkKind extends string { ] } } + +/** A valid models-as-data source kind. */ +class ValidSourceKind extends string { + ValidSourceKind() { + this = + [ + // shared ALL languages + "remote", "local" + ] + } +} + +/** A valid models-as-data summary kind. */ +class ValidSummaryKind extends string { + ValidSummaryKind() { + this = + [ + // shared ALL languages + "taint", "value" + ] + } +} + +/** A valid models-as-data neutral kind. */ +class ValidNeutralKind extends string { + ValidNeutralKind() { + this = + [ + // shared ALL languages + "summary", "source", "sink" + ] + } +} diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll index 948b361e4ad..8178dcf13d3 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll @@ -4,6 +4,8 @@ * Provides classes for validating kinds in models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ + +/** A valid models-as-data sink kind. */ class ValidSinkKind extends string { ValidSinkKind() { this = @@ -28,3 +30,36 @@ class ValidSinkKind extends string { ] } } + +/** A valid models-as-data source kind. */ +class ValidSourceKind extends string { + ValidSourceKind() { + this = + [ + // shared ALL languages + "remote", "local" + ] + } +} + +/** A valid models-as-data summary kind. */ +class ValidSummaryKind extends string { + ValidSummaryKind() { + this = + [ + // shared ALL languages + "taint", "value" + ] + } +} + +/** A valid models-as-data neutral kind. */ +class ValidNeutralKind extends string { + ValidNeutralKind() { + this = + [ + // shared ALL languages + "summary", "source", "sink" + ] + } +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll index 948b361e4ad..8178dcf13d3 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll @@ -4,6 +4,8 @@ * Provides classes for validating kinds in models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ + +/** A valid models-as-data sink kind. */ class ValidSinkKind extends string { ValidSinkKind() { this = @@ -28,3 +30,36 @@ class ValidSinkKind extends string { ] } } + +/** A valid models-as-data source kind. */ +class ValidSourceKind extends string { + ValidSourceKind() { + this = + [ + // shared ALL languages + "remote", "local" + ] + } +} + +/** A valid models-as-data summary kind. */ +class ValidSummaryKind extends string { + ValidSummaryKind() { + this = + [ + // shared ALL languages + "taint", "value" + ] + } +} + +/** A valid models-as-data neutral kind. */ +class ValidNeutralKind extends string { + ValidNeutralKind() { + this = + [ + // shared ALL languages + "summary", "source", "sink" + ] + } +} diff --git a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll index 948b361e4ad..8178dcf13d3 100644 --- a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll +++ b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll @@ -4,6 +4,8 @@ * Provides classes for validating kinds in models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ + +/** A valid models-as-data sink kind. */ class ValidSinkKind extends string { ValidSinkKind() { this = @@ -28,3 +30,36 @@ class ValidSinkKind extends string { ] } } + +/** A valid models-as-data source kind. */ +class ValidSourceKind extends string { + ValidSourceKind() { + this = + [ + // shared ALL languages + "remote", "local" + ] + } +} + +/** A valid models-as-data summary kind. */ +class ValidSummaryKind extends string { + ValidSummaryKind() { + this = + [ + // shared ALL languages + "taint", "value" + ] + } +} + +/** A valid models-as-data neutral kind. */ +class ValidNeutralKind extends string { + ValidNeutralKind() { + this = + [ + // shared ALL languages + "summary", "source", "sink" + ] + } +} From 0ab1848b70803675303044a3fdaae5f72f156ca3 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 30 May 2023 19:04:15 -0400 Subject: [PATCH 332/739] JS/Python/Ruby: use 'SharedModelValidation' file --- .../data/internal/ApiGraphModels.qll | 22 +++++++++++-------- .../data/internal/ApiGraphModels.qll | 22 +++++++++++-------- .../data/internal/ApiGraphModels.qll | 22 +++++++++++-------- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index e08c4d00932..4799f75937e 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -653,22 +653,26 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific + private import SharedModelValidation private string getInvalidModelKind() { + exists(string kind | summaryModel(_, _, _, _, kind) | + not kind instanceof ValidSummaryKind and + result = "Invalid kind \"" + kind + "\" in summary model." + ) + or exists(string kind | sinkModel(_, _, kind) | - not kind = - [ - "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", - "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", - "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", - "path-injection", "file-content-store", "hostname-verification", "response-splitting", - "information-leak", "xslt-injection", "jexl-injection", "bean-validation", - "template-injection", "fragment-injection", "command-injection" - ] and + not kind instanceof ValidSinkKind and not kind.matches("credentials-%") and not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) + or + exists(string kind | sourceModel(_, _, kind) | + not kind instanceof ValidSourceKind and + not kind.matches("qltest%") and + result = "Invalid kind \"" + kind + "\" in source model." + ) } /** diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index e08c4d00932..4799f75937e 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -653,22 +653,26 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific + private import SharedModelValidation private string getInvalidModelKind() { + exists(string kind | summaryModel(_, _, _, _, kind) | + not kind instanceof ValidSummaryKind and + result = "Invalid kind \"" + kind + "\" in summary model." + ) + or exists(string kind | sinkModel(_, _, kind) | - not kind = - [ - "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", - "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", - "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", - "path-injection", "file-content-store", "hostname-verification", "response-splitting", - "information-leak", "xslt-injection", "jexl-injection", "bean-validation", - "template-injection", "fragment-injection", "command-injection" - ] and + not kind instanceof ValidSinkKind and not kind.matches("credentials-%") and not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) + or + exists(string kind | sourceModel(_, _, kind) | + not kind instanceof ValidSourceKind and + not kind.matches("qltest%") and + result = "Invalid kind \"" + kind + "\" in source model." + ) } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index e08c4d00932..4799f75937e 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -653,22 +653,26 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific + private import SharedModelValidation private string getInvalidModelKind() { + exists(string kind | summaryModel(_, _, _, _, kind) | + not kind instanceof ValidSummaryKind and + result = "Invalid kind \"" + kind + "\" in summary model." + ) + or exists(string kind | sinkModel(_, _, kind) | - not kind = - [ - "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", - "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", - "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", - "path-injection", "file-content-store", "hostname-verification", "response-splitting", - "information-leak", "xslt-injection", "jexl-injection", "bean-validation", - "template-injection", "fragment-injection", "command-injection" - ] and + not kind instanceof ValidSinkKind and not kind.matches("credentials-%") and not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) + or + exists(string kind | sourceModel(_, _, kind) | + not kind instanceof ValidSourceKind and + not kind.matches("qltest%") and + result = "Invalid kind \"" + kind + "\" in source model." + ) } /** From 79f61cc645bbcfaffc35fed6482b0a08fe33306b Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 2 Jun 2023 13:54:45 -0400 Subject: [PATCH 333/739] Java/C#/Go/Swift: use 'SharedModelValidation' file --- .../code/csharp/dataflow/ExternalFlow.qll | 15 ++++++---- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 4 ++- .../code/java/dataflow/ExternalFlow.qll | 29 +++++++++++-------- .../codeql/swift/dataflow/ExternalFlow.qll | 4 ++- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 46a19828a81..902d6f246c9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -95,6 +95,7 @@ private import internal.DataFlowPublic private import internal.FlowSummaryImpl::Public private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific +private import SharedModelValidation /** Holds if a source model exists for the given parameters. */ predicate sourceModel = Extensions::sourceModel/9; @@ -206,24 +207,28 @@ module ModelValidation { private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | - not kind = ["taint", "value"] and + not kind instanceof ValidSummaryKind and + //not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) or exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | - not kind = - ["code-injection", "sql-injection", "js-injection", "html-injection", "file-content-store"] and + not kind instanceof ValidSinkKind and + // not kind = + // ["code-injection", "sql-injection", "js-injection", "html-injection", "file-content-store"] and not kind.matches("encryption-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind = ["local", "remote", "file", "file-write"] and + not kind instanceof ValidSourceKind and + //not kind = ["local", "remote", "file", "file-write"] and result = "Invalid kind \"" + kind + "\" in source model." ) or exists(string kind | neutralModel(_, _, _, _, kind, _) | - not kind = ["summary", "source", "sink"] and + not kind instanceof ValidNeutralKind and + //not kind = ["summary", "source", "sink"] and result = "Invalid kind \"" + kind + "\" in neutral model." ) } diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 0c6ee1c3134..05818ab68c7 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -68,6 +68,7 @@ private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific private import internal.AccessPathSyntax private import FlowSummary +private import SharedModelValidation /** * A module importing the frameworks that provide external flow data, @@ -190,7 +191,8 @@ module ModelValidation { private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | - not kind = ["taint", "value"] and + not kind instanceof ValidSummaryKind and + //not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index bb8485cd601..b3a128fb4e1 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -87,6 +87,7 @@ private import internal.FlowSummaryImplSpecific as FlowSummaryImplSpecific private import internal.AccessPathSyntax private import ExternalFlowExtensions as Extensions private import FlowSummary +private import SharedModelValidation /** * A class for activating additional model rows. @@ -311,20 +312,22 @@ module ModelValidation { private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | - not kind = ["taint", "value"] and + not kind instanceof ValidSummaryKind and + //not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) or exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | - not kind = - [ - "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", - "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", - "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", - "path-injection", "file-content-store", "hostname-verification", "response-splitting", - "information-leak", "xslt-injection", "jexl-injection", "bean-validation", - "template-injection", "fragment-injection", "command-injection" - ] and + not kind instanceof ValidSinkKind and + // not kind = + // [ + // "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", + // "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", + // "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", + // "path-injection", "file-content-store", "hostname-verification", "response-splitting", + // "information-leak", "xslt-injection", "jexl-injection", "bean-validation", + // "template-injection", "fragment-injection", "command-injection" + // ] and not kind.matches("regex-use%") and not kind.matches("qltest%") and msg = "Invalid kind \"" + kind + "\" in sink model." and @@ -335,13 +338,15 @@ module ModelValidation { ) or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind = ["remote", "contentprovider", "android-external-storage-dir"] and + not kind instanceof ValidSourceKind and + // not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." ) or exists(string kind | neutralModel(_, _, _, _, kind, _) | - not kind = ["summary", "source", "sink"] and + not kind instanceof ValidNeutralKind and + //not kind = ["summary", "source", "sink"] and result = "Invalid kind \"" + kind + "\" in neutral model." ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 82daf14a39a..0adc9be7373 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -74,6 +74,7 @@ private import internal.FlowSummaryImpl::Public private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific private import FlowSummary as FlowSummary +private import SharedModelValidation /** * A unit class for adding additional source model rows. @@ -266,7 +267,8 @@ module CsvValidation { private string getInvalidModelKind() { exists(string row, string kind | summaryModel(row) | kind = row.splitAt(";", 8) and - not kind = ["taint", "value"] and + not kind instanceof ValidSummaryKind and + //not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) } From 7317c29eead9417a19d66d148268135fbbcdbf68 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 2 Jun 2023 16:49:49 -0400 Subject: [PATCH 334/739] Shared: update kind information --- .../csharp/dataflow/SharedModelValidation.qll | 67 ++++++++++++------- .../go/dataflow/SharedModelValidation.qll | 67 ++++++++++++------- .../java/dataflow/SharedModelValidation.qll | 67 ++++++++++++------- .../data/internal/SharedModelValidation.qll | 67 ++++++++++++------- .../data/internal/SharedModelValidation.qll | 67 ++++++++++++------- .../data/internal/SharedModelValidation.qll | 67 ++++++++++++------- .../swift/dataflow/SharedModelValidation.qll | 67 ++++++++++++------- 7 files changed, 308 insertions(+), 161 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll index 8178dcf13d3..5b0105ad554 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll @@ -7,38 +7,57 @@ /** A valid models-as-data sink kind. */ class ValidSinkKind extends string { + bindingset[this] ValidSinkKind() { this = [ - // shared ALL languages - "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", - "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", - "file-content-store", "hostname-verification", "response-splitting", "information-leak", - "xslt-injection", "template-injection", "fragment-injection", "command-injection", - "unsafe-deserialization", "xxe", "database-store", "format-string", - // .matches("credentials-%"), .matches("regex-use%")" - // shared MOST languages - "code-injection", // .matches("encryption-%"), - // Java only - "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", - "bean-validation", "intent-redirection", "pending-intents", - // JS only - "mongodb.sink", - // Swift only - "preferences-store", "transmission", "predicate-injection", "webview-fetch", - "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + // shared + "code-injection", "command-injection", "file-content-store", "html-injection", + "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", + "sql-injection", "url-redirection", + // Java-only currently, but may be shared in the future + "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", + "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", + "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", + "template-injection", "xpath-injection", "xslt-injection", + // JavaScript-only currently, but may be shared in the future + "mongodb.sink", "nosql-injection", "unsafe-deserialization", + // Swift-only currently, but may be shared in the future + "database-store", "format-string", "hash-iteration-count", "predicate-injection", + "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" ] + or + this.matches([ + // shared + "encryption-%", + // Java-only currently, but may be shared in the future + "regex-use%", + // JavaScript-only currently, but may be shared in the future + "credentials-%", + // Swift-only currently, but may be shared in the future + "%string-%length", "weak-hash-input-%" + ]) } } /** A valid models-as-data source kind. */ class ValidSourceKind extends string { + bindingset[this] ValidSourceKind() { this = [ - // shared ALL languages - "remote", "local" + // shared + "local", "remote", + // Java + "android-external-storage-dir", "contentprovider", + // C# + "file", "file-write", + // JavaScript + "database-access-result" ] + or + // Swift + this.matches("%string-%length") } } @@ -47,8 +66,10 @@ class ValidSummaryKind extends string { ValidSummaryKind() { this = [ - // shared ALL languages - "taint", "value" + // shared + "taint", "value", + // JavaScript + "type" ] } } @@ -58,8 +79,8 @@ class ValidNeutralKind extends string { ValidNeutralKind() { this = [ - // shared ALL languages - "summary", "source", "sink" + // Java/C# currently + "sink", "source", "summary" ] } } diff --git a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll index 8178dcf13d3..5b0105ad554 100644 --- a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll +++ b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll @@ -7,38 +7,57 @@ /** A valid models-as-data sink kind. */ class ValidSinkKind extends string { + bindingset[this] ValidSinkKind() { this = [ - // shared ALL languages - "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", - "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", - "file-content-store", "hostname-verification", "response-splitting", "information-leak", - "xslt-injection", "template-injection", "fragment-injection", "command-injection", - "unsafe-deserialization", "xxe", "database-store", "format-string", - // .matches("credentials-%"), .matches("regex-use%")" - // shared MOST languages - "code-injection", // .matches("encryption-%"), - // Java only - "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", - "bean-validation", "intent-redirection", "pending-intents", - // JS only - "mongodb.sink", - // Swift only - "preferences-store", "transmission", "predicate-injection", "webview-fetch", - "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + // shared + "code-injection", "command-injection", "file-content-store", "html-injection", + "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", + "sql-injection", "url-redirection", + // Java-only currently, but may be shared in the future + "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", + "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", + "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", + "template-injection", "xpath-injection", "xslt-injection", + // JavaScript-only currently, but may be shared in the future + "mongodb.sink", "nosql-injection", "unsafe-deserialization", + // Swift-only currently, but may be shared in the future + "database-store", "format-string", "hash-iteration-count", "predicate-injection", + "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" ] + or + this.matches([ + // shared + "encryption-%", + // Java-only currently, but may be shared in the future + "regex-use%", + // JavaScript-only currently, but may be shared in the future + "credentials-%", + // Swift-only currently, but may be shared in the future + "%string-%length", "weak-hash-input-%" + ]) } } /** A valid models-as-data source kind. */ class ValidSourceKind extends string { + bindingset[this] ValidSourceKind() { this = [ - // shared ALL languages - "remote", "local" + // shared + "local", "remote", + // Java + "android-external-storage-dir", "contentprovider", + // C# + "file", "file-write", + // JavaScript + "database-access-result" ] + or + // Swift + this.matches("%string-%length") } } @@ -47,8 +66,10 @@ class ValidSummaryKind extends string { ValidSummaryKind() { this = [ - // shared ALL languages - "taint", "value" + // shared + "taint", "value", + // JavaScript + "type" ] } } @@ -58,8 +79,8 @@ class ValidNeutralKind extends string { ValidNeutralKind() { this = [ - // shared ALL languages - "summary", "source", "sink" + // Java/C# currently + "sink", "source", "summary" ] } } diff --git a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll index 8178dcf13d3..5b0105ad554 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll @@ -7,38 +7,57 @@ /** A valid models-as-data sink kind. */ class ValidSinkKind extends string { + bindingset[this] ValidSinkKind() { this = [ - // shared ALL languages - "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", - "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", - "file-content-store", "hostname-verification", "response-splitting", "information-leak", - "xslt-injection", "template-injection", "fragment-injection", "command-injection", - "unsafe-deserialization", "xxe", "database-store", "format-string", - // .matches("credentials-%"), .matches("regex-use%")" - // shared MOST languages - "code-injection", // .matches("encryption-%"), - // Java only - "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", - "bean-validation", "intent-redirection", "pending-intents", - // JS only - "mongodb.sink", - // Swift only - "preferences-store", "transmission", "predicate-injection", "webview-fetch", - "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + // shared + "code-injection", "command-injection", "file-content-store", "html-injection", + "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", + "sql-injection", "url-redirection", + // Java-only currently, but may be shared in the future + "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", + "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", + "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", + "template-injection", "xpath-injection", "xslt-injection", + // JavaScript-only currently, but may be shared in the future + "mongodb.sink", "nosql-injection", "unsafe-deserialization", + // Swift-only currently, but may be shared in the future + "database-store", "format-string", "hash-iteration-count", "predicate-injection", + "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" ] + or + this.matches([ + // shared + "encryption-%", + // Java-only currently, but may be shared in the future + "regex-use%", + // JavaScript-only currently, but may be shared in the future + "credentials-%", + // Swift-only currently, but may be shared in the future + "%string-%length", "weak-hash-input-%" + ]) } } /** A valid models-as-data source kind. */ class ValidSourceKind extends string { + bindingset[this] ValidSourceKind() { this = [ - // shared ALL languages - "remote", "local" + // shared + "local", "remote", + // Java + "android-external-storage-dir", "contentprovider", + // C# + "file", "file-write", + // JavaScript + "database-access-result" ] + or + // Swift + this.matches("%string-%length") } } @@ -47,8 +66,10 @@ class ValidSummaryKind extends string { ValidSummaryKind() { this = [ - // shared ALL languages - "taint", "value" + // shared + "taint", "value", + // JavaScript + "type" ] } } @@ -58,8 +79,8 @@ class ValidNeutralKind extends string { ValidNeutralKind() { this = [ - // shared ALL languages - "summary", "source", "sink" + // Java/C# currently + "sink", "source", "summary" ] } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll index 8178dcf13d3..5b0105ad554 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll @@ -7,38 +7,57 @@ /** A valid models-as-data sink kind. */ class ValidSinkKind extends string { + bindingset[this] ValidSinkKind() { this = [ - // shared ALL languages - "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", - "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", - "file-content-store", "hostname-verification", "response-splitting", "information-leak", - "xslt-injection", "template-injection", "fragment-injection", "command-injection", - "unsafe-deserialization", "xxe", "database-store", "format-string", - // .matches("credentials-%"), .matches("regex-use%")" - // shared MOST languages - "code-injection", // .matches("encryption-%"), - // Java only - "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", - "bean-validation", "intent-redirection", "pending-intents", - // JS only - "mongodb.sink", - // Swift only - "preferences-store", "transmission", "predicate-injection", "webview-fetch", - "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + // shared + "code-injection", "command-injection", "file-content-store", "html-injection", + "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", + "sql-injection", "url-redirection", + // Java-only currently, but may be shared in the future + "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", + "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", + "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", + "template-injection", "xpath-injection", "xslt-injection", + // JavaScript-only currently, but may be shared in the future + "mongodb.sink", "nosql-injection", "unsafe-deserialization", + // Swift-only currently, but may be shared in the future + "database-store", "format-string", "hash-iteration-count", "predicate-injection", + "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" ] + or + this.matches([ + // shared + "encryption-%", + // Java-only currently, but may be shared in the future + "regex-use%", + // JavaScript-only currently, but may be shared in the future + "credentials-%", + // Swift-only currently, but may be shared in the future + "%string-%length", "weak-hash-input-%" + ]) } } /** A valid models-as-data source kind. */ class ValidSourceKind extends string { + bindingset[this] ValidSourceKind() { this = [ - // shared ALL languages - "remote", "local" + // shared + "local", "remote", + // Java + "android-external-storage-dir", "contentprovider", + // C# + "file", "file-write", + // JavaScript + "database-access-result" ] + or + // Swift + this.matches("%string-%length") } } @@ -47,8 +66,10 @@ class ValidSummaryKind extends string { ValidSummaryKind() { this = [ - // shared ALL languages - "taint", "value" + // shared + "taint", "value", + // JavaScript + "type" ] } } @@ -58,8 +79,8 @@ class ValidNeutralKind extends string { ValidNeutralKind() { this = [ - // shared ALL languages - "summary", "source", "sink" + // Java/C# currently + "sink", "source", "summary" ] } } diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll index 8178dcf13d3..5b0105ad554 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll @@ -7,38 +7,57 @@ /** A valid models-as-data sink kind. */ class ValidSinkKind extends string { + bindingset[this] ValidSinkKind() { this = [ - // shared ALL languages - "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", - "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", - "file-content-store", "hostname-verification", "response-splitting", "information-leak", - "xslt-injection", "template-injection", "fragment-injection", "command-injection", - "unsafe-deserialization", "xxe", "database-store", "format-string", - // .matches("credentials-%"), .matches("regex-use%")" - // shared MOST languages - "code-injection", // .matches("encryption-%"), - // Java only - "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", - "bean-validation", "intent-redirection", "pending-intents", - // JS only - "mongodb.sink", - // Swift only - "preferences-store", "transmission", "predicate-injection", "webview-fetch", - "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + // shared + "code-injection", "command-injection", "file-content-store", "html-injection", + "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", + "sql-injection", "url-redirection", + // Java-only currently, but may be shared in the future + "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", + "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", + "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", + "template-injection", "xpath-injection", "xslt-injection", + // JavaScript-only currently, but may be shared in the future + "mongodb.sink", "nosql-injection", "unsafe-deserialization", + // Swift-only currently, but may be shared in the future + "database-store", "format-string", "hash-iteration-count", "predicate-injection", + "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" ] + or + this.matches([ + // shared + "encryption-%", + // Java-only currently, but may be shared in the future + "regex-use%", + // JavaScript-only currently, but may be shared in the future + "credentials-%", + // Swift-only currently, but may be shared in the future + "%string-%length", "weak-hash-input-%" + ]) } } /** A valid models-as-data source kind. */ class ValidSourceKind extends string { + bindingset[this] ValidSourceKind() { this = [ - // shared ALL languages - "remote", "local" + // shared + "local", "remote", + // Java + "android-external-storage-dir", "contentprovider", + // C# + "file", "file-write", + // JavaScript + "database-access-result" ] + or + // Swift + this.matches("%string-%length") } } @@ -47,8 +66,10 @@ class ValidSummaryKind extends string { ValidSummaryKind() { this = [ - // shared ALL languages - "taint", "value" + // shared + "taint", "value", + // JavaScript + "type" ] } } @@ -58,8 +79,8 @@ class ValidNeutralKind extends string { ValidNeutralKind() { this = [ - // shared ALL languages - "summary", "source", "sink" + // Java/C# currently + "sink", "source", "summary" ] } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll index 8178dcf13d3..5b0105ad554 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll @@ -7,38 +7,57 @@ /** A valid models-as-data sink kind. */ class ValidSinkKind extends string { + bindingset[this] ValidSinkKind() { this = [ - // shared ALL languages - "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", - "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", - "file-content-store", "hostname-verification", "response-splitting", "information-leak", - "xslt-injection", "template-injection", "fragment-injection", "command-injection", - "unsafe-deserialization", "xxe", "database-store", "format-string", - // .matches("credentials-%"), .matches("regex-use%")" - // shared MOST languages - "code-injection", // .matches("encryption-%"), - // Java only - "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", - "bean-validation", "intent-redirection", "pending-intents", - // JS only - "mongodb.sink", - // Swift only - "preferences-store", "transmission", "predicate-injection", "webview-fetch", - "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + // shared + "code-injection", "command-injection", "file-content-store", "html-injection", + "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", + "sql-injection", "url-redirection", + // Java-only currently, but may be shared in the future + "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", + "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", + "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", + "template-injection", "xpath-injection", "xslt-injection", + // JavaScript-only currently, but may be shared in the future + "mongodb.sink", "nosql-injection", "unsafe-deserialization", + // Swift-only currently, but may be shared in the future + "database-store", "format-string", "hash-iteration-count", "predicate-injection", + "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" ] + or + this.matches([ + // shared + "encryption-%", + // Java-only currently, but may be shared in the future + "regex-use%", + // JavaScript-only currently, but may be shared in the future + "credentials-%", + // Swift-only currently, but may be shared in the future + "%string-%length", "weak-hash-input-%" + ]) } } /** A valid models-as-data source kind. */ class ValidSourceKind extends string { + bindingset[this] ValidSourceKind() { this = [ - // shared ALL languages - "remote", "local" + // shared + "local", "remote", + // Java + "android-external-storage-dir", "contentprovider", + // C# + "file", "file-write", + // JavaScript + "database-access-result" ] + or + // Swift + this.matches("%string-%length") } } @@ -47,8 +66,10 @@ class ValidSummaryKind extends string { ValidSummaryKind() { this = [ - // shared ALL languages - "taint", "value" + // shared + "taint", "value", + // JavaScript + "type" ] } } @@ -58,8 +79,8 @@ class ValidNeutralKind extends string { ValidNeutralKind() { this = [ - // shared ALL languages - "summary", "source", "sink" + // Java/C# currently + "sink", "source", "summary" ] } } diff --git a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll index 8178dcf13d3..5b0105ad554 100644 --- a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll +++ b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll @@ -7,38 +7,57 @@ /** A valid models-as-data sink kind. */ class ValidSinkKind extends string { + bindingset[this] ValidSinkKind() { this = [ - // shared ALL languages - "request-forgery", "ldap-injection", "sql-injection", "nosql-injection", "log-injection", - "xpath-injection", "html-injection", "js-injection", "url-redirection", "path-injection", - "file-content-store", "hostname-verification", "response-splitting", "information-leak", - "xslt-injection", "template-injection", "fragment-injection", "command-injection", - "unsafe-deserialization", "xxe", "database-store", "format-string", - // .matches("credentials-%"), .matches("regex-use%")" - // shared MOST languages - "code-injection", // .matches("encryption-%"), - // Java only - "jndi-injection", "mvel-injection", "groovy-injection", "ognl-injection", "jexl-injection", - "bean-validation", "intent-redirection", "pending-intents", - // JS only - "mongodb.sink", - // Swift only - "preferences-store", "transmission", "predicate-injection", "webview-fetch", - "tls-protocol-version", "hash-iteration-count" // .matches("%string-%length"), .matches("weak-hash-input-") + // shared + "code-injection", "command-injection", "file-content-store", "html-injection", + "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", + "sql-injection", "url-redirection", + // Java-only currently, but may be shared in the future + "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", + "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", + "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", + "template-injection", "xpath-injection", "xslt-injection", + // JavaScript-only currently, but may be shared in the future + "mongodb.sink", "nosql-injection", "unsafe-deserialization", + // Swift-only currently, but may be shared in the future + "database-store", "format-string", "hash-iteration-count", "predicate-injection", + "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" ] + or + this.matches([ + // shared + "encryption-%", + // Java-only currently, but may be shared in the future + "regex-use%", + // JavaScript-only currently, but may be shared in the future + "credentials-%", + // Swift-only currently, but may be shared in the future + "%string-%length", "weak-hash-input-%" + ]) } } /** A valid models-as-data source kind. */ class ValidSourceKind extends string { + bindingset[this] ValidSourceKind() { this = [ - // shared ALL languages - "remote", "local" + // shared + "local", "remote", + // Java + "android-external-storage-dir", "contentprovider", + // C# + "file", "file-write", + // JavaScript + "database-access-result" ] + or + // Swift + this.matches("%string-%length") } } @@ -47,8 +66,10 @@ class ValidSummaryKind extends string { ValidSummaryKind() { this = [ - // shared ALL languages - "taint", "value" + // shared + "taint", "value", + // JavaScript + "type" ] } } @@ -58,8 +79,8 @@ class ValidNeutralKind extends string { ValidNeutralKind() { this = [ - // shared ALL languages - "summary", "source", "sink" + // Java/C# currently + "sink", "source", "summary" ] } } From 9f42ae3f29309b060eaa71834a7a9b5755517be4 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 2 Jun 2023 16:52:20 -0400 Subject: [PATCH 335/739] Shared: remove cpp note --- config/identical-files.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/identical-files.json b/config/identical-files.json index cdda39b041a..800ae570bb8 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -599,7 +599,7 @@ "python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll", "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" ], - "SharedModelValidation Java/C#/Go/JS/Python/Ruby/Swift (C++ is problematic for now)": [ + "SharedModelValidation Java/C#/Go/JS/Python/Ruby/Swift": [ "java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll", "go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll", From 615f2a573b8165d79b00493a8d64fb9d65375dae Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 2 Jun 2023 16:57:24 -0400 Subject: [PATCH 336/739] Java/C#/Go/Swift: remove commented-out code --- .../semmle/code/csharp/dataflow/ExternalFlow.qll | 6 ------ go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 1 - .../lib/semmle/code/java/dataflow/ExternalFlow.qll | 13 ------------- swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll | 1 - 4 files changed, 21 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 902d6f246c9..32c143c6636 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -208,27 +208,21 @@ module ModelValidation { private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSummaryKind and - //not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) or exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSinkKind and - // not kind = - // ["code-injection", "sql-injection", "js-injection", "html-injection", "file-content-store"] and - not kind.matches("encryption-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSourceKind and - //not kind = ["local", "remote", "file", "file-write"] and result = "Invalid kind \"" + kind + "\" in source model." ) or exists(string kind | neutralModel(_, _, _, _, kind, _) | not kind instanceof ValidNeutralKind and - //not kind = ["summary", "source", "sink"] and result = "Invalid kind \"" + kind + "\" in neutral model." ) } diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 05818ab68c7..9b12d3a2b38 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -192,7 +192,6 @@ module ModelValidation { private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSummaryKind and - //not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index b3a128fb4e1..3004910dc3f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -313,22 +313,11 @@ module ModelValidation { private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSummaryKind and - //not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) or exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSinkKind and - // not kind = - // [ - // "request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection", - // "mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection", - // "ognl-injection", "intent-redirection", "pending-intents", "url-redirection", - // "path-injection", "file-content-store", "hostname-verification", "response-splitting", - // "information-leak", "xslt-injection", "jexl-injection", "bean-validation", - // "template-injection", "fragment-injection", "command-injection" - // ] and - not kind.matches("regex-use%") and not kind.matches("qltest%") and msg = "Invalid kind \"" + kind + "\" in sink model." and // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. @@ -339,14 +328,12 @@ module ModelValidation { or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSourceKind and - // not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." ) or exists(string kind | neutralModel(_, _, _, _, kind, _) | not kind instanceof ValidNeutralKind and - //not kind = ["summary", "source", "sink"] and result = "Invalid kind \"" + kind + "\" in neutral model." ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 0adc9be7373..62e785ebf31 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -268,7 +268,6 @@ module CsvValidation { exists(string row, string kind | summaryModel(row) | kind = row.splitAt(";", 8) and not kind instanceof ValidSummaryKind and - //not kind = ["taint", "value"] and result = "Invalid kind \"" + kind + "\" in summary model." ) } From 254e4479234e6af9e9dbf0b27f1cd3ce4192d679 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 2 Jun 2023 17:00:39 -0400 Subject: [PATCH 337/739] JS/Python/Ruby: update getInvalidModelKind --- .../javascript/frameworks/data/internal/ApiGraphModels.qll | 2 -- .../semmle/python/frameworks/data/internal/ApiGraphModels.qll | 2 -- .../lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll | 2 -- 3 files changed, 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index 4799f75937e..dd46283be4b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -663,14 +663,12 @@ module ModelOutput { or exists(string kind | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - not kind.matches("credentials-%") and not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or exists(string kind | sourceModel(_, _, kind) | not kind instanceof ValidSourceKind and - not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." ) } diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index 4799f75937e..dd46283be4b 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -663,14 +663,12 @@ module ModelOutput { or exists(string kind | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - not kind.matches("credentials-%") and not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or exists(string kind | sourceModel(_, _, kind) | not kind instanceof ValidSourceKind and - not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." ) } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index 4799f75937e..dd46283be4b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -663,14 +663,12 @@ module ModelOutput { or exists(string kind | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - not kind.matches("credentials-%") and not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or exists(string kind | sourceModel(_, _, kind) | not kind instanceof ValidSourceKind and - not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." ) } From 76508d17c6487eed6bbbd5674e7a3255e62f9af3 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 2 Jun 2023 18:04:06 -0400 Subject: [PATCH 338/739] Go/Swift: validate source/sink kinds --- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 10 ++++++++++ swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 9b12d3a2b38..ca45d36320e 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -194,6 +194,16 @@ module ModelValidation { not kind instanceof ValidSummaryKind and result = "Invalid kind \"" + kind + "\" in summary model." ) + or + exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | + not kind instanceof ValidSinkKind and + result = "Invalid kind \"" + kind + "\" in sink model." + ) + or + exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | + not kind instanceof ValidSourceKind and + result = "Invalid kind \"" + kind + "\" in source model." + ) } private string getInvalidModelSignature() { diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 62e785ebf31..46085f27568 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -270,6 +270,16 @@ module CsvValidation { not kind instanceof ValidSummaryKind and result = "Invalid kind \"" + kind + "\" in summary model." ) + or + exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | + not kind instanceof ValidSinkKind and + result = "Invalid kind \"" + kind + "\" in sink model." + ) + or + exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | + not kind instanceof ValidSourceKind and + result = "Invalid kind \"" + kind + "\" in source model." + ) } private string getInvalidModelSubtype() { From 7b629f5d63deb67fc8ec10cc7fdf652a4de3bb0e Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 5 Jun 2023 08:23:31 -0400 Subject: [PATCH 339/739] Shared: include 'qltest%' and 'test-%' --- .../code/csharp/dataflow/SharedModelValidation.qll | 12 ++++++++---- .../lib/semmle/go/dataflow/SharedModelValidation.qll | 12 ++++++++---- .../lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 -- .../code/java/dataflow/SharedModelValidation.qll | 12 ++++++++---- .../frameworks/data/internal/ApiGraphModels.qll | 1 - .../data/internal/SharedModelValidation.qll | 12 ++++++++---- .../frameworks/data/internal/ApiGraphModels.qll | 1 - .../data/internal/SharedModelValidation.qll | 12 ++++++++---- .../ruby/frameworks/data/internal/ApiGraphModels.qll | 1 - .../data/internal/SharedModelValidation.qll | 12 ++++++++---- .../codeql/swift/dataflow/SharedModelValidation.qll | 12 ++++++++---- 11 files changed, 56 insertions(+), 33 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll index 5b0105ad554..f38e90257d1 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll @@ -29,7 +29,7 @@ class ValidSinkKind extends string { or this.matches([ // shared - "encryption-%", + "encryption-%", "qltest%", "test-%", // Java-only currently, but may be shared in the future "regex-use%", // JavaScript-only currently, but may be shared in the future @@ -53,11 +53,15 @@ class ValidSourceKind extends string { // C# "file", "file-write", // JavaScript - "database-access-result" + "database-access-result", "remote-flow" ] or - // Swift - this.matches("%string-%length") + this.matches([ + // shared + "qltest%", "test-%", + // Swift + "%string-%length" + ]) } } diff --git a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll index 5b0105ad554..f38e90257d1 100644 --- a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll +++ b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll @@ -29,7 +29,7 @@ class ValidSinkKind extends string { or this.matches([ // shared - "encryption-%", + "encryption-%", "qltest%", "test-%", // Java-only currently, but may be shared in the future "regex-use%", // JavaScript-only currently, but may be shared in the future @@ -53,11 +53,15 @@ class ValidSourceKind extends string { // C# "file", "file-write", // JavaScript - "database-access-result" + "database-access-result", "remote-flow" ] or - // Swift - this.matches("%string-%length") + this.matches([ + // shared + "qltest%", "test-%", + // Swift + "%string-%length" + ]) } } diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 3004910dc3f..2c63d9d37a0 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -318,7 +318,6 @@ module ModelValidation { or exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSinkKind and - not kind.matches("qltest%") and msg = "Invalid kind \"" + kind + "\" in sink model." and // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. if kind instanceof OutdatedSinkKind @@ -328,7 +327,6 @@ module ModelValidation { or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSourceKind and - not kind.matches("qltest%") and result = "Invalid kind \"" + kind + "\" in source model." ) or diff --git a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll index 5b0105ad554..f38e90257d1 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll @@ -29,7 +29,7 @@ class ValidSinkKind extends string { or this.matches([ // shared - "encryption-%", + "encryption-%", "qltest%", "test-%", // Java-only currently, but may be shared in the future "regex-use%", // JavaScript-only currently, but may be shared in the future @@ -53,11 +53,15 @@ class ValidSourceKind extends string { // C# "file", "file-write", // JavaScript - "database-access-result" + "database-access-result", "remote-flow" ] or - // Swift - this.matches("%string-%length") + this.matches([ + // shared + "qltest%", "test-%", + // Swift + "%string-%length" + ]) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index dd46283be4b..b0dd297b6c6 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -663,7 +663,6 @@ module ModelOutput { or exists(string kind | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll index 5b0105ad554..f38e90257d1 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll @@ -29,7 +29,7 @@ class ValidSinkKind extends string { or this.matches([ // shared - "encryption-%", + "encryption-%", "qltest%", "test-%", // Java-only currently, but may be shared in the future "regex-use%", // JavaScript-only currently, but may be shared in the future @@ -53,11 +53,15 @@ class ValidSourceKind extends string { // C# "file", "file-write", // JavaScript - "database-access-result" + "database-access-result", "remote-flow" ] or - // Swift - this.matches("%string-%length") + this.matches([ + // shared + "qltest%", "test-%", + // Swift + "%string-%length" + ]) } } diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index dd46283be4b..b0dd297b6c6 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -663,7 +663,6 @@ module ModelOutput { or exists(string kind | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll index 5b0105ad554..f38e90257d1 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll @@ -29,7 +29,7 @@ class ValidSinkKind extends string { or this.matches([ // shared - "encryption-%", + "encryption-%", "qltest%", "test-%", // Java-only currently, but may be shared in the future "regex-use%", // JavaScript-only currently, but may be shared in the future @@ -53,11 +53,15 @@ class ValidSourceKind extends string { // C# "file", "file-write", // JavaScript - "database-access-result" + "database-access-result", "remote-flow" ] or - // Swift - this.matches("%string-%length") + this.matches([ + // shared + "qltest%", "test-%", + // Swift + "%string-%length" + ]) } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index dd46283be4b..b0dd297b6c6 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -663,7 +663,6 @@ module ModelOutput { or exists(string kind | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - not kind.matches("test-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) or diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll index 5b0105ad554..f38e90257d1 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll @@ -29,7 +29,7 @@ class ValidSinkKind extends string { or this.matches([ // shared - "encryption-%", + "encryption-%", "qltest%", "test-%", // Java-only currently, but may be shared in the future "regex-use%", // JavaScript-only currently, but may be shared in the future @@ -53,11 +53,15 @@ class ValidSourceKind extends string { // C# "file", "file-write", // JavaScript - "database-access-result" + "database-access-result", "remote-flow" ] or - // Swift - this.matches("%string-%length") + this.matches([ + // shared + "qltest%", "test-%", + // Swift + "%string-%length" + ]) } } diff --git a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll index 5b0105ad554..f38e90257d1 100644 --- a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll +++ b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll @@ -29,7 +29,7 @@ class ValidSinkKind extends string { or this.matches([ // shared - "encryption-%", + "encryption-%", "qltest%", "test-%", // Java-only currently, but may be shared in the future "regex-use%", // JavaScript-only currently, but may be shared in the future @@ -53,11 +53,15 @@ class ValidSourceKind extends string { // C# "file", "file-write", // JavaScript - "database-access-result" + "database-access-result", "remote-flow" ] or - // Swift - this.matches("%string-%length") + this.matches([ + // shared + "qltest%", "test-%", + // Swift + "%string-%length" + ]) } } From 76f5dca861d71f1e7cd43e25c109bc09a8ca89a8 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 5 Jun 2023 08:51:55 -0400 Subject: [PATCH 340/739] Shared: move 'OutdatedSinkKind' to shared file and add outdated JS and C# sink kinds --- .../csharp/dataflow/SharedModelValidation.qll | 46 +++++++++++++++++++ .../go/dataflow/SharedModelValidation.qll | 46 +++++++++++++++++++ .../code/java/dataflow/ExternalFlow.qll | 44 ------------------ .../java/dataflow/SharedModelValidation.qll | 46 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 46 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 46 +++++++++++++++++++ .../data/internal/SharedModelValidation.qll | 46 +++++++++++++++++++ .../swift/dataflow/SharedModelValidation.qll | 46 +++++++++++++++++++ 8 files changed, 322 insertions(+), 44 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll index f38e90257d1..e68b8241897 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll @@ -40,6 +40,52 @@ class ValidSinkKind extends string { } } +class OutdatedSinkKind extends string { + OutdatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", + "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", + "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", + "code", "html", "remote" + ] + } + + private string replacementKind() { + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and + result = this + "-injection" + or + this = "url-redirect" and result = "url-redirection" + or + this = "ssti" and result = "template-injection" + or + this = "logging" and result = "log-injection" + or + this = "pending-intent-sent" and result = "pending-intents" + or + this = "intent-start" and result = "intent-redirection" + or + this = "set-hostname-verifier" and result = "hostname-verification" + or + this = "header-splitting" and result = "response-splitting" + or + this = "xss" and result = "html-injection\" or \"js-injection" + or + this = ["write-file", "remote"] and result = "file-content-store" + or + this = ["create-file", "read-file"] and result = "path-injection" + or + this = ["open-url", "jdbc-url"] and result = "request-forgery" + or + this = "command-line-injection" and result = "command-injection" + } + + string outdatedMessage() { + result = + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." + } +} + /** A valid models-as-data source kind. */ class ValidSourceKind extends string { bindingset[this] diff --git a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll index f38e90257d1..e68b8241897 100644 --- a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll +++ b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll @@ -40,6 +40,52 @@ class ValidSinkKind extends string { } } +class OutdatedSinkKind extends string { + OutdatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", + "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", + "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", + "code", "html", "remote" + ] + } + + private string replacementKind() { + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and + result = this + "-injection" + or + this = "url-redirect" and result = "url-redirection" + or + this = "ssti" and result = "template-injection" + or + this = "logging" and result = "log-injection" + or + this = "pending-intent-sent" and result = "pending-intents" + or + this = "intent-start" and result = "intent-redirection" + or + this = "set-hostname-verifier" and result = "hostname-verification" + or + this = "header-splitting" and result = "response-splitting" + or + this = "xss" and result = "html-injection\" or \"js-injection" + or + this = ["write-file", "remote"] and result = "file-content-store" + or + this = ["create-file", "read-file"] and result = "path-injection" + or + this = ["open-url", "jdbc-url"] and result = "request-forgery" + or + this = "command-line-injection" and result = "command-injection" + } + + string outdatedMessage() { + result = + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." + } +} + /** A valid models-as-data source kind. */ class ValidSourceKind extends string { bindingset[this] diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 2c63d9d37a0..77bdf56195e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -266,50 +266,6 @@ module ModelValidation { ) } - private class OutdatedSinkKind extends string { - OutdatedSinkKind() { - this = - [ - "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", - "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", - "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", - "jdbc-url" - ] - } - - private string replacementKind() { - this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap"] and - result = this + "-injection" - or - this = "url-redirect" and result = "url-redirection" - or - this = "ssti" and result = "template-injection" - or - this = "logging" and result = "log-injection" - or - this = "pending-intent-sent" and result = "pending-intents" - or - this = "intent-start" and result = "intent-redirection" - or - this = "set-hostname-verifier" and result = "hostname-verification" - or - this = "header-splitting" and result = "response-splitting" - or - this = "xss" and result = "html-injection\" or \"js-injection" - or - this = "write-file" and result = "file-content-store" - or - this = ["create-file", "read-file"] and result = "path-injection" - or - this = ["open-url", "jdbc-url"] and result = "request-forgery" - } - - string outdatedMessage() { - result = - "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." - } - } - private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSummaryKind and diff --git a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll index f38e90257d1..e68b8241897 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll @@ -40,6 +40,52 @@ class ValidSinkKind extends string { } } +class OutdatedSinkKind extends string { + OutdatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", + "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", + "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", + "code", "html", "remote" + ] + } + + private string replacementKind() { + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and + result = this + "-injection" + or + this = "url-redirect" and result = "url-redirection" + or + this = "ssti" and result = "template-injection" + or + this = "logging" and result = "log-injection" + or + this = "pending-intent-sent" and result = "pending-intents" + or + this = "intent-start" and result = "intent-redirection" + or + this = "set-hostname-verifier" and result = "hostname-verification" + or + this = "header-splitting" and result = "response-splitting" + or + this = "xss" and result = "html-injection\" or \"js-injection" + or + this = ["write-file", "remote"] and result = "file-content-store" + or + this = ["create-file", "read-file"] and result = "path-injection" + or + this = ["open-url", "jdbc-url"] and result = "request-forgery" + or + this = "command-line-injection" and result = "command-injection" + } + + string outdatedMessage() { + result = + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." + } +} + /** A valid models-as-data source kind. */ class ValidSourceKind extends string { bindingset[this] diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll index f38e90257d1..e68b8241897 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll @@ -40,6 +40,52 @@ class ValidSinkKind extends string { } } +class OutdatedSinkKind extends string { + OutdatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", + "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", + "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", + "code", "html", "remote" + ] + } + + private string replacementKind() { + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and + result = this + "-injection" + or + this = "url-redirect" and result = "url-redirection" + or + this = "ssti" and result = "template-injection" + or + this = "logging" and result = "log-injection" + or + this = "pending-intent-sent" and result = "pending-intents" + or + this = "intent-start" and result = "intent-redirection" + or + this = "set-hostname-verifier" and result = "hostname-verification" + or + this = "header-splitting" and result = "response-splitting" + or + this = "xss" and result = "html-injection\" or \"js-injection" + or + this = ["write-file", "remote"] and result = "file-content-store" + or + this = ["create-file", "read-file"] and result = "path-injection" + or + this = ["open-url", "jdbc-url"] and result = "request-forgery" + or + this = "command-line-injection" and result = "command-injection" + } + + string outdatedMessage() { + result = + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." + } +} + /** A valid models-as-data source kind. */ class ValidSourceKind extends string { bindingset[this] diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll index f38e90257d1..e68b8241897 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll @@ -40,6 +40,52 @@ class ValidSinkKind extends string { } } +class OutdatedSinkKind extends string { + OutdatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", + "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", + "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", + "code", "html", "remote" + ] + } + + private string replacementKind() { + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and + result = this + "-injection" + or + this = "url-redirect" and result = "url-redirection" + or + this = "ssti" and result = "template-injection" + or + this = "logging" and result = "log-injection" + or + this = "pending-intent-sent" and result = "pending-intents" + or + this = "intent-start" and result = "intent-redirection" + or + this = "set-hostname-verifier" and result = "hostname-verification" + or + this = "header-splitting" and result = "response-splitting" + or + this = "xss" and result = "html-injection\" or \"js-injection" + or + this = ["write-file", "remote"] and result = "file-content-store" + or + this = ["create-file", "read-file"] and result = "path-injection" + or + this = ["open-url", "jdbc-url"] and result = "request-forgery" + or + this = "command-line-injection" and result = "command-injection" + } + + string outdatedMessage() { + result = + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." + } +} + /** A valid models-as-data source kind. */ class ValidSourceKind extends string { bindingset[this] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll index f38e90257d1..e68b8241897 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll @@ -40,6 +40,52 @@ class ValidSinkKind extends string { } } +class OutdatedSinkKind extends string { + OutdatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", + "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", + "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", + "code", "html", "remote" + ] + } + + private string replacementKind() { + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and + result = this + "-injection" + or + this = "url-redirect" and result = "url-redirection" + or + this = "ssti" and result = "template-injection" + or + this = "logging" and result = "log-injection" + or + this = "pending-intent-sent" and result = "pending-intents" + or + this = "intent-start" and result = "intent-redirection" + or + this = "set-hostname-verifier" and result = "hostname-verification" + or + this = "header-splitting" and result = "response-splitting" + or + this = "xss" and result = "html-injection\" or \"js-injection" + or + this = ["write-file", "remote"] and result = "file-content-store" + or + this = ["create-file", "read-file"] and result = "path-injection" + or + this = ["open-url", "jdbc-url"] and result = "request-forgery" + or + this = "command-line-injection" and result = "command-injection" + } + + string outdatedMessage() { + result = + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." + } +} + /** A valid models-as-data source kind. */ class ValidSourceKind extends string { bindingset[this] diff --git a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll index f38e90257d1..e68b8241897 100644 --- a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll +++ b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll @@ -40,6 +40,52 @@ class ValidSinkKind extends string { } } +class OutdatedSinkKind extends string { + OutdatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", + "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", + "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", + "code", "html", "remote" + ] + } + + private string replacementKind() { + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and + result = this + "-injection" + or + this = "url-redirect" and result = "url-redirection" + or + this = "ssti" and result = "template-injection" + or + this = "logging" and result = "log-injection" + or + this = "pending-intent-sent" and result = "pending-intents" + or + this = "intent-start" and result = "intent-redirection" + or + this = "set-hostname-verifier" and result = "hostname-verification" + or + this = "header-splitting" and result = "response-splitting" + or + this = "xss" and result = "html-injection\" or \"js-injection" + or + this = ["write-file", "remote"] and result = "file-content-store" + or + this = ["create-file", "read-file"] and result = "path-injection" + or + this = ["open-url", "jdbc-url"] and result = "request-forgery" + or + this = "command-line-injection" and result = "command-injection" + } + + string outdatedMessage() { + result = + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." + } +} + /** A valid models-as-data source kind. */ class ValidSourceKind extends string { bindingset[this] From 62ac0dc47108c0424d01621b8876e2792cf092c0 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 5 Jun 2023 09:16:42 -0400 Subject: [PATCH 341/739] Shared: add outdated sink kind msg to 'getInvalidModelKind' for all languages --- .../ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 8 ++++++-- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 8 ++++++-- .../frameworks/data/internal/ApiGraphModels.qll | 8 ++++++-- .../python/frameworks/data/internal/ApiGraphModels.qll | 8 ++++++-- .../ruby/frameworks/data/internal/ApiGraphModels.qll | 8 ++++++-- swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll | 8 ++++++-- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 32c143c6636..5592dbe86c0 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -216,9 +216,13 @@ module ModelValidation { result = "Invalid kind \"" + kind + "\" in sink model." ) or - exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | + exists(string kind, string msg | sourceModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSourceKind and - result = "Invalid kind \"" + kind + "\" in source model." + msg = "Invalid kind \"" + kind + "\" in sink model." and + // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. + if kind instanceof OutdatedSinkKind + then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() + else result = msg ) or exists(string kind | neutralModel(_, _, _, _, kind, _) | diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index ca45d36320e..214e9d93285 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -195,9 +195,13 @@ module ModelValidation { result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | + exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSinkKind and - result = "Invalid kind \"" + kind + "\" in sink model." + msg = "Invalid kind \"" + kind + "\" in sink model." and + // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. + if kind instanceof OutdatedSinkKind + then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() + else result = msg ) or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index b0dd297b6c6..baf732c7d0c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -661,9 +661,13 @@ module ModelOutput { result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string kind | sinkModel(_, _, kind) | + exists(string kind, string msg | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - result = "Invalid kind \"" + kind + "\" in sink model." + msg = "Invalid kind \"" + kind + "\" in sink model." and + // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. + if kind instanceof OutdatedSinkKind + then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() + else result = msg ) or exists(string kind | sourceModel(_, _, kind) | diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index b0dd297b6c6..baf732c7d0c 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -661,9 +661,13 @@ module ModelOutput { result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string kind | sinkModel(_, _, kind) | + exists(string kind, string msg | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - result = "Invalid kind \"" + kind + "\" in sink model." + msg = "Invalid kind \"" + kind + "\" in sink model." and + // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. + if kind instanceof OutdatedSinkKind + then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() + else result = msg ) or exists(string kind | sourceModel(_, _, kind) | diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index b0dd297b6c6..baf732c7d0c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -661,9 +661,13 @@ module ModelOutput { result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string kind | sinkModel(_, _, kind) | + exists(string kind, string msg | sinkModel(_, _, kind) | not kind instanceof ValidSinkKind and - result = "Invalid kind \"" + kind + "\" in sink model." + msg = "Invalid kind \"" + kind + "\" in sink model." and + // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. + if kind instanceof OutdatedSinkKind + then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() + else result = msg ) or exists(string kind | sourceModel(_, _, kind) | diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 46085f27568..77dc65cf746 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -271,9 +271,13 @@ module CsvValidation { result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | + exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSinkKind and - result = "Invalid kind \"" + kind + "\" in sink model." + msg = "Invalid kind \"" + kind + "\" in sink model." and + // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. + if kind instanceof OutdatedSinkKind + then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() + else result = msg ) or exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | From 3f1dc8e5c79ea14f84aba30c0cfda1660a4ed5ce Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 5 Jun 2023 09:21:32 -0400 Subject: [PATCH 342/739] Shared: add outdated Swift sink kinds --- .../semmle/code/csharp/dataflow/SharedModelValidation.qll | 6 +++++- go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll | 6 +++++- .../lib/semmle/code/java/dataflow/SharedModelValidation.qll | 6 +++++- .../frameworks/data/internal/SharedModelValidation.qll | 6 +++++- .../frameworks/data/internal/SharedModelValidation.qll | 6 +++++- .../ruby/frameworks/data/internal/SharedModelValidation.qll | 6 +++++- .../ql/lib/codeql/swift/dataflow/SharedModelValidation.qll | 6 +++++- 7 files changed, 35 insertions(+), 7 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll index e68b8241897..40aad9caef7 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll @@ -47,7 +47,7 @@ class OutdatedSinkKind extends string { "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote" + "code", "html", "remote", "uncontrolled-format-string", "js-eval" ] } @@ -55,6 +55,8 @@ class OutdatedSinkKind extends string { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" or + this = "js-eval" and result = "code-injection" + or this = "url-redirect" and result = "url-redirection" or this = "ssti" and result = "template-injection" @@ -78,6 +80,8 @@ class OutdatedSinkKind extends string { this = ["open-url", "jdbc-url"] and result = "request-forgery" or this = "command-line-injection" and result = "command-injection" + or + this = "uncontrolled-format-string" and result = "format-string" } string outdatedMessage() { diff --git a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll index e68b8241897..40aad9caef7 100644 --- a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll +++ b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll @@ -47,7 +47,7 @@ class OutdatedSinkKind extends string { "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote" + "code", "html", "remote", "uncontrolled-format-string", "js-eval" ] } @@ -55,6 +55,8 @@ class OutdatedSinkKind extends string { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" or + this = "js-eval" and result = "code-injection" + or this = "url-redirect" and result = "url-redirection" or this = "ssti" and result = "template-injection" @@ -78,6 +80,8 @@ class OutdatedSinkKind extends string { this = ["open-url", "jdbc-url"] and result = "request-forgery" or this = "command-line-injection" and result = "command-injection" + or + this = "uncontrolled-format-string" and result = "format-string" } string outdatedMessage() { diff --git a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll index e68b8241897..40aad9caef7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll @@ -47,7 +47,7 @@ class OutdatedSinkKind extends string { "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote" + "code", "html", "remote", "uncontrolled-format-string", "js-eval" ] } @@ -55,6 +55,8 @@ class OutdatedSinkKind extends string { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" or + this = "js-eval" and result = "code-injection" + or this = "url-redirect" and result = "url-redirection" or this = "ssti" and result = "template-injection" @@ -78,6 +80,8 @@ class OutdatedSinkKind extends string { this = ["open-url", "jdbc-url"] and result = "request-forgery" or this = "command-line-injection" and result = "command-injection" + or + this = "uncontrolled-format-string" and result = "format-string" } string outdatedMessage() { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll index e68b8241897..40aad9caef7 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll @@ -47,7 +47,7 @@ class OutdatedSinkKind extends string { "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote" + "code", "html", "remote", "uncontrolled-format-string", "js-eval" ] } @@ -55,6 +55,8 @@ class OutdatedSinkKind extends string { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" or + this = "js-eval" and result = "code-injection" + or this = "url-redirect" and result = "url-redirection" or this = "ssti" and result = "template-injection" @@ -78,6 +80,8 @@ class OutdatedSinkKind extends string { this = ["open-url", "jdbc-url"] and result = "request-forgery" or this = "command-line-injection" and result = "command-injection" + or + this = "uncontrolled-format-string" and result = "format-string" } string outdatedMessage() { diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll index e68b8241897..40aad9caef7 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll @@ -47,7 +47,7 @@ class OutdatedSinkKind extends string { "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote" + "code", "html", "remote", "uncontrolled-format-string", "js-eval" ] } @@ -55,6 +55,8 @@ class OutdatedSinkKind extends string { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" or + this = "js-eval" and result = "code-injection" + or this = "url-redirect" and result = "url-redirection" or this = "ssti" and result = "template-injection" @@ -78,6 +80,8 @@ class OutdatedSinkKind extends string { this = ["open-url", "jdbc-url"] and result = "request-forgery" or this = "command-line-injection" and result = "command-injection" + or + this = "uncontrolled-format-string" and result = "format-string" } string outdatedMessage() { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll index e68b8241897..40aad9caef7 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll @@ -47,7 +47,7 @@ class OutdatedSinkKind extends string { "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote" + "code", "html", "remote", "uncontrolled-format-string", "js-eval" ] } @@ -55,6 +55,8 @@ class OutdatedSinkKind extends string { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" or + this = "js-eval" and result = "code-injection" + or this = "url-redirect" and result = "url-redirection" or this = "ssti" and result = "template-injection" @@ -78,6 +80,8 @@ class OutdatedSinkKind extends string { this = ["open-url", "jdbc-url"] and result = "request-forgery" or this = "command-line-injection" and result = "command-injection" + or + this = "uncontrolled-format-string" and result = "format-string" } string outdatedMessage() { diff --git a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll index e68b8241897..40aad9caef7 100644 --- a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll +++ b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll @@ -47,7 +47,7 @@ class OutdatedSinkKind extends string { "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote" + "code", "html", "remote", "uncontrolled-format-string", "js-eval" ] } @@ -55,6 +55,8 @@ class OutdatedSinkKind extends string { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" or + this = "js-eval" and result = "code-injection" + or this = "url-redirect" and result = "url-redirection" or this = "ssti" and result = "template-injection" @@ -78,6 +80,8 @@ class OutdatedSinkKind extends string { this = ["open-url", "jdbc-url"] and result = "request-forgery" or this = "command-line-injection" and result = "command-injection" + or + this = "uncontrolled-format-string" and result = "format-string" } string outdatedMessage() { From 9d5972acc2a3c84f158e4dd9ca99e9d75f180599 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 5 Jun 2023 12:16:08 -0400 Subject: [PATCH 343/739] Shared: update qldocs --- csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 1 + .../semmle/code/csharp/dataflow/SharedModelValidation.qll | 5 ++++- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 1 + go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll | 5 ++++- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 1 + .../lib/semmle/code/java/dataflow/SharedModelValidation.qll | 5 ++++- .../javascript/frameworks/data/internal/ApiGraphModels.qll | 1 + .../frameworks/data/internal/SharedModelValidation.qll | 5 ++++- .../python/frameworks/data/internal/ApiGraphModels.qll | 1 + .../frameworks/data/internal/SharedModelValidation.qll | 5 ++++- .../codeql/ruby/frameworks/data/internal/ApiGraphModels.qll | 1 + .../ruby/frameworks/data/internal/SharedModelValidation.qll | 5 ++++- swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll | 1 + swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll | 5 ++++- 14 files changed, 35 insertions(+), 7 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 5592dbe86c0..2093646a1f1 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -205,6 +205,7 @@ module ModelValidation { ) } + /** Gets an error message relating to an invalid kind in a model. */ private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSummaryKind and diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll index 40aad9caef7..9d863671941 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes for validating kinds in models as data rows. + * Provides classes and predicates related to validating models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ @@ -40,6 +40,7 @@ class ValidSinkKind extends string { } } +/** An outdated models-as-data sink kind. */ class OutdatedSinkKind extends string { OutdatedSinkKind() { this = @@ -51,6 +52,7 @@ class OutdatedSinkKind extends string { ] } + /** Gets a replacement kind for an outdated sink kind. */ private string replacementKind() { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" @@ -84,6 +86,7 @@ class OutdatedSinkKind extends string { this = "uncontrolled-format-string" and result = "format-string" } + /** Gets an error message for an outdated sink kind. */ string outdatedMessage() { result = "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 214e9d93285..10146aae3b9 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -189,6 +189,7 @@ module ModelValidation { ) } + /** Gets an error message relating to an invalid kind in a model. */ private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSummaryKind and diff --git a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll index 40aad9caef7..9d863671941 100644 --- a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll +++ b/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes for validating kinds in models as data rows. + * Provides classes and predicates related to validating models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ @@ -40,6 +40,7 @@ class ValidSinkKind extends string { } } +/** An outdated models-as-data sink kind. */ class OutdatedSinkKind extends string { OutdatedSinkKind() { this = @@ -51,6 +52,7 @@ class OutdatedSinkKind extends string { ] } + /** Gets a replacement kind for an outdated sink kind. */ private string replacementKind() { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" @@ -84,6 +86,7 @@ class OutdatedSinkKind extends string { this = "uncontrolled-format-string" and result = "format-string" } + /** Gets an error message for an outdated sink kind. */ string outdatedMessage() { result = "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 77bdf56195e..1f6e64d9b76 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -266,6 +266,7 @@ module ModelValidation { ) } + /** Gets an error message relating to an invalid kind in a model. */ private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSummaryKind and diff --git a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll index 40aad9caef7..9d863671941 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes for validating kinds in models as data rows. + * Provides classes and predicates related to validating models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ @@ -40,6 +40,7 @@ class ValidSinkKind extends string { } } +/** An outdated models-as-data sink kind. */ class OutdatedSinkKind extends string { OutdatedSinkKind() { this = @@ -51,6 +52,7 @@ class OutdatedSinkKind extends string { ] } + /** Gets a replacement kind for an outdated sink kind. */ private string replacementKind() { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" @@ -84,6 +86,7 @@ class OutdatedSinkKind extends string { this = "uncontrolled-format-string" and result = "format-string" } + /** Gets an error message for an outdated sink kind. */ string outdatedMessage() { result = "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index baf732c7d0c..fe4fa8c9c2d 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -655,6 +655,7 @@ module ModelOutput { import Specific::ModelOutputSpecific private import SharedModelValidation + /** Gets an error message relating to an invalid kind in a model. */ private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, kind) | not kind instanceof ValidSummaryKind and diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll index 40aad9caef7..9d863671941 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes for validating kinds in models as data rows. + * Provides classes and predicates related to validating models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ @@ -40,6 +40,7 @@ class ValidSinkKind extends string { } } +/** An outdated models-as-data sink kind. */ class OutdatedSinkKind extends string { OutdatedSinkKind() { this = @@ -51,6 +52,7 @@ class OutdatedSinkKind extends string { ] } + /** Gets a replacement kind for an outdated sink kind. */ private string replacementKind() { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" @@ -84,6 +86,7 @@ class OutdatedSinkKind extends string { this = "uncontrolled-format-string" and result = "format-string" } + /** Gets an error message for an outdated sink kind. */ string outdatedMessage() { result = "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index baf732c7d0c..fe4fa8c9c2d 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -655,6 +655,7 @@ module ModelOutput { import Specific::ModelOutputSpecific private import SharedModelValidation + /** Gets an error message relating to an invalid kind in a model. */ private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, kind) | not kind instanceof ValidSummaryKind and diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll index 40aad9caef7..9d863671941 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes for validating kinds in models as data rows. + * Provides classes and predicates related to validating models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ @@ -40,6 +40,7 @@ class ValidSinkKind extends string { } } +/** An outdated models-as-data sink kind. */ class OutdatedSinkKind extends string { OutdatedSinkKind() { this = @@ -51,6 +52,7 @@ class OutdatedSinkKind extends string { ] } + /** Gets a replacement kind for an outdated sink kind. */ private string replacementKind() { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" @@ -84,6 +86,7 @@ class OutdatedSinkKind extends string { this = "uncontrolled-format-string" and result = "format-string" } + /** Gets an error message for an outdated sink kind. */ string outdatedMessage() { result = "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index baf732c7d0c..fe4fa8c9c2d 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -655,6 +655,7 @@ module ModelOutput { import Specific::ModelOutputSpecific private import SharedModelValidation + /** Gets an error message relating to an invalid kind in a model. */ private string getInvalidModelKind() { exists(string kind | summaryModel(_, _, _, _, kind) | not kind instanceof ValidSummaryKind and diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll index 40aad9caef7..9d863671941 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes for validating kinds in models as data rows. + * Provides classes and predicates related to validating models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ @@ -40,6 +40,7 @@ class ValidSinkKind extends string { } } +/** An outdated models-as-data sink kind. */ class OutdatedSinkKind extends string { OutdatedSinkKind() { this = @@ -51,6 +52,7 @@ class OutdatedSinkKind extends string { ] } + /** Gets a replacement kind for an outdated sink kind. */ private string replacementKind() { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" @@ -84,6 +86,7 @@ class OutdatedSinkKind extends string { this = "uncontrolled-format-string" and result = "format-string" } + /** Gets an error message for an outdated sink kind. */ string outdatedMessage() { result = "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 77dc65cf746..1b876790b37 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -264,6 +264,7 @@ module CsvValidation { ) } + /** Gets an error message relating to an invalid kind in a model. */ private string getInvalidModelKind() { exists(string row, string kind | summaryModel(row) | kind = row.splitAt(";", 8) and diff --git a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll index 40aad9caef7..9d863671941 100644 --- a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll +++ b/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes for validating kinds in models as data rows. + * Provides classes and predicates related to validating models as data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ @@ -40,6 +40,7 @@ class ValidSinkKind extends string { } } +/** An outdated models-as-data sink kind. */ class OutdatedSinkKind extends string { OutdatedSinkKind() { this = @@ -51,6 +52,7 @@ class OutdatedSinkKind extends string { ] } + /** Gets a replacement kind for an outdated sink kind. */ private string replacementKind() { this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and result = this + "-injection" @@ -84,6 +86,7 @@ class OutdatedSinkKind extends string { this = "uncontrolled-format-string" and result = "format-string" } + /** Gets an error message for an outdated sink kind. */ string outdatedMessage() { result = "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." From 3cb2ec4e8710bdf159ddc5045c518f0a93934587 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 5 Jun 2023 19:06:07 +0200 Subject: [PATCH 344/739] fix nits from doc review --- javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp index 9ee5158bf99..9fb1f9a39ed 100644 --- a/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp +++ b/javascript/ql/src/Security/CWE-089/SqlInjection.inc.qhelp @@ -38,7 +38,7 @@ an HTTP request handler in a web application, whose parameter </p> <p> -The handler constructs constructs an SQL query string from user input +The handler constructs an SQL query string from user input and executes it as a database query using the <code>pg</code> library. The user input may contain quote characters, so this code is vulnerable to a SQL injection attack. @@ -65,7 +65,7 @@ escape the user input before embedding it into the query string: <example> <p> -In the following example an express handler attempts to delete +In the following example, an express handler attempts to delete a single document from a MongoDB collection. The document to be deleted is identified by its <code>_id</code> field, which is constructed from user input. The user input may contain a query @@ -75,7 +75,7 @@ object, so this code is vulnerable to a NoSQL injection attack. <sample src="examples/NoSqlInjection.js" /> <p> -To fix this vulnerability we can use the <code>$eq</code> operator +To fix this vulnerability, we can use the <code>$eq</code> operator to ensure that the user input is interpreted as a literal value and not as a query object: </p> From 6c46cd9c213351b7c0e63c85c1c956d7ab1a1fde Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 5 Jun 2023 13:11:08 -0400 Subject: [PATCH 345/739] Java/C#/Go/Swift: move 'SharedModelValidation.qll' to internal folder --- config/identical-files.json | 8 ++++---- .../ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 2 +- .../dataflow/{ => internal}/SharedModelValidation.qll | 0 go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 2 +- .../go/dataflow/{ => internal}/SharedModelValidation.qll | 0 java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- .../dataflow/{ => internal}/SharedModelValidation.qll | 0 swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll | 2 +- .../dataflow/{ => internal}/SharedModelValidation.qll | 0 9 files changed, 8 insertions(+), 8 deletions(-) rename csharp/ql/lib/semmle/code/csharp/dataflow/{ => internal}/SharedModelValidation.qll (100%) rename go/ql/lib/semmle/go/dataflow/{ => internal}/SharedModelValidation.qll (100%) rename java/ql/lib/semmle/code/java/dataflow/{ => internal}/SharedModelValidation.qll (100%) rename swift/ql/lib/codeql/swift/dataflow/{ => internal}/SharedModelValidation.qll (100%) diff --git a/config/identical-files.json b/config/identical-files.json index 800ae570bb8..52adf242dda 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -600,10 +600,10 @@ "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" ], "SharedModelValidation Java/C#/Go/JS/Python/Ruby/Swift": [ - "java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll", - "go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll", - "swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll", + "java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll", + "csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll", + "go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll", + "swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll", "javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll", "python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll", "ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll" diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 2093646a1f1..53cb7ead82e 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -95,7 +95,7 @@ private import internal.DataFlowPublic private import internal.FlowSummaryImpl::Public private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific -private import SharedModelValidation +private import internal.SharedModelValidation /** Holds if a source model exists for the given parameters. */ predicate sourceModel = Extensions::sourceModel/9; diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll similarity index 100% rename from csharp/ql/lib/semmle/code/csharp/dataflow/SharedModelValidation.qll rename to csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 10146aae3b9..9dbb826c35a 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -68,7 +68,7 @@ private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific private import internal.AccessPathSyntax private import FlowSummary -private import SharedModelValidation +private import internal.SharedModelValidation /** * A module importing the frameworks that provide external flow data, diff --git a/go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll similarity index 100% rename from go/ql/lib/semmle/go/dataflow/SharedModelValidation.qll rename to go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 1f6e64d9b76..0a838e2fdd9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -87,7 +87,7 @@ private import internal.FlowSummaryImplSpecific as FlowSummaryImplSpecific private import internal.AccessPathSyntax private import ExternalFlowExtensions as Extensions private import FlowSummary -private import SharedModelValidation +private import internal.SharedModelValidation /** * A class for activating additional model rows. diff --git a/java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll similarity index 100% rename from java/ql/lib/semmle/code/java/dataflow/SharedModelValidation.qll rename to java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 1b876790b37..729262deef8 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -74,7 +74,7 @@ private import internal.FlowSummaryImpl::Public private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific private import FlowSummary as FlowSummary -private import SharedModelValidation +private import internal.SharedModelValidation /** * A unit class for adding additional source model rows. diff --git a/swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll similarity index 100% rename from swift/ql/lib/codeql/swift/dataflow/SharedModelValidation.qll rename to swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll From 7a4b74dd6a10ee3dcc507736945f45c0c781e9e8 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 5 Jun 2023 13:21:39 -0400 Subject: [PATCH 346/739] C#: fix typo with outdated sink msg location --- .../lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 53cb7ead82e..28c681e26df 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -212,13 +212,8 @@ module ModelValidation { result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | + exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind instanceof ValidSinkKind and - result = "Invalid kind \"" + kind + "\" in sink model." - ) - or - exists(string kind, string msg | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSourceKind and msg = "Invalid kind \"" + kind + "\" in sink model." and // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. if kind instanceof OutdatedSinkKind @@ -226,6 +221,11 @@ module ModelValidation { else result = msg ) or + exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | + not kind instanceof ValidSourceKind and + result = "Invalid kind \"" + kind + "\" in source model." + ) + or exists(string kind | neutralModel(_, _, _, _, kind, _) | not kind instanceof ValidNeutralKind and result = "Invalid kind \"" + kind + "\" in neutral model." From 5a23421d9a93ca5d0b2ad2c038a85c168c8e126e Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 5 Jun 2023 13:46:56 -0400 Subject: [PATCH 347/739] Shared: minor updates to comments --- .../code/csharp/dataflow/internal/SharedModelValidation.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll | 2 +- .../code/java/dataflow/internal/SharedModelValidation.qll | 2 +- .../javascript/frameworks/data/internal/ApiGraphModels.qll | 2 +- .../frameworks/data/internal/SharedModelValidation.qll | 2 +- .../semmle/python/frameworks/data/internal/ApiGraphModels.qll | 2 +- .../python/frameworks/data/internal/SharedModelValidation.qll | 2 +- .../lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll | 2 +- .../ruby/frameworks/data/internal/SharedModelValidation.qll | 2 +- .../codeql/swift/dataflow/internal/SharedModelValidation.qll | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll index 9d863671941..c322bc62029 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes and predicates related to validating models as data rows. + * Provides classes and predicates related to validating models-as-data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll index 9d863671941..c322bc62029 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes and predicates related to validating models as data rows. + * Provides classes and predicates related to validating models-as-data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll index 9d863671941..c322bc62029 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes and predicates related to validating models as data rows. + * Provides classes and predicates related to validating models-as-data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index fe4fa8c9c2d..10bea158266 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -722,7 +722,7 @@ module ModelOutput { result = "Invalid token '" + token + "' is missing its arguments, in access path: " + path ) or - // Check for valid model kinds + // Check for invalid model kinds result = getInvalidModelKind() } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll index 9d863671941..c322bc62029 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes and predicates related to validating models as data rows. + * Provides classes and predicates related to validating models-as-data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index fe4fa8c9c2d..10bea158266 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -722,7 +722,7 @@ module ModelOutput { result = "Invalid token '" + token + "' is missing its arguments, in access path: " + path ) or - // Check for valid model kinds + // Check for invalid model kinds result = getInvalidModelKind() } } diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll index 9d863671941..c322bc62029 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes and predicates related to validating models as data rows. + * Provides classes and predicates related to validating models-as-data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index fe4fa8c9c2d..10bea158266 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -722,7 +722,7 @@ module ModelOutput { result = "Invalid token '" + token + "' is missing its arguments, in access path: " + path ) or - // Check for valid model kinds + // Check for invalid model kinds result = getInvalidModelKind() } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll index 9d863671941..c322bc62029 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes and predicates related to validating models as data rows. + * Provides classes and predicates related to validating models-as-data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll index 9d863671941..c322bc62029 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll @@ -1,7 +1,7 @@ /** * INTERNAL: Do not use. * - * Provides classes and predicates related to validating models as data rows. + * Provides classes and predicates related to validating models-as-data rows. * Such that we can share this logic across our CodeQL analysis of different languages. */ From d38bca1e8ced5cc0ea684fde4da1ed5291290e85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 04:02:46 +0000 Subject: [PATCH 348/739] Bump regex from 1.8.3 to 1.8.4 in /ql Bumps [regex](https://github.com/rust-lang/regex) from 1.8.3 to 1.8.4. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.8.3...1.8.4) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> --- ql/Cargo.lock | Bin 31667 -> 31667 bytes ql/buramu/Cargo.toml | 2 +- ql/extractor/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/Cargo.lock b/ql/Cargo.lock index de833d37b96bcb4b4ef42188f3f137daa116c0b8..7f62aa9e6773c4f8b6956a331bab55ccd562caf7 100644 GIT binary patch delta 87 zcmV~$!3}^Q3;@8mfKRtDDHIC+O!)fH5h$e#v4{yy;xat-u8*mY>7G-2k8>Buj3tvN p@0m??Ms1EI79p~goid=W6bfpHl8ulN)fzW}fB@RAb?Hy~!VfKL9Si^f delta 88 zcmV~$%ME}a3;@uufJg5RU_#5M<>Y|{bc8~~3J$^|Cb%0%eQ!)Nrg@fZT;J~VfGRez qBt|G2P-8*glndCRmZ5o4mntF=S7{;?1UZmItkEUguYDbF{^$qUdmCl| diff --git a/ql/buramu/Cargo.toml b/ql/buramu/Cargo.toml index 13aaddaf989..3c1c885037e 100644 --- a/ql/buramu/Cargo.toml +++ b/ql/buramu/Cargo.toml @@ -9,4 +9,4 @@ edition = "2018" lazy_static = "1.4.0" chrono = "0.4.26" rayon = "1.7.0" -regex = "1.8.3" +regex = "1.8.4" diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml index f026145c72f..90289b0d688 100644 --- a/ql/extractor/Cargo.toml +++ b/ql/extractor/Cargo.toml @@ -16,5 +16,5 @@ clap = { version = "4.2", features = ["derive"] } tracing = "0.1" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } rayon = "1.7.0" -regex = "1.8.3" +regex = "1.8.4" codeql-extractor = { path = "../../shared/tree-sitter-extractor" } From 1ccec90c6f5d2379f51797d29e2235466894f669 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:10:18 +0200 Subject: [PATCH 349/739] Apply suggestions from code review Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com> --- java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md b/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md index 5f666a0de4f..ae5cd306c2b 100644 --- a/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md +++ b/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kinds `create-file` and `read-file`. +* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`. From 0065e6e1d6efeb95b7a94a79cad40ad4a2a761cf Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 6 Jun 2023 10:04:22 +0200 Subject: [PATCH 350/739] Apply suggestions from code review Fix incorrect models-as-data rows --- java/ql/lib/ext/java.nio.file.model.yml | 6 ++++-- java/ql/lib/ext/java.nio.model.yml | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 475ddc43eef..f27f6a249a1 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -3,9 +3,11 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.nio.file", "Files", False, "copy", "", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[1]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[0]", "file-content-store", "manual"] - - ["java.nio.file", "Files", False, "copy", "", "", "Argument[1]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[1]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "createDirectories", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "createDirectory", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "createFile", "", "", "Argument[0]", "path-injection", "manual"] diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml index 9fbe1b253ec..1548dc2c649 100644 --- a/java/ql/lib/ext/java.nio.model.yml +++ b/java/ql/lib/ext/java.nio.model.yml @@ -6,7 +6,6 @@ extensions: - ["java.nio", "ByteBuffer", False, "array", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio", "ByteBuffer", False, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio", "ByteBuffer", False, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["java.nio", "Paths", False, "get", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # old PathCreation - addsTo: pack: codeql/java-all From 1601846478e04f082886014baf0d7cadfc17a991 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 6 Jun 2023 10:06:06 +0200 Subject: [PATCH 351/739] Add exclusion to the ZipSlip query to avoid FPs --- .../code/java/security/ZipSlipQuery.qll | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 4fad191a3e4..68365db51c2 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -4,6 +4,7 @@ import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.PathSanitizer private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.security.PathCreation /** * A method that returns the name of an archive entry. @@ -40,5 +41,25 @@ module ZipSlipFlow = TaintTracking::Global<ZipSlipConfig>; * A sink that represents a file creation, such as a file write, copy or move operation. */ private class FileCreationSink extends DataFlow::Node { - FileCreationSink() { sinkNode(this, "path-injection") } + FileCreationSink() { + sinkNode(this, "path-injection") and + not isPathCreation(this) + } +} + +/** + * Holds if `sink` is a path creation node that doesn't imply a read/write filesystem operation. + * This is to avoid creating new spurious alerts, since `PathCreation` sinks weren't + * previosuly part of this query. + */ +private predicate isPathCreation(DataFlow::Node sink) { + exists(PathCreation pc | + pc.getAnInput() = sink.asExpr() and + // exclude actual read/write operations included in `PathCreation` + not pc.(Call) + .getCallee() + .getDeclaringType() + .hasQualifiedName("java.io", + ["FileInputStream", "FileOutputStream", "FileReader", "FileWriter"]) + ) } From 72af63457518c54511882d59edaf75257a1dcdcd Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 6 Jun 2023 11:22:16 +0200 Subject: [PATCH 352/739] Kotlin: Add flow through use and with --- java/ql/lib/ext/kotlin.io.model.yml | 2 ++ java/ql/lib/ext/kotlin.model.yml | 7 +++++++ .../kotlin/library-tests/dataflow/summaries/use.kt | 11 +++++++++++ .../kotlin/library-tests/dataflow/summaries/with.kt | 9 +++++++++ 4 files changed, 29 insertions(+) create mode 100644 java/ql/lib/ext/kotlin.model.yml create mode 100644 java/ql/test/kotlin/library-tests/dataflow/summaries/use.kt create mode 100644 java/ql/test/kotlin/library-tests/dataflow/summaries/with.kt diff --git a/java/ql/lib/ext/kotlin.io.model.yml b/java/ql/lib/ext/kotlin.io.model.yml index 98de45df9d6..b748e04a292 100644 --- a/java/ql/lib/ext/kotlin.io.model.yml +++ b/java/ql/lib/ext/kotlin.io.model.yml @@ -11,6 +11,8 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["kotlin.io", "CloseableKt", False, "use", "", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["kotlin.io", "CloseableKt", False, "use", "", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] - ["kotlin.io", "FilesKt", False, "normalize", "(File)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["kotlin.io", "FilesKt", False, "relativeTo", "(File,File)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["kotlin.io", "FilesKt", False, "relativeTo", "(File,File)", "", "Argument[1]", "ReturnValue", "taint", "ai-manual"] diff --git a/java/ql/lib/ext/kotlin.model.yml b/java/ql/lib/ext/kotlin.model.yml new file mode 100644 index 00000000000..ea275a78515 --- /dev/null +++ b/java/ql/lib/ext/kotlin.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["kotlin", "StandardKt", False, "with", "", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] + - ["kotlin", "StandardKt", False, "with", "", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/kotlin/library-tests/dataflow/summaries/use.kt b/java/ql/test/kotlin/library-tests/dataflow/summaries/use.kt new file mode 100644 index 00000000000..07beffd2be2 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/dataflow/summaries/use.kt @@ -0,0 +1,11 @@ +import java.io.Closeable + +class UseFlowTest { + fun <T> taint(t: T) = t + fun sink(s: Closeable) { } + + fun test(input: Closeable) { + taint(input).use { it -> sink(it) } // $ hasValueFlow + sink(taint(input).use { it }) // $ hasValueFlow + } +} diff --git a/java/ql/test/kotlin/library-tests/dataflow/summaries/with.kt b/java/ql/test/kotlin/library-tests/dataflow/summaries/with.kt new file mode 100644 index 00000000000..d495f95c854 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/dataflow/summaries/with.kt @@ -0,0 +1,9 @@ +class WithFlowTest { + fun <T> taint(t: T) = t + fun sink(s: String) { } + + fun test(input: String) { + with(taint(input)) { sink(this) } // $ hasValueFlow + sink(with(taint(input)) { this }) // $ hasValueFlow + } +} From 1d8ca88aca07662a39fc7c20b07548c4c8c26b9c Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 6 Jun 2023 11:25:07 +0200 Subject: [PATCH 353/739] Add change note --- java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md diff --git a/java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md b/java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md new file mode 100644 index 00000000000..b21f31aae5f --- /dev/null +++ b/java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`. From f4fd908f7f38903368ef368996531108435ecbc6 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Tue, 6 Jun 2023 13:01:59 +0200 Subject: [PATCH 354/739] Java: Comment out sinks for which no query exists --- java/ql/lib/ext/java.lang.model.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index a0dc4947fc6..8625a68caa0 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -8,8 +8,9 @@ extensions: - ["java.lang", "ClassLoader", True, "getSystemResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "Runtime", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] - - ["java.lang", "Runtime", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] + # These are potential vulnerabilities, but not for command-injection. No query for this kind of vulnerability currently exists. + # - ["java.lang", "Runtime", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] + # - ["java.lang", "Runtime", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] # These are modeled in plain CodeQL. TODO: migrate them. # - ["java.lang", "ProcessBuilder", False, "command", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"] # - ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-manual"] From 17f9239c334d337c702808016470a85d083e9f92 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Tue, 6 Jun 2023 13:40:06 +0200 Subject: [PATCH 355/739] JS: Fix invalid source kind in test --- javascript/ql/test/library-tests/DataExtensions/Test.expected | 1 + .../ql/test/library-tests/DataExtensions/message.model.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/test/library-tests/DataExtensions/Test.expected b/javascript/ql/test/library-tests/DataExtensions/Test.expected index ba7992e3143..6c82916b357 100644 --- a/javascript/ql/test/library-tests/DataExtensions/Test.expected +++ b/javascript/ql/test/library-tests/DataExtensions/Test.expected @@ -5,3 +5,4 @@ sqlInjectionSinks | connection.example.ts:9:18:9:18 | q | remoteFlowSources | message.example.js:1:46:1:50 | event | +| message.example.js:2:16:2:25 | event.data | diff --git a/javascript/ql/test/library-tests/DataExtensions/message.model.yml b/javascript/ql/test/library-tests/DataExtensions/message.model.yml index 9c575566ce4..40017724aeb 100644 --- a/javascript/ql/test/library-tests/DataExtensions/message.model.yml +++ b/javascript/ql/test/library-tests/DataExtensions/message.model.yml @@ -6,5 +6,5 @@ extensions: - [ "global", "Member[addEventListener].WithStringArgument[0=message].Argument[1].Parameter[0].Member[data]", - "remote-flow", + "remote", ] From 75bc8756f2ec451512a000fb867766ac1de0b8c6 Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Tue, 6 Jun 2023 14:22:56 +0200 Subject: [PATCH 356/739] C#: Change standalone extraction to allow unsafe code --- .../Semmle.Extraction.CSharp.Standalone/Extractor.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs index 97a25d200f7..a9f43af2bea 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Extractor.cs @@ -33,7 +33,9 @@ namespace Semmle.Extraction.CSharp.Standalone CSharp.Extractor.Analyse(stopwatch, analyser, options, references => GetResolvedReferencesStandalone(referencePaths, references), (analyser, syntaxTrees) => CSharp.Extractor.ReadSyntaxTrees(sources, analyser, null, null, syntaxTrees), - (syntaxTrees, references) => CSharpCompilation.Create("csharp.dll", syntaxTrees, references), + (syntaxTrees, references) => CSharpCompilation.Create( + "csharp.dll", syntaxTrees, references, new CSharpCompilationOptions(OutputKind.ConsoleApplication, allowUnsafe: true) + ), (compilation, options) => analyser.Initialize(compilation, options), () => { }, _ => { }, From a4dec591c713e5e92e36e564910c1ea5b4e4c3bd Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Tue, 6 Jun 2023 15:01:54 +0200 Subject: [PATCH 357/739] C#: Improve error message for missing explicit interface implementation --- .../extractor/Semmle.Extraction.CSharp/Entities/Method.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs index 22bf9f69670..8b64df0443e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs @@ -243,7 +243,12 @@ namespace Semmle.Extraction.CSharp.Entities if (methodKind == MethodKind.ExplicitInterfaceImplementation) { // Retrieve the original method kind - methodKind = methodDecl.ExplicitInterfaceImplementations.Select(m => m.MethodKind).FirstOrDefault(); + if (methodDecl.ExplicitInterfaceImplementations.IsEmpty) + { + throw new InternalError(methodDecl, $"Couldn't get the original method kind for explicit interface implementation"); + } + + methodKind = methodDecl.ExplicitInterfaceImplementations.Select(m => m.MethodKind).First(); } switch (methodKind) From ca63122ce46a057fc68d016622bde177c668f271 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Tue, 6 Jun 2023 14:09:55 +0100 Subject: [PATCH 358/739] Kotlin: Relax version requirements If the latest version we know about is 1.9, and we are faced with 1.10, then we try 1.9 rather than failing with an exception. --- java/kotlin-extractor/kotlin_plugin_versions.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/java/kotlin-extractor/kotlin_plugin_versions.py b/java/kotlin-extractor/kotlin_plugin_versions.py index c5d9e433613..bf1c211073a 100755 --- a/java/kotlin-extractor/kotlin_plugin_versions.py +++ b/java/kotlin-extractor/kotlin_plugin_versions.py @@ -24,7 +24,6 @@ def version_string_to_tuple(version): # Version number used by CI. ci_version = '1.8.10' -# Version numbers in the list need to be in semantically increasing order many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20', '1.8.0', '1.9.0-Beta' ] many_versions_tuples = [version_string_to_tuple(v) for v in many_versions] @@ -42,18 +41,13 @@ def get_single_version(fakeVersionOutput = None): if m is None: raise Exception('Cannot detect version of kotlinc (got ' + str(versionOutput) + ')') current_version = version_string_to_tuple(m.group(1)) - matching_minor_versions = [ version for version in many_versions_tuples if version[0:2] == current_version[0:2] ] - if len(matching_minor_versions) == 0: - raise Exception(f'Cannot find a matching minor version for kotlinc version {current_version} (got {versionOutput}; know about {str(many_versions)})') - matching_minor_versions.sort(reverse = True) + many_versions_tuples.sort(reverse = True) - for version in matching_minor_versions: + for version in many_versions_tuples: if version[0:3] <= current_version[0:3]: return version_tuple_to_string(version) - return version_tuple_to_string(matching_minor_versions[-1]) - raise Exception(f'No suitable kotlinc version found for {current_version} (got {versionOutput}; know about {str(many_versions)})') def get_latest_url(): From 2529312d1d0533c1630e0d4f2650856a26f87db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 6 Jun 2023 15:58:19 +0200 Subject: [PATCH 359/739] Codegen: fix test.qlgen failure --- misc/codegen/test/test_qlgen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index 1e68e43c7dc..12d5d28bca6 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -885,7 +885,7 @@ def test_synth_property(generate_classes): schema.Class("MyObject", properties=[ schema.SingleProperty("foo", "bar", synth=True)]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", base_import=gen_import_prefix + "MyObject"), + "MyObject.qll": (a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_objects", synth=True, From e8f56f29817bfa96bcbfeacb02845d1818f27d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Vajk?= <tamasvajk@github.com> Date: Tue, 6 Jun 2023 16:20:48 +0200 Subject: [PATCH 360/739] Update csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs Co-authored-by: Michael B. Gale <mbg@github.com> --- csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs index 8b64df0443e..bae6a2b55ec 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs @@ -245,7 +245,7 @@ namespace Semmle.Extraction.CSharp.Entities // Retrieve the original method kind if (methodDecl.ExplicitInterfaceImplementations.IsEmpty) { - throw new InternalError(methodDecl, $"Couldn't get the original method kind for explicit interface implementation"); + throw new InternalError(methodDecl, $"Couldn't get the original method kind for an explicit interface implementation"); } methodKind = methodDecl.ExplicitInterfaceImplementations.Select(m => m.MethodKind).First(); From 75cbcdd72e8bad639f96447ff2b49cbc134bbf78 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Tue, 6 Jun 2023 16:38:31 +0200 Subject: [PATCH 361/739] Update MaD Declarations after Triage --- java/ql/lib/change-notes/2023-06-06-new-models.md | 15 +++++++++++++++ java/ql/lib/ext/com.alibaba.druid.sql.model.yml | 6 ++++++ .../ext/com.fasterxml.jackson.databind.model.yml | 6 ++++++ java/ql/lib/ext/com.jcraft.jsch.model.yml | 11 +++++++++++ java/ql/lib/ext/io.netty.handler.ssl.model.yml | 2 ++ java/ql/lib/ext/okhttp3.model.yml | 1 + java/ql/lib/ext/org.antlr.runtime.model.yml | 6 ++++++ .../lib/ext/org.fusesource.leveldbjni.model.yml | 6 ++++++ java/ql/lib/ext/org.influxdb.model.yml | 6 ++++++ .../lib/ext/org.springframework.core.io.model.yml | 6 ++++++ java/ql/lib/ext/org.yaml.snakeyaml.model.yml | 6 ++++++ 11 files changed, 71 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-06-06-new-models.md create mode 100644 java/ql/lib/ext/com.alibaba.druid.sql.model.yml create mode 100644 java/ql/lib/ext/com.jcraft.jsch.model.yml create mode 100644 java/ql/lib/ext/org.antlr.runtime.model.yml create mode 100644 java/ql/lib/ext/org.fusesource.leveldbjni.model.yml create mode 100644 java/ql/lib/ext/org.influxdb.model.yml create mode 100644 java/ql/lib/ext/org.springframework.core.io.model.yml create mode 100644 java/ql/lib/ext/org.yaml.snakeyaml.model.yml diff --git a/java/ql/lib/change-notes/2023-06-06-new-models.md b/java/ql/lib/change-notes/2023-06-06-new-models.md new file mode 100644 index 00000000000..cbb80968749 --- /dev/null +++ b/java/ql/lib/change-notes/2023-06-06-new-models.md @@ -0,0 +1,15 @@ +--- +category: minorAnalysis +--- +* Added models for the following packages: + + * com.alibaba.druid.sql + * com.fasterxml.jackson.databind + * com.jcraft.jsch + * io.netty.handler.ssl + * okhttp3 + * org.antlr.runtime + * org.fusesource.leveldbjni + * org.influxdb + * org.springframework.core.io + * org.yaml.snakeyaml diff --git a/java/ql/lib/ext/com.alibaba.druid.sql.model.yml b/java/ql/lib/ext/com.alibaba.druid.sql.model.yml new file mode 100644 index 00000000000..952cd6e8f1b --- /dev/null +++ b/java/ql/lib/ext/com.alibaba.druid.sql.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.alibaba.druid.sql", "SQLUtils", False, "toMySqlString", "(SQLObject)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] diff --git a/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml b/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml index 3768007ebe7..988820e84dd 100644 --- a/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml +++ b/java/ql/lib/ext/com.fasterxml.jackson.databind.model.yml @@ -9,3 +9,9 @@ extensions: - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "valueToTree", "", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"] - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "valueToTree", "", "", "Argument[0].MapValue.Element", "ReturnValue", "taint", "manual"] - ["com.fasterxml.jackson.databind", "ObjectReader", False, "createParser", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "readValue", "(File,Class)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.fasterxml.jackson.databind", "ObjectMapper", True, "writeValue", "(File,Object)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/com.jcraft.jsch.model.yml b/java/ql/lib/ext/com.jcraft.jsch.model.yml new file mode 100644 index 00000000000..3d658630d56 --- /dev/null +++ b/java/ql/lib/ext/com.jcraft.jsch.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.jcraft.jsch", "JSch", True, "getSession", "(String,String,int)", "", "Argument[1]", "request-forgery", "ai-manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.jcraft.jsch", "ChannelSftp", True, "realpath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] diff --git a/java/ql/lib/ext/io.netty.handler.ssl.model.yml b/java/ql/lib/ext/io.netty.handler.ssl.model.yml index 42cf9892f81..f63a7a3906f 100644 --- a/java/ql/lib/ext/io.netty.handler.ssl.model.yml +++ b/java/ql/lib/ext/io.netty.handler.ssl.model.yml @@ -5,3 +5,5 @@ extensions: data: - ["io.netty.handler.ssl", "OpenSslServerContext", False, "OpenSslServerContext", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["io.netty.handler.ssl", "SslContextBuilder", False, "forServer", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["io.netty.handler.ssl", "SslContextBuilder", False, "trustManager", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["io.netty.handler.ssl", "SslContextBuilder", False, "trustManager", "(InputStream)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/okhttp3.model.yml b/java/ql/lib/ext/okhttp3.model.yml index 2368292dab7..b7bfe8a10f7 100644 --- a/java/ql/lib/ext/okhttp3.model.yml +++ b/java/ql/lib/ext/okhttp3.model.yml @@ -58,3 +58,4 @@ extensions: - ["okhttp3", "HttpUrl$Builder", False, "setQueryParameter", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["okhttp3", "HttpUrl$Builder", False, "setQueryParameter", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["okhttp3", "HttpUrl$Builder", False, "username", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["okhttp3", "Request$Builder", True, "build", "()", "", "Argument[undefined]", "ReturnValue", "taint", "ai-manual"] diff --git a/java/ql/lib/ext/org.antlr.runtime.model.yml b/java/ql/lib/ext/org.antlr.runtime.model.yml new file mode 100644 index 00000000000..db66062c682 --- /dev/null +++ b/java/ql/lib/ext/org.antlr.runtime.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.antlr.runtime", "ANTLRFileStream", True, "ANTLRFileStream", "(String,String)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.fusesource.leveldbjni.model.yml b/java/ql/lib/ext/org.fusesource.leveldbjni.model.yml new file mode 100644 index 00000000000..2c3f221abd7 --- /dev/null +++ b/java/ql/lib/ext/org.fusesource.leveldbjni.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.fusesource.leveldbjni", "JniDBFactory", True, "open", "(File,Options)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/org.influxdb.model.yml b/java/ql/lib/ext/org.influxdb.model.yml new file mode 100644 index 00000000000..00dc8277407 --- /dev/null +++ b/java/ql/lib/ext/org.influxdb.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.influxdb", "InfluxDBFactory", False, "connect", "(String,String,String,Builder)", "", "Argument[0]", "request-forgery", "ai-manual"] diff --git a/java/ql/lib/ext/org.springframework.core.io.model.yml b/java/ql/lib/ext/org.springframework.core.io.model.yml new file mode 100644 index 00000000000..7f3f3718471 --- /dev/null +++ b/java/ql/lib/ext/org.springframework.core.io.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["org.springframework.core.io", "ResourceLoader", True, "getResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] # todo: look into whether this may also be a request forgery sink diff --git a/java/ql/lib/ext/org.yaml.snakeyaml.model.yml b/java/ql/lib/ext/org.yaml.snakeyaml.model.yml new file mode 100644 index 00000000000..e52ef0679bc --- /dev/null +++ b/java/ql/lib/ext/org.yaml.snakeyaml.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.yaml.snakeyaml", "Yaml", True, "load", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] From 0f010afce10584d2b03bef3921162f6ce1461b36 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 6 Jun 2023 16:53:26 +0200 Subject: [PATCH 362/739] C#: Add dotnet test that targets dll. --- csharp/ql/integration-tests/posix-only/dotnet_test/test.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/test.py b/csharp/ql/integration-tests/posix-only/dotnet_test/test.py index 7bc159e6720..1012454003b 100644 --- a/csharp/ql/integration-tests/posix-only/dotnet_test/test.py +++ b/csharp/ql/integration-tests/posix-only/dotnet_test/test.py @@ -1,5 +1,10 @@ from create_database_utils import * from diagnostics_test_utils import * -run_codeql_database_create(['dotnet test'], db=None, lang="csharp") +# Implicitly build and then run tests. +run_codeql_database_create(['dotnet test'], test_db="test-db", lang="csharp") check_diagnostics() + +# Explicitly build and then run tests. +run_codeql_database_create(['dotnet clean', 'rm -rf test-db', 'dotnet build -o myout', 'dotnet test myout/dotnet_test.dll'], test_db="test2-db", lang="csharp") +check_diagnostics(test_db="test2-db") \ No newline at end of file From 387cde5972e29bcc1787b72325ef60476dc27f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 23 May 2023 15:42:37 +0200 Subject: [PATCH 363/739] Swift: add BraceStmt.getVariable(_) child with logic in QL. --- .../codeql/swift/elements/stmt/BraceStmt.qll | 19 +++++++++++++++++++ swift/schema.py | 1 + 2 files changed, 20 insertions(+) diff --git a/swift/ql/lib/codeql/swift/elements/stmt/BraceStmt.qll b/swift/ql/lib/codeql/swift/elements/stmt/BraceStmt.qll index 7922c1fb47f..87bbfac8528 100644 --- a/swift/ql/lib/codeql/swift/elements/stmt/BraceStmt.qll +++ b/swift/ql/lib/codeql/swift/elements/stmt/BraceStmt.qll @@ -11,4 +11,23 @@ class BraceStmt extends Generated::BraceStmt { } override string toString() { result = "{ ... }" } + + override AstNode getImmediateElement(int index) { + result = + rank[index + 1](AstNode element, int i | + element = super.getImmediateElement(i) and + not element instanceof VarDecl + | + element order by i + ) + } + + override VarDecl getVariable(int index) { + result = + rank[index + 1](VarDecl variable, int i | + variable = super.getImmediateElement(i) + | + variable order by i + ) + } } diff --git a/swift/schema.py b/swift/schema.py index 3af02367d8a..36b667c4131 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -935,6 +935,7 @@ class StmtCondition(AstNode): elements: list[ConditionElement] | child class BraceStmt(Stmt): + variables: list[VarDecl] | child | doc("variable declared in the scope of this brace statement") elements: list[AstNode] | child class BreakStmt(Stmt): From 026492836c13d947280fca2dad574ef444a6888c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 23 May 2023 15:43:15 +0200 Subject: [PATCH 364/739] Swift: codegen --- swift/ql/.generated.list | 6 +++--- .../codeql/swift/generated/ParentChild.qll | 12 +++++++---- swift/ql/lib/codeql/swift/generated/Raw.qll | 5 +++++ .../codeql/swift/generated/stmt/BraceStmt.qll | 21 +++++++++++++++++++ swift/ql/lib/swift.dbscheme | 7 +++++++ 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 3fac0083642..bc1a195b178 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -380,10 +380,10 @@ lib/codeql/swift/generated/KeyPathComponent.qll c79c7bc04fc1426992ab472eedc1a20a lib/codeql/swift/generated/Locatable.qll be20967d48a34cdba126fe298606e0adc11697831f097acba9c52a0b7ce9983e 8aa01bc376614abbc3209e25785c72f86c9b4e94bb5f471a4a0677fedaec4f61 lib/codeql/swift/generated/Location.qll c5793987e77812059a28254dadee29bfe9b38153c0399fbb1bf6a2f5c237fdab 6e6d8802b021e36bbaad81845657769dd48a798ea33080ada05e9818a20b38f7 lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 -lib/codeql/swift/generated/ParentChild.qll 5c5ff9812efbed0adf465d1c8b9108c893c77ff946f6feaaec7223ad38664079 94038dcd8a5e98b959ce9f09b7b54b745b0df49b91339b9396017a209abe8bb7 +lib/codeql/swift/generated/ParentChild.qll f8647fba02b9acca7bf2870dfaee5709e2d3e3a12d27b012dd1e17f7df2e56e5 75d3501c2a59d931dd537321475687a73ff517e5caaae4ce2e0c2daec0d94df4 lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 991f95f30bde82ba43237bd9c1a68d3f450038ef828edb89219fbf583dd1956a e3e6c41caac09d532453c28167622fae7057d846f35750873eacd48cd128b957 +lib/codeql/swift/generated/Raw.qll e665a9c74c1d2926fdfafb2fda8bf428fc72b0b1afbf472f304b1a925bee9f09 c361be3af00814c13f35666881aed32327662495d1fe4bd5a4b5c1f481986a5b lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -566,7 +566,7 @@ lib/codeql/swift/generated/pattern/ParenPattern.qll 337cb03dcb7384f7ef13e35d843b lib/codeql/swift/generated/pattern/Pattern.qll 0e96528a8dd87185f4fb23ba33ea418932762127e99739d7e56e5c8988e024d1 ba1e010c9f7f891048fb8c4ff8ea5a6c664c09e43d74b860d559f6459f82554a lib/codeql/swift/generated/pattern/TuplePattern.qll b3a138b0942f7e3eecb52ad2f095584a6cd5f555e9487c6eaad6a5527ae99f0c d6ff67ecc7395571acef4b82da514cb737c72d97ea557d89da534469feda340c lib/codeql/swift/generated/pattern/TypedPattern.qll 6a9fd2815755eddc6918d6be8221c7afb90e4fba4fcb8eb54ff42754269bb481 f198c3b09553a5f5f3d97f8088ef82c00552b9635560750c56d801b09dbd9e26 -lib/codeql/swift/generated/stmt/BraceStmt.qll eea1a33767c14a3b96aea6bbe10f17c3ecd1d8ac263de07e475e23b46d85a20d a5ee6c19a38e968c245886c28c82513f39ca90a80a9ea11d0e3139a35f682046 +lib/codeql/swift/generated/stmt/BraceStmt.qll 9d2b2a2127fb245f10e554c6a9fa31280a30081ebc93d9802a55c334534341d6 e5bfffc41258886dd516ab51cfb7a2c27ef725edff6b29c2f552e9661dab0a35 lib/codeql/swift/generated/stmt/BreakStmt.qll 879cf66911cc7f53e7e8f4ae8244681018fb17d6501b269fb7cf9d8481f0b539 c78fc1b0e3e76321fc1653aa8b0aabaaacf082e01a003b78f693b106cc05faa0 lib/codeql/swift/generated/stmt/CaseLabelItem.qll 9536d2909a274c3a969eec25f8e5966adfaa9b0d6451ea6319d9f7bb2fd6fe07 02e25f036db50e9a6e9a7ceab6002dd605b73afb55fa1dee6f22e7af33a40913 lib/codeql/swift/generated/stmt/CaseStmt.qll c180478c6161439bc76bd39edfab343faba7450900ffedcadd3ccea12dc3a08c b537eb517db76113cfbc91c59e6bdfbf16ff83d639dfe6fd6892171f71a97090 diff --git a/swift/ql/lib/codeql/swift/generated/ParentChild.qll b/swift/ql/lib/codeql/swift/generated/ParentChild.qll index c2b8b7f38c4..8a91ccc7b82 100644 --- a/swift/ql/lib/codeql/swift/generated/ParentChild.qll +++ b/swift/ql/lib/codeql/swift/generated/ParentChild.qll @@ -3434,18 +3434,22 @@ private module Impl { } private Element getImmediateChildOfBraceStmt(BraceStmt e, int index, string partialPredicateCall) { - exists(int b, int bStmt, int n, int nElement | + exists(int b, int bStmt, int n, int nVariable, int nElement | b = 0 and bStmt = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfStmt(e, i, _)) | i) and n = bStmt and - nElement = n + 1 + max(int i | i = -1 or exists(e.getImmediateElement(i)) | i) and + nVariable = n + 1 + max(int i | i = -1 or exists(e.getVariable(i)) | i) and + nElement = nVariable + 1 + max(int i | i = -1 or exists(e.getImmediateElement(i)) | i) and ( none() or result = getImmediateChildOfStmt(e, index - b, partialPredicateCall) or - result = e.getImmediateElement(index - n) and - partialPredicateCall = "Element(" + (index - n).toString() + ")" + result = e.getVariable(index - n) and + partialPredicateCall = "Variable(" + (index - n).toString() + ")" + or + result = e.getImmediateElement(index - nVariable) and + partialPredicateCall = "Element(" + (index - nVariable).toString() + ")" ) ) } diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index 38e84cd3093..6dd726c6b27 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -2569,6 +2569,11 @@ module Raw { class BraceStmt extends @brace_stmt, Stmt { override string toString() { result = "BraceStmt" } + /** + * Gets the `index`th variable declared in the scope of this brace statement (0-based). + */ + VarDecl getVariable(int index) { brace_stmt_variables(this, index, result) } + /** * Gets the `index`th element of this brace statement (0-based). */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll index d136e02df08..319945162a9 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll @@ -3,11 +3,32 @@ private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw import codeql.swift.elements.AstNode import codeql.swift.elements.stmt.Stmt +import codeql.swift.elements.decl.VarDecl module Generated { class BraceStmt extends Synth::TBraceStmt, Stmt { override string getAPrimaryQlClass() { result = "BraceStmt" } + /** + * Gets the `index`th variable declared in the scope of this brace statement (0-based). + */ + VarDecl getVariable(int index) { + result = + Synth::convertVarDeclFromRaw(Synth::convertBraceStmtToRaw(this) + .(Raw::BraceStmt) + .getVariable(index)) + } + + /** + * Gets any of the variables declared in the scope of this brace statement. + */ + final VarDecl getAVariable() { result = this.getVariable(_) } + + /** + * Gets the number of variables declared in the scope of this brace statement. + */ + final int getNumberOfVariables() { result = count(int i | exists(this.getVariable(i))) } + /** * Gets the `index`th element of this brace statement (0-based). * diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 44e36e15e90..b8cc77513a6 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -1768,6 +1768,13 @@ brace_stmts( //dir=stmt unique int id: @brace_stmt ); +#keyset[id, index] +brace_stmt_variables( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + #keyset[id, index] brace_stmt_elements( //dir=stmt int id: @brace_stmt ref, From 8ccbad601bf62acd6ef206c9acaf204b07dcf051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 6 Jun 2023 15:37:26 +0200 Subject: [PATCH 365/739] Swift: PrintAst test changes --- .../decl/CapturedDecl/PrintAst.expected | 236 +++--- .../test/library-tests/ast/PrintAst.expected | 688 +++++++++--------- .../expr/methodlookup/PrintAst.expected | 48 +- 3 files changed, 486 insertions(+), 486 deletions(-) diff --git a/swift/ql/test/extractor-tests/generated/decl/CapturedDecl/PrintAst.expected b/swift/ql/test/extractor-tests/generated/decl/CapturedDecl/PrintAst.expected index 7e7f62e9471..110895e79ff 100644 --- a/swift/ql/test/extractor-tests/generated/decl/CapturedDecl/PrintAst.expected +++ b/swift/ql/test/extractor-tests/generated/decl/CapturedDecl/PrintAst.expected @@ -7,12 +7,12 @@ closures.swift: # 5| [NamedFunction] captureList() # 5| InterfaceType = () -> () # 5| getBody(): [BraceStmt] { ... } +# 6| getVariable(0): [ConcreteVarDecl] y +# 6| Type = Int # 6| getElement(0): [PatternBindingDecl] var ... = ... # 6| getInit(0): [IntegerLiteralExpr] 123 # 6| getPattern(0): [NamedPattern] y -# 6| getElement(1): [ConcreteVarDecl] y -# 6| Type = Int -# 7| getElement(2): [CallExpr] call to ... +# 7| getElement(1): [CallExpr] call to ... # 7| getFunction(): [CaptureListExpr] { ... } # 7| getBindingDecl(0): [PatternBindingDecl] var ... = ... # 7| getInit(0): [CallExpr] call to hello() @@ -58,12 +58,12 @@ closures.swift: # 14| [NamedFunction] setEscape() # 14| InterfaceType = () -> () # 14| getBody(): [BraceStmt] { ... } +# 15| getVariable(0): [ConcreteVarDecl] x +# 15| Type = Int # 15| getElement(0): [PatternBindingDecl] var ... = ... # 15| getInit(0): [IntegerLiteralExpr] 0 # 15| getPattern(0): [NamedPattern] x -# 15| getElement(1): [ConcreteVarDecl] x -# 15| Type = Int -# 16| getElement(2): [AssignExpr] ... = ... +# 16| getElement(1): [AssignExpr] ... = ... # 16| getDest(): [DeclRefExpr] escape # 16| getSource(): [ExplicitClosureExpr] { ... } # 16| getBody(): [BraceStmt] { ... } @@ -107,6 +107,10 @@ closures.swift: # 27| [NamedFunction] logical() # 27| InterfaceType = () -> Bool # 27| getBody(): [BraceStmt] { ... } +# 28| getVariable(0): [ConcreteVarDecl] f +# 28| Type = ((Int) -> Int)? +# 29| getVariable(1): [ConcreteVarDecl] x +# 29| Type = Int? # 28| getElement(0): [PatternBindingDecl] var ... = ... # 28| getInit(0): [ExplicitClosureExpr] { ... } # 28| getParam(0): [ParamDecl] x @@ -126,17 +130,13 @@ closures.swift: # 28| getPattern(0): [TypedPattern] ... as ... # 28| getSubPattern(): [NamedPattern] f # 28| getTypeRepr(): [TypeRepr] ((Int) -> Int)? -# 28| getElement(1): [ConcreteVarDecl] f -# 28| Type = ((Int) -> Int)? -# 29| getElement(2): [PatternBindingDecl] var ... = ... +# 29| getElement(1): [PatternBindingDecl] var ... = ... # 29| getInit(0): [IntegerLiteralExpr] 42 # 29| getInit(0).getFullyConverted(): [InjectIntoOptionalExpr] (Int?) ... # 29| getPattern(0): [TypedPattern] ... as ... # 29| getSubPattern(): [NamedPattern] x # 29| getTypeRepr(): [TypeRepr] Int? -# 29| getElement(3): [ConcreteVarDecl] x -# 29| Type = Int? -# 30| getElement(4): [ReturnStmt] return ... +# 30| getElement(2): [ReturnStmt] return ... # 30| getResult(): [BinaryExpr] ... .&&(_:_:) ... # 31| getFunction(): [MethodLookupExpr] .&&(_:_:) # 31| getBase(): [TypeExpr] Bool.Type @@ -272,12 +272,16 @@ closures.swift: # 50| [NamedFunction] foo() # 50| InterfaceType = () -> Int # 50| getBody(): [BraceStmt] { ... } +# 51| getVariable(0): [ConcreteVarDecl] x +# 51| Type = Int +# 52| getVariable(1): [ConcreteVarDecl] f +# 52| Type = (Int) -> () +# 54| getVariable(2): [ConcreteVarDecl] r +# 54| Type = () -> Int # 51| getElement(0): [PatternBindingDecl] var ... = ... # 51| getInit(0): [IntegerLiteralExpr] 1 # 51| getPattern(0): [NamedPattern] x -# 51| getElement(1): [ConcreteVarDecl] x -# 51| Type = Int -# 52| getElement(2): [PatternBindingDecl] var ... = ... +# 52| getElement(1): [PatternBindingDecl] var ... = ... # 52| getInit(0): [ExplicitClosureExpr] { ... } # 52| getParam(0): [ParamDecl] y # 52| Type = Int @@ -295,9 +299,7 @@ closures.swift: # 52| getExpr(): [DeclRefExpr] y # 52| getCapture(0): [CapturedDecl] x # 52| getPattern(0): [NamedPattern] f -# 52| getElement(3): [ConcreteVarDecl] f -# 52| Type = (Int) -> () -# 53| getElement(4): [BinaryExpr] ... .+=(_:_:) ... +# 53| getElement(2): [BinaryExpr] ... .+=(_:_:) ... # 53| getFunction(): [MethodLookupExpr] .+=(_:_:) # 53| getBase(): [TypeExpr] Int.Type # 53| getTypeRepr(): [TypeRepr] Int @@ -307,7 +309,7 @@ closures.swift: # 53| getSubExpr(): [DeclRefExpr] x # 53| getArgument(1): [Argument] : 40 # 53| getExpr(): [IntegerLiteralExpr] 40 -# 54| getElement(5): [PatternBindingDecl] var ... = ... +# 54| getElement(3): [PatternBindingDecl] var ... = ... # 54| getInit(0): [ExplicitClosureExpr] { ... } # 54| getBody(): [BraceStmt] { ... } # 54| getElement(0): [ReturnStmt] return ... @@ -315,13 +317,11 @@ closures.swift: # 54| getResult().getFullyConverted(): [LoadExpr] (Int) ... # 54| getCapture(0): [CapturedDecl] x # 54| getPattern(0): [NamedPattern] r -# 54| getElement(6): [ConcreteVarDecl] r -# 54| Type = () -> Int -# 55| getElement(7): [CallExpr] call to ... +# 55| getElement(4): [CallExpr] call to ... # 55| getFunction(): [DeclRefExpr] f # 55| getArgument(0): [Argument] : 1 # 55| getExpr(): [IntegerLiteralExpr] 1 -# 56| getElement(8): [ReturnStmt] return ... +# 56| getElement(5): [ReturnStmt] return ... # 56| getResult(): [CallExpr] call to ... # 56| getFunction(): [DeclRefExpr] r # 51| [Comment] // x is a non-escaping capture of f and r @@ -331,12 +331,16 @@ closures.swift: # 59| [NamedFunction] bar() # 59| InterfaceType = () -> () -> Int # 59| getBody(): [BraceStmt] { ... } +# 60| getVariable(0): [ConcreteVarDecl] x +# 60| Type = Int +# 61| getVariable(1): [ConcreteVarDecl] f +# 61| Type = (Int) -> () +# 63| getVariable(2): [ConcreteVarDecl] r +# 63| Type = () -> Int # 60| getElement(0): [PatternBindingDecl] var ... = ... # 60| getInit(0): [IntegerLiteralExpr] 1 # 60| getPattern(0): [NamedPattern] x -# 60| getElement(1): [ConcreteVarDecl] x -# 60| Type = Int -# 61| getElement(2): [PatternBindingDecl] var ... = ... +# 61| getElement(1): [PatternBindingDecl] var ... = ... # 61| getInit(0): [ExplicitClosureExpr] { ... } # 61| getParam(0): [ParamDecl] y # 61| Type = Int @@ -354,9 +358,7 @@ closures.swift: # 61| getExpr(): [DeclRefExpr] y # 61| getCapture(0): [CapturedDecl] x # 61| getPattern(0): [NamedPattern] f -# 61| getElement(3): [ConcreteVarDecl] f -# 61| Type = (Int) -> () -# 62| getElement(4): [BinaryExpr] ... .+=(_:_:) ... +# 62| getElement(2): [BinaryExpr] ... .+=(_:_:) ... # 62| getFunction(): [MethodLookupExpr] .+=(_:_:) # 62| getBase(): [TypeExpr] Int.Type # 62| getTypeRepr(): [TypeRepr] Int @@ -366,7 +368,7 @@ closures.swift: # 62| getSubExpr(): [DeclRefExpr] x # 62| getArgument(1): [Argument] : 40 # 62| getExpr(): [IntegerLiteralExpr] 40 -# 63| getElement(5): [PatternBindingDecl] var ... = ... +# 63| getElement(3): [PatternBindingDecl] var ... = ... # 63| getInit(0): [ExplicitClosureExpr] { ... } # 63| getBody(): [BraceStmt] { ... } # 63| getElement(0): [ReturnStmt] return ... @@ -374,13 +376,11 @@ closures.swift: # 63| getResult().getFullyConverted(): [LoadExpr] (Int) ... # 63| getCapture(0): [CapturedDecl] x # 63| getPattern(0): [NamedPattern] r -# 63| getElement(6): [ConcreteVarDecl] r -# 63| Type = () -> Int -# 64| getElement(7): [CallExpr] call to ... +# 64| getElement(4): [CallExpr] call to ... # 64| getFunction(): [DeclRefExpr] f # 64| getArgument(0): [Argument] : 1 # 64| getExpr(): [IntegerLiteralExpr] 1 -# 65| getElement(8): [ReturnStmt] return ... +# 65| getElement(5): [ReturnStmt] return ... # 65| getResult(): [DeclRefExpr] r # 60| [Comment] // x is a non-escaping capture of f, escaping capture of r # 60| @@ -398,12 +398,14 @@ closures.swift: # 69| [NamedFunction] baz() # 69| InterfaceType = () -> () -> Int # 69| getBody(): [BraceStmt] { ... } +# 70| getVariable(0): [ConcreteVarDecl] x +# 70| Type = Int +# 73| getVariable(1): [ConcreteVarDecl] r +# 73| Type = () -> Int # 70| getElement(0): [PatternBindingDecl] var ... = ... # 70| getInit(0): [IntegerLiteralExpr] 1 # 70| getPattern(0): [NamedPattern] x -# 70| getElement(1): [ConcreteVarDecl] x -# 70| Type = Int -# 71| getElement(2): [AssignExpr] ... = ... +# 71| getElement(1): [AssignExpr] ... = ... # 71| getDest(): [DeclRefExpr] g # 71| getSource(): [ExplicitClosureExpr] { ... } # 71| getParam(0): [ParamDecl] y @@ -422,7 +424,7 @@ closures.swift: # 71| getExpr(): [DeclRefExpr] y # 71| getCapture(0): [CapturedDecl] x # 71| getSource().getFullyConverted(): [InjectIntoOptionalExpr] (((Int) -> Void)?) ... -# 72| getElement(3): [BinaryExpr] ... .+=(_:_:) ... +# 72| getElement(2): [BinaryExpr] ... .+=(_:_:) ... # 72| getFunction(): [MethodLookupExpr] .+=(_:_:) # 72| getBase(): [TypeExpr] Int.Type # 72| getTypeRepr(): [TypeRepr] Int @@ -432,7 +434,7 @@ closures.swift: # 72| getSubExpr(): [DeclRefExpr] x # 72| getArgument(1): [Argument] : 40 # 72| getExpr(): [IntegerLiteralExpr] 40 -# 73| getElement(4): [PatternBindingDecl] var ... = ... +# 73| getElement(3): [PatternBindingDecl] var ... = ... # 73| getInit(0): [ExplicitClosureExpr] { ... } # 73| getBody(): [BraceStmt] { ... } # 73| getElement(0): [ReturnStmt] return ... @@ -440,15 +442,13 @@ closures.swift: # 73| getResult().getFullyConverted(): [LoadExpr] (Int) ... # 73| getCapture(0): [CapturedDecl] x # 73| getPattern(0): [NamedPattern] r -# 73| getElement(5): [ConcreteVarDecl] r -# 73| Type = () -> Int -# 74| getElement(6): [CallExpr] call to ... +# 74| getElement(4): [CallExpr] call to ... # 74| getFunction(): [ForceValueExpr] ...! # 74| getSubExpr(): [DeclRefExpr] g # 74| getSubExpr().getFullyConverted(): [LoadExpr] (((Int) -> Void)?) ... # 74| getArgument(0): [Argument] : 1 # 74| getExpr(): [IntegerLiteralExpr] 1 -# 75| getElement(7): [ReturnStmt] return ... +# 75| getElement(5): [ReturnStmt] return ... # 75| getResult(): [DeclRefExpr] r # 71| getCapture(0): [CapturedDecl] g # 70| [Comment] // x is an escaping capture of g and r @@ -458,20 +458,22 @@ closures.swift: # 78| [NamedFunction] quux() # 78| InterfaceType = () -> Int # 78| getBody(): [BraceStmt] { ... } +# 79| getVariable(0): [ConcreteVarDecl] y +# 79| Type = Int +# 103| getVariable(1): [ConcreteVarDecl] a +# 103| Type = () -> Void # 79| getElement(0): [PatternBindingDecl] var ... = ... # 79| getInit(0): [IntegerLiteralExpr] 0 # 79| getPattern(0): [NamedPattern] y -# 79| getElement(1): [ConcreteVarDecl] y -# 79| Type = Int -# 81| getElement(2): [NamedFunction] f() +# 81| getElement(1): [NamedFunction] f() # 81| InterfaceType = () -> () -> Void # 81| getBody(): [BraceStmt] { ... } +# 82| getVariable(0): [ConcreteVarDecl] x +# 82| Type = Int # 82| getElement(0): [PatternBindingDecl] var ... = ... # 82| getInit(0): [IntegerLiteralExpr] 5 # 82| getPattern(0): [NamedPattern] x -# 82| getElement(1): [ConcreteVarDecl] x -# 82| Type = Int -# 84| getElement(2): [NamedFunction] a() +# 84| getElement(1): [NamedFunction] a() # 84| InterfaceType = () -> () # 84| getBody(): [BraceStmt] { ... } # 85| getElement(0): [AssignExpr] ... = ... @@ -524,7 +526,7 @@ closures.swift: # 85| getCapture(0): [CapturedDecl] y # 85| getCapture(1): [CapturedDecl] x # 88| getCapture(2): [CapturedDecl] b() -# 92| getElement(3): [NamedFunction] b() +# 92| getElement(2): [NamedFunction] b() # 92| InterfaceType = () -> () # 92| getBody(): [BraceStmt] { ... } # 93| getElement(0): [AssignExpr] ... = ... @@ -585,18 +587,16 @@ closures.swift: # 93| getCapture(0): [CapturedDecl] y # 93| getCapture(1): [CapturedDecl] x # 96| getCapture(2): [CapturedDecl] a() -# 100| getElement(4): [ReturnStmt] return ... +# 100| getElement(3): [ReturnStmt] return ... # 100| getResult(): [DeclRefExpr] a() # 85| getCapture(0): [CapturedDecl] y -# 103| getElement(3): [PatternBindingDecl] var ... = ... +# 103| getElement(2): [PatternBindingDecl] var ... = ... # 103| getInit(0): [CallExpr] call to f() # 103| getFunction(): [DeclRefExpr] f() # 103| getPattern(0): [NamedPattern] a -# 103| getElement(4): [ConcreteVarDecl] a -# 103| Type = () -> Void -# 104| getElement(5): [CallExpr] call to ... +# 104| getElement(3): [CallExpr] call to ... # 104| getFunction(): [DeclRefExpr] a -# 105| getElement(6): [ReturnStmt] return ... +# 105| getElement(4): [ReturnStmt] return ... # 105| getResult(): [DeclRefExpr] y # 105| getResult().getFullyConverted(): [LoadExpr] (Int) ... # 105| [Comment] // 58341 @@ -604,16 +604,22 @@ closures.swift: # 108| [NamedFunction] sharedCapture() # 108| InterfaceType = () -> Int # 108| getBody(): [BraceStmt] { ... } +# 109| getVariable(0): [ConcreteVarDecl] incrX +# 109| Type = () -> () +# 109| getVariable(1): [ConcreteVarDecl] getX +# 109| Type = () -> Int +# 114| getVariable(2): [ConcreteVarDecl] doubleIncrX +# 114| Type = () -> () # 109| getElement(0): [PatternBindingDecl] var ... = ... # 109| getInit(0): [CallExpr] call to ... # 109| getFunction(): [ExplicitClosureExpr] { ... } # 109| getBody(): [BraceStmt] { ... } +# 110| getVariable(0): [ConcreteVarDecl] x +# 110| Type = Int # 110| getElement(0): [PatternBindingDecl] var ... = ... # 110| getInit(0): [IntegerLiteralExpr] 0 # 110| getPattern(0): [NamedPattern] x -# 110| getElement(1): [ConcreteVarDecl] x -# 110| Type = Int -# 111| getElement(2): [ReturnStmt] return ... +# 111| getElement(1): [ReturnStmt] return ... # 111| getResult(): [TupleExpr] (...) # 111| getElement(0): [ExplicitClosureExpr] { ... } # 111| getBody(): [BraceStmt] { ... } @@ -638,11 +644,7 @@ closures.swift: # 109| getPattern(0): [TuplePattern] (...) # 109| getElement(0): [NamedPattern] incrX # 109| getElement(1): [NamedPattern] getX -# 109| getElement(1): [ConcreteVarDecl] incrX -# 109| Type = () -> () -# 109| getElement(2): [ConcreteVarDecl] getX -# 109| Type = () -> Int -# 114| getElement(3): [PatternBindingDecl] var ... = ... +# 114| getElement(1): [PatternBindingDecl] var ... = ... # 114| getInit(0): [ExplicitClosureExpr] { ... } # 114| getBody(): [BraceStmt] { ... } # 115| getElement(0): [CallExpr] call to ... @@ -651,13 +653,11 @@ closures.swift: # 116| getFunction(): [DeclRefExpr] incrX # 115| getCapture(0): [CapturedDecl] incrX # 114| getPattern(0): [NamedPattern] doubleIncrX -# 114| getElement(4): [ConcreteVarDecl] doubleIncrX -# 114| Type = () -> () -# 119| getElement(5): [CallExpr] call to ... +# 119| getElement(2): [CallExpr] call to ... # 119| getFunction(): [DeclRefExpr] doubleIncrX -# 120| getElement(6): [CallExpr] call to ... +# 120| getElement(3): [CallExpr] call to ... # 120| getFunction(): [DeclRefExpr] doubleIncrX -# 121| getElement(7): [ReturnStmt] return ... +# 121| getElement(4): [ReturnStmt] return ... # 121| getResult(): [CallExpr] call to ... # 121| getFunction(): [DeclRefExpr] getX # 121| [Comment] // 4 @@ -688,12 +688,20 @@ closures.swift: # 127| [NamedFunction] sharedCaptureMultipleWriters() # 127| InterfaceType = () -> () # 127| getBody(): [BraceStmt] { ... } +# 128| getVariable(0): [ConcreteVarDecl] x +# 128| Type = Int +# 130| getVariable(1): [ConcreteVarDecl] callSink +# 130| Type = () -> () +# 132| getVariable(2): [ConcreteVarDecl] makeSetter +# 132| Type = (Int) -> () -> () +# 137| getVariable(3): [ConcreteVarDecl] goodSetter +# 137| Type = () -> () +# 138| getVariable(4): [ConcreteVarDecl] badSetter +# 138| Type = () -> () # 128| getElement(0): [PatternBindingDecl] var ... = ... # 128| getInit(0): [IntegerLiteralExpr] 123 # 128| getPattern(0): [NamedPattern] x -# 128| getElement(1): [ConcreteVarDecl] x -# 128| Type = Int -# 130| getElement(2): [PatternBindingDecl] var ... = ... +# 130| getElement(1): [PatternBindingDecl] var ... = ... # 130| getInit(0): [ExplicitClosureExpr] { ... } # 130| getBody(): [BraceStmt] { ... } # 130| getElement(0): [ReturnStmt] return ... @@ -704,13 +712,13 @@ closures.swift: # 130| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 130| getCapture(0): [CapturedDecl] x # 130| getPattern(0): [NamedPattern] callSink -# 130| getElement(3): [ConcreteVarDecl] callSink -# 130| Type = () -> () -# 132| getElement(4): [PatternBindingDecl] var ... = ... +# 132| getElement(2): [PatternBindingDecl] var ... = ... # 132| getInit(0): [ExplicitClosureExpr] { ... } # 132| getParam(0): [ParamDecl] y # 132| Type = Int # 132| getBody(): [BraceStmt] { ... } +# 133| getVariable(0): [ConcreteVarDecl] setter +# 133| Type = () -> () # 133| getElement(0): [PatternBindingDecl] var ... = ... # 133| getInit(0): [ExplicitClosureExpr] { ... } # 133| getBody(): [BraceStmt] { ... } @@ -721,47 +729,45 @@ closures.swift: # 133| getCapture(0): [CapturedDecl] x # 133| getCapture(1): [CapturedDecl] y # 133| getPattern(0): [NamedPattern] setter -# 133| getElement(1): [ConcreteVarDecl] setter -# 133| Type = () -> () -# 134| getElement(2): [ReturnStmt] return ... +# 134| getElement(1): [ReturnStmt] return ... # 134| getResult(): [DeclRefExpr] setter # 133| getCapture(0): [CapturedDecl] x # 132| getPattern(0): [NamedPattern] makeSetter -# 132| getElement(5): [ConcreteVarDecl] makeSetter -# 132| Type = (Int) -> () -> () -# 137| getElement(6): [PatternBindingDecl] var ... = ... +# 137| getElement(3): [PatternBindingDecl] var ... = ... # 137| getInit(0): [CallExpr] call to ... # 137| getFunction(): [DeclRefExpr] makeSetter # 137| getArgument(0): [Argument] : 42 # 137| getExpr(): [IntegerLiteralExpr] 42 # 137| getPattern(0): [NamedPattern] goodSetter -# 137| getElement(7): [ConcreteVarDecl] goodSetter -# 137| Type = () -> () -# 138| getElement(8): [PatternBindingDecl] var ... = ... +# 138| getElement(4): [PatternBindingDecl] var ... = ... # 138| getInit(0): [CallExpr] call to ... # 138| getFunction(): [DeclRefExpr] makeSetter # 138| getArgument(0): [Argument] : call to source() # 138| getExpr(): [CallExpr] call to source() # 138| getFunction(): [DeclRefExpr] source() # 138| getPattern(0): [NamedPattern] badSetter -# 138| getElement(9): [ConcreteVarDecl] badSetter -# 138| Type = () -> () -# 140| getElement(10): [CallExpr] call to ... +# 140| getElement(5): [CallExpr] call to ... # 140| getFunction(): [DeclRefExpr] goodSetter -# 141| getElement(11): [CallExpr] call to ... +# 141| getElement(6): [CallExpr] call to ... # 141| getFunction(): [DeclRefExpr] callSink -# 143| getElement(12): [CallExpr] call to ... +# 143| getElement(7): [CallExpr] call to ... # 143| getFunction(): [DeclRefExpr] badSetter -# 144| getElement(13): [CallExpr] call to ... +# 144| getElement(8): [CallExpr] call to ... # 144| getFunction(): [DeclRefExpr] callSink # 147| [NamedFunction] reentrant() # 147| InterfaceType = () -> Int # 147| getBody(): [BraceStmt] { ... } +# 167| getVariable(0): [ConcreteVarDecl] h +# 167| Type = (Int) -> Int +# 169| getVariable(1): [ConcreteVarDecl] y +# 169| Type = Int # 149| getElement(0): [NamedFunction] f(_:) # 149| InterfaceType = (Int) -> (Int) -> Int # 149| getParam(0): [ParamDecl] x # 149| Type = Int # 149| getBody(): [BraceStmt] { ... } +# 154| getVariable(0): [ConcreteVarDecl] next +# 154| Type = (Int) -> Int # 150| getElement(0): [IfStmt] if ... then { ... } # 150| getCondition(): [StmtCondition] StmtCondition # 150| getElement(0): [ConditionElement] ... .==(_:_:) ... @@ -797,9 +803,7 @@ closures.swift: # 154| getArgument(1): [Argument] : 1 # 154| getExpr(): [IntegerLiteralExpr] 1 # 154| getPattern(0): [NamedPattern] next -# 154| getElement(2): [ConcreteVarDecl] next -# 154| Type = (Int) -> Int -# 155| getElement(3): [ReturnStmt] return ... +# 155| getElement(2): [ReturnStmt] return ... # 155| getResult(): [ExplicitClosureExpr] { ... } # 155| getParam(0): [ParamDecl] k # 155| Type = Int @@ -841,6 +845,8 @@ closures.swift: # 158| getParam(0): [ParamDecl] x # 158| Type = Int # 158| getBody(): [BraceStmt] { ... } +# 163| getVariable(0): [ConcreteVarDecl] next +# 163| Type = (Int) -> Int # 159| getElement(0): [IfStmt] if ... then { ... } # 159| getCondition(): [StmtCondition] StmtCondition # 159| getElement(0): [ConditionElement] ... .==(_:_:) ... @@ -876,9 +882,7 @@ closures.swift: # 163| getArgument(1): [Argument] : 1 # 163| getExpr(): [IntegerLiteralExpr] 1 # 163| getPattern(0): [NamedPattern] next -# 163| getElement(2): [ConcreteVarDecl] next -# 163| Type = (Int) -> Int -# 164| getElement(3): [ReturnStmt] return ... +# 164| getElement(2): [ReturnStmt] return ... # 164| getResult(): [ExplicitClosureExpr] { ... } # 164| getParam(0): [ParamDecl] k # 164| Type = Int @@ -929,23 +933,23 @@ closures.swift: # 167| getArgument(0): [Argument] : 5 # 167| getExpr(): [IntegerLiteralExpr] 5 # 167| getPattern(0): [NamedPattern] h -# 167| getElement(3): [ConcreteVarDecl] h -# 167| Type = (Int) -> Int -# 169| getElement(4): [PatternBindingDecl] var ... = ... +# 169| getElement(3): [PatternBindingDecl] var ... = ... # 169| getInit(0): [CallExpr] call to ... # 169| getFunction(): [DeclRefExpr] h # 169| getArgument(0): [Argument] : 10 # 169| getExpr(): [IntegerLiteralExpr] 10 # 169| getPattern(0): [NamedPattern] y -# 169| getElement(5): [ConcreteVarDecl] y -# 169| Type = Int -# 171| getElement(6): [ReturnStmt] return ... +# 171| getElement(4): [ReturnStmt] return ... # 171| getResult(): [DeclRefExpr] y # 171| [Comment] // 10004003085 # 171| # 174| [NamedFunction] main() # 174| InterfaceType = () -> () # 174| getBody(): [BraceStmt] { ... } +# 188| getVariable(0): [ConcreteVarDecl] a +# 188| Type = () -> Int +# 189| getVariable(1): [ConcreteVarDecl] b +# 189| Type = () -> Int # 175| getElement(0): [CallExpr] call to print(_:separator:terminator:) # 175| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 175| getArgument(0): [Argument] : [...] @@ -1017,15 +1021,11 @@ closures.swift: # 188| getInit(0): [CallExpr] call to bar() # 188| getFunction(): [DeclRefExpr] bar() # 188| getPattern(0): [NamedPattern] a -# 188| getElement(9): [ConcreteVarDecl] a -# 188| Type = () -> Int -# 189| getElement(10): [PatternBindingDecl] var ... = ... +# 189| getElement(9): [PatternBindingDecl] var ... = ... # 189| getInit(0): [CallExpr] call to baz() # 189| getFunction(): [DeclRefExpr] baz() # 189| getPattern(0): [NamedPattern] b -# 189| getElement(11): [ConcreteVarDecl] b -# 189| Type = () -> Int -# 191| getElement(12): [CallExpr] call to print(_:separator:terminator:) +# 191| getElement(10): [CallExpr] call to print(_:separator:terminator:) # 191| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 191| getArgument(0): [Argument] : [...] # 191| getExpr(): [VarargExpansionExpr] [...] @@ -1042,7 +1042,7 @@ closures.swift: # 191| getExpr(): [DefaultArgumentExpr] default separator # 191| getArgument(2): [Argument] terminator: default terminator # 191| getExpr(): [DefaultArgumentExpr] default terminator -# 193| getElement(13): [CallExpr] call to print(_:separator:terminator:) +# 193| getElement(11): [CallExpr] call to print(_:separator:terminator:) # 193| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 193| getArgument(0): [Argument] : [...] # 193| getExpr(): [VarargExpansionExpr] [...] @@ -1059,13 +1059,13 @@ closures.swift: # 193| getExpr(): [DefaultArgumentExpr] default separator # 193| getArgument(2): [Argument] terminator: default terminator # 193| getExpr(): [DefaultArgumentExpr] default terminator -# 195| getElement(14): [CallExpr] call to ... +# 195| getElement(12): [CallExpr] call to ... # 195| getFunction(): [ForceValueExpr] ...! # 195| getSubExpr(): [DeclRefExpr] g # 195| getSubExpr().getFullyConverted(): [LoadExpr] (((Int) -> Void)?) ... # 195| getArgument(0): [Argument] : 1 # 195| getExpr(): [IntegerLiteralExpr] 1 -# 196| getElement(15): [CallExpr] call to print(_:separator:terminator:) +# 196| getElement(13): [CallExpr] call to print(_:separator:terminator:) # 196| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 196| getArgument(0): [Argument] : [...] # 196| getExpr(): [VarargExpansionExpr] [...] @@ -1082,13 +1082,13 @@ closures.swift: # 196| getExpr(): [DefaultArgumentExpr] default separator # 196| getArgument(2): [Argument] terminator: default terminator # 196| getExpr(): [DefaultArgumentExpr] default terminator -# 198| getElement(16): [CallExpr] call to ... +# 198| getElement(14): [CallExpr] call to ... # 198| getFunction(): [ForceValueExpr] ...! # 198| getSubExpr(): [DeclRefExpr] g # 198| getSubExpr().getFullyConverted(): [LoadExpr] (((Int) -> Void)?) ... # 198| getArgument(0): [Argument] : 1 # 198| getExpr(): [IntegerLiteralExpr] 1 -# 199| getElement(17): [CallExpr] call to print(_:separator:terminator:) +# 199| getElement(15): [CallExpr] call to print(_:separator:terminator:) # 199| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 199| getArgument(0): [Argument] : [...] # 199| getExpr(): [VarargExpansionExpr] [...] @@ -1105,7 +1105,7 @@ closures.swift: # 199| getExpr(): [DefaultArgumentExpr] default separator # 199| getArgument(2): [Argument] terminator: default terminator # 199| getExpr(): [DefaultArgumentExpr] default terminator -# 201| getElement(18): [CallExpr] call to print(_:separator:terminator:) +# 201| getElement(16): [CallExpr] call to print(_:separator:terminator:) # 201| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 201| getArgument(0): [Argument] : [...] # 201| getExpr(): [VarargExpansionExpr] [...] @@ -1119,7 +1119,7 @@ closures.swift: # 201| getExpr(): [DefaultArgumentExpr] default separator # 201| getArgument(2): [Argument] terminator: default terminator # 201| getExpr(): [DefaultArgumentExpr] default terminator -# 203| getElement(19): [CallExpr] call to print(_:separator:terminator:) +# 203| getElement(17): [CallExpr] call to print(_:separator:terminator:) # 203| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 203| getArgument(0): [Argument] : [...] # 203| getExpr(): [VarargExpansionExpr] [...] @@ -1133,7 +1133,7 @@ closures.swift: # 203| getExpr(): [DefaultArgumentExpr] default separator # 203| getArgument(2): [Argument] terminator: default terminator # 203| getExpr(): [DefaultArgumentExpr] default terminator -# 205| getElement(20): [CallExpr] call to print(_:separator:terminator:) +# 205| getElement(18): [CallExpr] call to print(_:separator:terminator:) # 205| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 205| getArgument(0): [Argument] : [...] # 205| getExpr(): [VarargExpansionExpr] [...] @@ -1144,9 +1144,9 @@ closures.swift: # 205| getExpr(): [DefaultArgumentExpr] default separator # 205| getArgument(2): [Argument] terminator: default terminator # 205| getExpr(): [DefaultArgumentExpr] default terminator -# 206| getElement(21): [CallExpr] call to sharedCaptureMultipleWriters() +# 206| getElement(19): [CallExpr] call to sharedCaptureMultipleWriters() # 206| getFunction(): [DeclRefExpr] sharedCaptureMultipleWriters() -# 208| getElement(22): [CallExpr] call to print(_:separator:terminator:) +# 208| getElement(20): [CallExpr] call to print(_:separator:terminator:) # 208| getFunction(): [DeclRefExpr] print(_:separator:terminator:) # 208| getArgument(0): [Argument] : [...] # 208| getExpr(): [VarargExpansionExpr] [...] diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index f1fbb4f1544..8ad1305aec9 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -209,23 +209,23 @@ cfg.swift: # 40| getAppendingExpr(): [TapExpr] TapExpr # 40| getSubExpr(): [OpaqueValueExpr] OpaqueValueExpr # 40| getBody(): [BraceStmt] { ... } -#-----| getElement(0): [ConcreteVarDecl] $interpolation +#-----| getVariable(0): [ConcreteVarDecl] $interpolation #-----| Type = DefaultStringInterpolation -# 40| getElement(1): [CallExpr] call to appendLiteral(_:) +# 40| getElement(0): [CallExpr] call to appendLiteral(_:) # 40| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 40| getBase(): [InOutExpr] &... # 40| getSubExpr(): [DeclRefExpr] $interpolation #-----| getMethodRef(): [DeclRefExpr] appendLiteral(_:) # 40| getArgument(0): [Argument] : Unknown error # 40| getExpr(): [StringLiteralExpr] Unknown error -# 40| getElement(2): [CallExpr] call to appendInterpolation(_:) +# 40| getElement(1): [CallExpr] call to appendInterpolation(_:) # 40| getFunction(): [MethodLookupExpr] .appendInterpolation(_:) # 40| getBase(): [InOutExpr] &... # 40| getSubExpr(): [DeclRefExpr] $interpolation # 40| getMethodRef(): [DeclRefExpr] appendInterpolation(_:) # 40| getArgument(0): [Argument] : error # 40| getExpr(): [DeclRefExpr] error -# 40| getElement(3): [CallExpr] call to appendLiteral(_:) +# 40| getElement(2): [CallExpr] call to appendLiteral(_:) # 40| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 40| getBase(): [InOutExpr] &... # 40| getSubExpr(): [DeclRefExpr] $interpolation @@ -312,6 +312,12 @@ cfg.swift: # 64| [NamedFunction] callClosures() # 64| InterfaceType = () -> () # 64| getBody(): [BraceStmt] { ... } +# 65| getVariable(0): [ConcreteVarDecl] x1 +# 65| Type = String +# 66| getVariable(1): [ConcreteVarDecl] x2 +# 66| Type = Int +# 67| getVariable(2): [ConcreteVarDecl] x3 +# 67| Type = Int # 65| getElement(0): [PatternBindingDecl] var ... = ... # 65| getInit(0): [CallExpr] call to ... # 65| getFunction(): [CallExpr] call to createClosure1(s:) @@ -319,9 +325,7 @@ cfg.swift: # 65| getArgument(0): [Argument] s: # 65| getExpr(): [StringLiteralExpr] # 65| getPattern(0): [NamedPattern] x1 -# 65| getElement(1): [ConcreteVarDecl] x1 -# 65| Type = String -# 66| getElement(2): [PatternBindingDecl] var ... = ... +# 66| getElement(1): [PatternBindingDecl] var ... = ... # 66| getInit(0): [CallExpr] call to ... # 66| getFunction(): [CallExpr] call to createClosure2(x:) # 66| getFunction(): [DeclRefExpr] createClosure2(x:) @@ -330,9 +334,7 @@ cfg.swift: # 66| getArgument(0): [Argument] : 10 # 66| getExpr(): [IntegerLiteralExpr] 10 # 66| getPattern(0): [NamedPattern] x2 -# 66| getElement(3): [ConcreteVarDecl] x2 -# 66| Type = Int -# 67| getElement(4): [PatternBindingDecl] var ... = ... +# 67| getElement(2): [PatternBindingDecl] var ... = ... # 67| getInit(0): [CallExpr] call to ... # 67| getFunction(): [CallExpr] call to createClosure3(x:) # 67| getFunction(): [DeclRefExpr] createClosure3(x:) @@ -341,13 +343,13 @@ cfg.swift: # 67| getArgument(0): [Argument] : 10 # 67| getExpr(): [IntegerLiteralExpr] 10 # 67| getPattern(0): [NamedPattern] x3 -# 67| getElement(5): [ConcreteVarDecl] x3 -# 67| Type = Int # 70| [NamedFunction] maybeParseInt(s:) # 70| InterfaceType = (String) -> Int? # 70| getParam(0): [ParamDecl] s # 70| Type = String # 70| getBody(): [BraceStmt] { ... } +# 71| getVariable(0): [ConcreteVarDecl] n +# 71| Type = Int? # 71| getElement(0): [PatternBindingDecl] var ... = ... # 71| getInit(0): [CallExpr] call to Self.init(_:) # 71| getFunction(): [MethodLookupExpr] Self.init(_:) @@ -359,14 +361,16 @@ cfg.swift: # 71| getPattern(0): [TypedPattern] ... as ... # 71| getSubPattern(): [NamedPattern] n # 71| getTypeRepr(): [TypeRepr] Int? -# 71| getElement(1): [ConcreteVarDecl] n -# 71| Type = Int? -# 72| getElement(2): [ReturnStmt] return ... +# 72| getElement(1): [ReturnStmt] return ... # 72| getResult(): [DeclRefExpr] n # 72| getResult().getFullyConverted(): [LoadExpr] (Int?) ... # 75| [NamedFunction] forceAndBackToOptional() # 75| InterfaceType = () -> Int? # 75| getBody(): [BraceStmt] { ... } +# 76| getVariable(0): [ConcreteVarDecl] nBang +# 76| Type = Int +# 77| getVariable(1): [ConcreteVarDecl] n +# 77| Type = Int? # 76| getElement(0): [PatternBindingDecl] var ... = ... # 76| getInit(0): [ForceValueExpr] ...! # 76| getSubExpr(): [CallExpr] call to maybeParseInt(s:) @@ -374,17 +378,13 @@ cfg.swift: # 76| getArgument(0): [Argument] s: 42 # 76| getExpr(): [StringLiteralExpr] 42 # 76| getPattern(0): [NamedPattern] nBang -# 76| getElement(1): [ConcreteVarDecl] nBang -# 76| Type = Int -# 77| getElement(2): [PatternBindingDecl] var ... = ... +# 77| getElement(1): [PatternBindingDecl] var ... = ... # 77| getInit(0): [CallExpr] call to maybeParseInt(s:) # 77| getFunction(): [DeclRefExpr] maybeParseInt(s:) # 77| getArgument(0): [Argument] s: 42 # 77| getExpr(): [StringLiteralExpr] 42 # 77| getPattern(0): [NamedPattern] n -# 77| getElement(3): [ConcreteVarDecl] n -# 77| Type = Int? -# 78| getElement(4): [ReturnStmt] return ... +# 78| getElement(2): [ReturnStmt] return ... # 78| getResult(): [BinaryExpr] ... .+(_:_:) ... # 78| getFunction(): [MethodLookupExpr] .+(_:_:) # 78| getBase(): [TypeExpr] Int.Type @@ -401,12 +401,14 @@ cfg.swift: # 81| [NamedFunction] testInOut() # 81| InterfaceType = () -> Int # 81| getBody(): [BraceStmt] { ... } +# 82| getVariable(0): [ConcreteVarDecl] temp +# 82| Type = Int +# 93| getVariable(1): [ConcreteVarDecl] tempOptional +# 93| Type = Int? # 82| getElement(0): [PatternBindingDecl] var ... = ... # 82| getInit(0): [IntegerLiteralExpr] 10 # 82| getPattern(0): [NamedPattern] temp -# 82| getElement(1): [ConcreteVarDecl] temp -# 82| Type = Int -# 84| getElement(2): [NamedFunction] add(a:) +# 84| getElement(1): [NamedFunction] add(a:) # 84| InterfaceType = (inout Int) -> () # 84| getParam(0): [ParamDecl] a # 84| Type = Int @@ -423,7 +425,7 @@ cfg.swift: # 85| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 85| getArgument(1): [Argument] : 1 # 85| getExpr(): [IntegerLiteralExpr] 1 -# 88| getElement(3): [NamedFunction] addOptional(a:) +# 88| getElement(2): [NamedFunction] addOptional(a:) # 88| InterfaceType = (inout Int?) -> () # 88| getParam(0): [ParamDecl] a # 88| Type = Int? @@ -431,25 +433,23 @@ cfg.swift: # 89| getElement(0): [AssignExpr] ... = ... # 89| getDest(): [DeclRefExpr] a # 89| getSource(): [NilLiteralExpr] nil -# 92| getElement(4): [CallExpr] call to add(a:) +# 92| getElement(3): [CallExpr] call to add(a:) # 92| getFunction(): [DeclRefExpr] add(a:) # 92| getArgument(0): [Argument] a: &... # 92| getExpr(): [InOutExpr] &... # 92| getSubExpr(): [DeclRefExpr] temp -# 93| getElement(5): [PatternBindingDecl] var ... = ... +# 93| getElement(4): [PatternBindingDecl] var ... = ... # 93| getInit(0): [IntegerLiteralExpr] 10 # 93| getInit(0).getFullyConverted(): [InjectIntoOptionalExpr] (Int?) ... # 93| getPattern(0): [TypedPattern] ... as ... # 93| getSubPattern(): [NamedPattern] tempOptional # 93| getTypeRepr(): [TypeRepr] Int? -# 93| getElement(6): [ConcreteVarDecl] tempOptional -# 93| Type = Int? -# 94| getElement(7): [CallExpr] call to addOptional(a:) +# 94| getElement(5): [CallExpr] call to addOptional(a:) # 94| getFunction(): [DeclRefExpr] addOptional(a:) # 94| getArgument(0): [Argument] a: &... # 94| getExpr(): [InOutExpr] &... # 94| getSubExpr(): [DeclRefExpr] tempOptional -# 95| getElement(8): [ReturnStmt] return ... +# 95| getElement(6): [ReturnStmt] return ... # 95| getResult(): [BinaryExpr] ... .+(_:_:) ... # 95| getFunction(): [MethodLookupExpr] .+(_:_:) # 95| getBase(): [TypeExpr] Int.Type @@ -511,6 +511,48 @@ cfg.swift: # 109| getParam(2): [ParamDecl] opt # 109| Type = C? # 109| getBody(): [BraceStmt] { ... } +# 110| getVariable(0): [ConcreteVarDecl] c +# 110| Type = C +# 111| getVariable(1): [ConcreteVarDecl] n1 +# 111| Type = Int +# 112| getVariable(2): [ConcreteVarDecl] n2 +# 112| Type = Int +# 113| getVariable(3): [ConcreteVarDecl] n3 +# 113| Type = Int +# 114| getVariable(4): [ConcreteVarDecl] n4 +# 114| Type = Int +# 116| getVariable(5): [ConcreteVarDecl] n5 +# 116| Type = Int +# 117| getVariable(6): [ConcreteVarDecl] n6 +# 117| Type = Int +# 118| getVariable(7): [ConcreteVarDecl] n7 +# 118| Type = Int +# 119| getVariable(8): [ConcreteVarDecl] n8 +# 119| Type = Int +# 121| getVariable(9): [ConcreteVarDecl] n9 +# 121| Type = Int +# 122| getVariable(10): [ConcreteVarDecl] n10 +# 122| Type = Int +# 123| getVariable(11): [ConcreteVarDecl] n11 +# 123| Type = Int +# 124| getVariable(12): [ConcreteVarDecl] n12 +# 124| Type = Int +# 126| getVariable(13): [ConcreteVarDecl] n13 +# 126| Type = Int +# 127| getVariable(14): [ConcreteVarDecl] n14 +# 127| Type = Int +# 128| getVariable(15): [ConcreteVarDecl] n15 +# 128| Type = Int +# 129| getVariable(16): [ConcreteVarDecl] n16 +# 129| Type = Int +# 131| getVariable(17): [ConcreteVarDecl] n17 +# 131| Type = Int? +# 132| getVariable(18): [ConcreteVarDecl] n18 +# 132| Type = Int? +# 133| getVariable(19): [ConcreteVarDecl] n19 +# 133| Type = Int? +# 134| getVariable(20): [ConcreteVarDecl] n20 +# 134| Type = Int? # 110| getElement(0): [PatternBindingDecl] var ... = ... # 110| getInit(0): [CallExpr] call to C.init(n:) # 110| getFunction(): [MethodLookupExpr] C.init(n:) @@ -520,93 +562,69 @@ cfg.swift: # 110| getArgument(0): [Argument] n: 42 # 110| getExpr(): [IntegerLiteralExpr] 42 # 110| getPattern(0): [NamedPattern] c -# 110| getElement(1): [ConcreteVarDecl] c -# 110| Type = C -# 111| getElement(2): [PatternBindingDecl] var ... = ... +# 111| getElement(1): [PatternBindingDecl] var ... = ... # 111| getInit(0): [MemberRefExpr] .myInt # 111| getBase(): [DeclRefExpr] c # 111| getPattern(0): [NamedPattern] n1 -# 111| getElement(3): [ConcreteVarDecl] n1 -# 111| Type = Int -# 112| getElement(4): [PatternBindingDecl] var ... = ... +# 112| getElement(2): [PatternBindingDecl] var ... = ... # 112| getInit(0): [MemberRefExpr] .myInt # 112| getBase(): [DeclRefExpr] c # 112| getBase().getFullyConverted(): [DotSelfExpr] .self # 112| getPattern(0): [NamedPattern] n2 -# 112| getElement(5): [ConcreteVarDecl] n2 -# 112| Type = Int -# 113| getElement(6): [PatternBindingDecl] var ... = ... +# 113| getElement(3): [PatternBindingDecl] var ... = ... # 113| getInit(0): [CallExpr] call to getMyInt() # 113| getFunction(): [MethodLookupExpr] .getMyInt() # 113| getBase(): [DeclRefExpr] c # 113| getMethodRef(): [DeclRefExpr] getMyInt() # 113| getPattern(0): [NamedPattern] n3 -# 113| getElement(7): [ConcreteVarDecl] n3 -# 113| Type = Int -# 114| getElement(8): [PatternBindingDecl] var ... = ... +# 114| getElement(4): [PatternBindingDecl] var ... = ... # 114| getInit(0): [CallExpr] call to getMyInt() # 114| getFunction(): [MethodLookupExpr] .getMyInt() # 114| getBase(): [DeclRefExpr] c # 114| getBase().getFullyConverted(): [DotSelfExpr] .self # 114| getMethodRef(): [DeclRefExpr] getMyInt() # 114| getPattern(0): [NamedPattern] n4 -# 114| getElement(9): [ConcreteVarDecl] n4 -# 114| Type = Int -# 116| getElement(10): [PatternBindingDecl] var ... = ... +# 116| getElement(5): [PatternBindingDecl] var ... = ... # 116| getInit(0): [MemberRefExpr] .myInt # 116| getBase(): [DeclRefExpr] param # 116| getPattern(0): [NamedPattern] n5 -# 116| getElement(11): [ConcreteVarDecl] n5 -# 116| Type = Int -# 117| getElement(12): [PatternBindingDecl] var ... = ... +# 117| getElement(6): [PatternBindingDecl] var ... = ... # 117| getInit(0): [MemberRefExpr] .myInt # 117| getBase(): [DeclRefExpr] param # 117| getBase().getFullyConverted(): [DotSelfExpr] .self # 117| getPattern(0): [NamedPattern] n6 -# 117| getElement(13): [ConcreteVarDecl] n6 -# 117| Type = Int -# 118| getElement(14): [PatternBindingDecl] var ... = ... +# 118| getElement(7): [PatternBindingDecl] var ... = ... # 118| getInit(0): [CallExpr] call to getMyInt() # 118| getFunction(): [MethodLookupExpr] .getMyInt() # 118| getBase(): [DeclRefExpr] param # 118| getMethodRef(): [DeclRefExpr] getMyInt() # 118| getPattern(0): [NamedPattern] n7 -# 118| getElement(15): [ConcreteVarDecl] n7 -# 118| Type = Int -# 119| getElement(16): [PatternBindingDecl] var ... = ... +# 119| getElement(8): [PatternBindingDecl] var ... = ... # 119| getInit(0): [CallExpr] call to getMyInt() # 119| getFunction(): [MethodLookupExpr] .getMyInt() # 119| getBase(): [DeclRefExpr] param # 119| getBase().getFullyConverted(): [DotSelfExpr] .self # 119| getMethodRef(): [DeclRefExpr] getMyInt() # 119| getPattern(0): [NamedPattern] n8 -# 119| getElement(17): [ConcreteVarDecl] n8 -# 119| Type = Int -# 121| getElement(18): [PatternBindingDecl] var ... = ... +# 121| getElement(9): [PatternBindingDecl] var ... = ... # 121| getInit(0): [MemberRefExpr] .myInt # 121| getBase(): [DeclRefExpr] inoutParam # 121| getBase().getFullyConverted(): [LoadExpr] (C) ... # 121| getPattern(0): [NamedPattern] n9 -# 121| getElement(19): [ConcreteVarDecl] n9 -# 121| Type = Int -# 122| getElement(20): [PatternBindingDecl] var ... = ... +# 122| getElement(10): [PatternBindingDecl] var ... = ... # 122| getInit(0): [MemberRefExpr] .myInt # 122| getBase(): [DeclRefExpr] inoutParam # 122| getBase().getFullyConverted(): [LoadExpr] (C) ... # 122| getSubExpr(): [DotSelfExpr] .self # 122| getPattern(0): [NamedPattern] n10 -# 122| getElement(21): [ConcreteVarDecl] n10 -# 122| Type = Int -# 123| getElement(22): [PatternBindingDecl] var ... = ... +# 123| getElement(11): [PatternBindingDecl] var ... = ... # 123| getInit(0): [CallExpr] call to getMyInt() # 123| getFunction(): [MethodLookupExpr] .getMyInt() # 123| getBase(): [DeclRefExpr] inoutParam # 123| getBase().getFullyConverted(): [LoadExpr] (C) ... # 123| getMethodRef(): [DeclRefExpr] getMyInt() # 123| getPattern(0): [NamedPattern] n11 -# 123| getElement(23): [ConcreteVarDecl] n11 -# 123| Type = Int -# 124| getElement(24): [PatternBindingDecl] var ... = ... +# 124| getElement(12): [PatternBindingDecl] var ... = ... # 124| getInit(0): [CallExpr] call to getMyInt() # 124| getFunction(): [MethodLookupExpr] .getMyInt() # 124| getBase(): [DeclRefExpr] inoutParam @@ -614,33 +632,25 @@ cfg.swift: # 124| getSubExpr(): [DotSelfExpr] .self # 124| getMethodRef(): [DeclRefExpr] getMyInt() # 124| getPattern(0): [NamedPattern] n12 -# 124| getElement(25): [ConcreteVarDecl] n12 -# 124| Type = Int -# 126| getElement(26): [PatternBindingDecl] var ... = ... +# 126| getElement(13): [PatternBindingDecl] var ... = ... # 126| getInit(0): [MemberRefExpr] .myInt # 126| getBase(): [ForceValueExpr] ...! # 126| getSubExpr(): [DeclRefExpr] opt # 126| getPattern(0): [NamedPattern] n13 -# 126| getElement(27): [ConcreteVarDecl] n13 -# 126| Type = Int -# 127| getElement(28): [PatternBindingDecl] var ... = ... +# 127| getElement(14): [PatternBindingDecl] var ... = ... # 127| getInit(0): [MemberRefExpr] .myInt # 127| getBase(): [ForceValueExpr] ...! # 127| getSubExpr(): [DeclRefExpr] opt # 127| getBase().getFullyConverted(): [DotSelfExpr] .self # 127| getPattern(0): [NamedPattern] n14 -# 127| getElement(29): [ConcreteVarDecl] n14 -# 127| Type = Int -# 128| getElement(30): [PatternBindingDecl] var ... = ... +# 128| getElement(15): [PatternBindingDecl] var ... = ... # 128| getInit(0): [CallExpr] call to getMyInt() # 128| getFunction(): [MethodLookupExpr] .getMyInt() # 128| getBase(): [ForceValueExpr] ...! # 128| getSubExpr(): [DeclRefExpr] opt # 128| getMethodRef(): [DeclRefExpr] getMyInt() # 128| getPattern(0): [NamedPattern] n15 -# 128| getElement(31): [ConcreteVarDecl] n15 -# 128| Type = Int -# 129| getElement(32): [PatternBindingDecl] var ... = ... +# 129| getElement(16): [PatternBindingDecl] var ... = ... # 129| getInit(0): [CallExpr] call to getMyInt() # 129| getFunction(): [MethodLookupExpr] .getMyInt() # 129| getBase(): [ForceValueExpr] ...! @@ -648,18 +658,14 @@ cfg.swift: # 129| getBase().getFullyConverted(): [DotSelfExpr] .self # 129| getMethodRef(): [DeclRefExpr] getMyInt() # 129| getPattern(0): [NamedPattern] n16 -# 129| getElement(33): [ConcreteVarDecl] n16 -# 129| Type = Int -# 131| getElement(34): [PatternBindingDecl] var ... = ... +# 131| getElement(17): [PatternBindingDecl] var ... = ... # 131| getInit(0): [OptionalEvaluationExpr] OptionalEvaluationExpr # 131| getSubExpr(): [MemberRefExpr] .myInt # 131| getBase(): [BindOptionalExpr] ...? # 131| getSubExpr(): [DeclRefExpr] opt # 131| getSubExpr().getFullyConverted(): [InjectIntoOptionalExpr] (Int?) ... # 131| getPattern(0): [NamedPattern] n17 -# 131| getElement(35): [ConcreteVarDecl] n17 -# 131| Type = Int? -# 132| getElement(36): [PatternBindingDecl] var ... = ... +# 132| getElement(18): [PatternBindingDecl] var ... = ... # 132| getInit(0): [OptionalEvaluationExpr] OptionalEvaluationExpr # 132| getSubExpr(): [MemberRefExpr] .myInt # 132| getBase(): [BindOptionalExpr] ...? @@ -667,9 +673,7 @@ cfg.swift: # 132| getBase().getFullyConverted(): [DotSelfExpr] .self # 132| getSubExpr().getFullyConverted(): [InjectIntoOptionalExpr] (Int?) ... # 132| getPattern(0): [NamedPattern] n18 -# 132| getElement(37): [ConcreteVarDecl] n18 -# 132| Type = Int? -# 133| getElement(38): [PatternBindingDecl] var ... = ... +# 133| getElement(19): [PatternBindingDecl] var ... = ... # 133| getInit(0): [OptionalEvaluationExpr] OptionalEvaluationExpr # 133| getSubExpr(): [CallExpr] call to getMyInt() # 133| getFunction(): [MethodLookupExpr] .getMyInt() @@ -678,9 +682,7 @@ cfg.swift: # 133| getMethodRef(): [DeclRefExpr] getMyInt() # 133| getSubExpr().getFullyConverted(): [InjectIntoOptionalExpr] (Int?) ... # 133| getPattern(0): [NamedPattern] n19 -# 133| getElement(39): [ConcreteVarDecl] n19 -# 133| Type = Int? -# 134| getElement(40): [PatternBindingDecl] var ... = ... +# 134| getElement(20): [PatternBindingDecl] var ... = ... # 134| getInit(0): [OptionalEvaluationExpr] OptionalEvaluationExpr # 134| getSubExpr(): [CallExpr] call to getMyInt() # 134| getFunction(): [MethodLookupExpr] .getMyInt() @@ -690,13 +692,15 @@ cfg.swift: # 134| getMethodRef(): [DeclRefExpr] getMyInt() # 134| getSubExpr().getFullyConverted(): [InjectIntoOptionalExpr] (Int?) ... # 134| getPattern(0): [NamedPattern] n20 -# 134| getElement(41): [ConcreteVarDecl] n20 -# 134| Type = Int? # 137| [NamedFunction] patterns(x:) # 137| InterfaceType = (Int) -> Bool # 137| getParam(0): [ParamDecl] x # 137| Type = Int # 137| getBody(): [BraceStmt] { ... } +# 150| getVariable(0): [ConcreteVarDecl] obj +# 150| Type = AnyObject +# 155| getVariable(1): [ConcreteVarDecl] xOptional +# 155| Type = Int? # 138| getElement(0): [ForEachStmt] for ... in ... { ... } # 138| getPattern(): [AnyPattern] _ # 138| getSequence(): [BinaryExpr] ... ....(_:_:) ... @@ -778,9 +782,7 @@ cfg.swift: # 150| getPattern(0): [TypedPattern] ... as ... # 150| getSubPattern(): [NamedPattern] obj # 150| getTypeRepr(): [TypeRepr] AnyObject -# 150| getElement(3): [ConcreteVarDecl] obj -# 150| Type = AnyObject -# 151| getElement(4): [IfStmt] if ... then { ... } +# 151| getElement(3): [IfStmt] if ... then { ... } # 151| getCondition(): [StmtCondition] StmtCondition # 151| getElement(0): [ConditionElement] obj # 151| getBoolean(): [DeclRefExpr] obj @@ -789,15 +791,13 @@ cfg.swift: # 151| getThen(): [BraceStmt] { ... } # 152| getElement(0): [ReturnStmt] return ... # 152| getResult(): [BooleanLiteralExpr] true -# 155| getElement(5): [PatternBindingDecl] var ... = ... +# 155| getElement(4): [PatternBindingDecl] var ... = ... # 155| getInit(0): [DeclRefExpr] x # 155| getInit(0).getFullyConverted(): [InjectIntoOptionalExpr] (Int?) ... # 155| getPattern(0): [TypedPattern] ... as ... # 155| getSubPattern(): [NamedPattern] xOptional # 155| getTypeRepr(): [TypeRepr] Int? -# 155| getElement(6): [ConcreteVarDecl] xOptional -# 155| Type = Int? -# 156| getElement(7): [IfStmt] if ... then { ... } else { ... } +# 156| getElement(5): [IfStmt] if ... then { ... } else { ... } # 156| getCondition(): [StmtCondition] StmtCondition # 156| getElement(0): [ConditionElement] .some(...) = ... # 156| getPattern(): [EnumElementPattern] .some(...) @@ -1203,6 +1203,38 @@ cfg.swift: # 243| getParam(1): [ParamDecl] b # 243| Type = Int # 243| getBody(): [BraceStmt] { ... } +# 244| getVariable(0): [ConcreteVarDecl] c +# 244| Type = Int +# 245| getVariable(1): [ConcreteVarDecl] d +# 245| Type = Int +# 246| getVariable(2): [ConcreteVarDecl] e +# 246| Type = Int +# 247| getVariable(3): [ConcreteVarDecl] f +# 247| Type = Int +# 248| getVariable(4): [ConcreteVarDecl] g +# 248| Type = Int +# 249| getVariable(5): [ConcreteVarDecl] h +# 249| Type = Int +# 250| getVariable(6): [ConcreteVarDecl] i +# 250| Type = Int +# 251| getVariable(7): [ConcreteVarDecl] j +# 251| Type = Int +# 252| getVariable(8): [ConcreteVarDecl] k +# 252| Type = Int +# 253| getVariable(9): [ConcreteVarDecl] l +# 253| Type = Int +# 254| getVariable(10): [ConcreteVarDecl] o +# 254| Type = Bool +# 255| getVariable(11): [ConcreteVarDecl] p +# 255| Type = Bool +# 256| getVariable(12): [ConcreteVarDecl] q +# 256| Type = Bool +# 257| getVariable(13): [ConcreteVarDecl] r +# 257| Type = Bool +# 258| getVariable(14): [ConcreteVarDecl] s +# 258| Type = Bool +# 259| getVariable(15): [ConcreteVarDecl] t +# 259| Type = Bool # 244| getElement(0): [PatternBindingDecl] var ... = ... # 244| getInit(0): [BinaryExpr] ... .+(_:_:) ... # 244| getFunction(): [MethodLookupExpr] .+(_:_:) @@ -1214,9 +1246,7 @@ cfg.swift: # 244| getArgument(1): [Argument] : b # 244| getExpr(): [DeclRefExpr] b # 244| getPattern(0): [NamedPattern] c -# 244| getElement(1): [ConcreteVarDecl] c -# 244| Type = Int -# 245| getElement(2): [PatternBindingDecl] var ... = ... +# 245| getElement(1): [PatternBindingDecl] var ... = ... # 245| getInit(0): [BinaryExpr] ... .-(_:_:) ... # 245| getFunction(): [MethodLookupExpr] .-(_:_:) # 245| getBase(): [TypeExpr] Int.Type @@ -1227,9 +1257,7 @@ cfg.swift: # 245| getArgument(1): [Argument] : b # 245| getExpr(): [DeclRefExpr] b # 245| getPattern(0): [NamedPattern] d -# 245| getElement(3): [ConcreteVarDecl] d -# 245| Type = Int -# 246| getElement(4): [PatternBindingDecl] var ... = ... +# 246| getElement(2): [PatternBindingDecl] var ... = ... # 246| getInit(0): [BinaryExpr] ... .*(_:_:) ... # 246| getFunction(): [MethodLookupExpr] .*(_:_:) # 246| getBase(): [TypeExpr] Int.Type @@ -1240,9 +1268,7 @@ cfg.swift: # 246| getArgument(1): [Argument] : b # 246| getExpr(): [DeclRefExpr] b # 246| getPattern(0): [NamedPattern] e -# 246| getElement(5): [ConcreteVarDecl] e -# 246| Type = Int -# 247| getElement(6): [PatternBindingDecl] var ... = ... +# 247| getElement(3): [PatternBindingDecl] var ... = ... # 247| getInit(0): [BinaryExpr] ... ./(_:_:) ... # 247| getFunction(): [MethodLookupExpr] ./(_:_:) # 247| getBase(): [TypeExpr] Int.Type @@ -1253,9 +1279,7 @@ cfg.swift: # 247| getArgument(1): [Argument] : b # 247| getExpr(): [DeclRefExpr] b # 247| getPattern(0): [NamedPattern] f -# 247| getElement(7): [ConcreteVarDecl] f -# 247| Type = Int -# 248| getElement(8): [PatternBindingDecl] var ... = ... +# 248| getElement(4): [PatternBindingDecl] var ... = ... # 248| getInit(0): [BinaryExpr] ... .%(_:_:) ... # 248| getFunction(): [MethodLookupExpr] .%(_:_:) # 248| getBase(): [TypeExpr] Int.Type @@ -1266,9 +1290,7 @@ cfg.swift: # 248| getArgument(1): [Argument] : b # 248| getExpr(): [DeclRefExpr] b # 248| getPattern(0): [NamedPattern] g -# 248| getElement(9): [ConcreteVarDecl] g -# 248| Type = Int -# 249| getElement(10): [PatternBindingDecl] var ... = ... +# 249| getElement(5): [PatternBindingDecl] var ... = ... # 249| getInit(0): [BinaryExpr] ... .&(_:_:) ... # 249| getFunction(): [MethodLookupExpr] .&(_:_:) # 249| getBase(): [TypeExpr] Int.Type @@ -1279,9 +1301,7 @@ cfg.swift: # 249| getArgument(1): [Argument] : b # 249| getExpr(): [DeclRefExpr] b # 249| getPattern(0): [NamedPattern] h -# 249| getElement(11): [ConcreteVarDecl] h -# 249| Type = Int -# 250| getElement(12): [PatternBindingDecl] var ... = ... +# 250| getElement(6): [PatternBindingDecl] var ... = ... # 250| getInit(0): [BinaryExpr] ... .|(_:_:) ... # 250| getFunction(): [MethodLookupExpr] .|(_:_:) # 250| getBase(): [TypeExpr] Int.Type @@ -1292,9 +1312,7 @@ cfg.swift: # 250| getArgument(1): [Argument] : b # 250| getExpr(): [DeclRefExpr] b # 250| getPattern(0): [NamedPattern] i -# 250| getElement(13): [ConcreteVarDecl] i -# 250| Type = Int -# 251| getElement(14): [PatternBindingDecl] var ... = ... +# 251| getElement(7): [PatternBindingDecl] var ... = ... # 251| getInit(0): [BinaryExpr] ... .^(_:_:) ... # 251| getFunction(): [MethodLookupExpr] .^(_:_:) # 251| getBase(): [TypeExpr] Int.Type @@ -1305,9 +1323,7 @@ cfg.swift: # 251| getArgument(1): [Argument] : b # 251| getExpr(): [DeclRefExpr] b # 251| getPattern(0): [NamedPattern] j -# 251| getElement(15): [ConcreteVarDecl] j -# 251| Type = Int -# 252| getElement(16): [PatternBindingDecl] var ... = ... +# 252| getElement(8): [PatternBindingDecl] var ... = ... # 252| getInit(0): [BinaryExpr] ... .<<(_:_:) ... # 252| getFunction(): [MethodLookupExpr] .<<(_:_:) # 252| getBase(): [TypeExpr] Int.Type @@ -1318,9 +1334,7 @@ cfg.swift: # 252| getArgument(1): [Argument] : b # 252| getExpr(): [DeclRefExpr] b # 252| getPattern(0): [NamedPattern] k -# 252| getElement(17): [ConcreteVarDecl] k -# 252| Type = Int -# 253| getElement(18): [PatternBindingDecl] var ... = ... +# 253| getElement(9): [PatternBindingDecl] var ... = ... # 253| getInit(0): [BinaryExpr] ... .>>(_:_:) ... # 253| getFunction(): [MethodLookupExpr] .>>(_:_:) # 253| getBase(): [TypeExpr] Int.Type @@ -1331,9 +1345,7 @@ cfg.swift: # 253| getArgument(1): [Argument] : b # 253| getExpr(): [DeclRefExpr] b # 253| getPattern(0): [NamedPattern] l -# 253| getElement(19): [ConcreteVarDecl] l -# 253| Type = Int -# 254| getElement(20): [PatternBindingDecl] var ... = ... +# 254| getElement(10): [PatternBindingDecl] var ... = ... # 254| getInit(0): [BinaryExpr] ... .==(_:_:) ... # 254| getFunction(): [MethodLookupExpr] .==(_:_:) # 254| getBase(): [TypeExpr] Int.Type @@ -1344,9 +1356,7 @@ cfg.swift: # 254| getArgument(1): [Argument] : b # 254| getExpr(): [DeclRefExpr] b # 254| getPattern(0): [NamedPattern] o -# 254| getElement(21): [ConcreteVarDecl] o -# 254| Type = Bool -# 255| getElement(22): [PatternBindingDecl] var ... = ... +# 255| getElement(11): [PatternBindingDecl] var ... = ... # 255| getInit(0): [BinaryExpr] ... .!=(_:_:) ... # 255| getFunction(): [MethodLookupExpr] .!=(_:_:) # 255| getBase(): [TypeExpr] Int.Type @@ -1357,9 +1367,7 @@ cfg.swift: # 255| getArgument(1): [Argument] : b # 255| getExpr(): [DeclRefExpr] b # 255| getPattern(0): [NamedPattern] p -# 255| getElement(23): [ConcreteVarDecl] p -# 255| Type = Bool -# 256| getElement(24): [PatternBindingDecl] var ... = ... +# 256| getElement(12): [PatternBindingDecl] var ... = ... # 256| getInit(0): [BinaryExpr] ... .<(_:_:) ... # 256| getFunction(): [MethodLookupExpr] .<(_:_:) # 256| getBase(): [TypeExpr] Int.Type @@ -1370,9 +1378,7 @@ cfg.swift: # 256| getArgument(1): [Argument] : b # 256| getExpr(): [DeclRefExpr] b # 256| getPattern(0): [NamedPattern] q -# 256| getElement(25): [ConcreteVarDecl] q -# 256| Type = Bool -# 257| getElement(26): [PatternBindingDecl] var ... = ... +# 257| getElement(13): [PatternBindingDecl] var ... = ... # 257| getInit(0): [BinaryExpr] ... .<=(_:_:) ... # 257| getFunction(): [MethodLookupExpr] .<=(_:_:) # 257| getBase(): [TypeExpr] Int.Type @@ -1383,9 +1389,7 @@ cfg.swift: # 257| getArgument(1): [Argument] : b # 257| getExpr(): [DeclRefExpr] b # 257| getPattern(0): [NamedPattern] r -# 257| getElement(27): [ConcreteVarDecl] r -# 257| Type = Bool -# 258| getElement(28): [PatternBindingDecl] var ... = ... +# 258| getElement(14): [PatternBindingDecl] var ... = ... # 258| getInit(0): [BinaryExpr] ... .>(_:_:) ... # 258| getFunction(): [MethodLookupExpr] .>(_:_:) # 258| getBase(): [TypeExpr] Int.Type @@ -1396,9 +1400,7 @@ cfg.swift: # 258| getArgument(1): [Argument] : b # 258| getExpr(): [DeclRefExpr] b # 258| getPattern(0): [NamedPattern] s -# 258| getElement(29): [ConcreteVarDecl] s -# 258| Type = Bool -# 259| getElement(30): [PatternBindingDecl] var ... = ... +# 259| getElement(15): [PatternBindingDecl] var ... = ... # 259| getInit(0): [BinaryExpr] ... .>=(_:_:) ... # 259| getFunction(): [MethodLookupExpr] .>=(_:_:) # 259| getBase(): [TypeExpr] Int.Type @@ -1409,8 +1411,6 @@ cfg.swift: # 259| getArgument(1): [Argument] : b # 259| getExpr(): [DeclRefExpr] b # 259| getPattern(0): [NamedPattern] t -# 259| getElement(31): [ConcreteVarDecl] t -# 259| Type = Bool # 262| [NamedFunction] interpolatedString(x:y:) # 262| InterfaceType = (Int, Int) -> String # 262| getParam(0): [ParamDecl] x @@ -1423,44 +1423,44 @@ cfg.swift: # 263| getAppendingExpr(): [TapExpr] TapExpr # 263| getSubExpr(): [OpaqueValueExpr] OpaqueValueExpr # 263| getBody(): [BraceStmt] { ... } -#-----| getElement(0): [ConcreteVarDecl] $interpolation +#-----| getVariable(0): [ConcreteVarDecl] $interpolation #-----| Type = DefaultStringInterpolation -# 263| getElement(1): [CallExpr] call to appendLiteral(_:) +# 263| getElement(0): [CallExpr] call to appendLiteral(_:) # 263| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation #-----| getMethodRef(): [DeclRefExpr] appendLiteral(_:) # 263| getArgument(0): [Argument] : # 263| getExpr(): [StringLiteralExpr] -# 263| getElement(2): [CallExpr] call to appendInterpolation(_:) +# 263| getElement(1): [CallExpr] call to appendInterpolation(_:) # 263| getFunction(): [MethodLookupExpr] .appendInterpolation(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation # 263| getMethodRef(): [DeclRefExpr] appendInterpolation(_:) # 263| getArgument(0): [Argument] : x # 263| getExpr(): [DeclRefExpr] x -# 263| getElement(3): [CallExpr] call to appendLiteral(_:) +# 263| getElement(2): [CallExpr] call to appendLiteral(_:) # 263| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation #-----| getMethodRef(): [DeclRefExpr] appendLiteral(_:) # 263| getArgument(0): [Argument] : + # 263| getExpr(): [StringLiteralExpr] + -# 263| getElement(4): [CallExpr] call to appendInterpolation(_:) +# 263| getElement(3): [CallExpr] call to appendInterpolation(_:) # 263| getFunction(): [MethodLookupExpr] .appendInterpolation(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation # 263| getMethodRef(): [DeclRefExpr] appendInterpolation(_:) # 263| getArgument(0): [Argument] : y # 263| getExpr(): [DeclRefExpr] y -# 263| getElement(5): [CallExpr] call to appendLiteral(_:) +# 263| getElement(4): [CallExpr] call to appendLiteral(_:) # 263| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation #-----| getMethodRef(): [DeclRefExpr] appendLiteral(_:) # 263| getArgument(0): [Argument] : is equal to # 263| getExpr(): [StringLiteralExpr] is equal to -# 263| getElement(6): [CallExpr] call to appendInterpolation(_:) +# 263| getElement(5): [CallExpr] call to appendInterpolation(_:) # 263| getFunction(): [MethodLookupExpr] .appendInterpolation(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation @@ -1475,14 +1475,14 @@ cfg.swift: # 263| getExpr(): [DeclRefExpr] x # 263| getArgument(1): [Argument] : y # 263| getExpr(): [DeclRefExpr] y -# 263| getElement(7): [CallExpr] call to appendLiteral(_:) +# 263| getElement(6): [CallExpr] call to appendLiteral(_:) # 263| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation #-----| getMethodRef(): [DeclRefExpr] appendLiteral(_:) # 263| getArgument(0): [Argument] : and here is a zero: # 263| getExpr(): [StringLiteralExpr] and here is a zero: -# 263| getElement(8): [CallExpr] call to appendInterpolation(_:) +# 263| getElement(7): [CallExpr] call to appendInterpolation(_:) # 263| getFunction(): [MethodLookupExpr] .appendInterpolation(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation @@ -1490,7 +1490,7 @@ cfg.swift: # 263| getArgument(0): [Argument] : call to returnZero() # 263| getExpr(): [CallExpr] call to returnZero() # 263| getFunction(): [DeclRefExpr] returnZero() -# 263| getElement(9): [CallExpr] call to appendLiteral(_:) +# 263| getElement(8): [CallExpr] call to appendLiteral(_:) # 263| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 263| getBase(): [InOutExpr] &... # 263| getSubExpr(): [DeclRefExpr] $interpolation @@ -1500,6 +1500,22 @@ cfg.swift: # 266| [NamedFunction] testSubscriptExpr() # 266| InterfaceType = () -> (Int, Int, Int, Int, Int) # 266| getBody(): [BraceStmt] { ... } +# 267| getVariable(0): [ConcreteVarDecl] a +# 267| Type = [Int] +# 280| getVariable(1): [ConcreteVarDecl] tupleWithA +# 280| Type = (Int, Int, Int, Int, Int) +# 282| getVariable(2): [ConcreteVarDecl] b +# 282| Type = [Int] +# 295| getVariable(3): [ConcreteVarDecl] a1 +# 295| Type = Int +# 295| getVariable(4): [ConcreteVarDecl] a2 +# 295| Type = Int +# 295| getVariable(5): [ConcreteVarDecl] a3 +# 295| Type = Int +# 295| getVariable(6): [ConcreteVarDecl] a4 +# 295| Type = Int +# 295| getVariable(7): [ConcreteVarDecl] a5 +# 295| Type = Int # 267| getElement(0): [PatternBindingDecl] var ... = ... # 267| getInit(0): [ArrayExpr] [...] # 267| getElement(0): [IntegerLiteralExpr] 0 @@ -1514,16 +1530,14 @@ cfg.swift: # 267| getElement(9): [IntegerLiteralExpr] 9 # 267| getElement(10): [IntegerLiteralExpr] 10 # 267| getPattern(0): [NamedPattern] a -# 267| getElement(1): [ConcreteVarDecl] a -# 267| Type = [Int] -# 268| getElement(2): [AssignExpr] ... = ... +# 268| getElement(1): [AssignExpr] ... = ... # 268| getDest(): [SubscriptExpr] ...[...] # 268| getBase(): [InOutExpr] &... # 268| getSubExpr(): [DeclRefExpr] a # 268| getArgument(0): [Argument] : 0 # 268| getExpr(): [IntegerLiteralExpr] 0 # 268| getSource(): [IntegerLiteralExpr] 0 -# 269| getElement(3): [BinaryExpr] ... .+=(_:_:) ... +# 269| getElement(2): [BinaryExpr] ... .+=(_:_:) ... # 269| getFunction(): [MethodLookupExpr] .+=(_:_:) # 269| getBase(): [TypeExpr] Int.Type # 269| getTypeRepr(): [TypeRepr] Int @@ -1537,7 +1551,7 @@ cfg.swift: # 269| getExpr(): [IntegerLiteralExpr] 1 # 269| getArgument(1): [Argument] : 1 # 269| getExpr(): [IntegerLiteralExpr] 1 -# 270| getElement(4): [BinaryExpr] ... .-=(_:_:) ... +# 270| getElement(3): [BinaryExpr] ... .-=(_:_:) ... # 270| getFunction(): [MethodLookupExpr] .-=(_:_:) # 270| getBase(): [TypeExpr] Int.Type # 270| getTypeRepr(): [TypeRepr] Int @@ -1551,7 +1565,7 @@ cfg.swift: # 270| getExpr(): [IntegerLiteralExpr] 2 # 270| getArgument(1): [Argument] : 1 # 270| getExpr(): [IntegerLiteralExpr] 1 -# 271| getElement(5): [BinaryExpr] ... .*=(_:_:) ... +# 271| getElement(4): [BinaryExpr] ... .*=(_:_:) ... # 271| getFunction(): [MethodLookupExpr] .*=(_:_:) # 271| getBase(): [TypeExpr] Int.Type # 271| getTypeRepr(): [TypeRepr] Int @@ -1565,7 +1579,7 @@ cfg.swift: # 271| getExpr(): [IntegerLiteralExpr] 3 # 271| getArgument(1): [Argument] : 1 # 271| getExpr(): [IntegerLiteralExpr] 1 -# 272| getElement(6): [BinaryExpr] ... ./=(_:_:) ... +# 272| getElement(5): [BinaryExpr] ... ./=(_:_:) ... # 272| getFunction(): [MethodLookupExpr] ./=(_:_:) # 272| getBase(): [TypeExpr] Int.Type # 272| getTypeRepr(): [TypeRepr] Int @@ -1579,7 +1593,7 @@ cfg.swift: # 272| getExpr(): [IntegerLiteralExpr] 4 # 272| getArgument(1): [Argument] : 1 # 272| getExpr(): [IntegerLiteralExpr] 1 -# 273| getElement(7): [BinaryExpr] ... .%=(_:_:) ... +# 273| getElement(6): [BinaryExpr] ... .%=(_:_:) ... # 273| getFunction(): [MethodLookupExpr] .%=(_:_:) # 273| getBase(): [TypeExpr] Int.Type # 273| getTypeRepr(): [TypeRepr] Int @@ -1593,7 +1607,7 @@ cfg.swift: # 273| getExpr(): [IntegerLiteralExpr] 5 # 273| getArgument(1): [Argument] : 1 # 273| getExpr(): [IntegerLiteralExpr] 1 -# 274| getElement(8): [BinaryExpr] ... .&=(_:_:) ... +# 274| getElement(7): [BinaryExpr] ... .&=(_:_:) ... # 274| getFunction(): [MethodLookupExpr] .&=(_:_:) # 274| getBase(): [TypeExpr] Int.Type # 274| getTypeRepr(): [TypeRepr] Int @@ -1607,7 +1621,7 @@ cfg.swift: # 274| getExpr(): [IntegerLiteralExpr] 6 # 274| getArgument(1): [Argument] : 1 # 274| getExpr(): [IntegerLiteralExpr] 1 -# 275| getElement(9): [BinaryExpr] ... .|=(_:_:) ... +# 275| getElement(8): [BinaryExpr] ... .|=(_:_:) ... # 275| getFunction(): [MethodLookupExpr] .|=(_:_:) # 275| getBase(): [TypeExpr] Int.Type # 275| getTypeRepr(): [TypeRepr] Int @@ -1621,7 +1635,7 @@ cfg.swift: # 275| getExpr(): [IntegerLiteralExpr] 7 # 275| getArgument(1): [Argument] : 1 # 275| getExpr(): [IntegerLiteralExpr] 1 -# 276| getElement(10): [BinaryExpr] ... .^=(_:_:) ... +# 276| getElement(9): [BinaryExpr] ... .^=(_:_:) ... # 276| getFunction(): [MethodLookupExpr] .^=(_:_:) # 276| getBase(): [TypeExpr] Int.Type # 276| getTypeRepr(): [TypeRepr] Int @@ -1635,7 +1649,7 @@ cfg.swift: # 276| getExpr(): [IntegerLiteralExpr] 8 # 276| getArgument(1): [Argument] : 1 # 276| getExpr(): [IntegerLiteralExpr] 1 -# 277| getElement(11): [BinaryExpr] ... .<<=(_:_:) ... +# 277| getElement(10): [BinaryExpr] ... .<<=(_:_:) ... # 277| getFunction(): [MethodLookupExpr] .<<=(_:_:) # 277| getBase(): [TypeExpr] Int.Type # 277| getTypeRepr(): [TypeRepr] Int @@ -1649,7 +1663,7 @@ cfg.swift: # 277| getExpr(): [IntegerLiteralExpr] 9 # 277| getArgument(1): [Argument] : 1 # 277| getExpr(): [IntegerLiteralExpr] 1 -# 278| getElement(12): [BinaryExpr] ... .>>=(_:_:) ... +# 278| getElement(11): [BinaryExpr] ... .>>=(_:_:) ... # 278| getFunction(): [MethodLookupExpr] .>>=(_:_:) # 278| getBase(): [TypeExpr] Int.Type # 278| getTypeRepr(): [TypeRepr] Int @@ -1663,7 +1677,7 @@ cfg.swift: # 278| getExpr(): [IntegerLiteralExpr] 10 # 278| getArgument(1): [Argument] : 1 # 278| getExpr(): [IntegerLiteralExpr] 1 -# 280| getElement(13): [PatternBindingDecl] var ... = ... +# 280| getElement(12): [PatternBindingDecl] var ... = ... # 280| getInit(0): [TupleExpr] (...) # 280| getElement(0): [SubscriptExpr] ...[...] # 280| getBase(): [InOutExpr] &... @@ -1696,9 +1710,7 @@ cfg.swift: # 280| getExpr(): [IntegerLiteralExpr] 4 # 280| getElement(4).getFullyConverted(): [LoadExpr] (Int) ... # 280| getPattern(0): [NamedPattern] tupleWithA -# 280| getElement(14): [ConcreteVarDecl] tupleWithA -# 280| Type = (Int, Int, Int, Int, Int) -# 282| getElement(15): [PatternBindingDecl] var ... = ... +# 282| getElement(13): [PatternBindingDecl] var ... = ... # 282| getInit(0): [ArrayExpr] [...] # 282| getElement(0): [IntegerLiteralExpr] 0 # 282| getElement(1): [IntegerLiteralExpr] 1 @@ -1713,9 +1725,7 @@ cfg.swift: # 282| getElement(10): [IntegerLiteralExpr] 10 # 282| getElement(11): [IntegerLiteralExpr] 11 # 282| getPattern(0): [NamedPattern] b -# 282| getElement(16): [ConcreteVarDecl] b -# 282| Type = [Int] -# 283| getElement(17): [AssignExpr] ... = ... +# 283| getElement(14): [AssignExpr] ... = ... # 283| getDest(): [SubscriptExpr] ...[...] # 283| getBase(): [InOutExpr] &... # 283| getSubExpr(): [DeclRefExpr] b @@ -1727,7 +1737,7 @@ cfg.swift: # 283| getArgument(0): [Argument] : 10 # 283| getExpr(): [IntegerLiteralExpr] 10 # 283| getSource().getFullyConverted(): [LoadExpr] (Int) ... -# 284| getElement(18): [AssignExpr] ... = ... +# 284| getElement(15): [AssignExpr] ... = ... # 284| getDest(): [SubscriptExpr] ...[...] # 284| getBase(): [InOutExpr] &... # 284| getSubExpr(): [DeclRefExpr] b @@ -1747,7 +1757,7 @@ cfg.swift: # 284| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 284| getArgument(1): [Argument] : 1 # 284| getExpr(): [IntegerLiteralExpr] 1 -# 285| getElement(19): [AssignExpr] ... = ... +# 285| getElement(16): [AssignExpr] ... = ... # 285| getDest(): [SubscriptExpr] ...[...] # 285| getBase(): [InOutExpr] &... # 285| getSubExpr(): [DeclRefExpr] b @@ -1767,7 +1777,7 @@ cfg.swift: # 285| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 285| getArgument(1): [Argument] : 1 # 285| getExpr(): [IntegerLiteralExpr] 1 -# 286| getElement(20): [AssignExpr] ... = ... +# 286| getElement(17): [AssignExpr] ... = ... # 286| getDest(): [SubscriptExpr] ...[...] # 286| getBase(): [InOutExpr] &... # 286| getSubExpr(): [DeclRefExpr] b @@ -1787,7 +1797,7 @@ cfg.swift: # 286| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 286| getArgument(1): [Argument] : 1 # 286| getExpr(): [IntegerLiteralExpr] 1 -# 287| getElement(21): [AssignExpr] ... = ... +# 287| getElement(18): [AssignExpr] ... = ... # 287| getDest(): [SubscriptExpr] ...[...] # 287| getBase(): [InOutExpr] &... # 287| getSubExpr(): [DeclRefExpr] b @@ -1807,7 +1817,7 @@ cfg.swift: # 287| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 287| getArgument(1): [Argument] : 1 # 287| getExpr(): [IntegerLiteralExpr] 1 -# 288| getElement(22): [AssignExpr] ... = ... +# 288| getElement(19): [AssignExpr] ... = ... # 288| getDest(): [SubscriptExpr] ...[...] # 288| getBase(): [InOutExpr] &... # 288| getSubExpr(): [DeclRefExpr] b @@ -1827,7 +1837,7 @@ cfg.swift: # 288| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 288| getArgument(1): [Argument] : 1 # 288| getExpr(): [IntegerLiteralExpr] 1 -# 289| getElement(23): [AssignExpr] ... = ... +# 289| getElement(20): [AssignExpr] ... = ... # 289| getDest(): [SubscriptExpr] ...[...] # 289| getBase(): [InOutExpr] &... # 289| getSubExpr(): [DeclRefExpr] b @@ -1847,7 +1857,7 @@ cfg.swift: # 289| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 289| getArgument(1): [Argument] : 1 # 289| getExpr(): [IntegerLiteralExpr] 1 -# 290| getElement(24): [AssignExpr] ... = ... +# 290| getElement(21): [AssignExpr] ... = ... # 290| getDest(): [SubscriptExpr] ...[...] # 290| getBase(): [InOutExpr] &... # 290| getSubExpr(): [DeclRefExpr] b @@ -1867,7 +1877,7 @@ cfg.swift: # 290| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 290| getArgument(1): [Argument] : 1 # 290| getExpr(): [IntegerLiteralExpr] 1 -# 291| getElement(25): [AssignExpr] ... = ... +# 291| getElement(22): [AssignExpr] ... = ... # 291| getDest(): [SubscriptExpr] ...[...] # 291| getBase(): [InOutExpr] &... # 291| getSubExpr(): [DeclRefExpr] b @@ -1887,7 +1897,7 @@ cfg.swift: # 291| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 291| getArgument(1): [Argument] : 1 # 291| getExpr(): [IntegerLiteralExpr] 1 -# 292| getElement(26): [AssignExpr] ... = ... +# 292| getElement(23): [AssignExpr] ... = ... # 292| getDest(): [SubscriptExpr] ...[...] # 292| getBase(): [InOutExpr] &... # 292| getSubExpr(): [DeclRefExpr] b @@ -1907,7 +1917,7 @@ cfg.swift: # 292| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 292| getArgument(1): [Argument] : 1 # 292| getExpr(): [IntegerLiteralExpr] 1 -# 293| getElement(27): [AssignExpr] ... = ... +# 293| getElement(24): [AssignExpr] ... = ... # 293| getDest(): [SubscriptExpr] ...[...] # 293| getBase(): [InOutExpr] &... # 293| getSubExpr(): [DeclRefExpr] b @@ -1927,7 +1937,7 @@ cfg.swift: # 293| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 293| getArgument(1): [Argument] : 1 # 293| getExpr(): [IntegerLiteralExpr] 1 -# 295| getElement(28): [PatternBindingDecl] var ... = ... +# 295| getElement(25): [PatternBindingDecl] var ... = ... # 295| getInit(0): [DeclRefExpr] tupleWithA # 295| getInit(0).getFullyConverted(): [LoadExpr] ((Int, Int, Int, Int, Int)) ... # 295| getPattern(0): [TuplePattern] (...) @@ -1936,17 +1946,7 @@ cfg.swift: # 295| getElement(2): [NamedPattern] a3 # 295| getElement(3): [NamedPattern] a4 # 295| getElement(4): [NamedPattern] a5 -# 295| getElement(29): [ConcreteVarDecl] a1 -# 295| Type = Int -# 295| getElement(30): [ConcreteVarDecl] a2 -# 295| Type = Int -# 295| getElement(31): [ConcreteVarDecl] a3 -# 295| Type = Int -# 295| getElement(32): [ConcreteVarDecl] a4 -# 295| Type = Int -# 295| getElement(33): [ConcreteVarDecl] a5 -# 295| Type = Int -# 296| getElement(34): [ReturnStmt] return ... +# 296| getElement(26): [ReturnStmt] return ... # 296| getResult(): [TupleExpr] (...) # 296| getElement(0): [BinaryExpr] ... .+(_:_:) ... # 296| getFunction(): [MethodLookupExpr] .+(_:_:) @@ -2301,12 +2301,12 @@ cfg.swift: # 345| [NamedFunction] loop_with_identity_expr() # 345| InterfaceType = () -> () # 345| getBody(): [BraceStmt] { ... } +# 346| getVariable(0): [ConcreteVarDecl] x +# 346| Type = Int # 346| getElement(0): [PatternBindingDecl] var ... = ... # 346| getInit(0): [IntegerLiteralExpr] 0 # 346| getPattern(0): [NamedPattern] x -# 346| getElement(1): [ConcreteVarDecl] x -# 346| Type = Int -# 347| getElement(2): [WhileStmt] while ... { ... } +# 347| getElement(1): [WhileStmt] while ... { ... } # 347| getCondition(): [StmtCondition] StmtCondition # 347| getElement(0): [ConditionElement] ... .<(_:_:) ... # 347| getBoolean(): [BinaryExpr] ... .<(_:_:) ... @@ -2608,6 +2608,8 @@ cfg.swift: # 408| [NamedFunction] localDeclarations() # 408| InterfaceType = () -> Int # 408| getBody(): [BraceStmt] { ... } +# 428| getVariable(0): [ConcreteVarDecl] myLocalVar +# 428| Type = Int # 409| getElement(0): [ClassDecl] MyLocalClass # 410| getMember(0): [PatternBindingDecl] var ... = ... # 410| getPattern(0): [TypedPattern] ... as ... @@ -2814,9 +2816,7 @@ cfg.swift: # 428| getPattern(0): [TypedPattern] ... as ... # 428| getSubPattern(): [NamedPattern] myLocalVar # 428| getTypeRepr(): [TypeRepr] Int -# 428| getElement(4): [ConcreteVarDecl] myLocalVar -# 428| Type = Int -# 442| getElement(5): [ReturnStmt] return ... +# 442| getElement(4): [ReturnStmt] return ... # 442| getResult(): [IntegerLiteralExpr] 0 # 430| [Comment] // Error: declaration is only valid at file scope # 430| @@ -2998,15 +2998,29 @@ cfg.swift: # 455| getParam(0): [ParamDecl] a # 455| Type = A # 455| getBody(): [BraceStmt] { ... } +# 456| getVariable(0): [ConcreteVarDecl] kpGet_b_x +# 456| Type = WritableKeyPath<A, Int> +# 457| getVariable(1): [ConcreteVarDecl] kpGet_bs_0_x +# 457| Type = WritableKeyPath<A, Int> +# 458| getVariable(2): [ConcreteVarDecl] kpGet_mayB_force_x +# 458| Type = WritableKeyPath<A, Int> +# 459| getVariable(3): [ConcreteVarDecl] kpGet_mayB_x +# 459| Type = KeyPath<A, Int?> +# 461| getVariable(4): [ConcreteVarDecl] apply_kpGet_b_x +# 461| Type = Int +# 462| getVariable(5): [ConcreteVarDecl] apply_kpGet_bs_0_x +# 462| Type = Int +# 463| getVariable(6): [ConcreteVarDecl] apply_kpGet_mayB_force_x +# 463| Type = Int +# 464| getVariable(7): [ConcreteVarDecl] apply_kpGet_mayB_x +# 464| Type = Int? # 456| getElement(0): [PatternBindingDecl] var ... = ... # 456| getInit(0): [KeyPathExpr] #keyPath(...) # 456| getRoot(): [TypeRepr] A # 456| getComponent(0): [KeyPathComponent] KeyPathComponent # 456| getComponent(1): [KeyPathComponent] KeyPathComponent # 456| getPattern(0): [NamedPattern] kpGet_b_x -# 456| getElement(1): [ConcreteVarDecl] kpGet_b_x -# 456| Type = WritableKeyPath<A, Int> -# 457| getElement(2): [PatternBindingDecl] var ... = ... +# 457| getElement(1): [PatternBindingDecl] var ... = ... # 457| getInit(0): [KeyPathExpr] #keyPath(...) # 457| getRoot(): [TypeRepr] A # 457| getComponent(0): [KeyPathComponent] KeyPathComponent @@ -3015,18 +3029,14 @@ cfg.swift: # 457| getExpr(): [IntegerLiteralExpr] 0 # 457| getComponent(2): [KeyPathComponent] KeyPathComponent # 457| getPattern(0): [NamedPattern] kpGet_bs_0_x -# 457| getElement(3): [ConcreteVarDecl] kpGet_bs_0_x -# 457| Type = WritableKeyPath<A, Int> -# 458| getElement(4): [PatternBindingDecl] var ... = ... +# 458| getElement(2): [PatternBindingDecl] var ... = ... # 458| getInit(0): [KeyPathExpr] #keyPath(...) # 458| getRoot(): [TypeRepr] A # 458| getComponent(0): [KeyPathComponent] KeyPathComponent # 458| getComponent(1): [KeyPathComponent] KeyPathComponent # 458| getComponent(2): [KeyPathComponent] KeyPathComponent # 458| getPattern(0): [NamedPattern] kpGet_mayB_force_x -# 458| getElement(5): [ConcreteVarDecl] kpGet_mayB_force_x -# 458| Type = WritableKeyPath<A, Int> -# 459| getElement(6): [PatternBindingDecl] var ... = ... +# 459| getElement(3): [PatternBindingDecl] var ... = ... # 459| getInit(0): [KeyPathExpr] #keyPath(...) # 459| getRoot(): [TypeRepr] A # 459| getComponent(0): [KeyPathComponent] KeyPathComponent @@ -3034,40 +3044,30 @@ cfg.swift: # 459| getComponent(2): [KeyPathComponent] KeyPathComponent #-----| getComponent(3): [KeyPathComponent] KeyPathComponent # 459| getPattern(0): [NamedPattern] kpGet_mayB_x -# 459| getElement(7): [ConcreteVarDecl] kpGet_mayB_x -# 459| Type = KeyPath<A, Int?> -# 461| getElement(8): [PatternBindingDecl] var ... = ... +# 461| getElement(4): [PatternBindingDecl] var ... = ... # 461| getInit(0): [KeyPathApplicationExpr] \...[...] # 461| getBase(): [DeclRefExpr] a # 461| getKeyPath(): [DeclRefExpr] kpGet_b_x # 461| getKeyPath().getFullyConverted(): [LoadExpr] (WritableKeyPath<A, Int>) ... # 461| getPattern(0): [NamedPattern] apply_kpGet_b_x -# 461| getElement(9): [ConcreteVarDecl] apply_kpGet_b_x -# 461| Type = Int -# 462| getElement(10): [PatternBindingDecl] var ... = ... +# 462| getElement(5): [PatternBindingDecl] var ... = ... # 462| getInit(0): [KeyPathApplicationExpr] \...[...] # 462| getBase(): [DeclRefExpr] a # 462| getKeyPath(): [DeclRefExpr] kpGet_bs_0_x # 462| getKeyPath().getFullyConverted(): [LoadExpr] (WritableKeyPath<A, Int>) ... # 462| getPattern(0): [NamedPattern] apply_kpGet_bs_0_x -# 462| getElement(11): [ConcreteVarDecl] apply_kpGet_bs_0_x -# 462| Type = Int -# 463| getElement(12): [PatternBindingDecl] var ... = ... +# 463| getElement(6): [PatternBindingDecl] var ... = ... # 463| getInit(0): [KeyPathApplicationExpr] \...[...] # 463| getBase(): [DeclRefExpr] a # 463| getKeyPath(): [DeclRefExpr] kpGet_mayB_force_x # 463| getKeyPath().getFullyConverted(): [LoadExpr] (WritableKeyPath<A, Int>) ... # 463| getPattern(0): [NamedPattern] apply_kpGet_mayB_force_x -# 463| getElement(13): [ConcreteVarDecl] apply_kpGet_mayB_force_x -# 463| Type = Int -# 464| getElement(14): [PatternBindingDecl] var ... = ... +# 464| getElement(7): [PatternBindingDecl] var ... = ... # 464| getInit(0): [KeyPathApplicationExpr] \...[...] # 464| getBase(): [DeclRefExpr] a # 464| getKeyPath(): [DeclRefExpr] kpGet_mayB_x # 464| getKeyPath().getFullyConverted(): [LoadExpr] (KeyPath<A, Int?>) ... # 464| getPattern(0): [NamedPattern] apply_kpGet_mayB_x -# 464| getElement(15): [ConcreteVarDecl] apply_kpGet_mayB_x -# 464| Type = Int? # 467| [NamedFunction] testIfConfig() # 467| InterfaceType = () -> () # 467| getBody(): [BraceStmt] { ... } @@ -3084,12 +3084,12 @@ cfg.swift: # 496| [NamedFunction] testAvailable() # 496| InterfaceType = () -> Int # 496| getBody(): [BraceStmt] { ... } +# 497| getVariable(0): [ConcreteVarDecl] x +# 497| Type = Int # 497| getElement(0): [PatternBindingDecl] var ... = ... # 497| getInit(0): [IntegerLiteralExpr] 0 # 497| getPattern(0): [NamedPattern] x -# 497| getElement(1): [ConcreteVarDecl] x -# 497| Type = Int -# 499| getElement(2): [IfStmt] if ... then { ... } +# 499| getElement(1): [IfStmt] if ... then { ... } # 499| getCondition(): [StmtCondition] StmtCondition # 499| getElement(0): [ConditionElement] #available # 499| getAvailability(): [AvailabilityInfo] #available @@ -3106,7 +3106,7 @@ cfg.swift: # 500| getSubExpr(): [DeclRefExpr] x # 500| getArgument(1): [Argument] : 1 # 500| getExpr(): [IntegerLiteralExpr] 1 -# 503| getElement(3): [IfStmt] if ... then { ... } +# 503| getElement(2): [IfStmt] if ... then { ... } # 503| getCondition(): [StmtCondition] StmtCondition # 503| getElement(0): [ConditionElement] #available # 503| getAvailability(): [AvailabilityInfo] #available @@ -3123,7 +3123,7 @@ cfg.swift: # 504| getSubExpr(): [DeclRefExpr] x # 504| getArgument(1): [Argument] : 1 # 504| getExpr(): [IntegerLiteralExpr] 1 -# 507| getElement(4): [IfStmt] if ... then { ... } +# 507| getElement(3): [IfStmt] if ... then { ... } # 507| getCondition(): [StmtCondition] StmtCondition # 507| getElement(0): [ConditionElement] #unavailable # 507| getAvailability(): [AvailabilityInfo] #unavailable @@ -3141,7 +3141,7 @@ cfg.swift: # 508| getSubExpr(): [DeclRefExpr] x # 508| getArgument(1): [Argument] : 1 # 508| getExpr(): [IntegerLiteralExpr] 1 -# 511| getElement(5): [GuardStmt] guard ... else { ... } +# 511| getElement(4): [GuardStmt] guard ... else { ... } # 511| getCondition(): [StmtCondition] StmtCondition # 511| getElement(0): [ConditionElement] #available # 511| getAvailability(): [AvailabilityInfo] #available @@ -3158,7 +3158,7 @@ cfg.swift: # 512| getSubExpr(): [DeclRefExpr] x # 512| getArgument(1): [Argument] : 1 # 512| getExpr(): [IntegerLiteralExpr] 1 -# 515| getElement(6): [IfStmt] if ... then { ... } +# 515| getElement(5): [IfStmt] if ... then { ... } # 515| getCondition(): [StmtCondition] StmtCondition # 515| getElement(0): [ConditionElement] #available # 515| getAvailability(): [AvailabilityInfo] #available @@ -3179,7 +3179,7 @@ cfg.swift: # 516| getSubExpr(): [DeclRefExpr] x # 516| getArgument(1): [Argument] : 1 # 516| getExpr(): [IntegerLiteralExpr] 1 -# 519| getElement(7): [ReturnStmt] return ... +# 519| getElement(6): [ReturnStmt] return ... # 519| getResult(): [DeclRefExpr] x # 519| getResult().getFullyConverted(): [LoadExpr] (Int) ... declarations.swift: @@ -3685,11 +3685,7 @@ declarations.swift: # 76| [NamedFunction] foo() # 76| InterfaceType = () -> Int # 76| getBody(): [BraceStmt] { ... } -# 77| getElement(0): [PatternBindingDecl] var ... = ... -# 77| getPattern(0): [TypedPattern] ... as ... -# 77| getSubPattern(): [NamedPattern] x -# 77| getTypeRepr(): [TypeRepr] Int -# 77| getElement(1): [ConcreteVarDecl] x +# 77| getVariable(0): [ConcreteVarDecl] x # 77| Type = Int # 77| getAccessor(0): [Accessor] get # 77| InterfaceType = () -> Int @@ -3708,7 +3704,11 @@ declarations.swift: # 77| getSubPattern(): [NamedPattern] _x # 77| getPropertyWrapperBackingVar(): [ConcreteVarDecl] _x # 77| Type = ZeroWrapper -# 78| getElement(2): [ReturnStmt] return ... +# 77| getElement(0): [PatternBindingDecl] var ... = ... +# 77| getPattern(0): [TypedPattern] ... as ... +# 77| getSubPattern(): [NamedPattern] x +# 77| getTypeRepr(): [TypeRepr] Int +# 78| getElement(1): [ReturnStmt] return ... # 78| getResult(): [DeclRefExpr] x # 81| [StructDecl] HasPropertyAndObserver # 82| getMember(0): [PatternBindingDecl] var ... = ... @@ -3974,18 +3974,18 @@ declarations.swift: # 123| getParam(0): [ParamDecl] value # 123| Type = Int # 123| getBody(): [BraceStmt] { ... } +#-----| getVariable(0): [ConcreteVarDecl] tmp +#-----| Type = Int #-----| getElement(0): [PatternBindingDecl] var ... = ... #-----| getInit(0): [MemberRefExpr] .hasDidSet1 #-----| getBase(): [DeclRefExpr] self #-----| getInit(0).getFullyConverted(): [LoadExpr] (Int) ... #-----| getPattern(0): [NamedPattern] tmp -#-----| getElement(1): [ConcreteVarDecl] tmp -#-----| Type = Int -#-----| getElement(2): [AssignExpr] ... = ... +#-----| getElement(1): [AssignExpr] ... = ... #-----| getDest(): [MemberRefExpr] .hasDidSet1 #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -#-----| getElement(3): [CallExpr] call to didSet +#-----| getElement(2): [CallExpr] call to didSet #-----| getFunction(): [MethodLookupExpr] .didSet #-----| getBase(): [InOutExpr] &... #-----| getSubExpr(): [DeclRefExpr] self @@ -4292,23 +4292,23 @@ expressions.swift: # 7| getAppendingExpr(): [TapExpr] TapExpr # 7| getSubExpr(): [OpaqueValueExpr] OpaqueValueExpr # 7| getBody(): [BraceStmt] { ... } -#-----| getElement(0): [ConcreteVarDecl] $interpolation +#-----| getVariable(0): [ConcreteVarDecl] $interpolation #-----| Type = DefaultStringInterpolation -# 7| getElement(1): [CallExpr] call to appendLiteral(_:) +# 7| getElement(0): [CallExpr] call to appendLiteral(_:) # 7| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 7| getBase(): [InOutExpr] &... # 7| getSubExpr(): [DeclRefExpr] $interpolation #-----| getMethodRef(): [DeclRefExpr] appendLiteral(_:) # 7| getArgument(0): [Argument] : hello # 7| getExpr(): [StringLiteralExpr] hello -# 7| getElement(2): [CallExpr] call to appendInterpolation(_:) +# 7| getElement(1): [CallExpr] call to appendInterpolation(_:) # 7| getFunction(): [MethodLookupExpr] .appendInterpolation(_:) # 7| getBase(): [InOutExpr] &... # 7| getSubExpr(): [DeclRefExpr] $interpolation # 7| getMethodRef(): [DeclRefExpr] appendInterpolation(_:) # 7| getArgument(0): [Argument] : a # 7| getExpr(): [DeclRefExpr] a -# 7| getElement(3): [CallExpr] call to appendLiteral(_:) +# 7| getElement(2): [CallExpr] call to appendLiteral(_:) # 7| getFunction(): [MethodLookupExpr] .appendLiteral(_:) # 7| getBase(): [InOutExpr] &... # 7| getSubExpr(): [DeclRefExpr] $interpolation @@ -5025,6 +5025,14 @@ expressions.swift: # 130| getParam(0): [ParamDecl] hp # 130| Type = HasProperty # 130| getBody(): [BraceStmt] { ... } +# 132| getVariable(0): [ConcreteVarDecl] x +# 132| Type = Int +# 133| getVariable(1): [ConcreteVarDecl] y +# 133| Type = Int +# 134| getVariable(2): [ConcreteVarDecl] z +# 134| Type = Int +# 136| getVariable(3): [ConcreteVarDecl] w +# 136| Type = Int # 131| getElement(0): [AssignExpr] ... = ... # 131| getDest(): [MemberRefExpr] .settableField # 131| getBase(): [DeclRefExpr] hp @@ -5034,41 +5042,33 @@ expressions.swift: # 132| getBase(): [DeclRefExpr] hp # 132| getInit(0).getFullyConverted(): [LoadExpr] (Int) ... # 132| getPattern(0): [NamedPattern] x -# 132| getElement(2): [ConcreteVarDecl] x -# 132| Type = Int -# 133| getElement(3): [PatternBindingDecl] var ... = ... +# 133| getElement(2): [PatternBindingDecl] var ... = ... # 133| getInit(0): [MemberRefExpr] .readOnlyField1 # 133| getBase(): [DeclRefExpr] hp # 133| getBase().getFullyConverted(): [LoadExpr] (HasProperty) ... # 133| getPattern(0): [NamedPattern] y -# 133| getElement(4): [ConcreteVarDecl] y -# 133| Type = Int -# 134| getElement(5): [PatternBindingDecl] var ... = ... +# 134| getElement(3): [PatternBindingDecl] var ... = ... # 134| getInit(0): [MemberRefExpr] .readOnlyField2 # 134| getBase(): [DeclRefExpr] hp # 134| getBase().getFullyConverted(): [LoadExpr] (HasProperty) ... # 134| getPattern(0): [NamedPattern] z -# 134| getElement(6): [ConcreteVarDecl] z -# 134| Type = Int -# 135| getElement(7): [AssignExpr] ... = ... +# 135| getElement(4): [AssignExpr] ... = ... # 135| getDest(): [MemberRefExpr] .normalField # 135| getBase(): [DeclRefExpr] hp # 135| getSource(): [IntegerLiteralExpr] 99 -# 136| getElement(8): [PatternBindingDecl] var ... = ... +# 136| getElement(5): [PatternBindingDecl] var ... = ... # 136| getInit(0): [MemberRefExpr] .normalField # 136| getBase(): [DeclRefExpr] hp # 136| getInit(0).getFullyConverted(): [LoadExpr] (Int) ... # 136| getPattern(0): [NamedPattern] w -# 136| getElement(9): [ConcreteVarDecl] w -# 136| Type = Int -# 137| getElement(10): [AssignExpr] ... = ... +# 137| getElement(6): [AssignExpr] ... = ... # 137| getDest(): [SubscriptExpr] ...[...] # 137| getBase(): [InOutExpr] &... # 137| getSubExpr(): [DeclRefExpr] hp # 137| getArgument(0): [Argument] : 1 # 137| getExpr(): [IntegerLiteralExpr] 1 # 137| getSource(): [IntegerLiteralExpr] 2 -# 138| getElement(11): [ReturnStmt] return ... +# 138| getElement(7): [ReturnStmt] return ... # 138| getResult(): [SubscriptExpr] ...[...] # 138| getBase(): [DeclRefExpr] hp # 138| getBase().getFullyConverted(): [LoadExpr] (HasProperty) ... @@ -5240,21 +5240,23 @@ expressions.swift: # 151| getParam(2): [ParamDecl] keyPathB # 151| Type = WritableKeyPath<A, B> # 151| getBody(): [BraceStmt] { ... } +# 152| getVariable(0): [ConcreteVarDecl] apply_keyPathInt +# 152| Type = Int +# 153| getVariable(1): [ConcreteVarDecl] apply_keyPathB +# 153| Type = B +# 154| getVariable(2): [ConcreteVarDecl] nested_apply +# 154| Type = Int # 152| getElement(0): [PatternBindingDecl] var ... = ... # 152| getInit(0): [KeyPathApplicationExpr] \...[...] # 152| getBase(): [DeclRefExpr] a # 152| getKeyPath(): [DeclRefExpr] keyPathInt # 152| getPattern(0): [NamedPattern] apply_keyPathInt -# 152| getElement(1): [ConcreteVarDecl] apply_keyPathInt -# 152| Type = Int -# 153| getElement(2): [PatternBindingDecl] var ... = ... +# 153| getElement(1): [PatternBindingDecl] var ... = ... # 153| getInit(0): [KeyPathApplicationExpr] \...[...] # 153| getBase(): [DeclRefExpr] a # 153| getKeyPath(): [DeclRefExpr] keyPathB # 153| getPattern(0): [NamedPattern] apply_keyPathB -# 153| getElement(3): [ConcreteVarDecl] apply_keyPathB -# 153| Type = B -# 154| getElement(4): [PatternBindingDecl] var ... = ... +# 154| getElement(2): [PatternBindingDecl] var ... = ... # 154| getInit(0): [KeyPathApplicationExpr] \...[...] # 154| getBase(): [KeyPathApplicationExpr] \...[...] # 154| getBase(): [DeclRefExpr] a @@ -5263,8 +5265,6 @@ expressions.swift: # 154| getRoot(): [TypeRepr] B # 154| getComponent(0): [KeyPathComponent] KeyPathComponent # 154| getPattern(0): [NamedPattern] nested_apply -# 154| getElement(5): [ConcreteVarDecl] nested_apply -# 154| Type = Int # 157| [NamedFunction] bitwise() # 157| InterfaceType = () -> () # 157| getBody(): [BraceStmt] { ... } @@ -5574,19 +5574,25 @@ patterns.swift: # 1| [NamedFunction] basic_patterns() # 1| InterfaceType = () -> () # 1| getBody(): [BraceStmt] { ... } +# 2| getVariable(0): [ConcreteVarDecl] an_int +# 2| Type = Int +# 3| getVariable(1): [ConcreteVarDecl] a_string +# 3| Type = String +# 4| getVariable(2): [ConcreteVarDecl] x +# 4| Type = Int +# 4| getVariable(3): [ConcreteVarDecl] y +# 4| Type = Int +# 4| getVariable(4): [ConcreteVarDecl] z +# 4| Type = Int # 2| getElement(0): [PatternBindingDecl] var ... = ... # 2| getInit(0): [IntegerLiteralExpr] 42 # 2| getPattern(0): [NamedPattern] an_int -# 2| getElement(1): [ConcreteVarDecl] an_int -# 2| Type = Int -# 3| getElement(2): [PatternBindingDecl] var ... = ... +# 3| getElement(1): [PatternBindingDecl] var ... = ... # 3| getInit(0): [StringLiteralExpr] here # 3| getPattern(0): [TypedPattern] ... as ... # 3| getSubPattern(): [NamedPattern] a_string # 3| getTypeRepr(): [TypeRepr] String -# 3| getElement(3): [ConcreteVarDecl] a_string -# 3| Type = String -# 4| getElement(4): [PatternBindingDecl] var ... = ... +# 4| getElement(2): [PatternBindingDecl] var ... = ... # 4| getInit(0): [TupleExpr] (...) # 4| getElement(0): [IntegerLiteralExpr] 1 # 4| getElement(1): [IntegerLiteralExpr] 2 @@ -5595,30 +5601,32 @@ patterns.swift: # 4| getElement(0): [NamedPattern] x # 4| getElement(1): [NamedPattern] y # 4| getElement(2): [NamedPattern] z -# 4| getElement(5): [ConcreteVarDecl] x -# 4| Type = Int -# 4| getElement(6): [ConcreteVarDecl] y -# 4| Type = Int -# 4| getElement(7): [ConcreteVarDecl] z -# 4| Type = Int -# 5| getElement(8): [PatternBindingDecl] var ... = ... +# 5| getElement(3): [PatternBindingDecl] var ... = ... # 5| getInit(0): [StringLiteralExpr] any # 5| getPattern(0): [AnyPattern] _ -# 6| getElement(9): [PatternBindingDecl] var ... = ... +# 6| getElement(4): [PatternBindingDecl] var ... = ... # 6| getInit(0): [StringLiteralExpr] paren # 6| getPattern(0): [AnyPattern] _ # 6| getPattern(0).getFullyUnresolved(): [ParenPattern] (...) # 9| [NamedFunction] switch_patterns() # 9| InterfaceType = () -> () # 9| getBody(): [BraceStmt] { ... } +# 10| getVariable(0): [ConcreteVarDecl] point +# 10| Type = (Int, Int) +# 24| getVariable(1): [ConcreteVarDecl] v +# 24| Type = Foo +# 31| getVariable(2): [ConcreteVarDecl] w +# 31| Type = Int? +# 38| getVariable(3): [ConcreteVarDecl] a +# 38| Type = Any +# 46| getVariable(4): [ConcreteVarDecl] b +# 46| Type = Bool # 10| getElement(0): [PatternBindingDecl] var ... = ... # 10| getInit(0): [TupleExpr] (...) # 10| getElement(0): [IntegerLiteralExpr] 1 # 10| getElement(1): [IntegerLiteralExpr] 2 # 10| getPattern(0): [NamedPattern] point -# 10| getElement(1): [ConcreteVarDecl] point -# 10| Type = (Int, Int) -# 11| getElement(2): [SwitchStmt] switch point { ... } +# 11| getElement(1): [SwitchStmt] switch point { ... } # 11| getExpr(): [DeclRefExpr] point # 12| getCase(0): [CaseStmt] case ... # 12| getBody(): [BraceStmt] { ... } @@ -5628,7 +5636,7 @@ patterns.swift: # 12| getElement(0): [NamedPattern] xx # 12| getElement(1): [NamedPattern] yy # 12| getPattern().getFullyUnresolved(): [BindingPattern] let ... -# 15| getElement(3): [SwitchStmt] switch 3 { ... } +# 15| getElement(2): [SwitchStmt] switch 3 { ... } # 15| getExpr(): [IntegerLiteralExpr] 3 # 16| getCase(0): [CaseStmt] case ... # 16| getBody(): [BraceStmt] { ... } @@ -5644,7 +5652,7 @@ patterns.swift: # 17| getElement(0): [StringLiteralExpr] # 17| getLabel(0): [CaseLabelItem] _ # 17| getPattern(): [AnyPattern] _ -# 20| getElement(4): [EnumDecl] Foo +# 20| getElement(3): [EnumDecl] Foo # 21| getMember(0): [EnumCaseDecl] case ... # 21| getMember(1): [EnumElementDecl] bar # 21| getMember(2): [EnumElementDecl] baz @@ -5652,7 +5660,7 @@ patterns.swift: # 21| Type = Int # 21| getParam(1): [ParamDecl] _ # 21| Type = String -# 24| getElement(5): [PatternBindingDecl] var ... = ... +# 24| getElement(4): [PatternBindingDecl] var ... = ... # 24| getInit(0): [MethodLookupExpr] .bar # 24| getBase(): [TypeExpr] Foo.Type # 24| getTypeRepr(): [TypeRepr] Foo @@ -5660,9 +5668,7 @@ patterns.swift: # 24| getPattern(0): [TypedPattern] ... as ... # 24| getSubPattern(): [NamedPattern] v # 24| getTypeRepr(): [TypeRepr] Foo -# 24| getElement(6): [ConcreteVarDecl] v -# 24| Type = Foo -# 26| getElement(7): [SwitchStmt] switch v { ... } +# 26| getElement(5): [SwitchStmt] switch v { ... } # 26| getExpr(): [DeclRefExpr] v # 27| getCase(0): [CaseStmt] case ... # 27| getBody(): [BraceStmt] { ... } @@ -5678,14 +5684,12 @@ patterns.swift: # 28| getElement(0): [NamedPattern] i # 28| getElement(1): [NamedPattern] s # 28| getPattern().getFullyUnresolved(): [BindingPattern] let ... -# 31| getElement(8): [PatternBindingDecl] var ... = ... +# 31| getElement(6): [PatternBindingDecl] var ... = ... # 31| getInit(0): [NilLiteralExpr] nil # 31| getPattern(0): [TypedPattern] ... as ... # 31| getSubPattern(): [NamedPattern] w # 31| getTypeRepr(): [TypeRepr] Int? -# 31| getElement(9): [ConcreteVarDecl] w -# 31| Type = Int? -# 33| getElement(10): [SwitchStmt] switch w { ... } +# 33| getElement(7): [SwitchStmt] switch w { ... } # 33| getExpr(): [DeclRefExpr] w # 34| getCase(0): [CaseStmt] case ... # 34| getBody(): [BraceStmt] { ... } @@ -5699,15 +5703,13 @@ patterns.swift: # 35| getElement(0): [StringLiteralExpr] none # 35| getLabel(0): [CaseLabelItem] _ # 35| getPattern(): [AnyPattern] _ -# 38| getElement(11): [PatternBindingDecl] var ... = ... +# 38| getElement(8): [PatternBindingDecl] var ... = ... # 38| getInit(0): [StringLiteralExpr] any # 38| getInit(0).getFullyConverted(): [ErasureExpr] (Any) ... # 38| getPattern(0): [TypedPattern] ... as ... # 38| getSubPattern(): [NamedPattern] a # 38| getTypeRepr(): [TypeRepr] Any -# 38| getElement(12): [ConcreteVarDecl] a -# 38| Type = Any -# 40| getElement(13): [SwitchStmt] switch a { ... } +# 40| getElement(9): [SwitchStmt] switch a { ... } # 40| getExpr(): [DeclRefExpr] a # 41| getCase(0): [CaseStmt] case ... # 41| getBody(): [BraceStmt] { ... } @@ -5728,12 +5730,10 @@ patterns.swift: # 43| getElement(0): [StringLiteralExpr] other # 43| getLabel(0): [CaseLabelItem] _ # 43| getPattern(): [AnyPattern] _ -# 46| getElement(14): [PatternBindingDecl] var ... = ... +# 46| getElement(10): [PatternBindingDecl] var ... = ... # 46| getInit(0): [BooleanLiteralExpr] true # 46| getPattern(0): [NamedPattern] b -# 46| getElement(15): [ConcreteVarDecl] b -# 46| Type = Bool -# 48| getElement(16): [SwitchStmt] switch b { ... } +# 48| getElement(11): [SwitchStmt] switch b { ... } # 48| getExpr(): [DeclRefExpr] b # 49| getCase(0): [CaseStmt] case ... # 49| getBody(): [BraceStmt] { ... } @@ -5760,6 +5760,12 @@ patterns.swift: # 54| [NamedFunction] bound_and_unbound() # 54| InterfaceType = () -> () # 54| getBody(): [BraceStmt] { ... } +# 55| getVariable(0): [ConcreteVarDecl] a +# 55| Type = Int +# 55| getVariable(1): [ConcreteVarDecl] b +# 55| Type = Int +# 55| getVariable(2): [ConcreteVarDecl] c +# 55| Type = Int # 55| getElement(0): [PatternBindingDecl] var ... = ... # 55| getInit(0): [IntegerLiteralExpr] 1 # 55| getInit(1): [IntegerLiteralExpr] 2 @@ -5769,13 +5775,7 @@ patterns.swift: # 55| getPattern(2): [TypedPattern] ... as ... # 55| getSubPattern(): [NamedPattern] c # 55| getTypeRepr(): [TypeRepr] Int -# 55| getElement(1): [ConcreteVarDecl] a -# 55| Type = Int -# 55| getElement(2): [ConcreteVarDecl] b -# 55| Type = Int -# 55| getElement(3): [ConcreteVarDecl] c -# 55| Type = Int -# 57| getElement(4): [IfStmt] if ... then { ... } +# 57| getElement(1): [IfStmt] if ... then { ... } # 57| getCondition(): [StmtCondition] StmtCondition # 57| getElement(0): [ConditionElement] let ...? = ... # 57| getPattern(): [OptionalSomePattern] let ...? @@ -5800,7 +5800,7 @@ patterns.swift: # 57| getSource(): [TupleExpr] (...) # 57| getElement(0): [DeclRefExpr] a # 57| getElement(1): [DeclRefExpr] c -# 58| getElement(5): [IfStmt] if ... then { ... } +# 58| getElement(2): [IfStmt] if ... then { ... } # 58| getCondition(): [StmtCondition] StmtCondition # 58| getElement(0): [ConditionElement] (...) = ... # 58| getPattern(): [TuplePattern] (...) @@ -5819,7 +5819,7 @@ patterns.swift: # 58| getDest(): [DiscardAssignmentExpr] _ # 58| getSource(): [DeclRefExpr] b # 58| getSource().getFullyConverted(): [ParenExpr] (...) -# 60| getElement(6): [SwitchStmt] switch a { ... } +# 60| getElement(3): [SwitchStmt] switch a { ... } # 60| getExpr(): [DeclRefExpr] a # 61| getCase(0): [CaseStmt] case ... # 61| getBody(): [BraceStmt] { ... } @@ -5878,6 +5878,10 @@ patterns.swift: # 77| [NamedFunction] test_enums() # 77| InterfaceType = () -> () # 77| getBody(): [BraceStmt] { ... } +# 78| getVariable(0): [ConcreteVarDecl] a +# 78| Type = MyEnum +# 144| getVariable(1): [ConcreteVarDecl] b +# 144| Type = MyEnum # 78| getElement(0): [PatternBindingDecl] var ... = ... # 78| getInit(0): [MethodLookupExpr] .myNone # 78| getBase(): [TypeExpr] MyEnum.Type @@ -5886,9 +5890,7 @@ patterns.swift: # 78| getPattern(0): [TypedPattern] ... as ... # 78| getSubPattern(): [NamedPattern] a # 78| getTypeRepr(): [TypeRepr] MyEnum -# 78| getElement(1): [ConcreteVarDecl] a -# 78| Type = MyEnum -# 80| getElement(2): [SwitchStmt] switch a { ... } +# 80| getElement(1): [SwitchStmt] switch a { ... } # 80| getExpr(): [DeclRefExpr] a # 80| getExpr().getFullyConverted(): [LoadExpr] (MyEnum) ... # 81| getCase(0): [CaseStmt] case ... @@ -5936,7 +5938,7 @@ patterns.swift: # 88| getElement(0): [NamedPattern] a # 88| getElement(1): [AnyPattern] _ # 88| getPattern().getFullyUnresolved(): [BindingPattern] let ... -# 92| getElement(3): [IfStmt] if ... then { ... } +# 92| getElement(2): [IfStmt] if ... then { ... } # 92| getCondition(): [StmtCondition] StmtCondition # 92| getElement(0): [ConditionElement] .mySingle(...) = ... # 92| getPattern(): [EnumElementPattern] .mySingle(...) @@ -5950,7 +5952,7 @@ patterns.swift: # 93| getFunction(): [DeclRefExpr] sink(arg:) # 93| getArgument(0): [Argument] arg: x # 93| getExpr(): [DeclRefExpr] x -# 95| getElement(4): [IfStmt] if ... then { ... } +# 95| getElement(3): [IfStmt] if ... then { ... } # 95| getCondition(): [StmtCondition] StmtCondition # 95| getElement(0): [ConditionElement] .myPair(...) = ... # 95| getPattern(): [EnumElementPattern] .myPair(...) @@ -5970,7 +5972,7 @@ patterns.swift: # 97| getFunction(): [DeclRefExpr] sink(arg:) # 97| getArgument(0): [Argument] arg: y # 97| getExpr(): [DeclRefExpr] y -# 100| getElement(5): [AssignExpr] ... = ... +# 100| getElement(4): [AssignExpr] ... = ... # 100| getDest(): [DeclRefExpr] a # 100| getSource(): [CallExpr] call to ... # 100| getFunction(): [MethodLookupExpr] .mySingle @@ -5980,7 +5982,7 @@ patterns.swift: # 100| getArgument(0): [Argument] : call to source() # 100| getExpr(): [CallExpr] call to source() # 100| getFunction(): [DeclRefExpr] source() -# 102| getElement(6): [SwitchStmt] switch a { ... } +# 102| getElement(5): [SwitchStmt] switch a { ... } # 102| getExpr(): [DeclRefExpr] a # 102| getExpr().getFullyConverted(): [LoadExpr] (MyEnum) ... # 103| getCase(0): [CaseStmt] case ... @@ -6028,7 +6030,7 @@ patterns.swift: # 110| getElement(0): [NamedPattern] a # 110| getElement(1): [AnyPattern] _ # 110| getPattern().getFullyUnresolved(): [BindingPattern] let ... -# 114| getElement(7): [IfStmt] if ... then { ... } +# 114| getElement(6): [IfStmt] if ... then { ... } # 114| getCondition(): [StmtCondition] StmtCondition # 114| getElement(0): [ConditionElement] .mySingle(...) = ... # 114| getPattern(): [EnumElementPattern] .mySingle(...) @@ -6042,7 +6044,7 @@ patterns.swift: # 115| getFunction(): [DeclRefExpr] sink(arg:) # 115| getArgument(0): [Argument] arg: x # 115| getExpr(): [DeclRefExpr] x -# 117| getElement(8): [IfStmt] if ... then { ... } +# 117| getElement(7): [IfStmt] if ... then { ... } # 117| getCondition(): [StmtCondition] StmtCondition # 117| getElement(0): [ConditionElement] .myPair(...) = ... # 117| getPattern(): [EnumElementPattern] .myPair(...) @@ -6062,7 +6064,7 @@ patterns.swift: # 119| getFunction(): [DeclRefExpr] sink(arg:) # 119| getArgument(0): [Argument] arg: y # 119| getExpr(): [DeclRefExpr] y -# 122| getElement(9): [AssignExpr] ... = ... +# 122| getElement(8): [AssignExpr] ... = ... # 122| getDest(): [DeclRefExpr] a # 122| getSource(): [CallExpr] call to ... # 122| getFunction(): [MethodLookupExpr] .myPair @@ -6074,7 +6076,7 @@ patterns.swift: # 122| getArgument(1): [Argument] : call to source() # 122| getExpr(): [CallExpr] call to source() # 122| getFunction(): [DeclRefExpr] source() -# 124| getElement(10): [SwitchStmt] switch a { ... } +# 124| getElement(9): [SwitchStmt] switch a { ... } # 124| getExpr(): [DeclRefExpr] a # 124| getExpr().getFullyConverted(): [LoadExpr] (MyEnum) ... # 125| getCase(0): [CaseStmt] case ... @@ -6122,7 +6124,7 @@ patterns.swift: # 132| getElement(0): [NamedPattern] a # 132| getElement(1): [AnyPattern] _ # 132| getPattern().getFullyUnresolved(): [BindingPattern] let ... -# 136| getElement(11): [IfStmt] if ... then { ... } +# 136| getElement(10): [IfStmt] if ... then { ... } # 136| getCondition(): [StmtCondition] StmtCondition # 136| getElement(0): [ConditionElement] .mySingle(...) = ... # 136| getPattern(): [EnumElementPattern] .mySingle(...) @@ -6136,7 +6138,7 @@ patterns.swift: # 137| getFunction(): [DeclRefExpr] sink(arg:) # 137| getArgument(0): [Argument] arg: x # 137| getExpr(): [DeclRefExpr] x -# 139| getElement(12): [IfStmt] if ... then { ... } +# 139| getElement(11): [IfStmt] if ... then { ... } # 139| getCondition(): [StmtCondition] StmtCondition # 139| getElement(0): [ConditionElement] .myPair(...) = ... # 139| getPattern(): [EnumElementPattern] .myPair(...) @@ -6156,7 +6158,7 @@ patterns.swift: # 141| getFunction(): [DeclRefExpr] sink(arg:) # 141| getArgument(0): [Argument] arg: y # 141| getExpr(): [DeclRefExpr] y -# 144| getElement(13): [PatternBindingDecl] var ... = ... +# 144| getElement(12): [PatternBindingDecl] var ... = ... # 144| getInit(0): [CallExpr] call to ... # 144| getFunction(): [MethodLookupExpr] .myCons # 144| getBase(): [TypeExpr] MyEnum.Type @@ -6170,9 +6172,7 @@ patterns.swift: # 144| getPattern(0): [TypedPattern] ... as ... # 144| getSubPattern(): [NamedPattern] b # 144| getTypeRepr(): [TypeRepr] MyEnum -# 144| getElement(14): [ConcreteVarDecl] b -# 144| Type = MyEnum -# 146| getElement(15): [SwitchStmt] switch b { ... } +# 146| getElement(13): [SwitchStmt] switch b { ... } # 146| getExpr(): [DeclRefExpr] b # 147| getCase(0): [CaseStmt] case ... # 148| getBody(): [BraceStmt] { ... } @@ -6242,7 +6242,7 @@ patterns.swift: # 158| getElement(0): [NamedPattern] a # 158| getElement(1): [AnyPattern] _ # 158| getPattern().getFullyUnresolved(): [BindingPattern] let ... -# 162| getElement(16): [IfStmt] if ... then { ... } +# 162| getElement(14): [IfStmt] if ... then { ... } # 162| getCondition(): [StmtCondition] StmtCondition # 162| getElement(0): [ConditionElement] .mySingle(...) = ... # 162| getPattern(): [EnumElementPattern] .mySingle(...) @@ -6264,7 +6264,7 @@ patterns.swift: # 163| getFunction(): [DeclRefExpr] sink(arg:) # 163| getArgument(0): [Argument] arg: x # 163| getExpr(): [DeclRefExpr] x -# 165| getElement(17): [IfStmt] if ... then { ... } +# 165| getElement(15): [IfStmt] if ... then { ... } # 165| getCondition(): [StmtCondition] StmtCondition # 165| getElement(0): [ConditionElement] .myPair(...) = ... # 165| getPattern(): [EnumElementPattern] .myPair(...) @@ -6292,7 +6292,7 @@ patterns.swift: # 167| getFunction(): [DeclRefExpr] sink(arg:) # 167| getArgument(0): [Argument] arg: y # 167| getExpr(): [DeclRefExpr] y -# 169| getElement(18): [IfStmt] if ... then { ... } +# 169| getElement(16): [IfStmt] if ... then { ... } # 169| getCondition(): [StmtCondition] StmtCondition # 169| getElement(0): [ConditionElement] .myCons(...) = ... # 169| getPattern(): [EnumElementPattern] .myCons(...) @@ -6309,7 +6309,7 @@ patterns.swift: # 170| getFunction(): [DeclRefExpr] sink(arg:) # 170| getArgument(0): [Argument] arg: c # 170| getExpr(): [DeclRefExpr] c -# 173| getElement(19): [SwitchStmt] switch (...) { ... } +# 173| getElement(17): [SwitchStmt] switch (...) { ... } # 173| getExpr(): [TupleExpr] (...) # 173| getElement(0): [DeclRefExpr] a # 173| getElement(0).getFullyConverted(): [LoadExpr] (MyEnum) ... @@ -6433,6 +6433,8 @@ statements.swift: # 1| [NamedFunction] loop() # 1| InterfaceType = () -> () # 1| getBody(): [BraceStmt] { ... } +# 9| getVariable(0): [ConcreteVarDecl] i +# 9| Type = Int # 2| getElement(0): [ForEachStmt] for ... in ... { ... } # 2| getPattern(): [NamedPattern] i # 2| getSequence(): [BinaryExpr] ... ....(_:_:) ... @@ -6464,9 +6466,7 @@ statements.swift: # 9| getElement(1): [PatternBindingDecl] var ... = ... # 9| getInit(0): [IntegerLiteralExpr] 0 # 9| getPattern(0): [NamedPattern] i -# 9| getElement(2): [ConcreteVarDecl] i -# 9| Type = Int -# 10| getElement(3): [WhileStmt] while ... { ... } +# 10| getElement(2): [WhileStmt] while ... { ... } # 10| getCondition(): [StmtCondition] StmtCondition # 10| getElement(0): [ConditionElement] ... .<(_:_:) ... # 10| getBoolean(): [BinaryExpr] ... .<(_:_:) ... @@ -6493,10 +6493,10 @@ statements.swift: # 11| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 11| getArgument(1): [Argument] : 1 # 11| getExpr(): [IntegerLiteralExpr] 1 -# 14| getElement(4): [AssignExpr] ... = ... +# 14| getElement(3): [AssignExpr] ... = ... # 14| getDest(): [DeclRefExpr] i # 14| getSource(): [IntegerLiteralExpr] 0 -# 15| getElement(5): [RepeatWhileStmt] repeat { ... } while ... +# 15| getElement(4): [RepeatWhileStmt] repeat { ... } while ... # 17| getCondition(): [BinaryExpr] ... .<(_:_:) ... # 17| getFunction(): [MethodLookupExpr] .<(_:_:) # 17| getBase(): [TypeExpr] Int.Type @@ -6521,7 +6521,7 @@ statements.swift: # 16| getExpr().getFullyConverted(): [LoadExpr] (Int) ... # 16| getArgument(1): [Argument] : 1 # 16| getExpr(): [IntegerLiteralExpr] 1 -# 19| getElement(6): [DoCatchStmt] do { ... } catch { ... } +# 19| getElement(5): [DoCatchStmt] do { ... } catch { ... } # 19| getBody(): [BraceStmt] { ... } # 20| getElement(0): [TryExpr] try ... # 20| getSubExpr(): [CallExpr] call to failure(_:) @@ -6544,7 +6544,7 @@ statements.swift: # 21| getLabel(0): [CaseLabelItem] error # 21| getPattern(): [NamedPattern] error # 21| getPattern().getFullyUnresolved(): [BindingPattern] let ... -# 25| getElement(7): [DoCatchStmt] do { ... } catch { ... } +# 25| getElement(6): [DoCatchStmt] do { ... } catch { ... } # 25| getBody(): [BraceStmt] { ... } # 26| getElement(0): [TryExpr] try ... # 26| getSubExpr(): [CallExpr] call to failure(_:) diff --git a/swift/ql/test/library-tests/elements/expr/methodlookup/PrintAst.expected b/swift/ql/test/library-tests/elements/expr/methodlookup/PrintAst.expected index cbe03b39e9d..5e25ea404d1 100644 --- a/swift/ql/test/library-tests/elements/expr/methodlookup/PrintAst.expected +++ b/swift/ql/test/library-tests/elements/expr/methodlookup/PrintAst.expected @@ -99,6 +99,8 @@ methodlookup.swift: # 22| getBody(): [BraceStmt] { ... } # 22| getElement(0): [DoStmt] do { ... } # 22| getBody(): [BraceStmt] { ... } +# 23| getVariable(0): [ConcreteVarDecl] foo +# 23| Type = Foo # 23| getElement(0): [PatternBindingDecl] var ... = ... # 23| getInit(0): [CallExpr] call to Foo.init() # 23| getFunction(): [MethodLookupExpr] Foo.init() @@ -106,20 +108,18 @@ methodlookup.swift: # 23| getTypeRepr(): [TypeRepr] Foo # 23| getMethodRef(): [DeclRefExpr] Foo.init() # 23| getPattern(0): [NamedPattern] foo -# 23| getElement(1): [ConcreteVarDecl] foo -# 23| Type = Foo -# 24| getElement(2): [AssignExpr] ... = ... +# 24| getElement(1): [AssignExpr] ... = ... # 24| getDest(): [DiscardAssignmentExpr] _ # 24| getSource(): [CallExpr] call to Foo.init() # 24| getFunction(): [MethodLookupExpr] Foo.init() # 24| getBase(): [TypeExpr] Foo.Type # 24| getTypeRepr(): [TypeRepr] Foo # 24| getMethodRef(): [DeclRefExpr] Foo.init() -# 26| getElement(3): [CallExpr] call to instanceMethod() +# 26| getElement(2): [CallExpr] call to instanceMethod() # 26| getFunction(): [MethodLookupExpr] .instanceMethod() # 26| getBase(): [DeclRefExpr] foo # 26| getMethodRef(): [DeclRefExpr] instanceMethod() -# 27| getElement(4): [CallExpr] call to { ... } +# 27| getElement(3): [CallExpr] call to { ... } # 27| getFunction(): [CallExpr] call to Foo.instanceMethod() # 27| getFunction(): [DotSyntaxBaseIgnoredExpr] Foo.instanceMethod() # 27| getQualifier(): [TypeExpr] Foo.Type @@ -139,12 +139,12 @@ methodlookup.swift: #-----| getCapture(0): [CapturedDecl] self # 27| getArgument(0): [Argument] : foo # 27| getExpr(): [DeclRefExpr] foo -# 29| getElement(5): [CallExpr] call to classMethod() +# 29| getElement(4): [CallExpr] call to classMethod() # 29| getFunction(): [MethodLookupExpr] .classMethod() # 29| getBase(): [TypeExpr] Foo.Type # 29| getTypeRepr(): [TypeRepr] Foo # 29| getMethodRef(): [DeclRefExpr] classMethod() -# 30| getElement(6): [CallExpr] call to staticMethod() +# 30| getElement(5): [CallExpr] call to staticMethod() # 30| getFunction(): [MethodLookupExpr] .staticMethod() # 30| getBase(): [TypeExpr] Foo.Type # 30| getTypeRepr(): [TypeRepr] Foo @@ -161,6 +161,8 @@ methodlookup.swift: # 33| getArgument(1): [Argument] operation: { ... } # 33| getExpr(): [ExplicitClosureExpr] { ... } # 33| getBody(): [BraceStmt] { ... } +# 34| getVariable(0): [ConcreteVarDecl] bar +# 34| Type = Bar # 34| getElement(0): [PatternBindingDecl] var ... = ... # 34| getInit(0): [CallExpr] call to Bar.init() # 34| getFunction(): [MethodLookupExpr] Bar.init() @@ -168,21 +170,19 @@ methodlookup.swift: # 34| getTypeRepr(): [TypeRepr] Bar # 34| getMethodRef(): [DeclRefExpr] Bar.init() # 34| getPattern(0): [NamedPattern] bar -# 34| getElement(1): [ConcreteVarDecl] bar -# 34| Type = Bar -# 35| getElement(2): [AssignExpr] ... = ... +# 35| getElement(1): [AssignExpr] ... = ... # 35| getDest(): [DiscardAssignmentExpr] _ # 35| getSource(): [CallExpr] call to Bar.init() # 35| getFunction(): [MethodLookupExpr] Bar.init() # 35| getBase(): [TypeExpr] Bar.Type # 35| getTypeRepr(): [TypeRepr] Bar # 35| getMethodRef(): [DeclRefExpr] Bar.init() -# 37| getElement(3): [CallExpr] call to instanceMethod() +# 37| getElement(2): [CallExpr] call to instanceMethod() # 37| getFunction(): [MethodLookupExpr] .instanceMethod() # 37| getBase(): [DeclRefExpr] bar # 37| getMethodRef(): [DeclRefExpr] instanceMethod() -# 37| getElement(3).getFullyConverted(): [AwaitExpr] await ... -# 40| getElement(4): [CallExpr] call to staticMethod() +# 37| getElement(2).getFullyConverted(): [AwaitExpr] await ... +# 40| getElement(3): [CallExpr] call to staticMethod() # 40| getFunction(): [MethodLookupExpr] .staticMethod() # 40| getBase(): [TypeExpr] Bar.Type # 40| getTypeRepr(): [TypeRepr] Bar @@ -202,6 +202,8 @@ methodlookup.swift: # 43| getArgument(1): [Argument] operation: { ... } # 43| getExpr(): [ExplicitClosureExpr] { ... } # 43| getBody(): [BraceStmt] { ... } +# 44| getVariable(0): [ConcreteVarDecl] baz +# 44| Type = Baz # 44| getElement(0): [PatternBindingDecl] var ... = ... # 44| getInit(0): [CallExpr] call to Baz.init() # 44| getFunction(): [MethodLookupExpr] Baz.init() @@ -211,9 +213,7 @@ methodlookup.swift: # 44| getMethodRef().getFullyConverted(): [FunctionConversionExpr] ((Baz.Type) -> @MainActor () -> Baz) ... # 44| getInit(0).getFullyConverted(): [AwaitExpr] await ... # 44| getPattern(0): [NamedPattern] baz -# 44| getElement(1): [ConcreteVarDecl] baz -# 44| Type = Baz -# 45| getElement(2): [AssignExpr] ... = ... +# 45| getElement(1): [AssignExpr] ... = ... # 45| getDest(): [DiscardAssignmentExpr] _ # 45| getSource(): [CallExpr] call to Baz.init() # 45| getFunction(): [MethodLookupExpr] Baz.init() @@ -222,13 +222,13 @@ methodlookup.swift: # 45| getMethodRef(): [DeclRefExpr] Baz.init() # 45| getMethodRef().getFullyConverted(): [FunctionConversionExpr] ((Baz.Type) -> @MainActor () -> Baz) ... # 45| getSource().getFullyConverted(): [AwaitExpr] await ... -# 47| getElement(3): [CallExpr] call to instanceMethod() +# 47| getElement(2): [CallExpr] call to instanceMethod() # 47| getFunction(): [MethodLookupExpr] .instanceMethod() # 47| getBase(): [DeclRefExpr] baz # 47| getMethodRef(): [DeclRefExpr] instanceMethod() # 47| getMethodRef().getFullyConverted(): [FunctionConversionExpr] ((Baz) -> @MainActor () -> ()) ... -# 47| getElement(3).getFullyConverted(): [AwaitExpr] await ... -# 48| getElement(4): [CallExpr] call to { ... } +# 47| getElement(2).getFullyConverted(): [AwaitExpr] await ... +# 48| getElement(3): [CallExpr] call to { ... } # 48| getFunction(): [CallExpr] call to Baz.instanceMethod() # 48| getFunction(): [DotSyntaxBaseIgnoredExpr] Baz.instanceMethod() # 48| getQualifier(): [TypeExpr] Baz.Type @@ -248,21 +248,21 @@ methodlookup.swift: #-----| getCapture(0): [CapturedDecl] self # 48| getArgument(0): [Argument] : baz # 48| getExpr(): [DeclRefExpr] baz -# 48| getElement(4).getFullyConverted(): [AwaitExpr] await ... -# 50| getElement(5): [CallExpr] call to classMethod() +# 48| getElement(3).getFullyConverted(): [AwaitExpr] await ... +# 50| getElement(4): [CallExpr] call to classMethod() # 50| getFunction(): [MethodLookupExpr] .classMethod() # 50| getBase(): [TypeExpr] Baz.Type # 50| getTypeRepr(): [TypeRepr] Baz # 50| getMethodRef(): [DeclRefExpr] classMethod() # 50| getMethodRef().getFullyConverted(): [FunctionConversionExpr] ((Baz.Type) -> @MainActor () -> ()) ... -# 50| getElement(5).getFullyConverted(): [AwaitExpr] await ... -# 51| getElement(6): [CallExpr] call to staticMethod() +# 50| getElement(4).getFullyConverted(): [AwaitExpr] await ... +# 51| getElement(5): [CallExpr] call to staticMethod() # 51| getFunction(): [MethodLookupExpr] .staticMethod() # 51| getBase(): [TypeExpr] Baz.Type # 51| getTypeRepr(): [TypeRepr] Baz # 51| getMethodRef(): [DeclRefExpr] staticMethod() # 51| getMethodRef().getFullyConverted(): [FunctionConversionExpr] ((Baz.Type) -> @MainActor () -> ()) ... -# 51| getElement(6).getFullyConverted(): [AwaitExpr] await ... +# 51| getElement(5).getFullyConverted(): [AwaitExpr] await ... # 43| [NilLiteralExpr] nil # 47| [Comment] // DotSyntaxCallExpr # 47| From 4a29087ce7105c1ec0ae4bab9a861242086d79cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 6 Jun 2023 16:31:16 +0200 Subject: [PATCH 366/739] Swift: update Cfg test: VarDecls no longer in BraceStmt basic blocks This is a consequence of VarDecls not being Elements of BraceStmts. = --- .../controlflow/graph/Cfg.expected | 196 +----------------- 1 file changed, 3 insertions(+), 193 deletions(-) diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index de69eda9614..067f4c42519 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -367,6 +367,7 @@ cfg.swift: #-----| -> [...] # 40| OpaqueValueExpr +#-----| -> .appendLiteral(_:) # 40| TapExpr #-----| -> "..." @@ -596,9 +597,6 @@ cfg.swift: #-----| -> exit callClosures() # 65| var ... = ... -#-----| -> x1 - -# 65| x1 #-----| -> x2 # 65| x1 @@ -617,9 +615,6 @@ cfg.swift: #-----| -> call to createClosure1(s:) # 66| var ... = ... -#-----| -> x2 - -# 66| x2 #-----| -> x3 # 66| x2 @@ -641,9 +636,6 @@ cfg.swift: #-----| -> call to ... # 67| var ... = ... -#-----| -> x3 - -# 67| x3 #-----| -> exit callClosures() (normal) # 67| x3 @@ -681,9 +673,6 @@ cfg.swift: # 71| var ... = ... #-----| -> n -# 71| n -#-----| -> n - # 71| n #-----| match -> ... as ... @@ -723,9 +712,6 @@ cfg.swift: #-----| -> nBang # 76| var ... = ... -#-----| -> nBang - -# 76| nBang #-----| -> n # 76| nBang @@ -744,9 +730,6 @@ cfg.swift: #-----| -> call to maybeParseInt(s:) # 77| var ... = ... -#-----| -> n - -# 77| n #-----| -> .+(_:_:) # 77| n @@ -803,9 +786,6 @@ cfg.swift: #-----| -> temp # 82| var ... = ... -#-----| -> temp - -# 82| temp #-----| -> add(a:) # 82| temp @@ -894,9 +874,6 @@ cfg.swift: #-----| -> &... # 93| var ... = ... -#-----| -> tempOptional - -# 93| tempOptional #-----| -> addOptional(a:) # 93| tempOptional @@ -1056,9 +1033,6 @@ cfg.swift: #-----| -> c # 110| var ... = ... -#-----| -> c - -# 110| c #-----| -> n1 # 110| c @@ -1077,9 +1051,6 @@ cfg.swift: #-----| -> call to C.init(n:) # 111| var ... = ... -#-----| -> n1 - -# 111| n1 #-----| -> n2 # 111| n1 @@ -1092,9 +1063,6 @@ cfg.swift: #-----| -> var ... = ... # 112| var ... = ... -#-----| -> n2 - -# 112| n2 #-----| -> n3 # 112| n2 @@ -1110,9 +1078,6 @@ cfg.swift: #-----| -> var ... = ... # 113| var ... = ... -#-----| -> n3 - -# 113| n3 #-----| -> n4 # 113| n3 @@ -1128,9 +1093,6 @@ cfg.swift: #-----| -> var ... = ... # 114| var ... = ... -#-----| -> n4 - -# 114| n4 #-----| -> n5 # 114| n4 @@ -1149,9 +1111,6 @@ cfg.swift: #-----| -> var ... = ... # 116| var ... = ... -#-----| -> n5 - -# 116| n5 #-----| -> n6 # 116| n5 @@ -1164,9 +1123,6 @@ cfg.swift: #-----| -> var ... = ... # 117| var ... = ... -#-----| -> n6 - -# 117| n6 #-----| -> n7 # 117| n6 @@ -1182,9 +1138,6 @@ cfg.swift: #-----| -> var ... = ... # 118| var ... = ... -#-----| -> n7 - -# 118| n7 #-----| -> n8 # 118| n7 @@ -1200,9 +1153,6 @@ cfg.swift: #-----| -> var ... = ... # 119| var ... = ... -#-----| -> n8 - -# 119| n8 #-----| -> n9 # 119| n8 @@ -1221,9 +1171,6 @@ cfg.swift: #-----| -> var ... = ... # 121| var ... = ... -#-----| -> n9 - -# 121| n9 #-----| -> n10 # 121| n9 @@ -1239,9 +1186,6 @@ cfg.swift: #-----| -> var ... = ... # 122| var ... = ... -#-----| -> n10 - -# 122| n10 #-----| -> n11 # 122| n10 @@ -1260,9 +1204,6 @@ cfg.swift: #-----| -> var ... = ... # 123| var ... = ... -#-----| -> n11 - -# 123| n11 #-----| -> n12 # 123| n11 @@ -1281,9 +1222,6 @@ cfg.swift: #-----| -> var ... = ... # 124| var ... = ... -#-----| -> n12 - -# 124| n12 #-----| -> n13 # 124| n12 @@ -1305,9 +1243,6 @@ cfg.swift: #-----| -> var ... = ... # 126| var ... = ... -#-----| -> n13 - -# 126| n13 #-----| -> n14 # 126| n13 @@ -1323,9 +1258,6 @@ cfg.swift: #-----| -> var ... = ... # 127| var ... = ... -#-----| -> n14 - -# 127| n14 #-----| -> n15 # 127| n14 @@ -1344,9 +1276,6 @@ cfg.swift: #-----| -> var ... = ... # 128| var ... = ... -#-----| -> n15 - -# 128| n15 #-----| -> n16 # 128| n15 @@ -1365,9 +1294,6 @@ cfg.swift: #-----| -> var ... = ... # 129| var ... = ... -#-----| -> n16 - -# 129| n16 #-----| -> n17 # 129| n16 @@ -1389,9 +1315,6 @@ cfg.swift: #-----| -> var ... = ... # 131| var ... = ... -#-----| -> n17 - -# 131| n17 #-----| -> n18 # 131| n17 @@ -1413,9 +1336,6 @@ cfg.swift: #-----| -> (Int?) ... # 132| var ... = ... -#-----| -> n18 - -# 132| n18 #-----| -> n19 # 132| n18 @@ -1440,9 +1360,6 @@ cfg.swift: #-----| -> (Int?) ... # 133| var ... = ... -#-----| -> n19 - -# 133| n19 #-----| -> n20 # 133| n19 @@ -1467,9 +1384,6 @@ cfg.swift: #-----| -> (Int?) ... # 134| var ... = ... -#-----| -> n20 - -# 134| n20 #-----| -> exit testMemberRef(param:inoutParam:opt:) (normal) # 134| n20 @@ -2379,9 +2293,6 @@ cfg.swift: #-----| -> c # 244| var ... = ... -#-----| -> c - -# 244| c #-----| -> d # 244| c @@ -2403,9 +2314,6 @@ cfg.swift: #-----| -> ... .+(_:_:) ... # 245| var ... = ... -#-----| -> d - -# 245| d #-----| -> e # 245| d @@ -2427,9 +2335,6 @@ cfg.swift: #-----| -> ... .-(_:_:) ... # 246| var ... = ... -#-----| -> e - -# 246| e #-----| -> f # 246| e @@ -2451,9 +2356,6 @@ cfg.swift: #-----| -> ... .*(_:_:) ... # 247| var ... = ... -#-----| -> f - -# 247| f #-----| -> g # 247| f @@ -2475,9 +2377,6 @@ cfg.swift: #-----| -> ... ./(_:_:) ... # 248| var ... = ... -#-----| -> g - -# 248| g #-----| -> h # 248| g @@ -2499,9 +2398,6 @@ cfg.swift: #-----| -> ... .%(_:_:) ... # 249| var ... = ... -#-----| -> h - -# 249| h #-----| -> i # 249| h @@ -2523,9 +2419,6 @@ cfg.swift: #-----| -> ... .&(_:_:) ... # 250| var ... = ... -#-----| -> i - -# 250| i #-----| -> j # 250| i @@ -2547,9 +2440,6 @@ cfg.swift: #-----| -> ... .|(_:_:) ... # 251| var ... = ... -#-----| -> j - -# 251| j #-----| -> k # 251| j @@ -2571,9 +2461,6 @@ cfg.swift: #-----| -> ... .^(_:_:) ... # 252| var ... = ... -#-----| -> k - -# 252| k #-----| -> l # 252| k @@ -2595,9 +2482,6 @@ cfg.swift: #-----| -> ... .<<(_:_:) ... # 253| var ... = ... -#-----| -> l - -# 253| l #-----| -> o # 253| l @@ -2619,9 +2503,6 @@ cfg.swift: #-----| -> ... .>>(_:_:) ... # 254| var ... = ... -#-----| -> o - -# 254| o #-----| -> p # 254| o @@ -2643,9 +2524,6 @@ cfg.swift: #-----| -> ... .==(_:_:) ... # 255| var ... = ... -#-----| -> p - -# 255| p #-----| -> q # 255| p @@ -2667,9 +2545,6 @@ cfg.swift: #-----| -> ... .!=(_:_:) ... # 256| var ... = ... -#-----| -> q - -# 256| q #-----| -> r # 256| q @@ -2691,9 +2566,6 @@ cfg.swift: #-----| -> ... .<(_:_:) ... # 257| var ... = ... -#-----| -> r - -# 257| r #-----| -> s # 257| r @@ -2715,9 +2587,6 @@ cfg.swift: #-----| -> ... .<=(_:_:) ... # 258| var ... = ... -#-----| -> s - -# 258| s #-----| -> t # 258| s @@ -2739,9 +2608,6 @@ cfg.swift: #-----| -> ... .>(_:_:) ... # 259| var ... = ... -#-----| -> t - -# 259| t #-----| -> exit binaryExprs(a:b:) (normal) # 259| t @@ -2789,6 +2655,7 @@ cfg.swift: #-----| -> return ... # 263| OpaqueValueExpr +#-----| -> .appendLiteral(_:) # 263| TapExpr #-----| -> "..." @@ -2954,9 +2821,6 @@ cfg.swift: # 267| var ... = ... #-----| -> a -# 267| a -#-----| -> a - # 267| a #-----| match -> 0 @@ -3285,9 +3149,6 @@ cfg.swift: #-----| -> ... .>>=(_:_:) ... # 280| var ... = ... -#-----| -> tupleWithA - -# 280| tupleWithA #-----| -> b # 280| tupleWithA @@ -3374,9 +3235,6 @@ cfg.swift: # 282| var ... = ... #-----| -> b -# 282| b -#-----| -> b - # 282| b #-----| match -> 0 @@ -3870,38 +3728,23 @@ cfg.swift: #-----| -> ... .>>(_:_:) ... # 295| var ... = ... -#-----| -> a1 +#-----| -> .+(_:_:) # 295| (...) #-----| -> a1 -# 295| a1 -#-----| -> a2 - # 295| a1 #-----| match -> a2 -# 295| a2 -#-----| -> a3 - # 295| a2 #-----| match -> a3 -# 295| a3 -#-----| -> a4 - # 295| a3 #-----| match -> a4 -# 295| a4 -#-----| -> a5 - # 295| a4 #-----| match -> a5 -# 295| a5 -#-----| -> .+(_:_:) - # 295| a5 #-----| match -> tupleWithA @@ -4630,9 +4473,6 @@ cfg.swift: #-----| -> x # 346| var ... = ... -#-----| -> x - -# 346| x #-----| -> while ... { ... } # 346| x @@ -5478,9 +5318,6 @@ cfg.swift: #-----| -> myLocalVar # 428| var ... = ... -#-----| -> myLocalVar - -# 428| myLocalVar #-----| -> 0 # 428| myLocalVar @@ -5690,9 +5527,6 @@ cfg.swift: #-----| -> kpGet_b_x # 456| var ... = ... -#-----| -> kpGet_b_x - -# 456| kpGet_b_x #-----| -> kpGet_bs_0_x # 456| kpGet_b_x @@ -5719,9 +5553,6 @@ cfg.swift: #-----| -> #keyPath(...) # 457| var ... = ... -#-----| -> kpGet_bs_0_x - -# 457| kpGet_bs_0_x #-----| -> kpGet_mayB_force_x # 457| kpGet_bs_0_x @@ -5754,9 +5585,6 @@ cfg.swift: #-----| -> #keyPath(...) # 458| var ... = ... -#-----| -> kpGet_mayB_force_x - -# 458| kpGet_mayB_force_x #-----| -> kpGet_mayB_x # 458| kpGet_mayB_force_x @@ -5786,9 +5614,6 @@ cfg.swift: #-----| -> #keyPath(...) # 459| var ... = ... -#-----| -> kpGet_mayB_x - -# 459| kpGet_mayB_x #-----| -> apply_kpGet_b_x # 459| kpGet_mayB_x @@ -5817,9 +5642,6 @@ cfg.swift: # 459| KeyPathComponent # 461| var ... = ... -#-----| -> apply_kpGet_b_x - -# 461| apply_kpGet_b_x #-----| -> apply_kpGet_bs_0_x # 461| apply_kpGet_b_x @@ -5838,9 +5660,6 @@ cfg.swift: #-----| -> (WritableKeyPath<A, Int>) ... # 462| var ... = ... -#-----| -> apply_kpGet_bs_0_x - -# 462| apply_kpGet_bs_0_x #-----| -> apply_kpGet_mayB_force_x # 462| apply_kpGet_bs_0_x @@ -5859,9 +5678,6 @@ cfg.swift: #-----| -> (WritableKeyPath<A, Int>) ... # 463| var ... = ... -#-----| -> apply_kpGet_mayB_force_x - -# 463| apply_kpGet_mayB_force_x #-----| -> apply_kpGet_mayB_x # 463| apply_kpGet_mayB_force_x @@ -5880,9 +5696,6 @@ cfg.swift: #-----| -> (WritableKeyPath<A, Int>) ... # 464| var ... = ... -#-----| -> apply_kpGet_mayB_x - -# 464| apply_kpGet_mayB_x #-----| -> exit test(a:) (normal) # 464| apply_kpGet_mayB_x @@ -5953,9 +5766,6 @@ cfg.swift: #-----| -> x # 497| var ... = ... -#-----| -> x - -# 497| x #-----| -> if ... then { ... } # 497| x From a831456e94638728de3b1820c32037f8c08cb01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 6 Jun 2023 16:50:15 +0200 Subject: [PATCH 367/739] Swift: make `BraceStmt`'s `variable` a `synth` property --- swift/ql/.generated.list | 4 ++-- swift/ql/lib/codeql/swift/generated/Raw.qll | 5 ----- swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll | 7 +------ swift/ql/lib/swift.dbscheme | 7 ------- swift/schema.py | 2 +- 5 files changed, 4 insertions(+), 21 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index bc1a195b178..bee175d0860 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -383,7 +383,7 @@ lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d lib/codeql/swift/generated/ParentChild.qll f8647fba02b9acca7bf2870dfaee5709e2d3e3a12d27b012dd1e17f7df2e56e5 75d3501c2a59d931dd537321475687a73ff517e5caaae4ce2e0c2daec0d94df4 lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll e665a9c74c1d2926fdfafb2fda8bf428fc72b0b1afbf472f304b1a925bee9f09 c361be3af00814c13f35666881aed32327662495d1fe4bd5a4b5c1f481986a5b +lib/codeql/swift/generated/Raw.qll 991f95f30bde82ba43237bd9c1a68d3f450038ef828edb89219fbf583dd1956a e3e6c41caac09d532453c28167622fae7057d846f35750873eacd48cd128b957 lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -566,7 +566,7 @@ lib/codeql/swift/generated/pattern/ParenPattern.qll 337cb03dcb7384f7ef13e35d843b lib/codeql/swift/generated/pattern/Pattern.qll 0e96528a8dd87185f4fb23ba33ea418932762127e99739d7e56e5c8988e024d1 ba1e010c9f7f891048fb8c4ff8ea5a6c664c09e43d74b860d559f6459f82554a lib/codeql/swift/generated/pattern/TuplePattern.qll b3a138b0942f7e3eecb52ad2f095584a6cd5f555e9487c6eaad6a5527ae99f0c d6ff67ecc7395571acef4b82da514cb737c72d97ea557d89da534469feda340c lib/codeql/swift/generated/pattern/TypedPattern.qll 6a9fd2815755eddc6918d6be8221c7afb90e4fba4fcb8eb54ff42754269bb481 f198c3b09553a5f5f3d97f8088ef82c00552b9635560750c56d801b09dbd9e26 -lib/codeql/swift/generated/stmt/BraceStmt.qll 9d2b2a2127fb245f10e554c6a9fa31280a30081ebc93d9802a55c334534341d6 e5bfffc41258886dd516ab51cfb7a2c27ef725edff6b29c2f552e9661dab0a35 +lib/codeql/swift/generated/stmt/BraceStmt.qll 5273745afaaf10dc4b6ee159ca304e1251dc11af3c86af812b28294cbbcf2597 dbd4b003b453742e7197b22633ec8c87418e207f7ca409a04e3c6fb2cf2ea5fd lib/codeql/swift/generated/stmt/BreakStmt.qll 879cf66911cc7f53e7e8f4ae8244681018fb17d6501b269fb7cf9d8481f0b539 c78fc1b0e3e76321fc1653aa8b0aabaaacf082e01a003b78f693b106cc05faa0 lib/codeql/swift/generated/stmt/CaseLabelItem.qll 9536d2909a274c3a969eec25f8e5966adfaa9b0d6451ea6319d9f7bb2fd6fe07 02e25f036db50e9a6e9a7ceab6002dd605b73afb55fa1dee6f22e7af33a40913 lib/codeql/swift/generated/stmt/CaseStmt.qll c180478c6161439bc76bd39edfab343faba7450900ffedcadd3ccea12dc3a08c b537eb517db76113cfbc91c59e6bdfbf16ff83d639dfe6fd6892171f71a97090 diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index 6dd726c6b27..38e84cd3093 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -2569,11 +2569,6 @@ module Raw { class BraceStmt extends @brace_stmt, Stmt { override string toString() { result = "BraceStmt" } - /** - * Gets the `index`th variable declared in the scope of this brace statement (0-based). - */ - VarDecl getVariable(int index) { brace_stmt_variables(this, index, result) } - /** * Gets the `index`th element of this brace statement (0-based). */ diff --git a/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll index 319945162a9..c5c86c1f015 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/BraceStmt.qll @@ -12,12 +12,7 @@ module Generated { /** * Gets the `index`th variable declared in the scope of this brace statement (0-based). */ - VarDecl getVariable(int index) { - result = - Synth::convertVarDeclFromRaw(Synth::convertBraceStmtToRaw(this) - .(Raw::BraceStmt) - .getVariable(index)) - } + VarDecl getVariable(int index) { none() } /** * Gets any of the variables declared in the scope of this brace statement. diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index b8cc77513a6..44e36e15e90 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -1768,13 +1768,6 @@ brace_stmts( //dir=stmt unique int id: @brace_stmt ); -#keyset[id, index] -brace_stmt_variables( //dir=stmt - int id: @brace_stmt ref, - int index: int ref, - int variable: @var_decl_or_none ref -); - #keyset[id, index] brace_stmt_elements( //dir=stmt int id: @brace_stmt ref, diff --git a/swift/schema.py b/swift/schema.py index 36b667c4131..a336efb02a5 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -935,7 +935,7 @@ class StmtCondition(AstNode): elements: list[ConditionElement] | child class BraceStmt(Stmt): - variables: list[VarDecl] | child | doc("variable declared in the scope of this brace statement") + variables: list[VarDecl] | synth | child | doc("variable declared in the scope of this brace statement") elements: list[AstNode] | child class BreakStmt(Stmt): From 4dae7ad35aa7c7a040142e56d081c1e4216eacea Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 6 Jun 2023 17:22:52 +0200 Subject: [PATCH 368/739] C#: Only inject the shared compilation flag, if argument is not exe or dll. --- csharp/tools/tracing-config.lua | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index 79b2ea2ca1c..7fa03af2de1 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -23,6 +23,7 @@ function RegisterExtractorPack(id) local match = false local dotnetRunNeedsSeparator = false; local dotnetRunInjectionIndex = nil; + local libOrExe = false; local argv = compilerArguments.argv if OperatingSystem == 'windows' then -- let's hope that this split matches the escaping rules `dotnet` applies to command line arguments @@ -37,7 +38,7 @@ function RegisterExtractorPack(id) if (not match) then Log(1, 'Dotnet subcommand detected: %s', arg) end - if arg == 'build' or arg == 'msbuild' or arg == 'publish' or arg == 'pack' or arg == 'test' then + if arg == 'build' or arg == 'msbuild' or arg == 'publish' or arg == 'pack' then match = true break end @@ -48,6 +49,14 @@ function RegisterExtractorPack(id) dotnetRunNeedsSeparator = true dotnetRunInjectionIndex = i + 1 end + if arg == 'test' then + match = true + end + -- for `dotnet test`, we should not append `-p:UseSharedCompilation=false` to the command line + -- if a library or executable is being provided as an argument. + if arg:match('%.exe$') or arg:match('%.dll') then + libOrExe = true + end end -- if we see a separator to `dotnet run`, inject just prior to the existing separator if arg == '--' then @@ -62,7 +71,7 @@ function RegisterExtractorPack(id) dotnetRunInjectionIndex = i end end - if match then + if match and not libOrExe then local injections = { '-p:UseSharedCompilation=false', '-p:EmitCompilerGeneratedFiles=true' } if dotnetRunNeedsSeparator then table.insert(injections, '--') From 03e94c7137f73a81ddbffab8eaade40c8063233f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 6 Jun 2023 17:37:02 +0200 Subject: [PATCH 369/739] Swift: add library pack change note --- swift/ql/lib/change-notes/2023-06-06-brace-stmt-variables.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 swift/ql/lib/change-notes/2023-06-06-brace-stmt-variables.md diff --git a/swift/ql/lib/change-notes/2023-06-06-brace-stmt-variables.md b/swift/ql/lib/change-notes/2023-06-06-brace-stmt-variables.md new file mode 100644 index 00000000000..8dc01f15659 --- /dev/null +++ b/swift/ql/lib/change-notes/2023-06-06-brace-stmt-variables.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* The `BraceStmt` AST node's `AstNode getElement(index)` member predicate no longer returns `VarDecl`s after the `PatternBindingDecl` that declares them. Instead, a new `VarDecl getVariable(index)` predicate has been introduced for accessing the variables declared in a `BraceStmt`. This change only affects query writers. From 322b254cba0ae79516c17187f4b6fd0859de6490 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 6 Jun 2023 20:46:14 +0200 Subject: [PATCH 370/739] Type tracking: Use `noopt`+`inline_late` in `TypeBackTracker::[small]step` --- .../codeql/typetracking/TypeTracking.qll | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/shared/typetracking/codeql/typetracking/TypeTracking.qll b/shared/typetracking/codeql/typetracking/TypeTracking.qll index 6bfc31db5f3..5ab814e0ddd 100644 --- a/shared/typetracking/codeql/typetracking/TypeTracking.qll +++ b/shared/typetracking/codeql/typetracking/TypeTracking.qll @@ -630,6 +630,42 @@ module TypeTracking<TypeTrackingInput I> { TypeTracker end() { result.end() } } + pragma[nomagic] + private predicate backStepProj(LocalSourceNode nodeTo, StepSummary summary) { + step(_, nodeTo, summary) + } + + bindingset[t, nodeTo] + pragma[inline_late] + pragma[noopt] + private TypeBackTracker backStepInlineLate( + TypeBackTracker t, LocalSourceNode nodeFrom, LocalSourceNode nodeTo + ) { + exists(StepSummary summary | + backStepProj(nodeTo, summary) and + result = prepend(t, summary) and + step(nodeFrom, nodeTo, summary) + ) + } + + pragma[nomagic] + private predicate backSmallStepProj(LocalSourceNode nodeTo, StepSummary summary) { + smallStep(_, nodeTo, summary) + } + + bindingset[t, nodeTo] + pragma[inline_late] + pragma[noopt] + private TypeBackTracker backSmallStepInlineLate( + TypeBackTracker t, LocalSourceNode nodeFrom, LocalSourceNode nodeTo + ) { + exists(StepSummary summary | + backSmallStepProj(nodeTo, summary) and + result = prepend(t, summary) and + smallStep(nodeFrom, nodeTo, summary) + ) + } + /** * A summary of the steps needed to back-track a use of a value to a given dataflow node. * @@ -665,9 +701,6 @@ module TypeTracking<TypeTrackingInput I> { TypeBackTracker() { this = MkTypeBackTracker(hasReturn, content) } - /** Gets the summary resulting from prepending `step` to this type-tracking summary. */ - private TypeBackTracker prepend(StepSummary step) { result = prepend(this, step) } - /** Gets a textual representation of this summary. */ string toString() { exists(string withReturn, string withContent | @@ -704,13 +737,9 @@ module TypeTracking<TypeTrackingInput I> { * Gets the summary that corresponds to having taken a backwards * heap and/or inter-procedural step from `nodeTo` to `nodeFrom`. */ - bindingset[nodeTo, this] + pragma[inline] TypeBackTracker step(LocalSourceNode nodeFrom, LocalSourceNode nodeTo) { - exists(StepSummary summary | - step(_, pragma[only_bind_out](nodeTo), pragma[only_bind_into](summary)) and - result = pragma[only_bind_into](pragma[only_bind_out](this)).prepend(summary) and - step(nodeFrom, pragma[only_bind_into](pragma[only_bind_out](nodeTo)), summary) - ) + result = backStepInlineLate(this, nodeFrom, nodeTo) } /** @@ -737,13 +766,9 @@ module TypeTracking<TypeTrackingInput I> { * } * ``` */ - bindingset[nodeTo, this] + pragma[inline] TypeBackTracker smallstep(Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - smallStep(_, pragma[only_bind_out](nodeTo), pragma[only_bind_into](summary)) and - result = pragma[only_bind_into](pragma[only_bind_out](this)).prepend(summary) and - smallStep(nodeFrom, pragma[only_bind_into](pragma[only_bind_out](nodeTo)), summary) - ) + result = backSmallStepInlineLate(this, nodeFrom, nodeTo) or simpleLocalSmallStep(nodeFrom, nodeTo) and result = this From a14e7fa694b5f4e9746170cbc71b365e37ff5848 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 00:16:58 +0000 Subject: [PATCH 371/739] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 4 ++-- java/documentation/library-coverage/coverage.rst | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 4e4b1ab7e1f..0e429b40b52 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -55,7 +55,7 @@ java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, java.io,44,,45,,22,,,,,,,,,,,,,,22,,,,,,,,,,,,,,,,,,,43,2 java.lang,18,,92,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36 java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20, -java.nio,38,,31,,3,,,,,,,,,,,,,,35,,,,,,,,,,,,,,,,,,,31, +java.nio,40,,35,,3,,,,,,,,,,,,,,37,,,,,,,,,,,,,,,,,,,35, java.sql,13,,3,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,1 java.util,44,,484,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440 javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, @@ -75,7 +75,7 @@ javax.ws.rs.core,3,,149,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,2,,,,,,94,55 javax.xml.transform,2,,6,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,1,,,,6, javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,, jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -kotlin,16,,1843,,,,,,,,,,,,,,,,14,,,,,,,,,2,,,,,,,,,,1836,7 +kotlin,16,,1847,,,,,,,,,,,,,,,,14,,,,,,,,,2,,,,,,,,,,1836,11 net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,, ognl,6,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, okhttp3,4,,47,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,22,25 diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 644b4aaef6a..55b9a0a071d 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -18,10 +18,10 @@ Java framework & library support `Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,41,7,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,, `JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,, - Java Standard Library,``java.*``,3,679,170,62,,9,,,17 + Java Standard Library,``java.*``,3,683,172,64,,9,,,17 Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2 - Kotlin Standard Library,``kotlin*``,,1843,16,14,,,,,2 + Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,113,3,,28,14,,34 Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,890,520,60,,18,18,,193 - Totals,,255,9182,1973,242,10,122,33,1,382 + Totals,,255,9190,1975,244,10,122,33,1,382 From 2f12ae2e0d5e4d54d33cd4a723509096f3627770 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 7 Jun 2023 08:57:12 +0200 Subject: [PATCH 372/739] Update java/ql/lib/ext/okhttp3.model.yml --- java/ql/lib/ext/okhttp3.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/okhttp3.model.yml b/java/ql/lib/ext/okhttp3.model.yml index b7bfe8a10f7..a0662408708 100644 --- a/java/ql/lib/ext/okhttp3.model.yml +++ b/java/ql/lib/ext/okhttp3.model.yml @@ -58,4 +58,4 @@ extensions: - ["okhttp3", "HttpUrl$Builder", False, "setQueryParameter", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["okhttp3", "HttpUrl$Builder", False, "setQueryParameter", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["okhttp3", "HttpUrl$Builder", False, "username", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - - ["okhttp3", "Request$Builder", True, "build", "()", "", "Argument[undefined]", "ReturnValue", "taint", "ai-manual"] + - ["okhttp3", "Request$Builder", True, "build", "()", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] From 4bf124bffe6b835519748107feb03e257f45afb2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 6 Jun 2023 15:40:04 +0200 Subject: [PATCH 373/739] Ruby/Python: Add `CallGraphConstruction` module for recursive type-tracking based call graph construction --- .../dataflow/new/internal/TypeTracker.qll | 345 ++++++++++++------ .../codeql/ruby/typetracking/TypeTracker.qll | 345 ++++++++++++------ 2 files changed, 454 insertions(+), 236 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll index 4be26f6cea9..25521f5f1a5 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll @@ -224,71 +224,47 @@ private module Cached { private import Cached +private predicate step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { + stepNoCall(nodeFrom, nodeTo, summary) + or + stepCall(nodeFrom, nodeTo, summary) +} + pragma[nomagic] -private predicate stepNoCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { - stepNoCall(nodeFrom, _, summary) +private predicate stepProj(TypeTrackingNode nodeFrom, StepSummary summary) { + step(nodeFrom, _, summary) } bindingset[nodeFrom, t] pragma[inline_late] pragma[noopt] -private TypeTracker stepNoCallInlineLate( - TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo -) { +private TypeTracker stepInlineLate(TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { exists(StepSummary summary | - stepNoCallProj(nodeFrom, summary) and + stepProj(nodeFrom, summary) and result = t.append(summary) and - stepNoCall(nodeFrom, nodeTo, summary) + step(nodeFrom, nodeTo, summary) ) } +private predicate smallstep(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { + smallstepNoCall(nodeFrom, nodeTo, summary) + or + smallstepCall(nodeFrom, nodeTo, summary) +} + pragma[nomagic] -private predicate stepCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { - stepCall(nodeFrom, _, summary) +private predicate smallstepProj(Node nodeFrom, StepSummary summary) { + smallstep(nodeFrom, _, summary) } bindingset[nodeFrom, t] pragma[inline_late] pragma[noopt] -private TypeTracker stepCallInlineLate( - TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo -) { +private TypeTracker smallstepInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { exists(StepSummary summary | - stepCallProj(nodeFrom, summary) and + smallstepProj(nodeFrom, summary) and result = t.append(summary) and - stepCall(nodeFrom, nodeTo, summary) - ) -} - -pragma[nomagic] -private predicate smallstepNoCallProj(Node nodeFrom, StepSummary summary) { - smallstepNoCall(nodeFrom, _, summary) -} - -bindingset[nodeFrom, t] -pragma[inline_late] -pragma[noopt] -private TypeTracker smallstepNoCallInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - smallstepNoCallProj(nodeFrom, summary) and - result = t.append(summary) and - smallstepNoCall(nodeFrom, nodeTo, summary) - ) -} - -pragma[nomagic] -private predicate smallstepCallProj(Node nodeFrom, StepSummary summary) { - smallstepCall(nodeFrom, _, summary) -} - -bindingset[nodeFrom, t] -pragma[inline_late] -pragma[noopt] -private TypeTracker smallstepCallInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - smallstepCallProj(nodeFrom, summary) and - result = t.append(summary) and - smallstepCall(nodeFrom, nodeTo, summary) + smallstep(nodeFrom, nodeTo, summary) ) } @@ -385,14 +361,7 @@ module StepSummary { /** * Gets the summary that corresponds to having taken a forwards * heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate is inlined, which enables better join-orders when - * the call graph construction and type tracking are mutually recursive. - * In such cases, non-linear recursion involving `step` will be limited - * to non-linear recursion for the parts of `step` that involve the - * call graph. */ - pragma[inline] predicate step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { stepNoCall(nodeFrom, nodeTo, summary) or @@ -424,7 +393,6 @@ module StepSummary { * Unlike `StepSummary::step`, this predicate does not compress * type-preserving steps. */ - pragma[inline] predicate smallstep(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { smallstepNoCall(nodeFrom, nodeTo, summary) or @@ -529,66 +497,13 @@ class TypeTracker extends TTypeTracker { */ TypeTracker continue() { content = noContent() and result = this } - /** - * Gets the summary that corresponds to having taken a forwards - * intra-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate should normally not be used; consider using `step` - * instead. - */ - pragma[inline] - TypeTracker stepNoCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - result = stepNoCallInlineLate(this, nodeFrom, nodeTo) - } - - /** - * Gets the summary that corresponds to having taken a forwards - * inter-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate should normally not be used; consider using `step` - * instead. - */ - pragma[inline] - TypeTracker stepCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - result = stepCallInlineLate(this, nodeFrom, nodeTo) - } - /** * Gets the summary that corresponds to having taken a forwards * heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. */ pragma[inline] TypeTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - result = this.stepNoCall(nodeFrom, nodeTo) - or - result = this.stepCall(nodeFrom, nodeTo) - } - - /** - * Gets the summary that corresponds to having taken a forwards - * intra-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate should normally not be used; consider using `step` - * instead. - */ - pragma[inline] - TypeTracker smallstepNoCall(Node nodeFrom, Node nodeTo) { - result = smallstepNoCallInlineLate(this, nodeFrom, nodeTo) - or - simpleLocalFlowStep(nodeFrom, nodeTo) and - result = this - } - - /** - * Gets the summary that corresponds to having taken a forwards - * inter-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate should normally not be used; consider using `step` - * instead. - */ - pragma[inline] - TypeTracker smallstepCall(Node nodeFrom, Node nodeTo) { - result = smallstepCallInlineLate(this, nodeFrom, nodeTo) + result = stepInlineLate(this, nodeFrom, nodeTo) } /** @@ -617,9 +532,10 @@ class TypeTracker extends TTypeTracker { */ pragma[inline] TypeTracker smallstep(Node nodeFrom, Node nodeTo) { - result = this.smallstepNoCall(nodeFrom, nodeTo) + result = smallstepInlineLate(this, nodeFrom, nodeTo) or - result = this.smallstepCall(nodeFrom, nodeTo) + simpleLocalFlowStep(nodeFrom, nodeTo) and + result = this } } @@ -631,6 +547,39 @@ module TypeTracker { TypeTracker end() { result.end() } } +pragma[nomagic] +private predicate backStepProj(TypeTrackingNode nodeTo, StepSummary summary) { + step(_, nodeTo, summary) +} + +bindingset[nodeTo, t] +pragma[inline_late] +pragma[noopt] +private TypeBackTracker backStepInlineLate( + TypeBackTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo +) { + exists(StepSummary summary | + backStepProj(nodeTo, summary) and + result = t.prepend(summary) and + step(nodeFrom, nodeTo, summary) + ) +} + +private predicate backSmallstepProj(TypeTrackingNode nodeTo, StepSummary summary) { + smallstep(_, nodeTo, summary) +} + +bindingset[nodeTo, t] +pragma[inline_late] +pragma[noopt] +private TypeBackTracker backSmallstepInlineLate(TypeBackTracker t, Node nodeFrom, Node nodeTo) { + exists(StepSummary summary | + backSmallstepProj(nodeTo, summary) and + result = t.prepend(summary) and + smallstep(nodeFrom, nodeTo, summary) + ) +} + /** * A summary of the steps needed to back-track a use of a value to a given dataflow node. * @@ -714,10 +663,7 @@ class TypeBackTracker extends TTypeBackTracker { */ pragma[inline] TypeBackTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - exists(StepSummary summary | - StepSummary::step(pragma[only_bind_out](nodeFrom), nodeTo, pragma[only_bind_into](summary)) and - this = result.prepend(pragma[only_bind_into](summary)) - ) + this = backStepInlineLate(result, nodeFrom, nodeTo) } /** @@ -746,10 +692,7 @@ class TypeBackTracker extends TTypeBackTracker { */ pragma[inline] TypeBackTracker smallstep(Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - StepSummary::smallstep(nodeFrom, nodeTo, summary) and - this = result.prepend(summary) - ) + this = backSmallstepInlineLate(result, nodeFrom, nodeTo) or simpleLocalFlowStep(nodeFrom, nodeTo) and this = result @@ -785,3 +728,169 @@ module TypeBackTracker { */ TypeBackTracker end() { result.end() } } + +/** + * INTERNAL: Do not use. + * + * Provides logic for constructing a call graph in mutual recursion with type tracking. + * + * When type tracking is used to construct a call graph, we cannot use the join-order + * from `stepInlineLate`, because `step` becomes a recursive call, which means that we + * will have a conjunct with 3 recursive calls: the call to `step`, the call to `stepProj`, + * and the recursive type tracking call itself. The solution is to split the three-way + * non-linear recursion into two non-linear predicates: one that first joins with the + * projected `stepCall` relation, followed by a predicate that joins with the full + * `stepCall` relation (`stepNoCall` not being recursive, can be join-ordered in the + * same way as in `stepInlineLate`). + */ +module CallGraphConstruction { + /** The input to call graph construction. */ + signature module InputSig { + /** A state to track during type tracking. */ + class State; + + /** Holds if type tracking should start at `start` in state `state`. */ + predicate start(Node start, State state); + + /** + * Holds if type tracking should use the step from `nodeFrom` to `nodeTo`, + * which _does not_ depend on the call graph. + * + * Implementing this predicate using `StepSummary::[small]stepNoCall` yields + * standard type tracking. + */ + predicate stepNoCall(Node nodeFrom, Node nodeTo, StepSummary summary); + + /** + * Holds if type tracking should use the step from `nodeFrom` to `nodeTo`, + * which _does_ depend on the call graph. + * + * Implementing this predicate using `StepSummary::[small]stepCall` yields + * standard type tracking. + */ + predicate stepCall(Node nodeFrom, Node nodeTo, StepSummary summary); + + /** A projection of an element from the state space. */ + class StateProj; + + /** Gets the projection of `state`. */ + StateProj stateProj(State state); + + /** Holds if type tracking should stop at `n` when we are tracking projected state `stateProj`. */ + predicate filter(Node n, StateProj stateProj); + } + + /** Provides the `track` predicate for use in call graph construction. */ + module Make<InputSig Input> { + pragma[nomagic] + private predicate stepNoCallProj(Node nodeFrom, StepSummary summary) { + Input::stepNoCall(nodeFrom, _, summary) + } + + pragma[nomagic] + private predicate stepCallProj(Node nodeFrom, StepSummary summary) { + Input::stepCall(nodeFrom, _, summary) + } + + bindingset[nodeFrom, t] + pragma[inline_late] + pragma[noopt] + private TypeTracker stepNoCallInlineLate( + TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo + ) { + exists(StepSummary summary | + stepNoCallProj(nodeFrom, summary) and + result = t.append(summary) and + Input::stepNoCall(nodeFrom, nodeTo, summary) + ) + } + + bindingset[state] + pragma[inline_late] + private Input::StateProj stateProjInlineLate(Input::State state) { + result = Input::stateProj(state) + } + + pragma[nomagic] + private Node track(Input::State state, TypeTracker t) { + t.start() and Input::start(result, state) + or + exists(Input::StateProj stateProj | + stateProj = stateProjInlineLate(state) and + not Input::filter(result, stateProj) + | + exists(TypeTracker t2 | t = stepNoCallInlineLate(t2, track(state, t2), result)) + or + exists(StepSummary summary | + // non-linear recursion + Input::stepCall(trackCall(state, t, summary), result, summary) + ) + ) + } + + bindingset[t, summary] + pragma[inline_late] + private TypeTracker appendInlineLate(TypeTracker t, StepSummary summary) { + result = t.append(summary) + } + + pragma[nomagic] + private Node trackCall(Input::State state, TypeTracker t, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = track(state, t2) and + stepCallProj(result, summary) and + t = appendInlineLate(t2, summary) + ) + } + + /** Gets a node that can be reached from _some_ start node in state `state`. */ + pragma[nomagic] + Node track(Input::State state) { result = track(state, TypeTracker::end()) } + } + + /** A simple version of `CallGraphConstruction` that uses standard type tracking. */ + module Simple { + /** The input to call graph construction. */ + signature module InputSig { + /** A state to track during type tracking. */ + class State; + + /** Holds if type tracking should start at `start` in state `state`. */ + predicate start(Node start, State state); + + /** Holds if type tracking should stop at `n`. */ + predicate filter(Node n); + } + + /** Provides the `track` predicate for use in call graph construction. */ + module Make<InputSig Input> { + private module I implements CallGraphConstruction::InputSig { + private import codeql.util.Unit + + class State = Input::State; + + predicate start(Node start, State state) { Input::start(start, state) } + + predicate stepNoCall(Node nodeFrom, Node nodeTo, StepSummary summary) { + StepSummary::stepNoCall(nodeFrom, nodeTo, summary) + } + + predicate stepCall(Node nodeFrom, Node nodeTo, StepSummary summary) { + StepSummary::stepCall(nodeFrom, nodeTo, summary) + } + + class StateProj = Unit; + + Unit stateProj(State state) { exists(state) and exists(result) } + + predicate filter(Node n, Unit u) { + Input::filter(n) and + exists(u) + } + } + + import CallGraphConstruction::Make<I> + } + } +} diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll index 4be26f6cea9..25521f5f1a5 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll @@ -224,71 +224,47 @@ private module Cached { private import Cached +private predicate step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { + stepNoCall(nodeFrom, nodeTo, summary) + or + stepCall(nodeFrom, nodeTo, summary) +} + pragma[nomagic] -private predicate stepNoCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { - stepNoCall(nodeFrom, _, summary) +private predicate stepProj(TypeTrackingNode nodeFrom, StepSummary summary) { + step(nodeFrom, _, summary) } bindingset[nodeFrom, t] pragma[inline_late] pragma[noopt] -private TypeTracker stepNoCallInlineLate( - TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo -) { +private TypeTracker stepInlineLate(TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { exists(StepSummary summary | - stepNoCallProj(nodeFrom, summary) and + stepProj(nodeFrom, summary) and result = t.append(summary) and - stepNoCall(nodeFrom, nodeTo, summary) + step(nodeFrom, nodeTo, summary) ) } +private predicate smallstep(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { + smallstepNoCall(nodeFrom, nodeTo, summary) + or + smallstepCall(nodeFrom, nodeTo, summary) +} + pragma[nomagic] -private predicate stepCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { - stepCall(nodeFrom, _, summary) +private predicate smallstepProj(Node nodeFrom, StepSummary summary) { + smallstep(nodeFrom, _, summary) } bindingset[nodeFrom, t] pragma[inline_late] pragma[noopt] -private TypeTracker stepCallInlineLate( - TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo -) { +private TypeTracker smallstepInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { exists(StepSummary summary | - stepCallProj(nodeFrom, summary) and + smallstepProj(nodeFrom, summary) and result = t.append(summary) and - stepCall(nodeFrom, nodeTo, summary) - ) -} - -pragma[nomagic] -private predicate smallstepNoCallProj(Node nodeFrom, StepSummary summary) { - smallstepNoCall(nodeFrom, _, summary) -} - -bindingset[nodeFrom, t] -pragma[inline_late] -pragma[noopt] -private TypeTracker smallstepNoCallInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - smallstepNoCallProj(nodeFrom, summary) and - result = t.append(summary) and - smallstepNoCall(nodeFrom, nodeTo, summary) - ) -} - -pragma[nomagic] -private predicate smallstepCallProj(Node nodeFrom, StepSummary summary) { - smallstepCall(nodeFrom, _, summary) -} - -bindingset[nodeFrom, t] -pragma[inline_late] -pragma[noopt] -private TypeTracker smallstepCallInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - smallstepCallProj(nodeFrom, summary) and - result = t.append(summary) and - smallstepCall(nodeFrom, nodeTo, summary) + smallstep(nodeFrom, nodeTo, summary) ) } @@ -385,14 +361,7 @@ module StepSummary { /** * Gets the summary that corresponds to having taken a forwards * heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate is inlined, which enables better join-orders when - * the call graph construction and type tracking are mutually recursive. - * In such cases, non-linear recursion involving `step` will be limited - * to non-linear recursion for the parts of `step` that involve the - * call graph. */ - pragma[inline] predicate step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { stepNoCall(nodeFrom, nodeTo, summary) or @@ -424,7 +393,6 @@ module StepSummary { * Unlike `StepSummary::step`, this predicate does not compress * type-preserving steps. */ - pragma[inline] predicate smallstep(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { smallstepNoCall(nodeFrom, nodeTo, summary) or @@ -529,66 +497,13 @@ class TypeTracker extends TTypeTracker { */ TypeTracker continue() { content = noContent() and result = this } - /** - * Gets the summary that corresponds to having taken a forwards - * intra-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate should normally not be used; consider using `step` - * instead. - */ - pragma[inline] - TypeTracker stepNoCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - result = stepNoCallInlineLate(this, nodeFrom, nodeTo) - } - - /** - * Gets the summary that corresponds to having taken a forwards - * inter-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate should normally not be used; consider using `step` - * instead. - */ - pragma[inline] - TypeTracker stepCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - result = stepCallInlineLate(this, nodeFrom, nodeTo) - } - /** * Gets the summary that corresponds to having taken a forwards * heap and/or inter-procedural step from `nodeFrom` to `nodeTo`. */ pragma[inline] TypeTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - result = this.stepNoCall(nodeFrom, nodeTo) - or - result = this.stepCall(nodeFrom, nodeTo) - } - - /** - * Gets the summary that corresponds to having taken a forwards - * intra-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate should normally not be used; consider using `step` - * instead. - */ - pragma[inline] - TypeTracker smallstepNoCall(Node nodeFrom, Node nodeTo) { - result = smallstepNoCallInlineLate(this, nodeFrom, nodeTo) - or - simpleLocalFlowStep(nodeFrom, nodeTo) and - result = this - } - - /** - * Gets the summary that corresponds to having taken a forwards - * inter-procedural step from `nodeFrom` to `nodeTo`. - * - * This predicate should normally not be used; consider using `step` - * instead. - */ - pragma[inline] - TypeTracker smallstepCall(Node nodeFrom, Node nodeTo) { - result = smallstepCallInlineLate(this, nodeFrom, nodeTo) + result = stepInlineLate(this, nodeFrom, nodeTo) } /** @@ -617,9 +532,10 @@ class TypeTracker extends TTypeTracker { */ pragma[inline] TypeTracker smallstep(Node nodeFrom, Node nodeTo) { - result = this.smallstepNoCall(nodeFrom, nodeTo) + result = smallstepInlineLate(this, nodeFrom, nodeTo) or - result = this.smallstepCall(nodeFrom, nodeTo) + simpleLocalFlowStep(nodeFrom, nodeTo) and + result = this } } @@ -631,6 +547,39 @@ module TypeTracker { TypeTracker end() { result.end() } } +pragma[nomagic] +private predicate backStepProj(TypeTrackingNode nodeTo, StepSummary summary) { + step(_, nodeTo, summary) +} + +bindingset[nodeTo, t] +pragma[inline_late] +pragma[noopt] +private TypeBackTracker backStepInlineLate( + TypeBackTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo +) { + exists(StepSummary summary | + backStepProj(nodeTo, summary) and + result = t.prepend(summary) and + step(nodeFrom, nodeTo, summary) + ) +} + +private predicate backSmallstepProj(TypeTrackingNode nodeTo, StepSummary summary) { + smallstep(_, nodeTo, summary) +} + +bindingset[nodeTo, t] +pragma[inline_late] +pragma[noopt] +private TypeBackTracker backSmallstepInlineLate(TypeBackTracker t, Node nodeFrom, Node nodeTo) { + exists(StepSummary summary | + backSmallstepProj(nodeTo, summary) and + result = t.prepend(summary) and + smallstep(nodeFrom, nodeTo, summary) + ) +} + /** * A summary of the steps needed to back-track a use of a value to a given dataflow node. * @@ -714,10 +663,7 @@ class TypeBackTracker extends TTypeBackTracker { */ pragma[inline] TypeBackTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) { - exists(StepSummary summary | - StepSummary::step(pragma[only_bind_out](nodeFrom), nodeTo, pragma[only_bind_into](summary)) and - this = result.prepend(pragma[only_bind_into](summary)) - ) + this = backStepInlineLate(result, nodeFrom, nodeTo) } /** @@ -746,10 +692,7 @@ class TypeBackTracker extends TTypeBackTracker { */ pragma[inline] TypeBackTracker smallstep(Node nodeFrom, Node nodeTo) { - exists(StepSummary summary | - StepSummary::smallstep(nodeFrom, nodeTo, summary) and - this = result.prepend(summary) - ) + this = backSmallstepInlineLate(result, nodeFrom, nodeTo) or simpleLocalFlowStep(nodeFrom, nodeTo) and this = result @@ -785,3 +728,169 @@ module TypeBackTracker { */ TypeBackTracker end() { result.end() } } + +/** + * INTERNAL: Do not use. + * + * Provides logic for constructing a call graph in mutual recursion with type tracking. + * + * When type tracking is used to construct a call graph, we cannot use the join-order + * from `stepInlineLate`, because `step` becomes a recursive call, which means that we + * will have a conjunct with 3 recursive calls: the call to `step`, the call to `stepProj`, + * and the recursive type tracking call itself. The solution is to split the three-way + * non-linear recursion into two non-linear predicates: one that first joins with the + * projected `stepCall` relation, followed by a predicate that joins with the full + * `stepCall` relation (`stepNoCall` not being recursive, can be join-ordered in the + * same way as in `stepInlineLate`). + */ +module CallGraphConstruction { + /** The input to call graph construction. */ + signature module InputSig { + /** A state to track during type tracking. */ + class State; + + /** Holds if type tracking should start at `start` in state `state`. */ + predicate start(Node start, State state); + + /** + * Holds if type tracking should use the step from `nodeFrom` to `nodeTo`, + * which _does not_ depend on the call graph. + * + * Implementing this predicate using `StepSummary::[small]stepNoCall` yields + * standard type tracking. + */ + predicate stepNoCall(Node nodeFrom, Node nodeTo, StepSummary summary); + + /** + * Holds if type tracking should use the step from `nodeFrom` to `nodeTo`, + * which _does_ depend on the call graph. + * + * Implementing this predicate using `StepSummary::[small]stepCall` yields + * standard type tracking. + */ + predicate stepCall(Node nodeFrom, Node nodeTo, StepSummary summary); + + /** A projection of an element from the state space. */ + class StateProj; + + /** Gets the projection of `state`. */ + StateProj stateProj(State state); + + /** Holds if type tracking should stop at `n` when we are tracking projected state `stateProj`. */ + predicate filter(Node n, StateProj stateProj); + } + + /** Provides the `track` predicate for use in call graph construction. */ + module Make<InputSig Input> { + pragma[nomagic] + private predicate stepNoCallProj(Node nodeFrom, StepSummary summary) { + Input::stepNoCall(nodeFrom, _, summary) + } + + pragma[nomagic] + private predicate stepCallProj(Node nodeFrom, StepSummary summary) { + Input::stepCall(nodeFrom, _, summary) + } + + bindingset[nodeFrom, t] + pragma[inline_late] + pragma[noopt] + private TypeTracker stepNoCallInlineLate( + TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo + ) { + exists(StepSummary summary | + stepNoCallProj(nodeFrom, summary) and + result = t.append(summary) and + Input::stepNoCall(nodeFrom, nodeTo, summary) + ) + } + + bindingset[state] + pragma[inline_late] + private Input::StateProj stateProjInlineLate(Input::State state) { + result = Input::stateProj(state) + } + + pragma[nomagic] + private Node track(Input::State state, TypeTracker t) { + t.start() and Input::start(result, state) + or + exists(Input::StateProj stateProj | + stateProj = stateProjInlineLate(state) and + not Input::filter(result, stateProj) + | + exists(TypeTracker t2 | t = stepNoCallInlineLate(t2, track(state, t2), result)) + or + exists(StepSummary summary | + // non-linear recursion + Input::stepCall(trackCall(state, t, summary), result, summary) + ) + ) + } + + bindingset[t, summary] + pragma[inline_late] + private TypeTracker appendInlineLate(TypeTracker t, StepSummary summary) { + result = t.append(summary) + } + + pragma[nomagic] + private Node trackCall(Input::State state, TypeTracker t, StepSummary summary) { + exists(TypeTracker t2 | + // non-linear recursion + result = track(state, t2) and + stepCallProj(result, summary) and + t = appendInlineLate(t2, summary) + ) + } + + /** Gets a node that can be reached from _some_ start node in state `state`. */ + pragma[nomagic] + Node track(Input::State state) { result = track(state, TypeTracker::end()) } + } + + /** A simple version of `CallGraphConstruction` that uses standard type tracking. */ + module Simple { + /** The input to call graph construction. */ + signature module InputSig { + /** A state to track during type tracking. */ + class State; + + /** Holds if type tracking should start at `start` in state `state`. */ + predicate start(Node start, State state); + + /** Holds if type tracking should stop at `n`. */ + predicate filter(Node n); + } + + /** Provides the `track` predicate for use in call graph construction. */ + module Make<InputSig Input> { + private module I implements CallGraphConstruction::InputSig { + private import codeql.util.Unit + + class State = Input::State; + + predicate start(Node start, State state) { Input::start(start, state) } + + predicate stepNoCall(Node nodeFrom, Node nodeTo, StepSummary summary) { + StepSummary::stepNoCall(nodeFrom, nodeTo, summary) + } + + predicate stepCall(Node nodeFrom, Node nodeTo, StepSummary summary) { + StepSummary::stepCall(nodeFrom, nodeTo, summary) + } + + class StateProj = Unit; + + Unit stateProj(State state) { exists(state) and exists(result) } + + predicate filter(Node n, Unit u) { + Input::filter(n) and + exists(u) + } + } + + import CallGraphConstruction::Make<I> + } + } +} From 88c5700c2452aa1208ae321e4d25b8aa4e3be948 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 6 Jun 2023 15:41:11 +0200 Subject: [PATCH 374/739] Ruby: Use `CallGraphConstruction` in call graph construction --- .../dataflow/internal/DataFlowDispatch.qll | 557 ++++++++---------- 1 file changed, 238 insertions(+), 319 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index 410867c7ead..625cc226b96 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -8,6 +8,8 @@ private import FlowSummaryImpl as FlowSummaryImpl private import FlowSummaryImplSpecific as FlowSummaryImplSpecific private import codeql.ruby.dataflow.FlowSummary private import codeql.ruby.dataflow.SSA +private import codeql.util.Boolean +private import codeql.util.Unit /** * A `LocalSourceNode` for a `self` variable. This is the implicit `self` @@ -470,49 +472,22 @@ private module Cached { import Cached -pragma[nomagic] -private predicate stepCallProj(DataFlow::LocalSourceNode nodeFrom, StepSummary summary) { - StepSummary::stepCall(nodeFrom, _, summary) -} - pragma[nomagic] private predicate isNotSelf(DataFlow::Node n) { not n instanceof SelfParameterNodeImpl } -pragma[nomagic] -private DataFlow::LocalSourceNode trackModuleAccess(Module m, TypeTracker t) { - t.start() and m = resolveConstantReadAccess(result.asExpr().getExpr()) - or +private module TrackModuleInput implements CallGraphConstruction::Simple::InputSig { + class State = Module; + + predicate start(DataFlow::Node start, Module m) { + m = resolveConstantReadAccess(start.asExpr().getExpr()) + } + // We exclude steps into `self` parameters, and instead rely on the type of the // enclosing module - isNotSelf(result) and - ( - exists(TypeTracker t2 | t = t2.stepNoCall(trackModuleAccess(m, t2), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(trackModuleAccessCall(m, t, summary), result, summary) - ) - ) + predicate filter(DataFlow::Node n) { n instanceof SelfParameterNodeImpl } } -bindingset[t, summary] -pragma[inline_late] -private TypeTracker append(TypeTracker t, StepSummary summary) { result = t.append(summary) } - -pragma[nomagic] -private DataFlow::LocalSourceNode trackModuleAccessCall(Module m, TypeTracker t, StepSummary summary) { - exists(TypeTracker t2 | - // non-linear recursion - result = trackModuleAccess(m, t2) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) -} - -pragma[nomagic] -private DataFlow::LocalSourceNode trackModuleAccess(Module m) { - result = trackModuleAccess(m, TypeTracker::end()) -} +predicate trackModuleAccess = CallGraphConstruction::Simple::Make<TrackModuleInput>::track/1; pragma[nomagic] private predicate hasUserDefinedNew(Module m) { @@ -552,182 +527,162 @@ private predicate isStandardNewCall(RelevantCall new, Module m, boolean exact) { ) } -/** Holds if `n` is an instance of type `tp`. */ -private predicate isInstance(DataFlow::Node n, Module tp, boolean exact) { - n.asExpr().getExpr() instanceof NilLiteral and - tp = TResolved("NilClass") and - exact = true - or - n.asExpr().getExpr().(BooleanLiteral).isFalse() and - tp = TResolved("FalseClass") and - exact = true - or - n.asExpr().getExpr().(BooleanLiteral).isTrue() and - tp = TResolved("TrueClass") and - exact = true - or - n.asExpr().getExpr() instanceof IntegerLiteral and - tp = TResolved("Integer") and - exact = true - or - n.asExpr().getExpr() instanceof FloatLiteral and - tp = TResolved("Float") and - exact = true - or - n.asExpr().getExpr() instanceof RationalLiteral and - tp = TResolved("Rational") and - exact = true - or - n.asExpr().getExpr() instanceof ComplexLiteral and - tp = TResolved("Complex") and - exact = true - or - n.asExpr().getExpr() instanceof StringlikeLiteral and - tp = TResolved("String") and - exact = true - or - n.asExpr() instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode and - tp = TResolved("Array") and - exact = true - or - n.asExpr() instanceof CfgNodes::ExprNodes::HashLiteralCfgNode and - tp = TResolved("Hash") and - exact = true - or - n.asExpr().getExpr() instanceof MethodBase and - tp = TResolved("Symbol") and - exact = true - or - n.asParameter() instanceof BlockParameter and - tp = TResolved("Proc") and - exact = true - or - n.asExpr().getExpr() instanceof Lambda and - tp = TResolved("Proc") and - exact = true - or - isStandardNewCall(n.asExpr(), tp, exact) - or - // `self` reference in method or top-level (but not in module or singleton method, - // where instance methods cannot be called; only singleton methods) - n = - any(SelfLocalSourceNode self | - exists(MethodBase m | - selfInMethod(self.getVariable(), m, tp) and - not m instanceof SingletonMethod and - if m.getEnclosingModule() instanceof Toplevel then exact = true else exact = false - ) - or - selfInToplevel(self.getVariable(), tp) and - exact = true - ) - or - // `in C => c then c.foo` - asModulePattern(n, tp) and - exact = false - or - // `case object when C then object.foo` - hasAdjacentTypeCheckedReads(_, _, n.asExpr(), tp) and - exact = false -} - private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary) { localFlowStepTypeTracker(nodeFrom, nodeTo) and summary.toString() = "level" } -pragma[nomagic] -private predicate hasAdjacentTypeCheckedReads(DataFlow::Node node) { - hasAdjacentTypeCheckedReads(_, _, node.asExpr(), _) -} - -pragma[nomagic] -private predicate smallStepNoCallForTrackInstance0( - DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary -) { - // We exclude steps into `self` parameters. For those, we instead rely on the type of - // the enclosing module - StepSummary::smallstepNoCall(nodeFrom, nodeTo, summary) and - isNotSelf(nodeTo) - or - // We exclude steps into type checked variables. For those, we instead rely on the - // type being checked against - localFlowStep(nodeFrom, nodeTo, summary) and - not hasAdjacentTypeCheckedReads(nodeTo) -} - -pragma[nomagic] -private predicate smallStepNoCallForTrackInstance0Proj(DataFlow::Node nodeFrom, StepSummary summary) { - smallStepNoCallForTrackInstance0(nodeFrom, _, summary) -} - -bindingset[t, nodeFrom] -pragma[inline_late] -pragma[noopt] -private TypeTracker smallStepNoCallForTrackInstance( - TypeTracker t, DataFlow::Node nodeFrom, DataFlow::Node nodeTo -) { - exists(StepSummary summary | - smallStepNoCallForTrackInstance0Proj(nodeFrom, summary) and - result = t.append(summary) and - smallStepNoCallForTrackInstance0(nodeFrom, nodeTo, summary) - ) -} - -pragma[nomagic] -private DataFlow::Node trackInstance(Module tp, boolean exact, TypeTracker t) { - t.start() and - ( - isInstance(result, tp, exact) +private module TrackInstanceInput implements CallGraphConstruction::InputSig { + pragma[nomagic] + private predicate isInstanceNoCall(DataFlow::Node n, Module tp, boolean exact) { + n.asExpr().getExpr() instanceof NilLiteral and + tp = TResolved("NilClass") and + exact = true or - exists(Module m | - (if m.isClass() then tp = TResolved("Class") else tp = TResolved("Module")) and - exact = true - | - // needed for e.g. `C.new` - m = resolveConstantReadAccess(result.asExpr().getExpr()) + n.asExpr().getExpr().(BooleanLiteral).isFalse() and + tp = TResolved("FalseClass") and + exact = true + or + n.asExpr().getExpr().(BooleanLiteral).isTrue() and + tp = TResolved("TrueClass") and + exact = true + or + n.asExpr().getExpr() instanceof IntegerLiteral and + tp = TResolved("Integer") and + exact = true + or + n.asExpr().getExpr() instanceof FloatLiteral and + tp = TResolved("Float") and + exact = true + or + n.asExpr().getExpr() instanceof RationalLiteral and + tp = TResolved("Rational") and + exact = true + or + n.asExpr().getExpr() instanceof ComplexLiteral and + tp = TResolved("Complex") and + exact = true + or + n.asExpr().getExpr() instanceof StringlikeLiteral and + tp = TResolved("String") and + exact = true + or + n.asExpr() instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode and + tp = TResolved("Array") and + exact = true + or + n.asExpr() instanceof CfgNodes::ExprNodes::HashLiteralCfgNode and + tp = TResolved("Hash") and + exact = true + or + n.asExpr().getExpr() instanceof MethodBase and + tp = TResolved("Symbol") and + exact = true + or + n.asParameter() instanceof BlockParameter and + tp = TResolved("Proc") and + exact = true + or + n.asExpr().getExpr() instanceof Lambda and + tp = TResolved("Proc") and + exact = true + or + // `self` reference in method or top-level (but not in module or singleton method, + // where instance methods cannot be called; only singleton methods) + n = + any(SelfLocalSourceNode self | + exists(MethodBase m | + selfInMethod(self.getVariable(), m, tp) and + not m instanceof SingletonMethod and + if m.getEnclosingModule() instanceof Toplevel then exact = true else exact = false + ) + or + selfInToplevel(self.getVariable(), tp) and + exact = true + ) + or + // `in C => c then c.foo` + asModulePattern(n, tp) and + exact = false + or + // `case object when C then object.foo` + hasAdjacentTypeCheckedReads(_, _, n.asExpr(), tp) and + exact = false + } + + pragma[nomagic] + private predicate isInstanceCall(DataFlow::Node n, Module tp, boolean exact) { + isStandardNewCall(n.asExpr(), tp, exact) + } + + /** Holds if `n` is an instance of type `tp`. */ + pragma[inline] + private predicate isInstance(DataFlow::Node n, Module tp, boolean exact) { + isInstanceNoCall(n, tp, exact) + or + isInstanceCall(n, tp, exact) + } + + pragma[nomagic] + private predicate hasAdjacentTypeCheckedReads(DataFlow::Node node) { + hasAdjacentTypeCheckedReads(_, _, node.asExpr(), _) + } + + newtype State = additional MkState(Module m, Boolean exact) + + predicate start(DataFlow::Node start, State state) { + exists(Module tp, boolean exact | state = MkState(tp, exact) | + isInstance(start, tp, exact) or - // needed for e.g. `self.include` - selfInModule(result.(SelfLocalSourceNode).getVariable(), m) - or - // needed for e.g. `self.puts` - selfInMethod(result.(SelfLocalSourceNode).getVariable(), any(SingletonMethod sm), m) + exists(Module m | + (if m.isClass() then tp = TResolved("Class") else tp = TResolved("Module")) and + exact = true + | + // needed for e.g. `C.new` + m = resolveConstantReadAccess(start.asExpr().getExpr()) + or + // needed for e.g. `self.include` + selfInModule(start.(SelfLocalSourceNode).getVariable(), m) + or + // needed for e.g. `self.puts` + selfInMethod(start.(SelfLocalSourceNode).getVariable(), any(SingletonMethod sm), m) + ) ) - ) - or - exists(TypeTracker t2 | - t = smallStepNoCallForTrackInstance(t2, trackInstance(tp, exact, t2), result) - ) - or - // We exclude steps into `self` parameters. For those, we instead rely on the type of - // the enclosing module - exists(StepSummary summary | - // non-linear recursion - StepSummary::smallstepCall(trackInstanceCall(tp, t, exact, summary), result, summary) and - isNotSelf(result) - ) -} + } -pragma[nomagic] -private predicate smallStepCallProj(DataFlow::Node nodeFrom, StepSummary summary) { - StepSummary::smallstepCall(nodeFrom, _, summary) -} + pragma[nomagic] + predicate stepNoCall(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary) { + // We exclude steps into `self` parameters. For those, we instead rely on the type of + // the enclosing module + StepSummary::smallstepNoCall(nodeFrom, nodeTo, summary) and + isNotSelf(nodeTo) + or + // We exclude steps into type checked variables. For those, we instead rely on the + // type being checked against + localFlowStep(nodeFrom, nodeTo, summary) and + not hasAdjacentTypeCheckedReads(nodeTo) + } -pragma[nomagic] -private DataFlow::Node trackInstanceCall( - Module tp, TypeTracker t, boolean exact, StepSummary summary -) { - exists(TypeTracker t2 | - // non-linear recursion - result = trackInstance(tp, exact, t2) and - smallStepCallProj(result, summary) and - t = append(t2, summary) - ) + predicate stepCall(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary) { + StepSummary::smallstepCall(nodeFrom, nodeTo, summary) + } + + class StateProj = Unit; + + Unit stateProj(State state) { exists(state) and exists(result) } + + // We exclude steps into `self` parameters, and instead rely on the type of the + // enclosing module + predicate filter(DataFlow::Node n, Unit u) { + n instanceof SelfParameterNodeImpl and + exists(u) + } } pragma[nomagic] private DataFlow::Node trackInstance(Module tp, boolean exact) { - result = trackInstance(tp, exact, TypeTracker::end()) + result = + CallGraphConstruction::Make<TrackInstanceInput>::track(TrackInstanceInput::MkState(tp, exact)) } pragma[nomagic] @@ -768,37 +723,17 @@ private CfgScope getTargetInstance(RelevantCall call, string method) { ) } -pragma[nomagic] -private DataFlow::LocalSourceNode trackBlock(Block block, TypeTracker t) { - t.start() and result.asExpr().getExpr() = block - or - // We exclude steps into `self` parameters, which may happen when the code - // base contains implementations of `call`. - isNotSelf(result) and - ( - exists(TypeTracker t2 | t = t2.stepNoCall(trackBlock(block, t2), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(trackBlockCall(block, t, summary), result, summary) - ) - ) +private module TrackBlockInput implements CallGraphConstruction::Simple::InputSig { + class State = Block; + + predicate start(DataFlow::Node start, Block block) { start.asExpr().getExpr() = block } + + // We exclude steps into `self` parameters, and instead rely on the type of the + // enclosing module + predicate filter(DataFlow::Node n) { n instanceof SelfParameterNodeImpl } } -pragma[nomagic] -private DataFlow::LocalSourceNode trackBlockCall(Block block, TypeTracker t, StepSummary summary) { - exists(TypeTracker t2 | - // non-linear recursion - result = trackBlock(block, t2) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) -} - -pragma[nomagic] -private DataFlow::LocalSourceNode trackBlock(Block block) { - result = trackBlock(block, TypeTracker::end()) -} +private predicate trackBlock = CallGraphConstruction::Simple::Make<TrackBlockInput>::track/1; /** Holds if `m` is a singleton method named `name`, defined on `object. */ private predicate singletonMethod(MethodBase m, string name, Expr object) { @@ -965,72 +900,81 @@ predicate singletonMethodOnInstance(MethodBase method, string name, Expr object) ) } -/** - * Holds if there is reverse flow from `nodeFrom` to `nodeTo` via a parameter. - * - * This is only used for tracking singleton methods, where we want to be able - * to handle cases like - * - * ```rb - * def add_singleton x - * def x.foo; end - * end - * - * y = add_singleton C.new - * y.foo - * ``` - * - * and - * - * ```rb - * class C - * def add_singleton_to_self - * def self.foo; end - * end - * end - * - * y = C.new - * y.add_singleton_to_self - * y.foo - * ``` - */ -pragma[nomagic] -private predicate paramReturnFlow( - DataFlow::Node nodeFrom, DataFlow::PostUpdateNode nodeTo, StepSummary summary -) { - exists(RelevantCall call, DataFlow::Node arg, DataFlow::ParameterNode p, Expr nodeFromPreExpr | - TypeTrackerSpecific::callStep(call, arg, p) and - nodeTo.getPreUpdateNode() = arg and - summary.toString() = "return" and - ( - nodeFromPreExpr = nodeFrom.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr().getExpr() +private module TrackSingletonMethodOnInstanceInput implements CallGraphConstruction::InputSig { + /** + * Holds if there is reverse flow from `nodeFrom` to `nodeTo` via a parameter. + * + * This is only used for tracking singleton methods, where we want to be able + * to handle cases like + * + * ```rb + * def add_singleton x + * def x.foo; end + * end + * + * y = add_singleton C.new + * y.foo + * ``` + * + * and + * + * ```rb + * class C + * def add_singleton_to_self + * def self.foo; end + * end + * end + * + * y = C.new + * y.add_singleton_to_self + * y.foo + * ``` + */ + pragma[nomagic] + private predicate paramReturnFlow( + DataFlow::Node nodeFrom, DataFlow::PostUpdateNode nodeTo, StepSummary summary + ) { + exists(RelevantCall call, DataFlow::Node arg, DataFlow::ParameterNode p, Expr nodeFromPreExpr | + TypeTrackerSpecific::callStep(call, arg, p) and + nodeTo.getPreUpdateNode() = arg and + summary.toString() = "return" and + ( + nodeFromPreExpr = nodeFrom.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr().getExpr() + or + nodeFromPreExpr = nodeFrom.asExpr().getExpr() and + singletonMethodOnInstance(_, _, nodeFromPreExpr) + ) + | + nodeFromPreExpr = p.getParameter().(NamedParameter).getVariable().getAnAccess() or - nodeFromPreExpr = nodeFrom.asExpr().getExpr() and - singletonMethodOnInstance(_, _, nodeFromPreExpr) + nodeFromPreExpr = p.(SelfParameterNodeImpl).getSelfVariable().getAnAccess() ) - | - nodeFromPreExpr = p.getParameter().(NamedParameter).getVariable().getAnAccess() - or - nodeFromPreExpr = p.(SelfParameterNodeImpl).getSelfVariable().getAnAccess() - ) -} + } -pragma[nomagic] -private DataFlow::Node trackSingletonMethodOnInstance(MethodBase method, string name, TypeTracker t) { - t.start() and - singletonMethodOnInstance(method, name, result.asExpr().getExpr()) - or - ( - exists(TypeTracker t2 | - t = t2.smallstepNoCall(trackSingletonMethodOnInstance(method, name, t2), result) - ) + class State = MethodBase; + + predicate start(DataFlow::Node start, MethodBase method) { + singletonMethodOnInstance(method, _, start.asExpr().getExpr()) + } + + predicate stepNoCall(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary) { + StepSummary::smallstepNoCall(nodeFrom, nodeTo, summary) or - exists(StepSummary summary | - // non-linear recursion - smallStepCallForTrackSingletonMethodOnInstance(trackSingletonMethodOnInstanceCall(method, - name, t, summary), result, summary) - ) - ) and + localFlowStep(nodeFrom, nodeTo, summary) + } + + predicate stepCall(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary) { + StepSummary::smallstepCall(nodeFrom, nodeTo, summary) + or + paramReturnFlow(nodeFrom, nodeTo, summary) + } + + class StateProj extends string { + StateProj() { singletonMethodOnInstance(_, this, _) } + } + + StateProj stateProj(MethodBase method) { singletonMethodOnInstance(method, result, _) } + // Stop flow at redefinitions. // // Example: @@ -1039,40 +983,15 @@ private DataFlow::Node trackSingletonMethodOnInstance(MethodBase method, string // def x.foo; end // x.foo # <- we want to resolve this call to the second definition only // ``` - not singletonMethodOnInstance(_, name, result.asExpr().getExpr()) -} - -pragma[nomagic] -private predicate smallStepCallForTrackSingletonMethodOnInstance( - DataFlow::Node nodeFrom, DataFlow::Node nodeTo, StepSummary summary -) { - StepSummary::smallstepCall(nodeFrom, nodeTo, summary) - or - paramReturnFlow(nodeFrom, nodeTo, summary) -} - -pragma[nomagic] -private predicate smallStepCallForTrackSingletonMethodOnInstanceProj( - DataFlow::Node nodeFrom, StepSummary summary -) { - smallStepCallForTrackSingletonMethodOnInstance(nodeFrom, _, summary) -} - -pragma[nomagic] -private DataFlow::Node trackSingletonMethodOnInstanceCall( - MethodBase method, string name, TypeTracker t, StepSummary summary -) { - exists(TypeTracker t2 | - // non-linear recursion - result = trackSingletonMethodOnInstance(method, name, t2) and - smallStepCallForTrackSingletonMethodOnInstanceProj(result, summary) and - t = append(t2, summary) - ) + predicate filter(DataFlow::Node n, StateProj name) { + singletonMethodOnInstance(_, name, n.asExpr().getExpr()) + } } pragma[nomagic] private DataFlow::Node trackSingletonMethodOnInstance(MethodBase method, string name) { - result = trackSingletonMethodOnInstance(method, name, TypeTracker::end()) + result = CallGraphConstruction::Make<TrackSingletonMethodOnInstanceInput>::track(method) and + singletonMethodOnInstance(method, name, _) } /** Holds if a `self` access may be the receiver of `call` directly inside module `m`. */ From 48ac3e58ee6bb7fdb26c079da1c413ab5c58fc2b Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 6 Jun 2023 16:09:10 +0200 Subject: [PATCH 375/739] Python: Use `CallGraphConstruction` in call graph construction --- .../new/internal/DataFlowDispatch.qll | 425 ++++++------------ 1 file changed, 144 insertions(+), 281 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 958bca246cb..895ef74b41e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -38,6 +38,7 @@ private import DataFlowPrivate private import FlowSummaryImpl as FlowSummaryImpl private import FlowSummaryImplSpecific as FlowSummaryImplSpecific private import semmle.python.internal.CachedStages +private import semmle.python.dataflow.new.internal.TypeTracker::CallGraphConstruction as CallGraphConstruction newtype TParameterPosition = /** Used for `self` in methods, and `cls` in classmethods. */ @@ -464,189 +465,105 @@ private predicate ignoreForCallGraph(File f) { f.getAbsolutePath().matches("%/site-packages/sympy/%") } -bindingset[n] -pragma[inline_late] -private predicate includeInCallGraph(TypeTrackingNode n) { - not ignoreForCallGraph(n.getLocation().getFile()) -} +private module TrackFunctionInput implements CallGraphConstruction::Simple::InputSig { + class State = Function; -pragma[nomagic] -private predicate stepCallProj(TypeTrackingNode nodeFrom, StepSummary summary) { - StepSummary::stepCall(nodeFrom, _, summary) -} - -bindingset[t, summary] -pragma[inline_late] -private TypeTracker append(TypeTracker t, StepSummary summary) { result = t.append(summary) } - -/** - * Gets a reference to the function `func`. - */ -private TypeTrackingNode functionTracker(TypeTracker t, Function func) { - includeInCallGraph(result) and - ( - t.start() and - ( - result.asExpr() = func.getDefinition() - or - // when a function is decorated, it's the result of the (last) decorator call that - // is used - result.asExpr() = func.getDefinition().(FunctionExpr).getADecoratorCall() - ) + predicate start(Node start, Function func) { + start.asExpr() = func.getDefinition() or - ( - exists(TypeTracker t2 | t = t2.stepNoCall(functionTracker(t2, func), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(functionTrackerCall(t, func, summary), result, summary) - ) - ) - ) -} + // when a function is decorated, it's the result of the (last) decorator call that + // is used + start.asExpr() = func.getDefinition().(FunctionExpr).getADecoratorCall() + } -pragma[nomagic] -private TypeTrackingNode functionTrackerCall(TypeTracker t, Function func, StepSummary summary) { - exists(TypeTracker t2 | - // non-linear recursion - result = functionTracker(t2, func) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) + predicate filter(Node n) { ignoreForCallGraph(n.getLocation().getFile()) } } /** * Gets a reference to the function `func`. */ -Node functionTracker(Function func) { functionTracker(TypeTracker::end(), func).flowsTo(result) } +Node functionTracker(Function func) { + CallGraphConstruction::Simple::Make<TrackFunctionInput>::track(func) + .(LocalSourceNode) + .flowsTo(result) +} -/** - * Gets a reference to the class `cls`. - */ -private TypeTrackingNode classTracker(TypeTracker t, Class cls) { - includeInCallGraph(result) and - ( - t.start() and - ( - result.asExpr() = cls.getParent() - or - // when a class is decorated, it's the result of the (last) decorator call that - // is used - result.asExpr() = cls.getParent().getADecoratorCall() - or - // `type(obj)`, where obj is an instance of this class - result = getTypeCall() and - result.(CallCfgNode).getArg(0) = classInstanceTracker(cls) - ) +private module TrackClassInput implements CallGraphConstruction::Simple::InputSig { + class State = Class; + + predicate start(Node start, Class cls) { + start.asExpr() = cls.getParent() or - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and - ( - exists(TypeTracker t2 | t = t2.stepNoCall(classTracker(t2, cls), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(classTrackerCall(t, cls, summary), result, summary) - ) - ) - ) -} + // when a class is decorated, it's the result of the (last) decorator call that + // is used + start.asExpr() = cls.getParent().getADecoratorCall() + or + // `type(obj)`, where obj is an instance of this class + start = getTypeCall() and + start.(CallCfgNode).getArg(0) = classInstanceTracker(cls) + } -pragma[nomagic] -private TypeTrackingNode classTrackerCall(TypeTracker t, Class cls, StepSummary summary) { - exists(TypeTracker t2 | - // non-linear recursion - result = classTracker(t2, cls) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) + predicate filter(Node n) { + ignoreForCallGraph(n.getLocation().getFile()) + or + n.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) + } } /** * Gets a reference to the class `cls`. */ -Node classTracker(Class cls) { classTracker(TypeTracker::end(), cls).flowsTo(result) } +Node classTracker(Class cls) { + CallGraphConstruction::Simple::Make<TrackClassInput>::track(cls).(LocalSourceNode).flowsTo(result) +} -/** - * Gets a reference to an instance of the class `cls`. - */ -private TypeTrackingNode classInstanceTracker(TypeTracker t, Class cls) { - includeInCallGraph(result) and - ( - t.start() and - resolveClassCall(result.(CallCfgNode).asCfgNode(), cls) +private module TrackClassInstanceInput implements CallGraphConstruction::Simple::InputSig { + class State = Class; + + predicate start(Node start, Class cls) { + resolveClassCall(start.(CallCfgNode).asCfgNode(), cls) or // result of `super().__new__` as used in a `__new__` method implementation - t.start() and exists(Class classUsedInSuper | - fromSuperNewCall(result.(CallCfgNode).asCfgNode(), classUsedInSuper, _, _) and + fromSuperNewCall(start.(CallCfgNode).asCfgNode(), classUsedInSuper, _, _) and classUsedInSuper = getADirectSuperclass*(cls) ) - or - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and - ( - exists(TypeTracker t2 | t = t2.stepNoCall(classInstanceTracker(t2, cls), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(classInstanceTrackerCall(t, cls, summary), result, summary) - ) - ) - ) -} + } -pragma[nomagic] -private TypeTrackingNode classInstanceTrackerCall(TypeTracker t, Class cls, StepSummary summary) { - exists(TypeTracker t2 | - // non-linear recursion - result = classInstanceTracker(t2, cls) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) + predicate filter(Node n) { + ignoreForCallGraph(n.getLocation().getFile()) + or + n.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) + } } /** * Gets a reference to an instance of the class `cls`. */ Node classInstanceTracker(Class cls) { - classInstanceTracker(TypeTracker::end(), cls).flowsTo(result) + CallGraphConstruction::Simple::Make<TrackClassInstanceInput>::track(cls) + .(LocalSourceNode) + .flowsTo(result) } -/** - * Gets a reference to the `self` argument of a method on class `classWithMethod`. - * The method cannot be a `staticmethod` or `classmethod`. - */ -private TypeTrackingNode selfTracker(TypeTracker t, Class classWithMethod) { - includeInCallGraph(result) and - ( - t.start() and +private module TrackSelfInput implements CallGraphConstruction::Simple::InputSig { + class State = Class; + + predicate start(Node start, Class classWithMethod) { exists(Function func | func = classWithMethod.getAMethod() and not isStaticmethod(func) and not isClassmethod(func) | - result.asExpr() = func.getArg(0) + start.asExpr() = func.getArg(0) ) - or - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and - ( - exists(TypeTracker t2 | t = t2.stepNoCall(selfTracker(t2, classWithMethod), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(selfTrackerCall(t, classWithMethod, summary), result, summary) - ) - ) - ) -} + } -pragma[nomagic] -private TypeTrackingNode selfTrackerCall(TypeTracker t, Class classWithMethod, StepSummary summary) { - exists(TypeTracker t2 | - // non-linear recursion - result = selfTracker(t2, classWithMethod) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) + predicate filter(Node n) { + ignoreForCallGraph(n.getLocation().getFile()) + or + n.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) + } } /** @@ -654,53 +571,32 @@ private TypeTrackingNode selfTrackerCall(TypeTracker t, Class classWithMethod, S * The method cannot be a `staticmethod` or `classmethod`. */ Node selfTracker(Class classWithMethod) { - selfTracker(TypeTracker::end(), classWithMethod).flowsTo(result) + CallGraphConstruction::Simple::Make<TrackSelfInput>::track(classWithMethod) + .(LocalSourceNode) + .flowsTo(result) } -/** - * Gets a reference to the enclosing class `classWithMethod` from within one of its - * methods, either through the `cls` argument from a `classmethod` or from `type(self)` - * from a normal method. - */ -private TypeTrackingNode clsArgumentTracker(TypeTracker t, Class classWithMethod) { - includeInCallGraph(result) and - ( - t.start() and - ( - exists(Function func | - func = classWithMethod.getAMethod() and - isClassmethod(func) - | - result.asExpr() = func.getArg(0) - ) - or - // type(self) - result = getTypeCall() and - result.(CallCfgNode).getArg(0) = selfTracker(classWithMethod) +private module TrackClsArgumentInput implements CallGraphConstruction::Simple::InputSig { + class State = Class; + + predicate start(Node start, Class classWithMethod) { + exists(Function func | + func = classWithMethod.getAMethod() and + isClassmethod(func) + | + start.asExpr() = func.getArg(0) ) or - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and - ( - exists(TypeTracker t2 | t = t2.stepNoCall(clsArgumentTracker(t2, classWithMethod), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(clsArgumentTrackerCall(t, classWithMethod, summary), result, summary) - ) - ) - ) -} + // type(self) + start = getTypeCall() and + start.(CallCfgNode).getArg(0) = selfTracker(classWithMethod) + } -pragma[nomagic] -private TypeTrackingNode clsArgumentTrackerCall( - TypeTracker t, Class classWithMethod, StepSummary summary -) { - exists(TypeTracker t2 | - // non-linear recursion - result = clsArgumentTracker(t2, classWithMethod) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) + predicate filter(Node n) { + ignoreForCallGraph(n.getLocation().getFile()) + or + n.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) + } } /** @@ -709,46 +605,28 @@ private TypeTrackingNode clsArgumentTrackerCall( * from a normal method. */ Node clsArgumentTracker(Class classWithMethod) { - clsArgumentTracker(TypeTracker::end(), classWithMethod).flowsTo(result) + CallGraphConstruction::Simple::Make<TrackClsArgumentInput>::track(classWithMethod) + .(LocalSourceNode) + .flowsTo(result) } -/** - * Gets a reference to the result of calling `super` without any argument, where the - * call happened in the method `func` (either a method or a classmethod). - */ -private TypeTrackingNode superCallNoArgumentTracker(TypeTracker t, Function func) { - includeInCallGraph(result) and - ( - t.start() and +private module TrackSuperCallNoArgumentInput implements CallGraphConstruction::Simple::InputSig { + class State = Function; + + predicate start(Node start, Function func) { not isStaticmethod(func) and - exists(CallCfgNode call | result = call | + exists(CallCfgNode call | start = call | call = getSuperCall() and not exists(call.getArg(_)) and call.getScope() = func ) - or - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and - ( - exists(TypeTracker t2 | t = t2.stepNoCall(superCallNoArgumentTracker(t2, func), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(superCallNoArgumentTrackerCall(t, func, summary), result, summary) - ) - ) - ) -} + } -pragma[nomagic] -private TypeTrackingNode superCallNoArgumentTrackerCall( - TypeTracker t, Function func, StepSummary summary -) { - exists(TypeTracker t2 | - // non-linear recursion - result = functionTracker(t2, func) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) + predicate filter(Node n) { + ignoreForCallGraph(n.getLocation().getFile()) + or + n.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) + } } /** @@ -756,45 +634,30 @@ private TypeTrackingNode superCallNoArgumentTrackerCall( * call happened in the method `func` (either a method or a classmethod). */ Node superCallNoArgumentTracker(Function func) { - superCallNoArgumentTracker(TypeTracker::end(), func).flowsTo(result) + CallGraphConstruction::Simple::Make<TrackSuperCallNoArgumentInput>::track(func) + .(LocalSourceNode) + .flowsTo(result) } -/** - * Gets a reference to the result of calling `super` with 2 arguments, where the - * first is a reference to the class `cls`, and the second argument is `obj`. - */ -private TypeTrackingNode superCallTwoArgumentTracker(TypeTracker t, Class cls, Node obj) { - includeInCallGraph(result) and - ( - t.start() and - exists(CallCfgNode call | result = call | - call = getSuperCall() and - call.getArg(0) = classTracker(cls) and - call.getArg(1) = obj - ) +private module TrackSuperCallTwoArgumentInput implements CallGraphConstruction::Simple::InputSig { + additional predicate superCall(CallCfgNode call, Class cls, Node obj) { + call = getSuperCall() and + call.getArg(0) = classTracker(cls) and + call.getArg(1) = obj + } + + class State = CallCfgNode; + + predicate start(Node start, CallCfgNode call) { + superCall(call, _, _) and + start = call + } + + predicate filter(Node n) { + ignoreForCallGraph(n.getLocation().getFile()) or - not result.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) and - ( - exists(TypeTracker t2 | t = t2.stepNoCall(superCallTwoArgumentTracker(t2, cls, obj), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(superCallTwoArgumentTrackerCall(t, cls, obj, summary), result, summary) - ) - ) - ) -} - -pragma[nomagic] -private TypeTrackingNode superCallTwoArgumentTrackerCall( - TypeTracker t, Class cls, Node obj, StepSummary summary -) { - exists(TypeTracker t2 | - // non-linear recursion - result = superCallTwoArgumentTracker(t2, cls, obj) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) + n.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) + } } /** @@ -802,7 +665,12 @@ private TypeTrackingNode superCallTwoArgumentTrackerCall( * first is a reference to the class `cls`, and the second argument is `obj`. */ Node superCallTwoArgumentTracker(Class cls, Node obj) { - superCallTwoArgumentTracker(TypeTracker::end(), cls, obj).flowsTo(result) + exists(CallCfgNode call | + TrackSuperCallTwoArgumentInput::superCall(call, cls, obj) and + CallGraphConstruction::Simple::Make<TrackSuperCallTwoArgumentInput>::track(call) + .(LocalSourceNode) + .flowsTo(result) + ) } // ============================================================================= @@ -946,35 +814,30 @@ Function findFunctionAccordingToMroKnownStartingClass(Class startingClass, strin // ============================================================================= // attribute trackers // ============================================================================= -/** Gets a reference to the attribute read `attr` */ -private TypeTrackingNode attrReadTracker(TypeTracker t, AttrRead attr) { - t.start() and - result = attr and - attr.getObject() in [ - classTracker(_), classInstanceTracker(_), selfTracker(_), clsArgumentTracker(_), - superCallNoArgumentTracker(_), superCallTwoArgumentTracker(_, _) - ] - or - exists(TypeTracker t2 | t = t2.stepNoCall(attrReadTracker(t2, attr), result)) - or - exists(StepSummary summary | - // non-linear recursion - StepSummary::stepCall(attrReadTrackerCall(t, attr, summary), result, summary) - ) -} +private module TrackAttrReadInput implements CallGraphConstruction::Simple::InputSig { + class State = AttrRead; -pragma[nomagic] -private TypeTrackingNode attrReadTrackerCall(TypeTracker t, AttrRead attr, StepSummary summary) { - exists(TypeTracker t2 | - // non-linear recursion - result = attrReadTracker(t2, attr) and - stepCallProj(result, summary) and - t = append(t2, summary) - ) + predicate start(Node start, AttrRead attr) { + start = attr and + attr.getObject() in [ + classTracker(_), classInstanceTracker(_), selfTracker(_), clsArgumentTracker(_), + superCallNoArgumentTracker(_), superCallTwoArgumentTracker(_, _) + ] + } + + predicate filter(Node n) { + ignoreForCallGraph(n.getLocation().getFile()) + or + n.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pp | pp.isSelf())) + } } /** Gets a reference to the attribute read `attr` */ -Node attrReadTracker(AttrRead attr) { attrReadTracker(TypeTracker::end(), attr).flowsTo(result) } +Node attrReadTracker(AttrRead attr) { + CallGraphConstruction::Simple::Make<TrackAttrReadInput>::track(attr) + .(LocalSourceNode) + .flowsTo(result) +} // ============================================================================= // call and argument resolution From 60725e9580b2a19095de5d111ec445910de60bb6 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 7 Jun 2023 09:07:22 +0200 Subject: [PATCH 376/739] Update java/ql/lib/ext/org.springframework.core.io.model.yml --- java/ql/lib/ext/org.springframework.core.io.model.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/ext/org.springframework.core.io.model.yml b/java/ql/lib/ext/org.springframework.core.io.model.yml index 7f3f3718471..b6dd35c8096 100644 --- a/java/ql/lib/ext/org.springframework.core.io.model.yml +++ b/java/ql/lib/ext/org.springframework.core.io.model.yml @@ -3,4 +3,5 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.springframework.core.io", "ResourceLoader", True, "getResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] # todo: look into whether this may also be a request forgery sink + - ["org.springframework.core.io", "ResourceLoader", True, "getResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.springframework.core.io", "ResourceLoader", True, "getResource", "(String)", "", "Argument[0]", "request-forgery", "manual"] From 8001ae9669ffe778732f2b5b4b2ff83d81f23b14 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 7 Jun 2023 09:08:24 +0200 Subject: [PATCH 377/739] Update java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com> --- java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 68365db51c2..8261aef9fb3 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -50,7 +50,7 @@ private class FileCreationSink extends DataFlow::Node { /** * Holds if `sink` is a path creation node that doesn't imply a read/write filesystem operation. * This is to avoid creating new spurious alerts, since `PathCreation` sinks weren't - * previosuly part of this query. + * previously part of this query. */ private predicate isPathCreation(DataFlow::Node sink) { exists(PathCreation pc | From 700e3d5e5317974facfad004e3fddcf8add57a06 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Wed, 7 Jun 2023 09:12:39 +0200 Subject: [PATCH 378/739] Codegen: rename `ipa` to `synth` --- misc/codegen/generators/cppgen.py | 2 +- misc/codegen/generators/dbschemegen.py | 4 +- misc/codegen/generators/qlgen.py | 74 +++++++++---------- misc/codegen/lib/ql.py | 38 +++++----- misc/codegen/lib/schema.py | 12 +-- misc/codegen/lib/schemadefs.py | 4 +- misc/codegen/loaders/schemaloader.py | 32 ++++---- misc/codegen/templates/ql_stub.mustache | 8 +- ...che => ql_synth_constructor_stub.mustache} | 8 +- ...types.mustache => ql_synth_types.mustache} | 16 ++-- misc/codegen/test/test_cppgen.py | 8 +- misc/codegen/test/test_dbschemegen.py | 12 +-- misc/codegen/test/test_ql.py | 4 +- misc/codegen/test/test_qlgen.py | 20 ++--- misc/codegen/test/test_schemaloader.py | 34 ++++----- 15 files changed, 138 insertions(+), 138 deletions(-) rename misc/codegen/templates/{ql_ipa_constructor_stub.mustache => ql_synth_constructor_stub.mustache} (61%) rename misc/codegen/templates/{ql_ipa_types.mustache => ql_synth_types.mustache} (91%) diff --git a/misc/codegen/generators/cppgen.py b/misc/codegen/generators/cppgen.py index 8f522dc1435..de53b771d35 100644 --- a/misc/codegen/generators/cppgen.py +++ b/misc/codegen/generators/cppgen.py @@ -85,7 +85,7 @@ class Processor: def get_classes(self): ret = {'': []} for k, cls in self._classmap.items(): - if not cls.ipa: + if not cls.synth: ret.setdefault(cls.group, []).append(self._get_class(cls.name)) return ret diff --git a/misc/codegen/generators/dbschemegen.py b/misc/codegen/generators/dbschemegen.py index bc45ae3022f..2c3cd5598d5 100755 --- a/misc/codegen/generators/dbschemegen.py +++ b/misc/codegen/generators/dbschemegen.py @@ -40,10 +40,10 @@ def dbtype(typename: str, add_or_none_except: typing.Optional[str] = None) -> st def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], add_or_none_except: typing.Optional[str] = None): """ Yield all dbscheme entities needed to model class `cls` """ - if cls.ipa: + if cls.synth: return if cls.derived: - yield Union(dbtype(cls.name), (dbtype(c) for c in cls.derived if not lookup[c].ipa)) + yield Union(dbtype(cls.name), (dbtype(c) for c in cls.derived if not lookup[c].synth)) dir = pathlib.Path(cls.group) if cls.group else None # output a table specific to a class only if it is a leaf class or it has 1-to-1 properties # Leaf classes need a table to bind the `@` ids diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py index 99aca88add4..0dad9d3322f 100755 --- a/misc/codegen/generators/qlgen.py +++ b/misc/codegen/generators/qlgen.py @@ -111,7 +111,7 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic is_predicate=prop.is_predicate, is_unordered=prop.is_unordered, description=prop.description, - synth=bool(cls.ipa) or prop.synth, + synth=bool(cls.synth) or prop.synth, type_is_hideable=lookup[prop.type].hideable if prop.type in lookup else False, ) if prop.is_single: @@ -179,26 +179,26 @@ def _to_db_type(x: str) -> str: _final_db_class_lookup = {} -def get_ql_ipa_class_db(name: str) -> ql.Synth.FinalClassDb: +def get_ql_synth_class_db(name: str) -> ql.Synth.FinalClassDb: return _final_db_class_lookup.setdefault(name, ql.Synth.FinalClassDb(name=name, params=[ ql.Synth.Param("id", _to_db_type(name))])) -def get_ql_ipa_class(cls: schema.Class): +def get_ql_synth_class(cls: schema.Class): if cls.derived: return ql.Synth.NonFinalClass(name=cls.name, derived=sorted(cls.derived), root=not cls.bases) - if cls.ipa and cls.ipa.from_class is not None: - source = cls.ipa.from_class - get_ql_ipa_class_db(source).subtract_type(cls.name) - return ql.Synth.FinalClassDerivedIpa(name=cls.name, - params=[ql.Synth.Param("id", _to_db_type(source))]) - if cls.ipa and cls.ipa.on_arguments is not None: - return ql.Synth.FinalClassFreshIpa(name=cls.name, - params=[ql.Synth.Param(k, _to_db_type(v)) - for k, v in cls.ipa.on_arguments.items()]) - return get_ql_ipa_class_db(cls.name) + if cls.synth and cls.synth.from_class is not None: + source = cls.synth.from_class + get_ql_synth_class_db(source).subtract_type(cls.name) + return ql.Synth.FinalClassDerivedSynth(name=cls.name, + params=[ql.Synth.Param("id", _to_db_type(source))]) + if cls.synth and cls.synth.on_arguments is not None: + return ql.Synth.FinalClassFreshSynth(name=cls.name, + params=[ql.Synth.Param(k, _to_db_type(v)) + for k, v in cls.synth.on_arguments.items()]) + return get_ql_synth_class_db(cls.name) def get_import(file: pathlib.Path, root_dir: pathlib.Path): @@ -291,26 +291,26 @@ def _should_skip_qltest(cls: schema.Class, lookup: typing.Dict[str, schema.Class def _get_stub(cls: schema.Class, base_import: str, generated_import_prefix: str) -> ql.Stub: - if isinstance(cls.ipa, schema.IpaInfo): - if cls.ipa.from_class is not None: + if isinstance(cls.synth, schema.SynthInfo): + if cls.synth.from_class is not None: accessors = [ - ql.IpaUnderlyingAccessor( + ql.SynthUnderlyingAccessor( argument="Entity", - type=_to_db_type(cls.ipa.from_class), + type=_to_db_type(cls.synth.from_class), constructorparams=["result"] ) ] - elif cls.ipa.on_arguments is not None: + elif cls.synth.on_arguments is not None: accessors = [ - ql.IpaUnderlyingAccessor( + ql.SynthUnderlyingAccessor( argument=inflection.camelize(arg), type=_to_db_type(type), - constructorparams=["result" if a == arg else "_" for a in cls.ipa.on_arguments] - ) for arg, type in cls.ipa.on_arguments.items() + constructorparams=["result" if a == arg else "_" for a in cls.synth.on_arguments] + ) for arg, type in cls.synth.on_arguments.items() ] else: accessors = [] - return ql.Stub(name=cls.name, base_import=base_import, import_prefix=generated_import_prefix, ipa_accessors=accessors) + return ql.Stub(name=cls.name, base_import=base_import, import_prefix=generated_import_prefix, synth_accessors=accessors) def generate(opts, renderer): @@ -344,7 +344,7 @@ def generate(opts, renderer): with renderer.manage(generated=generated, stubs=stubs, registry=opts.generated_registry, force=opts.force) as renderer: - db_classes = [cls for name, cls in classes.items() if not data.classes[name].ipa] + db_classes = [cls for name, cls in classes.items() if not data.classes[name].synth] renderer.render(ql.DbClasses(db_classes), out / "Raw.qll") classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name)) @@ -401,32 +401,32 @@ def generate(opts, renderer): elements_module=elements_module, property=p), test_dir / f"{c.name}_{p.getter}.ql") - final_ipa_types = [] - non_final_ipa_types = [] + final_synth_types = [] + non_final_synth_types = [] constructor_imports = [] - ipa_constructor_imports = [] + synth_constructor_imports = [] stubs = {} for cls in sorted(data.classes.values(), key=lambda cls: (cls.group, cls.name)): - ipa_type = get_ql_ipa_class(cls) - if ipa_type.is_final: - final_ipa_types.append(ipa_type) - if ipa_type.has_params: + synth_type = get_ql_synth_class(cls) + if synth_type.is_final: + final_synth_types.append(synth_type) + if synth_type.has_params: stub_file = stub_out / cls.group / f"{cls.name}Constructor.qll" if not renderer.is_customized_stub(stub_file): - # stub rendering must be postponed as we might not have yet all subtracted ipa types in `ipa_type` - stubs[stub_file] = ql.Synth.ConstructorStub(ipa_type, import_prefix=generated_import_prefix) + # stub rendering must be postponed as we might not have yet all subtracted synth types in `synth_type` + stubs[stub_file] = ql.Synth.ConstructorStub(synth_type, import_prefix=generated_import_prefix) constructor_import = get_import(stub_file, opts.root_dir) constructor_imports.append(constructor_import) - if ipa_type.is_ipa: - ipa_constructor_imports.append(constructor_import) + if synth_type.is_synth: + synth_constructor_imports.append(constructor_import) else: - non_final_ipa_types.append(ipa_type) + non_final_synth_types.append(synth_type) for stub_file, data in stubs.items(): renderer.render(data, stub_file) renderer.render(ql.Synth.Types(root.name, generated_import_prefix, - final_ipa_types, non_final_ipa_types), out / "Synth.qll") + final_synth_types, non_final_synth_types), out / "Synth.qll") renderer.render(ql.ImportList(constructor_imports), out / "SynthConstructors.qll") - renderer.render(ql.ImportList(ipa_constructor_imports), out / "PureSynthConstructors.qll") + renderer.render(ql.ImportList(synth_constructor_imports), out / "PureSynthConstructors.qll") if opts.ql_format: format(opts.codeql_binary, renderer.written) diff --git a/misc/codegen/lib/ql.py b/misc/codegen/lib/ql.py index a5f82a3d64b..59a672ab3ce 100644 --- a/misc/codegen/lib/ql.py +++ b/misc/codegen/lib/ql.py @@ -147,7 +147,7 @@ class Class: @dataclass -class IpaUnderlyingAccessor: +class SynthUnderlyingAccessor: argument: str type: str constructorparams: List[Param] @@ -165,11 +165,11 @@ class Stub: name: str base_import: str import_prefix: str - ipa_accessors: List[IpaUnderlyingAccessor] = field(default_factory=list) + synth_accessors: List[SynthUnderlyingAccessor] = field(default_factory=list) @property - def has_ipa_accessors(self) -> bool: - return bool(self.ipa_accessors) + def has_synth_accessors(self) -> bool: + return bool(self.synth_accessors) @dataclass @@ -245,8 +245,8 @@ class Synth: @dataclass class FinalClass(Class): is_final: ClassVar = True - is_derived_ipa: ClassVar = False - is_fresh_ipa: ClassVar = False + is_derived_synth: ClassVar = False + is_fresh_synth: ClassVar = False is_db: ClassVar = False params: List["Synth.Param"] = field(default_factory=list) @@ -256,37 +256,37 @@ class Synth: self.params[0].first = True @property - def is_ipa(self): - return self.is_fresh_ipa or self.is_derived_ipa + def is_synth(self): + return self.is_fresh_synth or self.is_derived_synth @property def has_params(self) -> bool: return bool(self.params) @dataclass - class FinalClassIpa(FinalClass): + class FinalClassSynth(FinalClass): pass @dataclass - class FinalClassDerivedIpa(FinalClassIpa): - is_derived_ipa: ClassVar = True + class FinalClassDerivedSynth(FinalClassSynth): + is_derived_synth: ClassVar = True @dataclass - class FinalClassFreshIpa(FinalClassIpa): - is_fresh_ipa: ClassVar = True + class FinalClassFreshSynth(FinalClassSynth): + is_fresh_synth: ClassVar = True @dataclass class FinalClassDb(FinalClass): is_db: ClassVar = True - subtracted_ipa_types: List["Synth.Class"] = field(default_factory=list) + subtracted_synth_types: List["Synth.Class"] = field(default_factory=list) def subtract_type(self, type: str): - self.subtracted_ipa_types.append(Synth.Class(type, first=not self.subtracted_ipa_types)) + self.subtracted_synth_types.append(Synth.Class(type, first=not self.subtracted_synth_types)) @property - def has_subtracted_ipa_types(self) -> bool: - return bool(self.subtracted_ipa_types) + def has_subtracted_synth_types(self) -> bool: + return bool(self.subtracted_synth_types) @property def db_id(self) -> str: @@ -304,7 +304,7 @@ class Synth: @dataclass class Types: - template: ClassVar = "ql_ipa_types" + template: ClassVar = "ql_synth_types" root: str import_prefix: str @@ -317,7 +317,7 @@ class Synth: @dataclass class ConstructorStub: - template: ClassVar = "ql_ipa_constructor_stub" + template: ClassVar = "ql_synth_constructor_stub" cls: "Synth.FinalClass" import_prefix: str diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py index 6c1869e92ce..bc1a90f9e25 100644 --- a/misc/codegen/lib/schema.py +++ b/misc/codegen/lib/schema.py @@ -75,7 +75,7 @@ RepeatedUnorderedProperty = functools.partial(Property, Property.Kind.REPEATED_U @dataclass -class IpaInfo: +class SynthInfo: from_class: Optional[str] = None on_arguments: Optional[Dict[str, str]] = None @@ -88,7 +88,7 @@ class Class: properties: List[Property] = field(default_factory=list) group: str = "" pragmas: List[str] = field(default_factory=list) - ipa: Optional[Union[IpaInfo, bool]] = None + synth: Optional[Union[SynthInfo, bool]] = None """^^^ filled with `True` for non-final classes with only synthesized final descendants """ doc: List[str] = field(default_factory=list) default_doc_name: Optional[str] = None @@ -105,10 +105,10 @@ class Class: _check_type(d, known) for p in self.properties: _check_type(p.type, known) - if self.ipa is not None: - _check_type(self.ipa.from_class, known) - if self.ipa.on_arguments is not None: - for t in self.ipa.on_arguments.values(): + if self.synth is not None: + _check_type(self.synth.from_class, known) + if self.synth.on_arguments is not None: + for t in self.synth.on_arguments.values(): _check_type(t, known) diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index b0d6e1c0f6b..61abbec75a5 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -160,7 +160,7 @@ def group(name: str = "") -> _ClassDecorator: return _annotate(group=name) -synth.from_class = lambda ref: _annotate(ipa=_schema.IpaInfo( +synth.from_class = lambda ref: _annotate(synth=_schema.SynthInfo( from_class=_schema.get_type_name(ref))) synth.on_arguments = lambda **kwargs: _annotate( - ipa=_schema.IpaInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()})) + synth=_schema.SynthInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()})) diff --git a/misc/codegen/loaders/schemaloader.py b/misc/codegen/loaders/schemaloader.py index 64f4d03cb57..c81c2061d91 100644 --- a/misc/codegen/loaders/schemaloader.py +++ b/misc/codegen/loaders/schemaloader.py @@ -40,7 +40,7 @@ def _get_class(cls: type) -> schema.Class: hideable=getattr(cls, "_hideable", False), # in the following we don't use `getattr` to avoid inheriting pragmas=cls.__dict__.get("_pragmas", []), - ipa=cls.__dict__.get("_ipa", None), + synth=cls.__dict__.get("_synth", None), properties=[ a | _PropertyNamer(n) for n, a in cls.__dict__.get("__annotations__", {}).items() @@ -65,34 +65,34 @@ def _toposort_classes_by_group(classes: typing.Dict[str, schema.Class]) -> typin return ret -def _fill_ipa_information(classes: typing.Dict[str, schema.Class]): - """ Take a dictionary where the `ipa` field is filled for all explicitly synthesized classes +def _fill_synth_information(classes: typing.Dict[str, schema.Class]): + """ Take a dictionary where the `synth` field is filled for all explicitly synthesized classes and update it so that all non-final classes that have only synthesized final descendants - get `True` as` value for the `ipa` field + get `True` as` value for the `synth` field """ if not classes: return - is_ipa: typing.Dict[str, bool] = {} + is_synth: typing.Dict[str, bool] = {} - def fill_is_ipa(name: str): - if name not in is_ipa: + def fill_is_synth(name: str): + if name not in is_synth: cls = classes[name] for d in cls.derived: - fill_is_ipa(d) - if cls.ipa is not None: - is_ipa[name] = True + fill_is_synth(d) + if cls.synth is not None: + is_synth[name] = True elif not cls.derived: - is_ipa[name] = False + is_synth[name] = False else: - is_ipa[name] = all(is_ipa[d] for d in cls.derived) + is_synth[name] = all(is_synth[d] for d in cls.derived) root = next(iter(classes)) - fill_is_ipa(root) + fill_is_synth(root) for name, cls in classes.items(): - if cls.ipa is None and is_ipa[name]: - cls.ipa = True + if cls.synth is None and is_synth[name]: + cls.synth = True def _fill_hideable_information(classes: typing.Dict[str, schema.Class]): @@ -134,7 +134,7 @@ def load(m: types.ModuleType) -> schema.Schema: null = name cls.is_null_class = True - _fill_ipa_information(classes) + _fill_synth_information(classes) _fill_hideable_information(classes) return schema.Schema(includes=includes, classes=_toposort_classes_by_group(classes), null=null) diff --git a/misc/codegen/templates/ql_stub.mustache b/misc/codegen/templates/ql_stub.mustache index 7e17efc6d46..b5b6a9d70cb 100644 --- a/misc/codegen/templates/ql_stub.mustache +++ b/misc/codegen/templates/ql_stub.mustache @@ -1,9 +1,9 @@ // generated by {{generator}}, remove this comment if you wish to edit this file private import {{base_import}} -{{#has_ipa_accessors}} +{{#has_synth_accessors}} private import {{import_prefix}}.Raw private import {{import_prefix}}.Synth -{{/has_ipa_accessors}} +{{/has_synth_accessors}} {{#ql_internal}} /** @@ -11,8 +11,8 @@ private import {{import_prefix}}.Synth */ {{/ql_internal}} class {{name}} extends Generated::{{name}} { - {{#ipa_accessors}} + {{#synth_accessors}} private cached {{type}} getUnderlying{{argument}}() { this = Synth::T{{name}}({{#constructorparams}}{{^first}},{{/first}}{{param}}{{/constructorparams}})} - {{/ipa_accessors}} + {{/synth_accessors}} } diff --git a/misc/codegen/templates/ql_ipa_constructor_stub.mustache b/misc/codegen/templates/ql_synth_constructor_stub.mustache similarity index 61% rename from misc/codegen/templates/ql_ipa_constructor_stub.mustache rename to misc/codegen/templates/ql_synth_constructor_stub.mustache index e5e525417d3..3425e8c618f 100644 --- a/misc/codegen/templates/ql_ipa_constructor_stub.mustache +++ b/misc/codegen/templates/ql_synth_constructor_stub.mustache @@ -2,15 +2,15 @@ private import {{import_prefix}}.Raw {{#cls}} {{#is_db}} -{{#has_subtracted_ipa_types}} +{{#has_subtracted_synth_types}} private import {{import_prefix}}.PureSynthConstructors -{{/has_subtracted_ipa_types}} +{{/has_subtracted_synth_types}} {{/is_db}} predicate construct{{name}}({{#params}}{{^first}}, {{/first}}{{type}} {{param}}{{/params}}) { {{#is_db}} - {{#subtracted_ipa_types}}{{^first}} and {{/first}}not construct{{name}}(id){{/subtracted_ipa_types}} - {{^subtracted_ipa_types}}any(){{/subtracted_ipa_types}} + {{#subtracted_synth_types}}{{^first}} and {{/first}}not construct{{name}}(id){{/subtracted_synth_types}} + {{^subtracted_synth_types}}any(){{/subtracted_synth_types}} {{/is_db}} {{^is_db}} none() diff --git a/misc/codegen/templates/ql_ipa_types.mustache b/misc/codegen/templates/ql_synth_types.mustache similarity index 91% rename from misc/codegen/templates/ql_ipa_types.mustache rename to misc/codegen/templates/ql_synth_types.mustache index d4244690930..a174d141a6b 100644 --- a/misc/codegen/templates/ql_ipa_types.mustache +++ b/misc/codegen/templates/ql_synth_types.mustache @@ -38,12 +38,12 @@ cached module Synth { * Converts a raw element to a synthesized `T{{name}}`, if possible. */ cached T{{name}} convert{{name}}FromRaw(Raw::Element e) { - {{^is_fresh_ipa}} + {{^is_fresh_synth}} result = T{{name}}(e) - {{/is_fresh_ipa}} - {{#is_fresh_ipa}} + {{/is_fresh_synth}} + {{#is_fresh_synth}} none() - {{/is_fresh_ipa}} + {{/is_fresh_synth}} } {{/final_classes}} @@ -68,12 +68,12 @@ cached module Synth { * Converts a synthesized `T{{name}}` to a raw DB element, if possible. */ cached Raw::Element convert{{name}}ToRaw(T{{name}} e) { - {{^is_fresh_ipa}} + {{^is_fresh_synth}} e = T{{name}}(result) - {{/is_fresh_ipa}} - {{#is_fresh_ipa}} + {{/is_fresh_synth}} + {{#is_fresh_synth}} none() - {{/is_fresh_ipa}} + {{/is_fresh_synth}} } {{/final_classes}} diff --git a/misc/codegen/test/test_cppgen.py b/misc/codegen/test/test_cppgen.py index ebb7b3887ef..fcd9b15e8d0 100644 --- a/misc/codegen/test/test_cppgen.py +++ b/misc/codegen/test/test_cppgen.py @@ -181,19 +181,19 @@ def test_cpp_skip_pragma(generate): ] -def test_ipa_classes_ignored(generate): +def test_synth_classes_ignored(generate): assert generate([ schema.Class( name="W", - ipa=schema.IpaInfo(), + synth=schema.SynthInfo(), ), schema.Class( name="X", - ipa=schema.IpaInfo(from_class="A"), + synth=schema.SynthInfo(from_class="A"), ), schema.Class( name="Y", - ipa=schema.IpaInfo(on_arguments={"a": "A", "b": "int"}), + synth=schema.SynthInfo(on_arguments={"a": "A", "b": "int"}), ), schema.Class( name="Z", diff --git a/misc/codegen/test/test_dbschemegen.py b/misc/codegen/test/test_dbschemegen.py index 45b5718a876..1fbbc046785 100644 --- a/misc/codegen/test/test_dbschemegen.py +++ b/misc/codegen/test/test_dbschemegen.py @@ -534,11 +534,11 @@ def test_null_class(generate): ) -def test_ipa_classes_ignored(generate): +def test_synth_classes_ignored(generate): assert generate([ - schema.Class(name="A", ipa=schema.IpaInfo()), - schema.Class(name="B", ipa=schema.IpaInfo(from_class="A")), - schema.Class(name="C", ipa=schema.IpaInfo(on_arguments={"x": "A"})), + schema.Class(name="A", synth=schema.SynthInfo()), + schema.Class(name="B", synth=schema.SynthInfo(from_class="A")), + schema.Class(name="C", synth=schema.SynthInfo(on_arguments={"x": "A"})), ]) == dbscheme.Scheme( src=schema_file.name, includes=[], @@ -546,10 +546,10 @@ def test_ipa_classes_ignored(generate): ) -def test_ipa_derived_classes_ignored(generate): +def test_synth_derived_classes_ignored(generate): assert generate([ schema.Class(name="A", derived={"B", "C"}), - schema.Class(name="B", bases=["A"], ipa=schema.IpaInfo()), + schema.Class(name="B", bases=["A"], synth=schema.SynthInfo()), schema.Class(name="C", bases=["A"]), ]) == dbscheme.Scheme( src=schema_file.name, diff --git a/misc/codegen/test/test_ql.py b/misc/codegen/test/test_ql.py index 6d1e2181194..35b3af77399 100644 --- a/misc/codegen/test/test_ql.py +++ b/misc/codegen/test/test_ql.py @@ -169,9 +169,9 @@ def test_class_without_description(): assert prop.has_description is False -def test_ipa_accessor_has_first_constructor_param_marked(): +def test_synth_accessor_has_first_constructor_param_marked(): params = ["a", "b", "c"] - x = ql.IpaUnderlyingAccessor("foo", "bar", params) + x = ql.SynthUnderlyingAccessor("foo", "bar", params) assert x.constructorparams[0].first assert [p.param for p in x.constructorparams] == params diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py index 12d5d28bca6..2a0fab2bbf2 100644 --- a/misc/codegen/test/test_qlgen.py +++ b/misc/codegen/test/test_qlgen.py @@ -848,13 +848,13 @@ def test_property_on_class_with_default_doc_name(generate_classes): } -def test_stub_on_class_with_ipa_from_class(generate_classes): +def test_stub_on_class_with_synth_from_class(generate_classes): assert generate_classes([ - schema.Class("MyObject", ipa=schema.IpaInfo(from_class="A"), + schema.Class("MyObject", synth=schema.SynthInfo(from_class="A"), properties=[schema.SingleProperty("foo", "bar")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", ipa_accessors=[ - ql.IpaUnderlyingAccessor(argument="Entity", type="Raw::A", constructorparams=["result"]), + "MyObject.qll": (a_ql_stub(name="MyObject", synth_accessors=[ + ql.SynthUnderlyingAccessor(argument="Entity", type="Raw::A", constructorparams=["result"]), ]), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_objects", synth=True, @@ -863,15 +863,15 @@ def test_stub_on_class_with_ipa_from_class(generate_classes): } -def test_stub_on_class_with_ipa_on_arguments(generate_classes): +def test_stub_on_class_with_synth_on_arguments(generate_classes): assert generate_classes([ - schema.Class("MyObject", ipa=schema.IpaInfo(on_arguments={"base": "A", "index": "int", "label": "string"}), + schema.Class("MyObject", synth=schema.SynthInfo(on_arguments={"base": "A", "index": "int", "label": "string"}), properties=[schema.SingleProperty("foo", "bar")]), ]) == { - "MyObject.qll": (a_ql_stub(name="MyObject", ipa_accessors=[ - ql.IpaUnderlyingAccessor(argument="Base", type="Raw::A", constructorparams=["result", "_", "_"]), - ql.IpaUnderlyingAccessor(argument="Index", type="int", constructorparams=["_", "result", "_"]), - ql.IpaUnderlyingAccessor(argument="Label", type="string", constructorparams=["_", "_", "result"]), + "MyObject.qll": (a_ql_stub(name="MyObject", synth_accessors=[ + ql.SynthUnderlyingAccessor(argument="Base", type="Raw::A", constructorparams=["result", "_", "_"]), + ql.SynthUnderlyingAccessor(argument="Index", type="int", constructorparams=["_", "result", "_"]), + ql.SynthUnderlyingAccessor(argument="Label", type="string", constructorparams=["_", "_", "result"]), ]), a_ql_class(name="MyObject", final=True, properties=[ ql.Property(singular="Foo", type="bar", tablename="my_objects", synth=True, diff --git a/misc/codegen/test/test_schemaloader.py b/misc/codegen/test/test_schemaloader.py index ed35f4b0271..d5772bea447 100644 --- a/misc/codegen/test/test_schemaloader.py +++ b/misc/codegen/test/test_schemaloader.py @@ -337,7 +337,7 @@ def test_class_with_pragmas(): } -def test_ipa_from_class(): +def test_synth_from_class(): @load class data: class A: @@ -348,12 +348,12 @@ def test_ipa_from_class(): pass assert data.classes == { - 'A': schema.Class('A', derived={'B'}, ipa=True), - 'B': schema.Class('B', bases=['A'], ipa=schema.IpaInfo(from_class="A")), + 'A': schema.Class('A', derived={'B'}, synth=True), + 'B': schema.Class('B', bases=['A'], synth=schema.SynthInfo(from_class="A")), } -def test_ipa_from_class_ref(): +def test_synth_from_class_ref(): @load class data: @defs.synth.from_class("B") @@ -364,12 +364,12 @@ def test_ipa_from_class_ref(): pass assert data.classes == { - 'A': schema.Class('A', derived={'B'}, ipa=schema.IpaInfo(from_class="B")), + 'A': schema.Class('A', derived={'B'}, synth=schema.SynthInfo(from_class="B")), 'B': schema.Class('B', bases=['A']), } -def test_ipa_from_class_dangling(): +def test_synth_from_class_dangling(): with pytest.raises(schema.Error): @load class data: @@ -378,7 +378,7 @@ def test_ipa_from_class_dangling(): pass -def test_ipa_class_on(): +def test_synth_class_on(): @load class data: class A: @@ -389,12 +389,12 @@ def test_ipa_class_on(): pass assert data.classes == { - 'A': schema.Class('A', derived={'B'}, ipa=True), - 'B': schema.Class('B', bases=['A'], ipa=schema.IpaInfo(on_arguments={'a': 'A', 'i': 'int'})), + 'A': schema.Class('A', derived={'B'}, synth=True), + 'B': schema.Class('B', bases=['A'], synth=schema.SynthInfo(on_arguments={'a': 'A', 'i': 'int'})), } -def test_ipa_class_on_ref(): +def test_synth_class_on_ref(): class A: pass @@ -408,12 +408,12 @@ def test_ipa_class_on_ref(): pass assert data.classes == { - 'A': schema.Class('A', derived={'B'}, ipa=schema.IpaInfo(on_arguments={'b': 'B', 'i': 'int'})), + 'A': schema.Class('A', derived={'B'}, synth=schema.SynthInfo(on_arguments={'b': 'B', 'i': 'int'})), 'B': schema.Class('B', bases=['A']), } -def test_ipa_class_on_dangling(): +def test_synth_class_on_dangling(): with pytest.raises(schema.Error): @load class data: @@ -422,7 +422,7 @@ def test_ipa_class_on_dangling(): pass -def test_ipa_class_hierarchy(): +def test_synth_class_hierarchy(): @load class data: class Root: @@ -447,10 +447,10 @@ def test_ipa_class_hierarchy(): assert data.classes == { 'Root': schema.Class('Root', derived={'Base', 'C'}), - 'Base': schema.Class('Base', bases=['Root'], derived={'Intermediate', 'B'}, ipa=True), - 'Intermediate': schema.Class('Intermediate', bases=['Base'], derived={'A'}, ipa=True), - 'A': schema.Class('A', bases=['Intermediate'], ipa=schema.IpaInfo(on_arguments={'a': 'Base', 'i': 'int'})), - 'B': schema.Class('B', bases=['Base'], ipa=schema.IpaInfo(from_class='Base')), + 'Base': schema.Class('Base', bases=['Root'], derived={'Intermediate', 'B'}, synth=True), + 'Intermediate': schema.Class('Intermediate', bases=['Base'], derived={'A'}, synth=True), + 'A': schema.Class('A', bases=['Intermediate'], synth=schema.SynthInfo(on_arguments={'a': 'Base', 'i': 'int'})), + 'B': schema.Class('B', bases=['Base'], synth=schema.SynthInfo(from_class='Base')), 'C': schema.Class('C', bases=['Root']), } From 27763d6bbed3823c91058f1bd82834b1fc3c1da6 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 7 Jun 2023 09:25:42 +0200 Subject: [PATCH 379/739] Improve ZipSlip exclusion to take varargs into account --- java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 8261aef9fb3..074153ffd8f 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -54,7 +54,10 @@ private class FileCreationSink extends DataFlow::Node { */ private predicate isPathCreation(DataFlow::Node sink) { exists(PathCreation pc | - pc.getAnInput() = sink.asExpr() and + pc.getAnInput() = sink.asExpr() + or + pc.getAnInput().(Argument).isVararg() and sink.(DataFlow::ImplicitVarargsArray).getCall() = pc + | // exclude actual read/write operations included in `PathCreation` not pc.(Call) .getCallee() From 0c8b4251cf6bc10e59977033d6252d95838e3b00 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 7 Jun 2023 10:07:01 +0200 Subject: [PATCH 380/739] Python: Avoid duplicated query-id --- .../ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql b/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql index 671bc0998fd..5a38a673080 100644 --- a/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql +++ b/python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql @@ -5,7 +5,7 @@ * @problem.severity error * @security-severity 9.3 * @precision high - * @id py/command-injection + * @id py/paramiko-command-injection * @tags security * experimental * external/cwe/cwe-074 From 416d3d587dd547270cb7fda929d1df9562bbf29e Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 7 Jun 2023 10:33:17 +0200 Subject: [PATCH 381/739] Accept test changes An uncovered test case is now correctly covered --- .../query-tests/security/CWE-552/UnsafeUrlForward.expected | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/ql/test/experimental/query-tests/security/CWE-552/UnsafeUrlForward.expected b/java/ql/test/experimental/query-tests/security/CWE-552/UnsafeUrlForward.expected index 11a8bc6c248..a39906b4115 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-552/UnsafeUrlForward.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-552/UnsafeUrlForward.expected @@ -3,6 +3,7 @@ edges | UnsafeLoadSpringResource.java:31:27:31:57 | new ClassPathResource(...) : ClassPathResource | UnsafeLoadSpringResource.java:35:31:35:33 | clr | | UnsafeLoadSpringResource.java:31:49:31:56 | fileName : String | UnsafeLoadSpringResource.java:31:27:31:57 | new ClassPathResource(...) : ClassPathResource | | UnsafeLoadSpringResource.java:68:32:68:77 | fileName : String | UnsafeLoadSpringResource.java:76:38:76:45 | fileName | +| UnsafeLoadSpringResource.java:108:32:108:77 | fileName : String | UnsafeLoadSpringResource.java:116:51:116:58 | fileName | | UnsafeRequestPath.java:20:17:20:63 | getServletPath(...) : String | UnsafeRequestPath.java:23:33:23:36 | path | | UnsafeResourceGet2.java:16:32:16:79 | getRequestParameterMap(...) : Map | UnsafeResourceGet2.java:17:20:17:25 | params : Map | | UnsafeResourceGet2.java:17:20:17:25 | params : Map | UnsafeResourceGet2.java:17:20:17:40 | get(...) : Object | @@ -35,6 +36,8 @@ nodes | UnsafeLoadSpringResource.java:35:31:35:33 | clr | semmle.label | clr | | UnsafeLoadSpringResource.java:68:32:68:77 | fileName : String | semmle.label | fileName : String | | UnsafeLoadSpringResource.java:76:38:76:45 | fileName | semmle.label | fileName | +| UnsafeLoadSpringResource.java:108:32:108:77 | fileName : String | semmle.label | fileName : String | +| UnsafeLoadSpringResource.java:116:51:116:58 | fileName | semmle.label | fileName | | UnsafeRequestPath.java:20:17:20:63 | getServletPath(...) : String | semmle.label | getServletPath(...) : String | | UnsafeRequestPath.java:23:33:23:36 | path | semmle.label | path | | UnsafeResourceGet2.java:16:32:16:79 | getRequestParameterMap(...) : Map | semmle.label | getRequestParameterMap(...) : Map | @@ -83,6 +86,7 @@ subpaths #select | UnsafeLoadSpringResource.java:35:31:35:33 | clr | UnsafeLoadSpringResource.java:27:32:27:77 | fileName : String | UnsafeLoadSpringResource.java:35:31:35:33 | clr | Potentially untrusted URL forward due to $@. | UnsafeLoadSpringResource.java:27:32:27:77 | fileName | user-provided value | | UnsafeLoadSpringResource.java:76:38:76:45 | fileName | UnsafeLoadSpringResource.java:68:32:68:77 | fileName : String | UnsafeLoadSpringResource.java:76:38:76:45 | fileName | Potentially untrusted URL forward due to $@. | UnsafeLoadSpringResource.java:68:32:68:77 | fileName | user-provided value | +| UnsafeLoadSpringResource.java:116:51:116:58 | fileName | UnsafeLoadSpringResource.java:108:32:108:77 | fileName : String | UnsafeLoadSpringResource.java:116:51:116:58 | fileName | Potentially untrusted URL forward due to $@. | UnsafeLoadSpringResource.java:108:32:108:77 | fileName | user-provided value | | UnsafeRequestPath.java:23:33:23:36 | path | UnsafeRequestPath.java:20:17:20:63 | getServletPath(...) : String | UnsafeRequestPath.java:23:33:23:36 | path | Potentially untrusted URL forward due to $@. | UnsafeRequestPath.java:20:17:20:63 | getServletPath(...) | user-provided value | | UnsafeResourceGet2.java:19:93:19:99 | loadUrl | UnsafeResourceGet2.java:16:32:16:79 | getRequestParameterMap(...) : Map | UnsafeResourceGet2.java:19:93:19:99 | loadUrl | Potentially untrusted URL forward due to $@. | UnsafeResourceGet2.java:16:32:16:79 | getRequestParameterMap(...) | user-provided value | | UnsafeResourceGet2.java:37:20:37:22 | url | UnsafeResourceGet2.java:32:32:32:79 | getRequestParameterMap(...) : Map | UnsafeResourceGet2.java:37:20:37:22 | url | Potentially untrusted URL forward due to $@. | UnsafeResourceGet2.java:32:32:32:79 | getRequestParameterMap(...) | user-provided value | From 0f75449abb71c17a60a96774d59f3509bb7e8b8c Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Wed, 7 Jun 2023 10:40:58 +0200 Subject: [PATCH 382/739] Improve code quality --- csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs index bae6a2b55ec..3729a5d2528 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs @@ -245,7 +245,7 @@ namespace Semmle.Extraction.CSharp.Entities // Retrieve the original method kind if (methodDecl.ExplicitInterfaceImplementations.IsEmpty) { - throw new InternalError(methodDecl, $"Couldn't get the original method kind for an explicit interface implementation"); + throw new InternalError(methodDecl, "Couldn't get the original method kind for an explicit interface implementation"); } methodKind = methodDecl.ExplicitInterfaceImplementations.Select(m => m.MethodKind).First(); From 76e1c6f76f0c1e1b23d7f24e0112e1ce07752e3f Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 7 Jun 2023 11:18:53 +0200 Subject: [PATCH 383/739] java: test type tracking through flow summaries --- .../dispatch/CallableViaSummary.java | 31 +++++++++++++++++++ .../dispatch/viaSummary.expected | 2 ++ .../test/library-tests/dispatch/viaSummary.ql | 9 ++++++ 3 files changed, 42 insertions(+) create mode 100644 java/ql/test/library-tests/dispatch/CallableViaSummary.java create mode 100644 java/ql/test/library-tests/dispatch/viaSummary.expected create mode 100644 java/ql/test/library-tests/dispatch/viaSummary.ql diff --git a/java/ql/test/library-tests/dispatch/CallableViaSummary.java b/java/ql/test/library-tests/dispatch/CallableViaSummary.java new file mode 100644 index 00000000000..da7c7d86efd --- /dev/null +++ b/java/ql/test/library-tests/dispatch/CallableViaSummary.java @@ -0,0 +1,31 @@ +import java.util.*; + +public class CallableViaSummary { + public interface Element { + public void handle(String message); + } + + public void main(String[] args) { + List<Element> elements = new ArrayList<>(); + + List<Element> elements2 = new ArrayList<>(); + + elements.add(new Element() { + @Override + public void handle(String message) { + System.out.println(message); + } + }); + + elements.add(message -> System.out.println(message)); + + // This dispatches to the two added elements because + // the summary of ArrayList causes flow via type tracking. + elements.get(0).handle("Hello, world!"); + + // This does not dispatch to anything, showing that the + // open-world assumption does not apply + // (and hence that type tracking is necessary above). + elements2.get(0).handle("Hello, world!"); + } +} \ No newline at end of file diff --git a/java/ql/test/library-tests/dispatch/viaSummary.expected b/java/ql/test/library-tests/dispatch/viaSummary.expected new file mode 100644 index 00000000000..7c311587d9a --- /dev/null +++ b/java/ql/test/library-tests/dispatch/viaSummary.expected @@ -0,0 +1,2 @@ +| CallableViaSummary.java:24:9:24:47 | handle(...) | CallableViaSummary.java:15:25:15:30 | handle | +| CallableViaSummary.java:24:9:24:47 | handle(...) | CallableViaSummary.java:20:22:20:59 | handle | diff --git a/java/ql/test/library-tests/dispatch/viaSummary.ql b/java/ql/test/library-tests/dispatch/viaSummary.ql new file mode 100644 index 00000000000..c421e1c9904 --- /dev/null +++ b/java/ql/test/library-tests/dispatch/viaSummary.ql @@ -0,0 +1,9 @@ +import java +import semmle.code.java.dispatch.VirtualDispatch + +from MethodAccess ma, Method m +where + m = viableImpl(ma) and + m.fromSource() and + ma.getFile().toString().matches("CallableViaSummary") +select ma, m From aec1e4a7131554595e7cbfc82647471ca8ef796a Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 7 Jun 2023 11:40:50 +0200 Subject: [PATCH 384/739] java: address ql alert --- java/ql/test/library-tests/dispatch/viaSummary.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/library-tests/dispatch/viaSummary.ql b/java/ql/test/library-tests/dispatch/viaSummary.ql index c421e1c9904..a7a88d0749d 100644 --- a/java/ql/test/library-tests/dispatch/viaSummary.ql +++ b/java/ql/test/library-tests/dispatch/viaSummary.ql @@ -5,5 +5,5 @@ from MethodAccess ma, Method m where m = viableImpl(ma) and m.fromSource() and - ma.getFile().toString().matches("CallableViaSummary") + ma.getFile().toString() = "CallableViaSummary" select ma, m From 5c9b0b9b76552929c283e539553dd75f38a053b8 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 7 Jun 2023 09:49:23 +0200 Subject: [PATCH 385/739] C#: Address review comments. --- .../integration-tests/posix-only/dotnet_test/test.py | 2 +- csharp/tools/tracing-config.lua | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/test.py b/csharp/ql/integration-tests/posix-only/dotnet_test/test.py index 1012454003b..f69d01b2188 100644 --- a/csharp/ql/integration-tests/posix-only/dotnet_test/test.py +++ b/csharp/ql/integration-tests/posix-only/dotnet_test/test.py @@ -7,4 +7,4 @@ check_diagnostics() # Explicitly build and then run tests. run_codeql_database_create(['dotnet clean', 'rm -rf test-db', 'dotnet build -o myout', 'dotnet test myout/dotnet_test.dll'], test_db="test2-db", lang="csharp") -check_diagnostics(test_db="test2-db") \ No newline at end of file +check_diagnostics(test_db="test2-db") diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index 7fa03af2de1..5ba1a078079 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -21,9 +21,9 @@ function RegisterExtractorPack(id) -- if that's `build`, we append `-p:UseSharedCompilation=false` to the command line, -- otherwise we do nothing. local match = false + local testMatch = false; local dotnetRunNeedsSeparator = false; local dotnetRunInjectionIndex = nil; - local libOrExe = false; local argv = compilerArguments.argv if OperatingSystem == 'windows' then -- let's hope that this split matches the escaping rules `dotnet` applies to command line arguments @@ -35,7 +35,7 @@ function RegisterExtractorPack(id) -- dotnet options start with either - or / (both are legal) local firstCharacter = string.sub(arg, 1, 1) if not (firstCharacter == '-') and not (firstCharacter == '/') then - if (not match) then + if (not match and not testMatch) then Log(1, 'Dotnet subcommand detected: %s', arg) end if arg == 'build' or arg == 'msbuild' or arg == 'publish' or arg == 'pack' then @@ -50,12 +50,12 @@ function RegisterExtractorPack(id) dotnetRunInjectionIndex = i + 1 end if arg == 'test' then - match = true + testMatch = true end -- for `dotnet test`, we should not append `-p:UseSharedCompilation=false` to the command line -- if a library or executable is being provided as an argument. - if arg:match('%.exe$') or arg:match('%.dll') then - libOrExe = true + if testMatch and (arg:match('%.exe$') or arg:match('%.dll')) then + testMatch = false end end -- if we see a separator to `dotnet run`, inject just prior to the existing separator @@ -71,7 +71,7 @@ function RegisterExtractorPack(id) dotnetRunInjectionIndex = i end end - if match and not libOrExe then + if match or testMatch then local injections = { '-p:UseSharedCompilation=false', '-p:EmitCompilerGeneratedFiles=true' } if dotnetRunNeedsSeparator then table.insert(injections, '--') From 3eb3178ba5d045a4b39e65a8f8948d2b10c01e62 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 7 Jun 2023 10:10:51 +0200 Subject: [PATCH 386/739] C#: Add change note. --- csharp/ql/lib/change-notes/2023-06-06-dotnettest.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2023-06-06-dotnettest.md diff --git a/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md b/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md new file mode 100644 index 00000000000..8e04877da1e --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* C#: Update the LUA tracer such that `-p:SharedCompilation=false` is not injected when `dotnet test` is applied to a `dll` or `exe` file. \ No newline at end of file From d4d571e43569d281b01bb797f871a952f9cbe984 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 7 Jun 2023 12:44:36 +0200 Subject: [PATCH 387/739] C#: Better change note. Co-authored-by: Michael B. Gale <mbg@github.com> --- csharp/ql/lib/change-notes/2023-06-06-dotnettest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md b/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md index 8e04877da1e..e7179b93189 100644 --- a/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md +++ b/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* C#: Update the LUA tracer such that `-p:SharedCompilation=false` is not injected when `dotnet test` is applied to a `dll` or `exe` file. \ No newline at end of file +* C#: Analysis of the `dotnet test` command supplied with a `dll` or `exe` file as argument no longer fails due to the addition of an erroneous `-p:SharedCompilation=false` argument. \ No newline at end of file From d6ac5cdc9446a48a0c53bbdc8c7c67b969b77b22 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Wed, 7 Jun 2023 12:39:00 +0100 Subject: [PATCH 388/739] Kotlin: Remove kotlin-explorer This was an exploration tool that I don't think has been used for some time. --- .github/labeler.yml | 3 +- CODEOWNERS | 1 - java/kotlin-explorer/.gitignore | 10 - java/kotlin-explorer/README | 9 - java/kotlin-explorer/build.gradle | 28 --- java/kotlin-explorer/gradle.properties | 7 - java/kotlin-explorer/settings.gradle | 8 - .../src/main/kotlin/Explorer.kt | 217 ------------------ 8 files changed, 1 insertion(+), 282 deletions(-) delete mode 100644 java/kotlin-explorer/.gitignore delete mode 100644 java/kotlin-explorer/README delete mode 100644 java/kotlin-explorer/build.gradle delete mode 100644 java/kotlin-explorer/gradle.properties delete mode 100644 java/kotlin-explorer/settings.gradle delete mode 100644 java/kotlin-explorer/src/main/kotlin/Explorer.kt diff --git a/.github/labeler.yml b/.github/labeler.yml index 503833fc4d7..5401e6afd71 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -11,7 +11,7 @@ Go: - change-notes/**/*go.* Java: - - any: [ 'java/**/*', '!java/kotlin-extractor/**/*', '!java/kotlin-explorer/**/*', '!java/ql/test/kotlin/**/*' ] + - any: [ 'java/**/*', '!java/kotlin-extractor/**/*', '!java/ql/test/kotlin/**/*' ] - change-notes/**/*java.* JS: @@ -20,7 +20,6 @@ JS: Kotlin: - java/kotlin-extractor/**/* - - java/kotlin-explorer/**/* - java/ql/test/kotlin/**/* Python: diff --git a/CODEOWNERS b/CODEOWNERS index 6e2dd9dc66b..b2eb53f0bb0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -8,7 +8,6 @@ /swift/ @github/codeql-swift /misc/codegen/ @github/codeql-swift /java/kotlin-extractor/ @github/codeql-kotlin -/java/kotlin-explorer/ @github/codeql-kotlin # ML-powered queries /javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers diff --git a/java/kotlin-explorer/.gitignore b/java/kotlin-explorer/.gitignore deleted file mode 100644 index 9c076360bbb..00000000000 --- a/java/kotlin-explorer/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.classpath -.gradle -.idea -.project -.settings -bin/ -build/ -gradle/ -gradlew -gradlew.bat diff --git a/java/kotlin-explorer/README b/java/kotlin-explorer/README deleted file mode 100644 index 0f500d7c25b..00000000000 --- a/java/kotlin-explorer/README +++ /dev/null @@ -1,9 +0,0 @@ - -This shows what is encoded in the kotlin.Metadata section shown in the -output of `javap -v SomeKotlinClass`. - -It is not currently able to extract the information from .class files -itself; the values are hard coded in src/main/kotlin/Explorer.kt - -Run `gradle run` in this directory to run it. - diff --git a/java/kotlin-explorer/build.gradle b/java/kotlin-explorer/build.gradle deleted file mode 100644 index b122d811d4f..00000000000 --- a/java/kotlin-explorer/build.gradle +++ /dev/null @@ -1,28 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version "${kotlinVersion}" - id 'org.jetbrains.dokka' version '1.4.32' - id "com.vanniktech.maven.publish" version '0.15.1' - id 'application' -} - -group 'com.github.codeql' -version '0.0.1' - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib" - implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.3.0" -} - -repositories { - mavenCentral() -} - -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { - kotlinOptions { - jvmTarget = "1.8" - } -} - -application { - mainClass = 'com.github.codeql.ExplorerKt' -} diff --git a/java/kotlin-explorer/gradle.properties b/java/kotlin-explorer/gradle.properties deleted file mode 100644 index 0854241bcda..00000000000 --- a/java/kotlin-explorer/gradle.properties +++ /dev/null @@ -1,7 +0,0 @@ -kotlin.code.style=official -kotlinVersion=1.5.21 - -GROUP=com.github.codeql -VERSION_NAME=0.0.1 -POM_DESCRIPTION=CodeQL Kotlin explorer - diff --git a/java/kotlin-explorer/settings.gradle b/java/kotlin-explorer/settings.gradle deleted file mode 100644 index 18f679f7b75..00000000000 --- a/java/kotlin-explorer/settings.gradle +++ /dev/null @@ -1,8 +0,0 @@ -pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal() - } -} - -rootProject.name = 'codeql-kotlin-explorer' diff --git a/java/kotlin-explorer/src/main/kotlin/Explorer.kt b/java/kotlin-explorer/src/main/kotlin/Explorer.kt deleted file mode 100644 index 31c3eb18dcb..00000000000 --- a/java/kotlin-explorer/src/main/kotlin/Explorer.kt +++ /dev/null @@ -1,217 +0,0 @@ -package com.github.codeql -import kotlinx.metadata.internal.metadata.jvm.deserialization.JvmMetadataVersion -import kotlinx.metadata.jvm.* -import kotlinx.metadata.* - -fun main(args : Array<String>) { - /* - Values from `javap -v` on TestKt.class from: - - class MyClass {} - - class MyParamClass<T> {} - - fun f(x: MyClass, y: MyClass?, - l1: MyParamClass<MyClass>, - l2: MyParamClass<MyClass?>, - l3: MyParamClass<MyClass>?, - l4: MyParamClass<MyClass?>?) { - } - */ - val kind = 2 - val metadataVersion = intArrayOf(1, 5, 1) - val data1 = arrayOf("\u0000\u0018\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\b\u0003\u001aX\u0010\u0000\u001a\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u00032\b\u0010\u0004\u001a\u0004\u0018\u00010\u00032\u000c\u0010\u0005\u001a\b\u0012\u0004\u0012\u00020\u00030\u00062\u000e\u0010\u0007\u001a\n\u0012\u0006\u0012\u0004\u0018\u00010\u00030\u00062\u000e\u0010\b\u001a\n\u0012\u0004\u0012\u00020\u0003\u0018\u00010\u00062\u0010\u0010\t\u001a\u000c\u0012\u0006\u0012\u0004\u0018\u00010\u0003\u0018\u00010\u0006") - val data2 = arrayOf("f","","x","LMyClass;","y","l1","LMyParamClass;","l2","l3","l4") - val extraString = null - val packageName = null - val extraInt = 48 - val kch = KotlinClassHeader(kind, metadataVersion, data1, data2, extraString, packageName, extraInt) - - val md = KotlinClassMetadata.read(kch) - when (md) { - is KotlinClassMetadata.Class -> println("Metadata for Class not yet supported") - is KotlinClassMetadata.FileFacade -> { - println("Metadata for FileFacade:") - val kmp = md.toKmPackage() - kmp.accept(MyPackageVisitor(0)) - } - is KotlinClassMetadata.SyntheticClass -> println("Metadata for SyntheticClass not yet supported") - is KotlinClassMetadata.MultiFileClassFacade -> println("Metadata for MultiFileClassFacade not yet supported") - is KotlinClassMetadata.MultiFileClassPart -> println("Metadata for MultiFileClassPart not yet supported") - is KotlinClassMetadata.Unknown -> println("Unknown kind") - else -> println("Unexpected kind") - } -} - -fun pr(indent: Int, s: String) { - println(" ".repeat(indent) + s) -} - -class MyPackageVisitor(val indent: Int): KmPackageVisitor() { - override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor? { - pr(indent, "=> Function; flags:$flags, name:$name") - return MyFunctionVisitor(indent + 1) - } - - override fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags): KmPropertyVisitor? { - pr(indent, "=> Properties not yet handled") - return null - } - - override fun visitTypeAlias(flags: Flags, name: String): KmTypeAliasVisitor? { - pr(indent, "=> Type aliases not yet handled") - return null - } - - override fun visitExtensions(type: KmExtensionType): KmPackageExtensionVisitor? { - pr(indent, "=> Package extensions; type:$type") - when (type) { - JvmPackageExtensionVisitor.TYPE -> return MyJvmPackageExtensionVisitor(indent + 1) - else -> { - pr(indent, "- Not yet handled") - return null - } - } - } -} - -class MyFunctionVisitor(val indent: Int): KmFunctionVisitor() { - override fun visitTypeParameter(flags: Flags, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? { - pr(indent, "=> Type parameter; flags:$flags, name:$name, id:$id, variance:$variance") - pr(indent, " -> Not yet handled") - return null - } - override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? { - pr(indent, "=> Receiver parameter type; flags:$flags") - pr(indent, " -> Not yet handled") - return null - } - - override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor? { - pr(indent, "=> Value parameter; flags:$flags, name:$name") - return MyValueParameterVisitor(indent + 1) - } - - override fun visitReturnType(flags: Flags): KmTypeVisitor? { - pr(indent, "=> Return type; flags:$flags") - return MyTypeVisitor(indent + 1) - } - - override fun visitVersionRequirement(): KmVersionRequirementVisitor? { - pr(indent, "=> VersionRequirement not yet handled") - return null - } - - override fun visitContract(): KmContractVisitor? { - pr(indent, "=> Contract not yet handled") - return null - } - - override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor? { - pr(indent, "=> Function extensions; type:$type") - when (type) { - JvmFunctionExtensionVisitor.TYPE -> return MyJvmFunctionExtensionVisitor(indent + 1) - else -> { - pr(indent, "- Not yet handled") - return null - } - } - } -} - -class MyValueParameterVisitor(val indent: Int): KmValueParameterVisitor() { - override fun visitType(flags: Flags): KmTypeVisitor? { - pr(indent, "=> Type; flags:$flags") - return MyTypeVisitor(indent + 1) - } - - override fun visitVarargElementType(flags: Flags): KmTypeVisitor? { - pr(indent, "=> VarargElementType not yet handled") - return null - } - - override fun visitExtensions(type: KmExtensionType): KmValueParameterExtensionVisitor? { - pr(indent, "=> Value parameter extensions; type:$type; not yet handled") - return null - } -} - -class MyTypeVisitor(val indent: Int): KmTypeVisitor() { - override fun visitClass(name: ClassName) { - pr(indent, "=> Class; name:$name") - } - - override fun visitTypeAlias(name: ClassName) { - pr(indent, "=> Type alias; name:$name") - } - - override fun visitTypeParameter(id: Int) { - pr(indent, "=> Type parameter; id:$id") - } - - override fun visitArgument(flags: Flags, variance: KmVariance): KmTypeVisitor? { - pr(indent, "=> Argument; flags:$flags, variance:$variance") - return MyTypeVisitor(indent + 1) - } - - override fun visitStarProjection() { - pr(indent, "=> Star projection") - } - - override fun visitAbbreviatedType(flags: Flags): KmTypeVisitor? { - pr(indent, "=> AbbreviatedType not yet handled") - return null - } - - override fun visitOuterType(flags: Flags): KmTypeVisitor? { - pr(indent, "=> OuterType not yet handled") - return null - } - - override fun visitFlexibleTypeUpperBound(flags: Flags, typeFlexibilityId: String?): KmTypeVisitor? { - pr(indent, "=> FlexibleTypeUpperBound not yet handled") - return null - } - - override fun visitExtensions(type: KmExtensionType): KmTypeExtensionVisitor? { - pr(indent, "=> Type extensions; type:$type") - when (type) { - JvmTypeExtensionVisitor.TYPE -> return MyJvmTypeExtensionVisitor(indent + 1) - else -> { - pr(indent, "- Not yet handled") - return null - } - } - } -} - -class MyJvmTypeExtensionVisitor(val indent: Int): JvmTypeExtensionVisitor() { - override fun visit(isRaw: Boolean) { - pr(indent, "=> isRaw:$isRaw") - } - - override fun visitAnnotation(annotation: KmAnnotation) { - pr(indent, "=> Annotation; annotation:$annotation") - } -} - -class MyJvmPackageExtensionVisitor(val indent: Int): JvmPackageExtensionVisitor() { - override fun visitLocalDelegatedProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags): KmPropertyVisitor? { - pr(indent, "=> Local delegate not yet handled") - return null - } - - override fun visitModuleName(name: String) { - pr(indent, "=> Module name; name:$name") - } -} - -class MyJvmFunctionExtensionVisitor(val indent: Int): JvmFunctionExtensionVisitor() { - override fun visit(signature: JvmMethodSignature?) { - pr(indent, "=> signature:$signature") - } - - override fun visitLambdaClassOriginName(internalName: String) { - pr(indent, "=> LambdaClassOriginName; internalName:$internalName") - } -} From 1bfbfec1bc2ec2d94ce0c9e9c2415f08f2d6289b Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 13:44:52 +0200 Subject: [PATCH 389/739] Java: use problem.severity in automodel extraction queries --- .../src/Telemetry/AutomodelApplicationModeExtractCandidates.ql | 2 +- .../AutomodelApplicationModeExtractNegativeExamples.ql | 2 +- .../AutomodelApplicationModeExtractPositiveExamples.ql | 2 +- .../ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql | 2 +- .../Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql | 2 +- .../Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql index 589a10ae663..997bc4d4a98 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql @@ -7,7 +7,7 @@ * @name Automodel candidates (application mode) * @description A query to extract automodel candidates in application mode. * @kind problem - * @severity info + * @problem.severity recommendation * @id java/ml/extract-automodel-application-candidates * @tags internal extract automodel application-mode candidates */ diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index 19beefad3d3..136dbcde11f 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -3,7 +3,7 @@ * * @name Negative examples (application mode) * @kind problem - * @severity info + * @problem.severity recommendation * @id java/ml/extract-automodel-application-negative-examples * @tags internal extract automodel application-mode negative examples */ diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql index 49be5c1d45f..ae11ffc93d4 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql @@ -3,7 +3,7 @@ * * @name Positive examples (application mode) * @kind problem - * @severity info + * @problem.severity recommendation * @id java/ml/extract-automodel-application-positive-examples * @tags internal extract automodel application-mode positive examples */ diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql index 391105b9d56..fa955c7de26 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql @@ -7,7 +7,7 @@ * @name Automodel candidates (framework mode) * @description A query to extract automodel candidates in framework mode. * @kind problem - * @severity info + * @problem.severity recommendation * @id java/ml/extract-automodel-framework-candidates * @tags internal extract automodel framework-mode candidates */ diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql index fb4bbc0e675..eabc40a82ba 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql @@ -3,7 +3,7 @@ * * @name Negative examples (framework mode) * @kind problem - * @severity info + * @problem.severity recommendation * @id java/ml/extract-automodel-framework-negative-examples * @tags internal extract automodel framework-mode negative examples */ diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql index 41cca592380..587d1ed2095 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql @@ -3,7 +3,7 @@ * * @name Positive examples (framework mode) * @kind problem - * @severity info + * @problem.severity recommendation * @id java/ml/extract-automodel-framework-positive-examples * @tags internal extract automodel framework-mode positive examples */ From 2e16b71215d8a886d8b4a41689bc58639518dcbe Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 13:52:57 +0200 Subject: [PATCH 390/739] Java: update qldoc of ClassQualifierCharacteristic --- .../Telemetry/AutomodelApplicationModeCharacteristics.qll | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index bf8a0ac1274..1da282f6f28 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -264,7 +264,10 @@ private class IsMaDTaintStepCharacteristic extends CharacteristicsImpl::NotASink /** * A negative characteristic that filters out qualifiers that are classes (i.e. static calls). These - *are unlikely to have any non-trivial flow going into them. + * are unlikely to have any non-trivial flow going into them. + * + * Technically, an accessed type _could_ come from outside of the source code, but there's not + * much likelihood of that being user-controlled. */ private class ClassQualifierCharacteristic extends CharacteristicsImpl::NotASinkCharacteristic { ClassQualifierCharacteristic() { this = "class qualifier" } From 7ab3cde3aac29624605a3727f17e8da641f2e86b Mon Sep 17 00:00:00 2001 From: yoff <lerchedahl@gmail.com> Date: Wed, 7 Jun 2023 13:54:31 +0200 Subject: [PATCH 391/739] Apply suggestions from code review Co-authored-by: Asger F <asgerf@github.com> --- ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll index 310dec3aadf..1968f6db4e8 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll @@ -1,10 +1,10 @@ /** - * Provides the implementation of a summary type tracker, that is type tracking through flow summaries. + * Provides the implementation of type tracking steps through flow summaries. * To use this, you must implement the `Input` signature. You can then use the predicates in the `Output` * signature to implement the predicates of the same names inside `TypeTrackerSpecific.qll`. */ -/** The classes and predicates needed to generate a summary type tracker. */ +/** The classes and predicates needed to generate type-tracking steps from summaries. */ signature module Input { // Dataflow nodes class Node; From be6b1d8aaf1888e31612b7a8c92fe8f43d48982d Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 13:58:56 +0200 Subject: [PATCH 392/739] Java: remove SkipFrameworkModeling characteristic in favour of later evaluation --- ...utomodelApplicationModeCharacteristics.qll | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 1da282f6f28..42d2d2bc802 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -294,32 +294,6 @@ private class ArgumentToLocalCall extends CharacteristicsImpl::UninterestingToMo } } -/** - * A characteristic that avoids modeling endpoint that are passed to frameworks - * in application mode. - * - * It's much more economical to use framework mode for those. - */ -private class SkipFrameworkModeling extends CharacteristicsImpl::UninterestingToModelCharacteristic { - SkipFrameworkModeling() { this = "skip modeling of large frameworks" } - - override predicate appliesToEndpoint(Endpoint e) { - ApplicationCandidatesImpl::getCallable(e) - .getDeclaringType() - .getPackage() - .getName() - .matches([ - "com.google%", // - "java.%", // - "javax.%", // - "org.apache%", // - "org.eclipse%", // - "org.gradle%", // - "org.slf4j%", // - ]) - } -} - /** * A Characteristic that marks endpoints as uninteresting to model, according to the Java ModelExclusions module. */ From 6ddf1f7eaf4eef6b36b63e6b0d93e7531603bf6c Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 7 Jun 2023 14:07:08 +0200 Subject: [PATCH 393/739] ruby/python: remove predicates from interface --- .../new/internal/SummaryTypeTracker.qll | 49 +++++++++++-------- .../new/internal/TypeTrackerSpecific.qll | 8 --- .../ruby/typetracking/SummaryTypeTracker.qll | 45 ++++++++++------- .../ruby/typetracking/TypeTrackerSpecific.qll | 15 ------ 4 files changed, 54 insertions(+), 63 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll index 310dec3aadf..4e0636826b8 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll @@ -1,10 +1,10 @@ /** - * Provides the implementation of a summary type tracker, that is type tracking through flow summaries. + * Provides the implementation of type tracking steps through flow summaries. * To use this, you must implement the `Input` signature. You can then use the predicates in the `Output` * signature to implement the predicates of the same names inside `TypeTrackerSpecific.qll`. */ -/** The classes and predicates needed to generate a summary type tracker. */ +/** The classes and predicates needed to generate type-tracking steps from summaries. */ signature module Input { // Dataflow nodes class Node; @@ -80,13 +80,6 @@ signature module Input { /** Gets a dataflow node respresenting the return of `callable` indicated by `return`. */ Node returnOf(Node callable, SummaryComponent return); - // Specific summary handling - /** Holds if component should be treated as a level step by type tracking. */ - predicate componentLevelStep(SummaryComponent component); - - /** Holds if the given component can't be evaluated by `evaluateSummaryComponentStackLocal`. */ - predicate isNonLocal(SummaryComponent component); - // Relating callables to nodes /** Gets a dataflow node respresenting a call to `callable`. */ Node callTo(SummarizedCallable callable); @@ -146,8 +139,8 @@ module SummaryFlow<Input I> implements Output<I> { I::SummaryComponentStack output ) { callable.propagatesFlow(I::push(I::content(contents), input), output, true) and - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) + not isNonLocal(input.head()) and + not isNonLocal(output.head()) } pragma[nomagic] @@ -155,8 +148,8 @@ module SummaryFlow<Input I> implements Output<I> { I::SummarizedCallable callable, I::TypeTrackerContent contents, I::SummaryComponentStack input, I::SummaryComponentStack output ) { - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) and + not isNonLocal(input.head()) and + not isNonLocal(output.head()) and ( callable.propagatesFlow(input, I::push(I::content(contents), output), true) or @@ -178,8 +171,8 @@ module SummaryFlow<Input I> implements Output<I> { callable .propagatesFlow(I::push(I::content(loadContents), input), I::push(I::content(storeContents), output), true) and - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) + not isNonLocal(input.head()) and + not isNonLocal(output.head()) } pragma[nomagic] @@ -190,8 +183,8 @@ module SummaryFlow<Input I> implements Output<I> { exists(I::TypeTrackerContent content | callable.propagatesFlow(I::push(I::withoutContent(content), input), output, true) and filter = I::getFilterFromWithoutContentStep(content) and - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) and + not isNonLocal(input.head()) and + not isNonLocal(output.head()) and input != output ) } @@ -204,12 +197,26 @@ module SummaryFlow<Input I> implements Output<I> { exists(I::TypeTrackerContent content | callable.propagatesFlow(I::push(I::withContent(content), input), output, true) and filter = I::getFilterFromWithContentStep(content) and - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) and + not isNonLocal(input.head()) and + not isNonLocal(output.head()) and input != output ) } + private predicate componentLevelStep(I::SummaryComponent component) { + exists(I::TypeTrackerContent content | + component = I::withoutContent(content) and + not exists(I::getFilterFromWithoutContentStep(content)) + ) + } + + pragma[nomagic] + private predicate isNonLocal(I::SummaryComponent component) { + component = I::content(_) + or + component = I::withContent(_) + } + /** * Gets a data flow I::Node corresponding an argument or return value of `call`, * as specified by `component`. @@ -255,7 +262,7 @@ module SummaryFlow<Input I> implements Output<I> { I::SummarizedCallable callable, I::SummaryComponent head, I::SummaryComponentStack tail ) { dependsOnSummaryComponentStackCons(callable, head, tail) and - not I::isNonLocal(head) + not isNonLocal(head) } pragma[nomagic] @@ -290,7 +297,7 @@ module SummaryFlow<Input I> implements Output<I> { or result = I::returnOf(prev, head) or - I::componentLevelStep(head) and + componentLevelStep(head) and result = prev ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index 81e673dc30b..f3f9b1b52b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -255,14 +255,6 @@ module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { callable.getALocalSource().asExpr().(CallableExpr).getInnerScope().getAReturnValueFlowNode() } - // Specific summary handling - predicate componentLevelStep(SummaryComponent component) { none() } - - pragma[nomagic] - predicate isNonLocal(SummaryComponent component) { - component = FlowSummary::SummaryComponent::content(_) - } - // Relating callables to nodes Node callTo(SummarizedCallable callable) { result = callable.getACallSimple() } } diff --git a/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll index 1968f6db4e8..4e0636826b8 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll @@ -80,13 +80,6 @@ signature module Input { /** Gets a dataflow node respresenting the return of `callable` indicated by `return`. */ Node returnOf(Node callable, SummaryComponent return); - // Specific summary handling - /** Holds if component should be treated as a level step by type tracking. */ - predicate componentLevelStep(SummaryComponent component); - - /** Holds if the given component can't be evaluated by `evaluateSummaryComponentStackLocal`. */ - predicate isNonLocal(SummaryComponent component); - // Relating callables to nodes /** Gets a dataflow node respresenting a call to `callable`. */ Node callTo(SummarizedCallable callable); @@ -146,8 +139,8 @@ module SummaryFlow<Input I> implements Output<I> { I::SummaryComponentStack output ) { callable.propagatesFlow(I::push(I::content(contents), input), output, true) and - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) + not isNonLocal(input.head()) and + not isNonLocal(output.head()) } pragma[nomagic] @@ -155,8 +148,8 @@ module SummaryFlow<Input I> implements Output<I> { I::SummarizedCallable callable, I::TypeTrackerContent contents, I::SummaryComponentStack input, I::SummaryComponentStack output ) { - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) and + not isNonLocal(input.head()) and + not isNonLocal(output.head()) and ( callable.propagatesFlow(input, I::push(I::content(contents), output), true) or @@ -178,8 +171,8 @@ module SummaryFlow<Input I> implements Output<I> { callable .propagatesFlow(I::push(I::content(loadContents), input), I::push(I::content(storeContents), output), true) and - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) + not isNonLocal(input.head()) and + not isNonLocal(output.head()) } pragma[nomagic] @@ -190,8 +183,8 @@ module SummaryFlow<Input I> implements Output<I> { exists(I::TypeTrackerContent content | callable.propagatesFlow(I::push(I::withoutContent(content), input), output, true) and filter = I::getFilterFromWithoutContentStep(content) and - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) and + not isNonLocal(input.head()) and + not isNonLocal(output.head()) and input != output ) } @@ -204,12 +197,26 @@ module SummaryFlow<Input I> implements Output<I> { exists(I::TypeTrackerContent content | callable.propagatesFlow(I::push(I::withContent(content), input), output, true) and filter = I::getFilterFromWithContentStep(content) and - not I::isNonLocal(input.head()) and - not I::isNonLocal(output.head()) and + not isNonLocal(input.head()) and + not isNonLocal(output.head()) and input != output ) } + private predicate componentLevelStep(I::SummaryComponent component) { + exists(I::TypeTrackerContent content | + component = I::withoutContent(content) and + not exists(I::getFilterFromWithoutContentStep(content)) + ) + } + + pragma[nomagic] + private predicate isNonLocal(I::SummaryComponent component) { + component = I::content(_) + or + component = I::withContent(_) + } + /** * Gets a data flow I::Node corresponding an argument or return value of `call`, * as specified by `component`. @@ -255,7 +262,7 @@ module SummaryFlow<Input I> implements Output<I> { I::SummarizedCallable callable, I::SummaryComponent head, I::SummaryComponentStack tail ) { dependsOnSummaryComponentStackCons(callable, head, tail) and - not I::isNonLocal(head) + not isNonLocal(head) } pragma[nomagic] @@ -290,7 +297,7 @@ module SummaryFlow<Input I> implements Output<I> { or result = I::returnOf(prev, head) or - I::componentLevelStep(head) and + componentLevelStep(head) and result = prev ) } diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll index 4f17302e72b..4283521afc5 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll @@ -467,21 +467,6 @@ module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { ) } - // Specific summary handling - predicate componentLevelStep(SummaryComponent component) { - exists(TypeTrackerContent content | - component = SummaryComponent::withoutContent(content) and - not exists(getFilterFromWithoutContentStep(content)) - ) - } - - pragma[nomagic] - predicate isNonLocal(SummaryComponent component) { - component = SC::content(_) - or - component = SC::withContent(_) - } - // Relating callables to nodes Node callTo(SummarizedCallable callable) { result.asExpr().getExpr() = callable.getACallSimple() } } From 92ad02a752ea645948ccce00cc393e7b0668d6cc Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 14:09:07 +0200 Subject: [PATCH 394/739] Java: update getRelatedLocation qldoc --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 42d2d2bc802..51c3cf57a60 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -103,7 +103,8 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig /** * Returns the related location for the given endpoint. * - * Related locations can be JavaDoc comments of the class or the method. + * The only related location we model is the the call expression surrounding to + * which the endpoint is either argument or qualifier (known as the call context). */ RelatedLocation getRelatedLocation(Endpoint e, RelatedLocationType type) { type = CallContext() and From 35b4c438ff09bd431858bc166121007bae933cca Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 7 Jun 2023 14:12:20 +0200 Subject: [PATCH 395/739] Fix Gson's JsonArray.add models When the type of the argument isn't JsonElement, the summary must be taint flow instead of value flow --- java/ql/lib/ext/com.google.gson.model.yml | 7 +++++- .../library-tests/frameworks/gson/Test.java | 24 +++++++++---------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/java/ql/lib/ext/com.google.gson.model.yml b/java/ql/lib/ext/com.google.gson.model.yml index 96f5355b2dc..73e14cf7cc8 100644 --- a/java/ql/lib/ext/com.google.gson.model.yml +++ b/java/ql/lib/ext/com.google.gson.model.yml @@ -26,7 +26,12 @@ extensions: - ["com.google.gson", "JsonElement", True, "getAsJsonPrimitive", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["com.google.gson", "JsonElement", True, "getAsString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["com.google.gson", "JsonElement", True, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["com.google.gson", "JsonArray", True, "add", "", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["com.google.gson", "JsonArray", True, "add", "(Boolean)", "", "Argument[0]", "Argument[this].Element", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "add", "(Character)", "", "Argument[0]", "Argument[this].Element", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "add", "(JsonElement)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["com.google.gson", "JsonArray", True, "add", "(Number)", "", "Argument[0]", "Argument[this].Element", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "add", "(String)", "", "Argument[0]", "Argument[this].Element", "taint", "manual"] + - ["com.google.gson", "JsonArray", True, "add", "(JsonArray)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["com.google.gson", "JsonArray", True, "asList", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["com.google.gson", "JsonArray", True, "get", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["com.google.gson", "JsonArray", True, "set", "", "", "Argument[1]", "Argument[this].Element", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/gson/Test.java b/java/ql/test/library-tests/frameworks/gson/Test.java index eb3e1e526f0..00811587e8b 100644 --- a/java/ql/test/library-tests/frameworks/gson/Test.java +++ b/java/ql/test/library-tests/frameworks/gson/Test.java @@ -25,7 +25,7 @@ public class Test { <K> K getMapKeyDefault(Map.Entry<K,?> container) { return container.getKey(); } JsonElement getMapValueDefault(JsonObject container) { return container.get(null); } <V> V getMapValueDefault(Map.Entry<?,V> container) { return container.getValue(); } - JsonArray newWithElementDefault(String element) { JsonArray a = new JsonArray(); a.add(element); return a; } + JsonArray newWithElementDefault(JsonElement element) { JsonArray a = new JsonArray(); a.add(element); return a; } JsonObject newWithMapKeyDefault(String key) { JsonObject o = new JsonObject(); o.add(key, (JsonElement) null); return o; } JsonObject newWithMapValueDefault(JsonElement element) { JsonObject o = new JsonObject(); o.add(null, element); return o; } Object source() { return null; } @@ -232,51 +232,51 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + // "com.google.gson;JsonArray;true;add;(Boolean);;Argument[0];Argument[this].Element;taint;manual" JsonArray out = null; Boolean in = (Boolean)source(); out.add(in); - sink(getElement(out)); // $ hasValueFlow + sink(getElement(out)); // $ hasTaintFlow } { - // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + // "com.google.gson;JsonArray;true;add;(Character);;Argument[0];Argument[this].Element;taint;manual" JsonArray out = null; Character in = (Character)source(); out.add(in); - sink(getElement(out)); // $ hasValueFlow + sink(getElement(out)); // $ hasTaintFlow } { - // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + // "com.google.gson;JsonArray;true;add;(JsonElement);;Argument[0];Argument[this].Element;value;manual" JsonArray out = null; JsonElement in = (JsonElement)source(); out.add(in); sink(getElement(out)); // $ hasValueFlow } { - // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + // "com.google.gson;JsonArray;true;add;(Number);;Argument[0];Argument[this].Element;taint;manual" JsonArray out = null; Number in = (Number)source(); out.add(in); - sink(getElement(out)); // $ hasValueFlow + sink(getElement(out)); // $ hasTaintFlow } { - // "com.google.gson;JsonArray;true;add;;;Argument[0];Argument[this].Element;value;manual" + // "com.google.gson;JsonArray;true;add;(JsonArray);;Argument[0].Element;Argument[this].Element;value;manual" JsonArray out = null; - String in = (String)source(); + JsonElement in = (JsonElement)source(); out.add(in); sink(getElement(out)); // $ hasValueFlow } { // "com.google.gson;JsonArray;true;asList;;;Argument[this].Element;ReturnValue.Element;value;manual" List out = null; - JsonArray in = (JsonArray)newWithElementDefault((String) source()); + JsonArray in = (JsonArray)newWithElementDefault((JsonElement) source()); out = in.asList(); sink(getElement(out)); // $ hasValueFlow } { // "com.google.gson;JsonArray;true;get;;;Argument[this].Element;ReturnValue;value;manual" JsonElement out = null; - JsonArray in = (JsonArray)newWithElementDefault((String) source()); + JsonArray in = (JsonArray)newWithElementDefault((JsonElement) source()); out = in.get(0); sink(out); // $ hasValueFlow } From a8799fe98103ea88c5e07888a15a8004736eeb87 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 14:38:52 +0200 Subject: [PATCH 396/739] Java: share getCallable interface between automodel extraction modes --- ...utomodelApplicationModeCharacteristics.qll | 31 ++++++++++++------- .../AutomodelFrameworkModeCharacteristics.qll | 29 +++++++++++------ .../Telemetry/AutomodelSharedGetCallable.qll | 21 +++++++++++++ 3 files changed, 59 insertions(+), 22 deletions(-) create mode 100644 java/ql/src/Telemetry/AutomodelSharedGetCallable.qll diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 51c3cf57a60..94140b7ed09 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -16,6 +16,7 @@ private import semmle.code.java.security.RequestForgery private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions private import AutomodelSharedUtil as AutomodelSharedUtil private import semmle.code.java.security.PathSanitizer as PathSanitizer +private import AutomodelSharedGetCallable as AutomodelSharedGetCallable import AutomodelSharedCharacteristics as SharedCharacteristics import AutomodelEndpointTypes as AutomodelEndpointTypes @@ -85,8 +86,8 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig additional predicate sinkSpec( Endpoint e, string package, string type, string name, string signature, string ext, string input ) { - ApplicationCandidatesImpl::getCallable(e).hasQualifiedName(package, type, name) and - signature = ExternalFlow::paramsString(getCallable(e)) and + ApplicationModeGetCallable::getCallable(e).hasQualifiedName(package, type, name) and + signature = ExternalFlow::paramsString(ApplicationModeGetCallable::getCallable(e)) and ext = "" and ( exists(Call c, int argIdx | @@ -110,13 +111,19 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig type = CallContext() and result = any(Call c | e.asExpr() = [c.getAnArgument(), c.getQualifier()]) } +} + +private class JavaCallable = Callable; + +private module ApplicationModeGetCallable implements AutomodelSharedGetCallable::GetCallableSig { + class Callable = JavaCallable; + + class Endpoint = ApplicationCandidatesImpl::Endpoint; /** * Returns the API callable being modeled. - * - * Each Java mode should implement this predicate. */ - additional Callable getCallable(Endpoint e) { + Callable getCallable(Endpoint e) { exists(Call c | e.asExpr() = [c.getAnArgument(), c.getQualifier()] and result = c.getCallee() @@ -209,8 +216,8 @@ private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASin override predicate appliesToEndpoint(Endpoint e) { not ApplicationCandidatesImpl::isSink(e, _) and - ApplicationCandidatesImpl::getCallable(e).getName().matches("is%") and - ApplicationCandidatesImpl::getCallable(e).getReturnType() instanceof BooleanType + ApplicationModeGetCallable::getCallable(e).getName().matches("is%") and + ApplicationModeGetCallable::getCallable(e).getReturnType() instanceof BooleanType } } @@ -228,7 +235,7 @@ private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::Not override predicate appliesToEndpoint(Endpoint e) { not ApplicationCandidatesImpl::isSink(e, _) and exists(Callable callable | - callable = ApplicationCandidatesImpl::getCallable(e) and + callable = ApplicationModeGetCallable::getCallable(e) and callable.getName().toLowerCase() = ["exists", "notexists"] and callable.getReturnType() instanceof BooleanType ) @@ -242,7 +249,7 @@ private class ExceptionCharacteristic extends CharacteristicsImpl::NotASinkChara ExceptionCharacteristic() { this = "exception" } override predicate appliesToEndpoint(Endpoint e) { - ApplicationCandidatesImpl::getCallable(e).getDeclaringType().getASupertype*() instanceof + ApplicationModeGetCallable::getCallable(e).getDeclaringType().getASupertype*() instanceof TypeThrowable } } @@ -291,7 +298,7 @@ private class ArgumentToLocalCall extends CharacteristicsImpl::UninterestingToMo ArgumentToLocalCall() { this = "argument to local call" } override predicate appliesToEndpoint(Endpoint e) { - ApplicationCandidatesImpl::getCallable(e).fromSource() + ApplicationModeGetCallable::getCallable(e).fromSource() } } @@ -302,7 +309,7 @@ private class ExcludedFromModeling extends CharacteristicsImpl::UninterestingToM ExcludedFromModeling() { this = "excluded from modeling" } override predicate appliesToEndpoint(Endpoint e) { - ModelExclusions::isUninterestingForModels(ApplicationCandidatesImpl::getCallable(e)) or + ModelExclusions::isUninterestingForModels(ApplicationModeGetCallable::getCallable(e)) or ModelExclusions::isUninterestingForModels(e.getEnclosingCallable()) } } @@ -316,7 +323,7 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter NonPublicMethodCharacteristic() { this = "non-public method" } override predicate appliesToEndpoint(Endpoint e) { - not ApplicationCandidatesImpl::getCallable(e).isPublic() + not ApplicationModeGetCallable::getCallable(e).isPublic() } } diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index 1a94d1a6338..d700dc22db1 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -15,6 +15,7 @@ private import semmle.code.java.security.QueryInjection private import semmle.code.java.security.RequestForgery private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions private import AutomodelSharedUtil as AutomodelSharedUtil +private import AutomodelSharedGetCallable as AutomodelSharedGetCallable import AutomodelSharedCharacteristics as SharedCharacteristics import AutomodelEndpointTypes as AutomodelEndpointTypes @@ -66,8 +67,8 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { additional predicate sinkSpec( Endpoint e, string package, string type, string name, string signature, string ext, string input ) { - FrameworkCandidatesImpl::getCallable(e).hasQualifiedName(package, type, name) and - signature = ExternalFlow::paramsString(getCallable(e)) and + FrameworkModeGetCallable::getCallable(e).hasQualifiedName(package, type, name) and + signature = ExternalFlow::paramsString(FrameworkModeGetCallable::getCallable(e)) and ext = "" and exists(int paramIdx | e.isParameterOf(_, paramIdx) | input = AutomodelSharedUtil::getArgumentForIndex(paramIdx) @@ -81,18 +82,26 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { */ RelatedLocation getRelatedLocation(Endpoint e, RelatedLocationType type) { type = MethodDoc() and - result = FrameworkCandidatesImpl::getCallable(e).(Documentable).getJavadoc() + result = FrameworkModeGetCallable::getCallable(e).(Documentable).getJavadoc() or type = ClassDoc() and - result = FrameworkCandidatesImpl::getCallable(e).getDeclaringType().(Documentable).getJavadoc() + result = FrameworkModeGetCallable::getCallable(e).getDeclaringType().(Documentable).getJavadoc() } +} + +private class JavaCallable = Callable; + +private module FrameworkModeGetCallable implements AutomodelSharedGetCallable::GetCallableSig { + class Callable = JavaCallable; + + class Endpoint = FrameworkCandidatesImpl::Endpoint; /** * Returns the callable that contains the given endpoint. * * Each Java mode should implement this predicate. */ - additional Callable getCallable(Endpoint e) { result = e.getEnclosingCallable() } + Callable getCallable(Endpoint e) { result = e.getEnclosingCallable() } } module CharacteristicsImpl = SharedCharacteristics::SharedCharacteristics<FrameworkCandidatesImpl>; @@ -163,8 +172,8 @@ private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASin override predicate appliesToEndpoint(Endpoint e) { not FrameworkCandidatesImpl::isSink(e, _) and - FrameworkCandidatesImpl::getCallable(e).getName().matches("is%") and - FrameworkCandidatesImpl::getCallable(e).getReturnType() instanceof BooleanType + FrameworkModeGetCallable::getCallable(e).getName().matches("is%") and + FrameworkModeGetCallable::getCallable(e).getReturnType() instanceof BooleanType } } @@ -182,7 +191,7 @@ private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::Not override predicate appliesToEndpoint(Endpoint e) { not FrameworkCandidatesImpl::isSink(e, _) and exists(Callable callable | - callable = FrameworkCandidatesImpl::getCallable(e) and + callable = FrameworkModeGetCallable::getCallable(e) and callable.getName().toLowerCase() = ["exists", "notexists"] and callable.getReturnType() instanceof BooleanType ) @@ -196,7 +205,7 @@ private class ExceptionCharacteristic extends CharacteristicsImpl::NotASinkChara ExceptionCharacteristic() { this = "exception" } override predicate appliesToEndpoint(Endpoint e) { - FrameworkCandidatesImpl::getCallable(e).getDeclaringType().getASupertype*() instanceof + FrameworkModeGetCallable::getCallable(e).getDeclaringType().getASupertype*() instanceof TypeThrowable } } @@ -222,7 +231,7 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter NonPublicMethodCharacteristic() { this = "non-public method" } override predicate appliesToEndpoint(Endpoint e) { - not FrameworkCandidatesImpl::getCallable(e).isPublic() + not FrameworkModeGetCallable::getCallable(e).isPublic() } } diff --git a/java/ql/src/Telemetry/AutomodelSharedGetCallable.qll b/java/ql/src/Telemetry/AutomodelSharedGetCallable.qll new file mode 100644 index 00000000000..87e20969381 --- /dev/null +++ b/java/ql/src/Telemetry/AutomodelSharedGetCallable.qll @@ -0,0 +1,21 @@ +/** + * An automodel extraction mode instantiates this interface to define how to access + * the callable that's associated with an endpoint. + */ +signature module GetCallableSig { + /** + * A callable is the definition of a method, function, etc. - something that can be called. + */ + class Callable; + + /** + * An endpoint is a potential candidate for modeling. This will typically be bound to the language's + * DataFlow node class, or a subtype thereof. + */ + class Endpoint; + + /** + * Gets the callable that's associated with the given endpoint. + */ + Callable getCallable(Endpoint endpoint); +} From 7e77e2ea82165754076608317cc2f30f5a17a9e2 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 14:42:20 +0200 Subject: [PATCH 397/739] Java: comment why we're using erased types in MaD --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 94140b7ed09..a2ad6bfe31d 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -190,6 +190,8 @@ class ApplicationModeMetadataExtractor extends string { ) and input = AutomodelSharedUtil::getArgumentForIndex(argIdx) and package = callable.getDeclaringType().getPackage().getName() and + // we're using the erased types because the MaD convention is to not specify type parameters. + // Whether something is or isn't a sink doesn't usually depend on the type parameters. type = callable.getDeclaringType().getErasure().(RefType).nestedName() and subtypes = this.considerSubtypes(callable).toString() and name = callable.getName() and From f9c890be3548a0e4eb25b75fa5aedbf2b00a9c54 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 7 Jun 2023 14:49:04 +0200 Subject: [PATCH 398/739] C#: Address review comments. --- csharp/tools/tracing-config.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index 5ba1a078079..49044226da3 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -21,7 +21,6 @@ function RegisterExtractorPack(id) -- if that's `build`, we append `-p:UseSharedCompilation=false` to the command line, -- otherwise we do nothing. local match = false - local testMatch = false; local dotnetRunNeedsSeparator = false; local dotnetRunInjectionIndex = nil; local argv = compilerArguments.argv @@ -35,7 +34,7 @@ function RegisterExtractorPack(id) -- dotnet options start with either - or / (both are legal) local firstCharacter = string.sub(arg, 1, 1) if not (firstCharacter == '-') and not (firstCharacter == '/') then - if (not match and not testMatch) then + if (not match) then Log(1, 'Dotnet subcommand detected: %s', arg) end if arg == 'build' or arg == 'msbuild' or arg == 'publish' or arg == 'pack' then @@ -50,12 +49,13 @@ function RegisterExtractorPack(id) dotnetRunInjectionIndex = i + 1 end if arg == 'test' then - testMatch = true + match = true end - -- for `dotnet test`, we should not append `-p:UseSharedCompilation=false` to the command line + -- for `dotnet [test|run]`, we should not append `-p:UseSharedCompilation=false` to the command line -- if a library or executable is being provided as an argument. - if testMatch and (arg:match('%.exe$') or arg:match('%.dll')) then - testMatch = false + if arg:match('%.exe$') or arg:match('%.dll') then + match = false + break end end -- if we see a separator to `dotnet run`, inject just prior to the existing separator @@ -71,7 +71,7 @@ function RegisterExtractorPack(id) dotnetRunInjectionIndex = i end end - if match or testMatch then + if match then local injections = { '-p:UseSharedCompilation=false', '-p:EmitCompilerGeneratedFiles=true' } if dotnetRunNeedsSeparator then table.insert(injections, '--') From 715b1351f368087d4634c699a4003f7540afb4b2 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 14:55:00 +0200 Subject: [PATCH 399/739] Java: share considerSubtypes predicate between Java modes --- ...utomodelApplicationModeCharacteristics.qll | 29 ++++--------------- ...lApplicationModeExtractNegativeExamples.ql | 2 +- ...lApplicationModeExtractPositiveExamples.ql | 2 +- .../AutomodelFrameworkModeCharacteristics.qll | 27 ++++------------- ...AutomodelFrameworkModeExtractCandidates.ql | 2 +- ...delFrameworkModeExtractNegativeExamples.ql | 2 +- ...delFrameworkModeExtractPositiveExamples.ql | 2 +- ...elSharedUtil.qll => AutomodelJavaUtil.qll} | 18 ++++++++++++ 8 files changed, 34 insertions(+), 50 deletions(-) rename java/ql/src/Telemetry/{AutomodelSharedUtil.qll => AutomodelJavaUtil.qll} (80%) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index a2ad6bfe31d..5e04e334fb9 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -14,7 +14,7 @@ private import semmle.code.java.Expr as Expr private import semmle.code.java.security.QueryInjection private import semmle.code.java.security.RequestForgery private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions -private import AutomodelSharedUtil as AutomodelSharedUtil +private import AutomodelJavaUtil as AutomodelJavaUtil private import semmle.code.java.security.PathSanitizer as PathSanitizer private import AutomodelSharedGetCallable as AutomodelSharedGetCallable import AutomodelSharedCharacteristics as SharedCharacteristics @@ -65,7 +65,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig RelatedLocation asLocation(Endpoint e) { result = e.asExpr() } - predicate isKnownKind = AutomodelSharedUtil::isKnownKind/3; + predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3; predicate isSink(Endpoint e, string kind) { exists(string package, string type, string name, string signature, string ext, string input | @@ -92,11 +92,11 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig ( exists(Call c, int argIdx | e.asExpr() = c.getArgument(argIdx) and - input = AutomodelSharedUtil::getArgumentForIndex(argIdx) + input = AutomodelJavaUtil::getArgumentForIndex(argIdx) ) or exists(Call c | - e.asExpr() = c.getQualifier() and input = AutomodelSharedUtil::getArgumentForIndex(-1) + e.asExpr() = c.getQualifier() and input = AutomodelJavaUtil::getArgumentForIndex(-1) ) ) } @@ -160,23 +160,6 @@ class Endpoint = ApplicationCandidatesImpl::Endpoint; class ApplicationModeMetadataExtractor extends string { ApplicationModeMetadataExtractor() { this = "ApplicationModeMetadataExtractor" } - /** - * By convention, the subtypes property of the MaD declaration should only be - * true when there _can_ exist any subtypes with a different implementation. - * - * It would technically be ok to always use the value 'true', but this would - * break convention. - */ - boolean considerSubtypes(Callable callable) { - if - callable.isStatic() or - callable.getDeclaringType().isStatic() or - callable.isFinal() or - callable.getDeclaringType().isFinal() - then result = false - else result = true - } - predicate hasMetadata( Endpoint e, string package, string type, string subtypes, string name, string signature, string input @@ -188,12 +171,12 @@ class ApplicationModeMetadataExtractor extends string { or e.asExpr() = call.getQualifier() and argIdx = -1 ) and - input = AutomodelSharedUtil::getArgumentForIndex(argIdx) and + input = AutomodelJavaUtil::getArgumentForIndex(argIdx) and package = callable.getDeclaringType().getPackage().getName() and // we're using the erased types because the MaD convention is to not specify type parameters. // Whether something is or isn't a sink doesn't usually depend on the type parameters. type = callable.getDeclaringType().getErasure().(RefType).nestedName() and - subtypes = this.considerSubtypes(callable).toString() and + subtypes = AutomodelJavaUtil::considerSubtypes(callable).toString() and name = callable.getName() and signature = ExternalFlow::paramsString(callable) ) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql index 136dbcde11f..e8a284dd6c0 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql @@ -11,7 +11,7 @@ private import java private import AutomodelApplicationModeCharacteristics private import AutomodelEndpointTypes -private import AutomodelSharedUtil +private import AutomodelJavaUtil /** * Gets a sample of endpoints (of at most `limit` samples) for which the given characteristic applies. diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql index ae11ffc93d4..c62476377db 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql @@ -10,7 +10,7 @@ private import AutomodelApplicationModeCharacteristics private import AutomodelEndpointTypes -private import AutomodelSharedUtil +private import AutomodelJavaUtil from Endpoint endpoint, SinkType sinkType, ApplicationModeMetadataExtractor meta, diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index d700dc22db1..9748f604300 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -14,7 +14,7 @@ private import semmle.code.java.Expr as Expr private import semmle.code.java.security.QueryInjection private import semmle.code.java.security.RequestForgery private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions -private import AutomodelSharedUtil as AutomodelSharedUtil +private import AutomodelJavaUtil as AutomodelJavaUtil private import AutomodelSharedGetCallable as AutomodelSharedGetCallable import AutomodelSharedCharacteristics as SharedCharacteristics import AutomodelEndpointTypes as AutomodelEndpointTypes @@ -48,7 +48,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { RelatedLocation asLocation(Endpoint e) { result = e.asParameter() } - predicate isKnownKind = AutomodelSharedUtil::isKnownKind/3; + predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3; predicate isSink(Endpoint e, string kind) { exists(string package, string type, string name, string signature, string ext, string input | @@ -71,7 +71,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { signature = ExternalFlow::paramsString(FrameworkModeGetCallable::getCallable(e)) and ext = "" and exists(int paramIdx | e.isParameterOf(_, paramIdx) | - input = AutomodelSharedUtil::getArgumentForIndex(paramIdx) + input = AutomodelJavaUtil::getArgumentForIndex(paramIdx) ) } @@ -120,33 +120,16 @@ class Endpoint = FrameworkCandidatesImpl::Endpoint; class FrameworkModeMetadataExtractor extends string { FrameworkModeMetadataExtractor() { this = "FrameworkModeMetadataExtractor" } - /** - * By convention, the subtypes property of the MaD declaration should only be - * true when there _can_ exist any subtypes with a different implementation. - * - * It would technically be ok to always use the value 'true', but this would - * break convention. - */ - boolean considerSubtypes(Callable callable) { - if - callable.isStatic() or - callable.getDeclaringType().isStatic() or - callable.isFinal() or - callable.getDeclaringType().isFinal() - then result = false - else result = true - } - predicate hasMetadata( Endpoint e, string package, string type, string subtypes, string name, string signature, string input, string parameterName ) { exists(Callable callable, int paramIdx | e.asParameter() = callable.getParameter(paramIdx) and - input = AutomodelSharedUtil::getArgumentForIndex(paramIdx) and + input = AutomodelJavaUtil::getArgumentForIndex(paramIdx) and package = callable.getDeclaringType().getPackage().getName() and type = callable.getDeclaringType().getErasure().(RefType).nestedName() and - subtypes = this.considerSubtypes(callable).toString() and + subtypes = AutomodelJavaUtil::considerSubtypes(callable).toString() and name = callable.getName() and parameterName = e.asParameter().getName() and signature = ExternalFlow::paramsString(callable) diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql index fa955c7de26..4186d1c17b9 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql @@ -13,7 +13,7 @@ */ private import AutomodelFrameworkModeCharacteristics -private import AutomodelSharedUtil +private import AutomodelJavaUtil from Endpoint endpoint, string message, FrameworkModeMetadataExtractor meta, DollarAtString package, diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql index eabc40a82ba..10e1870984d 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql @@ -10,7 +10,7 @@ private import AutomodelFrameworkModeCharacteristics private import AutomodelEndpointTypes -private import AutomodelSharedUtil +private import AutomodelJavaUtil from Endpoint endpoint, EndpointCharacteristic characteristic, float confidence, diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql index 587d1ed2095..2547239ee91 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql @@ -10,7 +10,7 @@ private import AutomodelFrameworkModeCharacteristics private import AutomodelEndpointTypes -private import AutomodelSharedUtil +private import AutomodelJavaUtil from Endpoint endpoint, SinkType sinkType, FrameworkModeMetadataExtractor meta, DollarAtString package, diff --git a/java/ql/src/Telemetry/AutomodelSharedUtil.qll b/java/ql/src/Telemetry/AutomodelJavaUtil.qll similarity index 80% rename from java/ql/src/Telemetry/AutomodelSharedUtil.qll rename to java/ql/src/Telemetry/AutomodelJavaUtil.qll index 7b4a88c8243..215ab1fca1a 100644 --- a/java/ql/src/Telemetry/AutomodelSharedUtil.qll +++ b/java/ql/src/Telemetry/AutomodelJavaUtil.qll @@ -1,3 +1,4 @@ +private import java private import AutomodelEndpointTypes as AutomodelEndpointTypes /** @@ -61,3 +62,20 @@ string getArgumentForIndex(int index) { or index >= 0 and result = "Argument[" + index + "]" } + +/** + * By convention, the subtypes property of the MaD declaration should only be + * true when there _can_ exist any subtypes with a different implementation. + * + * It would technically be ok to always use the value 'true', but this would + * break convention. + */ +boolean considerSubtypes(Callable callable) { + if + callable.isStatic() or + callable.getDeclaringType().isStatic() or + callable.isFinal() or + callable.getDeclaringType().isFinal() + then result = false + else result = true +} From ec3a7e39ad3ae91a5129c7d314f142a68b1b1fe7 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 14:57:38 +0200 Subject: [PATCH 400/739] Java: qldoc style --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 2 +- java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 5e04e334fb9..8556d659611 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -102,7 +102,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig } /** - * Returns the related location for the given endpoint. + * Gets the related location for the given endpoint. * * The only related location we model is the the call expression surrounding to * which the endpoint is either argument or qualifier (known as the call context). diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index 9748f604300..da37726d8f0 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -76,7 +76,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { } /** - * Returns the related location for the given endpoint. + * Gets the related location for the given endpoint. * * Related locations can be JavaDoc comments of the class or the method. */ From 2921df41da4e6872d97a867ea352e4f50f20bc05 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Wed, 7 Jun 2023 15:22:59 +0200 Subject: [PATCH 401/739] Java: fix import --- .../src/Telemetry/AutomodelApplicationModeExtractCandidates.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql index 997bc4d4a98..1e4c9c7e248 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql +++ b/java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql @@ -13,7 +13,7 @@ */ private import AutomodelApplicationModeCharacteristics -private import AutomodelSharedUtil +private import AutomodelJavaUtil from Endpoint endpoint, string message, ApplicationModeMetadataExtractor meta, DollarAtString package, From c0135673fac4bf62bef7da411eef2b10ad51d696 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 7 Jun 2023 16:18:32 +0200 Subject: [PATCH 402/739] Fix JsonArray.addAll model Properly test JsonArray.add(String) and JsonArray.addAll(JsonArray) as well --- java/ql/lib/ext/com.google.gson.model.yml | 2 +- .../test/library-tests/frameworks/gson/Test.java | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/ext/com.google.gson.model.yml b/java/ql/lib/ext/com.google.gson.model.yml index 73e14cf7cc8..7b41b57083a 100644 --- a/java/ql/lib/ext/com.google.gson.model.yml +++ b/java/ql/lib/ext/com.google.gson.model.yml @@ -31,7 +31,7 @@ extensions: - ["com.google.gson", "JsonArray", True, "add", "(JsonElement)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["com.google.gson", "JsonArray", True, "add", "(Number)", "", "Argument[0]", "Argument[this].Element", "taint", "manual"] - ["com.google.gson", "JsonArray", True, "add", "(String)", "", "Argument[0]", "Argument[this].Element", "taint", "manual"] - - ["com.google.gson", "JsonArray", True, "add", "(JsonArray)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] + - ["com.google.gson", "JsonArray", True, "addAll", "(JsonArray)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["com.google.gson", "JsonArray", True, "asList", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["com.google.gson", "JsonArray", True, "get", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["com.google.gson", "JsonArray", True, "set", "", "", "Argument[1]", "Argument[this].Element", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/gson/Test.java b/java/ql/test/library-tests/frameworks/gson/Test.java index 00811587e8b..6fa1fd2a1e5 100644 --- a/java/ql/test/library-tests/frameworks/gson/Test.java +++ b/java/ql/test/library-tests/frameworks/gson/Test.java @@ -260,23 +260,30 @@ public class Test { sink(getElement(out)); // $ hasTaintFlow } { - // "com.google.gson;JsonArray;true;add;(JsonArray);;Argument[0].Element;Argument[this].Element;value;manual" + // "com.google.gson;JsonArray;true;add;(String);;Argument[0];Argument[this].Element;taint;manual" JsonArray out = null; - JsonElement in = (JsonElement)source(); + String in = (String)source(); out.add(in); + sink(getElement(out)); // $ hasTaintFlow + } + { + // "com.google.gson;JsonArray;true;addAll;(JsonArray);;Argument[0].Element;Argument[this].Element;value;manual" + JsonArray out = null; + JsonArray in = newWithElementDefault((JsonElement) source()); + out.addAll(in); sink(getElement(out)); // $ hasValueFlow } { // "com.google.gson;JsonArray;true;asList;;;Argument[this].Element;ReturnValue.Element;value;manual" List out = null; - JsonArray in = (JsonArray)newWithElementDefault((JsonElement) source()); + JsonArray in = newWithElementDefault((JsonElement) source()); out = in.asList(); sink(getElement(out)); // $ hasValueFlow } { // "com.google.gson;JsonArray;true;get;;;Argument[this].Element;ReturnValue;value;manual" JsonElement out = null; - JsonArray in = (JsonArray)newWithElementDefault((JsonElement) source()); + JsonArray in = newWithElementDefault((JsonElement) source()); out = in.get(0); sink(out); // $ hasValueFlow } From 69854638b6fb5f333ccafc2785f26ae87ef6edba Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 7 Jun 2023 15:51:21 +0100 Subject: [PATCH 403/739] Add Go version table for --identify-environment --- go/extractor/cli/go-autobuilder/go-autobuilder.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/go/extractor/cli/go-autobuilder/go-autobuilder.go b/go/extractor/cli/go-autobuilder/go-autobuilder.go index 9fcad68d42a..f7fc575d0c1 100644 --- a/go/extractor/cli/go-autobuilder/go-autobuilder.go +++ b/go/extractor/cli/go-autobuilder/go-autobuilder.go @@ -910,6 +910,17 @@ func getVersionWhenGoModVersionSupported(v versionInfo) (msg, version string) { // Check the versions of Go found in the environment and in the `go.mod` file, and return a // version to install. If the version is the empty string then no installation is required. +// We never return a version of Go that is outside of the supported range. +// +// +-----------------------+-----------------------+-----------------------+-----------------------------------------------------+------------------------------------------------+ +// | Found in go.mod > | *None* | *Below min supported* | *In supported range* | *Above max supported | +// | Installed \/ | | | | | +// |-----------------------|-----------------------|-----------------------|-----------------------------------------------------|------------------------------------------------| +// | *None* | Install max supported | Install min supported | Install version from go.mod | Install max supported | +// | *Below min supported* | Install max supported | Install min supported | Install version from go.mod | Install max supported | +// | *In supported range* | No action | No action | Install version from go.mod if newer than installed | Install max supported if newer than installed | +// | *Above max supported* | Install max supported | Install min supported | Install version from go.mod | No action | +// +-----------------------+-----------------------+-----------------------+-----------------------------------------------------+------------------------------------------------+ func getVersionToInstall(v versionInfo) (msg, version string) { if !v.goModVersionFound { return getVersionWhenGoModVersionNotFound(v) From 57508b2b3b7623eec9924d983ea1e8ec68200401 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 30 May 2023 13:30:05 +0100 Subject: [PATCH 404/739] ruby: Limit rack PotentialResponseNode to things that look like they occur in a rack application --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll | 2 +- .../ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 78666b7fe1d..35a12c8e3eb 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -30,7 +30,7 @@ module App { AppCandidate() { call = this.getInstanceMethod("call") and call.getNumberOfParameters() = 1 and - call.getReturn() = trackRackResponse(resp) + call.getAReturningNode() = trackRackResponse(resp) } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index 65322dbac05..983d50aaeec 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -19,7 +19,10 @@ module Private { class PotentialResponseNode extends DataFlow::ArrayLiteralNode { // [status, headers, body] - PotentialResponseNode() { this.getNumberOfArguments() = 3 } + PotentialResponseNode() { + this.getNumberOfArguments() = 3 and + this.asExpr().getExpr().getEnclosingModule+().getAMethod().getName() = "call" + } /** * Gets an HTTP status code that may be returned in this response. From a5d8db6317d99656ab15993ebfcdf6a050905596 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Wed, 7 Jun 2023 15:55:01 +0100 Subject: [PATCH 405/739] Ruby: fix qldoc --- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 4 ++++ ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll | 4 ++++ ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll | 7 ++++++- .../lib/codeql/ruby/frameworks/rack/internal/Response.qll | 6 ++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index 64ca7cc0b60..74553476d17 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -1,3 +1,7 @@ +/** + * Provides modeling for the Rack library. + */ + /** * Provides modeling for the Rack library. */ diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 35a12c8e3eb..0a344f46dc8 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -1,3 +1,7 @@ +/** + * Provides modeling for Rack applications. + */ + private import codeql.ruby.ApiGraphs private import codeql.ruby.DataFlow private import codeql.ruby.typetracking.TypeTracker diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll index d40895a2f13..2aceebffbcd 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll @@ -1,3 +1,7 @@ +/** + * Provides modeling for the `Mime` component of the `Rack` library. + */ + private import codeql.ruby.ApiGraphs private import codeql.ruby.DataFlow @@ -1288,7 +1292,7 @@ private predicate mimeTypeMatches(string ext, string mimeType) { } /** - * Provides modeling for the `Response` component of the `Rack` library. + * Provides modeling for the `Mime` component of the `Rack` library. */ module Mime { class MimetypeCall extends DataFlow::CallNode { @@ -1300,6 +1304,7 @@ module Mime { result = this.getArgument(0).getConstantValue().getStringlikeValue() } + /** Gets the canonical MIME type string returned by this call. */ string getMimeType() { mimeTypeMatches(this.getExtension(), result) } } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index 983d50aaeec..26162a8d306 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -1,3 +1,7 @@ +/** + * Provides modeling for the `Response` component of the `Rack` library. + */ + private import codeql.ruby.AST private import codeql.ruby.ApiGraphs private import codeql.ruby.Concepts @@ -17,6 +21,7 @@ module Private { private DataFlow::Node trackInt(int i) { trackInt(TypeTracker::end(), i).flowsTo(result) } + /** A `DataFlow::Node` that may be a rack response. This is detected heuristically, if something "looks like" a rack response syntactically then we consider it to be a potential response node. */ class PotentialResponseNode extends DataFlow::ArrayLiteralNode { // [status, headers, body] PotentialResponseNode() { @@ -83,6 +88,7 @@ module Public { override string getMimetypeDefault() { none() } } + /** A `DataFlow::Node` returned from a rack request that has a redirect HTTP status code. */ class RedirectResponse extends ResponseNode, Http::Server::HttpRedirectResponse::Range { RedirectResponse() { this.getAStatusCode() = [300, 301, 302, 303, 307, 308] } From 19e1bab10245836ab79f80f639bb2ee131b6eeb4 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Wed, 7 Jun 2023 15:26:52 +0000 Subject: [PATCH 406/739] Python: Update expected output for syntax error queries --- .../2/query-tests/Imports/syntax_error/SyntaxError.expected | 2 +- .../3/query-tests/Imports/syntax_error/SyntaxError.expected | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/2/query-tests/Imports/syntax_error/SyntaxError.expected b/python/ql/test/2/query-tests/Imports/syntax_error/SyntaxError.expected index 7fc3fd5d706..b645e2ef286 100644 --- a/python/ql/test/2/query-tests/Imports/syntax_error/SyntaxError.expected +++ b/python/ql/test/2/query-tests/Imports/syntax_error/SyntaxError.expected @@ -1 +1 @@ -| nonsense.py:0:1:0:1 | Syntax Error | Syntax Error (in Python 2). | +| nonsense.py:1:1:1:1 | Syntax Error | Syntax Error (in Python 2). | diff --git a/python/ql/test/3/query-tests/Imports/syntax_error/SyntaxError.expected b/python/ql/test/3/query-tests/Imports/syntax_error/SyntaxError.expected index 2f8b8b32ce1..480891f7381 100644 --- a/python/ql/test/3/query-tests/Imports/syntax_error/SyntaxError.expected +++ b/python/ql/test/3/query-tests/Imports/syntax_error/SyntaxError.expected @@ -1 +1 @@ -| nonsense.py:0:1:0:1 | Syntax Error | Syntax Error (in Python 3). | +| nonsense.py:1:2:1:2 | Syntax Error | Syntax Error (in Python 3). | From 0a7ae587101b857557a82ea3aafb14c4310c2bdb Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Wed, 7 Jun 2023 16:30:53 +0100 Subject: [PATCH 407/739] Ruby: revert to simpler Rack PotentialResponseNode def and use TypeBackTracker to track instances --- .../ruby/frameworks/rack/internal/App.qll | 25 +++++++++++-------- .../frameworks/rack/internal/Response.qll | 5 +--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 0a344f46dc8..eb8b283fa16 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -7,15 +7,20 @@ private import codeql.ruby.DataFlow private import codeql.ruby.typetracking.TypeTracker private import Response::Private as RP -private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t, RP::PotentialResponseNode n) { - t.start() and - result = n - or - exists(TypeTracker t2 | result = trackRackResponse(t2, n).track(t2, t)) +/** A method node for a method named `call`. */ +private class CallMethodNode extends DataFlow::MethodNode { + CallMethodNode() { this.getMethodName() = "call" } } -private DataFlow::Node trackRackResponse(RP::PotentialResponseNode n) { - trackRackResponse(TypeTracker::end(), n).flowsTo(result) +private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, CallMethodNode call) { + t.start() and + result = call.getAReturningNode() + or + exists(TypeBackTracker t2 | result = trackRackResponse(t2, call).backtrack(t2, t)) +} + +private RP::PotentialResponseNode trackRackResponse(CallMethodNode call) { + result = trackRackResponse(TypeBackTracker::end(), call) } /** @@ -28,13 +33,13 @@ module App { * (traditionally called `env`) and returns a rack-compatible response. */ class AppCandidate extends DataFlow::ClassNode { - private DataFlow::MethodNode call; + private CallMethodNode call; private RP::PotentialResponseNode resp; AppCandidate() { call = this.getInstanceMethod("call") and call.getNumberOfParameters() = 1 and - call.getAReturningNode() = trackRackResponse(resp) + resp = trackRackResponse(call) } /** @@ -42,7 +47,7 @@ module App { */ DataFlow::ParameterNode getEnv() { result = call.getParameter(0) } - /** Gets the response returned from the request. */ + /** Gets the response returned from a request to this application. */ RP::PotentialResponseNode getResponse() { result = resp } } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index 26162a8d306..d5ca488fcda 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -24,10 +24,7 @@ module Private { /** A `DataFlow::Node` that may be a rack response. This is detected heuristically, if something "looks like" a rack response syntactically then we consider it to be a potential response node. */ class PotentialResponseNode extends DataFlow::ArrayLiteralNode { // [status, headers, body] - PotentialResponseNode() { - this.getNumberOfArguments() = 3 and - this.asExpr().getExpr().getEnclosingModule+().getAMethod().getName() = "call" - } + PotentialResponseNode() { this.getNumberOfArguments() = 3 } /** * Gets an HTTP status code that may be returned in this response. From 0efa212c4077564a9545d7c6a6dd5c16e795c619 Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Wed, 7 Jun 2023 19:27:46 +0200 Subject: [PATCH 408/739] Ruby: update tree-sitter-ruby --- ruby/extractor/Cargo.lock | Bin 31065 -> 31065 bytes ruby/extractor/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/extractor/Cargo.lock b/ruby/extractor/Cargo.lock index 85c546b9b96e189aae02de3062127274df104d7b..f048f2d7725d8d6e8b86e41a63b538afe657ba31 100644 GIT binary patch delta 99 zcmccliSgzq#tkc?0?bX)Qc_J*P1BN$l9Eg<%`FlWQ&Y_?EKLn9EK-vUEiKc`(-M=@ S43vpfIQgJ}_-6iSFF63U^dL9@ delta 100 zcmccliSgzq#tkc?0*wsJlFbdw%?-^=jLnUbO)bsR(h@CF6BARCEKQ6}lZ`AaO$?3A SOq7XLIQgQe*k=A{FF61&_#I6E diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index 133233f2f14..6857162af5e 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" [dependencies] tree-sitter = "0.20" tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "203f7bd3c1bbfbd98fc19add4b8fcb213c059205" } -tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "206c7077164372c596ffa8eaadb9435c28941364" } +tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "74fde5e5fb2bb5978aaee7895188eb199f7facf0" } clap = { version = "4.2", features = ["derive"] } tracing = "0.1" tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } From cbbd885e229823ad50aa77e554bb2078a955dce7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Jun 2023 00:17:14 +0000 Subject: [PATCH 409/739] Add changed framework coverage reports --- .../documentation/library-coverage/coverage.csv | 17 ++++++++++++----- .../documentation/library-coverage/coverage.rst | 8 ++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 0e429b40b52..93c93f8ef46 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -12,10 +12,11 @@ androidx.core.app,6,,95,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,12,83 androidx.fragment.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, androidx.slice,2,5,88,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,5,,27,61 cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.alibaba.druid.sql,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +com.fasterxml.jackson.databind,2,,6,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,6, com.google.common.base,4,,87,,,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,63,24 com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 @@ -23,6 +24,7 @@ com.google.common.flogger,29,,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,, com.google.common.io,8,,73,,1,,,,,,,,,,,,,,7,,,,,,,,,,,,,,,,,,,72,1 com.google.gson,,,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,14 com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, +com.jcraft.jsch,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,1, com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,, com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, @@ -41,7 +43,7 @@ io.netty.bootstrap,3,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,,,, io.netty.buffer,,,207,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,130,77 io.netty.channel,9,2,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,2,, io.netty.handler.codec,4,13,259,,,,,,,,,,,,,,,,1,,,,,,,,,3,,,,,,,,,13,143,116 -io.netty.handler.ssl,2,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,, +io.netty.handler.ssl,4,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,, io.netty.handler.stream,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, io.netty.resolver,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, io.netty.util,2,,23,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,,,,,,,21,2 @@ -52,10 +54,10 @@ jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,94,55 java.awt,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3 java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,44,,45,,22,,,,,,,,,,,,,,22,,,,,,,,,,,,,,,,,,,43,2 +java.io,49,,45,,22,,,,,,,,,,,,,,27,,,,,,,,,,,,,,,,,,,43,2 java.lang,18,,92,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36 java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20, -java.nio,40,,35,,3,,,,,,,,,,,,,,37,,,,,,,,,,,,,,,,,,,35, +java.nio,47,,35,,3,,,,,,,,,,,,,,44,,,,,,,,,,,,,,,,,,,35, java.sql,13,,3,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,1 java.util,44,,484,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440 javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, @@ -78,7 +80,8 @@ jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 kotlin,16,,1847,,,,,,,,,,,,,,,,14,,,,,,,,,2,,,,,,,,,,1836,11 net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,, ognl,6,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, -okhttp3,4,,47,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,22,25 +okhttp3,4,,48,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,23,25 +org.antlr.runtime,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 @@ -119,8 +122,10 @@ org.codehaus.cargo.container.installer,3,,,,,,,,,,,,,,,,,,2,,,,,,,,,1,,,,,,,,,,, org.codehaus.groovy.control,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,, org.eclipse.jetty.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.fusesource.leveldbjni,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, org.geogebra.web.full.main,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,, org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,, +org.influxdb,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, org.jboss.logging,324,,,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,, org.jdbi.v3.core,6,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,, @@ -134,6 +139,7 @@ org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 org.springframework.boot.jdbc,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.core.io,2,,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,,,,,,,, org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 org.springframework.http,14,,71,,,,,,,,,,,,,,,,,,,,,,,,,14,,,,,,,,,,61,10 org.springframework.jdbc.core,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,, @@ -153,6 +159,7 @@ org.springframework.web.util,,,165,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,140,25 org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,2, org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +org.yaml.snakeyaml,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, play.libs.ws,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, play.mvc,,13,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,24, ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 55b9a0a071d..ffd3ce0ed91 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -18,10 +18,10 @@ Java framework & library support `Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,41,7,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,, `JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,, - Java Standard Library,``java.*``,3,683,172,64,,9,,,17 + Java Standard Library,``java.*``,3,683,184,76,,9,,,17 Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2 - `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,113,3,,28,14,,34 - Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,890,520,60,,18,18,,193 - Totals,,255,9190,1975,244,10,122,33,1,382 + `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,115,4,,28,14,,35 + Others,"``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,894,528,66,,18,18,,195 + Totals,,255,9194,1997,263,10,122,33,1,385 From 65e651506ce0291c9e42dd936c4c3a43e76a74a5 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 8 Jun 2023 08:51:21 +0200 Subject: [PATCH 410/739] C#: Address review comments. --- csharp/tools/tracing-config.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index 49044226da3..f04169caff5 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -21,6 +21,7 @@ function RegisterExtractorPack(id) -- if that's `build`, we append `-p:UseSharedCompilation=false` to the command line, -- otherwise we do nothing. local match = false + local testMatch = false local dotnetRunNeedsSeparator = false; local dotnetRunInjectionIndex = nil; local argv = compilerArguments.argv @@ -50,10 +51,11 @@ function RegisterExtractorPack(id) end if arg == 'test' then match = true + testMatch = true end - -- for `dotnet [test|run]`, we should not append `-p:UseSharedCompilation=false` to the command line - -- if a library or executable is being provided as an argument. - if arg:match('%.exe$') or arg:match('%.dll') then + -- for `dotnet test`, we should not append `-p:UseSharedCompilation=false` to the command line + -- if an `exe` or `dll` is passed as an argument as the call is forwarded to vstest. + if testMatch and (arg:match('%.exe$') or arg:match('%.dll')) then match = false break end From 2fece9d72148593f39a770c5660ddd1f93bb1c44 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 8 Jun 2023 09:58:52 +0200 Subject: [PATCH 411/739] C#: Add MSTEST test project and check that the call to vstest doesn't get the UseSharedCompilation=false flag forwarded. --- .../dotnet_test_mstest/UnitTest1.cs | 10 ++++++++++ .../posix-only/dotnet_test_mstest/Usings.cs | 1 + .../dotnet_test_mstest.csproj | 19 +++++++++++++++++++ .../posix-only/dotnet_test_mstest/test.py | 10 ++++++++++ 4 files changed, 40 insertions(+) create mode 100644 csharp/ql/integration-tests/posix-only/dotnet_test_mstest/UnitTest1.cs create mode 100644 csharp/ql/integration-tests/posix-only/dotnet_test_mstest/Usings.cs create mode 100644 csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj create mode 100644 csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/UnitTest1.cs b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/UnitTest1.cs new file mode 100644 index 00000000000..7e3b2ce1d1c --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace dotnet_test_mstest; + +[TestClass] +public class UnitTest1 +{ + [TestMethod] + public void TestMethod1() + { + } +} diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/Usings.cs b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/Usings.cs new file mode 100644 index 00000000000..540383dcf43 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/Usings.cs @@ -0,0 +1 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj new file mode 100644 index 00000000000..95c7586e04e --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj @@ -0,0 +1,19 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net7.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + + <IsPackable>false</IsPackable> + <OutputType>Exe</OutputType> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" /> + <PackageReference Include="MSTest.TestAdapter" Version="2.2.10" /> + <PackageReference Include="MSTest.TestFramework" Version="2.2.10" /> + <PackageReference Include="coverlet.collector" Version="3.1.2" /> + </ItemGroup> + +</Project> diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py new file mode 100644 index 00000000000..345d26a1516 --- /dev/null +++ b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py @@ -0,0 +1,10 @@ +from create_database_utils import * +from diagnostics_test_utils import * + +# Implicitly build and then run tests. +run_codeql_database_create(['dotnet test'], test_db="test-db", lang="csharp") +check_diagnostics() + +# Explicitly build and then run tests. +run_codeql_database_create(['dotnet clean', 'rm -rf test-db', 'dotnet build -o myout --os win', 'dotnet test myout/dotnet_test_mstest.exe'], test_db="test2-db", lang="csharp") +check_diagnostics(test_db="test2-db") From a4ef8619c68bb28b7ad006cda1530c52e6d5ba8a Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 09:44:30 +0200 Subject: [PATCH 412/739] delete old deprecations --- cpp/ql/lib/semmle/code/cpp/Class.qll | 14 - cpp/ql/lib/semmle/code/cpp/File.qll | 20 - cpp/ql/lib/semmle/code/cpp/PrintAST.qll | 12 - .../lib/semmle/code/cpp/controlflow/SSA.qll | 3 - .../semmle/code/cpp/controlflow/SSAUtils.qll | 3 - .../code/cpp/controlflow/internal/CFG.qll | 9 - .../aliased_ssa/internal/AliasedSSA.qll | 3 - .../ir/implementation/internal/TOperand.qll | 14 - .../raw/internal/IRConstruction.qll | 5 - .../raw/internal/TranslatedExpr.qll | 3 - .../code/cpp/rangeanalysis/RangeSSA.qll | 3 - .../src/Security/CWE/CWE-020/ExternalAPIs.qll | 6 - .../CWE/CWE-020/ExternalAPIsSpecific.qll | 6 - .../CWE/CWE-020/SafeExternalAPIFunction.qll | 3 - .../Security/CWE/CWE-020/ir/ExternalAPIs.qll | 6 - .../CWE/CWE-020/ir/ExternalAPIsSpecific.qll | 6 - .../CWE-020/ir/SafeExternalAPIFunction.qll | 3 - cpp/ql/src/external/CodeDuplication.qll | 373 ------------------ .../library-tests/dataflow/fields/Nodes.qll | 3 - 19 files changed, 495 deletions(-) delete mode 100644 cpp/ql/src/external/CodeDuplication.qll diff --git a/cpp/ql/lib/semmle/code/cpp/Class.qll b/cpp/ql/lib/semmle/code/cpp/Class.qll index 2aba033329d..5f79ceefd26 100644 --- a/cpp/ql/lib/semmle/code/cpp/Class.qll +++ b/cpp/ql/lib/semmle/code/cpp/Class.qll @@ -176,20 +176,6 @@ class Class extends UserType { /** Holds if this class, struct or union has a constructor. */ predicate hasConstructor() { exists(this.getAConstructor()) } - /** - * Holds if this class has a copy constructor that is either explicitly - * declared (though possibly `= delete`) or is auto-generated, non-trivial - * and called from somewhere. - * - * DEPRECATED: There is more than one reasonable definition of what it means - * to have a copy constructor, and we do not want to promote one particular - * definition by naming it with this predicate. Having a copy constructor - * could mean that such a member is declared or defined in the source or that - * it is callable by a particular caller. For C++11, there's also a question - * of whether to include members that are defaulted or deleted. - */ - deprecated predicate hasCopyConstructor() { this.getAMemberFunction() instanceof CopyConstructor } - /** * Like accessOfBaseMember but returns multiple results if there are multiple * paths to `base` through the inheritance graph. diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll index b2e4e0a41a5..bac9b66965e 100644 --- a/cpp/ql/lib/semmle/code/cpp/File.qll +++ b/cpp/ql/lib/semmle/code/cpp/File.qll @@ -34,14 +34,6 @@ class Container extends Locatable, @container { */ string getAbsolutePath() { none() } // overridden by subclasses - /** - * DEPRECATED: Use `getLocation` instead. - * Gets a URL representing the location of this container. - * - * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls). - */ - deprecated string getURL() { none() } // overridden by subclasses - /** * Gets the relative path of this file or folder from the root folder of the * analyzed source location. The relative path of the root folder itself is @@ -183,12 +175,6 @@ class Folder extends Container, @folder { } override string getAPrimaryQlClass() { result = "Folder" } - - /** - * DEPRECATED: Use `getLocation` instead. - * Gets the URL of this folder. - */ - deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } } /** @@ -213,12 +199,6 @@ class File extends Container, @file { result.hasLocationInfo(_, 0, 0, 0, 0) } - /** - * DEPRECATED: Use `getLocation` instead. - * Gets the URL of this file. - */ - deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } - /** Holds if this file was compiled as C (at any point). */ predicate compiledAsC() { fileannotations(underlyingElement(this), 1, "compiled as c", "1") } diff --git a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll index b4d89eb8c1d..11e1791ba60 100644 --- a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll +++ b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll @@ -27,9 +27,6 @@ class PrintAstConfiguration extends TPrintAstConfiguration { predicate shouldPrintFunction(Function func) { any() } } -/** DEPRECATED: Alias for PrintAstConfiguration */ -deprecated class PrintASTConfiguration = PrintAstConfiguration; - private predicate shouldPrintFunction(Function func) { exists(PrintAstConfiguration config | config.shouldPrintFunction(func)) } @@ -239,9 +236,6 @@ class PrintAstNode extends TPrintAstNode { } } -/** DEPRECATED: Alias for PrintAstNode */ -deprecated class PrintASTNode = PrintAstNode; - /** * Class that restricts the elements that we compute `qlClass` for. */ @@ -286,9 +280,6 @@ abstract class BaseAstNode extends PrintAstNode { deprecated Locatable getAST() { result = this.getAst() } } -/** DEPRECATED: Alias for BaseAstNode */ -deprecated class BaseASTNode = BaseAstNode; - /** * A node representing an AST node other than a `DeclarationEntry`. */ @@ -296,9 +287,6 @@ abstract class AstNode extends BaseAstNode, TAstNode { AstNode() { this = TAstNode(ast) } } -/** DEPRECATED: Alias for AstNode */ -deprecated class ASTNode = AstNode; - /** * A node representing an `Expr`. */ diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll index 4732cd06184..f9dad008661 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll @@ -14,9 +14,6 @@ library class StandardSsa extends SsaHelper { StandardSsa() { this = 0 } } -/** DEPRECATED: Alias for StandardSsa */ -deprecated class StandardSSA = StandardSsa; - /** * A definition of one or more SSA variables, including phi node definitions. * An _SSA variable_, as defined in the literature, is effectively the pair of diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/SSAUtils.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/SSAUtils.qll index 45ef36f339d..5e9f85581b8 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/SSAUtils.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/SSAUtils.qll @@ -312,6 +312,3 @@ library class SsaHelper extends int { ssa_use(v, result, _, _) } } - -/** DEPRECATED: Alias for SsaHelper */ -deprecated class SSAHelper = SsaHelper; diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/CFG.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/CFG.qll index 25fdba90d52..99aed9702a9 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/CFG.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/CFG.qll @@ -1385,9 +1385,6 @@ private module Cached { conditionalSuccessor(n1, _, n2) } - /** DEPRECATED: Alias for qlCfgSuccessor */ - deprecated predicate qlCFGSuccessor = qlCfgSuccessor/2; - /** * Holds if `n2` is a control-flow node such that the control-flow * edge `(n1, n2)` may be taken when `n1` is an expression that is true. @@ -1398,9 +1395,6 @@ private module Cached { not conditionalSuccessor(n1, false, n2) } - /** DEPRECATED: Alias for qlCfgTrueSuccessor */ - deprecated predicate qlCFGTrueSuccessor = qlCfgTrueSuccessor/2; - /** * Holds if `n2` is a control-flow node such that the control-flow * edge `(n1, n2)` may be taken when `n1` is an expression that is false. @@ -1410,7 +1404,4 @@ private module Cached { conditionalSuccessor(n1, false, n2) and not conditionalSuccessor(n1, true, n2) } - - /** DEPRECATED: Alias for qlCfgFalseSuccessor */ - deprecated predicate qlCFGFalseSuccessor = qlCfgFalseSuccessor/2; } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll index 1dd116d6c0e..10fddf6352b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll @@ -577,9 +577,6 @@ private Overlap getVariableMemoryLocationOverlap( */ predicate canReuseSsaForOldResult(Instruction instr) { OldSsa::canReuseSsaForMemoryResult(instr) } -/** DEPRECATED: Alias for canReuseSsaForOldResult */ -deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1; - bindingset[result, b] private boolean unbindBool(boolean b) { result != b.booleanNot() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TOperand.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TOperand.qll index 607b88fa58d..8a330114fe9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TOperand.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TOperand.qll @@ -74,20 +74,12 @@ private module Shared { class TNonSsaMemoryOperand = Internal::TNonSsaMemoryOperand; - /** DEPRECATED: Alias for TNonSsaMemoryOperand */ - deprecated class TNonSSAMemoryOperand = TNonSsaMemoryOperand; - /** * Returns the non-Phi memory operand with the specified parameters. */ TNonSsaMemoryOperand nonSsaMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { result = Internal::TNonSsaMemoryOperand(useInstr, tag) } - - /** DEPRECATED: Alias for nonSsaMemoryOperand */ - deprecated TNonSSAMemoryOperand nonSSAMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) { - result = nonSsaMemoryOperand(useInstr, tag) - } } /** @@ -167,9 +159,6 @@ module UnaliasedSsaOperands { TChiOperand chiOperand(Unaliased::Instruction useInstr, ChiOperandTag tag) { none() } } -/** DEPRECATED: Alias for UnaliasedSsaOperands */ -deprecated module UnaliasedSSAOperands = UnaliasedSsaOperands; - /** * Provides wrappers for the constructors of each branch of `TOperand` that is used by the * aliased SSA stage. @@ -217,6 +206,3 @@ module AliasedSsaOperands { result = Internal::TAliasedChiOperand(useInstr, tag) } } - -/** DEPRECATED: Alias for AliasedSsaOperands */ -deprecated module AliasedSSAOperands = AliasedSsaOperands; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll index 1cfd8a2041e..8c0695247f8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll @@ -375,11 +375,6 @@ Locatable getInstructionAst(TStageInstruction instr) { ) } -/** DEPRECATED: Alias for getInstructionAst */ -deprecated Locatable getInstructionAST(TStageInstruction instr) { - result = getInstructionAst(instr) -} - CppType getInstructionResultType(TStageInstruction instr) { getInstructionTranslatedElement(instr).hasInstruction(_, getInstructionTag(instr), result) or diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 3080848b153..5832aa9f928 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -76,9 +76,6 @@ abstract class TranslatedExpr extends TranslatedElement { final override Locatable getAst() { result = expr } - /** DEPRECATED: Alias for getAst */ - deprecated override Locatable getAST() { result = this.getAst() } - final override Declaration getFunction() { result = getEnclosingDeclaration(expr) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll index 2503e4713d8..849dd70a9a3 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll @@ -40,9 +40,6 @@ library class RangeSsa extends SsaHelper { } } -/** DEPRECATED: Alias for RangeSsa */ -deprecated class RangeSSA = RangeSsa; - private predicate guard_defn(VariableAccess v, Expr guard, BasicBlock b, boolean branch) { guardCondition(guard, v, branch) and guardSuccessor(guard, branch, b) diff --git a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll index 5135aab8d83..51dad0fc18c 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll @@ -16,9 +16,6 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode { DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } } -/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ -deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; - /** An external API which is used with untrusted data. */ private newtype TExternalApi = /** An untrusted API method `m` where untrusted data is passed at `index`. */ @@ -51,6 +48,3 @@ class ExternalApiUsedWithUntrustedData extends TExternalApi { ) } } - -/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ -deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll index 2505f718bc6..2d9502f2f43 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll @@ -41,9 +41,6 @@ class ExternalApiDataNode extends DataFlow::Node { string getFunctionDescription() { result = this.getExternalFunction().toString() } } -/** DEPRECATED: Alias for ExternalApiDataNode */ -deprecated class ExternalAPIDataNode = ExternalApiDataNode; - /** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } @@ -58,9 +55,6 @@ deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configu override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } -/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ -deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; - /** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { diff --git a/cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll b/cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll index de59e82e552..aecbe148290 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/SafeExternalAPIFunction.qll @@ -10,9 +10,6 @@ private import semmle.code.cpp.models.interfaces.SideEffect */ abstract class SafeExternalApiFunction extends Function { } -/** DEPRECATED: Alias for SafeExternalApiFunction */ -deprecated class SafeExternalAPIFunction = SafeExternalApiFunction; - /** The default set of "safe" external APIs. */ private class DefaultSafeExternalApiFunction extends SafeExternalApiFunction { DefaultSafeExternalApiFunction() { diff --git a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll index 5135aab8d83..51dad0fc18c 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll @@ -16,9 +16,6 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode { DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } } -/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ -deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; - /** An external API which is used with untrusted data. */ private newtype TExternalApi = /** An untrusted API method `m` where untrusted data is passed at `index`. */ @@ -51,6 +48,3 @@ class ExternalApiUsedWithUntrustedData extends TExternalApi { ) } } - -/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ -deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll index 93da5497a22..87e1d6bd7c5 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll @@ -41,9 +41,6 @@ class ExternalApiDataNode extends DataFlow::Node { string getFunctionDescription() { result = this.getExternalFunction().toString() } } -/** DEPRECATED: Alias for ExternalApiDataNode */ -deprecated class ExternalAPIDataNode = ExternalApiDataNode; - /** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfigIR" } @@ -53,9 +50,6 @@ deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configu override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } -/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ -deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; - /** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } diff --git a/cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll b/cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll index de59e82e552..aecbe148290 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll @@ -10,9 +10,6 @@ private import semmle.code.cpp.models.interfaces.SideEffect */ abstract class SafeExternalApiFunction extends Function { } -/** DEPRECATED: Alias for SafeExternalApiFunction */ -deprecated class SafeExternalAPIFunction = SafeExternalApiFunction; - /** The default set of "safe" external APIs. */ private class DefaultSafeExternalApiFunction extends SafeExternalApiFunction { DefaultSafeExternalApiFunction() { diff --git a/cpp/ql/src/external/CodeDuplication.qll b/cpp/ql/src/external/CodeDuplication.qll deleted file mode 100644 index be2dc162e74..00000000000 --- a/cpp/ql/src/external/CodeDuplication.qll +++ /dev/null @@ -1,373 +0,0 @@ -/** Provides classes for detecting duplicate or similar code. */ - -import cpp - -deprecated private newtype TDuplicationOrSimilarity = MKDuplicationOrSimilarity() - -/** - * DEPRECATED: This class is no longer used. - * - * A token block used for detection of duplicate and similar code. - */ -deprecated class Copy extends TDuplicationOrSimilarity { - /** Gets the index of the token in this block starting at the location `loc`, if any. */ - int tokenStartingAt(Location loc) { none() } - - /** Gets the index of the token in this block ending at the location `loc`, if any. */ - int tokenEndingAt(Location loc) { none() } - - /** Gets the line on which the first token in this block starts. */ - int sourceStartLine() { none() } - - /** Gets the column on which the first token in this block starts. */ - int sourceStartColumn() { none() } - - /** Gets the line on which the last token in this block ends. */ - int sourceEndLine() { none() } - - /** Gets the column on which the last token in this block ends. */ - int sourceEndColumn() { none() } - - /** Gets the number of lines containing at least (part of) one token in this block. */ - int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() } - - /** Gets an opaque identifier for the equivalence class of this block. */ - int getEquivalenceClass() { none() } - - /** Gets the source file in which this block appears. */ - File sourceFile() { none() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.sourceFile().getAbsolutePath() = filepath and - startline = this.sourceStartLine() and - startcolumn = this.sourceStartColumn() and - endline = this.sourceEndLine() and - endcolumn = this.sourceEndColumn() - } - - /** Gets a textual representation of this element. */ - string toString() { none() } -} - -/** - * DEPRECATED: This class is no longer used. - * - * A block of duplicated code. - */ -deprecated class DuplicateBlock extends Copy { - override string toString() { - result = "Duplicate code: " + this.sourceLines() + " duplicated lines." - } -} - -/** - * DEPRECATED: This class is no longer used. - * - * A block of similar code. - */ -deprecated class SimilarBlock extends Copy { - override string toString() { - result = "Similar code: " + this.sourceLines() + " almost duplicated lines." - } -} - -/** - * DEPRECATED: The `CodeDuplication` library will be removed in a future release. - * - * Gets a function with a body and a location. - */ -deprecated FunctionDeclarationEntry sourceMethod() { - result.isDefinition() and - exists(result.getLocation()) and - numlines(unresolveElement(result.getFunction()), _, _, _) -} - -/** - * DEPRECATED: The `CodeDuplication` library will be removed in a future release. - * - * Gets the number of member functions in `c` with a body and a location. - */ -deprecated int numberOfSourceMethods(Class c) { - result = - count(FunctionDeclarationEntry m | - m = sourceMethod() and - m.getFunction().getDeclaringType() = c - ) -} - -deprecated private predicate blockCoversStatement(int equivClass, int first, int last, Stmt stmt) { - exists(DuplicateBlock b, Location loc | - stmt.getLocation() = loc and - first = b.tokenStartingAt(loc) and - last = b.tokenEndingAt(loc) and - b.getEquivalenceClass() = equivClass - ) -} - -deprecated private Stmt statementInMethod(FunctionDeclarationEntry m) { - result.getParent+() = m.getBlock() and - not result.getLocation() instanceof UnknownStmtLocation and - not result instanceof BlockStmt -} - -deprecated private predicate duplicateStatement( - FunctionDeclarationEntry m1, FunctionDeclarationEntry m2, Stmt s1, Stmt s2 -) { - exists(int equivClass, int first, int last | - s1 = statementInMethod(m1) and - s2 = statementInMethod(m2) and - blockCoversStatement(equivClass, first, last, s1) and - blockCoversStatement(equivClass, first, last, s2) and - s1 != s2 and - m1 != m2 - ) -} - -/** - * DEPRECATED: Information on duplicated statements is no longer available. - * - * Holds if `m1` is a function with `total` lines, and `m2` is a function - * that has `duplicate` lines in common with `m1`. - */ -deprecated predicate duplicateStatements( - FunctionDeclarationEntry m1, FunctionDeclarationEntry m2, int duplicate, int total -) { - duplicate = strictcount(Stmt s | duplicateStatement(m1, m2, s, _)) and - total = strictcount(statementInMethod(m1)) -} - -/** - * DEPRECATED: Information on duplicated methods is no longer available. - * - * Holds if `m` and other are identical functions. - */ -deprecated predicate duplicateMethod(FunctionDeclarationEntry m, FunctionDeclarationEntry other) { - exists(int total | duplicateStatements(m, other, total, total)) -} - -/** - * DEPRECATED: Information on similar lines is no longer available. - * - * INTERNAL: do not use. - * - * Holds if `line` in `f` is similar to a line somewhere else. - */ -deprecated predicate similarLines(File f, int line) { - exists(SimilarBlock b | b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()]) -} - -deprecated private predicate similarLinesPerEquivalenceClass(int equivClass, int lines, File f) { - lines = - strictsum(SimilarBlock b, int toSum | - (b.sourceFile() = f and b.getEquivalenceClass() = equivClass) and - toSum = b.sourceLines() - | - toSum - ) -} - -deprecated private predicate similarLinesCoveredFiles(File f, File otherFile) { - exists(int numLines | numLines = f.getMetrics().getNumberOfLines() | - exists(int coveredApprox | - coveredApprox = - strictsum(int num | - exists(int equivClass | - similarLinesPerEquivalenceClass(equivClass, num, f) and - similarLinesPerEquivalenceClass(equivClass, num, otherFile) and - f != otherFile - ) - ) and - (coveredApprox * 100) / numLines > 75 - ) - ) -} - -/** - * DEPRECATED: Information on similar lines is no longer available. - * - * Holds if `coveredLines` lines of `f` are similar to lines in `otherFile`. - */ -deprecated predicate similarLinesCovered(File f, int coveredLines, File otherFile) { - exists(int numLines | numLines = f.getMetrics().getNumberOfLines() | - similarLinesCoveredFiles(f, otherFile) and - exists(int notCovered | - notCovered = - count(int j | - j in [1 .. numLines] and - not similarLines(f, j) - ) and - coveredLines = numLines - notCovered - ) - ) -} - -/** - * DEPRECATED: Information on duplicate lines is no longer available. - * - * INTERNAL: do not use. - * - * Holds if `line` in `f` is duplicated by a line somewhere else. - */ -deprecated predicate duplicateLines(File f, int line) { - exists(DuplicateBlock b | - b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()] - ) -} - -deprecated private predicate duplicateLinesPerEquivalenceClass(int equivClass, int lines, File f) { - lines = - strictsum(DuplicateBlock b, int toSum | - (b.sourceFile() = f and b.getEquivalenceClass() = equivClass) and - toSum = b.sourceLines() - | - toSum - ) -} - -/** - * DEPRECATED: Information on duplicate lines is no longer available. - * - * Holds if `coveredLines` lines of `f` are duplicates of lines in `otherFile`. - */ -deprecated predicate duplicateLinesCovered(File f, int coveredLines, File otherFile) { - exists(int numLines | numLines = f.getMetrics().getNumberOfLines() | - exists(int coveredApprox | - coveredApprox = - strictsum(int num | - exists(int equivClass | - duplicateLinesPerEquivalenceClass(equivClass, num, f) and - duplicateLinesPerEquivalenceClass(equivClass, num, otherFile) and - f != otherFile - ) - ) and - (coveredApprox * 100) / numLines > 75 - ) and - exists(int notCovered | - notCovered = - count(int j | - j in [1 .. numLines] and - not duplicateLines(f, j) - ) and - coveredLines = numLines - notCovered - ) - ) -} - -/** - * DEPRECATED: Information on similar files is no longer available. - * - * Holds if most of `f` (`percent`%) is similar to `other`. - */ -deprecated predicate similarFiles(File f, File other, int percent) { - exists(int covered, int total | - similarLinesCovered(f, covered, other) and - total = f.getMetrics().getNumberOfLines() and - covered * 100 / total = percent and - percent > 80 - ) and - not duplicateFiles(f, other, _) -} - -/** - * DEPRECATED: Information on duplicate files is no longer available. - * - * Holds if most of `f` (`percent`%) is duplicated by `other`. - */ -deprecated predicate duplicateFiles(File f, File other, int percent) { - exists(int covered, int total | - duplicateLinesCovered(f, covered, other) and - total = f.getMetrics().getNumberOfLines() and - covered * 100 / total = percent and - percent > 70 - ) -} - -/** - * DEPRECATED: Information on duplicate classes is no longer available. - * - * Holds if most member functions of `c` (`numDup` out of `total`) are - * duplicates of member functions in `other`. - */ -deprecated predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int total) { - numDup = - strictcount(FunctionDeclarationEntry m1 | - exists(FunctionDeclarationEntry m2 | - duplicateMethod(m1, m2) and - m1 = sourceMethod() and - exists(Function f | f = m1.getFunction() and f.getDeclaringType() = c) and - exists(Function f | f = m2.getFunction() and f.getDeclaringType() = other) and - c != other - ) - ) and - total = numberOfSourceMethods(c) and - (numDup * 100) / total > 80 -} - -/** - * DEPRECATED: Information on duplicate classes is no longer available. - * - * Holds if most member functions of `c` are duplicates of member functions in - * `other`. Provides the human-readable `message` to describe the amount of - * duplication. - */ -deprecated predicate mostlyDuplicateClass(Class c, Class other, string message) { - exists(int numDup, int total | - mostlyDuplicateClassBase(c, other, numDup, total) and - ( - total != numDup and - exists(string s1, string s2, string s3, string name | - s1 = " out of " and - s2 = " methods in " and - s3 = " are duplicated in $@." and - name = c.getName() - | - message = numDup + s1 + total + s2 + name + s3 - ) - or - total = numDup and - exists(string s1, string s2, string name | - s1 = "All methods in " and s2 = " are identical in $@." and name = c.getName() - | - message = s1 + name + s2 - ) - ) - ) -} - -/** - * DEPRECATED: Information on file duplication is no longer available. - * - * Holds if `f` and `other` are similar or duplicates. - */ -deprecated predicate fileLevelDuplication(File f, File other) { - similarFiles(f, other, _) or duplicateFiles(f, other, _) -} - -/** - * DEPRECATED: Information on class duplication is no longer available. - * - * Holds if most member functions of `c` are duplicates of member functions in - * `other`. - */ -deprecated predicate classLevelDuplication(Class c, Class other) { - mostlyDuplicateClass(c, other, _) -} - -/** - * DEPRECATED: The CodeDuplication library will be removed in a future release. - * - * Holds if `line` in `f` should be allowed to be duplicated. This is the case - * for `#include` directives. - */ -deprecated predicate whitelistedLineForDuplication(File f, int line) { - exists(Include i | i.getFile() = f and i.getLocation().getStartLine() = line) -} diff --git a/cpp/ql/test/library-tests/dataflow/fields/Nodes.qll b/cpp/ql/test/library-tests/dataflow/fields/Nodes.qll index 7313518af91..8c4c547f4c8 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/Nodes.qll +++ b/cpp/ql/test/library-tests/dataflow/fields/Nodes.qll @@ -34,9 +34,6 @@ class AstNode extends Node, TAstNode { override Location getLocation() { result = n.getLocation() } } -/** DEPRECATED: Alias for AstNode */ -deprecated class ASTNode = AstNode; - class IRNode extends Node, TIRNode { IR::DataFlow::Node n; From 2241350d321e4ac86c4dbb1cb153e85687569198 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 7 Jun 2023 22:35:11 +0200 Subject: [PATCH 413/739] wait with deprecating Container::getURL() --- cpp/ql/lib/semmle/code/cpp/File.qll | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll index bac9b66965e..b2e4e0a41a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/File.qll +++ b/cpp/ql/lib/semmle/code/cpp/File.qll @@ -34,6 +34,14 @@ class Container extends Locatable, @container { */ string getAbsolutePath() { none() } // overridden by subclasses + /** + * DEPRECATED: Use `getLocation` instead. + * Gets a URL representing the location of this container. + * + * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls). + */ + deprecated string getURL() { none() } // overridden by subclasses + /** * Gets the relative path of this file or folder from the root folder of the * analyzed source location. The relative path of the root folder itself is @@ -175,6 +183,12 @@ class Folder extends Container, @folder { } override string getAPrimaryQlClass() { result = "Folder" } + + /** + * DEPRECATED: Use `getLocation` instead. + * Gets the URL of this folder. + */ + deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } } /** @@ -199,6 +213,12 @@ class File extends Container, @file { result.hasLocationInfo(_, 0, 0, 0, 0) } + /** + * DEPRECATED: Use `getLocation` instead. + * Gets the URL of this file. + */ + deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } + /** Holds if this file was compiled as C (at any point). */ predicate compiledAsC() { fileannotations(underlyingElement(this), 1, "compiled as c", "1") } From 39438c619690038b27b12d5908259250e0f328e0 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 8 Jun 2023 10:15:32 +0200 Subject: [PATCH 414/739] add change-note --- cpp/ql/lib/change-notes/2022-08-06-delete-deps.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2022-08-06-delete-deps.md diff --git a/cpp/ql/lib/change-notes/2022-08-06-delete-deps.md b/cpp/ql/lib/change-notes/2022-08-06-delete-deps.md new file mode 100644 index 00000000000..c234c189484 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-08-06-delete-deps.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `hasCopyConstructor` predicate from the `Class` class in `Class.qll`. +* Deleted many deprecated predicates and classes with uppercase `AST`, `SSA`, `CFG`, `API`, etc. in their names. Use the PascalCased versions instead. +* Deleted the deprecated `CodeDuplication.qll` file. \ No newline at end of file From c493e276eccbcefddf28ae58cb7b7accdf41edc2 Mon Sep 17 00:00:00 2001 From: Mathew Payne <geekmasher@gmail.com> Date: Thu, 8 Jun 2023 10:57:12 +0100 Subject: [PATCH 415/739] Update MaD sink kinds from main --- csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 0ce50e54a3a..22335fb0dce 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -213,8 +213,9 @@ module ModelValidation { exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | not kind = [ - "code", "command-injection", "html", "ldap-injection", "log-injection", "remote", "sql", - "url-redirection", "xss", + "code-injection", "command-injection", "file-content-store", "html-injection", + "ldap-injection", "log-injection", "remote", "sql-injection", "url-redirection", + "js-injection", ] and not kind.matches("encryption-%") and result = "Invalid kind \"" + kind + "\" in sink model." From a5e0669981449ff5671ba7e2fd4bd3d6c1d7995d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Thu, 8 Jun 2023 12:03:58 +0200 Subject: [PATCH 416/739] Swift: fix bad join order in NamedPattern.getVarDecl() Ideally the EDB itself should contain a direct reference from NamedPattern to VarDecl, not just a name, but oh well, this join order works fine. BEFORE: ``` [2023-06-08 11:40:01] Evaluated non-recursive predicate quick_eval#ff@60fe07kr in 6533ms (size: 91309). Evaluated relational algebra for predicate quick_eval#ff@60fe07kr with tuple counts: 1209062 ~3% {2} r1 = SCAN VarDecl#914e0d1e::Generated::VarDecl::getName#0#dispred#ff OUTPUT In.1, In.0 234687793 ~0% {2} r2 = JOIN r1 WITH NamedPattern#c3d26570::Generated::NamedPattern::getName#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1 19112791 ~0% {3} r3 = JOIN r2 WITH VarDecl#914e0d1e::Generated::VarDecl::getImmediateParentPattern#0#dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.0, Lhs.1 19112791 ~0% {3} r4 = JOIN r3 WITH Element#e67432df::Generated::Element::resolve#bf ON FIRST 1 OUTPUT Rhs.1, Lhs.2, Lhs.1 24647 ~0% {2} r5 = JOIN r4 WITH Element#d22cfd66::Element::getFullyUnresolved#bf ON FIRST 2 OUTPUT Lhs.1, Lhs.2 19112791 ~0% {3} r6 = JOIN r3 WITH Element#e67432df::Generated::Element::resolve#bf ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2 19112791 ~3% {3} r7 = JOIN r6 WITH Element#d22cfd66::Element::getFullyUnresolved#bf ON FIRST 1 OUTPUT Lhs.2, Rhs.1, Lhs.1 66662 ~4% {2} r8 = JOIN r7 WITH #Pattern#19b8cf65::Pattern::getImmediateEnclosingPattern#0#dispredPlus#bf ON FIRST 2 OUTPUT Lhs.0, Lhs.2 91309 ~2% {2} r9 = r5 UNION r8 return r9 ``` AFTER: ``` [2023-06-08 11:55:26] Evaluated non-recursive predicate quick_eval#ff@fe906afo in 26ms (size: 91309). Evaluated relational algebra for predicate quick_eval#ff@fe906afo with tuple counts: 92048 ~0% {3} r1 = SCAN NamedPattern#c3d26570::Generated::NamedPattern::getName#0#dispred#ff OUTPUT In.0, In.1, In.0 82893 ~0% {2} r2 = SCAN #Pattern#19b8cf65::Pattern::getImmediateEnclosingPattern#0#dispredPlus#fb#flipped OUTPUT In.1, In.0 66417 ~1% {3} r3 = JOIN r2 WITH NamedPattern#c3d26570::Generated::NamedPattern::getName#0#dispred#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.0 158465 ~0% {3} r4 = r1 UNION r3 94246 ~3% {3} r5 = JOIN r4 WITH VarDecl#914e0d1e::Generated::VarDecl::getImmediateParentPattern#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2 91309 ~2% {2} r6 = JOIN r5 WITH VarDecl#914e0d1e::Generated::VarDecl::getName#0#dispred#ff ON FIRST 2 OUTPUT Lhs.2, Lhs.0 return r6 ``` --- swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll index a9964f4370b..f55087f0f8e 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll @@ -19,8 +19,9 @@ class NamedPattern extends Generated::NamedPattern { * This will be the case as long as the variable is subsequently used. */ VarDecl getVarDecl() { - this.getImmediateEnclosingPattern*() = result.getParentPattern().getFullyUnresolved() and - result.getName() = this.getName() + this.getImmediateEnclosingPattern*() = result.getImmediateParentPattern() and + pragma[only_bind_out](pragma[only_bind_into](result).getName()) = + pragma[only_bind_out](pragma[only_bind_into](this).getName()) } override string toString() { result = this.getName() } From dc7a286948abf93a1233c63bcd3e34fb604b01aa Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 Jun 2023 11:29:04 +0100 Subject: [PATCH 417/739] Swift: Add lines of code to SummaryStats.ql. --- swift/ql/src/queries/Summary/SummaryStats.ql | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/swift/ql/src/queries/Summary/SummaryStats.ql b/swift/ql/src/queries/Summary/SummaryStats.ql index 444c4da2ca2..9174dd19aee 100644 --- a/swift/ql/src/queries/Summary/SummaryStats.ql +++ b/swift/ql/src/queries/Summary/SummaryStats.ql @@ -12,6 +12,15 @@ import codeql.swift.security.SensitiveExprs import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking +int linesOfCode() { + // approximate number of lines of code in the database + result = count(File f, int line | + exists(Location loc | + not loc instanceof UnknownLocation and loc.getFile() = f and loc.getStartLine() = line + ) + ) +} + /** * A taint configuration for tainted data reaching any node. */ @@ -37,6 +46,8 @@ float taintReach() { result = (taintedNodesCount() * 1000000.0) / count(DataFlow predicate statistic(string what, string value) { what = "Files" and value = count(File f).toString() or + what = "Lines of code" and value = linesOfCode().toString() + or what = "Expressions" and value = count(Expr e | not e.getFile() instanceof UnknownFile).toString() or what = "Local flow sources" and value = count(LocalFlowSource s).toString() From e0f16f46d2ca17ba21268e1b1a7cb8361a904d52 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 Jun 2023 11:35:08 +0100 Subject: [PATCH 418/739] Swift: Add compile errors / warnings to SummaryStats.ql. --- swift/ql/src/queries/Summary/SummaryStats.ql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swift/ql/src/queries/Summary/SummaryStats.ql b/swift/ql/src/queries/Summary/SummaryStats.ql index 9174dd19aee..73b80b7f147 100644 --- a/swift/ql/src/queries/Summary/SummaryStats.ql +++ b/swift/ql/src/queries/Summary/SummaryStats.ql @@ -48,6 +48,10 @@ predicate statistic(string what, string value) { or what = "Lines of code" and value = linesOfCode().toString() or + what = "Compiler errors" and value = count(CompilerError d).toString() + or + what = "Compiler warnings" and value = count(CompilerWarning d).toString() + or what = "Expressions" and value = count(Expr e | not e.getFile() instanceof UnknownFile).toString() or what = "Local flow sources" and value = count(LocalFlowSource s).toString() From c531b94594c782d1a0e67f4bb4839b03104c2d49 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 8 Jun 2023 11:59:10 +0100 Subject: [PATCH 419/739] Ruby: add a change note for rack redirect support --- ruby/ql/lib/change-notes/2023-06-08-rack-redirect.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2023-06-08-rack-redirect.md diff --git a/ruby/ql/lib/change-notes/2023-06-08-rack-redirect.md b/ruby/ql/lib/change-notes/2023-06-08-rack-redirect.md new file mode 100644 index 00000000000..09687fa95be --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-06-08-rack-redirect.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* HTTP redirect responses from Rack applications are now recognized as a potential sink for open redirect alerts. From 21b4f885a634ca921089e0f79e566a744594785b Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 8 Jun 2023 12:01:42 +0100 Subject: [PATCH 420/739] ruby: fix qldoc --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll index 2aceebffbcd..f9bd42c15b0 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll @@ -1295,6 +1295,7 @@ private predicate mimeTypeMatches(string ext, string mimeType) { * Provides modeling for the `Mime` component of the `Rack` library. */ module Mime { + /** A call to `Rack::Mime.mime_type`. This method maps file extensions to MIME types. */ class MimetypeCall extends DataFlow::CallNode { MimetypeCall() { this = API::getTopLevelMember("Rack").getMember("Mime").getAMethodCall("mime_type") From dabb4dd643b5cfc519487df289541dfd966c7bd8 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 8 Jun 2023 13:02:54 +0200 Subject: [PATCH 421/739] Java: Improve join-order for FunctionalInterface. --- java/ql/lib/semmle/code/java/Type.qll | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index f60fdcc8e5d..fcf31e3be0d 100644 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -987,6 +987,17 @@ private string getAPublicObjectMethodSignature() { ) } +pragma[nomagic] +private predicate interfaceInheritsOverridingNonAbstractMethod(Interface interface, Method m) { + interface.inherits(m) and + not m.isAbstract() and + m.overrides(_) +} + +bindingset[m] +pragma[inline_late] +private Method getAnOverridden(Method m) { m.overrides(result) } + private Method getAnAbstractMethod(Interface interface) { interface.inherits(result) and result.isAbstract() and @@ -995,9 +1006,8 @@ private Method getAnAbstractMethod(Interface interface) { // Make sure that there is no other non-abstract method // (e.g. `default`) which overrides the abstract one not exists(Method m | - interface.inherits(m) and - not m.isAbstract() and - m.overrides(result) + interfaceInheritsOverridingNonAbstractMethod(interface, m) and + result = getAnOverridden(m) ) } From a3ef5c69184ee9c501f2097a5f1e73e316c2ecbe Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 Jun 2023 11:35:18 +0100 Subject: [PATCH 422/739] Swift: QLDoc Diagnostics.qll. --- .../lib/codeql/swift/elements/Diagnostics.qll | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/swift/ql/lib/codeql/swift/elements/Diagnostics.qll b/swift/ql/lib/codeql/swift/elements/Diagnostics.qll index aec6d2be8f4..a0ec9995355 100644 --- a/swift/ql/lib/codeql/swift/elements/Diagnostics.qll +++ b/swift/ql/lib/codeql/swift/elements/Diagnostics.qll @@ -1,8 +1,14 @@ private import codeql.swift.generated.Diagnostics +/** + * A compiler-generated error, warning, note or remark. + */ class Diagnostics extends Generated::Diagnostics { override string toString() { result = this.getSeverity() + ": " + this.getText() } + /** + * Gets a string representing the severity of this compiler diagnostic. + */ string getSeverity() { this.getKind() = 1 and result = "error" or @@ -14,18 +20,30 @@ class Diagnostics extends Generated::Diagnostics { } } +/** + * A compiler error message. + */ class CompilerError extends Diagnostics { CompilerError() { this.getSeverity() = "error" } } +/** + * A compiler-generated warning. + */ class CompilerWarning extends Diagnostics { CompilerWarning() { this.getSeverity() = "warning" } } +/** + * A compiler-generated note (typically attached to an error or warning). + */ class CompilerNote extends Diagnostics { CompilerNote() { this.getSeverity() = "note" } } +/** + * A compiler-generated remark (milder than a warning, this does not indicate an issue). + */ class CompilerRemark extends Diagnostics { CompilerRemark() { this.getSeverity() = "remark" } } From 5727d49cce2b8729678becaff8835c12ace3e7f7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 8 Jun 2023 11:44:39 +0100 Subject: [PATCH 423/739] Swift: Take out common code for lines of code. --- swift/ql/lib/codeql/swift/elements/File.qll | 15 +++++++++++++++ .../src/diagnostics/SuccessfullyExtractedLines.ql | 6 +----- swift/ql/src/queries/Summary/SummaryStats.ql | 11 +---------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/File.qll b/swift/ql/lib/codeql/swift/elements/File.qll index 1c47cd163c2..b6da771ef60 100644 --- a/swift/ql/lib/codeql/swift/elements/File.qll +++ b/swift/ql/lib/codeql/swift/elements/File.qll @@ -1,4 +1,6 @@ private import codeql.swift.generated.File +private import codeql.swift.elements.Location +private import codeql.swift.elements.UnknownLocation class File extends Generated::File { /** toString */ @@ -17,4 +19,17 @@ class File extends Generated::File { string getBaseName() { result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1) } + + /** + * Gets the number of lines containing code in this file. This value + * is approximate. + */ + int getNumberOfLinesOfCode() { + result = + count(int line | + exists(Location loc | + not loc instanceof UnknownLocation and loc.getFile() = this and loc.getStartLine() = line + ) + ) + } } diff --git a/swift/ql/src/diagnostics/SuccessfullyExtractedLines.ql b/swift/ql/src/diagnostics/SuccessfullyExtractedLines.ql index 59b1d5bc8bc..373b6c4bd0f 100644 --- a/swift/ql/src/diagnostics/SuccessfullyExtractedLines.ql +++ b/swift/ql/src/diagnostics/SuccessfullyExtractedLines.ql @@ -8,8 +8,4 @@ import swift -select count(File f, int line | - exists(Location loc | - not loc instanceof UnknownLocation and loc.getFile() = f and loc.getStartLine() = line - ) - ) +select sum(File f | | f.getNumberOfLinesOfCode()) diff --git a/swift/ql/src/queries/Summary/SummaryStats.ql b/swift/ql/src/queries/Summary/SummaryStats.ql index 73b80b7f147..30122e666e3 100644 --- a/swift/ql/src/queries/Summary/SummaryStats.ql +++ b/swift/ql/src/queries/Summary/SummaryStats.ql @@ -12,15 +12,6 @@ import codeql.swift.security.SensitiveExprs import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking -int linesOfCode() { - // approximate number of lines of code in the database - result = count(File f, int line | - exists(Location loc | - not loc instanceof UnknownLocation and loc.getFile() = f and loc.getStartLine() = line - ) - ) -} - /** * A taint configuration for tainted data reaching any node. */ @@ -46,7 +37,7 @@ float taintReach() { result = (taintedNodesCount() * 1000000.0) / count(DataFlow predicate statistic(string what, string value) { what = "Files" and value = count(File f).toString() or - what = "Lines of code" and value = linesOfCode().toString() + what = "Lines of code" and value = sum(File f | | f.getNumberOfLinesOfCode()).toString() or what = "Compiler errors" and value = count(CompilerError d).toString() or From b4620042a5c356f84c726e9c68edb65d294e61cb Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Thu, 8 Jun 2023 12:09:22 +0100 Subject: [PATCH 424/739] Ruby: fix use of deprecated predicate --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index eb8b283fa16..5ea8ad38f29 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -14,7 +14,7 @@ private class CallMethodNode extends DataFlow::MethodNode { private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, CallMethodNode call) { t.start() and - result = call.getAReturningNode() + result = call.getAReturnNode() or exists(TypeBackTracker t2 | result = trackRackResponse(t2, call).backtrack(t2, t)) } From 57ae1e9ff790c6ae6710624300e5e20619f4c59e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 8 Jun 2023 12:49:08 +0100 Subject: [PATCH 425/739] C++: Add a testcase that started to fail in #13326. --- .../dataflow/taint-tests/localTaint.expected | 7 +++++++ cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 907cccd197b..f6a7625b57a 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -6584,6 +6584,13 @@ | taint.cpp:691:18:691:18 | s [post update] | taint.cpp:695:7:695:7 | s | | | taint.cpp:691:20:691:20 | ref arg x | taint.cpp:694:9:694:9 | x | | | taint.cpp:694:7:694:7 | s [post update] | taint.cpp:695:7:695:7 | s | | +| taint.cpp:700:13:700:18 | call to source | taint.cpp:702:11:702:11 | s | | +| taint.cpp:701:9:701:9 | p | taint.cpp:702:4:702:4 | p | | +| taint.cpp:702:4:702:4 | p | taint.cpp:702:4:702:6 | ... ++ | | +| taint.cpp:702:4:702:6 | ... ++ | taint.cpp:702:3:702:6 | * ... | TAINT | +| taint.cpp:702:4:702:6 | ... ++ | taint.cpp:703:8:703:8 | p | TAINT | +| taint.cpp:702:10:702:11 | * ... | taint.cpp:702:3:702:11 | ... = ... | | +| taint.cpp:702:11:702:11 | s | taint.cpp:702:10:702:11 | * ... | TAINT | | vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | | | vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 9806ddb395e..fa6074e44f6 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -693,4 +693,13 @@ void test_argument_source_field_to_obj() { sink(s); // $ SPURIOUS: ast,ir sink(s.x); // $ ast,ir sink(s.y); // clean +} + +namespace strings { + void test_write_to_read_then_incr_then_deref() { + char* s = source(); + char* p; + *p++ = *s; + sink(p); // $ ast ir + } } \ No newline at end of file From afb1129f2790447bd5eec24e2bf24025ddfeca17 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 8 Jun 2023 12:50:05 +0100 Subject: [PATCH 426/739] C++: Ensure that postfix crement operations are handled properly in dataflow SSA. --- .../cpp/ir/dataflow/internal/SsaInternals.qll | 20 ++++++++- .../dataflow/internal/ssa0/SsaInternals.qll | 41 ++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 551653c3aca..0cd152e2473 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -364,7 +364,25 @@ abstract private class OperandBasedUse extends UseImpl { OperandBasedUse() { any() } final override predicate hasIndexInBlock(IRBlock block, int index) { - operand.getUse() = block.getInstruction(index) + // See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this + // predicate's implementation. + exists(BaseSourceVariableInstruction base | base = this.getBase() | + if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand() + then + exists(Operand op, int indirectionIndex, int indirection | + indirectionIndex = this.getIndirectionIndex() and + indirection = this.getIndirection() and + op = + min(Operand cand, int i | + isUse(_, cand, base, indirection, indirectionIndex) and + block.getInstruction(i) = cand.getUse() + | + cand order by i + ) and + block.getInstruction(index) = op.getUse() + ) + else operand.getUse() = block.getInstruction(index) + ) } final Operand getOperand() { result = operand } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll index aa6a43a2580..38f9bbeec8e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll @@ -122,7 +122,46 @@ abstract private class OperandBasedUse extends UseImpl { override string toString() { result = operand.toString() } final override predicate hasIndexInBlock(IRBlock block, int index) { - operand.getUse() = block.getInstruction(index) + // Ideally, this would just be implemented as: + // ``` + // operand.getUse() = block.getInstruction(index) + // ``` + // but because the IR generated for a snippet such as + // ``` + // int x = *p++; + // ``` + // looks like + // ``` + // r1(glval<int>) = VariableAddress[x] : + // r2(glval<int *>) = VariableAddress[p] : + // r3(int *) = Load[p] : &:r2, m1 + // r4(int) = Constant[1] : + // r5(int *) = PointerAdd[4] : r3, r4 + // m3(int *) = Store[p] : &:r2, r5 + // r6(int *) = CopyValue : r3 + // r7(int) = Load[?] : &:r6, ~m2 + // m2(int) = Store[x] : &:r1, r7 + // ``` + // we need to ensure that the `r3` operand of the `CopyValue` instruction isn't seen as a fresh use + // of `p` that happens after the increment. So if the base instruction of this use comes from a + // post-fix crement operation we set the index of the SSA use that wraps the `r3` operand at the + // `CopyValue` instruction to be the same index as the `r3` operand at the `PointerAdd` instruction. + // This ensures that the SSA library doesn't create flow from the `PointerAdd` to `r6`. + exists(BaseSourceVariableInstruction base | base = this.getBase() | + if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand() + then + exists(Operand op | + op = + min(Operand cand, int i | + isUse(_, cand, base, _, _) and + block.getInstruction(i) = cand.getUse() + | + cand order by i + ) and + block.getInstruction(index) = op.getUse() + ) + else operand.getUse() = block.getInstruction(index) + ) } final override Cpp::Location getLocation() { result = operand.getLocation() } From a357eeedacabac1fe3ac5b2895c61e500e158c42 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 8 Jun 2023 12:50:16 +0100 Subject: [PATCH 427/739] C++: Accept test changes. --- .../CWE-193/pointer-deref/InvalidPointerDeref.expected | 10 ---------- .../Security/CWE/CWE-193/pointer-deref/test.cpp | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 1bff2ec77f7..0d92ae6db5a 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -664,11 +664,6 @@ edges | test.cpp:338:8:338:15 | * ... | test.cpp:342:8:342:17 | * ... | | test.cpp:341:8:341:17 | * ... | test.cpp:342:8:342:17 | * ... | | test.cpp:347:14:347:27 | new[] | test.cpp:348:15:348:16 | xs | -| test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ | -| test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ | -| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:15:350:19 | Load: * ... | -| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:16:350:19 | ... ++ | -| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:16:350:19 | ... ++ | | test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:16 | xs | | test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... | | test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... | @@ -1057,10 +1052,6 @@ nodes | test.cpp:342:8:342:17 | * ... | semmle.label | * ... | | test.cpp:347:14:347:27 | new[] | semmle.label | new[] | | test.cpp:348:15:348:16 | xs | semmle.label | xs | -| test.cpp:350:15:350:19 | Load: * ... | semmle.label | Load: * ... | -| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ | -| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ | -| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ | | test.cpp:355:14:355:27 | new[] | semmle.label | new[] | | test.cpp:356:15:356:16 | xs | semmle.label | xs | | test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... | @@ -1118,7 +1109,6 @@ subpaths | test.cpp:264:13:264:14 | Load: * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len | | test.cpp:274:5:274:10 | Store: ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len | | test.cpp:308:5:308:29 | Store: ... = ... | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:304:15:304:26 | new[] | new[] | test.cpp:308:8:308:10 | ... + ... | ... + ... | -| test.cpp:350:15:350:19 | Load: * ... | test.cpp:347:14:347:27 | new[] | test.cpp:350:15:350:19 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:347:14:347:27 | new[] | new[] | test.cpp:348:20:348:23 | size | size | | test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:372:15:372:16 | Load: * ... | test.cpp:363:14:363:27 | new[] | test.cpp:372:15:372:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:363:14:363:27 | new[] | new[] | test.cpp:365:19:365:22 | size | size | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index 7269af0153f..05b0f1c07ca 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -347,7 +347,7 @@ void test24(unsigned size) { char *xs = new char[size]; char *end = xs + size; if (xs < end) { - int val = *xs++; // GOOD [FALSE POSITIVE] + int val = *xs++; // GOOD } } From d6741f655d085175262da40b041b78a90969f788 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Thu, 8 Jun 2023 14:01:47 +0200 Subject: [PATCH 428/739] Ruby: restrict ORM tracking to calls --- ruby/ql/lib/codeql/ruby/security/XSS.qll | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/security/XSS.qll b/ruby/ql/lib/codeql/ruby/security/XSS.qll index 8196f508b55..f84ae0a52c0 100644 --- a/ruby/ql/lib/codeql/ruby/security/XSS.qll +++ b/ruby/ql/lib/codeql/ruby/security/XSS.qll @@ -285,7 +285,13 @@ private module OrmTracking { * A data flow configuration to track flow from finder calls to field accesses. */ private module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof OrmInstantiation } + predicate isSource(DataFlow::Node source) { + // We currently only use ORM instances that come from a call site, so restrict the sources + // to calls. This works around a performance issue that would arise from using 'self' as a source + // in ActiveRecord models. Over time, library models should stop relying on OrmInstantiation and instead + // use API graphs or type-tracking the same way we track other types. + source instanceof OrmInstantiation and source instanceof DataFlow::CallNode + } // Select any call receiver and narrow down later predicate isSink(DataFlow::Node sink) { sink = any(DataFlow::CallNode c).getReceiver() } @@ -293,6 +299,8 @@ private module OrmTracking { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { Shared::isAdditionalXssFlowStep(node1, node2) } + + predicate isBarrierIn(DataFlow::Node node) { node instanceof DataFlow::SelfParameterNode } } import DataFlow::Global<Config> From 5a2ac1b5ca9999d2865080f4dff8c35273b00cbe Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 8 Jun 2023 14:04:57 +0200 Subject: [PATCH 429/739] Java: Add more negation context to reduce string ops and improve perf. --- .../code/java/security/LogInjection.qll | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/LogInjection.qll b/java/ql/lib/semmle/code/java/security/LogInjection.qll index 2314d807a60..7fb85f6d8f1 100644 --- a/java/ql/lib/semmle/code/java/security/LogInjection.qll +++ b/java/ql/lib/semmle/code/java/security/LogInjection.qll @@ -46,16 +46,33 @@ private class LineBreaksLogInjectionSanitizer extends LogInjectionSanitizer { } } +private predicate stringMethodAccess( + MethodAccess ma, CompileTimeConstantExpr arg0, CompileTimeConstantExpr arg1 +) { + ma.getMethod().getDeclaringType() instanceof TypeString and + arg0 = ma.getArgument(0) and + arg1 = ma.getArgument(1) +} + +private predicate stringMethodArgument(CompileTimeConstantExpr arg) { + stringMethodAccess(_, arg, _) or stringMethodAccess(_, _, arg) +} + +bindingset[match] +pragma[inline_late] +private predicate stringMethodArgumentValueMatches(CompileTimeConstantExpr const, string match) { + stringMethodArgument(const) and + const.getStringValue().matches(match) +} + /** * Holds if the return value of `ma` is sanitized against log injection attacks * by removing line breaks from it. */ private predicate logInjectionSanitizer(MethodAccess ma) { exists(CompileTimeConstantExpr target, CompileTimeConstantExpr replacement | - ma.getMethod().getDeclaringType() instanceof TypeString and - target = ma.getArgument(0) and - replacement = ma.getArgument(1) and - not replacement.getStringValue().matches(["%\n%", "%\r%"]) + stringMethodAccess(ma, target, replacement) and + not stringMethodArgumentValueMatches(replacement, ["%\n%", "%\r%"]) | ma.getMethod().hasName("replace") and not replacement.getIntValue() = [10, 13] and @@ -68,7 +85,7 @@ private predicate logInjectionSanitizer(MethodAccess ma) { ( // Replace anything not in an allow list target.getStringValue().matches("[^%]") and - not target.getStringValue().matches("%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%") + not stringMethodArgumentValueMatches(target, "%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%") or // Replace line breaks target.getStringValue() = ["\n", "\r", "\\n", "\\r", "\\R"] From 5952a729df3e2724e2209e3fa005c1d3a6d6d032 Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Thu, 8 Jun 2023 13:10:43 +0100 Subject: [PATCH 430/739] Build: Bump build mode to C++20. --- .bazelrc | 2 +- swift/.clang-format | 2 +- swift/extractor/infra/file/BUILD.bazel | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bazelrc b/.bazelrc index a304a7b0e1a..e0ab5a34335 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,3 +1,3 @@ -build --repo_env=CC=clang --repo_env=CXX=clang++ --cxxopt="-std=c++17" +build --repo_env=CC=clang --repo_env=CXX=clang++ --cxxopt="-std=c++20" try-import %workspace%/local.bazelrc diff --git a/swift/.clang-format b/swift/.clang-format index 96d2febc1c2..ca0a3afd986 100644 --- a/swift/.clang-format +++ b/swift/.clang-format @@ -4,4 +4,4 @@ IndentWidth: 2 SortIncludes: false AllowShortIfStatementsOnASingleLine: WithoutElse AlwaysBreakBeforeMultilineStrings: false -Standard: c++17 +Standard: c++20 diff --git a/swift/extractor/infra/file/BUILD.bazel b/swift/extractor/infra/file/BUILD.bazel index 65cfea33995..d14a28ce622 100644 --- a/swift/extractor/infra/file/BUILD.bazel +++ b/swift/extractor/infra/file/BUILD.bazel @@ -24,7 +24,7 @@ genrule( # see if https://cplusplus.github.io/LWG/issue3657 is fixed with the current compiler or not # if fixed, PathHash.h.workaround will not compile cmd = "\n".join([ - "if clang -c -x c++ -std=c++17 -Wno-pragma-once-outside-header \\", + "if clang -c -x c++ -std=c++20 -Wno-pragma-once-outside-header \\", " $(rootpath PathHash.h.workaround) -o /dev/null &> /dev/null; then", " cp $(rootpath PathHash.h.workaround) $@", "else", From 838130ca3a50f4d6a321fb4566b44d63c1e6e8f6 Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Thu, 8 Jun 2023 13:11:14 +0100 Subject: [PATCH 431/739] Swift: Fix some C++20 todos. --- swift/extractor/trap/TrapLabel.h | 4 ++-- swift/logging/SwiftLogging.h | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/swift/extractor/trap/TrapLabel.h b/swift/extractor/trap/TrapLabel.h index fe8b18e127e..e8b374faff0 100644 --- a/swift/extractor/trap/TrapLabel.h +++ b/swift/extractor/trap/TrapLabel.h @@ -1,11 +1,11 @@ #pragma once +#include <bit> #include <cassert> #include <iomanip> #include <iostream> #include <string> #include <vector> -#include "absl/numeric/bits.h" #include <binlog/binlog.hpp> #include <cmath> #include <charconv> @@ -52,7 +52,7 @@ class UntypedTrapLabel { size_t strSize() const { if (id_ == 0) return 2; // #0 // Number of hex digits is ceil(bit_width(id) / 4), but C++ integer division can only do floor. - return /* # */ 1 + /* hex digits */ 1 + (absl::bit_width(id_) - 1) / 4; + return /* # */ 1 + /* hex digits */ 1 + (std::bit_width(id_) - 1) / 4; } friend bool operator!=(UntypedTrapLabel lhs, UntypedTrapLabel rhs) { return lhs.id_ != rhs.id_; } diff --git a/swift/logging/SwiftLogging.h b/swift/logging/SwiftLogging.h index ce0d4cd0c9e..a577863aced 100644 --- a/swift/logging/SwiftLogging.h +++ b/swift/logging/SwiftLogging.h @@ -55,15 +55,14 @@ #define DIAGNOSE_CRITICAL(ID, ...) DIAGNOSE_WITH_LEVEL(critical, ID, __VA_ARGS__) #define CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX "[{}] " -// TODO(C++20) replace non-standard , ##__VA_ARGS__ with __VA_OPT__(,) __VA_ARGS__ #define DIAGNOSE_WITH_LEVEL(LEVEL, ID, FORMAT, ...) \ do { \ auto _now = ::binlog::clockNow(); \ const ::codeql::SwiftDiagnostic& _id = ID; \ ::codeql::Log::diagnose(_id, std::chrono::nanoseconds{_now}, \ - fmt::format(FORMAT, ##__VA_ARGS__)); \ + fmt::format(FORMAT __VA_OPT__(, ) __VA_ARGS__)); \ LOG_WITH_LEVEL_AND_TIME(LEVEL, _now, CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX FORMAT, \ - _id.abbreviation(), ##__VA_ARGS__); \ + _id.abbreviation() __VA_OPT__(, ) __VA_ARGS__); \ } while (false) // avoid calling into binlog's original macros From 5450585c1c3d8f151fe408d43db8c5e806d79fe3 Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Thu, 8 Jun 2023 13:11:14 +0100 Subject: [PATCH 432/739] Swift: Remove SwiftDiagnostic constructor (C++20 todo). --- swift/logging/SwiftDiagnostics.h | 30 +++++++------------ .../IncompatibleOs.cpp | 29 +++++++++--------- swift/xcode-autobuilder/XcodeBuildRunner.cpp | 7 +++-- swift/xcode-autobuilder/xcode-autobuilder.cpp | 23 +++++++------- 4 files changed, 41 insertions(+), 48 deletions(-) diff --git a/swift/logging/SwiftDiagnostics.h b/swift/logging/SwiftDiagnostics.h index eb54421fd2b..e945e11b8e6 100644 --- a/swift/logging/SwiftDiagnostics.h +++ b/swift/logging/SwiftDiagnostics.h @@ -62,17 +62,6 @@ struct SwiftDiagnostic { std::optional<SwiftDiagnosticsLocation> location{}; - // optional arguments can be either Severity or Visibility to set the corresponding field. - // TODO(C++20) this constructor won't really be necessary anymore with designated initializers - template <typename... OptionalArgs> - constexpr SwiftDiagnostic(std::string_view id, - std::string_view name, - std::string_view action, - OptionalArgs... optionalArgs) - : id{id}, name{name}, action{action} { - (setOptionalArg(optionalArgs), ...); - } - // create a JSON diagnostics for this source with the given `timestamp` and Markdown `message` // A markdownMessage is emitted that includes both the message and the action to take. The id is // used to construct the source id in the form `swift/<prog name>/<id>` @@ -116,14 +105,15 @@ inline constexpr SwiftDiagnostic::Visibility operator&(SwiftDiagnostic::Visibili } constexpr SwiftDiagnostic internalError{ - "internal-error", - "Internal error", - "Some or all of the Swift analysis may have failed.\n" - "\n" - "If the error persists, contact support, quoting the error message and describing what " - "happened, or [open an issue in our open source repository][1].\n" - "\n" - "[1]: https://github.com/github/codeql/issues/new?labels=bug&template=ql---general.md", - SwiftDiagnostic::Severity::warning, + .id = "internal-error", + .name = "Internal error", + .action = + "Some or all of the Swift analysis may have failed.\n" + "\n" + "If the error persists, contact support, quoting the error message and describing what " + "happened, or [open an issue in our open source repository][1].\n" + "\n" + "[1]: https://github.com/github/codeql/issues/new?labels=bug&template=ql---general.md", + .severity = SwiftDiagnostic::Severity::warning, }; } // namespace codeql diff --git a/swift/tools/autobuilder-diagnostics/IncompatibleOs.cpp b/swift/tools/autobuilder-diagnostics/IncompatibleOs.cpp index 2920a00f955..0bab7afbf69 100644 --- a/swift/tools/autobuilder-diagnostics/IncompatibleOs.cpp +++ b/swift/tools/autobuilder-diagnostics/IncompatibleOs.cpp @@ -9,20 +9,21 @@ const std::string_view codeql::programName = "autobuilder"; constexpr codeql::SwiftDiagnostic incompatibleOs{ - "incompatible-os", - "Incompatible operating system (expected macOS)", - "[Change the Actions runner][1] to run on macOS.\n" - "\n" - "You may be able to run analysis on Linux by setting up a [manual build command][2].\n" - "\n" - "[1]: " - "https://docs.github.com/en/actions/using-workflows/" - "workflow-syntax-for-github-actions#jobsjob_idruns-on\n" - "[2]: " - "https://docs.github.com/en/enterprise-server/code-security/code-scanning/" - "automatically-scanning-your-code-for-vulnerabilities-and-errors/" - "configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-" - "language", + .id = "incompatible-os", + .name = "Incompatible operating system (expected macOS)", + .action = + "[Change the Actions runner][1] to run on macOS.\n" + "\n" + "You may be able to run analysis on Linux by setting up a [manual build command][2].\n" + "\n" + "[1]: " + "https://docs.github.com/en/actions/using-workflows/" + "workflow-syntax-for-github-actions#jobsjob_idruns-on\n" + "[2]: " + "https://docs.github.com/en/enterprise-server/code-security/code-scanning/" + "automatically-scanning-your-code-for-vulnerabilities-and-errors/" + "configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-" + "language", }; static codeql::Logger& logger() { diff --git a/swift/xcode-autobuilder/XcodeBuildRunner.cpp b/swift/xcode-autobuilder/XcodeBuildRunner.cpp index eaf5e7c0355..567f726ad89 100644 --- a/swift/xcode-autobuilder/XcodeBuildRunner.cpp +++ b/swift/xcode-autobuilder/XcodeBuildRunner.cpp @@ -9,9 +9,10 @@ #include "swift/xcode-autobuilder/CustomizingBuildLink.h" constexpr codeql::SwiftDiagnostic buildCommandFailed{ - "build-command-failed", "Detected build command failed", - "Set up a [manual build command][1] or [check the logs of the autobuild step][2].\n" - "\n[1]: " MANUAL_BUILD_COMMAND_HELP_LINK "\n[2]: " CHECK_LOGS_HELP_LINK}; + .id = "build-command-failed", + .name = "Detected build command failed", + .action = "Set up a [manual build command][1] or [check the logs of the autobuild step][2].\n" + "\n[1]: " MANUAL_BUILD_COMMAND_HELP_LINK "\n[2]: " CHECK_LOGS_HELP_LINK}; static codeql::Logger& logger() { static codeql::Logger ret{"build"}; diff --git a/swift/xcode-autobuilder/xcode-autobuilder.cpp b/swift/xcode-autobuilder/xcode-autobuilder.cpp index 4cc234de66b..fa10a674edd 100644 --- a/swift/xcode-autobuilder/xcode-autobuilder.cpp +++ b/swift/xcode-autobuilder/xcode-autobuilder.cpp @@ -13,21 +13,22 @@ static constexpr std::string_view unknownType = "<unknown_target_type>"; const std::string_view codeql::programName = "autobuilder"; -constexpr codeql::SwiftDiagnostic noProjectFound{"no-project-found", - "No Xcode project or workspace found", - "Set up a [manual build command][1].\n" - "\n[1]: " MANUAL_BUILD_COMMAND_HELP_LINK}; +constexpr codeql::SwiftDiagnostic noProjectFound{ + .id = "no-project-found", + .name = "No Xcode project or workspace found", + .action = "Set up a [manual build command][1].\n\n[1]: " MANUAL_BUILD_COMMAND_HELP_LINK}; constexpr codeql::SwiftDiagnostic noSwiftTarget{ - "no-swift-target", "No Swift compilation target found", - "To analyze a custom set of source files, set up a [manual build command][1].\n" - "\n[1]: " MANUAL_BUILD_COMMAND_HELP_LINK}; + .id = "no-swift-target", + .name = "No Swift compilation target found", + .action = "To analyze a custom set of source files, set up a [manual build " + "command][1].\n\n[1]: " MANUAL_BUILD_COMMAND_HELP_LINK}; constexpr codeql::SwiftDiagnostic spmNotSupported{ - "spm-not-supported", "Swift Package Manager is not supported", - "Swift Package Manager builds are not currently supported by `autobuild`. Set up a [manual " - "build command][1].\n" - "\n[1]: " MANUAL_BUILD_COMMAND_HELP_LINK}; + .id = "spm-not-supported", + .name = "Swift Package Manager is not supported", + .action = "Swift Package Manager builds are not currently supported by `autobuild`. Set up a " + "[manual build command][1].\n\n[1]: " MANUAL_BUILD_COMMAND_HELP_LINK}; static codeql::Logger& logger() { static codeql::Logger ret{"main"}; From 4608481d7b9e0f819a4e04675f9a9e5347209aa1 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Thu, 8 Jun 2023 14:53:09 +0200 Subject: [PATCH 433/739] Java: Fix more problems in the Gson models Found during type strengthening work by @aschackmull --- java/ql/lib/ext/com.google.gson.model.yml | 4 ++-- .../library-tests/frameworks/gson/Test.java | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/java/ql/lib/ext/com.google.gson.model.yml b/java/ql/lib/ext/com.google.gson.model.yml index 7b41b57083a..abc3693ae00 100644 --- a/java/ql/lib/ext/com.google.gson.model.yml +++ b/java/ql/lib/ext/com.google.gson.model.yml @@ -38,11 +38,11 @@ extensions: - ["com.google.gson", "JsonObject", True, "add", "", "", "Argument[0]", "Argument[this].MapKey", "value", "manual"] - ["com.google.gson", "JsonObject", True, "add", "", "", "Argument[1]", "Argument[this].MapValue", "value", "manual"] - ["com.google.gson", "JsonObject", True, "addProperty", "(String,String)", "", "Argument[0]", "Argument[this].MapKey", "value", "manual"] - - ["com.google.gson", "JsonObject", True, "addProperty", "(String,String)", "", "Argument[1]", "Argument[this].MapValue", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "addProperty", "(String,String)", "", "Argument[1]", "Argument[this].MapValue", "taint", "manual"] - ["com.google.gson", "JsonObject", True, "asMap", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["com.google.gson", "JsonObject", True, "asMap", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"] - ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this].MapKey", "ReturnValue.Element.MapKey", "value", "manual"] - - ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this].MapKey", "ReturnValue.Element.MapValue", "value", "manual"] + - ["com.google.gson", "JsonObject", True, "entrySet", "", "", "Argument[this].MapValue", "ReturnValue.Element.MapValue", "value", "manual"] - ["com.google.gson", "JsonObject", True, "get", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"] - ["com.google.gson", "JsonObject", True, "keySet", "", "", "Argument[this].MapKey", "ReturnValue.Element", "value", "manual"] - ["com.google.gson", "JsonPrimitive", True, "JsonPrimitive", "(Character)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/java/ql/test/library-tests/frameworks/gson/Test.java b/java/ql/test/library-tests/frameworks/gson/Test.java index 6fa1fd2a1e5..b1dc845f091 100644 --- a/java/ql/test/library-tests/frameworks/gson/Test.java +++ b/java/ql/test/library-tests/frameworks/gson/Test.java @@ -407,51 +407,51 @@ public class Test { sink(getMapKeyDefault(out)); // $ hasValueFlow } { - // "com.google.gson;JsonObject;true;addProperty;(String,String);;Argument[1];Argument[this].MapValue;value;manual" + // "com.google.gson;JsonObject;true;addProperty;(String,String);;Argument[1];Argument[this].MapValue;taint;manual" JsonObject out = null; String in = (String)source(); out.addProperty((String)null, in); - sink(getMapValueDefault(out)); // $ hasValueFlow + sink(getMapValueDefault(out)); // $ hasTaintFlow } { // "com.google.gson;JsonObject;true;asMap;;;Argument[this].MapKey;ReturnValue.MapKey;value;manual" Map out = null; - JsonObject in = (JsonObject)newWithMapKeyDefault((String) source()); + JsonObject in = newWithMapKeyDefault((String) source()); out = in.asMap(); sink(getMapKey(out)); // $ hasValueFlow } { // "com.google.gson;JsonObject;true;asMap;;;Argument[this].MapValue;ReturnValue.MapValue;value;manual" Map out = null; - JsonObject in = (JsonObject)newWithMapValueDefault((JsonElement) source()); + JsonObject in = newWithMapValueDefault((JsonElement) source()); out = in.asMap(); sink(getMapValue(out)); // $ hasValueFlow } { // "com.google.gson;JsonObject;true;entrySet;;;Argument[this].MapKey;ReturnValue.Element.MapKey;value;manual" Set<Map.Entry<String,JsonElement>> out = null; - JsonObject in = (JsonObject)newWithMapKeyDefault((String) source()); + JsonObject in = newWithMapKeyDefault((String) source()); out = in.entrySet(); sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow } { - // "com.google.gson;JsonObject;true;entrySet;;;Argument[this].MapKey;ReturnValue.Element.MapValue;value;manual" + // "com.google.gson;JsonObject;true;entrySet;;;Argument[this].MapValue;ReturnValue.Element.MapValue;value;manual" Set<Map.Entry<String,JsonElement>> out = null; - JsonObject in = (JsonObject) newWithMapKeyDefault((String) source()); + JsonObject in = newWithMapValueDefault((JsonElement) source()); out = in.entrySet(); sink(getMapValueDefault(getElement(out))); // $ hasValueFlow } { // "com.google.gson;JsonObject;true;get;;;Argument[this].MapValue;ReturnValue;value;manual" JsonElement out = null; - JsonObject in = (JsonObject)newWithMapValueDefault((JsonElement) source()); + JsonObject in = newWithMapValueDefault((JsonElement) source()); out = in.get(null); sink(out); // $ hasValueFlow } { // "com.google.gson;JsonObject;true;keySet;;;Argument[this].MapKey;ReturnValue.Element;value;manual" Set out = null; - JsonObject in = (JsonObject)newWithMapKeyDefault((String) source()); + JsonObject in = newWithMapKeyDefault((String) source()); out = in.keySet(); sink(getElement(out)); // $ hasValueFlow } From 74a9d9fa3746210cb90b01c70eb9bc20d4acb8b8 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Thu, 8 Jun 2023 15:29:36 +0200 Subject: [PATCH 434/739] Revert "Ruby: update tree-sitter-ruby" --- ruby/extractor/Cargo.lock | Bin 31065 -> 31065 bytes ruby/extractor/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/extractor/Cargo.lock b/ruby/extractor/Cargo.lock index f048f2d7725d8d6e8b86e41a63b538afe657ba31..85c546b9b96e189aae02de3062127274df104d7b 100644 GIT binary patch delta 100 zcmccliSgzq#tkc?0*wsJlFbdw%?-^=jLnUbO)bsR(h@CF6BARCEKQ6}lZ`AaO$?3A SOq7XLIQgQe*k=A{FF61&_#I6E delta 99 zcmccliSgzq#tkc?0?bX)Qc_J*P1BN$l9Eg<%`FlWQ&Y_?EKLn9EK-vUEiKc`(-M=@ S43vpfIQgJ}_-6iSFF63U^dL9@ diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index 6857162af5e..133233f2f14 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" [dependencies] tree-sitter = "0.20" tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "203f7bd3c1bbfbd98fc19add4b8fcb213c059205" } -tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "74fde5e5fb2bb5978aaee7895188eb199f7facf0" } +tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "206c7077164372c596ffa8eaadb9435c28941364" } clap = { version = "4.2", features = ["derive"] } tracing = "0.1" tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } From 9ec09000e5026d790d27381ad98032d05331a4c6 Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Thu, 8 Jun 2023 13:11:14 +0100 Subject: [PATCH 435/739] Swift: Remove no longer needed code. --- swift/extractor/trap/BUILD.bazel | 1 - swift/logging/SwiftDiagnostics.h | 7 ------- 2 files changed, 8 deletions(-) diff --git a/swift/extractor/trap/BUILD.bazel b/swift/extractor/trap/BUILD.bazel index f156aa9c984..f68e0551d64 100644 --- a/swift/extractor/trap/BUILD.bazel +++ b/swift/extractor/trap/BUILD.bazel @@ -53,6 +53,5 @@ swift_cc_library( deps = [ "//swift/extractor/infra/file", "//swift/logging", - "@absl//absl/numeric:bits", ], ) diff --git a/swift/logging/SwiftDiagnostics.h b/swift/logging/SwiftDiagnostics.h index e945e11b8e6..ecec68793aa 100644 --- a/swift/logging/SwiftDiagnostics.h +++ b/swift/logging/SwiftDiagnostics.h @@ -83,13 +83,6 @@ struct SwiftDiagnostic { private: bool has(Visibility v) const; - - constexpr void setOptionalArg(Visibility v) { visibility = v; } - constexpr void setOptionalArg(Severity s) { severity = s; } - - // intentionally left undefined - template <typename T> - constexpr void setOptionalArg(T); }; inline constexpr SwiftDiagnostic::Visibility operator|(SwiftDiagnostic::Visibility lhs, From 8401793755d6a6bfcb14958ee5c51ff27dab5088 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Thu, 8 Jun 2023 15:57:38 +0200 Subject: [PATCH 436/739] Run "Check framework coverage changes" workflow when models-as-data files change --- .github/workflows/csv-coverage-pr-artifacts.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/csv-coverage-pr-artifacts.yml b/.github/workflows/csv-coverage-pr-artifacts.yml index 19ad488a3ab..b560d98a79d 100644 --- a/.github/workflows/csv-coverage-pr-artifacts.yml +++ b/.github/workflows/csv-coverage-pr-artifacts.yml @@ -10,6 +10,7 @@ on: - "*/ql/src/**/*.qll" - "*/ql/lib/**/*.ql" - "*/ql/lib/**/*.qll" + - "*/ql/lib/ext/**/*.yml" - "misc/scripts/library-coverage/*.py" # input data files - "*/documentation/library-coverage/cwe-sink.csv" From a961fffda8ade49400406ee645c2641a36a95062 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" <mbg@github.com> Date: Thu, 8 Jun 2023 16:24:16 +0100 Subject: [PATCH 437/739] Pass architecture to dotnet test --- .../integration-tests/posix-only/dotnet_test_mstest/test.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py index 345d26a1516..ff14366807d 100644 --- a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py +++ b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py @@ -1,3 +1,4 @@ +import platform from create_database_utils import * from diagnostics_test_utils import * @@ -5,6 +6,9 @@ from diagnostics_test_utils import * run_codeql_database_create(['dotnet test'], test_db="test-db", lang="csharp") check_diagnostics() +# Fix `dotnet test` picking `x64` on arm-based macOS +architecture = '-a arm64' if platform.machine() == 'arm64' else '' + # Explicitly build and then run tests. -run_codeql_database_create(['dotnet clean', 'rm -rf test-db', 'dotnet build -o myout --os win', 'dotnet test myout/dotnet_test_mstest.exe'], test_db="test2-db", lang="csharp") +run_codeql_database_create(['dotnet clean', 'rm -rf test-db', 'dotnet build -o myout --os win', 'dotnet test myout/dotnet_test_mstest.exe ' + architecture], test_db="test2-db", lang="csharp") check_diagnostics(test_db="test2-db") From 2a1c0e8ba69c4fd7d0f278a69158eaacff1d79db Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 8 Jun 2023 19:02:07 +0200 Subject: [PATCH 438/739] C#: Re-factor. --- .../csharp/frameworks/EntityFramework.qll | 51 ++++++++++--------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 6e099a81fa2..4a6fd664099 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -339,7 +339,7 @@ module EntityFramework { * Gets the string representation for synthetic identifiers for SaveChanges methods * on this. */ - string getSyntheticNames() { + private string getSyntheticNames() { exists(string qualifier, string type, string name | this.getASaveChanges().hasQualifiedName(qualifier, type, name) | @@ -381,6 +381,17 @@ module EntityFramework { this.stepRev(tailHead, tailType, head, headType, dist) ) } + + pragma[nomagic] + string getInputSynthetic(SummaryComponentStack output, DbContextClassSetProperty p) { + exists(SummaryComponentStack synthetic, Property mapped | + this = p.getDbContextClass() and + input(this, synthetic, mapped) and + output(this, output, mapped, p) and + result = + getFullSyntheticName(this.getSyntheticNames(), p.getSyntheticName(), synthetic, output) + ) + } } private class DbContextClassSetProperty extends Property { @@ -454,12 +465,9 @@ module EntityFramework { override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - exists(SummaryComponentStack synthetic, string name, DbContextClass c, Property mapped | + exists(string name, DbContextClass c | preservesValue = true and - c = p.getDbContextClass() and - input(c, synthetic, mapped) and - output(c, output, mapped, p) and - name = getFullSyntheticName(c.getSyntheticNames(), p.getSyntheticName(), synthetic, output) and + name = c.getInputSynthetic(output, p) and input = SummaryComponentStack::syntheticGlobal(name) ) } @@ -478,18 +486,22 @@ module EntityFramework { ) } + pragma[nomagic] + string getOutputSynthetic(SummaryComponentStack input) { + exists(SummaryComponentStack synthetic, Property mapped, DbContextClassSetProperty dbSet | + input(c, input, mapped) and + output(c, synthetic, mapped, dbSet) and + result = + getFullSyntheticName(this.getSyntheticName(), dbSet.getSyntheticName(), input, synthetic) + ) + } + override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - exists( - SummaryComponentStack synthetic, string name, Property mapped, - DbContextClassSetProperty dbSet - | + exists(string name | preservesValue = true and - input(c, input, mapped) and - output(c, synthetic, mapped, dbSet) and - name = - getFullSyntheticName(this.getSyntheticName(), dbSet.getSyntheticName(), input, synthetic) and + name = this.getOutputSynthetic(input) and output = SummaryComponentStack::syntheticGlobal(name) ) } @@ -500,15 +512,8 @@ module EntityFramework { */ private class EFSummarizedCallableSyntheticGlobal extends SummaryComponent::SyntheticGlobal { EFSummarizedCallableSyntheticGlobal() { - exists( - DbContextClass c, SummaryComponentStack input, SummaryComponentStack output, - Property mapped, DbContextClassSetProperty dbSet - | - input(c, input, mapped) and - output(c, output, mapped, dbSet) - | - this = getFullSyntheticName(c.getSyntheticNames(), dbSet.getSyntheticName(), input, output) - ) + this = any(DbContextClass c).getInputSynthetic(_, _) or + this = any(DbContextSaveChanges c).getOutputSynthetic(_) } } From e4be303a2359917aadf855ead7f38f67a7a86654 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions@github.com> Date: Thu, 8 Jun 2023 19:57:37 +0000 Subject: [PATCH 439/739] Release preparation for version 2.13.4 --- cpp/ql/lib/CHANGELOG.md | 8 +++ .../0.7.3.md} | 9 +-- cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 6 ++ .../0.6.3.md} | 7 ++- cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++ .../lib/change-notes/released/1.5.3.md | 3 + .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++ .../src/change-notes/released/1.5.3.md | 3 + .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 21 +++++++ .../2023-05-17-update-csharp-sink-kinds.md | 9 --- .../2023-05-30-source-generators.md | 4 -- .../lib/change-notes/2023-06-06-dotnettest.md | 4 -- .../0.6.3.md} | 18 +++++- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ++ csharp/ql/src/change-notes/released/0.6.3.md | 3 + csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 4 ++ go/ql/lib/change-notes/released/0.5.3.md | 3 + go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++ go/ql/src/change-notes/released/0.5.3.md | 3 + go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 58 +++++++++++++++++++ .../2023-05-05-java-sink-kind-revamp.md | 22 ------- ...-12-androidwidget-source-kind-to-remote.md | 4 -- ...7-change-hostnamesanitizingprefix-regex.md | 5 -- .../2023-05-19-path-injection-sinks-mad.md | 4 -- ...023-05-22-inputstreamwrapper-transitive.md | 4 -- ...3-java-nio-file-files-copy-models-tweak.md | 4 -- .../change-notes/2023-05-24-kotlin-1.9.0.md | 4 -- .../2023-05-26-play-framework-models.md | 4 -- .../change-notes/2023-05-30-gson-models.md | 4 -- .../lib/change-notes/2023-05-30-new-models.md | 6 -- .../lib/change-notes/2023-06-01-new-models.md | 7 --- .../change-notes/2023-06-02-delete-deps.md | 6 -- .../2023-06-06-kotlin-use-with-flow.md | 4 -- .../lib/change-notes/2023-06-06-new-models.md | 15 ----- java/ql/lib/change-notes/released/0.6.3.md | 57 ++++++++++++++++++ java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 6 ++ .../0.6.3.md} | 7 ++- java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 20 +++++++ .../change-notes/2023-04-19-typescript-5-1.md | 4 -- .../change-notes/2023-04-30-npm-submodule.md | 5 -- .../2023-05-12-update-js-sink-kinds.md | 6 -- .../0.6.3.md} | 17 ++++-- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 8 +++ .../0.6.3.md} | 7 ++- javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++ .../change-notes/released/0.5.3.md | 3 + misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 4 ++ python/ql/lib/change-notes/released/0.9.3.md | 3 + python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 6 ++ .../0.7.3.md} | 9 +-- python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 12 ++++ ruby/ql/lib/change-notes/2023-05-06-mysql2.md | 4 -- ruby/ql/lib/change-notes/2023-05-06-pg.md | 4 -- ruby/ql/lib/change-notes/2023-05-07-sequel.md | 4 -- .../change-notes/2023-06-02-delete-deps.md | 7 --- ruby/ql/lib/change-notes/released/0.6.3.md | 11 ++++ ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 10 ++++ .../2023-05-24-delete-name-clash.md | 5 -- .../0.6.3.md} | 9 ++- ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++ shared/regex/change-notes/released/0.0.14.md | 3 + shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++ shared/ssa/change-notes/released/0.0.18.md | 3 + shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ++ .../tutorial/change-notes/released/0.0.11.md | 3 + shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++ .../change-notes/released/0.0.11.md | 3 + shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++ shared/typos/change-notes/released/0.0.18.md | 3 + shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 4 ++ shared/util/change-notes/released/0.0.11.md | 3 + shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ++ shared/yaml/change-notes/released/0.0.3.md | 3 + shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- 121 files changed, 425 insertions(+), 224 deletions(-) rename cpp/ql/lib/change-notes/{2022-08-06-delete-deps.md => released/0.7.3.md} (71%) rename cpp/ql/src/change-notes/{2023-05-24-overrun-write-query.md => released/0.6.3.md} (80%) create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.3.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.3.md delete mode 100644 csharp/ql/lib/change-notes/2023-05-17-update-csharp-sink-kinds.md delete mode 100644 csharp/ql/lib/change-notes/2023-05-30-source-generators.md delete mode 100644 csharp/ql/lib/change-notes/2023-06-06-dotnettest.md rename csharp/ql/lib/change-notes/{2023-06-02-delete-deps.md => released/0.6.3.md} (50%) create mode 100644 csharp/ql/src/change-notes/released/0.6.3.md create mode 100644 go/ql/lib/change-notes/released/0.5.3.md create mode 100644 go/ql/src/change-notes/released/0.5.3.md delete mode 100644 java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md delete mode 100644 java/ql/lib/change-notes/2023-05-12-androidwidget-source-kind-to-remote.md delete mode 100644 java/ql/lib/change-notes/2023-05-17-change-hostnamesanitizingprefix-regex.md delete mode 100644 java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md delete mode 100644 java/ql/lib/change-notes/2023-05-22-inputstreamwrapper-transitive.md delete mode 100644 java/ql/lib/change-notes/2023-05-23-java-nio-file-files-copy-models-tweak.md delete mode 100644 java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md delete mode 100644 java/ql/lib/change-notes/2023-05-26-play-framework-models.md delete mode 100644 java/ql/lib/change-notes/2023-05-30-gson-models.md delete mode 100644 java/ql/lib/change-notes/2023-05-30-new-models.md delete mode 100644 java/ql/lib/change-notes/2023-06-01-new-models.md delete mode 100644 java/ql/lib/change-notes/2023-06-02-delete-deps.md delete mode 100644 java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md delete mode 100644 java/ql/lib/change-notes/2023-06-06-new-models.md create mode 100644 java/ql/lib/change-notes/released/0.6.3.md rename java/ql/src/change-notes/{2023-06-05-lines-of-code.md => released/0.6.3.md} (77%) delete mode 100644 javascript/ql/lib/change-notes/2023-04-19-typescript-5-1.md delete mode 100644 javascript/ql/lib/change-notes/2023-04-30-npm-submodule.md delete mode 100644 javascript/ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md rename javascript/ql/lib/change-notes/{2023-06-02-delete-deps.md => released/0.6.3.md} (64%) rename javascript/ql/src/change-notes/{2023-06-01-restrict-regex-search-function.md => released/0.6.3.md} (90%) create mode 100644 misc/suite-helpers/change-notes/released/0.5.3.md create mode 100644 python/ql/lib/change-notes/released/0.9.3.md rename python/ql/src/change-notes/{2023-06-02-unsafe-deserialization-name-update.md => released/0.7.3.md} (81%) delete mode 100644 ruby/ql/lib/change-notes/2023-05-06-mysql2.md delete mode 100644 ruby/ql/lib/change-notes/2023-05-06-pg.md delete mode 100644 ruby/ql/lib/change-notes/2023-05-07-sequel.md delete mode 100644 ruby/ql/lib/change-notes/2023-06-02-delete-deps.md create mode 100644 ruby/ql/lib/change-notes/released/0.6.3.md delete mode 100644 ruby/ql/src/change-notes/2023-05-24-delete-name-clash.md rename ruby/ql/src/change-notes/{2023-05-26-super-and-flow-through.md => released/0.6.3.md} (57%) create mode 100644 shared/regex/change-notes/released/0.0.14.md create mode 100644 shared/ssa/change-notes/released/0.0.18.md create mode 100644 shared/tutorial/change-notes/released/0.0.11.md create mode 100644 shared/typetracking/change-notes/released/0.0.11.md create mode 100644 shared/typos/change-notes/released/0.0.18.md create mode 100644 shared/util/change-notes/released/0.0.11.md create mode 100644 shared/yaml/change-notes/released/0.0.3.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index e5d2ae643bc..e990e830005 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.7.3 + +### Minor Analysis Improvements + +* Deleted the deprecated `hasCopyConstructor` predicate from the `Class` class in `Class.qll`. +* Deleted many deprecated predicates and classes with uppercase `AST`, `SSA`, `CFG`, `API`, etc. in their names. Use the PascalCased versions instead. +* Deleted the deprecated `CodeDuplication.qll` file. + ## 0.7.2 ### New Features diff --git a/cpp/ql/lib/change-notes/2022-08-06-delete-deps.md b/cpp/ql/lib/change-notes/released/0.7.3.md similarity index 71% rename from cpp/ql/lib/change-notes/2022-08-06-delete-deps.md rename to cpp/ql/lib/change-notes/released/0.7.3.md index c234c189484..d6cb19b669d 100644 --- a/cpp/ql/lib/change-notes/2022-08-06-delete-deps.md +++ b/cpp/ql/lib/change-notes/released/0.7.3.md @@ -1,6 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.7.3 + +### Minor Analysis Improvements + * Deleted the deprecated `hasCopyConstructor` predicate from the `Class` class in `Class.qll`. * Deleted many deprecated predicates and classes with uppercase `AST`, `SSA`, `CFG`, `API`, etc. in their names. Use the PascalCased versions instead. -* Deleted the deprecated `CodeDuplication.qll` file. \ No newline at end of file +* Deleted the deprecated `CodeDuplication.qll` file. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index fee171e9685..a4ea9c8de17 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.2 +lastReleaseVersion: 0.7.3 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 1982886c434..2d39cafe571 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.7.3-dev +version: 0.7.3 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 4991b66538f..ca314dcd6d7 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.6.3 + +### New Queries + +* Added a new query, `cpp/overrun-write`, to detect buffer overflows in C-style functions that manipulate buffers. + ## 0.6.2 No user-facing changes. diff --git a/cpp/ql/src/change-notes/2023-05-24-overrun-write-query.md b/cpp/ql/src/change-notes/released/0.6.3.md similarity index 80% rename from cpp/ql/src/change-notes/2023-05-24-overrun-write-query.md rename to cpp/ql/src/change-notes/released/0.6.3.md index 32195223fcd..d9421d55250 100644 --- a/cpp/ql/src/change-notes/2023-05-24-overrun-write-query.md +++ b/cpp/ql/src/change-notes/released/0.6.3.md @@ -1,4 +1,5 @@ ---- -category: newQuery ---- +## 0.6.3 + +### New Queries + * Added a new query, `cpp/overrun-write`, to detect buffer overflows in C-style functions that manipulate buffers. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 46dffc3e763..1aa38f466f6 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.6.3-dev +version: 0.6.3 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index ad7a007007f..b466881d9d7 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.3 + +No user-facing changes. + ## 1.5.2 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.3.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.3.md new file mode 100644 index 00000000000..2e9bcb5e663 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.3.md @@ -0,0 +1,3 @@ +## 1.5.3 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 7eb901bae56..232224b0e26 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.5.2 +lastReleaseVersion: 1.5.3 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 4f2900e0b73..d48f3cb1b0a 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.5.3-dev +version: 1.5.3 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index ad7a007007f..b466881d9d7 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.3 + +No user-facing changes. + ## 1.5.2 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.3.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.3.md new file mode 100644 index 00000000000..2e9bcb5e663 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.3.md @@ -0,0 +1,3 @@ +## 1.5.3 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 7eb901bae56..232224b0e26 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.5.2 +lastReleaseVersion: 1.5.3 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 2318576e19e..f63efb58811 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.5.3-dev +version: 1.5.3 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 435255a997a..8fc9f20a131 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,24 @@ +## 0.6.3 + +### Major Analysis Improvements + +* The extractor has been changed to run after the traced compiler call. This allows inspecting compiler generated files, such as the output of source generators. With this change, `.cshtml` files and their generated `.cshtml.g.cs` counterparts are extracted on dotnet 6 and above. + +### Minor Analysis Improvements + +* C#: Analysis of the `dotnet test` command supplied with a `dll` or `exe` file as argument no longer fails due to the addition of an erroneous `-p:SharedCompilation=false` argument. +* Deleted the deprecated `WebConfigXML`, `ConfigurationXMLElement`, `LocationXMLElement`, `SystemWebXMLElement`, `SystemWebServerXMLElement`, `CustomErrorsXMLElement`, and `HttpRuntimeXMLElement` classes from `WebConfig.qll`. The non-deprecated names with PascalCased Xml suffixes should be used instead. +* Deleted the deprecated `Record` class from both `Types.qll` and `Type.qll`. +* Deleted the deprecated `StructuralComparisonConfiguration` class from `StructuralComparison.qll`, use `sameGvn` instead. +* Deleted the deprecated `isParameterOf` predicate from the `ParameterNode` class. +* Deleted the deprecated `SafeExternalAPICallable`, `ExternalAPIDataNode`, `UntrustedDataToExternalAPIConfig`, `UntrustedExternalAPIDataNode`, and `ExternalAPIUsedWithUntrustedData` classes from `ExternalAPIsQuery.qll`. The non-deprecated names with PascalCased Api suffixes should be used instead. +* Updated the following C# sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. + * `code` to `code-injection` + * `sql` to `sql-injection` + * `html` to `html-injection` + * `xss` to `js-injection` + * `remote` to `file-content-store` + ## 0.6.2 ### Minor Analysis Improvements diff --git a/csharp/ql/lib/change-notes/2023-05-17-update-csharp-sink-kinds.md b/csharp/ql/lib/change-notes/2023-05-17-update-csharp-sink-kinds.md deleted file mode 100644 index ce6d618af5e..00000000000 --- a/csharp/ql/lib/change-notes/2023-05-17-update-csharp-sink-kinds.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -category: minorAnalysis ---- -* Updated the following C# sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. - * `code` to `code-injection` - * `sql` to `sql-injection` - * `html` to `html-injection` - * `xss` to `js-injection` - * `remote` to `file-content-store` diff --git a/csharp/ql/lib/change-notes/2023-05-30-source-generators.md b/csharp/ql/lib/change-notes/2023-05-30-source-generators.md deleted file mode 100644 index 5483ce6af35..00000000000 --- a/csharp/ql/lib/change-notes/2023-05-30-source-generators.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* The extractor has been changed to run after the traced compiler call. This allows inspecting compiler generated files, such as the output of source generators. With this change, `.cshtml` files and their generated `.cshtml.g.cs` counterparts are extracted on dotnet 6 and above. diff --git a/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md b/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md deleted file mode 100644 index e7179b93189..00000000000 --- a/csharp/ql/lib/change-notes/2023-06-06-dotnettest.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* C#: Analysis of the `dotnet test` command supplied with a `dll` or `exe` file as argument no longer fails due to the addition of an erroneous `-p:SharedCompilation=false` argument. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2023-06-02-delete-deps.md b/csharp/ql/lib/change-notes/released/0.6.3.md similarity index 50% rename from csharp/ql/lib/change-notes/2023-06-02-delete-deps.md rename to csharp/ql/lib/change-notes/released/0.6.3.md index 13402f08147..51f62426686 100644 --- a/csharp/ql/lib/change-notes/2023-06-02-delete-deps.md +++ b/csharp/ql/lib/change-notes/released/0.6.3.md @@ -1,8 +1,20 @@ ---- -category: minorAnalysis ---- +## 0.6.3 + +### Major Analysis Improvements + +* The extractor has been changed to run after the traced compiler call. This allows inspecting compiler generated files, such as the output of source generators. With this change, `.cshtml` files and their generated `.cshtml.g.cs` counterparts are extracted on dotnet 6 and above. + +### Minor Analysis Improvements + +* C#: Analysis of the `dotnet test` command supplied with a `dll` or `exe` file as argument no longer fails due to the addition of an erroneous `-p:SharedCompilation=false` argument. * Deleted the deprecated `WebConfigXML`, `ConfigurationXMLElement`, `LocationXMLElement`, `SystemWebXMLElement`, `SystemWebServerXMLElement`, `CustomErrorsXMLElement`, and `HttpRuntimeXMLElement` classes from `WebConfig.qll`. The non-deprecated names with PascalCased Xml suffixes should be used instead. * Deleted the deprecated `Record` class from both `Types.qll` and `Type.qll`. * Deleted the deprecated `StructuralComparisonConfiguration` class from `StructuralComparison.qll`, use `sameGvn` instead. * Deleted the deprecated `isParameterOf` predicate from the `ParameterNode` class. * Deleted the deprecated `SafeExternalAPICallable`, `ExternalAPIDataNode`, `UntrustedDataToExternalAPIConfig`, `UntrustedExternalAPIDataNode`, and `ExternalAPIUsedWithUntrustedData` classes from `ExternalAPIsQuery.qll`. The non-deprecated names with PascalCased Api suffixes should be used instead. +* Updated the following C# sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. + * `code` to `code-injection` + * `sql` to `sql-injection` + * `html` to `html-injection` + * `xss` to `js-injection` + * `remote` to `file-content-store` diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 17e00fa022c..833f7eae10b 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.6.3-dev +version: 0.6.3 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index e214ec42a03..8e82ab07313 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.3 + +No user-facing changes. + ## 0.6.2 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/0.6.3.md b/csharp/ql/src/change-notes/released/0.6.3.md new file mode 100644 index 00000000000..83374bcef56 --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.6.3.md @@ -0,0 +1,3 @@ +## 0.6.3 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 95506e0f254..0ae9d1d6c03 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.6.3-dev +version: 0.6.3 groups: - csharp - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 5f09272c19b..0e0d00161e1 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.3 + +No user-facing changes. + ## 0.5.2 ### Minor Analysis Improvements diff --git a/go/ql/lib/change-notes/released/0.5.3.md b/go/ql/lib/change-notes/released/0.5.3.md new file mode 100644 index 00000000000..e97503053f0 --- /dev/null +++ b/go/ql/lib/change-notes/released/0.5.3.md @@ -0,0 +1,3 @@ +## 0.5.3 + +No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 2d9d3f587f8..2164e038a5d 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.2 +lastReleaseVersion: 0.5.3 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 287c27187e3..ce44cff6d9e 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.5.3-dev +version: 0.5.3 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 8a1b8bcfebc..61712c5e790 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.3 + +No user-facing changes. + ## 0.5.2 No user-facing changes. diff --git a/go/ql/src/change-notes/released/0.5.3.md b/go/ql/src/change-notes/released/0.5.3.md new file mode 100644 index 00000000000..e97503053f0 --- /dev/null +++ b/go/ql/src/change-notes/released/0.5.3.md @@ -0,0 +1,3 @@ +## 0.5.3 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 2d9d3f587f8..2164e038a5d 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.2 +lastReleaseVersion: 0.5.3 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 75963a0708e..65c84860754 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.5.3-dev +version: 0.5.3 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 53fb1470bb9..4b72014d78e 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,61 @@ +## 0.6.3 + +### New Features + +* Kotlin versions up to 1.9.0 are now supported. + +### Minor Analysis Improvements + +* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`. +* Added models for the following packages: + + * com.alibaba.druid.sql + * com.fasterxml.jackson.databind + * com.jcraft.jsch + * io.netty.handler.ssl + * okhttp3 + * org.antlr.runtime + * org.fusesource.leveldbjni + * org.influxdb + * org.springframework.core.io + * org.yaml.snakeyaml +* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead. +* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead. +* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead. +* Added models for the following packages: + + * java.lang + * java.nio.file +* Added dataflow models for the Gson deserialization library. +* Added models for the following packages: + + * okhttp3 +* Added more dataflow models for the Play Framework. +Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks. +* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`. +* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`. +* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname. +* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working. +* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working. + * `sql` to `sql-injection` + * `url-redirect` to `url-redirection` + * `xpath` to `xpath-injection` + * `ssti` to `template-injection` + * `logging` to `log-injection` + * `groovy` to `groovy-injection` + * `jexl` to `jexl-injection` + * `mvel` to `mvel-injection` + * `xslt` to `xslt-injection` + * `ldap` to `ldap-injection` + * `pending-intent-sent` to `pending-intents` + * `intent-start` to `intent-redirection` + * `set-hostname-verifier` to `hostname-verification` + * `header-splitting` to `response-splitting` + * `xss` to `html-injection` and `js-injection` + * `write-file` to `file-system-store` + * `create-file` and `read-file` to `path-injection` + * `open-url` and `jdbc-url` to `request-forgery` + ## 0.6.2 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md b/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md deleted file mode 100644 index ef54f491051..00000000000 --- a/java/ql/lib/change-notes/2023-05-05-java-sink-kind-revamp.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -category: minorAnalysis ---- -* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working. - * `sql` to `sql-injection` - * `url-redirect` to `url-redirection` - * `xpath` to `xpath-injection` - * `ssti` to `template-injection` - * `logging` to `log-injection` - * `groovy` to `groovy-injection` - * `jexl` to `jexl-injection` - * `mvel` to `mvel-injection` - * `xslt` to `xslt-injection` - * `ldap` to `ldap-injection` - * `pending-intent-sent` to `pending-intents` - * `intent-start` to `intent-redirection` - * `set-hostname-verifier` to `hostname-verification` - * `header-splitting` to `response-splitting` - * `xss` to `html-injection` and `js-injection` - * `write-file` to `file-system-store` - * `create-file` and `read-file` to `path-injection` - * `open-url` and `jdbc-url` to `request-forgery` diff --git a/java/ql/lib/change-notes/2023-05-12-androidwidget-source-kind-to-remote.md b/java/ql/lib/change-notes/2023-05-12-androidwidget-source-kind-to-remote.md deleted file mode 100644 index 7a2714a6527..00000000000 --- a/java/ql/lib/change-notes/2023-05-12-androidwidget-source-kind-to-remote.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working. diff --git a/java/ql/lib/change-notes/2023-05-17-change-hostnamesanitizingprefix-regex.md b/java/ql/lib/change-notes/2023-05-17-change-hostnamesanitizingprefix-regex.md deleted file mode 100644 index 8d81c97d9e3..00000000000 --- a/java/ql/lib/change-notes/2023-05-17-change-hostnamesanitizingprefix-regex.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname. - diff --git a/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md b/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md deleted file mode 100644 index ae5cd306c2b..00000000000 --- a/java/ql/lib/change-notes/2023-05-19-path-injection-sinks-mad.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`. diff --git a/java/ql/lib/change-notes/2023-05-22-inputstreamwrapper-transitive.md b/java/ql/lib/change-notes/2023-05-22-inputstreamwrapper-transitive.md deleted file mode 100644 index bba77d98d89..00000000000 --- a/java/ql/lib/change-notes/2023-05-22-inputstreamwrapper-transitive.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`. diff --git a/java/ql/lib/change-notes/2023-05-23-java-nio-file-files-copy-models-tweak.md b/java/ql/lib/change-notes/2023-05-23-java-nio-file-files-copy-models-tweak.md deleted file mode 100644 index 85fc9b89197..00000000000 --- a/java/ql/lib/change-notes/2023-05-23-java-nio-file-files-copy-models-tweak.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks. diff --git a/java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md b/java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md deleted file mode 100644 index f3647cc5488..00000000000 --- a/java/ql/lib/change-notes/2023-05-24-kotlin-1.9.0.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Kotlin versions up to 1.9.0 are now supported. diff --git a/java/ql/lib/change-notes/2023-05-26-play-framework-models.md b/java/ql/lib/change-notes/2023-05-26-play-framework-models.md deleted file mode 100644 index 69db10413eb..00000000000 --- a/java/ql/lib/change-notes/2023-05-26-play-framework-models.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added more dataflow models for the Play Framework. diff --git a/java/ql/lib/change-notes/2023-05-30-gson-models.md b/java/ql/lib/change-notes/2023-05-30-gson-models.md deleted file mode 100644 index 306d797ff1a..00000000000 --- a/java/ql/lib/change-notes/2023-05-30-gson-models.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added dataflow models for the Gson deserialization library. diff --git a/java/ql/lib/change-notes/2023-05-30-new-models.md b/java/ql/lib/change-notes/2023-05-30-new-models.md deleted file mode 100644 index 24e7563d727..00000000000 --- a/java/ql/lib/change-notes/2023-05-30-new-models.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* Added models for the following packages: - - * okhttp3 diff --git a/java/ql/lib/change-notes/2023-06-01-new-models.md b/java/ql/lib/change-notes/2023-06-01-new-models.md deleted file mode 100644 index d05b3d4d59d..00000000000 --- a/java/ql/lib/change-notes/2023-06-01-new-models.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -category: minorAnalysis ---- -* Added models for the following packages: - - * java.lang - * java.nio.file diff --git a/java/ql/lib/change-notes/2023-06-02-delete-deps.md b/java/ql/lib/change-notes/2023-06-02-delete-deps.md deleted file mode 100644 index 01b2fd5a457..00000000000 --- a/java/ql/lib/change-notes/2023-06-02-delete-deps.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead. -* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead. -* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md b/java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md deleted file mode 100644 index b21f31aae5f..00000000000 --- a/java/ql/lib/change-notes/2023-06-06-kotlin-use-with-flow.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`. diff --git a/java/ql/lib/change-notes/2023-06-06-new-models.md b/java/ql/lib/change-notes/2023-06-06-new-models.md deleted file mode 100644 index cbb80968749..00000000000 --- a/java/ql/lib/change-notes/2023-06-06-new-models.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -category: minorAnalysis ---- -* Added models for the following packages: - - * com.alibaba.druid.sql - * com.fasterxml.jackson.databind - * com.jcraft.jsch - * io.netty.handler.ssl - * okhttp3 - * org.antlr.runtime - * org.fusesource.leveldbjni - * org.influxdb - * org.springframework.core.io - * org.yaml.snakeyaml diff --git a/java/ql/lib/change-notes/released/0.6.3.md b/java/ql/lib/change-notes/released/0.6.3.md new file mode 100644 index 00000000000..b5b7e7f9556 --- /dev/null +++ b/java/ql/lib/change-notes/released/0.6.3.md @@ -0,0 +1,57 @@ +## 0.6.3 + +### New Features + +* Kotlin versions up to 1.9.0 are now supported. + +### Minor Analysis Improvements + +* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`. +* Added models for the following packages: + + * com.alibaba.druid.sql + * com.fasterxml.jackson.databind + * com.jcraft.jsch + * io.netty.handler.ssl + * okhttp3 + * org.antlr.runtime + * org.fusesource.leveldbjni + * org.influxdb + * org.springframework.core.io + * org.yaml.snakeyaml +* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead. +* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead. +* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead. +* Added models for the following packages: + + * java.lang + * java.nio.file +* Added dataflow models for the Gson deserialization library. +* Added models for the following packages: + + * okhttp3 +* Added more dataflow models for the Play Framework. +Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks. +* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`. +* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`. +* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname. +* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working. +* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working. + * `sql` to `sql-injection` + * `url-redirect` to `url-redirection` + * `xpath` to `xpath-injection` + * `ssti` to `template-injection` + * `logging` to `log-injection` + * `groovy` to `groovy-injection` + * `jexl` to `jexl-injection` + * `mvel` to `mvel-injection` + * `xslt` to `xslt-injection` + * `ldap` to `ldap-injection` + * `pending-intent-sent` to `pending-intents` + * `intent-start` to `intent-redirection` + * `set-hostname-verifier` to `hostname-verification` + * `header-splitting` to `response-splitting` + * `xss` to `html-injection` and `js-injection` + * `write-file` to `file-system-store` + * `create-file` and `read-file` to `path-injection` + * `open-url` and `jdbc-url` to `request-forgery` diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index ada2ac9e999..8a18f2bdabb 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.6.3-dev +version: 0.6.3 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 1e7cebcfca1..4852323b9b8 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.6.3 + +### Minor Analysis Improvements + +* The `java/summary/lines-of-code` query now only counts lines of Java code. The new `java/summary/lines-of-code-kotlin` counts lines of Kotlin code. + ## 0.6.2 ### Minor Analysis Improvements diff --git a/java/ql/src/change-notes/2023-06-05-lines-of-code.md b/java/ql/src/change-notes/released/0.6.3.md similarity index 77% rename from java/ql/src/change-notes/2023-06-05-lines-of-code.md rename to java/ql/src/change-notes/released/0.6.3.md index a96c891e506..96665727131 100644 --- a/java/ql/src/change-notes/2023-06-05-lines-of-code.md +++ b/java/ql/src/change-notes/released/0.6.3.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.6.3 + +### Minor Analysis Improvements + * The `java/summary/lines-of-code` query now only counts lines of Java code. The new `java/summary/lines-of-code-kotlin` counts lines of Kotlin code. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 2da31e822ff..b52ce1fd59c 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.6.3-dev +version: 0.6.3 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 3ac3bc23481..b4c69e3a2fd 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,23 @@ +## 0.6.3 + +### Major Analysis Improvements + +* Added support for TypeScript 5.1. + +### Minor Analysis Improvements + +* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead. +* Deleted the deprecated `localTaintStep` predicate from `DataFlow.qll`. +* Deleted the deprecated `stringStep`, and `localTaintStep` predicates from `TaintTracking.qll`. +* Deleted many modules that started with a lowercase letter. Use the versions that start with an uppercase letter instead. +* Deleted the deprecated `HtmlInjectionConfiguration` and `JQueryHtmlOrSelectorInjectionConfiguration` classes from `DomBasedXssQuery.qll`, use `Configuration` instead. +* Deleted the deprecated `DefiningIdentifier` class and the `Definitions.qll` file it was in. Use `SsaDefinition` instead. +* Deleted the deprecated `definitionReaches`, `localDefinitionReaches`, `getAPseudoDefinitionInput`, `nextDefAfter`, and `localDefinitionOverwrites` predicates from `DefUse.qll`. +* Updated the following JavaScript sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. + * `command-line-injection` to `command-injection` + * `credentials[kind]` to `credentials-kind` +- Added a support of sub modules in `node_modules`. + ## 0.6.2 ### Minor Analysis Improvements diff --git a/javascript/ql/lib/change-notes/2023-04-19-typescript-5-1.md b/javascript/ql/lib/change-notes/2023-04-19-typescript-5-1.md deleted file mode 100644 index 7260bd3d389..00000000000 --- a/javascript/ql/lib/change-notes/2023-04-19-typescript-5-1.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Added support for TypeScript 5.1. \ No newline at end of file diff --git a/javascript/ql/lib/change-notes/2023-04-30-npm-submodule.md b/javascript/ql/lib/change-notes/2023-04-30-npm-submodule.md deleted file mode 100644 index 5ef95cf7d58..00000000000 --- a/javascript/ql/lib/change-notes/2023-04-30-npm-submodule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- - -- Added a support of sub modules in `node_modules`. diff --git a/javascript/ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md b/javascript/ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md deleted file mode 100644 index 9d215924623..00000000000 --- a/javascript/ql/lib/change-notes/2023-05-12-update-js-sink-kinds.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* Updated the following JavaScript sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. - * `command-line-injection` to `command-injection` - * `credentials[kind]` to `credentials-kind` diff --git a/javascript/ql/lib/change-notes/2023-06-02-delete-deps.md b/javascript/ql/lib/change-notes/released/0.6.3.md similarity index 64% rename from javascript/ql/lib/change-notes/2023-06-02-delete-deps.md rename to javascript/ql/lib/change-notes/released/0.6.3.md index 9edbce9771e..0559c0fd746 100644 --- a/javascript/ql/lib/change-notes/2023-06-02-delete-deps.md +++ b/javascript/ql/lib/change-notes/released/0.6.3.md @@ -1,10 +1,19 @@ ---- -category: minorAnalysis ---- +## 0.6.3 + +### Major Analysis Improvements + +* Added support for TypeScript 5.1. + +### Minor Analysis Improvements + * Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead. * Deleted the deprecated `localTaintStep` predicate from `DataFlow.qll`. * Deleted the deprecated `stringStep`, and `localTaintStep` predicates from `TaintTracking.qll`. * Deleted many modules that started with a lowercase letter. Use the versions that start with an uppercase letter instead. * Deleted the deprecated `HtmlInjectionConfiguration` and `JQueryHtmlOrSelectorInjectionConfiguration` classes from `DomBasedXssQuery.qll`, use `Configuration` instead. * Deleted the deprecated `DefiningIdentifier` class and the `Definitions.qll` file it was in. Use `SsaDefinition` instead. -* Deleted the deprecated `definitionReaches`, `localDefinitionReaches`, `getAPseudoDefinitionInput`, `nextDefAfter`, and `localDefinitionOverwrites` predicates from `DefUse.qll`. \ No newline at end of file +* Deleted the deprecated `definitionReaches`, `localDefinitionReaches`, `getAPseudoDefinitionInput`, `nextDefAfter`, and `localDefinitionOverwrites` predicates from `DefUse.qll`. +* Updated the following JavaScript sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. + * `command-line-injection` to `command-injection` + * `credentials[kind]` to `credentials-kind` +- Added a support of sub modules in `node_modules`. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 52962f549b0..bda9945c1c3 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.6.3-dev +version: 0.6.3 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index eb914577876..0194f6f1c4a 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.6.3 + +### Minor Analysis Improvements + +* Fixed an issue where calls to a method named `search` would lead to false positive alerts related to regular expressions. + This happened when the call was incorrectly seen as a call to `String.prototype.search`, since this function converts its first argument + to a regular expression. The analysis is now more restrictive about when to treat `search` calls as regular expression sinks. + ## 0.6.2 ### Major Analysis Improvements diff --git a/javascript/ql/src/change-notes/2023-06-01-restrict-regex-search-function.md b/javascript/ql/src/change-notes/released/0.6.3.md similarity index 90% rename from javascript/ql/src/change-notes/2023-06-01-restrict-regex-search-function.md rename to javascript/ql/src/change-notes/released/0.6.3.md index a43aebff717..3b5d43026f8 100644 --- a/javascript/ql/src/change-notes/2023-06-01-restrict-regex-search-function.md +++ b/javascript/ql/src/change-notes/released/0.6.3.md @@ -1,6 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.6.3 + +### Minor Analysis Improvements + * Fixed an issue where calls to a method named `search` would lead to false positive alerts related to regular expressions. This happened when the call was incorrectly seen as a call to `String.prototype.search`, since this function converts its first argument to a regular expression. The analysis is now more restrictive about when to treat `search` calls as regular expression sinks. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 10e071e417c..6df72dd450f 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.6.3-dev +version: 0.6.3 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 46787616efa..9571c393549 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.3 + +No user-facing changes. + ## 0.5.2 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.5.3.md b/misc/suite-helpers/change-notes/released/0.5.3.md new file mode 100644 index 00000000000..e97503053f0 --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.5.3.md @@ -0,0 +1,3 @@ +## 0.5.3 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 2d9d3f587f8..2164e038a5d 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.2 +lastReleaseVersion: 0.5.3 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index b6fbcda7201..60af5875e10 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.5.3-dev +version: 0.5.3 groups: shared diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 91f53df486b..3bfc2ddf115 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.3 + +No user-facing changes. + ## 0.9.2 ### Minor Analysis Improvements diff --git a/python/ql/lib/change-notes/released/0.9.3.md b/python/ql/lib/change-notes/released/0.9.3.md new file mode 100644 index 00000000000..1c859ebb6b3 --- /dev/null +++ b/python/ql/lib/change-notes/released/0.9.3.md @@ -0,0 +1,3 @@ +## 0.9.3 + +No user-facing changes. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index e1eda519435..7af7247cbb0 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.2 +lastReleaseVersion: 0.9.3 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 9d4522d5f58..101ed2a7232 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.9.3-dev +version: 0.9.3 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 712de670fdc..655914b4a32 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.7.3 + +### Bug Fixes + +* The display name (`@name`) of the `py/unsafe-deserialization` query has been updated in favor of consistency with other languages. + ## 0.7.2 No user-facing changes. diff --git a/python/ql/src/change-notes/2023-06-02-unsafe-deserialization-name-update.md b/python/ql/src/change-notes/released/0.7.3.md similarity index 81% rename from python/ql/src/change-notes/2023-06-02-unsafe-deserialization-name-update.md rename to python/ql/src/change-notes/released/0.7.3.md index d786e9dc14d..2f9c3725fb0 100644 --- a/python/ql/src/change-notes/2023-06-02-unsafe-deserialization-name-update.md +++ b/python/ql/src/change-notes/released/0.7.3.md @@ -1,4 +1,5 @@ ---- -category: fix ---- -* The display name (`@name`) of the `py/unsafe-deserialization` query has been updated in favor of consistency with other languages. \ No newline at end of file +## 0.7.3 + +### Bug Fixes + +* The display name (`@name`) of the `py/unsafe-deserialization` query has been updated in favor of consistency with other languages. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index fee171e9685..a4ea9c8de17 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.2 +lastReleaseVersion: 0.7.3 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index eb327c2e42e..3c274ee84a9 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.7.3-dev +version: 0.7.3 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 65eba10cc10..5803375fd51 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.6.3 + +### Minor Analysis Improvements + +* Deleted many deprecated predicates and classes with uppercase `URL`, `XSS`, etc. in their names. Use the PascalCased versions instead. +* Deleted the deprecated `getValueText` predicate from the `Expr`, `StringComponent`, and `ExprCfgNode` classes. Use `getConstantValue` instead. +* Deleted the deprecated `VariableReferencePattern` class, use `ReferencePattern` instead. +* Deleted all deprecated aliases in `StandardLibrary.qll`, use `codeql.ruby.frameworks.Core` and `codeql.ruby.frameworks.Stdlib` instead. +* Support for the `sequel` gem has been added. Method calls that execute queries against a database that may be vulnerable to injection attacks will now be recognized. +* Support for the `mysql2` gem has been added. Method calls that execute queries against an MySQL database that may be vulnerable to injection attacks will now be recognized. +* Support for the `pg` gem has been added. Method calls that execute queries against a PostgreSQL database that may be vulnerable to injection attacks will now be recognized. + ## 0.6.2 ### Minor Analysis Improvements diff --git a/ruby/ql/lib/change-notes/2023-05-06-mysql2.md b/ruby/ql/lib/change-notes/2023-05-06-mysql2.md deleted file mode 100644 index d8fa92dd394..00000000000 --- a/ruby/ql/lib/change-notes/2023-05-06-mysql2.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Support for the `mysql2` gem has been added. Method calls that execute queries against an MySQL database that may be vulnerable to injection attacks will now be recognized. \ No newline at end of file diff --git a/ruby/ql/lib/change-notes/2023-05-06-pg.md b/ruby/ql/lib/change-notes/2023-05-06-pg.md deleted file mode 100644 index 0e671ff9106..00000000000 --- a/ruby/ql/lib/change-notes/2023-05-06-pg.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Support for the `pg` gem has been added. Method calls that execute queries against a PostgreSQL database that may be vulnerable to injection attacks will now be recognized. \ No newline at end of file diff --git a/ruby/ql/lib/change-notes/2023-05-07-sequel.md b/ruby/ql/lib/change-notes/2023-05-07-sequel.md deleted file mode 100644 index 3688f28db56..00000000000 --- a/ruby/ql/lib/change-notes/2023-05-07-sequel.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Support for the `sequel` gem has been added. Method calls that execute queries against a database that may be vulnerable to injection attacks will now be recognized. diff --git a/ruby/ql/lib/change-notes/2023-06-02-delete-deps.md b/ruby/ql/lib/change-notes/2023-06-02-delete-deps.md deleted file mode 100644 index f4df20530dc..00000000000 --- a/ruby/ql/lib/change-notes/2023-06-02-delete-deps.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -category: minorAnalysis ---- -* Deleted many deprecated predicates and classes with uppercase `URL`, `XSS`, etc. in their names. Use the PascalCased versions instead. -* Deleted the deprecated `getValueText` predicate from the `Expr`, `StringComponent`, and `ExprCfgNode` classes. Use `getConstantValue` instead. -* Deleted the deprecated `VariableReferencePattern` class, use `ReferencePattern` instead. -* Deleted all deprecated aliases in `StandardLibrary.qll`, use `codeql.ruby.frameworks.Core` and `codeql.ruby.frameworks.Stdlib` instead. \ No newline at end of file diff --git a/ruby/ql/lib/change-notes/released/0.6.3.md b/ruby/ql/lib/change-notes/released/0.6.3.md new file mode 100644 index 00000000000..35121021e9a --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.6.3.md @@ -0,0 +1,11 @@ +## 0.6.3 + +### Minor Analysis Improvements + +* Deleted many deprecated predicates and classes with uppercase `URL`, `XSS`, etc. in their names. Use the PascalCased versions instead. +* Deleted the deprecated `getValueText` predicate from the `Expr`, `StringComponent`, and `ExprCfgNode` classes. Use `getConstantValue` instead. +* Deleted the deprecated `VariableReferencePattern` class, use `ReferencePattern` instead. +* Deleted all deprecated aliases in `StandardLibrary.qll`, use `codeql.ruby.frameworks.Core` and `codeql.ruby.frameworks.Stdlib` instead. +* Support for the `sequel` gem has been added. Method calls that execute queries against a database that may be vulnerable to injection attacks will now be recognized. +* Support for the `mysql2` gem has been added. Method calls that execute queries against an MySQL database that may be vulnerable to injection attacks will now be recognized. +* Support for the `pg` gem has been added. Method calls that execute queries against a PostgreSQL database that may be vulnerable to injection attacks will now be recognized. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index bb01a5ff87d..2591c99f5cf 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.6.3-dev +version: 0.6.3 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 7e2e0df8b38..8bc499539cb 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.6.3 + +### Minor Analysis Improvements + +* Fixed a bug that would occur when an `initialize` method returns `self` or one of its parameters. + In such cases, the corresponding calls to `new` would be associated with an incorrect return type. + This could result in inaccurate call target resolution and cause false positive alerts. +* Fixed an issue where calls to `delete` or `assoc` with a constant-valued argument would be analyzed imprecisely, + as if the argument value was not a known constant. + ## 0.6.2 No user-facing changes. diff --git a/ruby/ql/src/change-notes/2023-05-24-delete-name-clash.md b/ruby/ql/src/change-notes/2023-05-24-delete-name-clash.md deleted file mode 100644 index 347a7b118db..00000000000 --- a/ruby/ql/src/change-notes/2023-05-24-delete-name-clash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Fixed an issue where calls to `delete` or `assoc` with a constant-valued argument would be analyzed imprecisely, - as if the argument value was not a known constant. diff --git a/ruby/ql/src/change-notes/2023-05-26-super-and-flow-through.md b/ruby/ql/src/change-notes/released/0.6.3.md similarity index 57% rename from ruby/ql/src/change-notes/2023-05-26-super-and-flow-through.md rename to ruby/ql/src/change-notes/released/0.6.3.md index 7059c51f24e..53544eca039 100644 --- a/ruby/ql/src/change-notes/2023-05-26-super-and-flow-through.md +++ b/ruby/ql/src/change-notes/released/0.6.3.md @@ -1,6 +1,9 @@ ---- -category: minorAnalysis ---- +## 0.6.3 + +### Minor Analysis Improvements + * Fixed a bug that would occur when an `initialize` method returns `self` or one of its parameters. In such cases, the corresponding calls to `new` would be associated with an incorrect return type. This could result in inaccurate call target resolution and cause false positive alerts. +* Fixed an issue where calls to `delete` or `assoc` with a constant-valued argument would be analyzed imprecisely, + as if the argument value was not a known constant. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 5501a2a1cc5..b7dafe32c5d 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.2 +lastReleaseVersion: 0.6.3 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 3bc462dc7ee..f98583c5f80 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.6.3-dev +version: 0.6.3 groups: - ruby - queries diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index cc83ed1e68c..e45483b6d3c 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.14 + +No user-facing changes. + ## 0.0.13 No user-facing changes. diff --git a/shared/regex/change-notes/released/0.0.14.md b/shared/regex/change-notes/released/0.0.14.md new file mode 100644 index 00000000000..63b4d50ca45 --- /dev/null +++ b/shared/regex/change-notes/released/0.0.14.md @@ -0,0 +1,3 @@ +## 0.0.14 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index 044e54e4f7e..ca29e45d0a6 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.13 +lastReleaseVersion: 0.0.14 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 86b105c881a..63d34ec6329 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.14-dev +version: 0.0.14 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 5e42000c1d1..41f9216baff 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.18 + +No user-facing changes. + ## 0.0.17 No user-facing changes. diff --git a/shared/ssa/change-notes/released/0.0.18.md b/shared/ssa/change-notes/released/0.0.18.md new file mode 100644 index 00000000000..86c60b8abe7 --- /dev/null +++ b/shared/ssa/change-notes/released/0.0.18.md @@ -0,0 +1,3 @@ +## 0.0.18 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index cbc3d3cd493..a0d2bc59d97 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.17 +lastReleaseVersion: 0.0.18 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 55ebe316292..be427812ded 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.0.18-dev +version: 0.0.18 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index 02876619527..28a38e6333b 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.11 + +No user-facing changes. + ## 0.0.10 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/0.0.11.md b/shared/tutorial/change-notes/released/0.0.11.md new file mode 100644 index 00000000000..19a2a55bd68 --- /dev/null +++ b/shared/tutorial/change-notes/released/0.0.11.md @@ -0,0 +1,3 @@ +## 0.0.11 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index af7544c0ae9..9d655dcca3e 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.0.11-dev +version: 0.0.11 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index c8729dc39f8..e87bb476477 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.11 + +No user-facing changes. + ## 0.0.10 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/0.0.11.md b/shared/typetracking/change-notes/released/0.0.11.md new file mode 100644 index 00000000000..19a2a55bd68 --- /dev/null +++ b/shared/typetracking/change-notes/released/0.0.11.md @@ -0,0 +1,3 @@ +## 0.0.11 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 10e32e39f99..ca6b6a9c76e 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.0.11-dev +version: 0.0.11 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 472d0ef41a5..9b3dcbace69 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.18 + +No user-facing changes. + ## 0.0.17 No user-facing changes. diff --git a/shared/typos/change-notes/released/0.0.18.md b/shared/typos/change-notes/released/0.0.18.md new file mode 100644 index 00000000000..86c60b8abe7 --- /dev/null +++ b/shared/typos/change-notes/released/0.0.18.md @@ -0,0 +1,3 @@ +## 0.0.18 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index cbc3d3cd493..a0d2bc59d97 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.17 +lastReleaseVersion: 0.0.18 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index fa4fe52aace..b3796de8fa1 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.0.18-dev +version: 0.0.18 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index 99aa576343d..fe9befff25a 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.11 + +No user-facing changes. + ## 0.0.10 No user-facing changes. diff --git a/shared/util/change-notes/released/0.0.11.md b/shared/util/change-notes/released/0.0.11.md new file mode 100644 index 00000000000..19a2a55bd68 --- /dev/null +++ b/shared/util/change-notes/released/0.0.11.md @@ -0,0 +1,3 @@ +## 0.0.11 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index b740014e5ae..e679dc42092 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.10 +lastReleaseVersion: 0.0.11 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index c044709ceee..f48343df59f 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.0.11-dev +version: 0.0.11 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 9119d5fc839..390989ba76a 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.3 + +No user-facing changes. + ## 0.0.2 No user-facing changes. diff --git a/shared/yaml/change-notes/released/0.0.3.md b/shared/yaml/change-notes/released/0.0.3.md new file mode 100644 index 00000000000..af7864fc7d5 --- /dev/null +++ b/shared/yaml/change-notes/released/0.0.3.md @@ -0,0 +1,3 @@ +## 0.0.3 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index 55dc06fbd76..a24b693d1e7 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.2 +lastReleaseVersion: 0.0.3 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 6b9f33c9125..e379f9bd9e1 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.0.3-dev +version: 0.0.3 groups: shared library: true warnOnImplicitThis: true From bff11c3d2352812aa68ce3068c04cd424ae637e0 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <93738568+jketema@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:33:50 +0200 Subject: [PATCH 440/739] Apply suggestions from code review --- java/ql/lib/CHANGELOG.md | 2 +- java/ql/lib/change-notes/released/0.6.3.md | 2 +- javascript/ql/lib/CHANGELOG.md | 2 +- javascript/ql/lib/change-notes/released/0.6.3.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 4b72014d78e..1056cefb86a 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -31,7 +31,7 @@ * okhttp3 * Added more dataflow models for the Play Framework. -Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks. +* Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks. * Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`. * Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`. * Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname. diff --git a/java/ql/lib/change-notes/released/0.6.3.md b/java/ql/lib/change-notes/released/0.6.3.md index b5b7e7f9556..05c95272941 100644 --- a/java/ql/lib/change-notes/released/0.6.3.md +++ b/java/ql/lib/change-notes/released/0.6.3.md @@ -31,7 +31,7 @@ * okhttp3 * Added more dataflow models for the Play Framework. -Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks. +* Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks. * Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`. * Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`. * Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname. diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index b4c69e3a2fd..47c4130c3af 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -16,7 +16,7 @@ * Updated the following JavaScript sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. * `command-line-injection` to `command-injection` * `credentials[kind]` to `credentials-kind` -- Added a support of sub modules in `node_modules`. +* Added a support of sub modules in `node_modules`. ## 0.6.2 diff --git a/javascript/ql/lib/change-notes/released/0.6.3.md b/javascript/ql/lib/change-notes/released/0.6.3.md index 0559c0fd746..c87e2deb626 100644 --- a/javascript/ql/lib/change-notes/released/0.6.3.md +++ b/javascript/ql/lib/change-notes/released/0.6.3.md @@ -16,4 +16,4 @@ * Updated the following JavaScript sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. * `command-line-injection` to `command-injection` * `credentials[kind]` to `credentials-kind` -- Added a support of sub modules in `node_modules`. +* Added a support of sub modules in `node_modules`. From da58b2afc8323a2e69038a661cc8515b91b1988d Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 8 Jun 2023 20:05:27 -0400 Subject: [PATCH 441/739] Shared: move shared file to 'shared' folder and add parameterized module for 'getInvalidModelKind' --- config/identical-files.json | 9 - csharp/ql/lib/qlpack.yml | 1 + .../code/csharp/dataflow/ExternalFlow.qll | 44 ++--- .../internal/SharedModelValidation.qll | 143 -------------- go/ql/lib/qlpack.yml | 1 + go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 39 ++-- .../internal/SharedModelValidation.qll | 143 -------------- java/ql/lib/qlpack.yml | 1 + .../code/java/dataflow/ExternalFlow.qll | 44 ++--- .../internal/SharedModelValidation.qll | 143 -------------- javascript/ql/lib/qlpack.yml | 1 + .../data/internal/ApiGraphModels.qll | 39 ++-- .../data/internal/SharedModelValidation.qll | 143 -------------- python/ql/lib/qlpack.yml | 1 + .../data/internal/ApiGraphModels.qll | 39 ++-- .../data/internal/SharedModelValidation.qll | 143 -------------- .../data/internal/ApiGraphModels.qll | 39 ++-- .../data/internal/SharedModelValidation.qll | 143 -------------- ruby/ql/lib/qlpack.yml | 1 + shared/mad/codeql-pack.lock.yml | 4 + shared/mad/codeql-pack.release.yml | 2 + shared/mad/codeql/mad/ModelValidation.qll | 177 ++++++++++++++++++ shared/mad/qlpack.yml | 6 + .../codeql/swift/dataflow/ExternalFlow.qll | 40 ++-- .../internal/SharedModelValidation.qll | 143 -------------- swift/ql/lib/qlpack.yml | 1 + 26 files changed, 308 insertions(+), 1182 deletions(-) delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll delete mode 100644 go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll delete mode 100644 javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll delete mode 100644 python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll delete mode 100644 ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll create mode 100644 shared/mad/codeql-pack.lock.yml create mode 100644 shared/mad/codeql-pack.release.yml create mode 100644 shared/mad/codeql/mad/ModelValidation.qll create mode 100644 shared/mad/qlpack.yml delete mode 100644 swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll diff --git a/config/identical-files.json b/config/identical-files.json index 52adf242dda..3c16c953129 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -598,14 +598,5 @@ "EncryptionKeySizes Python/Java": [ "python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll", "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" - ], - "SharedModelValidation Java/C#/Go/JS/Python/Ruby/Swift": [ - "java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll", - "go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll", - "swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll", - "javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll", - "python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll", - "ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll" ] } diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 17e00fa022c..093187eb865 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -6,6 +6,7 @@ extractor: csharp library: true upgrades: upgrades dependencies: + codeql/mad: ${workspace} codeql/ssa: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 28c681e26df..ae1c928b92c 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -95,7 +95,7 @@ private import internal.DataFlowPublic private import internal.FlowSummaryImpl::Public private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific -private import internal.SharedModelValidation +private import codeql.mad.ModelValidation as SharedModelVal /** Holds if a source model exists for the given parameters. */ predicate sourceModel = Extensions::sourceModel/9; @@ -205,32 +205,20 @@ module ModelValidation { ) } - /** Gets an error message relating to an invalid kind in a model. */ - private string getInvalidModelKind() { - exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSummaryKind and - result = "Invalid kind \"" + kind + "\" in summary model." - ) - or - exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSinkKind and - msg = "Invalid kind \"" + kind + "\" in sink model." and - // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. - if kind instanceof OutdatedSinkKind - then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() - else result = msg - ) - or - exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSourceKind and - result = "Invalid kind \"" + kind + "\" in source model." - ) - or - exists(string kind | neutralModel(_, _, _, _, kind, _) | - not kind instanceof ValidNeutralKind and - result = "Invalid kind \"" + kind + "\" in neutral model." - ) - } + /** Holds if a summary model exists for the given `kind`. */ + private predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } + + /** Holds if a sink model exists for the given `kind`. */ + private predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } + + /** Holds if a source model exists for the given `kind`. */ + private predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + + /** Holds if a neutral model exists for the given `kind`. */ + private predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) } + + private module KindVal = + SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; private string getInvalidModelSignature() { exists( @@ -273,7 +261,7 @@ module ModelValidation { msg = [ getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(), - getInvalidModelKind() + KindVal::getInvalidModelKind() ] } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll deleted file mode 100644 index c322bc62029..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SharedModelValidation.qll +++ /dev/null @@ -1,143 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides classes and predicates related to validating models-as-data rows. - * Such that we can share this logic across our CodeQL analysis of different languages. - */ - -/** A valid models-as-data sink kind. */ -class ValidSinkKind extends string { - bindingset[this] - ValidSinkKind() { - this = - [ - // shared - "code-injection", "command-injection", "file-content-store", "html-injection", - "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", - "sql-injection", "url-redirection", - // Java-only currently, but may be shared in the future - "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", - "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", - "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", - "template-injection", "xpath-injection", "xslt-injection", - // JavaScript-only currently, but may be shared in the future - "mongodb.sink", "nosql-injection", "unsafe-deserialization", - // Swift-only currently, but may be shared in the future - "database-store", "format-string", "hash-iteration-count", "predicate-injection", - "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" - ] - or - this.matches([ - // shared - "encryption-%", "qltest%", "test-%", - // Java-only currently, but may be shared in the future - "regex-use%", - // JavaScript-only currently, but may be shared in the future - "credentials-%", - // Swift-only currently, but may be shared in the future - "%string-%length", "weak-hash-input-%" - ]) - } -} - -/** An outdated models-as-data sink kind. */ -class OutdatedSinkKind extends string { - OutdatedSinkKind() { - this = - [ - "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", - "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", - "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote", "uncontrolled-format-string", "js-eval" - ] - } - - /** Gets a replacement kind for an outdated sink kind. */ - private string replacementKind() { - this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and - result = this + "-injection" - or - this = "js-eval" and result = "code-injection" - or - this = "url-redirect" and result = "url-redirection" - or - this = "ssti" and result = "template-injection" - or - this = "logging" and result = "log-injection" - or - this = "pending-intent-sent" and result = "pending-intents" - or - this = "intent-start" and result = "intent-redirection" - or - this = "set-hostname-verifier" and result = "hostname-verification" - or - this = "header-splitting" and result = "response-splitting" - or - this = "xss" and result = "html-injection\" or \"js-injection" - or - this = ["write-file", "remote"] and result = "file-content-store" - or - this = ["create-file", "read-file"] and result = "path-injection" - or - this = ["open-url", "jdbc-url"] and result = "request-forgery" - or - this = "command-line-injection" and result = "command-injection" - or - this = "uncontrolled-format-string" and result = "format-string" - } - - /** Gets an error message for an outdated sink kind. */ - string outdatedMessage() { - result = - "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." - } -} - -/** A valid models-as-data source kind. */ -class ValidSourceKind extends string { - bindingset[this] - ValidSourceKind() { - this = - [ - // shared - "local", "remote", - // Java - "android-external-storage-dir", "contentprovider", - // C# - "file", "file-write", - // JavaScript - "database-access-result", "remote-flow" - ] - or - this.matches([ - // shared - "qltest%", "test-%", - // Swift - "%string-%length" - ]) - } -} - -/** A valid models-as-data summary kind. */ -class ValidSummaryKind extends string { - ValidSummaryKind() { - this = - [ - // shared - "taint", "value", - // JavaScript - "type" - ] - } -} - -/** A valid models-as-data neutral kind. */ -class ValidNeutralKind extends string { - ValidNeutralKind() { - this = - [ - // Java/C# currently - "sink", "source", "summary" - ] - } -} diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 287c27187e3..271e9e13385 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -6,6 +6,7 @@ extractor: go library: true upgrades: upgrades dependencies: + codeql/mad: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} dataExtensions: diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 9dbb826c35a..448196fb1a0 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -68,7 +68,7 @@ private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific private import internal.AccessPathSyntax private import FlowSummary -private import internal.SharedModelValidation +private import codeql.mad.ModelValidation as SharedModelVal /** * A module importing the frameworks that provide external flow data, @@ -189,27 +189,20 @@ module ModelValidation { ) } - /** Gets an error message relating to an invalid kind in a model. */ - private string getInvalidModelKind() { - exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSummaryKind and - result = "Invalid kind \"" + kind + "\" in summary model." - ) - or - exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSinkKind and - msg = "Invalid kind \"" + kind + "\" in sink model." and - // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. - if kind instanceof OutdatedSinkKind - then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() - else result = msg - ) - or - exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSourceKind and - result = "Invalid kind \"" + kind + "\" in source model." - ) - } + /** Holds if a summary model exists for the given `kind`. */ + private predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } + + /** Holds if a sink model exists for the given `kind`. */ + private predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } + + /** Holds if a source model exists for the given `kind`. */ + private predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + + /** Holds if a neutral model exists for the given `kind`. */ + private predicate neutralKind(string kind) { none() } + + private module KindVal = + SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; private string getInvalidModelSignature() { exists( @@ -247,7 +240,7 @@ module ModelValidation { msg = [ getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(), - getInvalidModelKind() + KindVal::getInvalidModelKind() ] } } diff --git a/go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll b/go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll deleted file mode 100644 index c322bc62029..00000000000 --- a/go/ql/lib/semmle/go/dataflow/internal/SharedModelValidation.qll +++ /dev/null @@ -1,143 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides classes and predicates related to validating models-as-data rows. - * Such that we can share this logic across our CodeQL analysis of different languages. - */ - -/** A valid models-as-data sink kind. */ -class ValidSinkKind extends string { - bindingset[this] - ValidSinkKind() { - this = - [ - // shared - "code-injection", "command-injection", "file-content-store", "html-injection", - "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", - "sql-injection", "url-redirection", - // Java-only currently, but may be shared in the future - "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", - "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", - "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", - "template-injection", "xpath-injection", "xslt-injection", - // JavaScript-only currently, but may be shared in the future - "mongodb.sink", "nosql-injection", "unsafe-deserialization", - // Swift-only currently, but may be shared in the future - "database-store", "format-string", "hash-iteration-count", "predicate-injection", - "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" - ] - or - this.matches([ - // shared - "encryption-%", "qltest%", "test-%", - // Java-only currently, but may be shared in the future - "regex-use%", - // JavaScript-only currently, but may be shared in the future - "credentials-%", - // Swift-only currently, but may be shared in the future - "%string-%length", "weak-hash-input-%" - ]) - } -} - -/** An outdated models-as-data sink kind. */ -class OutdatedSinkKind extends string { - OutdatedSinkKind() { - this = - [ - "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", - "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", - "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote", "uncontrolled-format-string", "js-eval" - ] - } - - /** Gets a replacement kind for an outdated sink kind. */ - private string replacementKind() { - this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and - result = this + "-injection" - or - this = "js-eval" and result = "code-injection" - or - this = "url-redirect" and result = "url-redirection" - or - this = "ssti" and result = "template-injection" - or - this = "logging" and result = "log-injection" - or - this = "pending-intent-sent" and result = "pending-intents" - or - this = "intent-start" and result = "intent-redirection" - or - this = "set-hostname-verifier" and result = "hostname-verification" - or - this = "header-splitting" and result = "response-splitting" - or - this = "xss" and result = "html-injection\" or \"js-injection" - or - this = ["write-file", "remote"] and result = "file-content-store" - or - this = ["create-file", "read-file"] and result = "path-injection" - or - this = ["open-url", "jdbc-url"] and result = "request-forgery" - or - this = "command-line-injection" and result = "command-injection" - or - this = "uncontrolled-format-string" and result = "format-string" - } - - /** Gets an error message for an outdated sink kind. */ - string outdatedMessage() { - result = - "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." - } -} - -/** A valid models-as-data source kind. */ -class ValidSourceKind extends string { - bindingset[this] - ValidSourceKind() { - this = - [ - // shared - "local", "remote", - // Java - "android-external-storage-dir", "contentprovider", - // C# - "file", "file-write", - // JavaScript - "database-access-result", "remote-flow" - ] - or - this.matches([ - // shared - "qltest%", "test-%", - // Swift - "%string-%length" - ]) - } -} - -/** A valid models-as-data summary kind. */ -class ValidSummaryKind extends string { - ValidSummaryKind() { - this = - [ - // shared - "taint", "value", - // JavaScript - "type" - ] - } -} - -/** A valid models-as-data neutral kind. */ -class ValidNeutralKind extends string { - ValidNeutralKind() { - this = - [ - // Java/C# currently - "sink", "source", "summary" - ] - } -} diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index ada2ac9e999..c917caf0641 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -6,6 +6,7 @@ extractor: java library: true upgrades: upgrades dependencies: + codeql/mad: ${workspace} codeql/regex: ${workspace} codeql/tutorial: ${workspace} codeql/typetracking: ${workspace} diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 0a838e2fdd9..b0a5b702fa0 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -87,7 +87,7 @@ private import internal.FlowSummaryImplSpecific as FlowSummaryImplSpecific private import internal.AccessPathSyntax private import ExternalFlowExtensions as Extensions private import FlowSummary -private import internal.SharedModelValidation +private import codeql.mad.ModelValidation as SharedModelVal /** * A class for activating additional model rows. @@ -266,32 +266,20 @@ module ModelValidation { ) } - /** Gets an error message relating to an invalid kind in a model. */ - private string getInvalidModelKind() { - exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSummaryKind and - result = "Invalid kind \"" + kind + "\" in summary model." - ) - or - exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSinkKind and - msg = "Invalid kind \"" + kind + "\" in sink model." and - // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. - if kind instanceof OutdatedSinkKind - then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() - else result = msg - ) - or - exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSourceKind and - result = "Invalid kind \"" + kind + "\" in source model." - ) - or - exists(string kind | neutralModel(_, _, _, _, kind, _) | - not kind instanceof ValidNeutralKind and - result = "Invalid kind \"" + kind + "\" in neutral model." - ) - } + /** Holds if a summary model exists for the given `kind`. */ + private predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } + + /** Holds if a sink model exists for the given `kind`. */ + private predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } + + /** Holds if a source model exists for the given `kind`. */ + private predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + + /** Holds if a neutral model exists for the given `kind`. */ + private predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) } + + private module KindVal = + SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; private string getInvalidModelSignature() { exists( @@ -334,7 +322,7 @@ module ModelValidation { msg = [ getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(), - getInvalidModelKind() + KindVal::getInvalidModelKind() ] } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll b/java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll deleted file mode 100644 index c322bc62029..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/SharedModelValidation.qll +++ /dev/null @@ -1,143 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides classes and predicates related to validating models-as-data rows. - * Such that we can share this logic across our CodeQL analysis of different languages. - */ - -/** A valid models-as-data sink kind. */ -class ValidSinkKind extends string { - bindingset[this] - ValidSinkKind() { - this = - [ - // shared - "code-injection", "command-injection", "file-content-store", "html-injection", - "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", - "sql-injection", "url-redirection", - // Java-only currently, but may be shared in the future - "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", - "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", - "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", - "template-injection", "xpath-injection", "xslt-injection", - // JavaScript-only currently, but may be shared in the future - "mongodb.sink", "nosql-injection", "unsafe-deserialization", - // Swift-only currently, but may be shared in the future - "database-store", "format-string", "hash-iteration-count", "predicate-injection", - "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" - ] - or - this.matches([ - // shared - "encryption-%", "qltest%", "test-%", - // Java-only currently, but may be shared in the future - "regex-use%", - // JavaScript-only currently, but may be shared in the future - "credentials-%", - // Swift-only currently, but may be shared in the future - "%string-%length", "weak-hash-input-%" - ]) - } -} - -/** An outdated models-as-data sink kind. */ -class OutdatedSinkKind extends string { - OutdatedSinkKind() { - this = - [ - "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", - "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", - "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote", "uncontrolled-format-string", "js-eval" - ] - } - - /** Gets a replacement kind for an outdated sink kind. */ - private string replacementKind() { - this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and - result = this + "-injection" - or - this = "js-eval" and result = "code-injection" - or - this = "url-redirect" and result = "url-redirection" - or - this = "ssti" and result = "template-injection" - or - this = "logging" and result = "log-injection" - or - this = "pending-intent-sent" and result = "pending-intents" - or - this = "intent-start" and result = "intent-redirection" - or - this = "set-hostname-verifier" and result = "hostname-verification" - or - this = "header-splitting" and result = "response-splitting" - or - this = "xss" and result = "html-injection\" or \"js-injection" - or - this = ["write-file", "remote"] and result = "file-content-store" - or - this = ["create-file", "read-file"] and result = "path-injection" - or - this = ["open-url", "jdbc-url"] and result = "request-forgery" - or - this = "command-line-injection" and result = "command-injection" - or - this = "uncontrolled-format-string" and result = "format-string" - } - - /** Gets an error message for an outdated sink kind. */ - string outdatedMessage() { - result = - "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." - } -} - -/** A valid models-as-data source kind. */ -class ValidSourceKind extends string { - bindingset[this] - ValidSourceKind() { - this = - [ - // shared - "local", "remote", - // Java - "android-external-storage-dir", "contentprovider", - // C# - "file", "file-write", - // JavaScript - "database-access-result", "remote-flow" - ] - or - this.matches([ - // shared - "qltest%", "test-%", - // Swift - "%string-%length" - ]) - } -} - -/** A valid models-as-data summary kind. */ -class ValidSummaryKind extends string { - ValidSummaryKind() { - this = - [ - // shared - "taint", "value", - // JavaScript - "type" - ] - } -} - -/** A valid models-as-data neutral kind. */ -class ValidNeutralKind extends string { - ValidNeutralKind() { - this = - [ - // Java/C# currently - "sink", "source", "summary" - ] - } -} diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 52962f549b0..d0efe424316 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -6,6 +6,7 @@ extractor: javascript library: true upgrades: upgrades dependencies: + codeql/mad: ${workspace} codeql/regex: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index 10bea158266..f3474d452f4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -653,29 +653,22 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific - private import SharedModelValidation + private import codeql.mad.ModelValidation as SharedModelVal - /** Gets an error message relating to an invalid kind in a model. */ - private string getInvalidModelKind() { - exists(string kind | summaryModel(_, _, _, _, kind) | - not kind instanceof ValidSummaryKind and - result = "Invalid kind \"" + kind + "\" in summary model." - ) - or - exists(string kind, string msg | sinkModel(_, _, kind) | - not kind instanceof ValidSinkKind and - msg = "Invalid kind \"" + kind + "\" in sink model." and - // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. - if kind instanceof OutdatedSinkKind - then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() - else result = msg - ) - or - exists(string kind | sourceModel(_, _, kind) | - not kind instanceof ValidSourceKind and - result = "Invalid kind \"" + kind + "\" in source model." - ) - } + /** Holds if a summary model exists for the given `kind`. */ + private predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } + + /** Holds if a sink model exists for the given `kind`. */ + private predicate sinkKind(string kind) { sinkModel(_, _, kind) } + + /** Holds if a source model exists for the given `kind`. */ + private predicate sourceKind(string kind) { sourceModel(_, _, kind) } + + /** Holds if a neutral model exists for the given `kind`. */ + private predicate neutralKind(string kind) { none() } + + private module KindVal = + SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; /** * Gets an error message relating to an invalid CSV row in a model. @@ -723,6 +716,6 @@ module ModelOutput { ) or // Check for invalid model kinds - result = getInvalidModelKind() + result = KindVal::getInvalidModelKind() } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll deleted file mode 100644 index c322bc62029..00000000000 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/SharedModelValidation.qll +++ /dev/null @@ -1,143 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides classes and predicates related to validating models-as-data rows. - * Such that we can share this logic across our CodeQL analysis of different languages. - */ - -/** A valid models-as-data sink kind. */ -class ValidSinkKind extends string { - bindingset[this] - ValidSinkKind() { - this = - [ - // shared - "code-injection", "command-injection", "file-content-store", "html-injection", - "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", - "sql-injection", "url-redirection", - // Java-only currently, but may be shared in the future - "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", - "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", - "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", - "template-injection", "xpath-injection", "xslt-injection", - // JavaScript-only currently, but may be shared in the future - "mongodb.sink", "nosql-injection", "unsafe-deserialization", - // Swift-only currently, but may be shared in the future - "database-store", "format-string", "hash-iteration-count", "predicate-injection", - "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" - ] - or - this.matches([ - // shared - "encryption-%", "qltest%", "test-%", - // Java-only currently, but may be shared in the future - "regex-use%", - // JavaScript-only currently, but may be shared in the future - "credentials-%", - // Swift-only currently, but may be shared in the future - "%string-%length", "weak-hash-input-%" - ]) - } -} - -/** An outdated models-as-data sink kind. */ -class OutdatedSinkKind extends string { - OutdatedSinkKind() { - this = - [ - "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", - "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", - "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote", "uncontrolled-format-string", "js-eval" - ] - } - - /** Gets a replacement kind for an outdated sink kind. */ - private string replacementKind() { - this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and - result = this + "-injection" - or - this = "js-eval" and result = "code-injection" - or - this = "url-redirect" and result = "url-redirection" - or - this = "ssti" and result = "template-injection" - or - this = "logging" and result = "log-injection" - or - this = "pending-intent-sent" and result = "pending-intents" - or - this = "intent-start" and result = "intent-redirection" - or - this = "set-hostname-verifier" and result = "hostname-verification" - or - this = "header-splitting" and result = "response-splitting" - or - this = "xss" and result = "html-injection\" or \"js-injection" - or - this = ["write-file", "remote"] and result = "file-content-store" - or - this = ["create-file", "read-file"] and result = "path-injection" - or - this = ["open-url", "jdbc-url"] and result = "request-forgery" - or - this = "command-line-injection" and result = "command-injection" - or - this = "uncontrolled-format-string" and result = "format-string" - } - - /** Gets an error message for an outdated sink kind. */ - string outdatedMessage() { - result = - "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." - } -} - -/** A valid models-as-data source kind. */ -class ValidSourceKind extends string { - bindingset[this] - ValidSourceKind() { - this = - [ - // shared - "local", "remote", - // Java - "android-external-storage-dir", "contentprovider", - // C# - "file", "file-write", - // JavaScript - "database-access-result", "remote-flow" - ] - or - this.matches([ - // shared - "qltest%", "test-%", - // Swift - "%string-%length" - ]) - } -} - -/** A valid models-as-data summary kind. */ -class ValidSummaryKind extends string { - ValidSummaryKind() { - this = - [ - // shared - "taint", "value", - // JavaScript - "type" - ] - } -} - -/** A valid models-as-data neutral kind. */ -class ValidNeutralKind extends string { - ValidNeutralKind() { - this = - [ - // Java/C# currently - "sink", "source", "summary" - ] - } -} diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 9d4522d5f58..0d2694d78fe 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -6,6 +6,7 @@ extractor: python library: true upgrades: upgrades dependencies: + codeql/mad: ${workspace} codeql/regex: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index 10bea158266..f3474d452f4 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -653,29 +653,22 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific - private import SharedModelValidation + private import codeql.mad.ModelValidation as SharedModelVal - /** Gets an error message relating to an invalid kind in a model. */ - private string getInvalidModelKind() { - exists(string kind | summaryModel(_, _, _, _, kind) | - not kind instanceof ValidSummaryKind and - result = "Invalid kind \"" + kind + "\" in summary model." - ) - or - exists(string kind, string msg | sinkModel(_, _, kind) | - not kind instanceof ValidSinkKind and - msg = "Invalid kind \"" + kind + "\" in sink model." and - // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. - if kind instanceof OutdatedSinkKind - then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() - else result = msg - ) - or - exists(string kind | sourceModel(_, _, kind) | - not kind instanceof ValidSourceKind and - result = "Invalid kind \"" + kind + "\" in source model." - ) - } + /** Holds if a summary model exists for the given `kind`. */ + private predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } + + /** Holds if a sink model exists for the given `kind`. */ + private predicate sinkKind(string kind) { sinkModel(_, _, kind) } + + /** Holds if a source model exists for the given `kind`. */ + private predicate sourceKind(string kind) { sourceModel(_, _, kind) } + + /** Holds if a neutral model exists for the given `kind`. */ + private predicate neutralKind(string kind) { none() } + + private module KindVal = + SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; /** * Gets an error message relating to an invalid CSV row in a model. @@ -723,6 +716,6 @@ module ModelOutput { ) or // Check for invalid model kinds - result = getInvalidModelKind() + result = KindVal::getInvalidModelKind() } } diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll b/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll deleted file mode 100644 index c322bc62029..00000000000 --- a/python/ql/lib/semmle/python/frameworks/data/internal/SharedModelValidation.qll +++ /dev/null @@ -1,143 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides classes and predicates related to validating models-as-data rows. - * Such that we can share this logic across our CodeQL analysis of different languages. - */ - -/** A valid models-as-data sink kind. */ -class ValidSinkKind extends string { - bindingset[this] - ValidSinkKind() { - this = - [ - // shared - "code-injection", "command-injection", "file-content-store", "html-injection", - "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", - "sql-injection", "url-redirection", - // Java-only currently, but may be shared in the future - "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", - "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", - "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", - "template-injection", "xpath-injection", "xslt-injection", - // JavaScript-only currently, but may be shared in the future - "mongodb.sink", "nosql-injection", "unsafe-deserialization", - // Swift-only currently, but may be shared in the future - "database-store", "format-string", "hash-iteration-count", "predicate-injection", - "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" - ] - or - this.matches([ - // shared - "encryption-%", "qltest%", "test-%", - // Java-only currently, but may be shared in the future - "regex-use%", - // JavaScript-only currently, but may be shared in the future - "credentials-%", - // Swift-only currently, but may be shared in the future - "%string-%length", "weak-hash-input-%" - ]) - } -} - -/** An outdated models-as-data sink kind. */ -class OutdatedSinkKind extends string { - OutdatedSinkKind() { - this = - [ - "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", - "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", - "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote", "uncontrolled-format-string", "js-eval" - ] - } - - /** Gets a replacement kind for an outdated sink kind. */ - private string replacementKind() { - this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and - result = this + "-injection" - or - this = "js-eval" and result = "code-injection" - or - this = "url-redirect" and result = "url-redirection" - or - this = "ssti" and result = "template-injection" - or - this = "logging" and result = "log-injection" - or - this = "pending-intent-sent" and result = "pending-intents" - or - this = "intent-start" and result = "intent-redirection" - or - this = "set-hostname-verifier" and result = "hostname-verification" - or - this = "header-splitting" and result = "response-splitting" - or - this = "xss" and result = "html-injection\" or \"js-injection" - or - this = ["write-file", "remote"] and result = "file-content-store" - or - this = ["create-file", "read-file"] and result = "path-injection" - or - this = ["open-url", "jdbc-url"] and result = "request-forgery" - or - this = "command-line-injection" and result = "command-injection" - or - this = "uncontrolled-format-string" and result = "format-string" - } - - /** Gets an error message for an outdated sink kind. */ - string outdatedMessage() { - result = - "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." - } -} - -/** A valid models-as-data source kind. */ -class ValidSourceKind extends string { - bindingset[this] - ValidSourceKind() { - this = - [ - // shared - "local", "remote", - // Java - "android-external-storage-dir", "contentprovider", - // C# - "file", "file-write", - // JavaScript - "database-access-result", "remote-flow" - ] - or - this.matches([ - // shared - "qltest%", "test-%", - // Swift - "%string-%length" - ]) - } -} - -/** A valid models-as-data summary kind. */ -class ValidSummaryKind extends string { - ValidSummaryKind() { - this = - [ - // shared - "taint", "value", - // JavaScript - "type" - ] - } -} - -/** A valid models-as-data neutral kind. */ -class ValidNeutralKind extends string { - ValidNeutralKind() { - this = - [ - // Java/C# currently - "sink", "source", "summary" - ] - } -} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index 10bea158266..f3474d452f4 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -653,29 +653,22 @@ module ModelOutput { import Cached import Specific::ModelOutputSpecific - private import SharedModelValidation + private import codeql.mad.ModelValidation as SharedModelVal - /** Gets an error message relating to an invalid kind in a model. */ - private string getInvalidModelKind() { - exists(string kind | summaryModel(_, _, _, _, kind) | - not kind instanceof ValidSummaryKind and - result = "Invalid kind \"" + kind + "\" in summary model." - ) - or - exists(string kind, string msg | sinkModel(_, _, kind) | - not kind instanceof ValidSinkKind and - msg = "Invalid kind \"" + kind + "\" in sink model." and - // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. - if kind instanceof OutdatedSinkKind - then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() - else result = msg - ) - or - exists(string kind | sourceModel(_, _, kind) | - not kind instanceof ValidSourceKind and - result = "Invalid kind \"" + kind + "\" in source model." - ) - } + /** Holds if a summary model exists for the given `kind`. */ + private predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } + + /** Holds if a sink model exists for the given `kind`. */ + private predicate sinkKind(string kind) { sinkModel(_, _, kind) } + + /** Holds if a source model exists for the given `kind`. */ + private predicate sourceKind(string kind) { sourceModel(_, _, kind) } + + /** Holds if a neutral model exists for the given `kind`. */ + private predicate neutralKind(string kind) { none() } + + private module KindVal = + SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; /** * Gets an error message relating to an invalid CSV row in a model. @@ -723,6 +716,6 @@ module ModelOutput { ) or // Check for invalid model kinds - result = getInvalidModelKind() + result = KindVal::getInvalidModelKind() } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll deleted file mode 100644 index c322bc62029..00000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/SharedModelValidation.qll +++ /dev/null @@ -1,143 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides classes and predicates related to validating models-as-data rows. - * Such that we can share this logic across our CodeQL analysis of different languages. - */ - -/** A valid models-as-data sink kind. */ -class ValidSinkKind extends string { - bindingset[this] - ValidSinkKind() { - this = - [ - // shared - "code-injection", "command-injection", "file-content-store", "html-injection", - "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", - "sql-injection", "url-redirection", - // Java-only currently, but may be shared in the future - "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", - "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", - "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", - "template-injection", "xpath-injection", "xslt-injection", - // JavaScript-only currently, but may be shared in the future - "mongodb.sink", "nosql-injection", "unsafe-deserialization", - // Swift-only currently, but may be shared in the future - "database-store", "format-string", "hash-iteration-count", "predicate-injection", - "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" - ] - or - this.matches([ - // shared - "encryption-%", "qltest%", "test-%", - // Java-only currently, but may be shared in the future - "regex-use%", - // JavaScript-only currently, but may be shared in the future - "credentials-%", - // Swift-only currently, but may be shared in the future - "%string-%length", "weak-hash-input-%" - ]) - } -} - -/** An outdated models-as-data sink kind. */ -class OutdatedSinkKind extends string { - OutdatedSinkKind() { - this = - [ - "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", - "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", - "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote", "uncontrolled-format-string", "js-eval" - ] - } - - /** Gets a replacement kind for an outdated sink kind. */ - private string replacementKind() { - this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and - result = this + "-injection" - or - this = "js-eval" and result = "code-injection" - or - this = "url-redirect" and result = "url-redirection" - or - this = "ssti" and result = "template-injection" - or - this = "logging" and result = "log-injection" - or - this = "pending-intent-sent" and result = "pending-intents" - or - this = "intent-start" and result = "intent-redirection" - or - this = "set-hostname-verifier" and result = "hostname-verification" - or - this = "header-splitting" and result = "response-splitting" - or - this = "xss" and result = "html-injection\" or \"js-injection" - or - this = ["write-file", "remote"] and result = "file-content-store" - or - this = ["create-file", "read-file"] and result = "path-injection" - or - this = ["open-url", "jdbc-url"] and result = "request-forgery" - or - this = "command-line-injection" and result = "command-injection" - or - this = "uncontrolled-format-string" and result = "format-string" - } - - /** Gets an error message for an outdated sink kind. */ - string outdatedMessage() { - result = - "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." - } -} - -/** A valid models-as-data source kind. */ -class ValidSourceKind extends string { - bindingset[this] - ValidSourceKind() { - this = - [ - // shared - "local", "remote", - // Java - "android-external-storage-dir", "contentprovider", - // C# - "file", "file-write", - // JavaScript - "database-access-result", "remote-flow" - ] - or - this.matches([ - // shared - "qltest%", "test-%", - // Swift - "%string-%length" - ]) - } -} - -/** A valid models-as-data summary kind. */ -class ValidSummaryKind extends string { - ValidSummaryKind() { - this = - [ - // shared - "taint", "value", - // JavaScript - "type" - ] - } -} - -/** A valid models-as-data neutral kind. */ -class ValidNeutralKind extends string { - ValidNeutralKind() { - this = - [ - // Java/C# currently - "sink", "source", "summary" - ] - } -} diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index bb01a5ff87d..d201621268e 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -6,6 +6,7 @@ dbscheme: ruby.dbscheme upgrades: upgrades library: true dependencies: + codeql/mad: ${workspace} codeql/regex: ${workspace} codeql/ssa: ${workspace} codeql/tutorial: ${workspace} diff --git a/shared/mad/codeql-pack.lock.yml b/shared/mad/codeql-pack.lock.yml new file mode 100644 index 00000000000..06dd07fc7dc --- /dev/null +++ b/shared/mad/codeql-pack.lock.yml @@ -0,0 +1,4 @@ +--- +dependencies: {} +compiled: false +lockVersion: 1.0.0 diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml new file mode 100644 index 00000000000..044e54e4f7e --- /dev/null +++ b/shared/mad/codeql-pack.release.yml @@ -0,0 +1,2 @@ +--- +lastReleaseVersion: 0.0.13 diff --git a/shared/mad/codeql/mad/ModelValidation.qll b/shared/mad/codeql/mad/ModelValidation.qll new file mode 100644 index 00000000000..556e233ce2e --- /dev/null +++ b/shared/mad/codeql/mad/ModelValidation.qll @@ -0,0 +1,177 @@ +/** + * Provides classes and predicates related to validating models-as-data rows. + */ + +/** Holds if a model exists for the given `kind`. */ +signature predicate modelKindSig(string kind); + +/** Provides validation for models-as-data summary, sink, source, and neutral kinds. */ +module KindValidation< + modelKindSig/1 summaryKind, modelKindSig/1 sinkKind, modelKindSig/1 sourceKind, + modelKindSig/1 neutralKind> +{ + /** A valid models-as-data sink kind. */ + private class ValidSinkKind extends string { + bindingset[this] + ValidSinkKind() { + this = + [ + // shared + "code-injection", "command-injection", "file-content-store", "html-injection", + "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", + "sql-injection", "url-redirection", + // Java-only currently, but may be shared in the future + "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", + "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", + "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", + "template-injection", "xpath-injection", "xslt-injection", + // JavaScript-only currently, but may be shared in the future + "mongodb.sink", "nosql-injection", "unsafe-deserialization", + // Swift-only currently, but may be shared in the future + "database-store", "format-string", "hash-iteration-count", "predicate-injection", + "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" + ] + or + this.matches([ + // shared + "encryption-%", "qltest%", "test-%", + // Java-only currently, but may be shared in the future + "regex-use%", + // JavaScript-only currently, but may be shared in the future + "credentials-%", + // Swift-only currently, but may be shared in the future + "%string-%length", "weak-hash-input-%" + ]) + } + } + + /** An outdated models-as-data sink kind. */ + private class OutdatedSinkKind extends string { + OutdatedSinkKind() { + this = + [ + "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", + "ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier", + "header-splitting", "xss", "write-file", "create-file", "read-file", "open-url", + "jdbc-url", "command-line-injection", "code", "html", "remote", + "uncontrolled-format-string", "js-eval" + ] + } + + /** Gets a replacement kind for an outdated sink kind. */ + private string replacementKind() { + this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and + result = this + "-injection" + or + this = "js-eval" and result = "code-injection" + or + this = "url-redirect" and result = "url-redirection" + or + this = "ssti" and result = "template-injection" + or + this = "logging" and result = "log-injection" + or + this = "pending-intent-sent" and result = "pending-intents" + or + this = "intent-start" and result = "intent-redirection" + or + this = "set-hostname-verifier" and result = "hostname-verification" + or + this = "header-splitting" and result = "response-splitting" + or + this = "xss" and result = "html-injection\" or \"js-injection" + or + this = ["write-file", "remote"] and result = "file-content-store" + or + this = ["create-file", "read-file"] and result = "path-injection" + or + this = ["open-url", "jdbc-url"] and result = "request-forgery" + or + this = "command-line-injection" and result = "command-injection" + or + this = "uncontrolled-format-string" and result = "format-string" + } + + /** Gets an error message for an outdated sink kind. */ + string outdatedMessage() { + result = + "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." + } + } + + /** A valid models-as-data source kind. */ + private class ValidSourceKind extends string { + bindingset[this] + ValidSourceKind() { + this = + [ + // shared + "local", "remote", + // Java + "android-external-storage-dir", "contentprovider", + // C# + "file", "file-write", + // JavaScript + "database-access-result", "remote-flow" + ] + or + this.matches([ + // shared + "qltest%", "test-%", + // Swift + "%string-%length" + ]) + } + } + + /** A valid models-as-data summary kind. */ + private class ValidSummaryKind extends string { + ValidSummaryKind() { + this = + [ + // shared + "taint", "value", + // JavaScript + "type" + ] + } + } + + /** A valid models-as-data neutral kind. */ + private class ValidNeutralKind extends string { + ValidNeutralKind() { + this = + [ + // Java/C# currently + "sink", "source", "summary" + ] + } + } + + /** Gets an error message relating to an invalid kind in a model. */ + string getInvalidModelKind() { + exists(string kind | summaryKind(kind) | + not kind instanceof ValidSummaryKind and + result = "Invalid kind \"" + kind + "\" in summary model." + ) + or + exists(string kind, string msg | sinkKind(kind) | + not kind instanceof ValidSinkKind and + msg = "Invalid kind \"" + kind + "\" in sink model." and + // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. + if kind instanceof OutdatedSinkKind + then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() + else result = msg + ) + or + exists(string kind | sourceKind(kind) | + not kind instanceof ValidSourceKind and + result = "Invalid kind \"" + kind + "\" in source model." + ) + or + exists(string kind | neutralKind(kind) | + not kind instanceof ValidNeutralKind and + result = "Invalid kind \"" + kind + "\" in neutral model." + ) + } +} diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml new file mode 100644 index 00000000000..2b06aadd2cb --- /dev/null +++ b/shared/mad/qlpack.yml @@ -0,0 +1,6 @@ +name: codeql/mad +version: 0.0.14-dev +groups: shared +library: true +dependencies: +warnOnImplicitThis: true diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 729262deef8..d55563604c6 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -74,7 +74,7 @@ private import internal.FlowSummaryImpl::Public private import internal.FlowSummaryImpl::Private::External private import internal.FlowSummaryImplSpecific private import FlowSummary as FlowSummary -private import internal.SharedModelValidation +private import codeql.mad.ModelValidation as SharedModelVal /** * A unit class for adding additional source model rows. @@ -264,28 +264,20 @@ module CsvValidation { ) } - /** Gets an error message relating to an invalid kind in a model. */ - private string getInvalidModelKind() { - exists(string row, string kind | summaryModel(row) | - kind = row.splitAt(";", 8) and - not kind instanceof ValidSummaryKind and - result = "Invalid kind \"" + kind + "\" in summary model." - ) - or - exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSinkKind and - msg = "Invalid kind \"" + kind + "\" in sink model." and - // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. - if kind instanceof OutdatedSinkKind - then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() - else result = msg - ) - or - exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) | - not kind instanceof ValidSourceKind and - result = "Invalid kind \"" + kind + "\" in source model." - ) - } + /** Holds if a summary model exists for the given `kind`. */ + private predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } + + /** Holds if a sink model exists for the given `kind`. */ + private predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } + + /** Holds if a source model exists for the given `kind`. */ + private predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + + /** Holds if a neutral model exists for the given `kind`. */ + private predicate neutralKind(string kind) { none() } + + private module KindVal = + SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; private string getInvalidModelSubtype() { exists(string pred, string row | @@ -351,7 +343,7 @@ module CsvValidation { msg = [ getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(), - getInvalidModelSubtype(), getInvalidModelColumnCount(), getInvalidModelKind() + getInvalidModelSubtype(), getInvalidModelColumnCount(), KindVal::getInvalidModelKind() ] } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll b/swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll deleted file mode 100644 index c322bc62029..00000000000 --- a/swift/ql/lib/codeql/swift/dataflow/internal/SharedModelValidation.qll +++ /dev/null @@ -1,143 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides classes and predicates related to validating models-as-data rows. - * Such that we can share this logic across our CodeQL analysis of different languages. - */ - -/** A valid models-as-data sink kind. */ -class ValidSinkKind extends string { - bindingset[this] - ValidSinkKind() { - this = - [ - // shared - "code-injection", "command-injection", "file-content-store", "html-injection", - "js-injection", "ldap-injection", "log-injection", "path-injection", "request-forgery", - "sql-injection", "url-redirection", - // Java-only currently, but may be shared in the future - "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", - "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", - "mvel-injection", "ognl-injection", "pending-intents", "response-splitting", - "template-injection", "xpath-injection", "xslt-injection", - // JavaScript-only currently, but may be shared in the future - "mongodb.sink", "nosql-injection", "unsafe-deserialization", - // Swift-only currently, but may be shared in the future - "database-store", "format-string", "hash-iteration-count", "predicate-injection", - "preferences-store", "tls-protocol-version", "transmission", "webview-fetch", "xxe" - ] - or - this.matches([ - // shared - "encryption-%", "qltest%", "test-%", - // Java-only currently, but may be shared in the future - "regex-use%", - // JavaScript-only currently, but may be shared in the future - "credentials-%", - // Swift-only currently, but may be shared in the future - "%string-%length", "weak-hash-input-%" - ]) - } -} - -/** An outdated models-as-data sink kind. */ -class OutdatedSinkKind extends string { - OutdatedSinkKind() { - this = - [ - "sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt", "ldap", - "pending-intent-sent", "intent-start", "set-hostname-verifier", "header-splitting", "xss", - "write-file", "create-file", "read-file", "open-url", "jdbc-url", "command-line-injection", - "code", "html", "remote", "uncontrolled-format-string", "js-eval" - ] - } - - /** Gets a replacement kind for an outdated sink kind. */ - private string replacementKind() { - this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap", "code", "html"] and - result = this + "-injection" - or - this = "js-eval" and result = "code-injection" - or - this = "url-redirect" and result = "url-redirection" - or - this = "ssti" and result = "template-injection" - or - this = "logging" and result = "log-injection" - or - this = "pending-intent-sent" and result = "pending-intents" - or - this = "intent-start" and result = "intent-redirection" - or - this = "set-hostname-verifier" and result = "hostname-verification" - or - this = "header-splitting" and result = "response-splitting" - or - this = "xss" and result = "html-injection\" or \"js-injection" - or - this = ["write-file", "remote"] and result = "file-content-store" - or - this = ["create-file", "read-file"] and result = "path-injection" - or - this = ["open-url", "jdbc-url"] and result = "request-forgery" - or - this = "command-line-injection" and result = "command-injection" - or - this = "uncontrolled-format-string" and result = "format-string" - } - - /** Gets an error message for an outdated sink kind. */ - string outdatedMessage() { - result = - "The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead." - } -} - -/** A valid models-as-data source kind. */ -class ValidSourceKind extends string { - bindingset[this] - ValidSourceKind() { - this = - [ - // shared - "local", "remote", - // Java - "android-external-storage-dir", "contentprovider", - // C# - "file", "file-write", - // JavaScript - "database-access-result", "remote-flow" - ] - or - this.matches([ - // shared - "qltest%", "test-%", - // Swift - "%string-%length" - ]) - } -} - -/** A valid models-as-data summary kind. */ -class ValidSummaryKind extends string { - ValidSummaryKind() { - this = - [ - // shared - "taint", "value", - // JavaScript - "type" - ] - } -} - -/** A valid models-as-data neutral kind. */ -class ValidNeutralKind extends string { - ValidNeutralKind() { - this = - [ - // Java/C# currently - "sink", "source", "summary" - ] - } -} diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index f45d347bad3..f5335ce0f3f 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -6,6 +6,7 @@ dbscheme: swift.dbscheme upgrades: upgrades library: true dependencies: + codeql/mad: ${workspace} codeql/ssa: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} From 3bfb5f9ac4696ee208947e6344061a007386dbb0 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 8 Jun 2023 20:15:13 -0400 Subject: [PATCH 442/739] Shared: update comment and remove 'remote-flow' as a source kind --- shared/mad/codeql/mad/ModelValidation.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/mad/codeql/mad/ModelValidation.qll b/shared/mad/codeql/mad/ModelValidation.qll index 556e233ce2e..0486a4b07a2 100644 --- a/shared/mad/codeql/mad/ModelValidation.qll +++ b/shared/mad/codeql/mad/ModelValidation.qll @@ -112,7 +112,7 @@ module KindValidation< // C# "file", "file-write", // JavaScript - "database-access-result", "remote-flow" + "database-access-result" ] or this.matches([ @@ -131,7 +131,7 @@ module KindValidation< [ // shared "taint", "value", - // JavaScript + // Dynamic languages "type" ] } From 81b08b4399a5175bf530374fd71bf4e71cd14e20 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 00:18:12 +0000 Subject: [PATCH 443/739] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 2 +- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 93c93f8ef46..acfd9b9224c 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -22,7 +22,7 @@ com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 com.google.common.flogger,29,,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,, com.google.common.io,8,,73,,1,,,,,,,,,,,,,,7,,,,,,,,,,,,,,,,,,,72,1 -com.google.gson,,,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,14 +com.google.gson,,,44,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30,14 com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, com.jcraft.jsch,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,1, com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index ffd3ce0ed91..3e2043369dc 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -22,6 +22,6 @@ Java framework & library support Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,115,4,,28,14,,35 - Others,"``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,894,528,66,,18,18,,195 - Totals,,255,9194,1997,263,10,122,33,1,385 + Others,"``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,899,528,66,,18,18,,195 + Totals,,255,9199,1997,263,10,122,33,1,385 From bcba1f3a4dbf8b47c1a9bf04de6577906021114a Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 8 Jun 2023 21:51:24 -0400 Subject: [PATCH 444/739] Shared: update pack files --- shared/mad/codeql-pack.lock.yml | 4 ---- shared/mad/codeql-pack.release.yml | 2 -- shared/mad/qlpack.yml | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 shared/mad/codeql-pack.lock.yml delete mode 100644 shared/mad/codeql-pack.release.yml diff --git a/shared/mad/codeql-pack.lock.yml b/shared/mad/codeql-pack.lock.yml deleted file mode 100644 index 06dd07fc7dc..00000000000 --- a/shared/mad/codeql-pack.lock.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -dependencies: {} -compiled: false -lockVersion: 1.0.0 diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml deleted file mode 100644 index 044e54e4f7e..00000000000 --- a/shared/mad/codeql-pack.release.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -lastReleaseVersion: 0.0.13 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index 2b06aadd2cb..27e6c8e9750 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 0.0.14-dev +version: 0.0.1-dev groups: shared library: true dependencies: From 7aede5034d1f12347d9f72d17dc15bb17e6a3730 Mon Sep 17 00:00:00 2001 From: Jami <57204504+jcogs33@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:52:34 -0400 Subject: [PATCH 445/739] Docs: fix typo --- docs/codeql/ql-language-reference/modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/ql-language-reference/modules.rst b/docs/codeql/ql-language-reference/modules.rst index ee0d1f7966b..42344c72e3d 100644 --- a/docs/codeql/ql-language-reference/modules.rst +++ b/docs/codeql/ql-language-reference/modules.rst @@ -139,7 +139,7 @@ Parameterized modules ===================== Parameterized modules are QL's approach to generic programming. -Similar to explicit modules, parameterized modules are defined within other modules using the keywork ``module``. +Similar to explicit modules, parameterized modules are defined within other modules using the keyword ``module``. In addition to the module name, parameterized modules declare one or more parameters between the name and the module body. For example, consider the module ``M``, which takes two predicate parameters and defines a new predicate From 1d87f0793b613b25ed78694ce0c84bc60ce60d2d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 9 May 2023 11:40:35 +0200 Subject: [PATCH 446/739] Dataflow: Minor refactor. --- .../java/dataflow/internal/DataFlowImpl.qll | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index ddf98ac0f2f..77110c0db0d 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -1204,14 +1204,6 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t, ap) } - pragma[inline] - additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap - ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) - } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( @@ -1359,7 +1351,7 @@ module Impl<FullStateConfigSig Config> { ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and + fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1520,14 +1512,14 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap) + fwdFlow(node, state, _, _, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap) and + fwdFlow(node, state, _, _, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -1780,13 +1772,13 @@ module Impl<FullStateConfigSig Config> { boolean fwd, int nodes, int fields, int conscand, int states, int tuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) + ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and @@ -2197,8 +2189,8 @@ module Impl<FullStateConfigSig Config> { import BooleanCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and exists(lcc) @@ -2274,8 +2266,8 @@ module Impl<FullStateConfigSig Config> { pragma[nomagic] predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2365,7 +2357,7 @@ module Impl<FullStateConfigSig Config> { exists(AccessPathFront apf | Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf) + apf, _) ) } @@ -2579,8 +2571,8 @@ module Impl<FullStateConfigSig Config> { import LocalCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2632,7 +2624,7 @@ module Impl<FullStateConfigSig Config> { Stage5::parameterMayFlowThrough(p, _) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0) + TAccessPathApproxSome(apa), _, apa0, _) ) } @@ -2649,7 +2641,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and + Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and Stage5::revFlow(p, state, _) ) } From ad461a87b45113fb29a63dd1ebf2274021b4a5e1 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Mon, 8 May 2023 13:56:26 +0200 Subject: [PATCH 447/739] Dataflow: Strengthen tracked types. --- .../java/dataflow/internal/DataFlowImpl.qll | 92 +++++++++++++++---- .../dataflow/internal/DataFlowPrivate.qll | 13 ++- 2 files changed, 82 insertions(+), 23 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 77110c0db0d..8520f308f55 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ); - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -1199,9 +1199,20 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and + fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) + } + + private predicate fwdFlow1( + NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, + ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa + ) { + fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and PrevStage::revFlow(node, state, apa) and - filter(node, state, t, ap) + filter(node, state, t0, ap, t) + } + + private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { + fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } pragma[assume_small_delta] @@ -1331,6 +1342,11 @@ module Impl<FullStateConfigSig Config> { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and cons = apCons(c, t1, tail) + or + exists(Typ t0 | + typeStrengthen(t0, cons, t2) and + fwdFlowConsCand(t0, cons, c, t1, tail) + ) } pragma[nomagic] @@ -1955,10 +1971,10 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { PrevStage::revFlowState(state) and - exists(t) and + t0 = t and exists(ap) and not stateBarrier(node, state) and ( @@ -2210,10 +2226,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + // We can get away with not using type strengthening here, since we aren't + // going to use the tracked types in the construction of Stage 4 access + // paths. For Stage 4 and onwards, the tracked types must be consistent as + // the cons candidates including types are used to construct subsequent + // access path approximations. + t0 = t and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and ( notExpectsContent(node) or @@ -2325,11 +2347,18 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and ( notExpectsContent(node) or @@ -2601,9 +2630,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and exists(state) and exists(ap) } @@ -2812,9 +2848,7 @@ module Impl<FullStateConfigSig Config> { ap = TAccessPathNil() or // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap) and - Stage5::revFlow(node, state, ap.getApprox()) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) + pathStep(_, node, state, cc, sc, t, ap) } or TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | @@ -3332,13 +3366,31 @@ module Impl<FullStateConfigSig Config> { ap = mid.getAp() } + private predicate pathStep( + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, + AccessPath ap + ) { + exists(DataFlowType t0 | + pathStep0(mid, node, state, cc, sc, t0, ap) and + Stage5::revFlow(node, state, ap.getApprox()) and + ( + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) + ) + } + /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ pragma[assume_small_delta] pragma[nomagic] - private predicate pathStep( + private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 22f84241c96..4782e65b7e7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -176,7 +176,7 @@ predicate expectsContent(Node n, ContentSet c) { * possible flow. A single type is used for all numeric types to account for * numeric conversions, and otherwise the erasure is used. */ -DataFlowType getErasedRepr(Type t) { +RefType getErasedRepr(Type t) { exists(Type e | e = t.getErasure() | if e instanceof NumericOrCharType then result.(BoxedType).getPrimitiveType().getName() = "double" @@ -189,6 +189,15 @@ DataFlowType getErasedRepr(Type t) { t instanceof NullType and result instanceof TypeObject } +class DataFlowType extends SrcRefType { + DataFlowType() { this = getErasedRepr(_) } +} + +pragma[nomagic] +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { + t1.getASourceSupertype+() = t2 +} + pragma[noinline] DataFlowType getNodeType(Node n) { result = getErasedRepr(n.getTypeBound()) @@ -259,8 +268,6 @@ class DataFlowCallable extends TDataFlowCallable { class DataFlowExpr = Expr; -class DataFlowType = RefType; - private newtype TDataFlowCall = TCall(Call c) or TSummaryCall(SummarizedCallable c, Node receiver) { From e8cea79f1d4f4ee71329cfbdf364f1cb2a596fd3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 9 May 2023 11:45:00 +0200 Subject: [PATCH 448/739] Dataflow: Sync. --- .../cpp/dataflow/internal/DataFlowImpl.qll | 124 ++++++++++++------ .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 124 ++++++++++++------ .../csharp/dataflow/internal/DataFlowImpl.qll | 124 ++++++++++++------ .../go/dataflow/internal/DataFlowImpl.qll | 124 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl.qll | 124 ++++++++++++------ .../ruby/dataflow/internal/DataFlowImpl.qll | 124 ++++++++++++------ .../swift/dataflow/internal/DataFlowImpl.qll | 124 ++++++++++++------ 7 files changed, 588 insertions(+), 280 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index ddf98ac0f2f..8520f308f55 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ); - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and - PrevStage::revFlow(node, state, apa) and - filter(node, state, t, ap) + fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) } - pragma[inline] - additional predicate fwdFlow( + private predicate fwdFlow1( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap + ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) + fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and + PrevStage::revFlow(node, state, apa) and + filter(node, state, t0, ap, t) + } + + private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { + fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } pragma[assume_small_delta] @@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and cons = apCons(c, t1, tail) + or + exists(Typ t0 | + typeStrengthen(t0, cons, t2) and + fwdFlowConsCand(t0, cons, c, t1, tail) + ) } pragma[nomagic] @@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> { ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and + fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap) + fwdFlow(node, state, _, _, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap) and + fwdFlow(node, state, _, _, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> { boolean fwd, int nodes, int fields, int conscand, int states, int tuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) + ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and @@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { PrevStage::revFlowState(state) and - exists(t) and + t0 = t and exists(ap) and not stateBarrier(node, state) and ( @@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> { import BooleanCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and exists(lcc) @@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + // We can get away with not using type strengthening here, since we aren't + // going to use the tracked types in the construction of Stage 4 access + // paths. For Stage 4 and onwards, the tracked types must be consistent as + // the cons candidates including types are used to construct subsequent + // access path approximations. + t0 = t and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and ( notExpectsContent(node) or @@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> { pragma[nomagic] predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and ( notExpectsContent(node) or @@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> { exists(AccessPathFront apf | Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf) + apf, _) ) } @@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> { import LocalCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and exists(state) and exists(ap) } @@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> { Stage5::parameterMayFlowThrough(p, _) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0) + TAccessPathApproxSome(apa), _, apa0, _) ) } @@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and + Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> { ap = TAccessPathNil() or // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap) and - Stage5::revFlow(node, state, ap.getApprox()) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) + pathStep(_, node, state, cc, sc, t, ap) } or TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | @@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> { ap = mid.getAp() } + private predicate pathStep( + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, + AccessPath ap + ) { + exists(DataFlowType t0 | + pathStep0(mid, node, state, cc, sc, t0, ap) and + Stage5::revFlow(node, state, ap.getApprox()) and + ( + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) + ) + } + /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ pragma[assume_small_delta] pragma[nomagic] - private predicate pathStep( + private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index ddf98ac0f2f..8520f308f55 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ); - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and - PrevStage::revFlow(node, state, apa) and - filter(node, state, t, ap) + fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) } - pragma[inline] - additional predicate fwdFlow( + private predicate fwdFlow1( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap + ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) + fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and + PrevStage::revFlow(node, state, apa) and + filter(node, state, t0, ap, t) + } + + private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { + fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } pragma[assume_small_delta] @@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and cons = apCons(c, t1, tail) + or + exists(Typ t0 | + typeStrengthen(t0, cons, t2) and + fwdFlowConsCand(t0, cons, c, t1, tail) + ) } pragma[nomagic] @@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> { ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and + fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap) + fwdFlow(node, state, _, _, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap) and + fwdFlow(node, state, _, _, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> { boolean fwd, int nodes, int fields, int conscand, int states, int tuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) + ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and @@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { PrevStage::revFlowState(state) and - exists(t) and + t0 = t and exists(ap) and not stateBarrier(node, state) and ( @@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> { import BooleanCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and exists(lcc) @@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + // We can get away with not using type strengthening here, since we aren't + // going to use the tracked types in the construction of Stage 4 access + // paths. For Stage 4 and onwards, the tracked types must be consistent as + // the cons candidates including types are used to construct subsequent + // access path approximations. + t0 = t and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and ( notExpectsContent(node) or @@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> { pragma[nomagic] predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and ( notExpectsContent(node) or @@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> { exists(AccessPathFront apf | Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf) + apf, _) ) } @@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> { import LocalCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and exists(state) and exists(ap) } @@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> { Stage5::parameterMayFlowThrough(p, _) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0) + TAccessPathApproxSome(apa), _, apa0, _) ) } @@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and + Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> { ap = TAccessPathNil() or // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap) and - Stage5::revFlow(node, state, ap.getApprox()) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) + pathStep(_, node, state, cc, sc, t, ap) } or TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | @@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> { ap = mid.getAp() } + private predicate pathStep( + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, + AccessPath ap + ) { + exists(DataFlowType t0 | + pathStep0(mid, node, state, cc, sc, t0, ap) and + Stage5::revFlow(node, state, ap.getApprox()) and + ( + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) + ) + } + /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ pragma[assume_small_delta] pragma[nomagic] - private predicate pathStep( + private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index ddf98ac0f2f..8520f308f55 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ); - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and - PrevStage::revFlow(node, state, apa) and - filter(node, state, t, ap) + fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) } - pragma[inline] - additional predicate fwdFlow( + private predicate fwdFlow1( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap + ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) + fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and + PrevStage::revFlow(node, state, apa) and + filter(node, state, t0, ap, t) + } + + private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { + fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } pragma[assume_small_delta] @@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and cons = apCons(c, t1, tail) + or + exists(Typ t0 | + typeStrengthen(t0, cons, t2) and + fwdFlowConsCand(t0, cons, c, t1, tail) + ) } pragma[nomagic] @@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> { ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and + fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap) + fwdFlow(node, state, _, _, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap) and + fwdFlow(node, state, _, _, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> { boolean fwd, int nodes, int fields, int conscand, int states, int tuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) + ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and @@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { PrevStage::revFlowState(state) and - exists(t) and + t0 = t and exists(ap) and not stateBarrier(node, state) and ( @@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> { import BooleanCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and exists(lcc) @@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + // We can get away with not using type strengthening here, since we aren't + // going to use the tracked types in the construction of Stage 4 access + // paths. For Stage 4 and onwards, the tracked types must be consistent as + // the cons candidates including types are used to construct subsequent + // access path approximations. + t0 = t and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and ( notExpectsContent(node) or @@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> { pragma[nomagic] predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and ( notExpectsContent(node) or @@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> { exists(AccessPathFront apf | Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf) + apf, _) ) } @@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> { import LocalCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and exists(state) and exists(ap) } @@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> { Stage5::parameterMayFlowThrough(p, _) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0) + TAccessPathApproxSome(apa), _, apa0, _) ) } @@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and + Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> { ap = TAccessPathNil() or // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap) and - Stage5::revFlow(node, state, ap.getApprox()) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) + pathStep(_, node, state, cc, sc, t, ap) } or TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | @@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> { ap = mid.getAp() } + private predicate pathStep( + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, + AccessPath ap + ) { + exists(DataFlowType t0 | + pathStep0(mid, node, state, cc, sc, t0, ap) and + Stage5::revFlow(node, state, ap.getApprox()) and + ( + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) + ) + } + /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ pragma[assume_small_delta] pragma[nomagic] - private predicate pathStep( + private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index ddf98ac0f2f..8520f308f55 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ); - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and - PrevStage::revFlow(node, state, apa) and - filter(node, state, t, ap) + fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) } - pragma[inline] - additional predicate fwdFlow( + private predicate fwdFlow1( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap + ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) + fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and + PrevStage::revFlow(node, state, apa) and + filter(node, state, t0, ap, t) + } + + private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { + fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } pragma[assume_small_delta] @@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and cons = apCons(c, t1, tail) + or + exists(Typ t0 | + typeStrengthen(t0, cons, t2) and + fwdFlowConsCand(t0, cons, c, t1, tail) + ) } pragma[nomagic] @@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> { ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and + fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap) + fwdFlow(node, state, _, _, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap) and + fwdFlow(node, state, _, _, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> { boolean fwd, int nodes, int fields, int conscand, int states, int tuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) + ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and @@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { PrevStage::revFlowState(state) and - exists(t) and + t0 = t and exists(ap) and not stateBarrier(node, state) and ( @@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> { import BooleanCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and exists(lcc) @@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + // We can get away with not using type strengthening here, since we aren't + // going to use the tracked types in the construction of Stage 4 access + // paths. For Stage 4 and onwards, the tracked types must be consistent as + // the cons candidates including types are used to construct subsequent + // access path approximations. + t0 = t and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and ( notExpectsContent(node) or @@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> { pragma[nomagic] predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and ( notExpectsContent(node) or @@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> { exists(AccessPathFront apf | Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf) + apf, _) ) } @@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> { import LocalCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and exists(state) and exists(ap) } @@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> { Stage5::parameterMayFlowThrough(p, _) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0) + TAccessPathApproxSome(apa), _, apa0, _) ) } @@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and + Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> { ap = TAccessPathNil() or // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap) and - Stage5::revFlow(node, state, ap.getApprox()) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) + pathStep(_, node, state, cc, sc, t, ap) } or TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | @@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> { ap = mid.getAp() } + private predicate pathStep( + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, + AccessPath ap + ) { + exists(DataFlowType t0 | + pathStep0(mid, node, state, cc, sc, t0, ap) and + Stage5::revFlow(node, state, ap.getApprox()) and + ( + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) + ) + } + /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ pragma[assume_small_delta] pragma[nomagic] - private predicate pathStep( + private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index ddf98ac0f2f..8520f308f55 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ); - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and - PrevStage::revFlow(node, state, apa) and - filter(node, state, t, ap) + fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) } - pragma[inline] - additional predicate fwdFlow( + private predicate fwdFlow1( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap + ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) + fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and + PrevStage::revFlow(node, state, apa) and + filter(node, state, t0, ap, t) + } + + private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { + fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } pragma[assume_small_delta] @@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and cons = apCons(c, t1, tail) + or + exists(Typ t0 | + typeStrengthen(t0, cons, t2) and + fwdFlowConsCand(t0, cons, c, t1, tail) + ) } pragma[nomagic] @@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> { ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and + fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap) + fwdFlow(node, state, _, _, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap) and + fwdFlow(node, state, _, _, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> { boolean fwd, int nodes, int fields, int conscand, int states, int tuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) + ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and @@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { PrevStage::revFlowState(state) and - exists(t) and + t0 = t and exists(ap) and not stateBarrier(node, state) and ( @@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> { import BooleanCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and exists(lcc) @@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + // We can get away with not using type strengthening here, since we aren't + // going to use the tracked types in the construction of Stage 4 access + // paths. For Stage 4 and onwards, the tracked types must be consistent as + // the cons candidates including types are used to construct subsequent + // access path approximations. + t0 = t and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and ( notExpectsContent(node) or @@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> { pragma[nomagic] predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and ( notExpectsContent(node) or @@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> { exists(AccessPathFront apf | Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf) + apf, _) ) } @@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> { import LocalCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and exists(state) and exists(ap) } @@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> { Stage5::parameterMayFlowThrough(p, _) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0) + TAccessPathApproxSome(apa), _, apa0, _) ) } @@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and + Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> { ap = TAccessPathNil() or // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap) and - Stage5::revFlow(node, state, ap.getApprox()) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) + pathStep(_, node, state, cc, sc, t, ap) } or TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | @@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> { ap = mid.getAp() } + private predicate pathStep( + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, + AccessPath ap + ) { + exists(DataFlowType t0 | + pathStep0(mid, node, state, cc, sc, t0, ap) and + Stage5::revFlow(node, state, ap.getApprox()) and + ( + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) + ) + } + /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ pragma[assume_small_delta] pragma[nomagic] - private predicate pathStep( + private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index ddf98ac0f2f..8520f308f55 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ); - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and - PrevStage::revFlow(node, state, apa) and - filter(node, state, t, ap) + fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) } - pragma[inline] - additional predicate fwdFlow( + private predicate fwdFlow1( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap + ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) + fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and + PrevStage::revFlow(node, state, apa) and + filter(node, state, t0, ap, t) + } + + private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { + fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } pragma[assume_small_delta] @@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and cons = apCons(c, t1, tail) + or + exists(Typ t0 | + typeStrengthen(t0, cons, t2) and + fwdFlowConsCand(t0, cons, c, t1, tail) + ) } pragma[nomagic] @@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> { ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and + fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap) + fwdFlow(node, state, _, _, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap) and + fwdFlow(node, state, _, _, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> { boolean fwd, int nodes, int fields, int conscand, int states, int tuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) + ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and @@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { PrevStage::revFlowState(state) and - exists(t) and + t0 = t and exists(ap) and not stateBarrier(node, state) and ( @@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> { import BooleanCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and exists(lcc) @@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + // We can get away with not using type strengthening here, since we aren't + // going to use the tracked types in the construction of Stage 4 access + // paths. For Stage 4 and onwards, the tracked types must be consistent as + // the cons candidates including types are used to construct subsequent + // access path approximations. + t0 = t and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and ( notExpectsContent(node) or @@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> { pragma[nomagic] predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and ( notExpectsContent(node) or @@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> { exists(AccessPathFront apf | Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf) + apf, _) ) } @@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> { import LocalCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and exists(state) and exists(ap) } @@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> { Stage5::parameterMayFlowThrough(p, _) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0) + TAccessPathApproxSome(apa), _, apa0, _) ) } @@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and + Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> { ap = TAccessPathNil() or // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap) and - Stage5::revFlow(node, state, ap.getApprox()) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) + pathStep(_, node, state, cc, sc, t, ap) } or TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | @@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> { ap = mid.getAp() } + private predicate pathStep( + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, + AccessPath ap + ) { + exists(DataFlowType t0 | + pathStep0(mid, node, state, cc, sc, t0, ap) and + Stage5::revFlow(node, state, ap.getApprox()) and + ( + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) + ) + } + /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ pragma[assume_small_delta] pragma[nomagic] - private predicate pathStep( + private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index ddf98ac0f2f..8520f308f55 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> { DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ); - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and - PrevStage::revFlow(node, state, apa) and - filter(node, state, t, ap) + fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) } - pragma[inline] - additional predicate fwdFlow( + private predicate fwdFlow1( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap + ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) + fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and + PrevStage::revFlow(node, state, apa) and + filter(node, state, t0, ap, t) + } + + private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { + fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } pragma[assume_small_delta] @@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and cons = apCons(c, t1, tail) + or + exists(Typ t0 | + typeStrengthen(t0, cons, t2) and + fwdFlowConsCand(t0, cons, c, t1, tail) + ) } pragma[nomagic] @@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> { ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and + fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap) + fwdFlow(node, state, _, _, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap) and + fwdFlow(node, state, _, _, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> { boolean fwd, int nodes, int fields, int conscand, int states, int tuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and tuples = count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) + ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _)) or fwd = false and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and @@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { PrevStage::revFlowState(state) and - exists(t) and + t0 = t and exists(ap) and not stateBarrier(node, state) and ( @@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> { import BooleanCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and exists(lcc) @@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + // We can get away with not using type strengthening here, since we aren't + // going to use the tracked types in the construction of Stage 4 access + // paths. For Stage 4 and onwards, the tracked types must be consistent as + // the cons candidates including types are used to construct subsequent + // access path approximations. + t0 = t and + (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and ( notExpectsContent(node) or @@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> { pragma[nomagic] predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and ( notExpectsContent(node) or @@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> { exists(AccessPathFront apf | Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf) + apf, _) ) } @@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> { import LocalCallContext predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCc lcc + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t, + LocalCc lcc ) { localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and @@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> { ) } - bindingset[node, state, t, ap] - predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + ( + if castingNodeEx(node) + then + exists(Typ nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) and exists(state) and exists(ap) } @@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> { Stage5::parameterMayFlowThrough(p, _) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0) + TAccessPathApproxSome(apa), _, apa0, _) ) } @@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and + Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> { ap = TAccessPathNil() or // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap) and - Stage5::revFlow(node, state, ap.getApprox()) and - (if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) + pathStep(_, node, state, cc, sc, t, ap) } or TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | @@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> { ap = mid.getAp() } + private predicate pathStep( + PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, + AccessPath ap + ) { + exists(DataFlowType t0 | + pathStep0(mid, node, state, cc, sc, t0, ap) and + Stage5::revFlow(node, state, ap.getApprox()) and + ( + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + ) + ) + } + /** * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ pragma[assume_small_delta] pragma[nomagic] - private predicate pathStep( + private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { From 96c1b5b0a9f640008555c230ba3ca9ec15986031 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 9 May 2023 12:10:03 +0200 Subject: [PATCH 449/739] C#: Enable type strengthening. --- .../csharp/dataflow/internal/DataFlowPrivate.qll | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index d683e03dc2d..578c8fb8ed5 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -1984,6 +1984,21 @@ private class DataFlowUnknownType extends DataFlowType { DataFlowUnknownType() { this = Gvn::getGlobalValueNumber(any(UnknownType ut)) } } +private predicate uselessTypebound(DataFlowType t) { + t instanceof DataFlowUnknownType or + t instanceof Gvn::TypeParameterGvnType +} + +pragma[nomagic] +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { + t1 != t2 and + t1 = getANonTypeParameterSubTypeRestricted(t2) + or + t1 instanceof RelevantDataFlowType and + not uselessTypebound(t1) and + uselessTypebound(t2) +} + /** * Holds if `t1` and `t2` are compatible, that is, whether data can flow from * a node of type `t1` to a node of type `t2`. From fd832416d8ec214edf28cdeffbdc58c6c13c98c7 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 9 May 2023 12:10:31 +0200 Subject: [PATCH 450/739] Dataflow: Add empty type strengthening predicate for languages without type pruning. --- .../lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll | 2 ++ .../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 2 ++ go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 2 ++ .../lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll | 2 ++ ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll | 2 ++ swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll | 2 ++ 6 files changed, 12 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index 9b4e0e6a4f9..115989e3dea 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -205,6 +205,8 @@ predicate clearsContent(Node n, Content c) { */ predicate expectsContent(Node n, ContentSet c) { none() } +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } + /** Gets the type of `n` used for type pruning. */ Type getNodeType(Node n) { suppressUnusedNode(n) and diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index cc8d0cdbe94..33ff6f74775 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -753,6 +753,8 @@ predicate clearsContent(Node n, Content c) { */ predicate expectsContent(Node n, ContentSet c) { none() } +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } + /** Gets the type of `n` used for type pruning. */ DataFlowType getNodeType(Node n) { suppressUnusedNode(n) and diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index d45587aa3d4..e0adc9f5790 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -200,6 +200,8 @@ predicate expectsContent(Node n, ContentSet c) { FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c) } +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } + /** Gets the type of `n` used for type pruning. */ DataFlowType getNodeType(Node n) { result = TTodoDataFlowType() and exists(n) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 693a2f13fc4..de493e5bb53 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -502,6 +502,8 @@ class CastNode extends Node { pragma[inline] predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() } +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } + /** * Gets the type of `node`. */ diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 6a7d87e9bd5..7708eff235a 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1231,6 +1231,8 @@ class DataFlowType extends TDataFlowType { string toString() { result = "" } } +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } + /** Gets the type of `n` used for type pruning. */ DataFlowType getNodeType(NodeImpl n) { result = TTodoDataFlowType() and exists(n) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 7b2bc359c9a..ab2bbc050a4 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -793,6 +793,8 @@ class DataFlowType extends TDataFlowType { string toString() { result = "" } } +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } + /** Gets the type of `n` used for type pruning. */ DataFlowType getNodeType(NodeImpl n) { any() // return the singleton DataFlowType until we support type pruning for Swift From 4633abe19e95503362526406b249154167718421 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 9 May 2023 13:26:38 +0200 Subject: [PATCH 451/739] Java: Autoformat --- .../semmle/code/java/dataflow/internal/DataFlowPrivate.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 4782e65b7e7..01bf90cb7ba 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -194,9 +194,7 @@ class DataFlowType extends SrcRefType { } pragma[nomagic] -predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { - t1.getASourceSupertype+() = t2 -} +predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { t1.getASourceSupertype+() = t2 } pragma[noinline] DataFlowType getNodeType(Node n) { From 21dea62e99754629e978d32bee8e88204561df1e Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 9 May 2023 14:42:50 +0200 Subject: [PATCH 452/739] C#: Fix qltests. --- .../collections/CollectionFlow.expected | 12 ++--- .../dataflow/external-models/ExternalFlow.cs | 6 +-- .../external-models/ExternalFlow.expected | 14 +++--- .../external-models/ExternalFlow.ext.yml | 4 +- .../dataflow/global/DataFlowPath.expected | 10 ++-- .../global/TaintTrackingPath.expected | 10 ++-- .../EntityFramework/Dataflow.expected | 48 +++++++++---------- .../CWE-338/InsecureRandomness.expected | 14 +++--- 8 files changed, 58 insertions(+), 60 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected index d5bbeef765a..1aabed1e806 100644 --- a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected @@ -214,8 +214,8 @@ edges | CollectionFlow.cs:385:58:385:61 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:385:67:385:70 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:385:67:385:70 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:385:67:385:73 | access to indexer : A | | CollectionFlow.cs:387:59:387:62 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | -| CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : Object [property Value] : A | -| CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : Object [property Value] : A | CollectionFlow.cs:387:68:387:85 | access to property Value : A | +| CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : KeyValuePair<Int32,T> [property Value] : A | +| CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : KeyValuePair<Int32,T> [property Value] : A | CollectionFlow.cs:387:68:387:85 | access to property Value : A | | CollectionFlow.cs:389:60:389:63 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:389:69:389:79 | access to property Values : ICollection<T> [element] : A | | CollectionFlow.cs:389:69:389:79 | access to property Values : ICollection<T> [element] : A | CollectionFlow.cs:389:69:389:87 | call to method First<T> : A | @@ -223,8 +223,8 @@ edges | CollectionFlow.cs:391:67:391:70 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:391:67:391:75 | access to property Keys : ICollection<T> [element] : A | | CollectionFlow.cs:391:67:391:75 | access to property Keys : ICollection<T> [element] : A | CollectionFlow.cs:391:67:391:83 | call to method First<T> : A | | CollectionFlow.cs:393:57:393:60 | dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | -| CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : Object [property Key] : A | -| CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : Object [property Key] : A | CollectionFlow.cs:393:66:393:81 | access to property Key : A | +| CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : KeyValuePair<T,Int32> [property Key] : A | +| CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : KeyValuePair<T,Int32> [property Key] : A | CollectionFlow.cs:393:66:393:81 | access to property Key : A | | CollectionFlow.cs:395:49:395:52 | args : A[] [element] : A | CollectionFlow.cs:395:63:395:66 | access to parameter args : A[] [element] : A | | CollectionFlow.cs:395:49:395:52 | args : null [element] : A | CollectionFlow.cs:395:63:395:66 | access to parameter args : null [element] : A | | CollectionFlow.cs:395:63:395:66 | access to parameter args : A[] [element] : A | CollectionFlow.cs:395:63:395:69 | access to array element | @@ -440,7 +440,7 @@ nodes | CollectionFlow.cs:385:67:385:73 | access to indexer : A | semmle.label | access to indexer : A | | CollectionFlow.cs:387:59:387:62 | dict : Dictionary<T,T> [element, property Value] : A | semmle.label | dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Value] : A | -| CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : Object [property Value] : A | semmle.label | call to method First<KeyValuePair<Int32,T>> : Object [property Value] : A | +| CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : KeyValuePair<Int32,T> [property Value] : A | semmle.label | call to method First<KeyValuePair<Int32,T>> : KeyValuePair<Int32,T> [property Value] : A | | CollectionFlow.cs:387:68:387:85 | access to property Value : A | semmle.label | access to property Value : A | | CollectionFlow.cs:389:60:389:63 | dict : Dictionary<T,T> [element, property Value] : A | semmle.label | dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Value] : A | @@ -452,7 +452,7 @@ nodes | CollectionFlow.cs:391:67:391:83 | call to method First<T> : A | semmle.label | call to method First<T> : A | | CollectionFlow.cs:393:57:393:60 | dict : Dictionary<T,T> [element, property Key] : A | semmle.label | dict : Dictionary<T,T> [element, property Key] : A | | CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Key] : A | -| CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : Object [property Key] : A | semmle.label | call to method First<KeyValuePair<T,Int32>> : Object [property Key] : A | +| CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : KeyValuePair<T,Int32> [property Key] : A | semmle.label | call to method First<KeyValuePair<T,Int32>> : KeyValuePair<T,Int32> [property Key] : A | | CollectionFlow.cs:393:66:393:81 | access to property Key : A | semmle.label | access to property Key : A | | CollectionFlow.cs:395:49:395:52 | args : A[] [element] : A | semmle.label | args : A[] [element] : A | | CollectionFlow.cs:395:49:395:52 | args : null [element] : A | semmle.label | args : null [element] : A | diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.cs b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.cs index 05772dfb29a..7a0e896e54d 100644 --- a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.cs +++ b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.cs @@ -149,9 +149,9 @@ namespace My.Qltest static T Apply<S, T>(Func<S, T> f, S s) => throw null; - static S[] Map<S, T>(S[] elements, Func<S, T> f) => throw null; + static T[] Map<S, T>(S[] elements, Func<S, T> f) => throw null; - static void Apply2<S>(Action<S> f, S s1, S s2) => throw null; + static void Apply2(Action<object> f, D d1, D d2) => throw null; static void Parse(string s, out int i) => throw null; @@ -235,4 +235,4 @@ namespace My.Qltest static void Sink(object o) { } } -} \ No newline at end of file +} diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected index 09ce9945cdf..c69a86a5cb3 100644 --- a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected @@ -12,10 +12,10 @@ edges | ExternalFlow.cs:30:13:30:16 | [post] this access : D [field Field] : Object | ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object | | ExternalFlow.cs:30:26:30:37 | object creation of type Object : Object | ExternalFlow.cs:30:13:30:16 | [post] this access : D [field Field] : Object | | ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object | ExternalFlow.cs:31:18:31:39 | call to method StepFieldGetter | -| ExternalFlow.cs:36:19:36:62 | (...) ... : Object [field Field] : Object | ExternalFlow.cs:36:18:36:69 | access to field Field | +| ExternalFlow.cs:36:19:36:62 | (...) ... : D [field Field] : Object | ExternalFlow.cs:36:18:36:69 | access to field Field | | ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object | ExternalFlow.cs:37:18:37:21 | this access : D [field Field] : Object | | ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object | ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | -| ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | ExternalFlow.cs:36:19:36:62 | (...) ... : Object [field Field] : Object | +| ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | ExternalFlow.cs:36:19:36:62 | (...) ... : D [field Field] : Object | | ExternalFlow.cs:36:43:36:54 | object creation of type Object : Object | ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object | | ExternalFlow.cs:36:43:36:54 | object creation of type Object : Object | ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object | | ExternalFlow.cs:37:18:37:21 | this access : D [field Field] : Object | ExternalFlow.cs:37:18:37:27 | access to field Field | @@ -38,8 +38,7 @@ edges | ExternalFlow.cs:72:23:72:23 | o : Object | ExternalFlow.cs:72:35:72:35 | access to parameter o | | ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object | ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object | -| ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | ExternalFlow.cs:78:18:78:24 | access to array element : Object | -| ExternalFlow.cs:78:18:78:24 | access to array element : Object | ExternalFlow.cs:78:18:78:24 | (...) ... | +| ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | ExternalFlow.cs:78:18:78:24 | access to array element | | ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object | ExternalFlow.cs:84:29:84:32 | access to local variable objs : null [element] : Object | | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object | | ExternalFlow.cs:84:25:84:41 | call to method Map<Object,Object> : T[] [element] : Object | ExternalFlow.cs:85:18:85:22 | access to local variable objs2 : T[] [element] : Object | @@ -91,7 +90,7 @@ nodes | ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object | semmle.label | this access : D [field Field] : Object | | ExternalFlow.cs:31:18:31:39 | call to method StepFieldGetter | semmle.label | call to method StepFieldGetter | | ExternalFlow.cs:36:18:36:69 | access to field Field | semmle.label | access to field Field | -| ExternalFlow.cs:36:19:36:62 | (...) ... : Object [field Field] : Object | semmle.label | (...) ... : Object [field Field] : Object | +| ExternalFlow.cs:36:19:36:62 | (...) ... : D [field Field] : Object | semmle.label | (...) ... : D [field Field] : Object | | ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object | semmle.label | [post] this access : D [field Field] : Object | | ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object | semmle.label | call to method StepFieldSetter : D [field Field2, field Field] : Object | | ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | semmle.label | access to field Field2 : Object [field Field] : Object | @@ -124,8 +123,7 @@ nodes | ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object | semmle.label | call to method Map<Int32,Object> : T[] [element] : Object | | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | semmle.label | access to local variable objs : T[] [element] : Object | -| ExternalFlow.cs:78:18:78:24 | (...) ... | semmle.label | (...) ... | -| ExternalFlow.cs:78:18:78:24 | access to array element : Object | semmle.label | access to array element : Object | +| ExternalFlow.cs:78:18:78:24 | access to array element | semmle.label | access to array element | | ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object | semmle.label | { ..., ... } : null [element] : Object | | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | ExternalFlow.cs:84:25:84:41 | call to method Map<Object,Object> : T[] [element] : Object | semmle.label | call to method Map<Object,Object> : T[] [element] : Object | @@ -184,7 +182,7 @@ subpaths | ExternalFlow.cs:60:47:60:47 | access to parameter o | ExternalFlow.cs:60:64:60:75 | object creation of type Object : Object | ExternalFlow.cs:60:47:60:47 | access to parameter o | $@ | ExternalFlow.cs:60:64:60:75 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:66:18:66:18 | access to local variable o | ExternalFlow.cs:65:45:65:56 | object creation of type Object : Object | ExternalFlow.cs:66:18:66:18 | access to local variable o | $@ | ExternalFlow.cs:65:45:65:56 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:72:35:72:35 | access to parameter o | ExternalFlow.cs:71:32:71:43 | object creation of type Object : Object | ExternalFlow.cs:72:35:72:35 | access to parameter o | $@ | ExternalFlow.cs:71:32:71:43 | object creation of type Object : Object | object creation of type Object : Object | -| ExternalFlow.cs:78:18:78:24 | (...) ... | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:78:18:78:24 | (...) ... | $@ | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | object creation of type Object : Object | +| ExternalFlow.cs:78:18:78:24 | access to array element | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:78:18:78:24 | access to array element | $@ | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:85:18:85:25 | access to array element | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | ExternalFlow.cs:85:18:85:25 | access to array element | $@ | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:92:18:92:18 | (...) ... | ExternalFlow.cs:90:21:90:34 | object creation of type String : String | ExternalFlow.cs:92:18:92:18 | (...) ... | $@ | ExternalFlow.cs:90:21:90:34 | object creation of type String : String | object creation of type String : String | | ExternalFlow.cs:102:22:102:22 | access to parameter d | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | ExternalFlow.cs:102:22:102:22 | access to parameter d | $@ | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | object creation of type Object : Object | diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ext.yml b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ext.yml index f626949e6f4..a2bf0d8b525 100644 --- a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ext.yml +++ b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ext.yml @@ -16,8 +16,8 @@ extensions: - ["My.Qltest", "D", false, "StepElementSetter", "(System.Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["My.Qltest", "D", false, "Apply<,>", "(System.Func<S,T>,S)", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"] - ["My.Qltest", "D", false, "Apply<,>", "(System.Func<S,T>,S)", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] - - ["My.Qltest", "D", false, "Apply2<>", "(System.Action<S>,S,S)", "", "Argument[1].Field[My.Qltest.D.Field]", "Argument[0].Parameter[0]", "value", "manual"] - - ["My.Qltest", "D", false, "Apply2<>", "(System.Action<S>,S,S)", "", "Argument[2].Field[My.Qltest.D.Field2]", "Argument[0].Parameter[0]", "value", "manual"] + - ["My.Qltest", "D", false, "Apply2", "(System.Action<System.Object>,My.Qltest.D,My.Qltest.D)", "", "Argument[1].Field[My.Qltest.D.Field]", "Argument[0].Parameter[0]", "value", "manual"] + - ["My.Qltest", "D", false, "Apply2", "(System.Action<System.Object>,My.Qltest.D,My.Qltest.D)", "", "Argument[2].Field[My.Qltest.D.Field2]", "Argument[0].Parameter[0]", "value", "manual"] - ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func<S,T>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func<S,T>)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] - ["My.Qltest", "D", false, "Parse", "(System.String,System.Int32)", "", "Argument[0]", "Argument[1]", "taint", "manual"] diff --git a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected index bce1914e42b..767e66301ce 100644 --- a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected @@ -267,7 +267,7 @@ edges | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:31:514:32 | [post] access to local variable y1 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:36:514:37 | [post] access to local variable y2 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:42:514:43 | [post] access to local variable y3 : SimpleClass [field field] : String | -| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | +| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:544:20:544:20 | [post] access to local variable x : SimpleClass [field field] : String | @@ -286,8 +286,8 @@ edges | GlobalDataFlow.cs:515:15:515:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:515:15:515:22 | access to field field | | GlobalDataFlow.cs:516:15:516:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:22 | access to field field | | GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:22 | access to field field | -| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | -| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:21 | access to field field | +| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | +| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:21 | access to field field | | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:534:15:534:15 | access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field | @@ -579,8 +579,8 @@ nodes | GlobalDataFlow.cs:516:15:516:22 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String | | GlobalDataFlow.cs:517:15:517:22 | access to field field | semmle.label | access to field field | -| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String | -| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String | +| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | semmle.label | [post] access to local variable x : SubSimpleClass [field field] : String | +| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | semmle.label | access to local variable x : SubSimpleClass [field field] : String | | GlobalDataFlow.cs:526:15:526:21 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String | diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected index 5dae90d82a6..dec8a134712 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected @@ -293,7 +293,7 @@ edges | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:31:514:32 | [post] access to local variable y1 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:36:514:37 | [post] access to local variable y2 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:42:514:43 | [post] access to local variable y3 : SimpleClass [field field] : String | -| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | +| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:544:20:544:20 | [post] access to local variable x : SimpleClass [field field] : String | @@ -312,8 +312,8 @@ edges | GlobalDataFlow.cs:515:15:515:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:515:15:515:22 | access to field field | | GlobalDataFlow.cs:516:15:516:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:22 | access to field field | | GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:22 | access to field field | -| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | -| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:21 | access to field field | +| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | +| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:21 | access to field field | | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:534:15:534:15 | access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field | @@ -633,8 +633,8 @@ nodes | GlobalDataFlow.cs:516:15:516:22 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String | | GlobalDataFlow.cs:517:15:517:22 | access to field field | semmle.label | access to field field | -| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String | -| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String | +| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | semmle.label | [post] access to local variable x : SubSimpleClass [field field] : String | +| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | semmle.label | access to local variable x : SubSimpleClass [field field] : String | | GlobalDataFlow.cs:526:15:526:21 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String | diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected index 811f1a04d8b..a9d4895fb46 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected @@ -74,14 +74,14 @@ edges | EntityFramework.cs:196:13:196:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | EntityFramework.cs:196:13:196:15 | [post] access to local variable ctx : MyContext [property Persons, element, property Name] : String | | EntityFramework.cs:196:29:196:29 | access to parameter p : Person [property Name] : String | EntityFramework.cs:196:13:196:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | | EntityFramework.cs:197:13:197:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | -| EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | EntityFramework.cs:204:18:204:36 | call to method First<Person> : Object [property Name] : String | -| EntityFramework.cs:204:18:204:36 | call to method First<Person> : Object [property Name] : String | EntityFramework.cs:204:18:204:41 | access to property Name | -| EntityFramework.cs:212:18:212:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | EntityFramework.cs:212:18:212:38 | call to method First<Address> : Object [property Street] : String | -| EntityFramework.cs:212:18:212:38 | call to method First<Address> : Object [property Street] : String | EntityFramework.cs:212:18:212:45 | access to property Street | -| EntityFramework.cs:219:18:219:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | EntityFramework.cs:219:18:219:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | -| EntityFramework.cs:219:18:219:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | -| EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | EntityFramework.cs:219:18:219:54 | call to method First<Address> : Object [property Street] : String | -| EntityFramework.cs:219:18:219:54 | call to method First<Address> : Object [property Street] : String | EntityFramework.cs:219:18:219:61 | access to property Street | +| EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | EntityFramework.cs:204:18:204:36 | call to method First<Person> : Person [property Name] : String | +| EntityFramework.cs:204:18:204:36 | call to method First<Person> : Person [property Name] : String | EntityFramework.cs:204:18:204:41 | access to property Name | +| EntityFramework.cs:212:18:212:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | EntityFramework.cs:212:18:212:38 | call to method First<Address> : Address [property Street] : String | +| EntityFramework.cs:212:18:212:38 | call to method First<Address> : Address [property Street] : String | EntityFramework.cs:212:18:212:45 | access to property Street | +| EntityFramework.cs:219:18:219:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | EntityFramework.cs:219:18:219:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | +| EntityFramework.cs:219:18:219:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | +| EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | EntityFramework.cs:219:18:219:54 | call to method First<Address> : Address [property Street] : String | +| EntityFramework.cs:219:18:219:54 | call to method First<Address> : Address [property Street] : String | EntityFramework.cs:219:18:219:61 | access to property Street | | EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:83:18:83:28 | access to local variable taintSource | | EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:84:35:84:45 | access to local variable taintSource : String | | EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:85:18:85:42 | (...) ... | @@ -165,14 +165,14 @@ edges | EntityFrameworkCore.cs:229:13:229:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | EntityFrameworkCore.cs:229:13:229:15 | [post] access to local variable ctx : MyContext [property Persons, element, property Name] : String | | EntityFrameworkCore.cs:229:29:229:29 | access to parameter p : Person [property Name] : String | EntityFrameworkCore.cs:229:13:229:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | | EntityFrameworkCore.cs:230:13:230:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | -| EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Object [property Name] : String | -| EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Object [property Name] : String | EntityFrameworkCore.cs:237:18:237:41 | access to property Name | -| EntityFrameworkCore.cs:245:18:245:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Object [property Street] : String | -| EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Object [property Street] : String | EntityFrameworkCore.cs:245:18:245:45 | access to property Street | -| EntityFrameworkCore.cs:252:18:252:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | -| EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | -| EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Object [property Street] : String | -| EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Object [property Street] : String | EntityFrameworkCore.cs:252:18:252:61 | access to property Street | +| EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Person [property Name] : String | +| EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Person [property Name] : String | EntityFrameworkCore.cs:237:18:237:41 | access to property Name | +| EntityFrameworkCore.cs:245:18:245:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Address [property Street] : String | +| EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Address [property Street] : String | EntityFrameworkCore.cs:245:18:245:45 | access to property Street | +| EntityFrameworkCore.cs:252:18:252:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | +| EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Address [property Street] : String | +| EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Address [property Street] : String | EntityFrameworkCore.cs:252:18:252:61 | access to property Street | nodes | EntityFramework.cs:59:13:62:13 | { ..., ... } : Person [property Name] : String | semmle.label | { ..., ... } : Person [property Name] : String | | EntityFramework.cs:61:24:61:32 | "tainted" : String | semmle.label | "tainted" : String | @@ -237,15 +237,15 @@ nodes | EntityFramework.cs:196:29:196:29 | access to parameter p : Person [property Name] : String | semmle.label | access to parameter p : Person [property Name] : String | | EntityFramework.cs:197:13:197:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | semmle.label | access to local variable ctx : MyContext [property Persons, element, property Name] : String | | EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Name] : String | -| EntityFramework.cs:204:18:204:36 | call to method First<Person> : Object [property Name] : String | semmle.label | call to method First<Person> : Object [property Name] : String | +| EntityFramework.cs:204:18:204:36 | call to method First<Person> : Person [property Name] : String | semmle.label | call to method First<Person> : Person [property Name] : String | | EntityFramework.cs:204:18:204:41 | access to property Name | semmle.label | access to property Name | | EntityFramework.cs:212:18:212:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | semmle.label | access to property Addresses : DbSet<Address> [element, property Street] : String | -| EntityFramework.cs:212:18:212:38 | call to method First<Address> : Object [property Street] : String | semmle.label | call to method First<Address> : Object [property Street] : String | +| EntityFramework.cs:212:18:212:38 | call to method First<Address> : Address [property Street] : String | semmle.label | call to method First<Address> : Address [property Street] : String | | EntityFramework.cs:212:18:212:45 | access to property Street | semmle.label | access to property Street | | EntityFramework.cs:219:18:219:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | -| EntityFramework.cs:219:18:219:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | semmle.label | call to method First<Person> : Object [property Addresses, element, property Street] : String | +| EntityFramework.cs:219:18:219:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | semmle.label | call to method First<Person> : Person [property Addresses, element, property Street] : String | | EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | semmle.label | access to property Addresses : ICollection<Address> [element, property Street] : String | -| EntityFramework.cs:219:18:219:54 | call to method First<Address> : Object [property Street] : String | semmle.label | call to method First<Address> : Object [property Street] : String | +| EntityFramework.cs:219:18:219:54 | call to method First<Address> : Address [property Street] : String | semmle.label | call to method First<Address> : Address [property Street] : String | | EntityFramework.cs:219:18:219:61 | access to property Street | semmle.label | access to property Street | | EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | semmle.label | "tainted" : String | | EntityFrameworkCore.cs:83:18:83:28 | access to local variable taintSource | semmle.label | access to local variable taintSource | @@ -318,15 +318,15 @@ nodes | EntityFrameworkCore.cs:229:29:229:29 | access to parameter p : Person [property Name] : String | semmle.label | access to parameter p : Person [property Name] : String | | EntityFrameworkCore.cs:230:13:230:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | semmle.label | access to local variable ctx : MyContext [property Persons, element, property Name] : String | | EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Name] : String | -| EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Object [property Name] : String | semmle.label | call to method First<Person> : Object [property Name] : String | +| EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Person [property Name] : String | semmle.label | call to method First<Person> : Person [property Name] : String | | EntityFrameworkCore.cs:237:18:237:41 | access to property Name | semmle.label | access to property Name | | EntityFrameworkCore.cs:245:18:245:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | semmle.label | access to property Addresses : DbSet<Address> [element, property Street] : String | -| EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Object [property Street] : String | semmle.label | call to method First<Address> : Object [property Street] : String | +| EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Address [property Street] : String | semmle.label | call to method First<Address> : Address [property Street] : String | | EntityFrameworkCore.cs:245:18:245:45 | access to property Street | semmle.label | access to property Street | | EntityFrameworkCore.cs:252:18:252:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | -| EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | semmle.label | call to method First<Person> : Object [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | semmle.label | call to method First<Person> : Person [property Addresses, element, property Street] : String | | EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | semmle.label | access to property Addresses : ICollection<Address> [element, property Street] : String | -| EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Object [property Street] : String | semmle.label | call to method First<Address> : Object [property Street] : String | +| EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Address [property Street] : String | semmle.label | call to method First<Address> : Address [property Street] : String | | EntityFrameworkCore.cs:252:18:252:61 | access to property Street | semmle.label | access to property Street | subpaths #select diff --git a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected index 4cc2e788074..011ec3faee0 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected @@ -1,10 +1,10 @@ edges -| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Int32 | InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Int32 | -| InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Int32 | -| InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | +| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Byte | InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Byte | +| InsecureRandomness.cs:28:23:28:43 | (...) ... : Byte | InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Byte | +| InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | InsecureRandomness.cs:28:23:28:43 | (...) ... : Byte | | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String | InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String | | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String | -| InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Int32 | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | +| InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Byte | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | | InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | | InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | @@ -16,12 +16,12 @@ nodes | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | semmle.label | call to method InsecureRandomString | | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | semmle.label | call to method InsecureRandomStringFromSelection | | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | semmle.label | call to method InsecureRandomStringFromIndexer | -| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Int32 | semmle.label | [post] access to local variable data : Byte[] [element] : Int32 | -| InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | semmle.label | (...) ... : Int32 | +| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Byte | semmle.label | [post] access to local variable data : Byte[] [element] : Byte | +| InsecureRandomness.cs:28:23:28:43 | (...) ... : Byte | semmle.label | (...) ... : Byte | | InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | semmle.label | call to method Next : Int32 | | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String | semmle.label | [post] access to local variable result : StringBuilder [element] : String | | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | semmle.label | call to method GetString : String | -| InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Int32 | semmle.label | access to local variable data : Byte[] [element] : Int32 | +| InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Byte | semmle.label | access to local variable data : Byte[] [element] : Byte | | InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String | semmle.label | access to local variable result : StringBuilder [element] : String | | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | semmle.label | call to method ToString : String | | InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | semmle.label | call to method Next : Int32 | From a0a9d30286d5607e6ae6e0ab45e676a589ec1bb4 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Wed, 10 May 2023 09:46:27 +0200 Subject: [PATCH 453/739] Java: Fix qltests. --- java/ql/lib/ext/java.sql.model.yml | 6 +- .../CWE-200/AndroidWebResourceResponse.qll | 8 +- .../CWE-020/Log4jInjectionTest.expected | 46 ++-- .../InsecureWebResourceResponse.expected | 246 +++++++++--------- .../CWE-200/SensitiveAndroidFileLeak.expected | 48 ++-- .../CWE-470/UnsafeReflection.expected | 14 +- .../CWE-552/UnsafeUrlForward.expected | 12 +- .../CWE-598/SensitiveGetQuery.expected | 16 +- .../security/CWE-755/NFEAndroidDoS.expected | 26 +- java/ql/test/ext/TestModels/Test.java | 2 +- .../CWE-078/ExecTaintedLocal.expected | 6 +- 11 files changed, 217 insertions(+), 213 deletions(-) diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index c93a89cfd2c..58985c886b5 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -21,7 +21,6 @@ extensions: extensible: summaryModel data: - ["java.sql", "Connection", True, "nativeSQL", "(String)", "", "Argument[0]", "ReturnValue", "taint", "hq-manual"] - - ["java.sql", "PreparedStatement", True, "setString", "(int,String)", "", "Argument[1]", "Argument[this]", "value", "manual"] - ["java.sql", "ResultSet", True, "getString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] - addsTo: @@ -31,13 +30,14 @@ extensions: - ["java.sql", "Connection", "createStatement", "()", "summary", "manual"] - ["java.sql", "PreparedStatement", "executeUpdate", "()", "summary", "manual"] - ["java.sql", "PreparedStatement", "executeQuery", "()", "summary", "manual"] + - ["java.sql", "PreparedStatement", "setInt", "(int,int)", "summary", "manual"] + - ["java.sql", "PreparedStatement", "setLong", "(int,long)", "summary", "manual"] + - ["java.sql", "PreparedStatement", "setString", "(int,String)", "summary", "manual"] - ["java.sql", "ResultSet", "next", "()", "summary", "manual"] - ["java.sql", "Statement", "close", "()", "summary", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.sql", "PreparedStatement", "setInt", "(int,int)", "summary", "manual"] # value-numeric - - ["java.sql", "PreparedStatement", "setLong", "(int,long)", "summary", "manual"] # value-numeric - ["java.sql", "ResultSet", "getInt", "(int)", "summary", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getInt", "(String)", "summary", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getLong", "(String)", "summary", "manual"] # taint-numeric diff --git a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll index bd177b30213..05055bdfa84 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll @@ -55,10 +55,14 @@ class WebResourceResponseSink extends DataFlow::Node { } /** - * A value step from the URL argument of `WebView::loadUrl` to the URL parameter of + * A taint step from the URL argument of `WebView::loadUrl` to the URL/WebResourceRequest parameter of * `WebViewClient::shouldInterceptRequest`. + * + * TODO: This ought to be a value step when it is targeting the URL parameter, + * and it ought to check the parameter type in both cases to ensure that we only + * hit the overloads we intend to. */ -private class FetchUrlStep extends AdditionalValueStep { +private class FetchUrlStep extends AdditionalTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists( // webview.loadUrl(url) -> webview.setWebViewClient(new WebViewClient() { shouldInterceptRequest(view, url) }); diff --git a/java/ql/test/experimental/query-tests/security/CWE-020/Log4jInjectionTest.expected b/java/ql/test/experimental/query-tests/security/CWE-020/Log4jInjectionTest.expected index f3d88d25805..93b2b060685 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-020/Log4jInjectionTest.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-020/Log4jInjectionTest.expected @@ -2075,28 +2075,28 @@ edges | Log4jJndiInjectionTest.java:1085:39:1085:46 | source(...) : String | Log4jJndiInjectionTest.java:1085:25:1085:46 | (...)... | | Log4jJndiInjectionTest.java:1088:47:1088:54 | source(...) : String | Log4jJndiInjectionTest.java:1088:38:1088:54 | (...)... | | Log4jJndiInjectionTest.java:1089:53:1089:60 | source(...) : String | Log4jJndiInjectionTest.java:1089:44:1089:60 | (...)... | -| Log4jJndiInjectionTest.java:1091:13:1091:15 | map [post update] : Map [<map.value>] : String | Log4jJndiInjectionTest.java:1092:34:1092:36 | map | -| Log4jJndiInjectionTest.java:1091:28:1091:44 | (...)... : String | Log4jJndiInjectionTest.java:1091:13:1091:15 | map [post update] : Map [<map.value>] : String | +| Log4jJndiInjectionTest.java:1091:13:1091:15 | map [post update] : HashMap [<map.value>] : String | Log4jJndiInjectionTest.java:1092:34:1092:36 | map | +| Log4jJndiInjectionTest.java:1091:28:1091:44 | (...)... : String | Log4jJndiInjectionTest.java:1091:13:1091:15 | map [post update] : HashMap [<map.value>] : String | | Log4jJndiInjectionTest.java:1091:37:1091:44 | source(...) : String | Log4jJndiInjectionTest.java:1091:28:1091:44 | (...)... : String | -| Log4jJndiInjectionTest.java:1095:31:1095:88 | with(...) : MapMessage | Log4jJndiInjectionTest.java:1096:26:1096:29 | mmsg | -| Log4jJndiInjectionTest.java:1095:71:1095:87 | (...)... : String | Log4jJndiInjectionTest.java:1095:31:1095:88 | with(...) : MapMessage | +| Log4jJndiInjectionTest.java:1095:31:1095:88 | with(...) : StringMapMessage | Log4jJndiInjectionTest.java:1096:26:1096:29 | mmsg | +| Log4jJndiInjectionTest.java:1095:71:1095:87 | (...)... : String | Log4jJndiInjectionTest.java:1095:31:1095:88 | with(...) : StringMapMessage | | Log4jJndiInjectionTest.java:1095:80:1095:87 | source(...) : String | Log4jJndiInjectionTest.java:1095:71:1095:87 | (...)... : String | -| Log4jJndiInjectionTest.java:1100:13:1100:16 | mmsg [post update] : MapMessage | Log4jJndiInjectionTest.java:1101:26:1101:29 | mmsg | -| Log4jJndiInjectionTest.java:1100:35:1100:51 | (...)... : String | Log4jJndiInjectionTest.java:1100:13:1100:16 | mmsg [post update] : MapMessage | +| Log4jJndiInjectionTest.java:1100:13:1100:16 | mmsg [post update] : StringMapMessage | Log4jJndiInjectionTest.java:1101:26:1101:29 | mmsg | +| Log4jJndiInjectionTest.java:1100:35:1100:51 | (...)... : String | Log4jJndiInjectionTest.java:1100:13:1100:16 | mmsg [post update] : StringMapMessage | | Log4jJndiInjectionTest.java:1100:44:1100:51 | source(...) : String | Log4jJndiInjectionTest.java:1100:35:1100:51 | (...)... : String | -| Log4jJndiInjectionTest.java:1105:13:1105:16 | mmsg [post update] : MapMessage | Log4jJndiInjectionTest.java:1106:26:1106:29 | mmsg | -| Log4jJndiInjectionTest.java:1105:34:1105:50 | (...)... : String | Log4jJndiInjectionTest.java:1105:13:1105:16 | mmsg [post update] : MapMessage | +| Log4jJndiInjectionTest.java:1105:13:1105:16 | mmsg [post update] : StringMapMessage | Log4jJndiInjectionTest.java:1106:26:1106:29 | mmsg | +| Log4jJndiInjectionTest.java:1105:34:1105:50 | (...)... : String | Log4jJndiInjectionTest.java:1105:13:1105:16 | mmsg [post update] : StringMapMessage | | Log4jJndiInjectionTest.java:1105:43:1105:50 | source(...) : String | Log4jJndiInjectionTest.java:1105:34:1105:50 | (...)... : String | -| Log4jJndiInjectionTest.java:1111:13:1111:15 | map [post update] : Map [<map.value>] : String | Log4jJndiInjectionTest.java:1112:25:1112:27 | map : Map [<map.value>] : String | -| Log4jJndiInjectionTest.java:1111:33:1111:49 | (...)... : String | Log4jJndiInjectionTest.java:1111:13:1111:15 | map [post update] : Map [<map.value>] : String | +| Log4jJndiInjectionTest.java:1111:13:1111:15 | map [post update] : HashMap [<map.value>] : String | Log4jJndiInjectionTest.java:1112:25:1112:27 | map : HashMap [<map.value>] : String | +| Log4jJndiInjectionTest.java:1111:33:1111:49 | (...)... : String | Log4jJndiInjectionTest.java:1111:13:1111:15 | map [post update] : HashMap [<map.value>] : String | | Log4jJndiInjectionTest.java:1111:42:1111:49 | source(...) : String | Log4jJndiInjectionTest.java:1111:33:1111:49 | (...)... : String | -| Log4jJndiInjectionTest.java:1112:13:1112:16 | mmsg [post update] : MapMessage | Log4jJndiInjectionTest.java:1113:26:1113:29 | mmsg | -| Log4jJndiInjectionTest.java:1112:25:1112:27 | map : Map [<map.value>] : String | Log4jJndiInjectionTest.java:1112:13:1112:16 | mmsg [post update] : MapMessage | +| Log4jJndiInjectionTest.java:1112:13:1112:16 | mmsg [post update] : StringMapMessage | Log4jJndiInjectionTest.java:1113:26:1113:29 | mmsg | +| Log4jJndiInjectionTest.java:1112:25:1112:27 | map : HashMap [<map.value>] : String | Log4jJndiInjectionTest.java:1112:13:1112:16 | mmsg [post update] : StringMapMessage | | Log4jJndiInjectionTest.java:1116:61:1116:68 | source(...) : String | Log4jJndiInjectionTest.java:1116:52:1116:68 | (...)... | | Log4jJndiInjectionTest.java:1117:81:1117:88 | source(...) : String | Log4jJndiInjectionTest.java:1117:72:1117:88 | (...)... | -| Log4jJndiInjectionTest.java:1119:13:1119:15 | map [post update] : Map [<map.value>] : String | Log4jJndiInjectionTest.java:1120:43:1120:45 | map | -| Log4jJndiInjectionTest.java:1119:13:1119:15 | map [post update] : Map [<map.value>] : String | Log4jJndiInjectionTest.java:1121:63:1121:65 | map | -| Log4jJndiInjectionTest.java:1119:33:1119:49 | (...)... : String | Log4jJndiInjectionTest.java:1119:13:1119:15 | map [post update] : Map [<map.value>] : String | +| Log4jJndiInjectionTest.java:1119:13:1119:15 | map [post update] : HashMap [<map.value>] : String | Log4jJndiInjectionTest.java:1120:43:1120:45 | map | +| Log4jJndiInjectionTest.java:1119:13:1119:15 | map [post update] : HashMap [<map.value>] : String | Log4jJndiInjectionTest.java:1121:63:1121:65 | map | +| Log4jJndiInjectionTest.java:1119:33:1119:49 | (...)... : String | Log4jJndiInjectionTest.java:1119:13:1119:15 | map [post update] : HashMap [<map.value>] : String | | Log4jJndiInjectionTest.java:1119:42:1119:49 | source(...) : String | Log4jJndiInjectionTest.java:1119:33:1119:49 | (...)... : String | nodes | Log4jJndiInjectionTest.java:24:16:24:45 | getParameter(...) : String | semmle.label | getParameter(...) : String | @@ -4168,33 +4168,33 @@ nodes | Log4jJndiInjectionTest.java:1088:47:1088:54 | source(...) : String | semmle.label | source(...) : String | | Log4jJndiInjectionTest.java:1089:44:1089:60 | (...)... | semmle.label | (...)... | | Log4jJndiInjectionTest.java:1089:53:1089:60 | source(...) : String | semmle.label | source(...) : String | -| Log4jJndiInjectionTest.java:1091:13:1091:15 | map [post update] : Map [<map.value>] : String | semmle.label | map [post update] : Map [<map.value>] : String | +| Log4jJndiInjectionTest.java:1091:13:1091:15 | map [post update] : HashMap [<map.value>] : String | semmle.label | map [post update] : HashMap [<map.value>] : String | | Log4jJndiInjectionTest.java:1091:28:1091:44 | (...)... : String | semmle.label | (...)... : String | | Log4jJndiInjectionTest.java:1091:37:1091:44 | source(...) : String | semmle.label | source(...) : String | | Log4jJndiInjectionTest.java:1092:34:1092:36 | map | semmle.label | map | -| Log4jJndiInjectionTest.java:1095:31:1095:88 | with(...) : MapMessage | semmle.label | with(...) : MapMessage | +| Log4jJndiInjectionTest.java:1095:31:1095:88 | with(...) : StringMapMessage | semmle.label | with(...) : StringMapMessage | | Log4jJndiInjectionTest.java:1095:71:1095:87 | (...)... : String | semmle.label | (...)... : String | | Log4jJndiInjectionTest.java:1095:80:1095:87 | source(...) : String | semmle.label | source(...) : String | | Log4jJndiInjectionTest.java:1096:26:1096:29 | mmsg | semmle.label | mmsg | -| Log4jJndiInjectionTest.java:1100:13:1100:16 | mmsg [post update] : MapMessage | semmle.label | mmsg [post update] : MapMessage | +| Log4jJndiInjectionTest.java:1100:13:1100:16 | mmsg [post update] : StringMapMessage | semmle.label | mmsg [post update] : StringMapMessage | | Log4jJndiInjectionTest.java:1100:35:1100:51 | (...)... : String | semmle.label | (...)... : String | | Log4jJndiInjectionTest.java:1100:44:1100:51 | source(...) : String | semmle.label | source(...) : String | | Log4jJndiInjectionTest.java:1101:26:1101:29 | mmsg | semmle.label | mmsg | -| Log4jJndiInjectionTest.java:1105:13:1105:16 | mmsg [post update] : MapMessage | semmle.label | mmsg [post update] : MapMessage | +| Log4jJndiInjectionTest.java:1105:13:1105:16 | mmsg [post update] : StringMapMessage | semmle.label | mmsg [post update] : StringMapMessage | | Log4jJndiInjectionTest.java:1105:34:1105:50 | (...)... : String | semmle.label | (...)... : String | | Log4jJndiInjectionTest.java:1105:43:1105:50 | source(...) : String | semmle.label | source(...) : String | | Log4jJndiInjectionTest.java:1106:26:1106:29 | mmsg | semmle.label | mmsg | -| Log4jJndiInjectionTest.java:1111:13:1111:15 | map [post update] : Map [<map.value>] : String | semmle.label | map [post update] : Map [<map.value>] : String | +| Log4jJndiInjectionTest.java:1111:13:1111:15 | map [post update] : HashMap [<map.value>] : String | semmle.label | map [post update] : HashMap [<map.value>] : String | | Log4jJndiInjectionTest.java:1111:33:1111:49 | (...)... : String | semmle.label | (...)... : String | | Log4jJndiInjectionTest.java:1111:42:1111:49 | source(...) : String | semmle.label | source(...) : String | -| Log4jJndiInjectionTest.java:1112:13:1112:16 | mmsg [post update] : MapMessage | semmle.label | mmsg [post update] : MapMessage | -| Log4jJndiInjectionTest.java:1112:25:1112:27 | map : Map [<map.value>] : String | semmle.label | map : Map [<map.value>] : String | +| Log4jJndiInjectionTest.java:1112:13:1112:16 | mmsg [post update] : StringMapMessage | semmle.label | mmsg [post update] : StringMapMessage | +| Log4jJndiInjectionTest.java:1112:25:1112:27 | map : HashMap [<map.value>] : String | semmle.label | map : HashMap [<map.value>] : String | | Log4jJndiInjectionTest.java:1113:26:1113:29 | mmsg | semmle.label | mmsg | | Log4jJndiInjectionTest.java:1116:52:1116:68 | (...)... | semmle.label | (...)... | | Log4jJndiInjectionTest.java:1116:61:1116:68 | source(...) : String | semmle.label | source(...) : String | | Log4jJndiInjectionTest.java:1117:72:1117:88 | (...)... | semmle.label | (...)... | | Log4jJndiInjectionTest.java:1117:81:1117:88 | source(...) : String | semmle.label | source(...) : String | -| Log4jJndiInjectionTest.java:1119:13:1119:15 | map [post update] : Map [<map.value>] : String | semmle.label | map [post update] : Map [<map.value>] : String | +| Log4jJndiInjectionTest.java:1119:13:1119:15 | map [post update] : HashMap [<map.value>] : String | semmle.label | map [post update] : HashMap [<map.value>] : String | | Log4jJndiInjectionTest.java:1119:33:1119:49 | (...)... : String | semmle.label | (...)... : String | | Log4jJndiInjectionTest.java:1119:42:1119:49 | source(...) : String | semmle.label | source(...) : String | | Log4jJndiInjectionTest.java:1120:43:1120:45 | map | semmle.label | map | diff --git a/java/ql/test/experimental/query-tests/security/CWE-200/InsecureWebResourceResponse.expected b/java/ql/test/experimental/query-tests/security/CWE-200/InsecureWebResourceResponse.expected index 37741e5f605..07ce59763ad 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-200/InsecureWebResourceResponse.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-200/InsecureWebResourceResponse.expected @@ -1,152 +1,152 @@ edges -| InsecureWebResourceResponse.java:28:27:28:37 | getIntent(...) : Intent | InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | InsecureWebResourceResponse.java:30:25:30:32 | inputUrl : Object | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | InsecureWebResourceResponse.java:32:25:32:32 | inputUrl : Object | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | InsecureWebResourceResponse.java:34:25:34:32 | inputUrl : Object | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | InsecureWebResourceResponse.java:36:26:36:33 | inputUrl : Object | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | InsecureWebResourceResponse.java:38:26:38:33 | inputUrl : Object | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | InsecureWebResourceResponse.java:40:25:40:32 | inputUrl : Object | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | InsecureWebResourceResponse.java:42:25:42:32 | inputUrl : Object | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | InsecureWebResourceResponse.java:44:26:44:33 | inputUrl : Object | -| InsecureWebResourceResponse.java:30:25:30:32 | inputUrl : Object | InsecureWebResourceResponse.java:59:34:59:43 | url : Object | -| InsecureWebResourceResponse.java:32:25:32:32 | inputUrl : Object | InsecureWebResourceResponse.java:80:34:80:43 | url : Object | -| InsecureWebResourceResponse.java:34:25:34:32 | inputUrl : Object | InsecureWebResourceResponse.java:106:34:106:43 | url : Object | -| InsecureWebResourceResponse.java:36:26:36:33 | inputUrl : Object | InsecureWebResourceResponse.java:131:36:131:45 | url : Object | -| InsecureWebResourceResponse.java:38:26:38:33 | inputUrl : Object | InsecureWebResourceResponse.java:156:35:156:44 | url : Object | -| InsecureWebResourceResponse.java:40:25:40:32 | inputUrl : Object | InsecureWebResourceResponse.java:181:34:181:43 | url : Object | -| InsecureWebResourceResponse.java:42:25:42:32 | inputUrl : Object | InsecureWebResourceResponse.java:188:34:188:43 | url : Object | -| InsecureWebResourceResponse.java:44:26:44:33 | inputUrl : Object | InsecureWebResourceResponse.java:217:35:217:44 | url : Object | -| InsecureWebResourceResponse.java:59:34:59:43 | url : Object | InsecureWebResourceResponse.java:75:20:75:22 | url : Object | -| InsecureWebResourceResponse.java:63:77:63:86 | url : Object | InsecureWebResourceResponse.java:65:41:65:43 | url : Object | +| InsecureWebResourceResponse.java:28:27:28:37 | getIntent(...) : Intent | InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | InsecureWebResourceResponse.java:30:25:30:32 | inputUrl : String | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | InsecureWebResourceResponse.java:32:25:32:32 | inputUrl : String | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | InsecureWebResourceResponse.java:34:25:34:32 | inputUrl : String | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | InsecureWebResourceResponse.java:36:26:36:33 | inputUrl : String | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | InsecureWebResourceResponse.java:38:26:38:33 | inputUrl : String | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | InsecureWebResourceResponse.java:40:25:40:32 | inputUrl : String | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | InsecureWebResourceResponse.java:42:25:42:32 | inputUrl : String | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | InsecureWebResourceResponse.java:44:26:44:33 | inputUrl : String | +| InsecureWebResourceResponse.java:30:25:30:32 | inputUrl : String | InsecureWebResourceResponse.java:59:34:59:43 | url : String | +| InsecureWebResourceResponse.java:32:25:32:32 | inputUrl : String | InsecureWebResourceResponse.java:80:34:80:43 | url : String | +| InsecureWebResourceResponse.java:34:25:34:32 | inputUrl : String | InsecureWebResourceResponse.java:106:34:106:43 | url : String | +| InsecureWebResourceResponse.java:36:26:36:33 | inputUrl : String | InsecureWebResourceResponse.java:131:36:131:45 | url : String | +| InsecureWebResourceResponse.java:38:26:38:33 | inputUrl : String | InsecureWebResourceResponse.java:156:35:156:44 | url : String | +| InsecureWebResourceResponse.java:40:25:40:32 | inputUrl : String | InsecureWebResourceResponse.java:181:34:181:43 | url : String | +| InsecureWebResourceResponse.java:42:25:42:32 | inputUrl : String | InsecureWebResourceResponse.java:188:34:188:43 | url : String | +| InsecureWebResourceResponse.java:44:26:44:33 | inputUrl : String | InsecureWebResourceResponse.java:217:35:217:44 | url : String | +| InsecureWebResourceResponse.java:59:34:59:43 | url : String | InsecureWebResourceResponse.java:75:20:75:22 | url : String | +| InsecureWebResourceResponse.java:63:77:63:86 | url : String | InsecureWebResourceResponse.java:65:41:65:43 | url : String | | InsecureWebResourceResponse.java:65:31:65:44 | parse(...) : Uri | InsecureWebResourceResponse.java:66:71:66:73 | uri : Uri | -| InsecureWebResourceResponse.java:65:41:65:43 | url : Object | InsecureWebResourceResponse.java:65:31:65:44 | parse(...) : Uri | +| InsecureWebResourceResponse.java:65:41:65:43 | url : String | InsecureWebResourceResponse.java:65:31:65:44 | parse(...) : Uri | | InsecureWebResourceResponse.java:66:51:66:84 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:68:71:68:81 | inputStream | | InsecureWebResourceResponse.java:66:71:66:73 | uri : Uri | InsecureWebResourceResponse.java:66:71:66:83 | getPath(...) : String | | InsecureWebResourceResponse.java:66:71:66:83 | getPath(...) : String | InsecureWebResourceResponse.java:66:51:66:84 | new FileInputStream(...) : FileInputStream | -| InsecureWebResourceResponse.java:75:20:75:22 | url : Object | InsecureWebResourceResponse.java:63:77:63:86 | url : Object | -| InsecureWebResourceResponse.java:75:20:75:22 | url : Object | InsecureWebResourceResponse.java:84:77:84:86 | url : Object | -| InsecureWebResourceResponse.java:75:20:75:22 | url : Object | InsecureWebResourceResponse.java:110:77:110:86 | url : Object | -| InsecureWebResourceResponse.java:75:20:75:22 | url : Object | InsecureWebResourceResponse.java:192:77:192:102 | request : Object | -| InsecureWebResourceResponse.java:75:20:75:22 | url : Object | InsecureWebResourceResponse.java:232:69:232:78 | url : Object | -| InsecureWebResourceResponse.java:80:34:80:43 | url : Object | InsecureWebResourceResponse.java:101:20:101:22 | url : Object | -| InsecureWebResourceResponse.java:84:77:84:86 | url : Object | InsecureWebResourceResponse.java:86:41:86:43 | url : Object | +| InsecureWebResourceResponse.java:75:20:75:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | +| InsecureWebResourceResponse.java:75:20:75:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | +| InsecureWebResourceResponse.java:75:20:75:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | +| InsecureWebResourceResponse.java:75:20:75:22 | url : String | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:75:20:75:22 | url : String | InsecureWebResourceResponse.java:232:69:232:78 | url : String | +| InsecureWebResourceResponse.java:80:34:80:43 | url : String | InsecureWebResourceResponse.java:101:20:101:22 | url : String | +| InsecureWebResourceResponse.java:84:77:84:86 | url : String | InsecureWebResourceResponse.java:86:41:86:43 | url : String | | InsecureWebResourceResponse.java:86:31:86:44 | parse(...) : Uri | InsecureWebResourceResponse.java:88:66:88:68 | uri : Uri | -| InsecureWebResourceResponse.java:86:41:86:43 | url : Object | InsecureWebResourceResponse.java:86:31:86:44 | parse(...) : Uri | +| InsecureWebResourceResponse.java:86:41:86:43 | url : String | InsecureWebResourceResponse.java:86:31:86:44 | parse(...) : Uri | | InsecureWebResourceResponse.java:88:42:88:90 | new File(...) : File | InsecureWebResourceResponse.java:89:75:89:83 | cacheFile : File | | InsecureWebResourceResponse.java:88:66:88:68 | uri : Uri | InsecureWebResourceResponse.java:88:66:88:89 | getLastPathSegment(...) : String | | InsecureWebResourceResponse.java:88:66:88:89 | getLastPathSegment(...) : String | InsecureWebResourceResponse.java:88:42:88:90 | new File(...) : File | | InsecureWebResourceResponse.java:89:55:89:84 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:91:75:91:85 | inputStream | | InsecureWebResourceResponse.java:89:75:89:83 | cacheFile : File | InsecureWebResourceResponse.java:89:55:89:84 | new FileInputStream(...) : FileInputStream | -| InsecureWebResourceResponse.java:101:20:101:22 | url : Object | InsecureWebResourceResponse.java:63:77:63:86 | url : Object | -| InsecureWebResourceResponse.java:101:20:101:22 | url : Object | InsecureWebResourceResponse.java:84:77:84:86 | url : Object | -| InsecureWebResourceResponse.java:101:20:101:22 | url : Object | InsecureWebResourceResponse.java:110:77:110:86 | url : Object | -| InsecureWebResourceResponse.java:101:20:101:22 | url : Object | InsecureWebResourceResponse.java:192:77:192:102 | request : Object | -| InsecureWebResourceResponse.java:101:20:101:22 | url : Object | InsecureWebResourceResponse.java:232:69:232:78 | url : Object | -| InsecureWebResourceResponse.java:106:34:106:43 | url : Object | InsecureWebResourceResponse.java:127:20:127:22 | url : Object | -| InsecureWebResourceResponse.java:110:77:110:86 | url : Object | InsecureWebResourceResponse.java:112:41:112:43 | url : Object | +| InsecureWebResourceResponse.java:101:20:101:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | +| InsecureWebResourceResponse.java:101:20:101:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | +| InsecureWebResourceResponse.java:101:20:101:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | +| InsecureWebResourceResponse.java:101:20:101:22 | url : String | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:101:20:101:22 | url : String | InsecureWebResourceResponse.java:232:69:232:78 | url : String | +| InsecureWebResourceResponse.java:106:34:106:43 | url : String | InsecureWebResourceResponse.java:127:20:127:22 | url : String | +| InsecureWebResourceResponse.java:110:77:110:86 | url : String | InsecureWebResourceResponse.java:112:41:112:43 | url : String | | InsecureWebResourceResponse.java:112:31:112:44 | parse(...) : Uri | InsecureWebResourceResponse.java:113:35:113:37 | uri : Uri | -| InsecureWebResourceResponse.java:112:41:112:43 | url : Object | InsecureWebResourceResponse.java:112:31:112:44 | parse(...) : Uri | +| InsecureWebResourceResponse.java:112:41:112:43 | url : String | InsecureWebResourceResponse.java:112:31:112:44 | parse(...) : Uri | | InsecureWebResourceResponse.java:113:35:113:37 | uri : Uri | InsecureWebResourceResponse.java:113:35:113:47 | getPath(...) : String | | InsecureWebResourceResponse.java:113:35:113:47 | getPath(...) : String | InsecureWebResourceResponse.java:113:35:113:60 | substring(...) : String | | InsecureWebResourceResponse.java:113:35:113:60 | substring(...) : String | InsecureWebResourceResponse.java:115:75:115:78 | path : String | | InsecureWebResourceResponse.java:115:55:115:108 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:117:75:117:85 | inputStream | | InsecureWebResourceResponse.java:115:75:115:78 | path : String | InsecureWebResourceResponse.java:115:75:115:107 | substring(...) : String | | InsecureWebResourceResponse.java:115:75:115:107 | substring(...) : String | InsecureWebResourceResponse.java:115:55:115:108 | new FileInputStream(...) : FileInputStream | -| InsecureWebResourceResponse.java:127:20:127:22 | url : Object | InsecureWebResourceResponse.java:63:77:63:86 | url : Object | -| InsecureWebResourceResponse.java:127:20:127:22 | url : Object | InsecureWebResourceResponse.java:84:77:84:86 | url : Object | -| InsecureWebResourceResponse.java:127:20:127:22 | url : Object | InsecureWebResourceResponse.java:110:77:110:86 | url : Object | -| InsecureWebResourceResponse.java:127:20:127:22 | url : Object | InsecureWebResourceResponse.java:192:77:192:102 | request : Object | -| InsecureWebResourceResponse.java:127:20:127:22 | url : Object | InsecureWebResourceResponse.java:232:69:232:78 | url : Object | -| InsecureWebResourceResponse.java:131:36:131:45 | url : Object | InsecureWebResourceResponse.java:152:20:152:22 | url : Object | -| InsecureWebResourceResponse.java:152:20:152:22 | url : Object | InsecureWebResourceResponse.java:63:77:63:86 | url : Object | -| InsecureWebResourceResponse.java:152:20:152:22 | url : Object | InsecureWebResourceResponse.java:84:77:84:86 | url : Object | -| InsecureWebResourceResponse.java:152:20:152:22 | url : Object | InsecureWebResourceResponse.java:110:77:110:86 | url : Object | -| InsecureWebResourceResponse.java:152:20:152:22 | url : Object | InsecureWebResourceResponse.java:192:77:192:102 | request : Object | -| InsecureWebResourceResponse.java:152:20:152:22 | url : Object | InsecureWebResourceResponse.java:232:69:232:78 | url : Object | -| InsecureWebResourceResponse.java:156:35:156:44 | url : Object | InsecureWebResourceResponse.java:177:20:177:22 | url : Object | -| InsecureWebResourceResponse.java:177:20:177:22 | url : Object | InsecureWebResourceResponse.java:63:77:63:86 | url : Object | -| InsecureWebResourceResponse.java:177:20:177:22 | url : Object | InsecureWebResourceResponse.java:84:77:84:86 | url : Object | -| InsecureWebResourceResponse.java:177:20:177:22 | url : Object | InsecureWebResourceResponse.java:110:77:110:86 | url : Object | -| InsecureWebResourceResponse.java:177:20:177:22 | url : Object | InsecureWebResourceResponse.java:192:77:192:102 | request : Object | -| InsecureWebResourceResponse.java:177:20:177:22 | url : Object | InsecureWebResourceResponse.java:232:69:232:78 | url : Object | -| InsecureWebResourceResponse.java:181:34:181:43 | url : Object | InsecureWebResourceResponse.java:184:20:184:22 | url : Object | -| InsecureWebResourceResponse.java:184:20:184:22 | url : Object | InsecureWebResourceResponse.java:63:77:63:86 | url : Object | -| InsecureWebResourceResponse.java:184:20:184:22 | url : Object | InsecureWebResourceResponse.java:84:77:84:86 | url : Object | -| InsecureWebResourceResponse.java:184:20:184:22 | url : Object | InsecureWebResourceResponse.java:110:77:110:86 | url : Object | -| InsecureWebResourceResponse.java:184:20:184:22 | url : Object | InsecureWebResourceResponse.java:192:77:192:102 | request : Object | -| InsecureWebResourceResponse.java:184:20:184:22 | url : Object | InsecureWebResourceResponse.java:232:69:232:78 | url : Object | -| InsecureWebResourceResponse.java:188:34:188:43 | url : Object | InsecureWebResourceResponse.java:209:20:209:22 | url : Object | -| InsecureWebResourceResponse.java:192:77:192:102 | request : Object | InsecureWebResourceResponse.java:194:31:194:37 | request : Object | -| InsecureWebResourceResponse.java:194:31:194:37 | request : Object | InsecureWebResourceResponse.java:194:31:194:46 | getUrl(...) : Uri | +| InsecureWebResourceResponse.java:127:20:127:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | +| InsecureWebResourceResponse.java:127:20:127:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | +| InsecureWebResourceResponse.java:127:20:127:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | +| InsecureWebResourceResponse.java:127:20:127:22 | url : String | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:127:20:127:22 | url : String | InsecureWebResourceResponse.java:232:69:232:78 | url : String | +| InsecureWebResourceResponse.java:131:36:131:45 | url : String | InsecureWebResourceResponse.java:152:20:152:22 | url : String | +| InsecureWebResourceResponse.java:152:20:152:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | +| InsecureWebResourceResponse.java:152:20:152:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | +| InsecureWebResourceResponse.java:152:20:152:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | +| InsecureWebResourceResponse.java:152:20:152:22 | url : String | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:152:20:152:22 | url : String | InsecureWebResourceResponse.java:232:69:232:78 | url : String | +| InsecureWebResourceResponse.java:156:35:156:44 | url : String | InsecureWebResourceResponse.java:177:20:177:22 | url : String | +| InsecureWebResourceResponse.java:177:20:177:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | +| InsecureWebResourceResponse.java:177:20:177:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | +| InsecureWebResourceResponse.java:177:20:177:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | +| InsecureWebResourceResponse.java:177:20:177:22 | url : String | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:177:20:177:22 | url : String | InsecureWebResourceResponse.java:232:69:232:78 | url : String | +| InsecureWebResourceResponse.java:181:34:181:43 | url : String | InsecureWebResourceResponse.java:184:20:184:22 | url : String | +| InsecureWebResourceResponse.java:184:20:184:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | +| InsecureWebResourceResponse.java:184:20:184:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | +| InsecureWebResourceResponse.java:184:20:184:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | +| InsecureWebResourceResponse.java:184:20:184:22 | url : String | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:184:20:184:22 | url : String | InsecureWebResourceResponse.java:232:69:232:78 | url : String | +| InsecureWebResourceResponse.java:188:34:188:43 | url : String | InsecureWebResourceResponse.java:209:20:209:22 | url : String | +| InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | InsecureWebResourceResponse.java:194:31:194:37 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:194:31:194:37 | request : WebResourceRequest | InsecureWebResourceResponse.java:194:31:194:46 | getUrl(...) : Uri | | InsecureWebResourceResponse.java:194:31:194:46 | getUrl(...) : Uri | InsecureWebResourceResponse.java:196:66:196:68 | uri : Uri | | InsecureWebResourceResponse.java:196:42:196:90 | new File(...) : File | InsecureWebResourceResponse.java:197:75:197:83 | cacheFile : File | | InsecureWebResourceResponse.java:196:66:196:68 | uri : Uri | InsecureWebResourceResponse.java:196:66:196:89 | getLastPathSegment(...) : String | | InsecureWebResourceResponse.java:196:66:196:89 | getLastPathSegment(...) : String | InsecureWebResourceResponse.java:196:42:196:90 | new File(...) : File | | InsecureWebResourceResponse.java:197:55:197:84 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:199:75:199:85 | inputStream | | InsecureWebResourceResponse.java:197:75:197:83 | cacheFile : File | InsecureWebResourceResponse.java:197:55:197:84 | new FileInputStream(...) : FileInputStream | -| InsecureWebResourceResponse.java:209:20:209:22 | url : Object | InsecureWebResourceResponse.java:63:77:63:86 | url : Object | -| InsecureWebResourceResponse.java:209:20:209:22 | url : Object | InsecureWebResourceResponse.java:84:77:84:86 | url : Object | -| InsecureWebResourceResponse.java:209:20:209:22 | url : Object | InsecureWebResourceResponse.java:110:77:110:86 | url : Object | -| InsecureWebResourceResponse.java:209:20:209:22 | url : Object | InsecureWebResourceResponse.java:192:77:192:102 | request : Object | -| InsecureWebResourceResponse.java:209:20:209:22 | url : Object | InsecureWebResourceResponse.java:232:69:232:78 | url : Object | -| InsecureWebResourceResponse.java:217:35:217:44 | url : Object | InsecureWebResourceResponse.java:226:20:226:22 | url : Object | -| InsecureWebResourceResponse.java:226:20:226:22 | url : Object | InsecureWebResourceResponse.java:63:77:63:86 | url : Object | -| InsecureWebResourceResponse.java:226:20:226:22 | url : Object | InsecureWebResourceResponse.java:84:77:84:86 | url : Object | -| InsecureWebResourceResponse.java:226:20:226:22 | url : Object | InsecureWebResourceResponse.java:110:77:110:86 | url : Object | -| InsecureWebResourceResponse.java:226:20:226:22 | url : Object | InsecureWebResourceResponse.java:192:77:192:102 | request : Object | -| InsecureWebResourceResponse.java:226:20:226:22 | url : Object | InsecureWebResourceResponse.java:232:69:232:78 | url : Object | -| InsecureWebResourceResponse.java:232:69:232:78 | url : Object | InsecureWebResourceResponse.java:234:33:234:35 | url : Object | +| InsecureWebResourceResponse.java:209:20:209:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | +| InsecureWebResourceResponse.java:209:20:209:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | +| InsecureWebResourceResponse.java:209:20:209:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | +| InsecureWebResourceResponse.java:209:20:209:22 | url : String | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:209:20:209:22 | url : String | InsecureWebResourceResponse.java:232:69:232:78 | url : String | +| InsecureWebResourceResponse.java:217:35:217:44 | url : String | InsecureWebResourceResponse.java:226:20:226:22 | url : String | +| InsecureWebResourceResponse.java:226:20:226:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | +| InsecureWebResourceResponse.java:226:20:226:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | +| InsecureWebResourceResponse.java:226:20:226:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | +| InsecureWebResourceResponse.java:226:20:226:22 | url : String | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | +| InsecureWebResourceResponse.java:226:20:226:22 | url : String | InsecureWebResourceResponse.java:232:69:232:78 | url : String | +| InsecureWebResourceResponse.java:232:69:232:78 | url : String | InsecureWebResourceResponse.java:234:33:234:35 | url : String | | InsecureWebResourceResponse.java:234:23:234:36 | parse(...) : Uri | InsecureWebResourceResponse.java:235:63:235:65 | uri : Uri | -| InsecureWebResourceResponse.java:234:33:234:35 | url : Object | InsecureWebResourceResponse.java:234:23:234:36 | parse(...) : Uri | +| InsecureWebResourceResponse.java:234:33:234:35 | url : String | InsecureWebResourceResponse.java:234:23:234:36 | parse(...) : Uri | | InsecureWebResourceResponse.java:235:43:235:76 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:237:63:237:73 | inputStream | | InsecureWebResourceResponse.java:235:63:235:65 | uri : Uri | InsecureWebResourceResponse.java:235:63:235:75 | getPath(...) : String | | InsecureWebResourceResponse.java:235:63:235:75 | getPath(...) : String | InsecureWebResourceResponse.java:235:43:235:76 | new FileInputStream(...) : FileInputStream | -| InsecureWebViewActivity.java:27:27:27:37 | getIntent(...) : Intent | InsecureWebViewActivity.java:27:27:27:64 | getStringExtra(...) : Object | -| InsecureWebViewActivity.java:27:27:27:64 | getStringExtra(...) : Object | InsecureWebViewActivity.java:28:20:28:27 | inputUrl : Object | -| InsecureWebViewActivity.java:28:20:28:27 | inputUrl : Object | InsecureWebViewActivity.java:42:28:42:37 | url : Object | -| InsecureWebViewActivity.java:42:28:42:37 | url : Object | InsecureWebViewActivity.java:43:25:43:27 | url : Object | -| InsecureWebViewActivity.java:43:25:43:27 | url : Object | InsecureWebViewActivity.java:53:77:53:86 | url : Object | -| InsecureWebViewActivity.java:53:77:53:86 | url : Object | InsecureWebViewActivity.java:55:41:55:43 | url : Object | +| InsecureWebViewActivity.java:27:27:27:37 | getIntent(...) : Intent | InsecureWebViewActivity.java:27:27:27:64 | getStringExtra(...) : String | +| InsecureWebViewActivity.java:27:27:27:64 | getStringExtra(...) : String | InsecureWebViewActivity.java:28:20:28:27 | inputUrl : String | +| InsecureWebViewActivity.java:28:20:28:27 | inputUrl : String | InsecureWebViewActivity.java:42:28:42:37 | url : String | +| InsecureWebViewActivity.java:42:28:42:37 | url : String | InsecureWebViewActivity.java:43:25:43:27 | url : String | +| InsecureWebViewActivity.java:43:25:43:27 | url : String | InsecureWebViewActivity.java:53:77:53:86 | url : String | +| InsecureWebViewActivity.java:53:77:53:86 | url : String | InsecureWebViewActivity.java:55:41:55:43 | url : String | | InsecureWebViewActivity.java:55:31:55:44 | parse(...) : Uri | InsecureWebViewActivity.java:56:71:56:73 | uri : Uri | -| InsecureWebViewActivity.java:55:41:55:43 | url : Object | InsecureWebViewActivity.java:55:31:55:44 | parse(...) : Uri | +| InsecureWebViewActivity.java:55:41:55:43 | url : String | InsecureWebViewActivity.java:55:31:55:44 | parse(...) : Uri | | InsecureWebViewActivity.java:56:51:56:84 | new FileInputStream(...) : FileInputStream | InsecureWebViewActivity.java:58:71:58:81 | inputStream | | InsecureWebViewActivity.java:56:71:56:73 | uri : Uri | InsecureWebViewActivity.java:56:71:56:83 | getPath(...) : String | | InsecureWebViewActivity.java:56:71:56:83 | getPath(...) : String | InsecureWebViewActivity.java:56:51:56:84 | new FileInputStream(...) : FileInputStream | nodes | InsecureWebResourceResponse.java:28:27:28:37 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent | -| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : Object | semmle.label | getStringExtra(...) : Object | -| InsecureWebResourceResponse.java:30:25:30:32 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebResourceResponse.java:32:25:32:32 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebResourceResponse.java:34:25:34:32 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebResourceResponse.java:36:26:36:33 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebResourceResponse.java:38:26:38:33 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebResourceResponse.java:40:25:40:32 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebResourceResponse.java:42:25:42:32 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebResourceResponse.java:44:26:44:33 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebResourceResponse.java:59:34:59:43 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:63:77:63:86 | url : Object | semmle.label | url : Object | +| InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | +| InsecureWebResourceResponse.java:30:25:30:32 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebResourceResponse.java:32:25:32:32 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebResourceResponse.java:34:25:34:32 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebResourceResponse.java:36:26:36:33 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebResourceResponse.java:38:26:38:33 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebResourceResponse.java:40:25:40:32 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebResourceResponse.java:42:25:42:32 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebResourceResponse.java:44:26:44:33 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebResourceResponse.java:59:34:59:43 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:63:77:63:86 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:65:31:65:44 | parse(...) : Uri | semmle.label | parse(...) : Uri | -| InsecureWebResourceResponse.java:65:41:65:43 | url : Object | semmle.label | url : Object | +| InsecureWebResourceResponse.java:65:41:65:43 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:66:51:66:84 | new FileInputStream(...) : FileInputStream | semmle.label | new FileInputStream(...) : FileInputStream | | InsecureWebResourceResponse.java:66:71:66:73 | uri : Uri | semmle.label | uri : Uri | | InsecureWebResourceResponse.java:66:71:66:83 | getPath(...) : String | semmle.label | getPath(...) : String | | InsecureWebResourceResponse.java:68:71:68:81 | inputStream | semmle.label | inputStream | -| InsecureWebResourceResponse.java:75:20:75:22 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:80:34:80:43 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:84:77:84:86 | url : Object | semmle.label | url : Object | +| InsecureWebResourceResponse.java:75:20:75:22 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:80:34:80:43 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:84:77:84:86 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:86:31:86:44 | parse(...) : Uri | semmle.label | parse(...) : Uri | -| InsecureWebResourceResponse.java:86:41:86:43 | url : Object | semmle.label | url : Object | +| InsecureWebResourceResponse.java:86:41:86:43 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:88:42:88:90 | new File(...) : File | semmle.label | new File(...) : File | | InsecureWebResourceResponse.java:88:66:88:68 | uri : Uri | semmle.label | uri : Uri | | InsecureWebResourceResponse.java:88:66:88:89 | getLastPathSegment(...) : String | semmle.label | getLastPathSegment(...) : String | | InsecureWebResourceResponse.java:89:55:89:84 | new FileInputStream(...) : FileInputStream | semmle.label | new FileInputStream(...) : FileInputStream | | InsecureWebResourceResponse.java:89:75:89:83 | cacheFile : File | semmle.label | cacheFile : File | | InsecureWebResourceResponse.java:91:75:91:85 | inputStream | semmle.label | inputStream | -| InsecureWebResourceResponse.java:101:20:101:22 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:106:34:106:43 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:110:77:110:86 | url : Object | semmle.label | url : Object | +| InsecureWebResourceResponse.java:101:20:101:22 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:106:34:106:43 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:110:77:110:86 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:112:31:112:44 | parse(...) : Uri | semmle.label | parse(...) : Uri | -| InsecureWebResourceResponse.java:112:41:112:43 | url : Object | semmle.label | url : Object | +| InsecureWebResourceResponse.java:112:41:112:43 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:113:35:113:37 | uri : Uri | semmle.label | uri : Uri | | InsecureWebResourceResponse.java:113:35:113:47 | getPath(...) : String | semmle.label | getPath(...) : String | | InsecureWebResourceResponse.java:113:35:113:60 | substring(...) : String | semmle.label | substring(...) : String | @@ -154,16 +154,16 @@ nodes | InsecureWebResourceResponse.java:115:75:115:78 | path : String | semmle.label | path : String | | InsecureWebResourceResponse.java:115:75:115:107 | substring(...) : String | semmle.label | substring(...) : String | | InsecureWebResourceResponse.java:117:75:117:85 | inputStream | semmle.label | inputStream | -| InsecureWebResourceResponse.java:127:20:127:22 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:131:36:131:45 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:152:20:152:22 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:156:35:156:44 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:177:20:177:22 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:181:34:181:43 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:184:20:184:22 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:188:34:188:43 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:192:77:192:102 | request : Object | semmle.label | request : Object | -| InsecureWebResourceResponse.java:194:31:194:37 | request : Object | semmle.label | request : Object | +| InsecureWebResourceResponse.java:127:20:127:22 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:131:36:131:45 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:152:20:152:22 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:156:35:156:44 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:177:20:177:22 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:181:34:181:43 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:184:20:184:22 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:188:34:188:43 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | semmle.label | request : WebResourceRequest | +| InsecureWebResourceResponse.java:194:31:194:37 | request : WebResourceRequest | semmle.label | request : WebResourceRequest | | InsecureWebResourceResponse.java:194:31:194:46 | getUrl(...) : Uri | semmle.label | getUrl(...) : Uri | | InsecureWebResourceResponse.java:196:42:196:90 | new File(...) : File | semmle.label | new File(...) : File | | InsecureWebResourceResponse.java:196:66:196:68 | uri : Uri | semmle.label | uri : Uri | @@ -171,24 +171,24 @@ nodes | InsecureWebResourceResponse.java:197:55:197:84 | new FileInputStream(...) : FileInputStream | semmle.label | new FileInputStream(...) : FileInputStream | | InsecureWebResourceResponse.java:197:75:197:83 | cacheFile : File | semmle.label | cacheFile : File | | InsecureWebResourceResponse.java:199:75:199:85 | inputStream | semmle.label | inputStream | -| InsecureWebResourceResponse.java:209:20:209:22 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:217:35:217:44 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:226:20:226:22 | url : Object | semmle.label | url : Object | -| InsecureWebResourceResponse.java:232:69:232:78 | url : Object | semmle.label | url : Object | +| InsecureWebResourceResponse.java:209:20:209:22 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:217:35:217:44 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:226:20:226:22 | url : String | semmle.label | url : String | +| InsecureWebResourceResponse.java:232:69:232:78 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:234:23:234:36 | parse(...) : Uri | semmle.label | parse(...) : Uri | -| InsecureWebResourceResponse.java:234:33:234:35 | url : Object | semmle.label | url : Object | +| InsecureWebResourceResponse.java:234:33:234:35 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:235:43:235:76 | new FileInputStream(...) : FileInputStream | semmle.label | new FileInputStream(...) : FileInputStream | | InsecureWebResourceResponse.java:235:63:235:65 | uri : Uri | semmle.label | uri : Uri | | InsecureWebResourceResponse.java:235:63:235:75 | getPath(...) : String | semmle.label | getPath(...) : String | | InsecureWebResourceResponse.java:237:63:237:73 | inputStream | semmle.label | inputStream | | InsecureWebViewActivity.java:27:27:27:37 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent | -| InsecureWebViewActivity.java:27:27:27:64 | getStringExtra(...) : Object | semmle.label | getStringExtra(...) : Object | -| InsecureWebViewActivity.java:28:20:28:27 | inputUrl : Object | semmle.label | inputUrl : Object | -| InsecureWebViewActivity.java:42:28:42:37 | url : Object | semmle.label | url : Object | -| InsecureWebViewActivity.java:43:25:43:27 | url : Object | semmle.label | url : Object | -| InsecureWebViewActivity.java:53:77:53:86 | url : Object | semmle.label | url : Object | +| InsecureWebViewActivity.java:27:27:27:64 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | +| InsecureWebViewActivity.java:28:20:28:27 | inputUrl : String | semmle.label | inputUrl : String | +| InsecureWebViewActivity.java:42:28:42:37 | url : String | semmle.label | url : String | +| InsecureWebViewActivity.java:43:25:43:27 | url : String | semmle.label | url : String | +| InsecureWebViewActivity.java:53:77:53:86 | url : String | semmle.label | url : String | | InsecureWebViewActivity.java:55:31:55:44 | parse(...) : Uri | semmle.label | parse(...) : Uri | -| InsecureWebViewActivity.java:55:41:55:43 | url : Object | semmle.label | url : Object | +| InsecureWebViewActivity.java:55:41:55:43 | url : String | semmle.label | url : String | | InsecureWebViewActivity.java:56:51:56:84 | new FileInputStream(...) : FileInputStream | semmle.label | new FileInputStream(...) : FileInputStream | | InsecureWebViewActivity.java:56:71:56:73 | uri : Uri | semmle.label | uri : Uri | | InsecureWebViewActivity.java:56:71:56:83 | getPath(...) : String | semmle.label | getPath(...) : String | diff --git a/java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected b/java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected index 43a64e4226a..9c5b6ce8b69 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected @@ -1,47 +1,47 @@ edges | FileService.java:20:31:20:43 | intent : Intent | FileService.java:21:28:21:33 | intent : Intent | -| FileService.java:21:28:21:33 | intent : Intent | FileService.java:21:28:21:64 | getStringExtra(...) : Object | -| FileService.java:21:28:21:64 | getStringExtra(...) : Object | FileService.java:25:42:25:50 | localPath : Object | +| FileService.java:21:28:21:33 | intent : Intent | FileService.java:21:28:21:64 | getStringExtra(...) : String | +| FileService.java:21:28:21:64 | getStringExtra(...) : String | FileService.java:25:42:25:50 | localPath : String | | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | FileService.java:40:41:40:55 | params : Object[] | -| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : Object | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | -| FileService.java:25:42:25:50 | localPath : Object | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : Object | -| FileService.java:25:42:25:50 | localPath : Object | FileService.java:32:13:32:28 | sourceUri : Object | -| FileService.java:32:13:32:28 | sourceUri : Object | FileService.java:35:17:35:25 | sourceUri : Object | -| FileService.java:34:20:36:13 | {...} : Object[] [[]] : Object | FileService.java:34:20:36:13 | new Object[] : Object[] [[]] : Object | -| FileService.java:35:17:35:25 | sourceUri : Object | FileService.java:34:20:36:13 | {...} : Object[] [[]] : Object | -| FileService.java:40:41:40:55 | params : Object[] | FileService.java:44:33:44:52 | (...)... : Object | -| FileService.java:44:33:44:52 | (...)... : Object | FileService.java:45:53:45:59 | ...[...] | +| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : String | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | +| FileService.java:25:42:25:50 | localPath : String | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : String | +| FileService.java:25:42:25:50 | localPath : String | FileService.java:32:13:32:28 | sourceUri : String | +| FileService.java:32:13:32:28 | sourceUri : String | FileService.java:35:17:35:25 | sourceUri : String | +| FileService.java:34:20:36:13 | {...} : Object[] [[]] : String | FileService.java:34:20:36:13 | new Object[] : Object[] [[]] : String | +| FileService.java:35:17:35:25 | sourceUri : String | FileService.java:34:20:36:13 | {...} : Object[] [[]] : String | +| FileService.java:40:41:40:55 | params : Object[] | FileService.java:44:33:44:52 | (...)... : String[] | +| FileService.java:44:33:44:52 | (...)... : String[] | FileService.java:45:53:45:59 | ...[...] | | LeakFileActivity2.java:15:13:15:18 | intent : Intent | LeakFileActivity2.java:16:26:16:31 | intent : Intent | | LeakFileActivity2.java:16:26:16:31 | intent : Intent | FileService.java:20:31:20:43 | intent : Intent | | LeakFileActivity.java:14:35:14:38 | data : Intent | LeakFileActivity.java:18:40:18:59 | contentIntent : Intent | | LeakFileActivity.java:18:40:18:59 | contentIntent : Intent | LeakFileActivity.java:19:31:19:43 | contentIntent : Intent | -| LeakFileActivity.java:19:31:19:43 | contentIntent : Intent | LeakFileActivity.java:19:31:19:53 | getData(...) : Object | -| LeakFileActivity.java:19:31:19:53 | getData(...) : Object | LeakFileActivity.java:21:58:21:72 | streamsToUpload : Object | -| LeakFileActivity.java:21:58:21:72 | streamsToUpload : Object | LeakFileActivity.java:21:58:21:82 | getPath(...) | +| LeakFileActivity.java:19:31:19:43 | contentIntent : Intent | LeakFileActivity.java:19:31:19:53 | getData(...) : Uri | +| LeakFileActivity.java:19:31:19:53 | getData(...) : Uri | LeakFileActivity.java:21:58:21:72 | streamsToUpload : Uri | +| LeakFileActivity.java:21:58:21:72 | streamsToUpload : Uri | LeakFileActivity.java:21:58:21:82 | getPath(...) | nodes | FileService.java:20:31:20:43 | intent : Intent | semmle.label | intent : Intent | | FileService.java:21:28:21:33 | intent : Intent | semmle.label | intent : Intent | -| FileService.java:21:28:21:64 | getStringExtra(...) : Object | semmle.label | getStringExtra(...) : Object | +| FileService.java:21:28:21:64 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | semmle.label | makeParamsToExecute(...) : Object[] | -| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : Object | semmle.label | makeParamsToExecute(...) : Object[] [[]] : Object | -| FileService.java:25:42:25:50 | localPath : Object | semmle.label | localPath : Object | -| FileService.java:32:13:32:28 | sourceUri : Object | semmle.label | sourceUri : Object | -| FileService.java:34:20:36:13 | new Object[] : Object[] [[]] : Object | semmle.label | new Object[] : Object[] [[]] : Object | -| FileService.java:34:20:36:13 | {...} : Object[] [[]] : Object | semmle.label | {...} : Object[] [[]] : Object | -| FileService.java:35:17:35:25 | sourceUri : Object | semmle.label | sourceUri : Object | +| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : String | semmle.label | makeParamsToExecute(...) : Object[] [[]] : String | +| FileService.java:25:42:25:50 | localPath : String | semmle.label | localPath : String | +| FileService.java:32:13:32:28 | sourceUri : String | semmle.label | sourceUri : String | +| FileService.java:34:20:36:13 | new Object[] : Object[] [[]] : String | semmle.label | new Object[] : Object[] [[]] : String | +| FileService.java:34:20:36:13 | {...} : Object[] [[]] : String | semmle.label | {...} : Object[] [[]] : String | +| FileService.java:35:17:35:25 | sourceUri : String | semmle.label | sourceUri : String | | FileService.java:40:41:40:55 | params : Object[] | semmle.label | params : Object[] | -| FileService.java:44:33:44:52 | (...)... : Object | semmle.label | (...)... : Object | +| FileService.java:44:33:44:52 | (...)... : String[] | semmle.label | (...)... : String[] | | FileService.java:45:53:45:59 | ...[...] | semmle.label | ...[...] | | LeakFileActivity2.java:15:13:15:18 | intent : Intent | semmle.label | intent : Intent | | LeakFileActivity2.java:16:26:16:31 | intent : Intent | semmle.label | intent : Intent | | LeakFileActivity.java:14:35:14:38 | data : Intent | semmle.label | data : Intent | | LeakFileActivity.java:18:40:18:59 | contentIntent : Intent | semmle.label | contentIntent : Intent | | LeakFileActivity.java:19:31:19:43 | contentIntent : Intent | semmle.label | contentIntent : Intent | -| LeakFileActivity.java:19:31:19:53 | getData(...) : Object | semmle.label | getData(...) : Object | -| LeakFileActivity.java:21:58:21:72 | streamsToUpload : Object | semmle.label | streamsToUpload : Object | +| LeakFileActivity.java:19:31:19:53 | getData(...) : Uri | semmle.label | getData(...) : Uri | +| LeakFileActivity.java:21:58:21:72 | streamsToUpload : Uri | semmle.label | streamsToUpload : Uri | | LeakFileActivity.java:21:58:21:82 | getPath(...) | semmle.label | getPath(...) | subpaths -| FileService.java:25:42:25:50 | localPath : Object | FileService.java:32:13:32:28 | sourceUri : Object | FileService.java:34:20:36:13 | new Object[] : Object[] [[]] : Object | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : Object | +| FileService.java:25:42:25:50 | localPath : String | FileService.java:32:13:32:28 | sourceUri : String | FileService.java:34:20:36:13 | new Object[] : Object[] [[]] : String | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : String | #select | FileService.java:45:53:45:59 | ...[...] | LeakFileActivity2.java:15:13:15:18 | intent : Intent | FileService.java:45:53:45:59 | ...[...] | Leaking arbitrary Android file from $@. | LeakFileActivity2.java:15:13:15:18 | intent | this user input | | FileService.java:45:53:45:59 | ...[...] | LeakFileActivity2.java:16:26:16:31 | intent : Intent | FileService.java:45:53:45:59 | ...[...] | Leaking arbitrary Android file from $@. | LeakFileActivity2.java:16:26:16:31 | intent | this user input | diff --git a/java/ql/test/experimental/query-tests/security/CWE-470/UnsafeReflection.expected b/java/ql/test/experimental/query-tests/security/CWE-470/UnsafeReflection.expected index b6f894c3e5f..606cf994976 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-470/UnsafeReflection.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-470/UnsafeReflection.expected @@ -6,17 +6,17 @@ edges | UnsafeReflection.java:34:33:34:70 | getParameter(...) : String | UnsafeReflection.java:39:58:39:71 | parameterValue | | UnsafeReflection.java:46:24:46:82 | beanIdOrClassName : String | UnsafeReflection.java:53:30:53:46 | beanIdOrClassName : String | | UnsafeReflection.java:46:132:46:168 | body : Map | UnsafeReflection.java:49:37:49:40 | body : Map | -| UnsafeReflection.java:49:23:49:59 | (...)... : Object | UnsafeReflection.java:53:67:53:73 | rawData : Object | +| UnsafeReflection.java:49:23:49:59 | (...)... : List | UnsafeReflection.java:53:67:53:73 | rawData : List | | UnsafeReflection.java:49:37:49:40 | body : Map | UnsafeReflection.java:49:37:49:59 | get(...) : Object | -| UnsafeReflection.java:49:37:49:59 | get(...) : Object | UnsafeReflection.java:49:23:49:59 | (...)... : Object | +| UnsafeReflection.java:49:37:49:59 | get(...) : Object | UnsafeReflection.java:49:23:49:59 | (...)... : List | | UnsafeReflection.java:53:30:53:46 | beanIdOrClassName : String | UnsafeReflection.java:104:34:104:57 | beanIdOrClassName : String | -| UnsafeReflection.java:53:67:53:73 | rawData : Object | UnsafeReflection.java:104:102:104:118 | data : Object | +| UnsafeReflection.java:53:67:53:73 | rawData : List | UnsafeReflection.java:104:102:104:118 | data : List | | UnsafeReflection.java:62:33:62:70 | getParameter(...) : String | UnsafeReflection.java:68:76:68:89 | parameterValue | | UnsafeReflection.java:77:33:77:70 | getParameter(...) : String | UnsafeReflection.java:83:76:83:89 | parameterValue | | UnsafeReflection.java:92:33:92:70 | getParameter(...) : String | UnsafeReflection.java:98:76:98:89 | parameterValue | | UnsafeReflection.java:104:34:104:57 | beanIdOrClassName : String | UnsafeReflection.java:119:21:119:26 | method | | UnsafeReflection.java:104:34:104:57 | beanIdOrClassName : String | UnsafeReflection.java:119:35:119:38 | bean | -| UnsafeReflection.java:104:102:104:118 | data : Object | UnsafeReflection.java:119:41:119:44 | data | +| UnsafeReflection.java:104:102:104:118 | data : List | UnsafeReflection.java:119:41:119:44 | data | nodes | UnsafeReflection.java:21:28:21:60 | getParameter(...) : String | semmle.label | getParameter(...) : String | | UnsafeReflection.java:22:33:22:70 | getParameter(...) : String | semmle.label | getParameter(...) : String | @@ -29,11 +29,11 @@ nodes | UnsafeReflection.java:39:58:39:71 | parameterValue | semmle.label | parameterValue | | UnsafeReflection.java:46:24:46:82 | beanIdOrClassName : String | semmle.label | beanIdOrClassName : String | | UnsafeReflection.java:46:132:46:168 | body : Map | semmle.label | body : Map | -| UnsafeReflection.java:49:23:49:59 | (...)... : Object | semmle.label | (...)... : Object | +| UnsafeReflection.java:49:23:49:59 | (...)... : List | semmle.label | (...)... : List | | UnsafeReflection.java:49:37:49:40 | body : Map | semmle.label | body : Map | | UnsafeReflection.java:49:37:49:59 | get(...) : Object | semmle.label | get(...) : Object | | UnsafeReflection.java:53:30:53:46 | beanIdOrClassName : String | semmle.label | beanIdOrClassName : String | -| UnsafeReflection.java:53:67:53:73 | rawData : Object | semmle.label | rawData : Object | +| UnsafeReflection.java:53:67:53:73 | rawData : List | semmle.label | rawData : List | | UnsafeReflection.java:62:33:62:70 | getParameter(...) : String | semmle.label | getParameter(...) : String | | UnsafeReflection.java:68:76:68:89 | parameterValue | semmle.label | parameterValue | | UnsafeReflection.java:77:33:77:70 | getParameter(...) : String | semmle.label | getParameter(...) : String | @@ -41,7 +41,7 @@ nodes | UnsafeReflection.java:92:33:92:70 | getParameter(...) : String | semmle.label | getParameter(...) : String | | UnsafeReflection.java:98:76:98:89 | parameterValue | semmle.label | parameterValue | | UnsafeReflection.java:104:34:104:57 | beanIdOrClassName : String | semmle.label | beanIdOrClassName : String | -| UnsafeReflection.java:104:102:104:118 | data : Object | semmle.label | data : Object | +| UnsafeReflection.java:104:102:104:118 | data : List | semmle.label | data : List | | UnsafeReflection.java:119:21:119:26 | method | semmle.label | method | | UnsafeReflection.java:119:35:119:38 | bean | semmle.label | bean | | UnsafeReflection.java:119:41:119:44 | data | semmle.label | data | diff --git a/java/ql/test/experimental/query-tests/security/CWE-552/UnsafeUrlForward.expected b/java/ql/test/experimental/query-tests/security/CWE-552/UnsafeUrlForward.expected index a39906b4115..57874f96e18 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-552/UnsafeUrlForward.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-552/UnsafeUrlForward.expected @@ -6,11 +6,11 @@ edges | UnsafeLoadSpringResource.java:108:32:108:77 | fileName : String | UnsafeLoadSpringResource.java:116:51:116:58 | fileName | | UnsafeRequestPath.java:20:17:20:63 | getServletPath(...) : String | UnsafeRequestPath.java:23:33:23:36 | path | | UnsafeResourceGet2.java:16:32:16:79 | getRequestParameterMap(...) : Map | UnsafeResourceGet2.java:17:20:17:25 | params : Map | -| UnsafeResourceGet2.java:17:20:17:25 | params : Map | UnsafeResourceGet2.java:17:20:17:40 | get(...) : Object | -| UnsafeResourceGet2.java:17:20:17:40 | get(...) : Object | UnsafeResourceGet2.java:19:93:19:99 | loadUrl | +| UnsafeResourceGet2.java:17:20:17:25 | params : Map | UnsafeResourceGet2.java:17:20:17:40 | get(...) : String | +| UnsafeResourceGet2.java:17:20:17:40 | get(...) : String | UnsafeResourceGet2.java:19:93:19:99 | loadUrl | | UnsafeResourceGet2.java:32:32:32:79 | getRequestParameterMap(...) : Map | UnsafeResourceGet2.java:33:20:33:25 | params : Map | -| UnsafeResourceGet2.java:33:20:33:25 | params : Map | UnsafeResourceGet2.java:33:20:33:40 | get(...) : Object | -| UnsafeResourceGet2.java:33:20:33:40 | get(...) : Object | UnsafeResourceGet2.java:37:20:37:22 | url | +| UnsafeResourceGet2.java:33:20:33:25 | params : Map | UnsafeResourceGet2.java:33:20:33:40 | get(...) : String | +| UnsafeResourceGet2.java:33:20:33:40 | get(...) : String | UnsafeResourceGet2.java:37:20:37:22 | url | | UnsafeResourceGet.java:32:23:32:56 | getParameter(...) : String | UnsafeResourceGet.java:41:20:41:22 | url | | UnsafeResourceGet.java:111:24:111:58 | getParameter(...) : String | UnsafeResourceGet.java:115:68:115:78 | requestPath | | UnsafeResourceGet.java:143:23:143:56 | getParameter(...) : String | UnsafeResourceGet.java:150:20:150:22 | url | @@ -42,11 +42,11 @@ nodes | UnsafeRequestPath.java:23:33:23:36 | path | semmle.label | path | | UnsafeResourceGet2.java:16:32:16:79 | getRequestParameterMap(...) : Map | semmle.label | getRequestParameterMap(...) : Map | | UnsafeResourceGet2.java:17:20:17:25 | params : Map | semmle.label | params : Map | -| UnsafeResourceGet2.java:17:20:17:40 | get(...) : Object | semmle.label | get(...) : Object | +| UnsafeResourceGet2.java:17:20:17:40 | get(...) : String | semmle.label | get(...) : String | | UnsafeResourceGet2.java:19:93:19:99 | loadUrl | semmle.label | loadUrl | | UnsafeResourceGet2.java:32:32:32:79 | getRequestParameterMap(...) : Map | semmle.label | getRequestParameterMap(...) : Map | | UnsafeResourceGet2.java:33:20:33:25 | params : Map | semmle.label | params : Map | -| UnsafeResourceGet2.java:33:20:33:40 | get(...) : Object | semmle.label | get(...) : Object | +| UnsafeResourceGet2.java:33:20:33:40 | get(...) : String | semmle.label | get(...) : String | | UnsafeResourceGet2.java:37:20:37:22 | url | semmle.label | url | | UnsafeResourceGet.java:32:23:32:56 | getParameter(...) : String | semmle.label | getParameter(...) : String | | UnsafeResourceGet.java:41:20:41:22 | url | semmle.label | url | diff --git a/java/ql/test/experimental/query-tests/security/CWE-598/SensitiveGetQuery.expected b/java/ql/test/experimental/query-tests/security/CWE-598/SensitiveGetQuery.expected index 0c641999e27..28471144374 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-598/SensitiveGetQuery.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-598/SensitiveGetQuery.expected @@ -1,11 +1,11 @@ edges | SensitiveGetQuery2.java:12:13:12:37 | getParameterMap(...) : Map | SensitiveGetQuery2.java:14:30:14:32 | map : Map | -| SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | SensitiveGetQuery2.java:15:29:15:36 | password | -| SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | SensitiveGetQuery2.java:15:29:15:36 | password : Object | +| SensitiveGetQuery2.java:14:21:14:48 | (...)... : String | SensitiveGetQuery2.java:15:29:15:36 | password | +| SensitiveGetQuery2.java:14:21:14:48 | (...)... : String | SensitiveGetQuery2.java:15:29:15:36 | password : String | | SensitiveGetQuery2.java:14:30:14:32 | map : Map | SensitiveGetQuery2.java:14:30:14:48 | get(...) : Object | -| SensitiveGetQuery2.java:14:30:14:48 | get(...) : Object | SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | -| SensitiveGetQuery2.java:15:29:15:36 | password : Object | SensitiveGetQuery2.java:18:40:18:54 | password : Object | -| SensitiveGetQuery2.java:18:40:18:54 | password : Object | SensitiveGetQuery2.java:19:61:19:68 | password | +| SensitiveGetQuery2.java:14:30:14:48 | get(...) : Object | SensitiveGetQuery2.java:14:21:14:48 | (...)... : String | +| SensitiveGetQuery2.java:15:29:15:36 | password : String | SensitiveGetQuery2.java:18:40:18:54 | password : String | +| SensitiveGetQuery2.java:18:40:18:54 | password : String | SensitiveGetQuery2.java:19:61:19:68 | password | | SensitiveGetQuery3.java:12:21:12:60 | getRequestParameter(...) : String | SensitiveGetQuery3.java:13:57:13:64 | password | | SensitiveGetQuery3.java:17:10:17:40 | getParameter(...) : String | SensitiveGetQuery3.java:12:21:12:60 | getRequestParameter(...) : String | | SensitiveGetQuery4.java:14:24:14:66 | getRequestParameter(...) : String | SensitiveGetQuery4.java:16:37:16:47 | accessToken | @@ -16,12 +16,12 @@ edges | SensitiveGetQuery.java:17:40:17:54 | password : String | SensitiveGetQuery.java:18:61:18:68 | password | nodes | SensitiveGetQuery2.java:12:13:12:37 | getParameterMap(...) : Map | semmle.label | getParameterMap(...) : Map | -| SensitiveGetQuery2.java:14:21:14:48 | (...)... : Object | semmle.label | (...)... : Object | +| SensitiveGetQuery2.java:14:21:14:48 | (...)... : String | semmle.label | (...)... : String | | SensitiveGetQuery2.java:14:30:14:32 | map : Map | semmle.label | map : Map | | SensitiveGetQuery2.java:14:30:14:48 | get(...) : Object | semmle.label | get(...) : Object | | SensitiveGetQuery2.java:15:29:15:36 | password | semmle.label | password | -| SensitiveGetQuery2.java:15:29:15:36 | password : Object | semmle.label | password : Object | -| SensitiveGetQuery2.java:18:40:18:54 | password : Object | semmle.label | password : Object | +| SensitiveGetQuery2.java:15:29:15:36 | password : String | semmle.label | password : String | +| SensitiveGetQuery2.java:18:40:18:54 | password : String | semmle.label | password : String | | SensitiveGetQuery2.java:19:61:19:68 | password | semmle.label | password | | SensitiveGetQuery3.java:12:21:12:60 | getRequestParameter(...) : String | semmle.label | getRequestParameter(...) : String | | SensitiveGetQuery3.java:13:57:13:64 | password | semmle.label | password | diff --git a/java/ql/test/experimental/query-tests/security/CWE-755/NFEAndroidDoS.expected b/java/ql/test/experimental/query-tests/security/CWE-755/NFEAndroidDoS.expected index 73657a38158..5f0e5b028f9 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-755/NFEAndroidDoS.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-755/NFEAndroidDoS.expected @@ -1,25 +1,25 @@ edges -| NFEAndroidDoS.java:13:24:13:34 | getIntent(...) : Intent | NFEAndroidDoS.java:13:24:13:61 | getStringExtra(...) : Object | -| NFEAndroidDoS.java:13:24:13:61 | getStringExtra(...) : Object | NFEAndroidDoS.java:14:21:14:51 | parseDouble(...) | -| NFEAndroidDoS.java:22:21:22:31 | getIntent(...) : Intent | NFEAndroidDoS.java:22:21:22:55 | getStringExtra(...) : Object | -| NFEAndroidDoS.java:22:21:22:55 | getStringExtra(...) : Object | NFEAndroidDoS.java:23:15:23:40 | parseInt(...) | -| NFEAndroidDoS.java:25:22:25:32 | getIntent(...) : Intent | NFEAndroidDoS.java:25:22:25:57 | getStringExtra(...) : Object | -| NFEAndroidDoS.java:25:22:25:57 | getStringExtra(...) : Object | NFEAndroidDoS.java:26:16:26:42 | parseInt(...) | -| NFEAndroidDoS.java:43:24:43:34 | getIntent(...) : Intent | NFEAndroidDoS.java:43:24:43:61 | getStringExtra(...) : Object | -| NFEAndroidDoS.java:43:24:43:61 | getStringExtra(...) : Object | NFEAndroidDoS.java:44:21:44:43 | new Double(...) | -| NFEAndroidDoS.java:43:24:43:61 | getStringExtra(...) : Object | NFEAndroidDoS.java:47:21:47:47 | valueOf(...) | +| NFEAndroidDoS.java:13:24:13:34 | getIntent(...) : Intent | NFEAndroidDoS.java:13:24:13:61 | getStringExtra(...) : String | +| NFEAndroidDoS.java:13:24:13:61 | getStringExtra(...) : String | NFEAndroidDoS.java:14:21:14:51 | parseDouble(...) | +| NFEAndroidDoS.java:22:21:22:31 | getIntent(...) : Intent | NFEAndroidDoS.java:22:21:22:55 | getStringExtra(...) : String | +| NFEAndroidDoS.java:22:21:22:55 | getStringExtra(...) : String | NFEAndroidDoS.java:23:15:23:40 | parseInt(...) | +| NFEAndroidDoS.java:25:22:25:32 | getIntent(...) : Intent | NFEAndroidDoS.java:25:22:25:57 | getStringExtra(...) : String | +| NFEAndroidDoS.java:25:22:25:57 | getStringExtra(...) : String | NFEAndroidDoS.java:26:16:26:42 | parseInt(...) | +| NFEAndroidDoS.java:43:24:43:34 | getIntent(...) : Intent | NFEAndroidDoS.java:43:24:43:61 | getStringExtra(...) : String | +| NFEAndroidDoS.java:43:24:43:61 | getStringExtra(...) : String | NFEAndroidDoS.java:44:21:44:43 | new Double(...) | +| NFEAndroidDoS.java:43:24:43:61 | getStringExtra(...) : String | NFEAndroidDoS.java:47:21:47:47 | valueOf(...) | nodes | NFEAndroidDoS.java:13:24:13:34 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent | -| NFEAndroidDoS.java:13:24:13:61 | getStringExtra(...) : Object | semmle.label | getStringExtra(...) : Object | +| NFEAndroidDoS.java:13:24:13:61 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | | NFEAndroidDoS.java:14:21:14:51 | parseDouble(...) | semmle.label | parseDouble(...) | | NFEAndroidDoS.java:22:21:22:31 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent | -| NFEAndroidDoS.java:22:21:22:55 | getStringExtra(...) : Object | semmle.label | getStringExtra(...) : Object | +| NFEAndroidDoS.java:22:21:22:55 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | | NFEAndroidDoS.java:23:15:23:40 | parseInt(...) | semmle.label | parseInt(...) | | NFEAndroidDoS.java:25:22:25:32 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent | -| NFEAndroidDoS.java:25:22:25:57 | getStringExtra(...) : Object | semmle.label | getStringExtra(...) : Object | +| NFEAndroidDoS.java:25:22:25:57 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | | NFEAndroidDoS.java:26:16:26:42 | parseInt(...) | semmle.label | parseInt(...) | | NFEAndroidDoS.java:43:24:43:34 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent | -| NFEAndroidDoS.java:43:24:43:61 | getStringExtra(...) : Object | semmle.label | getStringExtra(...) : Object | +| NFEAndroidDoS.java:43:24:43:61 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | | NFEAndroidDoS.java:44:21:44:43 | new Double(...) | semmle.label | new Double(...) | | NFEAndroidDoS.java:47:21:47:47 | valueOf(...) | semmle.label | valueOf(...) | subpaths diff --git a/java/ql/test/ext/TestModels/Test.java b/java/ql/test/ext/TestModels/Test.java index 83efd12e967..6bbc7a07879 100644 --- a/java/ql/test/ext/TestModels/Test.java +++ b/java/ql/test/ext/TestModels/Test.java @@ -82,7 +82,7 @@ public class Test { Connection con = DriverManager.getConnection(""); PreparedStatement ps1 = con.prepareStatement("UPDATE EMPLOYEES SET NAME = ? WHERE ID = ?"); ps1.setString(1, (String)source()); - sink(ps1); // $hasValueFlow + sink(ps1); // safe // java.util.concurrent.atomic AtomicReference ar = new AtomicReference(source()); diff --git a/java/ql/test/query-tests/security/CWE-078/ExecTaintedLocal.expected b/java/ql/test/query-tests/security/CWE-078/ExecTaintedLocal.expected index 2ae893b5d1d..05dd12f9a5b 100644 --- a/java/ql/test/query-tests/security/CWE-078/ExecTaintedLocal.expected +++ b/java/ql/test/query-tests/security/CWE-078/ExecTaintedLocal.expected @@ -5,8 +5,8 @@ edges | Test.java:6:35:6:44 | arg : String | Test.java:22:15:22:27 | ... + ... : String | | Test.java:10:29:10:74 | {...} : String[] [[]] : String | Test.java:10:29:10:74 | new String[] | | Test.java:10:61:10:73 | ... + ... : String | Test.java:10:29:10:74 | {...} : String[] [[]] : String | -| Test.java:16:5:16:7 | cmd [post update] : List [<element>] : String | Test.java:18:29:18:31 | cmd | -| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : List [<element>] : String | +| Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | Test.java:18:29:18:31 | cmd | +| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | | Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | Test.java:24:29:24:32 | cmd1 | | Test.java:22:15:22:27 | ... + ... : String | Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | | Test.java:28:38:28:47 | arg : String | Test.java:29:44:29:64 | ... + ... | @@ -20,7 +20,7 @@ nodes | Test.java:10:29:10:74 | new String[] | semmle.label | new String[] | | Test.java:10:29:10:74 | {...} : String[] [[]] : String | semmle.label | {...} : String[] [[]] : String | | Test.java:10:61:10:73 | ... + ... : String | semmle.label | ... + ... : String | -| Test.java:16:5:16:7 | cmd [post update] : List [<element>] : String | semmle.label | cmd [post update] : List [<element>] : String | +| Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | semmle.label | cmd [post update] : ArrayList [<element>] : String | | Test.java:16:13:16:25 | ... + ... : String | semmle.label | ... + ... : String | | Test.java:18:29:18:31 | cmd | semmle.label | cmd | | Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | semmle.label | cmd1 [post update] : String[] [[]] : String | From 441ccef6c44e897997f243c89b31f1ca74b596b7 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 11 May 2023 10:24:22 +0200 Subject: [PATCH 454/739] Dataflow: Bugfix, use arg type rather than strengthened param type. --- java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 8520f308f55..869866584ec 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -2677,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and + Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and Stage5::revFlow(p, state, _) ) } From 8a584b78ac28ede24b7867fe96516c91c6082acf Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 11 May 2023 10:25:12 +0200 Subject: [PATCH 455/739] Dataflow: Enable type strengthening in partial flow. --- .../java/dataflow/internal/DataFlowImpl.qll | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 869866584ec..d83adf3d39e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -4008,7 +4008,7 @@ module Impl<FullStateConfigSig Config> { ap = TPartialNil() and exists(explorationLimit()) or - partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and distSrc(node.getEnclosingCallable()) <= explorationLimit() } or TPartialPathNodeRev( @@ -4034,11 +4034,20 @@ module Impl<FullStateConfigSig Config> { } pragma[nomagic] - private predicate partialPathNodeMk0( - NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + private predicate partialPathStep( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { - partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) + } + + pragma[nomagic] + private predicate partialPathStep1( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, + PartialAccessPath ap + ) { + partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and not fullBarrier(node) and not stateBarrier(node, state) and not clearsContentEx(node, ap.getHead()) and @@ -4046,9 +4055,19 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if node.asNode() instanceof CastingNode - then compatibleTypes(node.getDataFlowType(), t) - else any() + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + + pragma[nomagic] + private predicate partialPathTypeStrengthen( + DataFlowType t0, PartialAccessPath ap, DataFlowType t + ) { + partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } /** @@ -4227,7 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } - private predicate partialPathStep( + private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { @@ -4353,6 +4372,11 @@ module Impl<FullStateConfigSig Config> { DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) + or + exists(DataFlowType t0 | + partialPathTypeStrengthen(t0, ap2, t2) and + apConsFwd(t1, ap1, c, t0, ap2) + ) } pragma[nomagic] From 53f2b8aab0bbf4124eded8755171e0e29761738d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 11 May 2023 10:28:02 +0200 Subject: [PATCH 456/739] Dataflow: Sync. --- .../cpp/dataflow/internal/DataFlowImpl.qll | 44 ++++++++++++++----- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 44 ++++++++++++++----- .../csharp/dataflow/internal/DataFlowImpl.qll | 44 ++++++++++++++----- .../go/dataflow/internal/DataFlowImpl.qll | 44 ++++++++++++++----- .../dataflow/new/internal/DataFlowImpl.qll | 44 ++++++++++++++----- .../ruby/dataflow/internal/DataFlowImpl.qll | 44 ++++++++++++++----- .../swift/dataflow/internal/DataFlowImpl.qll | 44 ++++++++++++++----- 7 files changed, 238 insertions(+), 70 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 8520f308f55..d83adf3d39e 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -2677,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and + Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -4008,7 +4008,7 @@ module Impl<FullStateConfigSig Config> { ap = TPartialNil() and exists(explorationLimit()) or - partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and distSrc(node.getEnclosingCallable()) <= explorationLimit() } or TPartialPathNodeRev( @@ -4034,11 +4034,20 @@ module Impl<FullStateConfigSig Config> { } pragma[nomagic] - private predicate partialPathNodeMk0( - NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + private predicate partialPathStep( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { - partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) + } + + pragma[nomagic] + private predicate partialPathStep1( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, + PartialAccessPath ap + ) { + partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and not fullBarrier(node) and not stateBarrier(node, state) and not clearsContentEx(node, ap.getHead()) and @@ -4046,9 +4055,19 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if node.asNode() instanceof CastingNode - then compatibleTypes(node.getDataFlowType(), t) - else any() + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + + pragma[nomagic] + private predicate partialPathTypeStrengthen( + DataFlowType t0, PartialAccessPath ap, DataFlowType t + ) { + partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } /** @@ -4227,7 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } - private predicate partialPathStep( + private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { @@ -4353,6 +4372,11 @@ module Impl<FullStateConfigSig Config> { DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) + or + exists(DataFlowType t0 | + partialPathTypeStrengthen(t0, ap2, t2) and + apConsFwd(t1, ap1, c, t0, ap2) + ) } pragma[nomagic] diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 8520f308f55..d83adf3d39e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -2677,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and + Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -4008,7 +4008,7 @@ module Impl<FullStateConfigSig Config> { ap = TPartialNil() and exists(explorationLimit()) or - partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and distSrc(node.getEnclosingCallable()) <= explorationLimit() } or TPartialPathNodeRev( @@ -4034,11 +4034,20 @@ module Impl<FullStateConfigSig Config> { } pragma[nomagic] - private predicate partialPathNodeMk0( - NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + private predicate partialPathStep( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { - partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) + } + + pragma[nomagic] + private predicate partialPathStep1( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, + PartialAccessPath ap + ) { + partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and not fullBarrier(node) and not stateBarrier(node, state) and not clearsContentEx(node, ap.getHead()) and @@ -4046,9 +4055,19 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if node.asNode() instanceof CastingNode - then compatibleTypes(node.getDataFlowType(), t) - else any() + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + + pragma[nomagic] + private predicate partialPathTypeStrengthen( + DataFlowType t0, PartialAccessPath ap, DataFlowType t + ) { + partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } /** @@ -4227,7 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } - private predicate partialPathStep( + private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { @@ -4353,6 +4372,11 @@ module Impl<FullStateConfigSig Config> { DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) + or + exists(DataFlowType t0 | + partialPathTypeStrengthen(t0, ap2, t2) and + apConsFwd(t1, ap1, c, t0, ap2) + ) } pragma[nomagic] diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 8520f308f55..d83adf3d39e 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -2677,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and + Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -4008,7 +4008,7 @@ module Impl<FullStateConfigSig Config> { ap = TPartialNil() and exists(explorationLimit()) or - partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and distSrc(node.getEnclosingCallable()) <= explorationLimit() } or TPartialPathNodeRev( @@ -4034,11 +4034,20 @@ module Impl<FullStateConfigSig Config> { } pragma[nomagic] - private predicate partialPathNodeMk0( - NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + private predicate partialPathStep( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { - partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) + } + + pragma[nomagic] + private predicate partialPathStep1( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, + PartialAccessPath ap + ) { + partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and not fullBarrier(node) and not stateBarrier(node, state) and not clearsContentEx(node, ap.getHead()) and @@ -4046,9 +4055,19 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if node.asNode() instanceof CastingNode - then compatibleTypes(node.getDataFlowType(), t) - else any() + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + + pragma[nomagic] + private predicate partialPathTypeStrengthen( + DataFlowType t0, PartialAccessPath ap, DataFlowType t + ) { + partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } /** @@ -4227,7 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } - private predicate partialPathStep( + private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { @@ -4353,6 +4372,11 @@ module Impl<FullStateConfigSig Config> { DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) + or + exists(DataFlowType t0 | + partialPathTypeStrengthen(t0, ap2, t2) and + apConsFwd(t1, ap1, c, t0, ap2) + ) } pragma[nomagic] diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 8520f308f55..d83adf3d39e 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -2677,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and + Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -4008,7 +4008,7 @@ module Impl<FullStateConfigSig Config> { ap = TPartialNil() and exists(explorationLimit()) or - partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and distSrc(node.getEnclosingCallable()) <= explorationLimit() } or TPartialPathNodeRev( @@ -4034,11 +4034,20 @@ module Impl<FullStateConfigSig Config> { } pragma[nomagic] - private predicate partialPathNodeMk0( - NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + private predicate partialPathStep( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { - partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) + } + + pragma[nomagic] + private predicate partialPathStep1( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, + PartialAccessPath ap + ) { + partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and not fullBarrier(node) and not stateBarrier(node, state) and not clearsContentEx(node, ap.getHead()) and @@ -4046,9 +4055,19 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if node.asNode() instanceof CastingNode - then compatibleTypes(node.getDataFlowType(), t) - else any() + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + + pragma[nomagic] + private predicate partialPathTypeStrengthen( + DataFlowType t0, PartialAccessPath ap, DataFlowType t + ) { + partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } /** @@ -4227,7 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } - private predicate partialPathStep( + private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { @@ -4353,6 +4372,11 @@ module Impl<FullStateConfigSig Config> { DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) + or + exists(DataFlowType t0 | + partialPathTypeStrengthen(t0, ap2, t2) and + apConsFwd(t1, ap1, c, t0, ap2) + ) } pragma[nomagic] diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 8520f308f55..d83adf3d39e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -2677,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and + Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -4008,7 +4008,7 @@ module Impl<FullStateConfigSig Config> { ap = TPartialNil() and exists(explorationLimit()) or - partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and distSrc(node.getEnclosingCallable()) <= explorationLimit() } or TPartialPathNodeRev( @@ -4034,11 +4034,20 @@ module Impl<FullStateConfigSig Config> { } pragma[nomagic] - private predicate partialPathNodeMk0( - NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + private predicate partialPathStep( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { - partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) + } + + pragma[nomagic] + private predicate partialPathStep1( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, + PartialAccessPath ap + ) { + partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and not fullBarrier(node) and not stateBarrier(node, state) and not clearsContentEx(node, ap.getHead()) and @@ -4046,9 +4055,19 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if node.asNode() instanceof CastingNode - then compatibleTypes(node.getDataFlowType(), t) - else any() + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + + pragma[nomagic] + private predicate partialPathTypeStrengthen( + DataFlowType t0, PartialAccessPath ap, DataFlowType t + ) { + partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } /** @@ -4227,7 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } - private predicate partialPathStep( + private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { @@ -4353,6 +4372,11 @@ module Impl<FullStateConfigSig Config> { DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) + or + exists(DataFlowType t0 | + partialPathTypeStrengthen(t0, ap2, t2) and + apConsFwd(t1, ap1, c, t0, ap2) + ) } pragma[nomagic] diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 8520f308f55..d83adf3d39e 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -2677,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and + Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -4008,7 +4008,7 @@ module Impl<FullStateConfigSig Config> { ap = TPartialNil() and exists(explorationLimit()) or - partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and distSrc(node.getEnclosingCallable()) <= explorationLimit() } or TPartialPathNodeRev( @@ -4034,11 +4034,20 @@ module Impl<FullStateConfigSig Config> { } pragma[nomagic] - private predicate partialPathNodeMk0( - NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + private predicate partialPathStep( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { - partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) + } + + pragma[nomagic] + private predicate partialPathStep1( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, + PartialAccessPath ap + ) { + partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and not fullBarrier(node) and not stateBarrier(node, state) and not clearsContentEx(node, ap.getHead()) and @@ -4046,9 +4055,19 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if node.asNode() instanceof CastingNode - then compatibleTypes(node.getDataFlowType(), t) - else any() + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + + pragma[nomagic] + private predicate partialPathTypeStrengthen( + DataFlowType t0, PartialAccessPath ap, DataFlowType t + ) { + partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } /** @@ -4227,7 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } - private predicate partialPathStep( + private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { @@ -4353,6 +4372,11 @@ module Impl<FullStateConfigSig Config> { DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) + or + exists(DataFlowType t0 | + partialPathTypeStrengthen(t0, ap2, t2) and + apConsFwd(t1, ap1, c, t0, ap2) + ) } pragma[nomagic] diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 8520f308f55..d83adf3d39e 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -2677,7 +2677,7 @@ module Impl<FullStateConfigSig Config> { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { exists(AccessPathApprox apa | ap.getApprox() = apa | Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, _, _, t, apa, _) and + Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and Stage5::revFlow(p, state, _) ) } @@ -4008,7 +4008,7 @@ module Impl<FullStateConfigSig Config> { ap = TPartialNil() and exists(explorationLimit()) or - partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and distSrc(node.getEnclosingCallable()) <= explorationLimit() } or TPartialPathNodeRev( @@ -4034,11 +4034,20 @@ module Impl<FullStateConfigSig Config> { } pragma[nomagic] - private predicate partialPathNodeMk0( - NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + private predicate partialPathStep( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { - partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and + partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) + } + + pragma[nomagic] + private predicate partialPathStep1( + PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, + PartialAccessPath ap + ) { + partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and not fullBarrier(node) and not stateBarrier(node, state) and not clearsContentEx(node, ap.getHead()) and @@ -4046,9 +4055,19 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if node.asNode() instanceof CastingNode - then compatibleTypes(node.getDataFlowType(), t) - else any() + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + + pragma[nomagic] + private predicate partialPathTypeStrengthen( + DataFlowType t0, PartialAccessPath ap, DataFlowType t + ) { + partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } /** @@ -4227,7 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } - private predicate partialPathStep( + private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap ) { @@ -4353,6 +4372,11 @@ module Impl<FullStateConfigSig Config> { DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) + or + exists(DataFlowType t0 | + partialPathTypeStrengthen(t0, ap2, t2) and + apConsFwd(t1, ap1, c, t0, ap2) + ) } pragma[nomagic] From 4399138c829bf9b55f161ffe0874351174e21ca9 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 11 May 2023 10:42:15 +0200 Subject: [PATCH 457/739] Dataflow: Fix QL4QL alert. --- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 1 + cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 1 + .../ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 1 + go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 1 + java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 1 + .../ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll | 1 + ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll | 1 + swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll | 1 + 8 files changed, 8 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index d83adf3d39e..ffb42d453d0 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -4246,6 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } + pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index d83adf3d39e..ffb42d453d0 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -4246,6 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } + pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index d83adf3d39e..ffb42d453d0 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -4246,6 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } + pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index d83adf3d39e..ffb42d453d0 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -4246,6 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } + pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index d83adf3d39e..ffb42d453d0 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -4246,6 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } + pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index d83adf3d39e..ffb42d453d0 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -4246,6 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } + pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index d83adf3d39e..ffb42d453d0 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -4246,6 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } + pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index d83adf3d39e..ffb42d453d0 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -4246,6 +4246,7 @@ module Impl<FullStateConfigSig Config> { } } + pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap From 95afd551ff743183ffcab867a2b9afebcb78e1dd Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 11 May 2023 13:36:41 +0200 Subject: [PATCH 458/739] Java: Fix qltest --- .../library-tests/frameworks/apache-collections/Test.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/ql/test/library-tests/frameworks/apache-collections/Test.java b/java/ql/test/library-tests/frameworks/apache-collections/Test.java index 188849457ac..09906405d75 100644 --- a/java/ql/test/library-tests/frameworks/apache-collections/Test.java +++ b/java/ql/test/library-tests/frameworks/apache-collections/Test.java @@ -721,14 +721,14 @@ public class Test { { // "org.apache.commons.collections4;MapUtils;true;getMap;;;MapValue of Argument[0];ReturnValue;value;manual" Map out = null; - Map in = newTreeMapWithMapValue((String)source()); + Map in = newTreeMapWithMapValue((Map)source()); out = MapUtils.getMap(in, null, null); sink(out); // $ hasValueFlow } { // "org.apache.commons.collections4;MapUtils;true;getMap;;;MapValue of Argument[0];ReturnValue;value;manual" Map out = null; - Map in = newTreeMapWithMapValue((String)source()); + Map in = newTreeMapWithMapValue((Map)source()); out = MapUtils.getMap(in, null); sink(out); // $ hasValueFlow } @@ -7257,4 +7257,4 @@ public class Test { } } -} \ No newline at end of file +} From d230509905a1867555bef82ce30e051722235676 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Mon, 15 May 2023 13:09:35 +0200 Subject: [PATCH 459/739] Dataflow: Address review comments. --- .../cpp/dataflow/internal/DataFlowImpl.qll | 45 +++++++------------ .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 45 +++++++------------ .../csharp/dataflow/internal/DataFlowImpl.qll | 45 +++++++------------ .../go/dataflow/internal/DataFlowImpl.qll | 45 +++++++------------ .../java/dataflow/internal/DataFlowImpl.qll | 45 +++++++------------ .../dataflow/new/internal/DataFlowImpl.qll | 45 +++++++------------ .../ruby/dataflow/internal/DataFlowImpl.qll | 45 +++++++------------ .../swift/dataflow/internal/DataFlowImpl.qll | 45 +++++++------------ 8 files changed, 120 insertions(+), 240 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index ffb42d453d0..984c5ae2018 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -1211,6 +1211,7 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t0, ap, t) } + pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } @@ -2255,6 +2256,16 @@ module Impl<FullStateConfigSig Config> { import MkStage<Stage2>::Stage<Stage3Param> } + bindingset[node, t0] + private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + private module Stage4Param implements MkStage<Stage3>::StageParam { private module PrevStage = Stage3; @@ -2351,14 +2362,7 @@ module Impl<FullStateConfigSig Config> { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and ( notExpectsContent(node) or @@ -2632,14 +2636,7 @@ module Impl<FullStateConfigSig Config> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and exists(state) and exists(ap) } @@ -3373,14 +3370,7 @@ module Impl<FullStateConfigSig Config> { exists(DataFlowType t0 | pathStep0(mid, node, state, cc, sc, t0, ap) and Stage5::revFlow(node, state, ap.getApprox()) and - ( - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) + strengthenType(node, t0, t) ) } @@ -4055,12 +4045,7 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 + strengthenType(node, t0, t) } pragma[nomagic] diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index ffb42d453d0..984c5ae2018 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -1211,6 +1211,7 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t0, ap, t) } + pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } @@ -2255,6 +2256,16 @@ module Impl<FullStateConfigSig Config> { import MkStage<Stage2>::Stage<Stage3Param> } + bindingset[node, t0] + private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + private module Stage4Param implements MkStage<Stage3>::StageParam { private module PrevStage = Stage3; @@ -2351,14 +2362,7 @@ module Impl<FullStateConfigSig Config> { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and ( notExpectsContent(node) or @@ -2632,14 +2636,7 @@ module Impl<FullStateConfigSig Config> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and exists(state) and exists(ap) } @@ -3373,14 +3370,7 @@ module Impl<FullStateConfigSig Config> { exists(DataFlowType t0 | pathStep0(mid, node, state, cc, sc, t0, ap) and Stage5::revFlow(node, state, ap.getApprox()) and - ( - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) + strengthenType(node, t0, t) ) } @@ -4055,12 +4045,7 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 + strengthenType(node, t0, t) } pragma[nomagic] diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index ffb42d453d0..984c5ae2018 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -1211,6 +1211,7 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t0, ap, t) } + pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } @@ -2255,6 +2256,16 @@ module Impl<FullStateConfigSig Config> { import MkStage<Stage2>::Stage<Stage3Param> } + bindingset[node, t0] + private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + private module Stage4Param implements MkStage<Stage3>::StageParam { private module PrevStage = Stage3; @@ -2351,14 +2362,7 @@ module Impl<FullStateConfigSig Config> { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and ( notExpectsContent(node) or @@ -2632,14 +2636,7 @@ module Impl<FullStateConfigSig Config> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and exists(state) and exists(ap) } @@ -3373,14 +3370,7 @@ module Impl<FullStateConfigSig Config> { exists(DataFlowType t0 | pathStep0(mid, node, state, cc, sc, t0, ap) and Stage5::revFlow(node, state, ap.getApprox()) and - ( - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) + strengthenType(node, t0, t) ) } @@ -4055,12 +4045,7 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 + strengthenType(node, t0, t) } pragma[nomagic] diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index ffb42d453d0..984c5ae2018 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -1211,6 +1211,7 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t0, ap, t) } + pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } @@ -2255,6 +2256,16 @@ module Impl<FullStateConfigSig Config> { import MkStage<Stage2>::Stage<Stage3Param> } + bindingset[node, t0] + private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + private module Stage4Param implements MkStage<Stage3>::StageParam { private module PrevStage = Stage3; @@ -2351,14 +2362,7 @@ module Impl<FullStateConfigSig Config> { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and ( notExpectsContent(node) or @@ -2632,14 +2636,7 @@ module Impl<FullStateConfigSig Config> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and exists(state) and exists(ap) } @@ -3373,14 +3370,7 @@ module Impl<FullStateConfigSig Config> { exists(DataFlowType t0 | pathStep0(mid, node, state, cc, sc, t0, ap) and Stage5::revFlow(node, state, ap.getApprox()) and - ( - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) + strengthenType(node, t0, t) ) } @@ -4055,12 +4045,7 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 + strengthenType(node, t0, t) } pragma[nomagic] diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index ffb42d453d0..984c5ae2018 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -1211,6 +1211,7 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t0, ap, t) } + pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } @@ -2255,6 +2256,16 @@ module Impl<FullStateConfigSig Config> { import MkStage<Stage2>::Stage<Stage3Param> } + bindingset[node, t0] + private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + private module Stage4Param implements MkStage<Stage3>::StageParam { private module PrevStage = Stage3; @@ -2351,14 +2362,7 @@ module Impl<FullStateConfigSig Config> { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and ( notExpectsContent(node) or @@ -2632,14 +2636,7 @@ module Impl<FullStateConfigSig Config> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and exists(state) and exists(ap) } @@ -3373,14 +3370,7 @@ module Impl<FullStateConfigSig Config> { exists(DataFlowType t0 | pathStep0(mid, node, state, cc, sc, t0, ap) and Stage5::revFlow(node, state, ap.getApprox()) and - ( - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) + strengthenType(node, t0, t) ) } @@ -4055,12 +4045,7 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 + strengthenType(node, t0, t) } pragma[nomagic] diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index ffb42d453d0..984c5ae2018 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -1211,6 +1211,7 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t0, ap, t) } + pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } @@ -2255,6 +2256,16 @@ module Impl<FullStateConfigSig Config> { import MkStage<Stage2>::Stage<Stage3Param> } + bindingset[node, t0] + private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + private module Stage4Param implements MkStage<Stage3>::StageParam { private module PrevStage = Stage3; @@ -2351,14 +2362,7 @@ module Impl<FullStateConfigSig Config> { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and ( notExpectsContent(node) or @@ -2632,14 +2636,7 @@ module Impl<FullStateConfigSig Config> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and exists(state) and exists(ap) } @@ -3373,14 +3370,7 @@ module Impl<FullStateConfigSig Config> { exists(DataFlowType t0 | pathStep0(mid, node, state, cc, sc, t0, ap) and Stage5::revFlow(node, state, ap.getApprox()) and - ( - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) + strengthenType(node, t0, t) ) } @@ -4055,12 +4045,7 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 + strengthenType(node, t0, t) } pragma[nomagic] diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index ffb42d453d0..984c5ae2018 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -1211,6 +1211,7 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t0, ap, t) } + pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } @@ -2255,6 +2256,16 @@ module Impl<FullStateConfigSig Config> { import MkStage<Stage2>::Stage<Stage3Param> } + bindingset[node, t0] + private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + private module Stage4Param implements MkStage<Stage3>::StageParam { private module PrevStage = Stage3; @@ -2351,14 +2362,7 @@ module Impl<FullStateConfigSig Config> { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and ( notExpectsContent(node) or @@ -2632,14 +2636,7 @@ module Impl<FullStateConfigSig Config> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and exists(state) and exists(ap) } @@ -3373,14 +3370,7 @@ module Impl<FullStateConfigSig Config> { exists(DataFlowType t0 | pathStep0(mid, node, state, cc, sc, t0, ap) and Stage5::revFlow(node, state, ap.getApprox()) and - ( - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) + strengthenType(node, t0, t) ) } @@ -4055,12 +4045,7 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 + strengthenType(node, t0, t) } pragma[nomagic] diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index ffb42d453d0..984c5ae2018 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -1211,6 +1211,7 @@ module Impl<FullStateConfigSig Config> { filter(node, state, t0, ap, t) } + pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } @@ -2255,6 +2256,16 @@ module Impl<FullStateConfigSig Config> { import MkStage<Stage2>::Stage<Stage3Param> } + bindingset[node, t0] + private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + if castingNodeEx(node) + then + exists(DataFlowType nt | nt = node.getDataFlowType() | + if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) + ) + else t = t0 + } + private module Stage4Param implements MkStage<Stage3>::StageParam { private module PrevStage = Stage3; @@ -2351,14 +2362,7 @@ module Impl<FullStateConfigSig Config> { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { exists(state) and not clear(node, ap) and - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and ( notExpectsContent(node) or @@ -2632,14 +2636,7 @@ module Impl<FullStateConfigSig Config> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { - ( - if castingNodeEx(node) - then - exists(Typ nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) and + strengthenType(node, t0, t) and exists(state) and exists(ap) } @@ -3373,14 +3370,7 @@ module Impl<FullStateConfigSig Config> { exists(DataFlowType t0 | pathStep0(mid, node, state, cc, sc, t0, ap) and Stage5::revFlow(node, state, ap.getApprox()) and - ( - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 - ) + strengthenType(node, t0, t) ) } @@ -4055,12 +4045,7 @@ module Impl<FullStateConfigSig Config> { notExpectsContent(node) or expectsContentEx(node, ap.getHead()) ) and - if castingNodeEx(node) - then - exists(DataFlowType nt | nt = node.getDataFlowType() | - if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0) - ) - else t = t0 + strengthenType(node, t0, t) } pragma[nomagic] From 85d6b44d9288169a3886641f6d82d3fe381a9b77 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Wed, 7 Jun 2023 11:30:33 +0200 Subject: [PATCH 460/739] Java: Fix test output. --- .../TopJdkApisTest/TopJdkApisTest.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected index b362ef171f5..4fee1c07e06 100644 --- a/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected +++ b/java/ql/test/query-tests/Metrics/GeneratedVsManualCoverage/TopJdkApisTest/TopJdkApisTest.expected @@ -8,7 +8,7 @@ | java.nio | 0 | 0 | 2 | 3 | 5 | 0.4 | 0.0 | 0.4 | 0.0 | NaN | 0.6 | | java.nio.charset | 0 | 0 | 0 | 1 | 1 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | | java.nio.file | 0 | 0 | 7 | 1 | 8 | 0.875 | 0.0 | 0.875 | 0.0 | NaN | 0.125 | -| java.sql | 0 | 0 | 2 | 14 | 16 | 0.125 | 0.0 | 0.125 | 0.0 | NaN | 0.875 | +| java.sql | 0 | 0 | 1 | 15 | 16 | 0.0625 | 0.0 | 0.0625 | 0.0 | NaN | 0.9375 | | java.text | 0 | 0 | 0 | 5 | 5 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | | java.time | 0 | 0 | 0 | 17 | 17 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | | java.time.chrono | 0 | 0 | 0 | 1 | 1 | 0.0 | 0.0 | 0.0 | NaN | NaN | 1.0 | From 68f1e40370bbebd4001b8e6f6771bb2295746bad Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 8 Jun 2023 14:35:28 +0200 Subject: [PATCH 461/739] Java/C#: Add change notes. --- csharp/ql/lib/change-notes/2023-06-08-type-strengthening.md | 4 ++++ java/ql/lib/change-notes/2023-06-08-type-strengthening.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2023-06-08-type-strengthening.md create mode 100644 java/ql/lib/change-notes/2023-06-08-type-strengthening.md diff --git a/csharp/ql/lib/change-notes/2023-06-08-type-strengthening.md b/csharp/ql/lib/change-notes/2023-06-08-type-strengthening.md new file mode 100644 index 00000000000..60daaa53058 --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-06-08-type-strengthening.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* The data flow library now performs type strengthening. This increases precision for all data flow queries by excluding paths that can be inferred to be impossible due to incompatible types. diff --git a/java/ql/lib/change-notes/2023-06-08-type-strengthening.md b/java/ql/lib/change-notes/2023-06-08-type-strengthening.md new file mode 100644 index 00000000000..60daaa53058 --- /dev/null +++ b/java/ql/lib/change-notes/2023-06-08-type-strengthening.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* The data flow library now performs type strengthening. This increases precision for all data flow queries by excluding paths that can be inferred to be impossible due to incompatible types. From 7620c051d3f3f801676d082fb5fe6b98bc057cba Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 9 Jun 2023 09:15:45 +0200 Subject: [PATCH 462/739] C#: Remove the savechanges origin name from the synthetic name (this is not needed). --- .../csharp/frameworks/EntityFramework.qll | 33 +- .../EntityFramework/FlowSummaries.expected | 406 ++++++++---------- 2 files changed, 179 insertions(+), 260 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 4a6fd664099..4a636afbfbd 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -335,18 +335,6 @@ module EntityFramework { result.getName().matches("SaveChanges%") } - /** - * Gets the string representation for synthetic identifiers for SaveChanges methods - * on this. - */ - private string getSyntheticNames() { - exists(string qualifier, string type, string name | - this.getASaveChanges().hasQualifiedName(qualifier, type, name) - | - result = getQualifiedName(qualifier, type, name) - ) - } - /** Holds if component stack `head :: tail` is required for the input specification. */ predicate requiresComponentStackIn( Content head, Type headType, SummaryComponentStack tail, int dist @@ -388,8 +376,7 @@ module EntityFramework { this = p.getDbContextClass() and input(this, synthetic, mapped) and output(this, output, mapped, p) and - result = - getFullSyntheticName(this.getSyntheticNames(), p.getSyntheticName(), synthetic, output) + result = getFullSyntheticName(p.getSyntheticName(), synthetic, output) ) } } @@ -446,13 +433,12 @@ module EntityFramework { ) } - bindingset[save, prop, stack1, stack2] + bindingset[prop, stack1, stack2] private string getFullSyntheticName( - string save, string prop, SummaryComponentStack stack1, SummaryComponentStack stack2 + string prop, SummaryComponentStack stack1, SummaryComponentStack stack2 ) { result = - save + "#" // - + prop + "#" // + prop + "#" // + SummaryComponentStack::getComponentStack(stack1) + "#" // + SummaryComponentStack::getComponentStack(stack2) } @@ -478,21 +464,12 @@ module EntityFramework { DbContextSaveChanges() { this = c.getASaveChanges() } - private string getSyntheticName() { - exists(string qualifier, string type, string name | - this.(Method).hasQualifiedName(qualifier, type, name) - | - result = getQualifiedName(qualifier, type, name) - ) - } - pragma[nomagic] string getOutputSynthetic(SummaryComponentStack input) { exists(SummaryComponentStack synthetic, Property mapped, DbContextClassSetProperty dbSet | input(c, input, mapped) and output(c, synthetic, mapped, dbSet) and - result = - getFullSyntheticName(this.getSyntheticName(), dbSet.getSyntheticName(), input, synthetic) + result = getFullSyntheticName(dbSet.getSyntheticName(), input, synthetic) ) } diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected index a07191d8fa0..a5a2f0ac120 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected @@ -1,236 +1,178 @@ summary -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChanges#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync#EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChanges#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[System.Data.Entity.DbContext.SaveChangesAsync#EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | neutral sourceNode sinkNode From 97c4f497bcd74a4ccea7b3e1724a5875427bc06e Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 1 Jun 2023 16:37:34 +0200 Subject: [PATCH 463/739] Go: Rewrite inline expectation tests to use parameterized module --- .../frameworks/CleverGo/HeaderWrite.expected | 2 ++ .../frameworks/CleverGo/HeaderWrite.ql | 12 +++++------- .../frameworks/CleverGo/HttpRedirect.expected | 2 ++ .../frameworks/CleverGo/HttpRedirect.ql | 10 +++++----- .../CleverGo/HttpResponseBody.expected | 2 ++ .../frameworks/CleverGo/HttpResponseBody.ql | 10 +++++----- .../frameworks/CleverGo/TaintTracking.expected | 2 ++ .../frameworks/CleverGo/TaintTracking.ql | 10 +++++----- .../CleverGo/UntrustedSources.expected | 2 ++ .../frameworks/CleverGo/UntrustedSources.ql | 10 +++++----- .../frameworks/Fiber/HeaderWrite.expected | 2 ++ .../frameworks/Fiber/HeaderWrite.ql | 12 +++++------- .../frameworks/Fiber/Redirect.expected | 2 ++ .../experimental/frameworks/Fiber/Redirect.ql | 10 +++++----- .../frameworks/Fiber/ResponseBody.expected | 2 ++ .../frameworks/Fiber/ResponseBody.ql | 10 +++++----- .../frameworks/Fiber/TaintTracking.expected | 2 ++ .../frameworks/Fiber/TaintTracking.ql | 10 +++++----- .../Fiber/UntrustedFlowSources.expected | 2 ++ .../frameworks/Fiber/UntrustedFlowSources.ql | 10 +++++----- .../semmle/go/Function/isVariadic.expected | 2 ++ .../semmle/go/Function/isVariadic.ql | 10 +++++----- .../go/Types/ImplementsComparable.expected | 2 ++ .../semmle/go/Types/ImplementsComparable.ql | 10 +++++----- .../go/Types/SignatureType_isVariadic.expected | 2 ++ .../go/Types/SignatureType_isVariadic.ql | 10 +++++----- .../semmle/go/concepts/HTTP/Handler.expected | 2 ++ .../semmle/go/concepts/HTTP/Handler.ql | 10 +++++----- .../go/concepts/LoggerCall/LoggerCall.expected | 2 ++ .../go/concepts/LoggerCall/LoggerCall.ql | 10 +++++----- .../go/dataflow/ArrayConversion/Flows.expected | 2 ++ .../go/dataflow/ArrayConversion/Flows.ql | 18 ++++++++---------- .../ExternalFlowVarArgs/Flows.expected | 1 + .../go/dataflow/ExternalFlowVarArgs/Flows.ql | 18 ++++++++---------- .../dataflow/GuardingFunctions/test.expected | 2 ++ .../go/dataflow/GuardingFunctions/test.ql | 10 +++++----- .../test.expected | 2 ++ .../ListOfConstantsSanitizerGuards/test.ql | 10 +++++----- .../PromotedFields/DataFlowConfig.expected | 2 ++ .../dataflow/PromotedFields/DataFlowConfig.ql | 10 +++++----- .../PromotedMethods/DataFlowConfig.expected | 2 ++ .../dataflow/PromotedMethods/DataFlowConfig.ql | 10 +++++----- .../dataflow/TypeAssertions/DataFlow.expected | 2 ++ .../go/dataflow/TypeAssertions/DataFlow.ql | 10 +++++----- .../semmle/go/dataflow/VarArgs/Flows.expected | 2 ++ .../semmle/go/dataflow/VarArgs/Flows.ql | 18 ++++++++---------- .../VarArgsWithFunctionModels/Flows.expected | 1 + .../VarArgsWithFunctionModels/Flows.ql | 18 ++++++++---------- .../go/frameworks/CouchbaseV1/test.expected | 2 ++ .../semmle/go/frameworks/CouchbaseV1/test.ql | 10 +++++----- .../EvanphxJsonPatch/TaintFlows.expected | 2 ++ .../frameworks/EvanphxJsonPatch/TaintFlows.ql | 10 +++++----- .../GoKit/untrustedflowsource.expected | 2 ++ .../go/frameworks/GoKit/untrustedflowsource.ql | 10 +++++----- .../K8sIoApiCoreV1/TaintFlowsInline.expected | 2 ++ .../K8sIoApiCoreV1/TaintFlowsInline.ql | 10 +++++----- .../TaintFlowsInline.expected | 2 ++ .../TaintFlowsInline.ql | 10 +++++----- .../SecretInterfaceSource.expected | 2 ++ .../K8sIoClientGo/SecretInterfaceSource.ql | 10 +++++----- .../semmle/go/frameworks/NoSQL/Query.expected | 2 ++ .../semmle/go/frameworks/NoSQL/Query.ql | 10 +++++----- .../semmle/go/frameworks/Revel/test.expected | 2 ++ .../semmle/go/frameworks/Revel/test.ql | 18 ++++++++---------- .../frameworks/StdlibTaintFlow/test.expected | 2 ++ .../go/frameworks/StdlibTaintFlow/test.ql | 10 +++++----- .../go/frameworks/Zap/TaintFlows.expected | 2 ++ .../semmle/go/frameworks/Zap/TaintFlows.ql | 10 +++++----- .../IncorrectIntegerConversion.expected | 2 ++ .../CWE-681/IncorrectIntegerConversion.ql | 10 +++++----- 70 files changed, 258 insertions(+), 204 deletions(-) diff --git a/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.expected b/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.ql b/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.ql index 20dc73705a8..6a1420db6d6 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.ql +++ b/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.ql @@ -2,14 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import experimental.frameworks.CleverGo -class HttpHeaderWriteTest extends InlineExpectationsTest { - HttpHeaderWriteTest() { this = "HttpHeaderWriteTest" } +module HttpHeaderWriteTest implements TestSig { + string getARelevantTag() { result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"] } - override string getARelevantTag() { - result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"] - } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { // Dynamic key-value header: exists(Http::HeaderWrite hw | hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -56,3 +52,5 @@ class HttpHeaderWriteTest extends InlineExpectationsTest { ) } } + +import MakeTest<HttpHeaderWriteTest> diff --git a/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.expected b/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.ql b/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.ql index 4b7bcb7823c..a0a8ce0a242 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.ql +++ b/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.ql @@ -2,12 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import experimental.frameworks.CleverGo -class HttpRedirectTest extends InlineExpectationsTest { - HttpRedirectTest() { this = "HttpRedirectTest" } +module HttpRedirectTest implements TestSig { + string getARelevantTag() { result = "redirectUrl" } - override string getARelevantTag() { result = "redirectUrl" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "redirectUrl" and exists(Http::Redirect rd | rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -17,3 +15,5 @@ class HttpRedirectTest extends InlineExpectationsTest { ) } } + +import MakeTest<HttpRedirectTest> diff --git a/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.expected b/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.ql b/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.ql index a2b3dc62167..b34f1ec23be 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.ql +++ b/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.ql @@ -2,12 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import experimental.frameworks.CleverGo -class HttpResponseBodyTest extends InlineExpectationsTest { - HttpResponseBodyTest() { this = "HttpResponseBodyTest" } +module HttpResponseBodyTest implements TestSig { + string getARelevantTag() { result = ["contentType", "responseBody"] } - override string getARelevantTag() { result = ["contentType", "responseBody"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Http::ResponseBody rd | rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and @@ -23,3 +21,5 @@ class HttpResponseBodyTest extends InlineExpectationsTest { ) } } + +import MakeTest<HttpResponseBodyTest> diff --git a/go/ql/test/experimental/frameworks/CleverGo/TaintTracking.expected b/go/ql/test/experimental/frameworks/CleverGo/TaintTracking.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/TaintTracking.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/TaintTracking.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/TaintTracking.ql b/go/ql/test/experimental/frameworks/CleverGo/TaintTracking.ql index 5de07cbe043..f5d74acdf56 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/TaintTracking.ql +++ b/go/ql/test/experimental/frameworks/CleverGo/TaintTracking.ql @@ -14,12 +14,10 @@ class Configuration extends TaintTracking::Configuration { } } -class TaintTrackingTest extends InlineExpectationsTest { - TaintTrackingTest() { this = "TaintTrackingTest" } +module TaintTrackingTest implements TestSig { + string getARelevantTag() { result = "taintSink" } - override string getARelevantTag() { result = "taintSink" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "taintSink" and exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) | element = sink.toString() and @@ -29,3 +27,5 @@ class TaintTrackingTest extends InlineExpectationsTest { ) } } + +import MakeTest<TaintTrackingTest> diff --git a/go/ql/test/experimental/frameworks/CleverGo/UntrustedSources.expected b/go/ql/test/experimental/frameworks/CleverGo/UntrustedSources.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/UntrustedSources.expected +++ b/go/ql/test/experimental/frameworks/CleverGo/UntrustedSources.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/CleverGo/UntrustedSources.ql b/go/ql/test/experimental/frameworks/CleverGo/UntrustedSources.ql index 4ace887e367..d414451dc21 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/UntrustedSources.ql +++ b/go/ql/test/experimental/frameworks/CleverGo/UntrustedSources.ql @@ -2,12 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import experimental.frameworks.CleverGo -class UntrustedFlowSourceTest extends InlineExpectationsTest { - UntrustedFlowSourceTest() { this = "UntrustedFlowSourceTest" } +module UntrustedFlowSourceTest implements TestSig { + string getARelevantTag() { result = "untrustedFlowSource" } - override string getARelevantTag() { result = "untrustedFlowSource" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "untrustedFlowSource" and exists(DataFlow::CallNode sinkCall, DataFlow::ArgumentNode arg | sinkCall.getCalleeName() = "sink" and @@ -21,3 +19,5 @@ class UntrustedFlowSourceTest extends InlineExpectationsTest { ) } } + +import MakeTest<UntrustedFlowSourceTest> diff --git a/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected b/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected +++ b/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.ql b/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.ql index 0130172e7d0..70494910554 100644 --- a/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.ql +++ b/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.ql @@ -2,14 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import experimental.frameworks.Fiber -class HttpHeaderWriteTest extends InlineExpectationsTest { - HttpHeaderWriteTest() { this = "HttpHeaderWriteTest" } +module HttpHeaderWriteTest implements TestSig { + string getARelevantTag() { result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"] } - override string getARelevantTag() { - result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"] - } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { // Dynamic key-value header: exists(Http::HeaderWrite hw | hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -56,3 +52,5 @@ class HttpHeaderWriteTest extends InlineExpectationsTest { ) } } + +import MakeTest<HttpHeaderWriteTest> diff --git a/go/ql/test/experimental/frameworks/Fiber/Redirect.expected b/go/ql/test/experimental/frameworks/Fiber/Redirect.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/Fiber/Redirect.expected +++ b/go/ql/test/experimental/frameworks/Fiber/Redirect.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/Redirect.ql b/go/ql/test/experimental/frameworks/Fiber/Redirect.ql index 37bb0f97bfb..1f609ea3959 100644 --- a/go/ql/test/experimental/frameworks/Fiber/Redirect.ql +++ b/go/ql/test/experimental/frameworks/Fiber/Redirect.ql @@ -2,12 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import experimental.frameworks.Fiber -class HttpRedirectTest extends InlineExpectationsTest { - HttpRedirectTest() { this = "HttpRedirectTest" } +module HttpRedirectTest implements TestSig { + string getARelevantTag() { result = "redirectUrl" } - override string getARelevantTag() { result = "redirectUrl" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "redirectUrl" and exists(Http::Redirect rd | rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -17,3 +15,5 @@ class HttpRedirectTest extends InlineExpectationsTest { ) } } + +import MakeTest<HttpRedirectTest> diff --git a/go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected b/go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected +++ b/go/ql/test/experimental/frameworks/Fiber/ResponseBody.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/ResponseBody.ql b/go/ql/test/experimental/frameworks/Fiber/ResponseBody.ql index 74a9008749d..574f514b343 100644 --- a/go/ql/test/experimental/frameworks/Fiber/ResponseBody.ql +++ b/go/ql/test/experimental/frameworks/Fiber/ResponseBody.ql @@ -2,12 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import experimental.frameworks.Fiber -class HttpResponseBodyTest extends InlineExpectationsTest { - HttpResponseBodyTest() { this = "HttpResponseBodyTest" } +module HttpResponseBodyTest implements TestSig { + string getARelevantTag() { result = ["contentType", "responseBody"] } - override string getARelevantTag() { result = ["contentType", "responseBody"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Http::ResponseBody rd | rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and @@ -23,3 +21,5 @@ class HttpResponseBodyTest extends InlineExpectationsTest { ) } } + +import MakeTest<HttpResponseBodyTest> diff --git a/go/ql/test/experimental/frameworks/Fiber/TaintTracking.expected b/go/ql/test/experimental/frameworks/Fiber/TaintTracking.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/Fiber/TaintTracking.expected +++ b/go/ql/test/experimental/frameworks/Fiber/TaintTracking.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/TaintTracking.ql b/go/ql/test/experimental/frameworks/Fiber/TaintTracking.ql index dba5c65328c..5e2082acd60 100644 --- a/go/ql/test/experimental/frameworks/Fiber/TaintTracking.ql +++ b/go/ql/test/experimental/frameworks/Fiber/TaintTracking.ql @@ -14,12 +14,10 @@ class Configuration extends TaintTracking::Configuration { } } -class TaintTrackingTest extends InlineExpectationsTest { - TaintTrackingTest() { this = "TaintTrackingTest" } +module TaintTrackingTest implements TestSig { + string getARelevantTag() { result = "taintSink" } - override string getARelevantTag() { result = "taintSink" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "taintSink" and exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) | element = sink.toString() and @@ -29,3 +27,5 @@ class TaintTrackingTest extends InlineExpectationsTest { ) } } + +import MakeTest<TaintTrackingTest> diff --git a/go/ql/test/experimental/frameworks/Fiber/UntrustedFlowSources.expected b/go/ql/test/experimental/frameworks/Fiber/UntrustedFlowSources.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/experimental/frameworks/Fiber/UntrustedFlowSources.expected +++ b/go/ql/test/experimental/frameworks/Fiber/UntrustedFlowSources.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/experimental/frameworks/Fiber/UntrustedFlowSources.ql b/go/ql/test/experimental/frameworks/Fiber/UntrustedFlowSources.ql index 3e7666b581a..4964c900207 100644 --- a/go/ql/test/experimental/frameworks/Fiber/UntrustedFlowSources.ql +++ b/go/ql/test/experimental/frameworks/Fiber/UntrustedFlowSources.ql @@ -2,12 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import experimental.frameworks.Fiber -class UntrustedFlowSourceTest extends InlineExpectationsTest { - UntrustedFlowSourceTest() { this = "UntrustedFlowSourceTest" } +module UntrustedFlowSourceTest implements TestSig { + string getARelevantTag() { result = "untrustedFlowSource" } - override string getARelevantTag() { result = "untrustedFlowSource" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "untrustedFlowSource" and exists(DataFlow::CallNode sinkCall, DataFlow::ArgumentNode arg | sinkCall.getCalleeName() = "sink" and @@ -21,3 +19,5 @@ class UntrustedFlowSourceTest extends InlineExpectationsTest { ) } } + +import MakeTest<UntrustedFlowSourceTest> diff --git a/go/ql/test/library-tests/semmle/go/Function/isVariadic.expected b/go/ql/test/library-tests/semmle/go/Function/isVariadic.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/Function/isVariadic.expected +++ b/go/ql/test/library-tests/semmle/go/Function/isVariadic.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/Function/isVariadic.ql b/go/ql/test/library-tests/semmle/go/Function/isVariadic.ql index b501b84eadd..9a75a5f0136 100644 --- a/go/ql/test/library-tests/semmle/go/Function/isVariadic.ql +++ b/go/ql/test/library-tests/semmle/go/Function/isVariadic.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class FunctionIsVariadicTest extends InlineExpectationsTest { - FunctionIsVariadicTest() { this = "Function::IsVariadicTest" } +module FunctionIsVariadicTest implements TestSig { + string getARelevantTag() { result = "isVariadic" } - override string getARelevantTag() { result = "isVariadic" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(CallExpr ce | ce.getTarget().isVariadic() and ce.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -17,3 +15,5 @@ class FunctionIsVariadicTest extends InlineExpectationsTest { ) } } + +import MakeTest<FunctionIsVariadicTest> diff --git a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected +++ b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.ql b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.ql index 789472ecd2f..048352a3ee0 100644 --- a/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.ql +++ b/go/ql/test/library-tests/semmle/go/Types/ImplementsComparable.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class ImplementsComparableTest extends InlineExpectationsTest { - ImplementsComparableTest() { this = "ImplementsComparableTest" } +module ImplementsComparableTest implements TestSig { + string getARelevantTag() { result = "implementsComparable" } - override string getARelevantTag() { result = "implementsComparable" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { // file = "interface.go" and tag = "implementsComparable" and exists(TypeSpec ts | @@ -20,3 +18,5 @@ class ImplementsComparableTest extends InlineExpectationsTest { ) } } + +import MakeTest<ImplementsComparableTest> diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.ql b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.ql index d2ae79ae7d9..e6b96ce608e 100644 --- a/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.ql +++ b/go/ql/test/library-tests/semmle/go/Types/SignatureType_isVariadic.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class SignatureTypeIsVariadicTest extends InlineExpectationsTest { - SignatureTypeIsVariadicTest() { this = "SignatureType::IsVariadicTest" } +module SignatureTypeIsVariadicTest implements TestSig { + string getARelevantTag() { result = "isVariadic" } - override string getARelevantTag() { result = "isVariadic" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(FuncDef fd | fd.isVariadic() and fd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -17,3 +15,5 @@ class SignatureTypeIsVariadicTest extends InlineExpectationsTest { ) } } + +import MakeTest<SignatureTypeIsVariadicTest> diff --git a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.expected b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.expected +++ b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.ql b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.ql index c6972eba275..6b982271404 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.ql +++ b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class HttpHandler extends InlineExpectationsTest { - HttpHandler() { this = "httphandler" } +module HttpHandler implements TestSig { + string getARelevantTag() { result = "handler" } - override string getARelevantTag() { result = "handler" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "handler" and exists(Http::RequestHandler h, DataFlow::Node check | element = h.toString() and value = check.toString() @@ -17,3 +15,5 @@ class HttpHandler extends InlineExpectationsTest { ) } } + +import MakeTest<HttpHandler> diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.expected b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.expected +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.ql b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.ql index ce1be9a05d7..ab4890f9746 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.ql +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/LoggerCall.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class LoggerTest extends InlineExpectationsTest { - LoggerTest() { this = "LoggerTest" } +module LoggerTest implements TestSig { + string getARelevantTag() { result = "logger" } - override string getARelevantTag() { result = "logger" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(LoggerCall log | log.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and @@ -16,3 +14,5 @@ class LoggerTest extends InlineExpectationsTest { ) } } + +import MakeTest<LoggerTest> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ArrayConversion/Flows.expected b/go/ql/test/library-tests/semmle/go/dataflow/ArrayConversion/Flows.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ArrayConversion/Flows.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ArrayConversion/Flows.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ArrayConversion/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/ArrayConversion/Flows.ql index e6e99b0e6c2..500572f5d45 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ArrayConversion/Flows.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ArrayConversion/Flows.ql @@ -13,12 +13,10 @@ class DataConfiguration extends DataFlow::Configuration { } } -class DataFlowTest extends InlineExpectationsTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements TestSig { + string getARelevantTag() { result = "dataflow" } - override string getARelevantTag() { result = "dataflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "dataflow" and exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | element = sink.toString() and @@ -41,12 +39,10 @@ class TaintConfiguration extends TaintTracking::Configuration { } } -class TaintFlowTest extends InlineExpectationsTest { - TaintFlowTest() { this = "TaintFlowTest" } +module TaintFlowTest implements TestSig { + string getARelevantTag() { result = "taintflow" } - override string getARelevantTag() { result = "taintflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "taintflow" and exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | element = sink.toString() and @@ -56,3 +52,5 @@ class TaintFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/Flows.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/Flows.expected index 81332464f79..105b7026d0c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/Flows.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/Flows.expected @@ -1,2 +1,3 @@ failures invalidModelRow +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/Flows.ql index 1be00de1f13..e30f7bc28e3 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/Flows.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/Flows.ql @@ -15,12 +15,10 @@ class DataConfiguration extends DataFlow::Configuration { } } -class DataFlowTest extends InlineExpectationsTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements TestSig { + string getARelevantTag() { result = "dataflow" } - override string getARelevantTag() { result = "dataflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "dataflow" and exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | element = sink.toString() and @@ -43,12 +41,10 @@ class TaintConfiguration extends TaintTracking::Configuration { } } -class TaintFlowTest extends InlineExpectationsTest { - TaintFlowTest() { this = "TaintFlowTest" } +module TaintFlowTest implements TestSig { + string getARelevantTag() { result = "taintflow" } - override string getARelevantTag() { result = "taintflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "taintflow" and exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | element = sink.toString() and @@ -58,3 +54,5 @@ class TaintFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/GuardingFunctions/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/GuardingFunctions/test.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/GuardingFunctions/test.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/GuardingFunctions/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/GuardingFunctions/test.ql b/go/ql/test/library-tests/semmle/go/dataflow/GuardingFunctions/test.ql index 2b11d284076..d5bc1496b3d 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/GuardingFunctions/test.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/GuardingFunctions/test.ql @@ -23,12 +23,10 @@ class TestConfig extends DataFlow::Configuration { } } -class DataFlowTest extends InlineExpectationsTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements TestSig { + string getARelevantTag() { result = "dataflow" } - override string getARelevantTag() { result = "dataflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "dataflow" and exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) | element = sink.toString() and @@ -38,3 +36,5 @@ class DataFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<DataFlowTest> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ListOfConstantsSanitizerGuards/test.expected b/go/ql/test/library-tests/semmle/go/dataflow/ListOfConstantsSanitizerGuards/test.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ListOfConstantsSanitizerGuards/test.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ListOfConstantsSanitizerGuards/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ListOfConstantsSanitizerGuards/test.ql b/go/ql/test/library-tests/semmle/go/dataflow/ListOfConstantsSanitizerGuards/test.ql index f75495313d4..aa9b9c3e074 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ListOfConstantsSanitizerGuards/test.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ListOfConstantsSanitizerGuards/test.ql @@ -13,12 +13,10 @@ class TestConfig extends TaintTracking::Configuration { } } -class DataFlowTest extends InlineExpectationsTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements TestSig { + string getARelevantTag() { result = "dataflow" } - override string getARelevantTag() { result = "dataflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "dataflow" and exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) | element = sink.toString() and @@ -28,3 +26,5 @@ class DataFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<DataFlowTest> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/DataFlowConfig.expected b/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/DataFlowConfig.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/DataFlowConfig.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/DataFlowConfig.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/DataFlowConfig.ql b/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/DataFlowConfig.ql index 90c0878ff8d..8222ae35d87 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/DataFlowConfig.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/PromotedFields/DataFlowConfig.ql @@ -21,12 +21,10 @@ class TestConfig extends DataFlow::Configuration { } } -class PromotedFieldsTest extends InlineExpectationsTest { - PromotedFieldsTest() { this = "PromotedFieldsTest" } +module PromotedFieldsTest implements TestSig { + string getARelevantTag() { result = "promotedfields" } - override string getARelevantTag() { result = "promotedfields" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(TestConfig config, DataFlow::PathNode sink | config.hasFlowPath(_, sink) and sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -37,3 +35,5 @@ class PromotedFieldsTest extends InlineExpectationsTest { ) } } + +import MakeTest<PromotedFieldsTest> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected b/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.ql b/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.ql index f99f7775a3b..fac89a50650 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/PromotedMethods/DataFlowConfig.ql @@ -21,12 +21,10 @@ class TestConfig extends DataFlow::Configuration { } } -class PromotedMethodsTest extends InlineExpectationsTest { - PromotedMethodsTest() { this = "PromotedMethodsTest" } +module PromotedMethodsTest implements TestSig { + string getARelevantTag() { result = "promotedmethods" } - override string getARelevantTag() { result = "promotedmethods" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(TestConfig config, DataFlow::Node source, DataFlow::Node sink | config.hasFlow(source, sink) | @@ -38,3 +36,5 @@ class PromotedMethodsTest extends InlineExpectationsTest { ) } } + +import MakeTest<PromotedMethodsTest> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/TypeAssertions/DataFlow.expected b/go/ql/test/library-tests/semmle/go/dataflow/TypeAssertions/DataFlow.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/TypeAssertions/DataFlow.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/TypeAssertions/DataFlow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/TypeAssertions/DataFlow.ql b/go/ql/test/library-tests/semmle/go/dataflow/TypeAssertions/DataFlow.ql index edabb61bf5d..9412fb13486 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/TypeAssertions/DataFlow.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/TypeAssertions/DataFlow.ql @@ -13,12 +13,10 @@ class Configuration extends DataFlow::Configuration { } } -class DataFlowTest extends InlineExpectationsTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements TestSig { + string getARelevantTag() { result = "dataflow" } - override string getARelevantTag() { result = "dataflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "dataflow" and exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) | element = sink.toString() and @@ -28,3 +26,5 @@ class DataFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<DataFlowTest> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.expected b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.ql index e6e99b0e6c2..500572f5d45 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.ql @@ -13,12 +13,10 @@ class DataConfiguration extends DataFlow::Configuration { } } -class DataFlowTest extends InlineExpectationsTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements TestSig { + string getARelevantTag() { result = "dataflow" } - override string getARelevantTag() { result = "dataflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "dataflow" and exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | element = sink.toString() and @@ -41,12 +39,10 @@ class TaintConfiguration extends TaintTracking::Configuration { } } -class TaintFlowTest extends InlineExpectationsTest { - TaintFlowTest() { this = "TaintFlowTest" } +module TaintFlowTest implements TestSig { + string getARelevantTag() { result = "taintflow" } - override string getARelevantTag() { result = "taintflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "taintflow" and exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | element = sink.toString() and @@ -56,3 +52,5 @@ class TaintFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.expected b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.expected index 81332464f79..105b7026d0c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.expected @@ -1,2 +1,3 @@ failures invalidModelRow +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql index 87e9b301148..d0a3946616a 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql @@ -43,12 +43,10 @@ class DataConfiguration extends DataFlow::Configuration { } } -class DataFlowTest extends InlineExpectationsTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements TestSig { + string getARelevantTag() { result = "dataflow" } - override string getARelevantTag() { result = "dataflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "dataflow" and exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | element = sink.toString() and @@ -71,12 +69,10 @@ class TaintConfiguration extends TaintTracking::Configuration { } } -class TaintFlowTest extends InlineExpectationsTest { - TaintFlowTest() { this = "TaintFlowTest" } +module TaintFlowTest implements TestSig { + string getARelevantTag() { result = "taintflow" } - override string getARelevantTag() { result = "taintflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "taintflow" and exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | element = sink.toString() and @@ -86,6 +82,8 @@ class TaintFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>> // from TaintConfiguration cfg, DataFlow::PartialPathNode source, DataFlow::PartialPathNode sink // where // cfg.hasPartialFlow(source, sink, _) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.expected b/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.ql b/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.ql index 535fb6dd627..0b1bef94328 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/CouchbaseV1/test.ql @@ -2,12 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import semmle.go.security.SqlInjection -class SqlInjectionTest extends InlineExpectationsTest { - SqlInjectionTest() { this = "SqlInjectionTest" } +module SqlInjectionTest implements TestSig { + string getARelevantTag() { result = "sqlinjection" } - override string getARelevantTag() { result = "sqlinjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "sqlinjection" and exists(DataFlow::Node sink | any(SqlInjection::Configuration c).hasFlow(_, sink) | element = sink.toString() and @@ -17,3 +15,5 @@ class SqlInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<SqlInjectionTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/TaintFlows.expected b/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/TaintFlows.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/TaintFlows.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/TaintFlows.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/TaintFlows.ql b/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/TaintFlows.ql index 0d411503e34..998afbf88b5 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/TaintFlows.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/EvanphxJsonPatch/TaintFlows.ql @@ -16,12 +16,10 @@ class Configuration extends TaintTracking::Configuration { } } -class TaintFlowTest extends InlineExpectationsTest { - TaintFlowTest() { this = "TaintFlowTest" } +module TaintFlowTest implements TestSig { + string getARelevantTag() { result = "taintflow" } - override string getARelevantTag() { result = "taintflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "taintflow" and exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) | element = sink.toString() and @@ -31,3 +29,5 @@ class TaintFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<TaintFlowTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/GoKit/untrustedflowsource.expected b/go/ql/test/library-tests/semmle/go/frameworks/GoKit/untrustedflowsource.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/GoKit/untrustedflowsource.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/GoKit/untrustedflowsource.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/GoKit/untrustedflowsource.ql b/go/ql/test/library-tests/semmle/go/frameworks/GoKit/untrustedflowsource.ql index 7cffdcb78ba..ff95de5b731 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/GoKit/untrustedflowsource.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/GoKit/untrustedflowsource.ql @@ -2,12 +2,10 @@ import go import semmle.go.frameworks.GoKit import TestUtilities.InlineExpectationsTest -class UntrustedFlowSourceTest extends InlineExpectationsTest { - UntrustedFlowSourceTest() { this = "untrustedflowsourcetest" } +module UntrustedFlowSourceTest implements TestSig { + string getARelevantTag() { result = "source" } - override string getARelevantTag() { result = "source" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(UntrustedFlowSource source | source .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -18,3 +16,5 @@ class UntrustedFlowSourceTest extends InlineExpectationsTest { ) } } + +import MakeTest<UntrustedFlowSourceTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApiCoreV1/TaintFlowsInline.expected b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApiCoreV1/TaintFlowsInline.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApiCoreV1/TaintFlowsInline.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApiCoreV1/TaintFlowsInline.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApiCoreV1/TaintFlowsInline.ql b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApiCoreV1/TaintFlowsInline.ql index 8a9292957b3..793308837c1 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApiCoreV1/TaintFlowsInline.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApiCoreV1/TaintFlowsInline.ql @@ -21,12 +21,10 @@ class TestConfig extends TaintTracking::Configuration { } } -class K8sIoApiCoreV1Test extends InlineExpectationsTest { - K8sIoApiCoreV1Test() { this = "K8sIoApiCoreV1Test" } +module K8sIoApiCoreV1Test implements TestSig { + string getARelevantTag() { result = "KsIoApiCoreV" } - override string getARelevantTag() { result = "KsIoApiCoreV" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(TestConfig config, DataFlow::PathNode sink | config.hasFlowPath(_, sink) and sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -37,3 +35,5 @@ class K8sIoApiCoreV1Test extends InlineExpectationsTest { ) } } + +import MakeTest<K8sIoApiCoreV1Test> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApimachineryPkgRuntime/TaintFlowsInline.expected b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApimachineryPkgRuntime/TaintFlowsInline.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApimachineryPkgRuntime/TaintFlowsInline.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApimachineryPkgRuntime/TaintFlowsInline.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApimachineryPkgRuntime/TaintFlowsInline.ql b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApimachineryPkgRuntime/TaintFlowsInline.ql index e9b2c13ccca..901dcb9eaf5 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApimachineryPkgRuntime/TaintFlowsInline.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoApimachineryPkgRuntime/TaintFlowsInline.ql @@ -21,12 +21,10 @@ class TestConfig extends TaintTracking::Configuration { } } -class K8sIoApimachineryPkgRuntimeTest extends InlineExpectationsTest { - K8sIoApimachineryPkgRuntimeTest() { this = "KsIoApimachineryPkgRuntimeTest" } +module K8sIoApimachineryPkgRuntimeTest implements TestSig { + string getARelevantTag() { result = "KsIoApimachineryPkgRuntime" } - override string getARelevantTag() { result = "KsIoApimachineryPkgRuntime" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(TestConfig config, DataFlow::PathNode sink | config.hasFlowPath(_, sink) and sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -37,3 +35,5 @@ class K8sIoApimachineryPkgRuntimeTest extends InlineExpectationsTest { ) } } + +import MakeTest<K8sIoApimachineryPkgRuntimeTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.ql b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.ql index 1650e263252..be38cebd11b 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/K8sIoClientGo/SecretInterfaceSource.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class K8sIoApimachineryPkgRuntimeTest extends InlineExpectationsTest { - K8sIoApimachineryPkgRuntimeTest() { this = "KsIoClientGoTest" } +module K8sIoApimachineryPkgRuntimeTest implements TestSig { + string getARelevantTag() { result = "KsIoClientGo" } - override string getARelevantTag() { result = "KsIoClientGo" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(K8sIoClientGo::SecretInterfaceSource source | source .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -17,3 +15,5 @@ class K8sIoApimachineryPkgRuntimeTest extends InlineExpectationsTest { ) } } + +import MakeTest<K8sIoApimachineryPkgRuntimeTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.expected b/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.ql b/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.ql index cfe40a0066e..3f14991d274 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/NoSQL/Query.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class NoSqlQueryTest extends InlineExpectationsTest { - NoSqlQueryTest() { this = "NoSQLQueryTest" } +module NoSqlQueryTest implements TestSig { + string getARelevantTag() { result = "nosqlquery" } - override string getARelevantTag() { result = "nosqlquery" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(NoSql::Query q | q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and @@ -16,3 +14,5 @@ class NoSqlQueryTest extends InlineExpectationsTest { ) } } + +import MakeTest<NoSqlQueryTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.ql b/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.ql index 9d2b876d803..bae5b14ccd4 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.ql @@ -15,12 +15,10 @@ class TestConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } } -class MissingDataFlowTest extends InlineExpectationsTest { - MissingDataFlowTest() { this = "MissingDataFlow" } +module MissingDataFlowTest implements TestSig { + string getARelevantTag() { result = "noflow" } - override string getARelevantTag() { result = "noflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "noflow" and value = "" and exists(Sink sink | @@ -32,12 +30,10 @@ class MissingDataFlowTest extends InlineExpectationsTest { } } -class HttpResponseBodyTest extends InlineExpectationsTest { - HttpResponseBodyTest() { this = "HttpResponseBodyTest" } +module HttpResponseBodyTest implements TestSig { + string getARelevantTag() { result = "responsebody" } - override string getARelevantTag() { result = "responsebody" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "responsebody" and exists(Http::ResponseBody rb | rb.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -47,3 +43,5 @@ class HttpResponseBodyTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<MissingDataFlowTest, HttpResponseBodyTest>> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.expected b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.ql b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.ql index 57796416265..f91654329a1 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/test.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class FileSystemAccessTest extends InlineExpectationsTest { - FileSystemAccessTest() { this = "FileSystemAccess" } +module FileSystemAccessTest implements TestSig { + string getARelevantTag() { result = "fsaccess" } - override string getARelevantTag() { result = "fsaccess" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(FileSystemAccess f | f.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and @@ -16,3 +14,5 @@ class FileSystemAccessTest extends InlineExpectationsTest { ) } } + +import MakeTest<FileSystemAccessTest> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Zap/TaintFlows.expected b/go/ql/test/library-tests/semmle/go/frameworks/Zap/TaintFlows.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Zap/TaintFlows.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Zap/TaintFlows.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Zap/TaintFlows.ql b/go/ql/test/library-tests/semmle/go/frameworks/Zap/TaintFlows.ql index a012615e48e..14650f8f20d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Zap/TaintFlows.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Zap/TaintFlows.ql @@ -13,12 +13,10 @@ class TestConfig extends TaintTracking::Configuration { } } -class ZapTest extends InlineExpectationsTest { - ZapTest() { this = "ZapTest" } +module ZapTest implements TestSig { + string getARelevantTag() { result = "zap" } - override string getARelevantTag() { result = "zap" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "zap" and exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) | element = sink.toString() and @@ -28,3 +26,5 @@ class ZapTest extends InlineExpectationsTest { ) } } + +import MakeTest<ZapTest> diff --git a/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.expected b/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.expected +++ b/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.ql b/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.ql index e4eb088abd8..3e7ccd8d8c1 100644 --- a/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.ql +++ b/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.ql @@ -2,12 +2,10 @@ import go import TestUtilities.InlineExpectationsTest import semmle.go.security.IncorrectIntegerConversionLib -class TestIncorrectIntegerConversion extends InlineExpectationsTest { - TestIncorrectIntegerConversion() { this = "TestIncorrectIntegerConversion" } +module TestIncorrectIntegerConversion implements TestSig { + string getARelevantTag() { result = "hasValueFlow" } - override string getARelevantTag() { result = "hasValueFlow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasValueFlow" and exists(DataFlow::Node sink, DataFlow::Node sinkConverted | any(ConversionWithoutBoundsCheckConfig config).hasFlowTo(sink) and @@ -21,3 +19,5 @@ class TestIncorrectIntegerConversion extends InlineExpectationsTest { ) } } + +import MakeTest<TestIncorrectIntegerConversion> From 49993b023e6ed1000b9d1cd6784af2f71778b3be Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 5 Jun 2023 16:54:08 +0200 Subject: [PATCH 464/739] Java: Rewrite inline expectation tests to use parameterized module --- .../default-parameter-mad-flow/test.expected | 2 ++ .../kotlin/default-parameter-mad-flow/test.ql | 10 +++++----- .../dataflow/callback-dispatch/test.expected | 2 ++ .../dataflow/callback-dispatch/test.ql | 10 +++++----- .../EntryPointTypesTest.expected | 2 ++ .../entrypoint-types/EntryPointTypesTest.ql | 10 +++++----- .../library-tests/dataflow/state/test.expected | 2 ++ .../test/library-tests/dataflow/state/test.ql | 10 +++++----- .../dataflow/taintsources/local.expected | 2 ++ .../dataflow/taintsources/local.ql | 10 +++++----- .../dataflow/taintsources/remote.expected | 2 ++ .../dataflow/taintsources/remote.ql | 10 +++++----- .../frameworks/JaxWs/JaxRs.expected | 2 ++ .../library-tests/frameworks/JaxWs/JaxRs.ql | 10 +++++----- .../frameworks/JaxWs/JaxWsEndpoint.expected | 2 ++ .../frameworks/JaxWs/JaxWsEndpoint.ql | 10 +++++----- .../android/taint-database/flowSteps.expected | 2 ++ .../android/taint-database/flowSteps.ql | 10 +++++----- .../android/taint-database/sinks.expected | 2 ++ .../frameworks/android/taint-database/sinks.ql | 10 +++++----- .../frameworks/guava/handwritten/flow.expected | 2 ++ .../frameworks/guava/handwritten/flow.ql | 10 +++++----- .../frameworks/jms/FlowTest.expected | 2 ++ .../library-tests/frameworks/jms/FlowTest.ql | 10 +++++----- .../frameworks/jms/RemoteSourcesTest.expected | 2 ++ .../frameworks/jms/RemoteSourcesTest.ql | 10 +++++----- .../frameworks/rabbitmq/SourceTest.expected | 2 ++ .../frameworks/rabbitmq/SourceTest.ql | 10 +++++----- .../neutralsinks/NeutralSinksTest.expected | 2 ++ .../neutrals/neutralsinks/NeutralSinksTest.ql | 18 ++++++++---------- .../ql/test/library-tests/xml/XMLTest.expected | 4 +++- java/ql/test/library-tests/xml/XMLTest.ql | 10 +++++----- ...PartialPathTraversalFromRemoteTest.expected | 2 ++ .../PartialPathTraversalFromRemoteTest.ql | 10 +++++----- .../CWE-074/JndiInjectionTest.expected | 2 ++ .../security/CWE-074/JndiInjectionTest.ql | 10 +++++----- .../CWE-074/XsltInjectionTest.expected | 2 ++ .../security/CWE-074/XsltInjectionTest.ql | 10 +++++----- .../security/CWE-079/semmle/tests/XSS.expected | 2 ++ .../security/CWE-079/semmle/tests/XSS.ql | 10 +++++----- .../semmle/examples/springjdbc.expected | 2 ++ .../CWE-089/semmle/examples/springjdbc.ql | 10 +++++----- .../CWE-094/ApkInstallationTest.expected | 2 ++ .../security/CWE-094/ApkInstallationTest.ql | 10 +++++----- .../CWE-094/GroovyInjectionTest.expected | 2 ++ .../security/CWE-094/GroovyInjectionTest.ql | 10 +++++----- .../CWE-094/JexlInjectionTest.expected | 2 ++ .../security/CWE-094/JexlInjectionTest.ql | 10 +++++----- .../CWE-094/MvelInjectionTest.expected | 2 ++ .../security/CWE-094/MvelInjectionTest.ql | 10 +++++----- .../CWE-094/SpelInjectionTest.expected | 2 ++ .../security/CWE-094/SpelInjectionTest.ql | 10 +++++----- .../CWE-094/TemplateInjectionTest.expected | 2 ++ .../security/CWE-094/TemplateInjectionTest.ql | 10 +++++----- .../StaticInitializationVectorTest.expected | 2 ++ .../CWE-1204/StaticInitializationVectorTest.ql | 10 +++++----- .../CWE-273/UnsafeCertTrustTest.expected | 2 ++ .../security/CWE-273/UnsafeCertTrustTest.ql | 10 +++++----- .../Test1/test.expected | 2 ++ .../Test1/test.ql | 10 +++++----- .../Test2/test.expected | 2 ++ .../Test2/test.ql | 10 +++++----- .../Test3/test.expected | 2 ++ .../Test3/test.ql | 10 +++++----- .../Test4/test.expected | 2 ++ .../Test4/test.ql | 10 +++++----- .../Test5/test.expected | 2 ++ .../Test5/test.ql | 10 +++++----- .../test.expected | 2 ++ .../test.ql | 10 +++++----- .../InsecureTrustManagerTest.expected | 2 ++ .../InsecureTrustManagerTest.ql | 10 +++++----- .../CWE-297/InsecureJavaMailTest.expected | 2 ++ .../security/CWE-297/InsecureJavaMailTest.ql | 10 +++++----- ...leartextStorageAndroidDatabaseTest.expected | 2 ++ .../CleartextStorageAndroidDatabaseTest.ql | 10 +++++----- ...artextStorageAndroidFilesystemTest.expected | 2 ++ .../CleartextStorageAndroidFilesystemTest.ql | 10 +++++----- .../CleartextStorageSharedPrefsTest.expected | 2 ++ .../CleartextStorageSharedPrefsTest.ql | 10 +++++----- .../CWE-326/InsufficientKeySizeTest.expected | 2 ++ .../CWE-326/InsufficientKeySizeTest.ql | 10 +++++----- .../MissingJWTSignatureCheckTest.expected | 2 ++ .../CWE-347/MissingJWTSignatureCheckTest.ql | 10 +++++----- ...tInjectionInPreferenceActivityTest.expected | 2 ++ ...ragmentInjectionInPreferenceActivityTest.ql | 10 +++++----- .../DebuggableAttributeEnabledTest.expected | 2 ++ .../DebuggableAttributeEnabledTest.ql | 10 +++++----- .../CWE-502/UnsafeDeserialization.expected | 2 ++ .../security/CWE-502/UnsafeDeserialization.ql | 10 +++++----- .../CWE-522/InsecureBasicAuthTest.expected | 2 ++ .../security/CWE-522/InsecureBasicAuthTest.ql | 10 +++++----- .../CWE-522/InsecureLdapAuthTest.expected | 2 ++ .../security/CWE-522/InsecureLdapAuthTest.ql | 10 +++++----- .../CWE-524/SensitiveKeyboardCache.expected | 2 ++ .../security/CWE-524/SensitiveKeyboardCache.ql | 10 +++++----- .../CWE-643/XPathInjectionTest.expected | 2 ++ .../security/CWE-643/XPathInjectionTest.ql | 10 +++++----- .../security/CWE-730/PolynomialReDoS.expected | 2 ++ .../security/CWE-730/PolynomialReDoS.ql | 10 +++++----- .../security/CWE-730/ReDoS.expected | 2 ++ .../test/query-tests/security/CWE-730/ReDoS.ql | 10 +++++----- .../CWE-730/RegexInjectionTest.expected | 2 ++ .../security/CWE-730/RegexInjectionTest.ql | 10 +++++----- .../CWE-749/UnsafeAndroidAccessTest.expected | 2 ++ .../CWE-749/UnsafeAndroidAccessTest.ql | 10 +++++----- .../tests/HardcodedCredentialsApiCall.expected | 2 ++ .../tests/HardcodedCredentialsApiCall.ql | 10 +++++----- .../HardcodedCredentialsComparison.expected | 2 ++ .../tests/HardcodedCredentialsComparison.ql | 10 +++++----- .../HardcodedCredentialsSourceCall.expected | 2 ++ .../tests/HardcodedCredentialsSourceCall.ql | 10 +++++----- .../tests/HardcodedPasswordField.expected | 2 ++ .../semmle/tests/HardcodedPasswordField.ql | 10 +++++----- .../tests/ConditionalBypassTest.expected | 2 ++ .../semmle/tests/ConditionalBypassTest.ql | 10 +++++----- .../CWE-917/OgnlInjectionTest.expected | 2 ++ .../security/CWE-917/OgnlInjectionTest.ql | 10 +++++----- .../security/CWE-918/RequestForgery.expected | 2 ++ .../security/CWE-918/RequestForgery.ql | 10 +++++----- .../ImproperIntentVerification.expected | 2 ++ .../CWE-925/ImproperIntentVerification.ql | 10 +++++----- ...icitlyExportedAndroidComponentTest.expected | 2 ++ .../ImplicitlyExportedAndroidComponentTest.ql | 10 +++++----- ...tProviderIncompletePermissionsTest.expected | 2 ++ ...ContentProviderIncompletePermissionsTest.ql | 10 +++++----- .../ImplicitPendingIntentsTest.expected | 2 ++ .../CWE-927/ImplicitPendingIntentsTest.ql | 10 +++++----- .../CWE-927/SensitiveResultReceiver.expected | 2 ++ .../CWE-927/SensitiveResultReceiver.ql | 10 +++++----- .../AndroidIntentRedirectionTest.expected | 2 ++ .../CWE-940/AndroidIntentRedirectionTest.ql | 10 +++++----- 132 files changed, 466 insertions(+), 336 deletions(-) diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.expected b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql index 78afdd7bb66..65f44797116 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql @@ -19,12 +19,10 @@ module Config implements DataFlow::ConfigSig { module Flow = TaintTracking::Global<Config>; -class InlineFlowTest extends InlineExpectationsTest { - InlineFlowTest() { this = "HasFlowTest" } +module InlineFlowTest implements TestSig { + string getARelevantTag() { result = "flow" } - override string getARelevantTag() { result = "flow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "flow" and exists(DataFlow::Node sink | Flow::flowTo(sink) | sink.getLocation() = location and @@ -33,3 +31,5 @@ class InlineFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<InlineFlowTest> diff --git a/java/ql/test/library-tests/dataflow/callback-dispatch/test.expected b/java/ql/test/library-tests/dataflow/callback-dispatch/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/callback-dispatch/test.expected +++ b/java/ql/test/library-tests/dataflow/callback-dispatch/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql index 131d0a5706d..a4f8b4e822d 100644 --- a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql +++ b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ql @@ -12,12 +12,10 @@ module Config implements DataFlow::ConfigSig { module Flow = DataFlow::Global<Config>; -class HasFlowTest extends InlineExpectationsTest { - HasFlowTest() { this = "HasFlowTest" } +module HasFlowTest implements TestSig { + string getARelevantTag() { result = "flow" } - override string getARelevantTag() { result = "flow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "flow" and exists(DataFlow::Node src, DataFlow::Node sink | Flow::flow(src, sink) | sink.getLocation() = location and @@ -26,3 +24,5 @@ class HasFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasFlowTest> diff --git a/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.expected b/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.expected +++ b/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.ql b/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.ql index 5a0ca1865c1..29d355671ec 100644 --- a/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.ql +++ b/java/ql/test/library-tests/dataflow/entrypoint-types/EntryPointTypesTest.ql @@ -18,12 +18,10 @@ module TaintFlowConfig implements DataFlow::ConfigSig { module TaintFlow = TaintTracking::Global<TaintFlowConfig>; -class HasFlowTest extends InlineExpectationsTest { - HasFlowTest() { this = "HasFlowTest" } +module HasFlowTest implements TestSig { + string getARelevantTag() { result = "hasTaintFlow" } - override string getARelevantTag() { result = ["hasTaintFlow"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasTaintFlow" and exists(DataFlow::Node sink | TaintFlow::flowTo(sink) | sink.getLocation() = location and @@ -32,3 +30,5 @@ class HasFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasFlowTest> diff --git a/java/ql/test/library-tests/dataflow/state/test.expected b/java/ql/test/library-tests/dataflow/state/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/state/test.expected +++ b/java/ql/test/library-tests/dataflow/state/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/state/test.ql b/java/ql/test/library-tests/dataflow/state/test.ql index b82dd95c0b1..b6063962ef2 100644 --- a/java/ql/test/library-tests/dataflow/state/test.ql +++ b/java/ql/test/library-tests/dataflow/state/test.ql @@ -59,12 +59,10 @@ module Flow = TaintTracking::GlobalWithState<Config>; module PartialFlow = Flow::FlowExploration<explorationLimit/0>; -class HasFlowTest extends InlineExpectationsTest { - HasFlowTest() { this = "HasFlowTest" } +module HasFlowTest implements TestSig { + string getARelevantTag() { result = ["pFwd", "pRev", "flow"] } - override string getARelevantTag() { result = ["pFwd", "pRev", "flow"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "flow" and exists(Flow::PathNode src, Flow::PathNode sink | Flow::flowPath(src, sink) and @@ -92,3 +90,5 @@ class HasFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasFlowTest> diff --git a/java/ql/test/library-tests/dataflow/taintsources/local.expected b/java/ql/test/library-tests/dataflow/taintsources/local.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/local.expected +++ b/java/ql/test/library-tests/dataflow/taintsources/local.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/taintsources/local.ql b/java/ql/test/library-tests/dataflow/taintsources/local.ql index a174629ca6e..45697947173 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/local.ql +++ b/java/ql/test/library-tests/dataflow/taintsources/local.ql @@ -26,12 +26,10 @@ module LocalTaintConfig implements DataFlow::ConfigSig { module LocalTaintFlow = TaintTracking::Global<LocalTaintConfig>; -class LocalFlowTest extends InlineExpectationsTest { - LocalFlowTest() { this = "LocalFlowTest" } +module LocalFlowTest implements TestSig { + string getARelevantTag() { result = ["hasLocalValueFlow", "hasLocalTaintFlow"] } - override string getARelevantTag() { result = ["hasLocalValueFlow", "hasLocalTaintFlow"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasLocalValueFlow" and exists(DataFlow::Node sink | LocalValueFlow::flowTo(sink) | sink.getLocation() = location and @@ -49,3 +47,5 @@ class LocalFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<LocalFlowTest> diff --git a/java/ql/test/library-tests/dataflow/taintsources/remote.expected b/java/ql/test/library-tests/dataflow/taintsources/remote.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/remote.expected +++ b/java/ql/test/library-tests/dataflow/taintsources/remote.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/taintsources/remote.ql b/java/ql/test/library-tests/dataflow/taintsources/remote.ql index fa1f206ca74..7f58a68d438 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/remote.ql +++ b/java/ql/test/library-tests/dataflow/taintsources/remote.ql @@ -22,12 +22,10 @@ module RemoteTaintConfig implements DataFlow::ConfigSig { module RemoteTaintFlow = TaintTracking::Global<RemoteTaintConfig>; -class RemoteFlowTest extends InlineExpectationsTest { - RemoteFlowTest() { this = "RemoteFlowTest" } +module RemoteFlowTest implements TestSig { + string getARelevantTag() { result = ["hasRemoteValueFlow", "hasRemoteTaintFlow"] } - override string getARelevantTag() { result = ["hasRemoteValueFlow", "hasRemoteTaintFlow"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasRemoteValueFlow" and exists(DataFlow::Node sink | RemoteValueFlow::flowTo(sink) | sink.getLocation() = location and @@ -45,3 +43,5 @@ class RemoteFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<RemoteFlowTest> diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected b/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.ql b/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.ql index 70c0cef4917..a1d25dc275e 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.ql +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxRs.ql @@ -3,10 +3,8 @@ import semmle.code.java.frameworks.JaxWS import semmle.code.java.security.XSS import TestUtilities.InlineExpectationsTest -class JaxRsTest extends InlineExpectationsTest { - JaxRsTest() { this = "JaxRsTest" } - - override string getARelevantTag() { +module JaxRsTest implements TestSig { + string getARelevantTag() { result = [ "ResourceMethod", "RootResourceClass", "NonRootResourceClass", @@ -18,7 +16,7 @@ class JaxRsTest extends InlineExpectationsTest { ] } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "ResourceMethod" and exists(JaxRsResourceMethod resourceMethod | resourceMethod.getLocation() = location and @@ -168,3 +166,5 @@ class JaxRsTest extends InlineExpectationsTest { ) } } + +import MakeTest<JaxRsTest> diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected b/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.ql b/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.ql index 6ebd597bb0a..8ccc69dc8c2 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.ql +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.frameworks.JaxWS import TestUtilities.InlineExpectationsTest -class JaxWsEndpointTest extends InlineExpectationsTest { - JaxWsEndpointTest() { this = "JaxWsEndpointTest" } +module JaxWsEndpointTest implements TestSig { + string getARelevantTag() { result = ["JaxWsEndpoint", "JaxWsEndpointRemoteMethod"] } - override string getARelevantTag() { result = ["JaxWsEndpoint", "JaxWsEndpointRemoteMethod"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "JaxWsEndpoint" and exists(JaxWsEndpoint jaxWsEndpoint | jaxWsEndpoint.getLocation() = location and @@ -25,3 +23,5 @@ class JaxWsEndpointTest extends InlineExpectationsTest { ) } } + +import MakeTest<JaxWsEndpointTest> diff --git a/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.expected b/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.expected +++ b/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.ql b/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.ql index 5bbe2cab89c..64cb38486de 100644 --- a/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.ql +++ b/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.ql @@ -14,12 +14,10 @@ module Config implements DataFlow::ConfigSig { module Flow = TaintTracking::Global<Config>; -class FlowStepTest extends InlineExpectationsTest { - FlowStepTest() { this = "FlowStepTest" } +module FlowStepTest implements TestSig { + string getARelevantTag() { result = "taintReachesReturn" } - override string getARelevantTag() { result = "taintReachesReturn" } - - override predicate hasActualResult(Location l, string element, string tag, string value) { + predicate hasActualResult(Location l, string element, string tag, string value) { tag = "taintReachesReturn" and value = "" and exists(DataFlow::Node source | Flow::flow(source, _) | @@ -28,3 +26,5 @@ class FlowStepTest extends InlineExpectationsTest { ) } } + +import MakeTest<FlowStepTest> diff --git a/java/ql/test/library-tests/frameworks/android/taint-database/sinks.expected b/java/ql/test/library-tests/frameworks/android/taint-database/sinks.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/taint-database/sinks.expected +++ b/java/ql/test/library-tests/frameworks/android/taint-database/sinks.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/taint-database/sinks.ql b/java/ql/test/library-tests/frameworks/android/taint-database/sinks.ql index 234b7ca74b0..c0661820294 100644 --- a/java/ql/test/library-tests/frameworks/android/taint-database/sinks.ql +++ b/java/ql/test/library-tests/frameworks/android/taint-database/sinks.ql @@ -14,12 +14,10 @@ module Config implements DataFlow::ConfigSig { module Flow = TaintTracking::Global<Config>; -class SinkTest extends InlineExpectationsTest { - SinkTest() { this = "SinkTest" } +module SinkTest implements TestSig { + string getARelevantTag() { result = "taintReachesSink" } - override string getARelevantTag() { result = "taintReachesSink" } - - override predicate hasActualResult(Location l, string element, string tag, string value) { + predicate hasActualResult(Location l, string element, string tag, string value) { tag = "taintReachesSink" and value = "" and exists(DataFlow::Node source | Flow::flow(source, _) | @@ -28,3 +26,5 @@ class SinkTest extends InlineExpectationsTest { ) } } + +import MakeTest<SinkTest> diff --git a/java/ql/test/library-tests/frameworks/guava/handwritten/flow.expected b/java/ql/test/library-tests/frameworks/guava/handwritten/flow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/guava/handwritten/flow.expected +++ b/java/ql/test/library-tests/frameworks/guava/handwritten/flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/guava/handwritten/flow.ql b/java/ql/test/library-tests/frameworks/guava/handwritten/flow.ql index fbfc56486f8..300475bd6af 100644 --- a/java/ql/test/library-tests/frameworks/guava/handwritten/flow.ql +++ b/java/ql/test/library-tests/frameworks/guava/handwritten/flow.ql @@ -24,12 +24,10 @@ module ValueFlowConfig implements DataFlow::ConfigSig { module ValueFlow = DataFlow::Global<ValueFlowConfig>; -class HasFlowTest extends InlineExpectationsTest { - HasFlowTest() { this = "HasFlowTest" } +module HasFlowTest implements TestSig { + string getARelevantTag() { result = ["numTaintFlow", "numValueFlow"] } - override string getARelevantTag() { result = ["numTaintFlow", "numValueFlow"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "numTaintFlow" and exists(DataFlow::Node src, DataFlow::Node sink, int num | TaintFlow::flow(src, sink) | not ValueFlow::flow(src, sink) and @@ -48,3 +46,5 @@ class HasFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasFlowTest> diff --git a/java/ql/test/library-tests/frameworks/jms/FlowTest.expected b/java/ql/test/library-tests/frameworks/jms/FlowTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/jms/FlowTest.expected +++ b/java/ql/test/library-tests/frameworks/jms/FlowTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/jms/FlowTest.ql b/java/ql/test/library-tests/frameworks/jms/FlowTest.ql index 3644b87e6d3..ef42c248189 100644 --- a/java/ql/test/library-tests/frameworks/jms/FlowTest.ql +++ b/java/ql/test/library-tests/frameworks/jms/FlowTest.ql @@ -14,15 +14,15 @@ module TestConfig implements DataFlow::ConfigSig { module TestFlow = TaintTracking::Global<TestConfig>; -class JmsFlowTest extends InlineExpectationsTest { - JmsFlowTest() { this = "JmsFlowTest" } +module JmsFlowTest implements TestSig { + string getARelevantTag() { result = "tainted" } - override string getARelevantTag() { result = "tainted" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "tainted" and exists(TestFlow::PathNode sink | TestFlow::flowPath(_, sink) | location = sink.getNode().getLocation() and element = sink.getNode().toString() and value = "" ) } } + +import MakeTest<JmsFlowTest> diff --git a/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.expected b/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.expected +++ b/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.ql b/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.ql index 6d1d496075d..78b1dda532e 100644 --- a/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.ql +++ b/java/ql/test/library-tests/frameworks/jms/RemoteSourcesTest.ql @@ -2,15 +2,15 @@ import java import semmle.code.java.dataflow.FlowSources import TestUtilities.InlineExpectationsTest -class JmsRemoteSourcesTest extends InlineExpectationsTest { - JmsRemoteSourcesTest() { this = "JmsRemoteSourcesTest" } +module JmsRemoteSourcesTest implements TestSig { + string getARelevantTag() { result = "source" } - override string getARelevantTag() { result = "source" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "source" and exists(RemoteFlowSource source | location = source.getLocation() and element = source.toString() and value = "" ) } } + +import MakeTest<JmsRemoteSourcesTest> diff --git a/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.expected b/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.expected +++ b/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.ql b/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.ql index 7ce7b2a6ebf..bc46ba9518b 100644 --- a/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.ql +++ b/java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.dataflow.FlowSources import TestUtilities.InlineExpectationsTest -class SourceTest extends InlineExpectationsTest { - SourceTest() { this = "SourceTest" } +module SourceTest implements TestSig { + string getARelevantTag() { result = "source" } - override string getARelevantTag() { result = "source" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "source" and exists(RemoteFlowSource source | not source.asParameter().getCallable().getDeclaringType().hasName("DefaultConsumer") and @@ -17,3 +15,5 @@ class SourceTest extends InlineExpectationsTest { ) } } + +import MakeTest<SourceTest> diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected +++ b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql index 224b03ea51c..a345d6df1fc 100644 --- a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql +++ b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql @@ -4,12 +4,10 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -class SinkTest extends InlineExpectationsTest { - SinkTest() { this = "SinkTest" } +module SinkTest implements TestSig { + string getARelevantTag() { result = "isSink" } - override string getARelevantTag() { result = "isSink" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "isSink" and exists(DataFlow::Node sink | sinkNode(sink, _) and @@ -20,12 +18,10 @@ class SinkTest extends InlineExpectationsTest { } } -class NeutralSinkTest extends InlineExpectationsTest { - NeutralSinkTest() { this = "NeutralSinkTest" } +module NeutralSinkTest implements TestSig { + string getARelevantTag() { result = "isNeutralSink" } - override string getARelevantTag() { result = "isNeutralSink" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "isNeutralSink" and exists(Call call, Callable callable | call.getCallee() = callable and @@ -38,3 +34,5 @@ class NeutralSinkTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<SinkTest, NeutralSinkTest>> diff --git a/java/ql/test/library-tests/xml/XMLTest.expected b/java/ql/test/library-tests/xml/XMLTest.expected index 61d3c801963..316503fd211 100644 --- a/java/ql/test/library-tests/xml/XMLTest.expected +++ b/java/ql/test/library-tests/xml/XMLTest.expected @@ -1,2 +1,4 @@ +failures +testFailures | test.xml:4:5:4:32 | attribute=value | Unexpected result: hasXmlResult= | -| test.xml:5:29:5:52 | $ hasXmlResult | Missing result:hasXmlResult= | \ No newline at end of file +| test.xml:5:29:5:52 | $ hasXmlResult | Missing result:hasXmlResult= | diff --git a/java/ql/test/library-tests/xml/XMLTest.ql b/java/ql/test/library-tests/xml/XMLTest.ql index c5011b848d4..40c5481e3e3 100644 --- a/java/ql/test/library-tests/xml/XMLTest.ql +++ b/java/ql/test/library-tests/xml/XMLTest.ql @@ -1,12 +1,10 @@ import semmle.code.xml.XML import TestUtilities.InlineExpectationsTest -class XmlTest extends InlineExpectationsTest { - XmlTest() { this = "XmlTest" } +module XmlTest implements TestSig { + string getARelevantTag() { result = "hasXmlResult" } - override string getARelevantTag() { result = "hasXmlResult" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasXmlResult" and exists(XmlAttribute a | a.getLocation() = location and @@ -15,3 +13,5 @@ class XmlTest extends InlineExpectationsTest { ) } } + +import MakeTest<XmlTest> diff --git a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.expected b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.expected +++ b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.ql b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.ql index a07eb6892c3..26a6012d7fb 100644 --- a/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.ql +++ b/java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalFromRemoteTest.ql @@ -8,12 +8,10 @@ class TestRemoteSource extends RemoteFlowSource { override string getSourceType() { result = "TestSource" } } -class Test extends InlineExpectationsTest { - Test() { this = "PartialPathTraversalFromRemoteTest" } +module Test implements TestSig { + string getARelevantTag() { result = "hasTaintFlow" } - override string getARelevantTag() { result = "hasTaintFlow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasTaintFlow" and exists(DataFlow::Node sink | PartialPathTraversalFromRemoteFlow::flowTo(sink) | sink.getLocation() = location and @@ -22,3 +20,5 @@ class Test extends InlineExpectationsTest { ) } } + +import MakeTest<Test> diff --git a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.expected b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql index 7a6141b93ce..242bf9c3f54 100644 --- a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.JndiInjectionQuery import TestUtilities.InlineExpectationsTest -class HasJndiInjectionTest extends InlineExpectationsTest { - HasJndiInjectionTest() { this = "HasJndiInjectionTest" } +module HasJndiInjectionTest implements TestSig { + string getARelevantTag() { result = "hasJndiInjection" } - override string getARelevantTag() { result = "hasJndiInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasJndiInjection" and exists(DataFlow::Node sink | JndiInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class HasJndiInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasJndiInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.expected b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql index 1f5a3030cdb..4d5200477d8 100644 --- a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql @@ -4,12 +4,10 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.XsltInjectionQuery import TestUtilities.InlineExpectationsTest -class HasXsltInjectionTest extends InlineExpectationsTest { - HasXsltInjectionTest() { this = "HasXsltInjectionTest" } +module HasXsltInjectionTest implements TestSig { + string getARelevantTag() { result = "hasXsltInjection" } - override string getARelevantTag() { result = "hasXsltInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasXsltInjection" and exists(DataFlow::Node sink | XsltInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -18,3 +16,5 @@ class HasXsltInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasXsltInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.ql b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.ql index 454f42112ea..5e901c83498 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.ql +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.XssQuery import TestUtilities.InlineExpectationsTest -class XssTest extends InlineExpectationsTest { - XssTest() { this = "XssTest" } +module XssTest implements TestSig { + string getARelevantTag() { result = "xss" } - override string getARelevantTag() { result = "xss" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "xss" and exists(DataFlow::Node sink | XssFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class XssTest extends InlineExpectationsTest { ) } } + +import MakeTest<XssTest> diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.ql b/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.ql index bee1fa84ebc..7934ecd9d8d 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.ql +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/springjdbc.ql @@ -9,12 +9,10 @@ private class SourceMethodSource extends RemoteFlowSource { override string getSourceType() { result = "source" } } -class HasFlowTest extends InlineExpectationsTest { - HasFlowTest() { this = "HasFlowTest" } +module HasFlowTest implements TestSig { + string getARelevantTag() { result = "sqlInjection" } - override string getARelevantTag() { result = "sqlInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "sqlInjection" and exists(DataFlow::Node sink | QueryInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -23,3 +21,5 @@ class HasFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasFlowTest> diff --git a/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.expected b/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.ql b/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.ql index dd6aec2ebe3..b10e291d376 100644 --- a/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.ql @@ -3,12 +3,10 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.ArbitraryApkInstallationQuery import TestUtilities.InlineExpectationsTest -class HasApkInstallationTest extends InlineExpectationsTest { - HasApkInstallationTest() { this = "HasApkInstallationTest" } +module HasApkInstallationTest implements TestSig { + string getARelevantTag() { result = "hasApkInstallation" } - override string getARelevantTag() { result = "hasApkInstallation" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasApkInstallation" and exists(DataFlow::Node sink | ApkInstallationFlow::flowTo(sink) | sink.getLocation() = location and @@ -17,3 +15,5 @@ class HasApkInstallationTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasApkInstallationTest> diff --git a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql index 9d979f125a8..bc39280407e 100644 --- a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql @@ -4,12 +4,10 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.GroovyInjectionQuery import TestUtilities.InlineExpectationsTest -class HasGroovyInjectionTest extends InlineExpectationsTest { - HasGroovyInjectionTest() { this = "HasGroovyInjectionTest" } +module HasGroovyInjectionTest implements TestSig { + string getARelevantTag() { result = "hasGroovyInjection" } - override string getARelevantTag() { result = "hasGroovyInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasGroovyInjection" and exists(DataFlow::Node sink | GroovyInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -18,3 +16,5 @@ class HasGroovyInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasGroovyInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql index 9593ae1a8ee..07f1573b039 100644 --- a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.JexlInjectionQuery import TestUtilities.InlineExpectationsTest -class JexlInjectionTest extends InlineExpectationsTest { - JexlInjectionTest() { this = "HasJexlInjectionTest" } +module JexlInjectionTest implements TestSig { + string getARelevantTag() { result = "hasJexlInjection" } - override string getARelevantTag() { result = "hasJexlInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasJexlInjection" and exists(DataFlow::Node sink | JexlInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class JexlInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<JexlInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql index 8dc4127cbf1..f7599250077 100644 --- a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql @@ -4,12 +4,10 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.MvelInjectionQuery import TestUtilities.InlineExpectationsTest -class HasMvelInjectionTest extends InlineExpectationsTest { - HasMvelInjectionTest() { this = "HasMvelInjectionTest" } +module HasMvelInjectionTest implements TestSig { + string getARelevantTag() { result = "hasMvelInjection" } - override string getARelevantTag() { result = "hasMvelInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasMvelInjection" and exists(DataFlow::Node sink | MvelInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -18,3 +16,5 @@ class HasMvelInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasMvelInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql index 78e147849f1..a017c96f60b 100644 --- a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql @@ -4,12 +4,10 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.SpelInjectionQuery import TestUtilities.InlineExpectationsTest -class HasSpelInjectionTest extends InlineExpectationsTest { - HasSpelInjectionTest() { this = "HasSpelInjectionTest" } +module HasSpelInjectionTest implements TestSig { + string getARelevantTag() { result = "hasSpelInjection" } - override string getARelevantTag() { result = "hasSpelInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasSpelInjection" and exists(DataFlow::Node sink | SpelInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -18,3 +16,5 @@ class HasSpelInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasSpelInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql index 7e0a7ae1ae2..4c37e8a5f01 100644 --- a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.TemplateInjectionQuery import TestUtilities.InlineExpectationsTest -class TemplateInjectionTest extends InlineExpectationsTest { - TemplateInjectionTest() { this = "TemplateInjectionTest" } +module TemplateInjectionTest implements TestSig { + string getARelevantTag() { result = "hasTemplateInjection" } - override string getARelevantTag() { result = "hasTemplateInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasTemplateInjection" and exists(DataFlow::Node sink | TemplateInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class TemplateInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<TemplateInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.expected b/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.expected +++ b/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.ql b/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.ql index ceaf8e11a4f..2ccb8fa7c52 100644 --- a/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.ql +++ b/java/ql/test/query-tests/security/CWE-1204/StaticInitializationVectorTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.StaticInitializationVectorQuery import TestUtilities.InlineExpectationsTest -class StaticInitializationVectorTest extends InlineExpectationsTest { - StaticInitializationVectorTest() { this = "StaticInitializationVectorTest" } +module StaticInitializationVectorTest implements TestSig { + string getARelevantTag() { result = "staticInitializationVector" } - override string getARelevantTag() { result = "staticInitializationVector" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "staticInitializationVector" and exists(DataFlow::Node sink | StaticInitializationVectorFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class StaticInitializationVectorTest extends InlineExpectationsTest { ) } } + +import MakeTest<StaticInitializationVectorTest> diff --git a/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.expected b/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.expected +++ b/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.ql b/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.ql index fd18ccc27eb..e896e272aa4 100644 --- a/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.ql +++ b/java/ql/test/query-tests/security/CWE-273/UnsafeCertTrustTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.UnsafeCertTrustQuery import TestUtilities.InlineExpectationsTest -class UnsafeCertTrustTest extends InlineExpectationsTest { - UnsafeCertTrustTest() { this = "HasUnsafeCertTrustTest" } +module UnsafeCertTrustTest implements TestSig { + string getARelevantTag() { result = "hasUnsafeCertTrust" } - override string getARelevantTag() { result = "hasUnsafeCertTrust" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasUnsafeCertTrust" and exists(Expr unsafeTrust | unsafeTrust instanceof RabbitMQEnableHostnameVerificationNotSet @@ -20,3 +18,5 @@ class UnsafeCertTrustTest extends InlineExpectationsTest { ) } } + +import MakeTest<UnsafeCertTrustTest> diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql index 91a23044730..1a6c3a9d0c0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test1/test.ql @@ -2,12 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.AndroidCertificatePinningQuery -class Test extends InlineExpectationsTest { - Test() { this = "AndroidMissingCertificatePinningTest" } +module Test implements TestSig { + string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - - override predicate hasActualResult(Location loc, string el, string tag, string value) { + predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | missingPinning(node, _) and loc = node.getLocation() and @@ -17,3 +15,5 @@ class Test extends InlineExpectationsTest { ) } } + +import MakeTest<Test> diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql index 91a23044730..1a6c3a9d0c0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test2/test.ql @@ -2,12 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.AndroidCertificatePinningQuery -class Test extends InlineExpectationsTest { - Test() { this = "AndroidMissingCertificatePinningTest" } +module Test implements TestSig { + string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - - override predicate hasActualResult(Location loc, string el, string tag, string value) { + predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | missingPinning(node, _) and loc = node.getLocation() and @@ -17,3 +15,5 @@ class Test extends InlineExpectationsTest { ) } } + +import MakeTest<Test> diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql index 91a23044730..1a6c3a9d0c0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test3/test.ql @@ -2,12 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.AndroidCertificatePinningQuery -class Test extends InlineExpectationsTest { - Test() { this = "AndroidMissingCertificatePinningTest" } +module Test implements TestSig { + string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - - override predicate hasActualResult(Location loc, string el, string tag, string value) { + predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | missingPinning(node, _) and loc = node.getLocation() and @@ -17,3 +15,5 @@ class Test extends InlineExpectationsTest { ) } } + +import MakeTest<Test> diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql index 91a23044730..1a6c3a9d0c0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test4/test.ql @@ -2,12 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.AndroidCertificatePinningQuery -class Test extends InlineExpectationsTest { - Test() { this = "AndroidMissingCertificatePinningTest" } +module Test implements TestSig { + string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - - override predicate hasActualResult(Location loc, string el, string tag, string value) { + predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | missingPinning(node, _) and loc = node.getLocation() and @@ -17,3 +15,5 @@ class Test extends InlineExpectationsTest { ) } } + +import MakeTest<Test> diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql index 91a23044730..1a6c3a9d0c0 100644 --- a/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/AndroidMissingCertificatePinning/Test5/test.ql @@ -2,12 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.AndroidCertificatePinningQuery -class Test extends InlineExpectationsTest { - Test() { this = "AndroidMissingCertificatePinningTest" } +module Test implements TestSig { + string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - override string getARelevantTag() { result = ["hasNoTrustedResult", "hasUntrustedResult"] } - - override predicate hasActualResult(Location loc, string el, string tag, string value) { + predicate hasActualResult(Location loc, string el, string tag, string value) { exists(DataFlow::Node node | missingPinning(node, _) and loc = node.getLocation() and @@ -17,3 +15,5 @@ class Test extends InlineExpectationsTest { ) } } + +import MakeTest<Test> diff --git a/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.expected b/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.expected +++ b/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.ql b/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.ql index 6166e0fe239..70d242e7ebb 100644 --- a/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.ql +++ b/java/ql/test/query-tests/security/CWE-295/ImproperWebVeiwCertificateValidation/test.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.AndroidWebViewCertificateValidationQuery import TestUtilities.InlineExpectationsTest -class WebViewTest extends InlineExpectationsTest { - WebViewTest() { this = "WebViewTest" } +module WebViewTest implements TestSig { + string getARelevantTag() { result = "hasResult" } - override string getARelevantTag() { result = "hasResult" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(OnReceivedSslErrorMethod m | trustsAllCerts(m) and location = m.getLocation() and @@ -17,3 +15,5 @@ class WebViewTest extends InlineExpectationsTest { ) } } + +import MakeTest<WebViewTest> diff --git a/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.expected b/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.expected +++ b/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.ql b/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.ql index 0f068d04679..11a59f51feb 100644 --- a/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.ql +++ b/java/ql/test/query-tests/security/CWE-295/InsecureTrustManager/InsecureTrustManagerTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.InsecureTrustManagerQuery import TestUtilities.InlineExpectationsTest -class InsecureTrustManagerTest extends InlineExpectationsTest { - InsecureTrustManagerTest() { this = "InsecureTrustManagerTest" } +module InsecureTrustManagerTest implements TestSig { + string getARelevantTag() { result = "hasValueFlow" } - override string getARelevantTag() { result = "hasValueFlow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasValueFlow" and exists(DataFlow::Node sink | InsecureTrustManagerFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class InsecureTrustManagerTest extends InlineExpectationsTest { ) } } + +import MakeTest<InsecureTrustManagerTest> diff --git a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected +++ b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.ql b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.ql index 137dde369f9..ffe4673b62c 100644 --- a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.ql +++ b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.Mail import TestUtilities.InlineExpectationsTest -class InsecureJavaMailTest extends InlineExpectationsTest { - InsecureJavaMailTest() { this = "HasInsecureJavaMailTest" } +module InsecureJavaMailTest implements TestSig { + string getARelevantTag() { result = "hasInsecureJavaMail" } - override string getARelevantTag() { result = "hasInsecureJavaMail" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsecureJavaMail" and exists(MethodAccess ma | ma.getLocation() = location and @@ -22,3 +20,5 @@ class InsecureJavaMailTest extends InlineExpectationsTest { ) } } + +import MakeTest<InsecureJavaMailTest> diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.ql b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.ql index 421b3a408c4..8b49ed472f5 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.ql +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery import TestUtilities.InlineExpectationsTest -class CleartextStorageAndroidDatabaseTest extends InlineExpectationsTest { - CleartextStorageAndroidDatabaseTest() { this = "CleartextStorageAndroidDatabaseTest" } +module CleartextStorageAndroidDatabaseTest implements TestSig { + string getARelevantTag() { result = "hasCleartextStorageAndroidDatabase" } - override string getARelevantTag() { result = "hasCleartextStorageAndroidDatabase" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasCleartextStorageAndroidDatabase" and exists(SensitiveSource data, LocalDatabaseOpenMethodAccess s, Expr input, Expr store | input = s.getAnInput() and @@ -20,3 +18,5 @@ class CleartextStorageAndroidDatabaseTest extends InlineExpectationsTest { ) } } + +import MakeTest<CleartextStorageAndroidDatabaseTest> diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.ql b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.ql index ab221086f81..7b7380ccedf 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.ql +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.CleartextStorageAndroidFilesystemQuery import TestUtilities.InlineExpectationsTest -class CleartextStorageAndroidFilesystemTest extends InlineExpectationsTest { - CleartextStorageAndroidFilesystemTest() { this = "CleartextStorageAndroidFilesystemTest" } +module CleartextStorageAndroidFilesystemTest implements TestSig { + string getARelevantTag() { result = "hasCleartextStorageAndroidFilesystem" } - override string getARelevantTag() { result = "hasCleartextStorageAndroidFilesystem" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasCleartextStorageAndroidFilesystem" and exists(SensitiveSource data, LocalFileOpenCall s, Expr input, Expr store | input = s.getAnInput() and @@ -20,3 +18,5 @@ class CleartextStorageAndroidFilesystemTest extends InlineExpectationsTest { ) } } + +import MakeTest<CleartextStorageAndroidFilesystemTest> diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.ql b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.ql index cbd17429e5c..025daff6c82 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.ql +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.CleartextStorageSharedPrefsQuery import TestUtilities.InlineExpectationsTest -class CleartextStorageSharedPrefsTest extends InlineExpectationsTest { - CleartextStorageSharedPrefsTest() { this = "CleartextStorageSharedPrefsTest" } +module CleartextStorageSharedPrefsTest implements TestSig { + string getARelevantTag() { result = "hasCleartextStorageSharedPrefs" } - override string getARelevantTag() { result = "hasCleartextStorageSharedPrefs" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasCleartextStorageSharedPrefs" and exists(SensitiveSource data, SharedPreferencesEditorMethodAccess s, Expr input, Expr store | input = s.getAnInput() and @@ -20,3 +18,5 @@ class CleartextStorageSharedPrefsTest extends InlineExpectationsTest { ) } } + +import MakeTest<CleartextStorageSharedPrefsTest> diff --git a/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.expected b/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.expected +++ b/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql b/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql index 1384a36e4ce..642495eebaa 100644 --- a/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql +++ b/java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql @@ -2,12 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.InsufficientKeySizeQuery -class InsufficientKeySizeTest extends InlineExpectationsTest { - InsufficientKeySizeTest() { this = "InsufficientKeySize" } +module InsufficientKeySizeTest implements TestSig { + string getARelevantTag() { result = "hasInsufficientKeySize" } - override string getARelevantTag() { result = "hasInsufficientKeySize" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsufficientKeySize" and exists(KeySizeFlow::PathNode sink | KeySizeFlow::flowPath(_, sink) | sink.getNode().getLocation() = location and @@ -16,3 +14,5 @@ class InsufficientKeySizeTest extends InlineExpectationsTest { ) } } + +import MakeTest<InsufficientKeySizeTest> diff --git a/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.expected b/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.expected +++ b/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.ql b/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.ql index df6867bbefe..3d9a18fc1a8 100644 --- a/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.ql +++ b/java/ql/test/query-tests/security/CWE-347/MissingJWTSignatureCheckTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.MissingJWTSignatureCheckQuery import TestUtilities.InlineExpectationsTest -class HasMissingJwtSignatureCheckTest extends InlineExpectationsTest { - HasMissingJwtSignatureCheckTest() { this = "HasMissingJwtSignatureCheckTest" } +module HasMissingJwtSignatureCheckTest implements TestSig { + string getARelevantTag() { result = "hasMissingJwtSignatureCheck" } - override string getARelevantTag() { result = "hasMissingJwtSignatureCheck" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasMissingJwtSignatureCheck" and exists(DataFlow::Node sink | MissingJwtSignatureCheckFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class HasMissingJwtSignatureCheckTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasMissingJwtSignatureCheckTest> diff --git a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.expected b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.expected +++ b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.ql b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.ql index 1e4d7b42cb5..c1878d4976d 100644 --- a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.ql +++ b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionInPreferenceActivityTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.FragmentInjection import TestUtilities.InlineExpectationsTest -class FragmentInjectionInPreferenceActivityTest extends InlineExpectationsTest { - FragmentInjectionInPreferenceActivityTest() { this = "FragmentInjectionInPreferenceActivityTest" } +module FragmentInjectionInPreferenceActivityTest implements TestSig { + string getARelevantTag() { result = "hasPreferenceFragmentInjection" } - override string getARelevantTag() { result = "hasPreferenceFragmentInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasPreferenceFragmentInjection" and exists(IsValidFragmentMethod isValidFragment | isValidFragment.isUnsafe() | isValidFragment.getLocation() = location and @@ -16,3 +14,5 @@ class FragmentInjectionInPreferenceActivityTest extends InlineExpectationsTest { ) } } + +import MakeTest<FragmentInjectionInPreferenceActivityTest> diff --git a/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.expected b/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.expected +++ b/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.ql b/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.ql index 76433545aa5..79a762ea209 100644 --- a/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.ql +++ b/java/ql/test/query-tests/security/CWE-489/debuggable-attribute/DebuggableAttributeEnabledTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.xml.AndroidManifest import TestUtilities.InlineExpectationsTest -class DebuggableAttributeEnabledTest extends InlineExpectationsTest { - DebuggableAttributeEnabledTest() { this = "DebuggableAttributeEnabledTest" } +module DebuggableAttributeEnabledTest implements TestSig { + string getARelevantTag() { result = "hasDebuggableAttributeEnabled" } - override string getARelevantTag() { result = "hasDebuggableAttributeEnabled" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasDebuggableAttributeEnabled" and exists(AndroidApplicationXmlElement androidAppElem | androidAppElem.isDebuggable() and @@ -19,3 +17,5 @@ class DebuggableAttributeEnabledTest extends InlineExpectationsTest { ) } } + +import MakeTest<DebuggableAttributeEnabledTest> diff --git a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected +++ b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.ql b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.ql index 4d10c798e33..68623825985 100644 --- a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.ql +++ b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.UnsafeDeserializationQuery import TestUtilities.InlineExpectationsTest -class UnsafeDeserializationTest extends InlineExpectationsTest { - UnsafeDeserializationTest() { this = "UnsafeDeserializationTest" } +module UnsafeDeserializationTest implements TestSig { + string getARelevantTag() { result = "unsafeDeserialization" } - override string getARelevantTag() { result = "unsafeDeserialization" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "unsafeDeserialization" and exists(DataFlow::Node sink | UnsafeDeserializationFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class UnsafeDeserializationTest extends InlineExpectationsTest { ) } } + +import MakeTest<UnsafeDeserializationTest> diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected +++ b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql index 29057edce71..c0384899d56 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql +++ b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.InsecureBasicAuthQuery import TestUtilities.InlineExpectationsTest -class HasInsecureBasicAuthTest extends InlineExpectationsTest { - HasInsecureBasicAuthTest() { this = "HasInsecureBasicAuthTest" } +module HasInsecureBasicAuthTest implements TestSig { + string getARelevantTag() { result = "hasInsecureBasicAuth" } - override string getARelevantTag() { result = "hasInsecureBasicAuth" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsecureBasicAuth" and exists(DataFlow::Node sink | InsecureBasicAuthFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class HasInsecureBasicAuthTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasInsecureBasicAuthTest> diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql index 4ae89d21313..f75550f5112 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.InsecureLdapAuthQuery import TestUtilities.InlineExpectationsTest -class InsecureLdapAuthenticationTest extends InlineExpectationsTest { - InsecureLdapAuthenticationTest() { this = "InsecureLdapAuthentication" } +module InsecureLdapAuthenticationTest implements TestSig { + string getARelevantTag() { result = "hasInsecureLdapAuth" } - override string getARelevantTag() { result = "hasInsecureLdapAuth" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsecureLdapAuth" and exists(DataFlow::Node sink | InsecureLdapUrlFlow::flowTo(sink) | BasicAuthFlow::flowTo(sink) and @@ -18,3 +16,5 @@ class InsecureLdapAuthenticationTest extends InlineExpectationsTest { ) } } + +import MakeTest<InsecureLdapAuthenticationTest> diff --git a/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected +++ b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.ql b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.ql index 26ce8bc7fb7..caa50f9fa75 100644 --- a/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.ql +++ b/java/ql/test/query-tests/security/CWE-524/SensitiveKeyboardCache.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.SensitiveKeyboardCacheQuery import TestUtilities.InlineExpectationsTest -class SensitiveKeyboardCacheTest extends InlineExpectationsTest { - SensitiveKeyboardCacheTest() { this = "SensitiveKeyboardCacheTest" } +module SensitiveKeyboardCacheTest implements TestSig { + string getARelevantTag() { result = "hasResult" } - override string getARelevantTag() { result = "hasResult" } - - override predicate hasActualResult(Location loc, string element, string tag, string value) { + predicate hasActualResult(Location loc, string element, string tag, string value) { exists(AndroidEditableXmlElement el | el = getASensitiveCachedInput() and loc = el.getLocation() and @@ -17,3 +15,5 @@ class SensitiveKeyboardCacheTest extends InlineExpectationsTest { ) } } + +import MakeTest<SensitiveKeyboardCacheTest> diff --git a/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.expected b/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.ql b/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.ql index 385ade9105b..3f39a4752bb 100644 --- a/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-643/XPathInjectionTest.ql @@ -3,12 +3,10 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.XPathInjectionQuery import TestUtilities.InlineExpectationsTest -class HasXPathInjectionTest extends InlineExpectationsTest { - HasXPathInjectionTest() { this = "HasXPathInjectionTest" } +module HasXPathInjectionTest implements TestSig { + string getARelevantTag() { result = "hasXPathInjection" } - override string getARelevantTag() { result = "hasXPathInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasXPathInjection" and exists(DataFlow::Node sink | XPathInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -17,3 +15,5 @@ class HasXPathInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasXPathInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.expected b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.expected +++ b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql index 75af0160def..45dea80e72b 100644 --- a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql +++ b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql @@ -1,12 +1,10 @@ import TestUtilities.InlineExpectationsTest import semmle.code.java.security.regexp.PolynomialReDoSQuery -class HasPolyRedos extends InlineExpectationsTest { - HasPolyRedos() { this = "HasPolyRedos" } +module HasPolyRedos implements TestSig { + string getARelevantTag() { result = "hasPolyRedos" } - override string getARelevantTag() { result = "hasPolyRedos" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasPolyRedos" and exists(DataFlow::Node sink | PolynomialRedosFlow::flowTo(sink) and @@ -16,3 +14,5 @@ class HasPolyRedos extends InlineExpectationsTest { ) } } + +import MakeTest<HasPolyRedos> diff --git a/java/ql/test/query-tests/security/CWE-730/ReDoS.expected b/java/ql/test/query-tests/security/CWE-730/ReDoS.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-730/ReDoS.expected +++ b/java/ql/test/query-tests/security/CWE-730/ReDoS.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-730/ReDoS.ql b/java/ql/test/query-tests/security/CWE-730/ReDoS.ql index f7d5d7175b3..97719364f94 100644 --- a/java/ql/test/query-tests/security/CWE-730/ReDoS.ql +++ b/java/ql/test/query-tests/security/CWE-730/ReDoS.ql @@ -4,12 +4,10 @@ private import semmle.code.java.regex.RegexTreeView::RegexTreeView as TreeView import codeql.regex.nfa.ExponentialBackTracking::Make<TreeView> as ExponentialBackTracking import semmle.code.java.regex.regex -class HasExpRedos extends InlineExpectationsTest { - HasExpRedos() { this = "HasExpRedos" } +module HasExpRedos implements TestSig { + string getARelevantTag() { result = ["hasExpRedos", "hasParseFailure"] } - override string getARelevantTag() { result = ["hasExpRedos", "hasParseFailure"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasExpRedos" and exists(TreeView::RegExpTerm t | ExponentialBackTracking::hasReDoSResult(t, _, _, _) and @@ -28,3 +26,5 @@ class HasExpRedos extends InlineExpectationsTest { ) } } + +import MakeTest<HasExpRedos> diff --git a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql index f42de310988..afc621e0767 100644 --- a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql @@ -2,12 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.security.regexp.RegexInjectionQuery -class RegexInjectionTest extends InlineExpectationsTest { - RegexInjectionTest() { this = "RegexInjectionTest" } +module RegexInjectionTest implements TestSig { + string getARelevantTag() { result = "hasRegexInjection" } - override string getARelevantTag() { result = "hasRegexInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasRegexInjection" and exists(RegexInjectionFlow::PathNode sink | RegexInjectionFlow::flowPath(_, sink) | location = sink.getNode().getLocation() and @@ -16,3 +14,5 @@ class RegexInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<RegexInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.expected b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.expected +++ b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql index 4da1ca7fd5f..99fba4e9172 100644 --- a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql +++ b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.UnsafeAndroidAccessQuery import TestUtilities.InlineExpectationsTest -class UnsafeAndroidAccessTest extends InlineExpectationsTest { - UnsafeAndroidAccessTest() { this = "HasUnsafeAndroidAccess" } +module UnsafeAndroidAccessTest implements TestSig { + string getARelevantTag() { result = "hasUnsafeAndroidAccess" } - override string getARelevantTag() { result = "hasUnsafeAndroidAccess" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasUnsafeAndroidAccess" and exists(DataFlow::Node sink | FetchUntrustedResourceFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class UnsafeAndroidAccessTest extends InlineExpectationsTest { ) } } + +import MakeTest<UnsafeAndroidAccessTest> diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql index 7d7b8e2d2a5..2b2290fad10 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.HardcodedCredentialsApiCallQuery import TestUtilities.InlineExpectationsTest -class HardcodedCredentialsApiCallTest extends InlineExpectationsTest { - HardcodedCredentialsApiCallTest() { this = "HardcodedCredentialsApiCallTest" } +module HardcodedCredentialsApiCallTest implements TestSig { + string getARelevantTag() { result = "HardcodedCredentialsApiCall" } - override string getARelevantTag() { result = "HardcodedCredentialsApiCall" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "HardcodedCredentialsApiCall" and exists(DataFlow::Node sink | HardcodedCredentialApiCallFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class HardcodedCredentialsApiCallTest extends InlineExpectationsTest { ) } } + +import MakeTest<HardcodedCredentialsApiCallTest> diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.ql index bde1851e43c..10698984828 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.ql +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.HardcodedCredentialsComparison import TestUtilities.InlineExpectationsTest -class HardcodedCredentialsComparisonTest extends InlineExpectationsTest { - HardcodedCredentialsComparisonTest() { this = "HardcodedCredentialsComparisonTest" } +module HardcodedCredentialsComparisonTest implements TestSig { + string getARelevantTag() { result = "HardcodedCredentialsComparison" } - override string getARelevantTag() { result = "HardcodedCredentialsComparison" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "HardcodedCredentialsComparison" and exists(Expr sink | isHardcodedCredentialsComparison(sink, _, _) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class HardcodedCredentialsComparisonTest extends InlineExpectationsTest { ) } } + +import MakeTest<HardcodedCredentialsComparisonTest> diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.ql index 0fcf2f128ad..ab941d80a4e 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.ql +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.HardcodedCredentialsSourceCallQuery import TestUtilities.InlineExpectationsTest -class HardcodedCredentialsSourceCallTest extends InlineExpectationsTest { - HardcodedCredentialsSourceCallTest() { this = "HardcodedCredentialsSourceCallTest" } +module HardcodedCredentialsSourceCallTest implements TestSig { + string getARelevantTag() { result = "HardcodedCredentialsSourceCall" } - override string getARelevantTag() { result = "HardcodedCredentialsSourceCall" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "HardcodedCredentialsSourceCall" and exists(DataFlow::Node sink | HardcodedCredentialSourceCallFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class HardcodedCredentialsSourceCallTest extends InlineExpectationsTest { ) } } + +import MakeTest<HardcodedCredentialsSourceCallTest> diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.ql index 057bbbc2ab0..f734ca356ac 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.ql +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.HardcodedPasswordField import TestUtilities.InlineExpectationsTest -class HardcodedPasswordFieldTest extends InlineExpectationsTest { - HardcodedPasswordFieldTest() { this = "HardcodedPasswordFieldTest" } +module HardcodedPasswordFieldTest implements TestSig { + string getARelevantTag() { result = "HardcodedPasswordField" } - override string getARelevantTag() { result = "HardcodedPasswordField" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "HardcodedPasswordField" and exists(Expr assigned | passwordFieldAssignedHardcodedValue(_, assigned) | assigned.getLocation() = location and @@ -16,3 +14,5 @@ class HardcodedPasswordFieldTest extends InlineExpectationsTest { ) } } + +import MakeTest<HardcodedPasswordFieldTest> diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected +++ b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql index 20ca408f1b2..e77ea5ad228 100644 --- a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql +++ b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.ConditionalBypassQuery import TestUtilities.InlineExpectationsTest -class ConditionalBypassTest extends InlineExpectationsTest { - ConditionalBypassTest() { this = "ConditionalBypassTest" } +module ConditionalBypassTest implements TestSig { + string getARelevantTag() { result = "hasConditionalBypassTest" } - override string getARelevantTag() { result = "hasConditionalBypassTest" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasConditionalBypassTest" and exists(DataFlow::Node sink | ConditionalBypassFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class ConditionalBypassTest extends InlineExpectationsTest { ) } } + +import MakeTest<ConditionalBypassTest> diff --git a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.expected b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql index 68db2593628..52dd8ad3417 100644 --- a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.OgnlInjectionQuery import TestUtilities.InlineExpectationsTest -class OgnlInjectionTest extends InlineExpectationsTest { - OgnlInjectionTest() { this = "HasOgnlInjection" } +module OgnlInjectionTest implements TestSig { + string getARelevantTag() { result = "hasOgnlInjection" } - override string getARelevantTag() { result = "hasOgnlInjection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasOgnlInjection" and exists(DataFlow::Node sink | OgnlInjectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class OgnlInjectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<OgnlInjectionTest> diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.ql b/java/ql/test/query-tests/security/CWE-918/RequestForgery.ql index 865e6e8f0d3..41dbaad7d05 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.ql +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.RequestForgeryConfig import TestUtilities.InlineExpectationsTest -class HasFlowTest extends InlineExpectationsTest { - HasFlowTest() { this = "HasFlowTest" } +module HasFlowTest implements TestSig { + string getARelevantTag() { result = "SSRF" } - override string getARelevantTag() { result = "SSRF" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "SSRF" and exists(DataFlow::Node sink | RequestForgeryFlow::flowTo(sink) and @@ -17,3 +15,5 @@ class HasFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasFlowTest> diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected +++ b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql index 30ced62b2ed..baba5cac103 100644 --- a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql +++ b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.ImproperIntentVerificationQuery import TestUtilities.InlineExpectationsTest -class HasFlowTest extends InlineExpectationsTest { - HasFlowTest() { this = "HasFlowTest" } +module HasFlowTest implements TestSig { + string getARelevantTag() { result = "hasResult" } - override string getARelevantTag() { result = "hasResult" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasResult" and exists(Method orm | unverifiedSystemReceiver(_, orm, _) | orm.getLocation() = location and @@ -16,3 +14,5 @@ class HasFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasFlowTest> diff --git a/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.expected b/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.expected +++ b/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.ql b/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.ql index fbda52d36ab..934fc5c899b 100644 --- a/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.ql +++ b/java/ql/test/query-tests/security/CWE-926/ImplicitlyExportedAndroidComponentTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.ImplicitlyExportedAndroidComponent import TestUtilities.InlineExpectationsTest -class ImplicitlyExportedAndroidComponentTest extends InlineExpectationsTest { - ImplicitlyExportedAndroidComponentTest() { this = "ImplicitlyExportedAndroidComponentTest" } +module ImplicitlyExportedAndroidComponentTest implements TestSig { + string getARelevantTag() { result = "hasImplicitExport" } - override string getARelevantTag() { result = "hasImplicitExport" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasImplicitExport" and exists(ImplicitlyExportedAndroidComponent impExpAndroidComp | impExpAndroidComp.getLocation() = location and @@ -16,3 +14,5 @@ class ImplicitlyExportedAndroidComponentTest extends InlineExpectationsTest { ) } } + +import MakeTest<ImplicitlyExportedAndroidComponentTest> diff --git a/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.expected b/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.expected +++ b/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.ql b/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.ql index 9ba691685eb..c7ce16660e1 100644 --- a/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.ql +++ b/java/ql/test/query-tests/security/CWE-926/incomplete_provider_permissions/ContentProviderIncompletePermissionsTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.xml.AndroidManifest import TestUtilities.InlineExpectationsTest -class ContentProviderIncompletePermissionsTest extends InlineExpectationsTest { - ContentProviderIncompletePermissionsTest() { this = "ContentProviderIncompletePermissionsTest" } +module ContentProviderIncompletePermissionsTest implements TestSig { + string getARelevantTag() { result = "hasIncompletePermissions" } - override string getARelevantTag() { result = "hasIncompletePermissions" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasIncompletePermissions" and exists(AndroidProviderXmlElement provider | provider.getLocation() = location and @@ -20,3 +18,5 @@ class ContentProviderIncompletePermissionsTest extends InlineExpectationsTest { ) } } + +import MakeTest<ContentProviderIncompletePermissionsTest> diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.ql b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.ql index 972653380aa..e43b90f8ee8 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.ql +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.ImplicitPendingIntentsQuery import TestUtilities.InlineExpectationsTest -class ImplicitPendingIntentsTest extends InlineExpectationsTest { - ImplicitPendingIntentsTest() { this = "ImplicitPendingIntentsTest" } +module ImplicitPendingIntentsTest implements TestSig { + string getARelevantTag() { result = "hasImplicitPendingIntent" } - override string getARelevantTag() { result = ["hasImplicitPendingIntent"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasImplicitPendingIntent" and exists(DataFlow::Node sink | ImplicitPendingIntentStartFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class ImplicitPendingIntentsTest extends InlineExpectationsTest { ) } } + +import MakeTest<ImplicitPendingIntentsTest> diff --git a/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.expected b/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.expected +++ b/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.ql b/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.ql index fb7b1dfee43..0624ae91ca9 100644 --- a/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.ql +++ b/java/ql/test/query-tests/security/CWE-927/SensitiveResultReceiver.ql @@ -8,12 +8,10 @@ class TestSource extends RemoteFlowSource { override string getSourceType() { result = "test" } } -class ResultReceiverTest extends InlineExpectationsTest { - ResultReceiverTest() { this = "ResultReceiverTest" } +module ResultReceiverTest implements TestSig { + string getARelevantTag() { result = "hasSensitiveResultReceiver" } - override string getARelevantTag() { result = "hasSensitiveResultReceiver" } - - override predicate hasActualResult(Location loc, string element, string tag, string value) { + predicate hasActualResult(Location loc, string element, string tag, string value) { exists(SensitiveResultReceiverFlow::PathNode sink | isSensitiveResultReceiver(_, sink, _) and element = sink.toString() and @@ -23,3 +21,5 @@ class ResultReceiverTest extends InlineExpectationsTest { ) } } + +import MakeTest<ResultReceiverTest> diff --git a/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.expected b/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql b/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql index 7b74855caa5..6c4d121a2bc 100644 --- a/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql @@ -2,12 +2,10 @@ import java import semmle.code.java.security.AndroidIntentRedirectionQuery import TestUtilities.InlineExpectationsTest -class HasAndroidIntentRedirectionTest extends InlineExpectationsTest { - HasAndroidIntentRedirectionTest() { this = "HasAndroidIntentRedirectionTest" } +module HasAndroidIntentRedirectionTest implements TestSig { + string getARelevantTag() { result = "hasAndroidIntentRedirection" } - override string getARelevantTag() { result = "hasAndroidIntentRedirection" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasAndroidIntentRedirection" and exists(DataFlow::Node sink | IntentRedirectionFlow::flowTo(sink) | sink.getLocation() = location and @@ -16,3 +14,5 @@ class HasAndroidIntentRedirectionTest extends InlineExpectationsTest { ) } } + +import MakeTest<HasAndroidIntentRedirectionTest> From 8f599faf85e2228a5f593206e37b4cc74199e798 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Wed, 7 Jun 2023 13:37:23 +0200 Subject: [PATCH 465/739] Python: Rewrite inline expectation tests to use parameterized module --- .../dataflow/calls/DataFlowCallTest.expected | 2 ++ .../dataflow/calls/DataFlowCallTest.ql | 10 +++++----- .../dataflow/global-flow/accesses.expected | 2 ++ .../dataflow/global-flow/accesses.ql | 18 ++++++++---------- .../TestSensitiveDataSources.expected | 2 ++ .../sensitive-data/TestSensitiveDataSources.ql | 10 +++++----- .../variable-capture/CaptureTest.expected | 2 ++ .../dataflow/variable-capture/CaptureTest.ql | 10 +++++----- .../import-resolution/importflow.expected | 2 ++ .../import-resolution/importflow.ql | 18 ++++++++---------- .../import-resolution/imports.expected | 2 ++ .../experimental/import-resolution/imports.ql | 18 ++++++++---------- .../InlineCallGraphTest.expected | 1 + .../InlineCallGraphTest.expected | 1 + .../CallGraph/InlineCallGraphTest.expected | 1 + .../CallGraph/InlineCallGraphTest.ql | 10 +++++----- .../library-tests/ApiGraphs/py2/use.expected | 2 ++ .../ql/test/library-tests/ApiGraphs/py2/use.ql | 14 +++++++------- .../missing-relevant-tag/Test.expected | 2 ++ .../missing-relevant-tag/Test.ql | 10 +++++----- .../essa/ssa-compute/UseUse.expected | 2 ++ .../library-tests/essa/ssa-compute/UseUse.ql | 10 +++++----- .../PoorMansFunctionResolutionTest.expected | 2 ++ .../PoorMansFunctionResolutionTest.ql | 10 +++++----- .../test.expected | 2 ++ .../ModificationOfParameterWithDefault/test.ql | 14 +++++++------- .../ExceptionInfo.expected | 2 ++ .../ExceptionInfo.ql | 10 +++++----- 28 files changed, 105 insertions(+), 84 deletions(-) diff --git a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected b/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected +++ b/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.ql b/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.ql index d939b3092e4..6e992d6e035 100644 --- a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.ql +++ b/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.ql @@ -4,16 +4,14 @@ import semmle.python.dataflow.new.internal.DataFlowDispatch as DataFlowDispatch import TestUtilities.InlineExpectationsTest private import semmle.python.dataflow.new.internal.PrintNode -class DataFlowCallTest extends InlineExpectationsTest { - DataFlowCallTest() { this = "DataFlowCallTest" } - - override string getARelevantTag() { +module DataFlowCallTest implements TestSig { + string getARelevantTag() { result in ["call", "callType"] or result = "arg[" + any(DataFlowDispatch::ArgumentPosition pos).toString() + "]" } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(DataFlowDispatch::DataFlowCall call | location = call.getLocation() and @@ -35,3 +33,5 @@ class DataFlowCallTest extends InlineExpectationsTest { ) } } + +import MakeTest<DataFlowCallTest> diff --git a/python/ql/test/experimental/dataflow/global-flow/accesses.expected b/python/ql/test/experimental/dataflow/global-flow/accesses.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/global-flow/accesses.expected +++ b/python/ql/test/experimental/dataflow/global-flow/accesses.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/global-flow/accesses.ql b/python/ql/test/experimental/dataflow/global-flow/accesses.ql index 9344c0eb8c2..5d65758ec14 100644 --- a/python/ql/test/experimental/dataflow/global-flow/accesses.ql +++ b/python/ql/test/experimental/dataflow/global-flow/accesses.ql @@ -2,12 +2,10 @@ import python import semmle.python.dataflow.new.DataFlow import TestUtilities.InlineExpectationsTest -class GlobalReadTest extends InlineExpectationsTest { - GlobalReadTest() { this = "GlobalReadTest" } +module GlobalReadTest implements TestSig { + string getARelevantTag() { result = "reads" } - override string getARelevantTag() { result = "reads" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::ModuleVariableNode n, DataFlow::Node read | read = n.getARead() and value = n.getVariable().getId() and @@ -19,12 +17,10 @@ class GlobalReadTest extends InlineExpectationsTest { } } -class GlobalWriteTest extends InlineExpectationsTest { - GlobalWriteTest() { this = "GlobalWriteTest" } +module GlobalWriteTest implements TestSig { + string getARelevantTag() { result = "writes" } - override string getARelevantTag() { result = "writes" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::ModuleVariableNode n, DataFlow::Node read | read = n.getAWrite() and value = n.getVariable().getId() and @@ -34,3 +30,5 @@ class GlobalWriteTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<GlobalReadTest, GlobalWriteTest>> diff --git a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected b/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected +++ b/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.ql b/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.ql index f2cd5684f3a..601ece30c35 100644 --- a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.ql +++ b/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.ql @@ -8,12 +8,10 @@ import TestUtilities.InlineExpectationsTest import semmle.python.dataflow.new.SensitiveDataSources private import semmle.python.ApiGraphs -class SensitiveDataSourcesTest extends InlineExpectationsTest { - SensitiveDataSourcesTest() { this = "SensitiveDataSourcesTest" } +module SensitiveDataSourcesTest implements TestSig { + string getARelevantTag() { result in ["SensitiveDataSource", "SensitiveUse"] } - override string getARelevantTag() { result in ["SensitiveDataSource", "SensitiveUse"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(SensitiveDataSource source | location = source.getLocation() and @@ -32,6 +30,8 @@ class SensitiveDataSourcesTest extends InlineExpectationsTest { } } +import MakeTest<SensitiveDataSourcesTest> + class SensitiveUseConfiguration extends TaintTracking::Configuration { SensitiveUseConfiguration() { this = "SensitiveUseConfiguration" } diff --git a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected b/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected +++ b/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql b/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql index 015bef4056c..68d15822cf6 100644 --- a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql +++ b/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql @@ -3,12 +3,10 @@ import semmle.python.dataflow.new.DataFlow import TestUtilities.InlineExpectationsTest import experimental.dataflow.testConfig -class CaptureTest extends InlineExpectationsTest { - CaptureTest() { this = "CaptureTest" } +module CaptureTest implements TestSig { + string getARelevantTag() { result = "captured" } - override string getARelevantTag() { result = "captured" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Node sink | exists(TestConfiguration cfg | cfg.hasFlowTo(sink)) | location = sink.getLocation() and tag = "captured" and @@ -17,3 +15,5 @@ class CaptureTest extends InlineExpectationsTest { ) } } + +import MakeTest<CaptureTest> diff --git a/python/ql/test/experimental/import-resolution/importflow.expected b/python/ql/test/experimental/import-resolution/importflow.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/import-resolution/importflow.expected +++ b/python/ql/test/experimental/import-resolution/importflow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index afb2278d1c5..aa34551c3b6 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -72,12 +72,10 @@ private class ImportConfiguration extends DataFlow::Configuration { } } -class ResolutionTest extends InlineExpectationsTest { - ResolutionTest() { this = "ResolutionTest" } +module ResolutionTest implements TestSig { + string getARelevantTag() { result = "prints" } - override string getARelevantTag() { result = "prints" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { ( exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | config.hasFlowPath(source, sink) and @@ -105,12 +103,10 @@ private string getTagForVersion(int version) { version = major_version() } -class VersionSpecificResolutionTest extends InlineExpectationsTest { - VersionSpecificResolutionTest() { this = "VersionSpecificResolutionTest" } +module VersionSpecificResolutionTest implements TestSig { + string getARelevantTag() { result = getTagForVersion(_) } - override string getARelevantTag() { result = getTagForVersion(_) } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { ( exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config | config.hasFlowPath(source, sink) and @@ -130,3 +126,5 @@ class VersionSpecificResolutionTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<ResolutionTest, VersionSpecificResolutionTest>> diff --git a/python/ql/test/experimental/import-resolution/imports.expected b/python/ql/test/experimental/import-resolution/imports.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/import-resolution/imports.expected +++ b/python/ql/test/experimental/import-resolution/imports.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/import-resolution/imports.ql b/python/ql/test/experimental/import-resolution/imports.ql index e5d357c5ef4..48a8a411665 100644 --- a/python/ql/test/experimental/import-resolution/imports.ql +++ b/python/ql/test/experimental/import-resolution/imports.ql @@ -18,12 +18,10 @@ private class ImmediateModuleRef extends DataFlow::Node { string getAsname() { result = alias } } -class ImportTest extends InlineExpectationsTest { - ImportTest() { this = "ImportTest" } +module ImportTest implements TestSig { + string getARelevantTag() { result = "imports" } - override string getARelevantTag() { result = "imports" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(ImmediateModuleRef ref | tag = "imports" and location = ref.getLocation() and @@ -33,12 +31,10 @@ class ImportTest extends InlineExpectationsTest { } } -class AliasTest extends InlineExpectationsTest { - AliasTest() { this = "AliasTest" } +module AliasTest implements TestSig { + string getARelevantTag() { result = "as" } - override string getARelevantTag() { result = "as" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(ImmediateModuleRef ref | tag = "as" and location = ref.getLocation() and @@ -47,3 +43,5 @@ class AliasTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<ImportTest, AliasTest>> diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected index d5ed453c51a..de783b3bdcb 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected +++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected @@ -1,4 +1,5 @@ failures +testFailures debug_callableNotUnique pointsTo_found_typeTracker_notFound typeTracker_found_pointsTo_notFound diff --git a/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected index d5ed453c51a..de783b3bdcb 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected +++ b/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected @@ -1,4 +1,5 @@ failures +testFailures debug_callableNotUnique pointsTo_found_typeTracker_notFound typeTracker_found_pointsTo_notFound diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected index 62d713fce6d..31987baf6d7 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected @@ -1,4 +1,5 @@ failures +testFailures debug_callableNotUnique pointsTo_found_typeTracker_notFound | code/class_attr_assign.py:10:9:10:27 | ControlFlowNode for Attribute() | my_func | diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql index fa658d892f0..42a7d90af5a 100644 --- a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql +++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.ql @@ -37,12 +37,10 @@ predicate typeTrackerClassCall(CallNode call, Function callable) { ) } -class CallGraphTest extends InlineExpectationsTest { - CallGraphTest() { this = "CallGraphTest" } +module CallGraphTest implements TestSig { + string getARelevantTag() { result in ["pt", "tt"] } - override string getARelevantTag() { result in ["pt", "tt"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(CallNode call, Function target | tag = "tt" and @@ -58,6 +56,8 @@ class CallGraphTest extends InlineExpectationsTest { } } +import MakeTest<CallGraphTest> + bindingset[call, target] string getCallEdgeValue(CallNode call, Function target) { if call.getLocation().getFile() = target.getLocation().getFile() diff --git a/python/ql/test/library-tests/ApiGraphs/py2/use.expected b/python/ql/test/library-tests/ApiGraphs/py2/use.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/ApiGraphs/py2/use.expected +++ b/python/ql/test/library-tests/ApiGraphs/py2/use.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/ApiGraphs/py2/use.ql b/python/ql/test/library-tests/ApiGraphs/py2/use.ql index 7a4301a14fb..c89ad1c5196 100644 --- a/python/ql/test/library-tests/ApiGraphs/py2/use.ql +++ b/python/ql/test/library-tests/ApiGraphs/py2/use.ql @@ -3,22 +3,20 @@ import semmle.python.dataflow.new.DataFlow import TestUtilities.InlineExpectationsTest import semmle.python.ApiGraphs -class ApiUseTest extends InlineExpectationsTest { - ApiUseTest() { this = "ApiUseTest" } - - override string getARelevantTag() { result = "use" } +module ApiUseTest implements TestSig { + string getARelevantTag() { result = "use" } private predicate relevant_node(API::Node a, DataFlow::Node n, Location l) { n = a.getAValueReachableFromSource() and l = n.getLocation() } - override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(DataFlow::Node n | this.relevant_node(_, n, location) | + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node n | relevant_node(_, n, location) | tag = "use" and // Only report the longest path on this line: value = max(API::Node a2, Location l2 | - this.relevant_node(a2, _, l2) and + relevant_node(a2, _, l2) and l2.getFile() = location.getFile() and l2.getStartLine() = location.getStartLine() | @@ -28,3 +26,5 @@ class ApiUseTest extends InlineExpectationsTest { ) } } + +import MakeTest<ApiUseTest> diff --git a/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected b/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected index 561ab92d635..2cd3654766b 100644 --- a/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected +++ b/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected @@ -1,2 +1,4 @@ +failures +testFailures | test.py:1:1:1:3 | foo | Tag mismatch: Actual result with tag 'foo' that is not part of getARelevantTag() | | test.py:4:1:4:3 | foo | Tag mismatch: Actual result with tag 'foo' that is not part of getARelevantTag() | diff --git a/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.ql b/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.ql index 6d36f279e50..e4694ffc10d 100644 --- a/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.ql +++ b/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.ql @@ -4,12 +4,10 @@ import python import TestUtilities.InlineExpectationsTest -class MissingRelevantTag extends InlineExpectationsTest { - MissingRelevantTag() { this = "MissingRelevantTag" } +module MissingRelevantTag implements TestSig { + string getARelevantTag() { none() } - override string getARelevantTag() { none() } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Name name | name.getId() = "foo" | location = name.getLocation() and element = name.toString() and @@ -18,3 +16,5 @@ class MissingRelevantTag extends InlineExpectationsTest { ) } } + +import MakeTest<MissingRelevantTag> diff --git a/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected b/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected +++ b/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/essa/ssa-compute/UseUse.ql b/python/ql/test/library-tests/essa/ssa-compute/UseUse.ql index 5ce82f81769..4635dda09f8 100644 --- a/python/ql/test/library-tests/essa/ssa-compute/UseUse.ql +++ b/python/ql/test/library-tests/essa/ssa-compute/UseUse.ql @@ -2,12 +2,10 @@ import python import semmle.python.essa.SsaCompute import TestUtilities.InlineExpectationsTest -class UseTest extends InlineExpectationsTest { - UseTest() { this = "UseTest" } +module UseTest implements TestSig { + string getARelevantTag() { result in ["use-use", "def-use", "def"] } - override string getARelevantTag() { result in ["use-use", "def-use", "def"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(string name | name in ["x", "y"] | exists(NameNode nodeTo, Location prevLoc | @@ -39,3 +37,5 @@ class UseTest extends InlineExpectationsTest { ) } } + +import MakeTest<UseTest> diff --git a/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected b/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected +++ b/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.ql b/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.ql index 90983bfd59b..338d6853a74 100644 --- a/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.ql +++ b/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.ql @@ -3,12 +3,10 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.frameworks.internal.PoorMansFunctionResolution import TestUtilities.InlineExpectationsTest -class InlinePoorMansFunctionResolutionTest extends InlineExpectationsTest { - InlinePoorMansFunctionResolutionTest() { this = "InlinePoorMansFunctionResolutionTest" } +module InlinePoorMansFunctionResolutionTest implements TestSig { + string getARelevantTag() { result = "resolved" } - override string getARelevantTag() { result = "resolved" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Function func, DataFlow::Node ref | ref = poorMansFunctionTracker(func) and @@ -26,3 +24,5 @@ class InlinePoorMansFunctionResolutionTest extends InlineExpectationsTest { ) } } + +import MakeTest<InlinePoorMansFunctionResolutionTest> diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql index 3e4853b7b20..97a01fd4b5f 100644 --- a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql @@ -4,17 +4,15 @@ import TestUtilities.InlineExpectationsTest import semmle.python.functions.ModificationOfParameterWithDefault private import semmle.python.dataflow.new.internal.PrintNode -class ModificationOfParameterWithDefaultTest extends InlineExpectationsTest { - ModificationOfParameterWithDefaultTest() { this = "ModificationOfParameterWithDefaultTest" } +module ModificationOfParameterWithDefaultTest implements TestSig { + string getARelevantTag() { result = "modification" } - override string getARelevantTag() { result = "modification" } - - predicate relevant_node(DataFlow::Node sink) { + private predicate relevant_node(DataFlow::Node sink) { exists(ModificationOfParameterWithDefault::Configuration cfg | cfg.hasFlowTo(sink)) } - override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(DataFlow::Node n | this.relevant_node(n) | + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node n | relevant_node(n) | n.getLocation() = location and tag = "modification" and value = prettyNode(n) and @@ -22,3 +20,5 @@ class ModificationOfParameterWithDefaultTest extends InlineExpectationsTest { ) } } + +import MakeTest<ModificationOfParameterWithDefaultTest> diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected +++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.ql b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.ql index d4ce46b5cd8..eb837559386 100644 --- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.ql +++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.ql @@ -3,12 +3,10 @@ import semmle.python.dataflow.new.DataFlow import TestUtilities.InlineExpectationsTest import semmle.python.security.dataflow.ExceptionInfo -class ExceptionInfoTest extends InlineExpectationsTest { - ExceptionInfoTest() { this = "ExceptionInfoTest" } +module ExceptionInfoTest implements TestSig { + string getARelevantTag() { result = "exceptionInfo" } - override string getARelevantTag() { result = "exceptionInfo" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(ExceptionInfo e | location = e.getLocation() and @@ -18,3 +16,5 @@ class ExceptionInfoTest extends InlineExpectationsTest { ) } } + +import MakeTest<ExceptionInfoTest> From 9633f00ed193494a9fe0d802aff6677c115def9c Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Wed, 7 Jun 2023 13:51:09 +0200 Subject: [PATCH 466/739] QL-for-QL: Rewrite inline expectation tests to use parameterized module --- .../dataflow/getAStringValue/getAStringValue.expected | 2 ++ ql/ql/test/dataflow/getAStringValue/getAStringValue.ql | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ql/ql/test/dataflow/getAStringValue/getAStringValue.expected b/ql/ql/test/dataflow/getAStringValue/getAStringValue.expected index e69de29bb2d..48de9172b36 100644 --- a/ql/ql/test/dataflow/getAStringValue/getAStringValue.expected +++ b/ql/ql/test/dataflow/getAStringValue/getAStringValue.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/ql/ql/test/dataflow/getAStringValue/getAStringValue.ql b/ql/ql/test/dataflow/getAStringValue/getAStringValue.ql index 82534f535fe..fbd8bf0477f 100644 --- a/ql/ql/test/dataflow/getAStringValue/getAStringValue.ql +++ b/ql/ql/test/dataflow/getAStringValue/getAStringValue.ql @@ -2,12 +2,10 @@ import ql import codeql_ql.dataflow.DataFlow import TestUtilities.InlineExpectationsTest -class GetAStringValueTest extends InlineExpectationsTest { - GetAStringValueTest() { this = "getAStringValue" } +module GetAStringValueTest implements TestSig { + string getARelevantTag() { result = "getAStringValue" } - override string getARelevantTag() { result = "getAStringValue" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Expr e | e = any(Call c).getAnArgument() and tag = "getAStringValue" and @@ -17,3 +15,5 @@ class GetAStringValueTest extends InlineExpectationsTest { ) } } + +import MakeTest<GetAStringValueTest> From 4485560f4377482ec7e2f6e1343be2a5c09dda23 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Wed, 7 Jun 2023 13:51:23 +0200 Subject: [PATCH 467/739] Ruby: Rewrite inline expectation tests to use parameterized module --- .../concepts/CryptographicOperation.expected | 2 ++ .../concepts/CryptographicOperation.ql | 10 +++++----- .../dataflow/api-graphs/use.expected | 2 ++ .../library-tests/dataflow/api-graphs/use.ql | 18 +++++++++--------- .../barrier-guards/barrier-guards.expected | 1 + .../dataflow/barrier-guards/barrier-guards.ql | 10 +++++----- .../ImproperMemoization.expected | 1 + .../ImproperMemoization.ql | 10 +++++----- ...completeMultiCharacterSanitization.expected | 2 ++ .../IncompleteMultiCharacterSanitization.ql | 10 +++++----- .../cwe-300/InsecureDependency.expected | 1 + .../security/cwe-300/InsecureDependency.ql | 10 +++++----- 12 files changed, 43 insertions(+), 34 deletions(-) diff --git a/ruby/ql/test/library-tests/concepts/CryptographicOperation.expected b/ruby/ql/test/library-tests/concepts/CryptographicOperation.expected index e69de29bb2d..48de9172b36 100644 --- a/ruby/ql/test/library-tests/concepts/CryptographicOperation.expected +++ b/ruby/ql/test/library-tests/concepts/CryptographicOperation.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/ruby/ql/test/library-tests/concepts/CryptographicOperation.ql b/ruby/ql/test/library-tests/concepts/CryptographicOperation.ql index a9efedadbba..602ee166fce 100644 --- a/ruby/ql/test/library-tests/concepts/CryptographicOperation.ql +++ b/ruby/ql/test/library-tests/concepts/CryptographicOperation.ql @@ -2,17 +2,15 @@ import codeql.ruby.AST import codeql.ruby.Concepts import TestUtilities.InlineExpectationsTest -class CryptographicOperationTest extends InlineExpectationsTest { - CryptographicOperationTest() { this = "CryptographicOperationTest" } - - override string getARelevantTag() { +module CryptographicOperationTest implements TestSig { + string getARelevantTag() { result in [ "CryptographicOperation", "CryptographicOperationInput", "CryptographicOperationAlgorithm", "CryptographicOperationBlockMode" ] } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Cryptography::CryptographicOperation cryptoOperation | location = cryptoOperation.getLocation() and ( @@ -31,3 +29,5 @@ class CryptographicOperationTest extends InlineExpectationsTest { ) } } + +import MakeTest<CryptographicOperationTest> diff --git a/ruby/ql/test/library-tests/dataflow/api-graphs/use.expected b/ruby/ql/test/library-tests/dataflow/api-graphs/use.expected index e69de29bb2d..48de9172b36 100644 --- a/ruby/ql/test/library-tests/dataflow/api-graphs/use.expected +++ b/ruby/ql/test/library-tests/dataflow/api-graphs/use.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/ruby/ql/test/library-tests/dataflow/api-graphs/use.ql b/ruby/ql/test/library-tests/dataflow/api-graphs/use.ql index cbb9d85314e..a0c11640ce0 100644 --- a/ruby/ql/test/library-tests/dataflow/api-graphs/use.ql +++ b/ruby/ql/test/library-tests/dataflow/api-graphs/use.ql @@ -17,10 +17,8 @@ class CustomEntryPointUse extends API::EntryPoint { } } -class ApiUseTest extends InlineExpectationsTest { - ApiUseTest() { this = "ApiUseTest" } - - override string getARelevantTag() { result = ["use", "def", "call"] } +module ApiUseTest implements TestSig { + string getARelevantTag() { result = ["use", "def", "call"] } private predicate relevantNode(API::Node a, DataFlow::Node n, Location l, string tag) { l = n.getLocation() and @@ -36,13 +34,13 @@ class ApiUseTest extends InlineExpectationsTest { ) } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "use" and // def tags are always optional - exists(DataFlow::Node n | this.relevantNode(_, n, location, tag) | + exists(DataFlow::Node n | relevantNode(_, n, location, tag) | // Only report the longest path on this line: value = max(API::Node a2, Location l2, DataFlow::Node n2 | - this.relevantNode(a2, n2, l2, tag) and + relevantNode(a2, n2, l2, tag) and l2.getFile() = location.getFile() and l2.getEndLine() = location.getEndLine() | @@ -56,14 +54,16 @@ class ApiUseTest extends InlineExpectationsTest { // We also permit optional annotations for any other path on the line. // This is used to test subclass paths, which typically have a shorter canonical path. - override predicate hasOptionalResult(Location location, string element, string tag, string value) { - exists(API::Node a, DataFlow::Node n | this.relevantNode(a, n, location, tag) | + predicate hasOptionalResult(Location location, string element, string tag, string value) { + exists(API::Node a, DataFlow::Node n | relevantNode(a, n, location, tag) | element = n.toString() and value = getAPath(a, _) ) } } +import MakeTest<ApiUseTest> + private int size(AstNode n) { not n instanceof StmtSequence and result = count(n.getAChild*()) } /** diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected index ded17452785..3cbbb4a5f4a 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -1,5 +1,6 @@ WARNING: Type BarrierGuard has been deprecated and may be removed in future (barrier-guards.ql:10,3-15) failures +testFailures oldStyleBarrierGuards | barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | barrier-guards.rb:3:4:3:6 | foo | true | | barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | barrier-guards.rb:3:11:3:15 | "foo" | true | diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql index ff2f0bc76f4..0c8ba907734 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql @@ -24,12 +24,10 @@ query predicate controls(CfgNode condition, BasicBlock bb, SuccessorTypes::Condi ) } -class BarrierGuardTest extends InlineExpectationsTest { - BarrierGuardTest() { this = "BarrierGuardTest" } +module BarrierGuardTest implements TestSig { + string getARelevantTag() { result = "guarded" } - override string getARelevantTag() { result = "guarded" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "guarded" and exists(DataFlow::Node n | newStyleBarrierGuards(n) and @@ -39,3 +37,5 @@ class BarrierGuardTest extends InlineExpectationsTest { ) } } + +import MakeTest<BarrierGuardTest> diff --git a/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.expected b/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.expected index 717539ce87a..86c29d64b6e 100644 --- a/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.expected +++ b/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.expected @@ -1,4 +1,5 @@ failures +testFailures | improper_memoization.rb:100:1:104:3 | m14 | Unexpected result: result=BAD | #select | improper_memoization.rb:50:1:55:3 | m7 | improper_memoization.rb:50:8:50:10 | arg | improper_memoization.rb:51:3:53:5 | ... \|\|= ... | diff --git a/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.ql b/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.ql index d41e7b262b7..d1056f7cd12 100644 --- a/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.ql +++ b/ruby/ql/test/query-tests/experimental/improper-memoization/ImproperMemoization.ql @@ -2,12 +2,10 @@ import codeql.ruby.AST import TestUtilities.InlineExpectationsTest import codeql.ruby.security.ImproperMemoizationQuery -class ImproperMemoizationTest extends InlineExpectationsTest { - ImproperMemoizationTest() { this = "ImproperMemoizationTest" } +module ImproperMemoizationTest implements TestSig { + string getARelevantTag() { result = "result" } - override string getARelevantTag() { result = "result" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "result" and value = "BAD" and exists(Expr e | @@ -18,6 +16,8 @@ class ImproperMemoizationTest extends InlineExpectationsTest { } } +import MakeTest<ImproperMemoizationTest> + from Method m, Parameter p, AssignLogicalOrExpr s where isImproperMemoizationMethod(m, p, s) select m, p, s diff --git a/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.expected b/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.expected index e69de29bb2d..48de9172b36 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.expected +++ b/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.ql b/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.ql index 391452b246a..b9b447f00ee 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.ql +++ b/ruby/ql/test/query-tests/security/cwe-116/IncompleteMultiCharacterSanitization/IncompleteMultiCharacterSanitization.ql @@ -8,17 +8,17 @@ import codeql.ruby.DataFlow import codeql.ruby.security.IncompleteMultiCharacterSanitizationQuery as Query import TestUtilities.InlineExpectationsTest -class Test extends InlineExpectationsTest { - Test() { this = "IncompleteMultiCharacterSanitizationTest" } +module Test implements TestSig { + string getARelevantTag() { result = "hasResult" } - override string getARelevantTag() { result = "hasResult" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasResult" and hasResult(location, element, value) } } +import MakeTest<Test> + predicate hasResult(Location location, string element, string value) { exists(DataFlow::Node replace, string kind | replace.getLocation() = location and diff --git a/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.expected b/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.expected index 94e588e4bdf..d123230e55d 100644 --- a/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.expected +++ b/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.expected @@ -1,4 +1,5 @@ failures +testFailures #select | Gemfile:2:8:2:28 | "http://rubygems.org" | Dependency source URL uses the unencrypted protocol HTTP. Use HTTPS instead. | | Gemfile:3:8:3:27 | "ftp://rubygems.org" | Dependency source URL uses the unencrypted protocol FTP. Use FTPS or SFTP instead. | diff --git a/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.ql b/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.ql index e6169220f33..75bf5dce16d 100644 --- a/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.ql +++ b/ruby/ql/test/query-tests/security/cwe-300/InsecureDependency.ql @@ -2,12 +2,10 @@ import codeql.ruby.AST import TestUtilities.InlineExpectationsTest import codeql.ruby.security.InsecureDependencyQuery -class InsecureDependencyTest extends InlineExpectationsTest { - InsecureDependencyTest() { this = "InsecureDependencyTest" } +module InsecureDependencyTest implements TestSig { + string getARelevantTag() { result = "result" } - override string getARelevantTag() { result = "result" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "result" and value = "BAD" and exists(Expr e | @@ -18,6 +16,8 @@ class InsecureDependencyTest extends InlineExpectationsTest { } } +import MakeTest<InsecureDependencyTest> + from Expr url, string msg where insecureDependencyUrl(url, msg) select url, msg From bf3677df16434943fde46f691bc96ae0408675a3 Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Fri, 9 Jun 2023 11:10:32 +0200 Subject: [PATCH 468/739] C#: Make sure System.Private.CoreLib is added only once as a reference in standalone extraction --- .../BuildAnalysis.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs index 47bdd3ae568..fc974c7ded6 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs @@ -100,6 +100,18 @@ namespace Semmle.BuildAnalyser dllDirNames.Add(runtimeLocation); } + if (options.UseMscorlib) + { + // Add mscorlib.dll or System.Private.CoreLib.dll to the list of DLLs to reference. + var loc = typeof(object).Assembly.Location; + var dir = Path.GetDirectoryName(loc); + if (dir != null) + { + progressMonitor.Log(Util.Logging.Severity.Debug, $"Adding folder {dir} to DLL search path."); + dllDirNames.Add(dir); + } + } + // These files can sometimes prevent `dotnet restore` from working correctly. using (new FileRenamer(sourceDir.GetFiles("global.json", SearchOption.AllDirectories))) using (new FileRenamer(sourceDir.GetFiles("Directory.Build.props", SearchOption.AllDirectories))) @@ -122,11 +134,6 @@ namespace Semmle.BuildAnalyser ResolveConflicts(); - if (options.UseMscorlib) - { - UseReference(typeof(object).Assembly.Location); - } - // Output the findings foreach (var r in usedReferences.Keys) { From 5510d050c145d1b3d6fa20da8f9f8a2f833e204f Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 9 Jun 2023 11:40:04 +0200 Subject: [PATCH 469/739] C#: Synthetic names only needs to rely on the output stack. --- .../csharp/frameworks/EntityFramework.qll | 40 +-- .../EntityFramework/FlowSummaries.expected | 316 ++++++++---------- 2 files changed, 153 insertions(+), 203 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 4a636afbfbd..6030537aa65 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -371,12 +371,14 @@ module EntityFramework { } pragma[nomagic] - string getInputSynthetic(SummaryComponentStack output, DbContextClassSetProperty p) { - exists(SummaryComponentStack synthetic, Property mapped | - this = p.getDbContextClass() and - input(this, synthetic, mapped) and - output(this, output, mapped, p) and - result = getFullSyntheticName(p.getSyntheticName(), synthetic, output) + string getSyntheticNames( + SummaryComponentStack input, SummaryComponentStack output, DbContextClassSetProperty dbSet + ) { + exists(Property mapped | + this = dbSet.getDbContextClass() and + input(this, input, mapped) and + output(this, output, mapped, dbSet) and + result = dbSet.getSyntheticName() + "#" + SummaryComponentStack::getComponentStack(output) ) } } @@ -433,16 +435,6 @@ module EntityFramework { ) } - bindingset[prop, stack1, stack2] - private string getFullSyntheticName( - string prop, SummaryComponentStack stack1, SummaryComponentStack stack2 - ) { - result = - prop + "#" // - + SummaryComponentStack::getComponentStack(stack1) + "#" // - + SummaryComponentStack::getComponentStack(stack2) - } - private class DbContextClassSetPropertySynthetic extends EFSummarizedCallable { private DbContextClassSetProperty p; @@ -453,7 +445,7 @@ module EntityFramework { ) { exists(string name, DbContextClass c | preservesValue = true and - name = c.getInputSynthetic(output, p) and + name = c.getSyntheticNames(_, output, p) and input = SummaryComponentStack::syntheticGlobal(name) ) } @@ -464,21 +456,12 @@ module EntityFramework { DbContextSaveChanges() { this = c.getASaveChanges() } - pragma[nomagic] - string getOutputSynthetic(SummaryComponentStack input) { - exists(SummaryComponentStack synthetic, Property mapped, DbContextClassSetProperty dbSet | - input(c, input, mapped) and - output(c, synthetic, mapped, dbSet) and - result = getFullSyntheticName(dbSet.getSyntheticName(), input, synthetic) - ) - } - override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { exists(string name | preservesValue = true and - name = this.getOutputSynthetic(input) and + name = c.getSyntheticNames(input, _, _) and output = SummaryComponentStack::syntheticGlobal(name) ) } @@ -489,8 +472,7 @@ module EntityFramework { */ private class EFSummarizedCallableSyntheticGlobal extends SummaryComponent::SyntheticGlobal { EFSummarizedCallableSyntheticGlobal() { - this = any(DbContextClass c).getInputSynthetic(_, _) or - this = any(DbContextSaveChanges c).getOutputSynthetic(_) + this = any(DbContextClass c).getSyntheticNames(_, _, _) } } diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected index a5a2f0ac120..820aca482f3 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected @@ -1,178 +1,146 @@ summary -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | -| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | -| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id]#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | -| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name]#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId]#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id]#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | -| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name]#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Id]];ReturnValue.Element.Property[EFCoreTests.Person.Id];value;manual | +| EFCoreTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Name]];ReturnValue.Element.Property[EFCoreTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Addresses;();;SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_PersonAddresses;();;SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Id]];ReturnValue.Element.Property[EFTests.Person.Id];value;manual | +| EFTests;MyContext;false;get_Persons;();;SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Name]];ReturnValue.Element.Property[EFTests.Person.Name];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChanges;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.AddressId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.AddressId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.PersonId];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.PersonId]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Addresses#ReturnValue.Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Address].Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Addresses].Element.Property[EFCoreTests.Address.Street]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Id]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name]];value;manual | +| Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];SyntheticGlobal[EFCoreTests.MyContext.Persons#ReturnValue.Element.Property[EFCoreTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.AddressId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.AddressId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.PersonId];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.PersonId]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Addresses#ReturnValue.Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Street]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Id]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.PersonAddresses#ReturnValue.Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name]];value;manual | +| System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];SyntheticGlobal[EFTests.MyContext.Persons#ReturnValue.Element.Property[EFTests.Person.Name]];value;manual | neutral sourceNode sinkNode From a50d91ea48daf16418cc31f64740f6daa7b379bd Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 9 Jun 2023 14:31:10 +0200 Subject: [PATCH 470/739] Ruby: fix bug in filter_map summary --- .../lib/codeql/ruby/frameworks/core/Array.qll | 6 +- .../dataflow/array-flow/array-flow.expected | 12145 ++++++++-------- .../dataflow/array-flow/array_flow.rb | 15 +- 3 files changed, 6100 insertions(+), 6066 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Array.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Array.qll index a1007f9806a..a6f5a5e36ff 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Array.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Array.qll @@ -2067,7 +2067,11 @@ module Enumerable { override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { input = "Argument[self].Element[any]" and - output = ["Argument[block].Parameter[0]", "ReturnValue.Element[?]"] and + output = "Argument[block].Parameter[0]" and + preservesValue = true + or + input = "Argument[block].ReturnValue" and + output = "ReturnValue.Element[?]" and preservesValue = true } } diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected index f1d10325a46..d258253537a 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected @@ -1125,270 +1125,252 @@ edges | array_flow.rb:506:5:506:5 | a [element 3] | array_flow.rb:507:9:507:9 | a [element 3] | | array_flow.rb:506:19:506:28 | call to source | array_flow.rb:506:5:506:5 | a [element 3] | | array_flow.rb:506:19:506:28 | call to source | array_flow.rb:506:5:506:5 | a [element 3] | -| array_flow.rb:507:5:507:5 | b [element] | array_flow.rb:510:10:510:10 | b [element] | -| array_flow.rb:507:5:507:5 | b [element] | array_flow.rb:510:10:510:10 | b [element] | -| array_flow.rb:507:9:507:9 | a [element 3] | array_flow.rb:507:9:509:7 | call to filter_map [element] | -| array_flow.rb:507:9:507:9 | a [element 3] | array_flow.rb:507:9:509:7 | call to filter_map [element] | +| array_flow.rb:507:5:507:5 | b [element] | array_flow.rb:511:10:511:10 | b [element] | +| array_flow.rb:507:5:507:5 | b [element] | array_flow.rb:511:10:511:10 | b [element] | +| array_flow.rb:507:9:507:9 | a [element 3] | array_flow.rb:507:9:510:7 | call to filter_map [element] | +| array_flow.rb:507:9:507:9 | a [element 3] | array_flow.rb:507:9:510:7 | call to filter_map [element] | | array_flow.rb:507:9:507:9 | a [element 3] | array_flow.rb:507:26:507:26 | x | | array_flow.rb:507:9:507:9 | a [element 3] | array_flow.rb:507:26:507:26 | x | -| array_flow.rb:507:9:509:7 | call to filter_map [element] | array_flow.rb:507:5:507:5 | b [element] | -| array_flow.rb:507:9:509:7 | call to filter_map [element] | array_flow.rb:507:5:507:5 | b [element] | +| array_flow.rb:507:9:510:7 | call to filter_map [element] | array_flow.rb:507:5:507:5 | b [element] | +| array_flow.rb:507:9:510:7 | call to filter_map [element] | array_flow.rb:507:5:507:5 | b [element] | | array_flow.rb:507:26:507:26 | x | array_flow.rb:508:14:508:14 | x | | array_flow.rb:507:26:507:26 | x | array_flow.rb:508:14:508:14 | x | -| array_flow.rb:510:10:510:10 | b [element] | array_flow.rb:510:10:510:13 | ...[...] | -| array_flow.rb:510:10:510:10 | b [element] | array_flow.rb:510:10:510:13 | ...[...] | -| array_flow.rb:514:5:514:5 | a [element 3] | array_flow.rb:515:9:515:9 | a [element 3] | -| array_flow.rb:514:5:514:5 | a [element 3] | array_flow.rb:515:9:515:9 | a [element 3] | -| array_flow.rb:514:19:514:28 | call to source | array_flow.rb:514:5:514:5 | a [element 3] | -| array_flow.rb:514:19:514:28 | call to source | array_flow.rb:514:5:514:5 | a [element 3] | -| array_flow.rb:515:5:515:5 | b [element] | array_flow.rb:520:10:520:10 | b [element] | -| array_flow.rb:515:5:515:5 | b [element] | array_flow.rb:520:10:520:10 | b [element] | -| array_flow.rb:515:9:515:9 | [post] a [element] | array_flow.rb:519:10:519:10 | a [element] | -| array_flow.rb:515:9:515:9 | [post] a [element] | array_flow.rb:519:10:519:10 | a [element] | -| array_flow.rb:515:9:515:9 | a [element 3] | array_flow.rb:515:9:515:9 | [post] a [element] | -| array_flow.rb:515:9:515:9 | a [element 3] | array_flow.rb:515:9:515:9 | [post] a [element] | -| array_flow.rb:515:9:515:9 | a [element 3] | array_flow.rb:515:9:518:7 | call to filter! [element] | -| array_flow.rb:515:9:515:9 | a [element 3] | array_flow.rb:515:9:518:7 | call to filter! [element] | -| array_flow.rb:515:9:515:9 | a [element 3] | array_flow.rb:515:23:515:23 | x | -| array_flow.rb:515:9:515:9 | a [element 3] | array_flow.rb:515:23:515:23 | x | -| array_flow.rb:515:9:518:7 | call to filter! [element] | array_flow.rb:515:5:515:5 | b [element] | -| array_flow.rb:515:9:518:7 | call to filter! [element] | array_flow.rb:515:5:515:5 | b [element] | -| array_flow.rb:515:23:515:23 | x | array_flow.rb:516:14:516:14 | x | -| array_flow.rb:515:23:515:23 | x | array_flow.rb:516:14:516:14 | x | -| array_flow.rb:519:10:519:10 | a [element] | array_flow.rb:519:10:519:13 | ...[...] | -| array_flow.rb:519:10:519:10 | a [element] | array_flow.rb:519:10:519:13 | ...[...] | -| array_flow.rb:520:10:520:10 | b [element] | array_flow.rb:520:10:520:13 | ...[...] | -| array_flow.rb:520:10:520:10 | b [element] | array_flow.rb:520:10:520:13 | ...[...] | -| array_flow.rb:524:5:524:5 | a [element 3] | array_flow.rb:525:9:525:9 | a [element 3] | -| array_flow.rb:524:5:524:5 | a [element 3] | array_flow.rb:525:9:525:9 | a [element 3] | -| array_flow.rb:524:19:524:30 | call to source | array_flow.rb:524:5:524:5 | a [element 3] | -| array_flow.rb:524:19:524:30 | call to source | array_flow.rb:524:5:524:5 | a [element 3] | -| array_flow.rb:525:5:525:5 | b | array_flow.rb:528:10:528:10 | b | -| array_flow.rb:525:5:525:5 | b | array_flow.rb:528:10:528:10 | b | -| array_flow.rb:525:9:525:9 | a [element 3] | array_flow.rb:525:9:527:7 | call to find | -| array_flow.rb:525:9:525:9 | a [element 3] | array_flow.rb:525:9:527:7 | call to find | -| array_flow.rb:525:9:525:9 | a [element 3] | array_flow.rb:525:41:525:41 | x | -| array_flow.rb:525:9:525:9 | a [element 3] | array_flow.rb:525:41:525:41 | x | -| array_flow.rb:525:9:527:7 | call to find | array_flow.rb:525:5:525:5 | b | -| array_flow.rb:525:9:527:7 | call to find | array_flow.rb:525:5:525:5 | b | -| array_flow.rb:525:21:525:32 | call to source | array_flow.rb:525:9:527:7 | call to find | -| array_flow.rb:525:21:525:32 | call to source | array_flow.rb:525:9:527:7 | call to find | -| array_flow.rb:525:41:525:41 | x | array_flow.rb:526:14:526:14 | x | -| array_flow.rb:525:41:525:41 | x | array_flow.rb:526:14:526:14 | x | -| array_flow.rb:532:5:532:5 | a [element 3] | array_flow.rb:533:9:533:9 | a [element 3] | -| array_flow.rb:532:5:532:5 | a [element 3] | array_flow.rb:533:9:533:9 | a [element 3] | -| array_flow.rb:532:19:532:28 | call to source | array_flow.rb:532:5:532:5 | a [element 3] | -| array_flow.rb:532:19:532:28 | call to source | array_flow.rb:532:5:532:5 | a [element 3] | -| array_flow.rb:533:5:533:5 | b [element] | array_flow.rb:536:10:536:10 | b [element] | -| array_flow.rb:533:5:533:5 | b [element] | array_flow.rb:536:10:536:10 | b [element] | -| array_flow.rb:533:9:533:9 | a [element 3] | array_flow.rb:533:9:535:7 | call to find_all [element] | -| array_flow.rb:533:9:533:9 | a [element 3] | array_flow.rb:533:9:535:7 | call to find_all [element] | -| array_flow.rb:533:9:533:9 | a [element 3] | array_flow.rb:533:24:533:24 | x | -| array_flow.rb:533:9:533:9 | a [element 3] | array_flow.rb:533:24:533:24 | x | -| array_flow.rb:533:9:535:7 | call to find_all [element] | array_flow.rb:533:5:533:5 | b [element] | -| array_flow.rb:533:9:535:7 | call to find_all [element] | array_flow.rb:533:5:533:5 | b [element] | -| array_flow.rb:533:24:533:24 | x | array_flow.rb:534:14:534:14 | x | -| array_flow.rb:533:24:533:24 | x | array_flow.rb:534:14:534:14 | x | -| array_flow.rb:536:10:536:10 | b [element] | array_flow.rb:536:10:536:13 | ...[...] | -| array_flow.rb:536:10:536:10 | b [element] | array_flow.rb:536:10:536:13 | ...[...] | -| array_flow.rb:540:5:540:5 | a [element 3] | array_flow.rb:541:5:541:5 | a [element 3] | -| array_flow.rb:540:5:540:5 | a [element 3] | array_flow.rb:541:5:541:5 | a [element 3] | -| array_flow.rb:540:19:540:28 | call to source | array_flow.rb:540:5:540:5 | a [element 3] | -| array_flow.rb:540:19:540:28 | call to source | array_flow.rb:540:5:540:5 | a [element 3] | -| array_flow.rb:541:5:541:5 | a [element 3] | array_flow.rb:541:22:541:22 | x | -| array_flow.rb:541:5:541:5 | a [element 3] | array_flow.rb:541:22:541:22 | x | -| array_flow.rb:541:22:541:22 | x | array_flow.rb:542:14:542:14 | x | -| array_flow.rb:541:22:541:22 | x | array_flow.rb:542:14:542:14 | x | -| array_flow.rb:547:5:547:5 | a [element 0] | array_flow.rb:549:10:549:10 | a [element 0] | -| array_flow.rb:547:5:547:5 | a [element 0] | array_flow.rb:549:10:549:10 | a [element 0] | -| array_flow.rb:547:5:547:5 | a [element 0] | array_flow.rb:550:9:550:9 | a [element 0] | -| array_flow.rb:547:5:547:5 | a [element 0] | array_flow.rb:550:9:550:9 | a [element 0] | -| array_flow.rb:547:5:547:5 | a [element 0] | array_flow.rb:553:9:553:9 | a [element 0] | -| array_flow.rb:547:5:547:5 | a [element 0] | array_flow.rb:553:9:553:9 | a [element 0] | -| array_flow.rb:547:5:547:5 | a [element 3] | array_flow.rb:553:9:553:9 | a [element 3] | -| array_flow.rb:547:5:547:5 | a [element 3] | array_flow.rb:553:9:553:9 | a [element 3] | -| array_flow.rb:547:10:547:21 | call to source | array_flow.rb:547:5:547:5 | a [element 0] | -| array_flow.rb:547:10:547:21 | call to source | array_flow.rb:547:5:547:5 | a [element 0] | -| array_flow.rb:547:30:547:41 | call to source | array_flow.rb:547:5:547:5 | a [element 3] | -| array_flow.rb:547:30:547:41 | call to source | array_flow.rb:547:5:547:5 | a [element 3] | -| array_flow.rb:548:5:548:5 | [post] a [element] | array_flow.rb:549:10:549:10 | a [element] | -| array_flow.rb:548:5:548:5 | [post] a [element] | array_flow.rb:549:10:549:10 | a [element] | -| array_flow.rb:548:5:548:5 | [post] a [element] | array_flow.rb:550:9:550:9 | a [element] | -| array_flow.rb:548:5:548:5 | [post] a [element] | array_flow.rb:550:9:550:9 | a [element] | -| array_flow.rb:548:5:548:5 | [post] a [element] | array_flow.rb:553:9:553:9 | a [element] | -| array_flow.rb:548:5:548:5 | [post] a [element] | array_flow.rb:553:9:553:9 | a [element] | -| array_flow.rb:548:12:548:23 | call to source | array_flow.rb:548:5:548:5 | [post] a [element] | -| array_flow.rb:548:12:548:23 | call to source | array_flow.rb:548:5:548:5 | [post] a [element] | -| array_flow.rb:549:10:549:10 | a [element 0] | array_flow.rb:549:10:549:16 | call to first | -| array_flow.rb:549:10:549:10 | a [element 0] | array_flow.rb:549:10:549:16 | call to first | -| array_flow.rb:549:10:549:10 | a [element] | array_flow.rb:549:10:549:16 | call to first | -| array_flow.rb:549:10:549:10 | a [element] | array_flow.rb:549:10:549:16 | call to first | -| array_flow.rb:550:5:550:5 | b [element 0] | array_flow.rb:551:10:551:10 | b [element 0] | -| array_flow.rb:550:5:550:5 | b [element 0] | array_flow.rb:551:10:551:10 | b [element 0] | -| array_flow.rb:550:5:550:5 | b [element] | array_flow.rb:551:10:551:10 | b [element] | -| array_flow.rb:550:5:550:5 | b [element] | array_flow.rb:551:10:551:10 | b [element] | -| array_flow.rb:550:5:550:5 | b [element] | array_flow.rb:552:10:552:10 | b [element] | -| array_flow.rb:550:5:550:5 | b [element] | array_flow.rb:552:10:552:10 | b [element] | -| array_flow.rb:550:9:550:9 | a [element 0] | array_flow.rb:550:9:550:18 | call to first [element 0] | -| array_flow.rb:550:9:550:9 | a [element 0] | array_flow.rb:550:9:550:18 | call to first [element 0] | -| array_flow.rb:550:9:550:9 | a [element] | array_flow.rb:550:9:550:18 | call to first [element] | -| array_flow.rb:550:9:550:9 | a [element] | array_flow.rb:550:9:550:18 | call to first [element] | -| array_flow.rb:550:9:550:18 | call to first [element 0] | array_flow.rb:550:5:550:5 | b [element 0] | -| array_flow.rb:550:9:550:18 | call to first [element 0] | array_flow.rb:550:5:550:5 | b [element 0] | -| array_flow.rb:550:9:550:18 | call to first [element] | array_flow.rb:550:5:550:5 | b [element] | -| array_flow.rb:550:9:550:18 | call to first [element] | array_flow.rb:550:5:550:5 | b [element] | -| array_flow.rb:551:10:551:10 | b [element 0] | array_flow.rb:551:10:551:13 | ...[...] | -| array_flow.rb:551:10:551:10 | b [element 0] | array_flow.rb:551:10:551:13 | ...[...] | -| array_flow.rb:551:10:551:10 | b [element] | array_flow.rb:551:10:551:13 | ...[...] | -| array_flow.rb:551:10:551:10 | b [element] | array_flow.rb:551:10:551:13 | ...[...] | -| array_flow.rb:552:10:552:10 | b [element] | array_flow.rb:552:10:552:13 | ...[...] | -| array_flow.rb:552:10:552:10 | b [element] | array_flow.rb:552:10:552:13 | ...[...] | -| array_flow.rb:553:5:553:5 | c [element 0] | array_flow.rb:554:10:554:10 | c [element 0] | -| array_flow.rb:553:5:553:5 | c [element 0] | array_flow.rb:554:10:554:10 | c [element 0] | -| array_flow.rb:553:5:553:5 | c [element 3] | array_flow.rb:555:10:555:10 | c [element 3] | -| array_flow.rb:553:5:553:5 | c [element 3] | array_flow.rb:555:10:555:10 | c [element 3] | -| array_flow.rb:553:5:553:5 | c [element] | array_flow.rb:554:10:554:10 | c [element] | -| array_flow.rb:553:5:553:5 | c [element] | array_flow.rb:554:10:554:10 | c [element] | -| array_flow.rb:553:5:553:5 | c [element] | array_flow.rb:555:10:555:10 | c [element] | -| array_flow.rb:553:5:553:5 | c [element] | array_flow.rb:555:10:555:10 | c [element] | -| array_flow.rb:553:9:553:9 | a [element 0] | array_flow.rb:553:9:553:18 | call to first [element 0] | -| array_flow.rb:553:9:553:9 | a [element 0] | array_flow.rb:553:9:553:18 | call to first [element 0] | -| array_flow.rb:553:9:553:9 | a [element 3] | array_flow.rb:553:9:553:18 | call to first [element 3] | -| array_flow.rb:553:9:553:9 | a [element 3] | array_flow.rb:553:9:553:18 | call to first [element 3] | -| array_flow.rb:553:9:553:9 | a [element] | array_flow.rb:553:9:553:18 | call to first [element] | -| array_flow.rb:553:9:553:9 | a [element] | array_flow.rb:553:9:553:18 | call to first [element] | -| array_flow.rb:553:9:553:18 | call to first [element 0] | array_flow.rb:553:5:553:5 | c [element 0] | -| array_flow.rb:553:9:553:18 | call to first [element 0] | array_flow.rb:553:5:553:5 | c [element 0] | -| array_flow.rb:553:9:553:18 | call to first [element 3] | array_flow.rb:553:5:553:5 | c [element 3] | -| array_flow.rb:553:9:553:18 | call to first [element 3] | array_flow.rb:553:5:553:5 | c [element 3] | -| array_flow.rb:553:9:553:18 | call to first [element] | array_flow.rb:553:5:553:5 | c [element] | -| array_flow.rb:553:9:553:18 | call to first [element] | array_flow.rb:553:5:553:5 | c [element] | -| array_flow.rb:554:10:554:10 | c [element 0] | array_flow.rb:554:10:554:13 | ...[...] | -| array_flow.rb:554:10:554:10 | c [element 0] | array_flow.rb:554:10:554:13 | ...[...] | -| array_flow.rb:554:10:554:10 | c [element] | array_flow.rb:554:10:554:13 | ...[...] | -| array_flow.rb:554:10:554:10 | c [element] | array_flow.rb:554:10:554:13 | ...[...] | -| array_flow.rb:555:10:555:10 | c [element 3] | array_flow.rb:555:10:555:13 | ...[...] | -| array_flow.rb:555:10:555:10 | c [element 3] | array_flow.rb:555:10:555:13 | ...[...] | -| array_flow.rb:555:10:555:10 | c [element] | array_flow.rb:555:10:555:13 | ...[...] | -| array_flow.rb:555:10:555:10 | c [element] | array_flow.rb:555:10:555:13 | ...[...] | -| array_flow.rb:559:5:559:5 | a [element 2] | array_flow.rb:560:9:560:9 | a [element 2] | -| array_flow.rb:559:5:559:5 | a [element 2] | array_flow.rb:560:9:560:9 | a [element 2] | -| array_flow.rb:559:5:559:5 | a [element 2] | array_flow.rb:565:9:565:9 | a [element 2] | -| array_flow.rb:559:5:559:5 | a [element 2] | array_flow.rb:565:9:565:9 | a [element 2] | -| array_flow.rb:559:16:559:27 | call to source | array_flow.rb:559:5:559:5 | a [element 2] | -| array_flow.rb:559:16:559:27 | call to source | array_flow.rb:559:5:559:5 | a [element 2] | -| array_flow.rb:560:5:560:5 | b [element] | array_flow.rb:564:10:564:10 | b [element] | -| array_flow.rb:560:5:560:5 | b [element] | array_flow.rb:564:10:564:10 | b [element] | -| array_flow.rb:560:9:560:9 | a [element 2] | array_flow.rb:560:9:563:7 | call to flat_map [element] | -| array_flow.rb:560:9:560:9 | a [element 2] | array_flow.rb:560:9:563:7 | call to flat_map [element] | -| array_flow.rb:560:9:560:9 | a [element 2] | array_flow.rb:560:24:560:24 | x | -| array_flow.rb:560:9:560:9 | a [element 2] | array_flow.rb:560:24:560:24 | x | -| array_flow.rb:560:9:563:7 | call to flat_map [element] | array_flow.rb:560:5:560:5 | b [element] | -| array_flow.rb:560:9:563:7 | call to flat_map [element] | array_flow.rb:560:5:560:5 | b [element] | -| array_flow.rb:560:24:560:24 | x | array_flow.rb:561:14:561:14 | x | -| array_flow.rb:560:24:560:24 | x | array_flow.rb:561:14:561:14 | x | -| array_flow.rb:562:13:562:24 | call to source | array_flow.rb:560:9:563:7 | call to flat_map [element] | -| array_flow.rb:562:13:562:24 | call to source | array_flow.rb:560:9:563:7 | call to flat_map [element] | -| array_flow.rb:564:10:564:10 | b [element] | array_flow.rb:564:10:564:13 | ...[...] | -| array_flow.rb:564:10:564:10 | b [element] | array_flow.rb:564:10:564:13 | ...[...] | -| array_flow.rb:565:5:565:5 | b [element] | array_flow.rb:569:10:569:10 | b [element] | -| array_flow.rb:565:5:565:5 | b [element] | array_flow.rb:569:10:569:10 | b [element] | -| array_flow.rb:565:9:565:9 | a [element 2] | array_flow.rb:565:24:565:24 | x | -| array_flow.rb:565:9:565:9 | a [element 2] | array_flow.rb:565:24:565:24 | x | -| array_flow.rb:565:9:568:7 | call to flat_map [element] | array_flow.rb:565:5:565:5 | b [element] | -| array_flow.rb:565:9:568:7 | call to flat_map [element] | array_flow.rb:565:5:565:5 | b [element] | -| array_flow.rb:565:24:565:24 | x | array_flow.rb:566:14:566:14 | x | -| array_flow.rb:565:24:565:24 | x | array_flow.rb:566:14:566:14 | x | -| array_flow.rb:567:9:567:20 | call to source | array_flow.rb:565:9:568:7 | call to flat_map [element] | -| array_flow.rb:567:9:567:20 | call to source | array_flow.rb:565:9:568:7 | call to flat_map [element] | -| array_flow.rb:569:10:569:10 | b [element] | array_flow.rb:569:10:569:13 | ...[...] | -| array_flow.rb:569:10:569:10 | b [element] | array_flow.rb:569:10:569:13 | ...[...] | -| array_flow.rb:573:5:573:5 | a [element 2, element 1] | array_flow.rb:574:9:574:9 | a [element 2, element 1] | -| array_flow.rb:573:5:573:5 | a [element 2, element 1] | array_flow.rb:574:9:574:9 | a [element 2, element 1] | -| array_flow.rb:573:20:573:29 | call to source | array_flow.rb:573:5:573:5 | a [element 2, element 1] | -| array_flow.rb:573:20:573:29 | call to source | array_flow.rb:573:5:573:5 | a [element 2, element 1] | -| array_flow.rb:574:5:574:5 | b [element] | array_flow.rb:575:10:575:10 | b [element] | -| array_flow.rb:574:5:574:5 | b [element] | array_flow.rb:575:10:575:10 | b [element] | -| array_flow.rb:574:9:574:9 | a [element 2, element 1] | array_flow.rb:574:9:574:17 | call to flatten [element] | -| array_flow.rb:574:9:574:9 | a [element 2, element 1] | array_flow.rb:574:9:574:17 | call to flatten [element] | -| array_flow.rb:574:9:574:17 | call to flatten [element] | array_flow.rb:574:5:574:5 | b [element] | -| array_flow.rb:574:9:574:17 | call to flatten [element] | array_flow.rb:574:5:574:5 | b [element] | +| array_flow.rb:511:10:511:10 | b [element] | array_flow.rb:511:10:511:13 | ...[...] | +| array_flow.rb:511:10:511:10 | b [element] | array_flow.rb:511:10:511:13 | ...[...] | +| array_flow.rb:518:5:518:5 | d [element] | array_flow.rb:521:10:521:10 | d [element] | +| array_flow.rb:518:5:518:5 | d [element] | array_flow.rb:521:10:521:10 | d [element] | +| array_flow.rb:518:9:520:7 | call to filter_map [element] | array_flow.rb:518:5:518:5 | d [element] | +| array_flow.rb:518:9:520:7 | call to filter_map [element] | array_flow.rb:518:5:518:5 | d [element] | +| array_flow.rb:519:9:519:20 | call to source | array_flow.rb:518:9:520:7 | call to filter_map [element] | +| array_flow.rb:519:9:519:20 | call to source | array_flow.rb:518:9:520:7 | call to filter_map [element] | +| array_flow.rb:521:10:521:10 | d [element] | array_flow.rb:521:10:521:13 | ...[...] | +| array_flow.rb:521:10:521:10 | d [element] | array_flow.rb:521:10:521:13 | ...[...] | +| array_flow.rb:525:5:525:5 | a [element 3] | array_flow.rb:526:9:526:9 | a [element 3] | +| array_flow.rb:525:5:525:5 | a [element 3] | array_flow.rb:526:9:526:9 | a [element 3] | +| array_flow.rb:525:19:525:28 | call to source | array_flow.rb:525:5:525:5 | a [element 3] | +| array_flow.rb:525:19:525:28 | call to source | array_flow.rb:525:5:525:5 | a [element 3] | +| array_flow.rb:526:5:526:5 | b [element] | array_flow.rb:531:10:531:10 | b [element] | +| array_flow.rb:526:5:526:5 | b [element] | array_flow.rb:531:10:531:10 | b [element] | +| array_flow.rb:526:9:526:9 | [post] a [element] | array_flow.rb:530:10:530:10 | a [element] | +| array_flow.rb:526:9:526:9 | [post] a [element] | array_flow.rb:530:10:530:10 | a [element] | +| array_flow.rb:526:9:526:9 | a [element 3] | array_flow.rb:526:9:526:9 | [post] a [element] | +| array_flow.rb:526:9:526:9 | a [element 3] | array_flow.rb:526:9:526:9 | [post] a [element] | +| array_flow.rb:526:9:526:9 | a [element 3] | array_flow.rb:526:9:529:7 | call to filter! [element] | +| array_flow.rb:526:9:526:9 | a [element 3] | array_flow.rb:526:9:529:7 | call to filter! [element] | +| array_flow.rb:526:9:526:9 | a [element 3] | array_flow.rb:526:23:526:23 | x | +| array_flow.rb:526:9:526:9 | a [element 3] | array_flow.rb:526:23:526:23 | x | +| array_flow.rb:526:9:529:7 | call to filter! [element] | array_flow.rb:526:5:526:5 | b [element] | +| array_flow.rb:526:9:529:7 | call to filter! [element] | array_flow.rb:526:5:526:5 | b [element] | +| array_flow.rb:526:23:526:23 | x | array_flow.rb:527:14:527:14 | x | +| array_flow.rb:526:23:526:23 | x | array_flow.rb:527:14:527:14 | x | +| array_flow.rb:530:10:530:10 | a [element] | array_flow.rb:530:10:530:13 | ...[...] | +| array_flow.rb:530:10:530:10 | a [element] | array_flow.rb:530:10:530:13 | ...[...] | +| array_flow.rb:531:10:531:10 | b [element] | array_flow.rb:531:10:531:13 | ...[...] | +| array_flow.rb:531:10:531:10 | b [element] | array_flow.rb:531:10:531:13 | ...[...] | +| array_flow.rb:535:5:535:5 | a [element 3] | array_flow.rb:536:9:536:9 | a [element 3] | +| array_flow.rb:535:5:535:5 | a [element 3] | array_flow.rb:536:9:536:9 | a [element 3] | +| array_flow.rb:535:19:535:30 | call to source | array_flow.rb:535:5:535:5 | a [element 3] | +| array_flow.rb:535:19:535:30 | call to source | array_flow.rb:535:5:535:5 | a [element 3] | +| array_flow.rb:536:5:536:5 | b | array_flow.rb:539:10:539:10 | b | +| array_flow.rb:536:5:536:5 | b | array_flow.rb:539:10:539:10 | b | +| array_flow.rb:536:9:536:9 | a [element 3] | array_flow.rb:536:9:538:7 | call to find | +| array_flow.rb:536:9:536:9 | a [element 3] | array_flow.rb:536:9:538:7 | call to find | +| array_flow.rb:536:9:536:9 | a [element 3] | array_flow.rb:536:41:536:41 | x | +| array_flow.rb:536:9:536:9 | a [element 3] | array_flow.rb:536:41:536:41 | x | +| array_flow.rb:536:9:538:7 | call to find | array_flow.rb:536:5:536:5 | b | +| array_flow.rb:536:9:538:7 | call to find | array_flow.rb:536:5:536:5 | b | +| array_flow.rb:536:21:536:32 | call to source | array_flow.rb:536:9:538:7 | call to find | +| array_flow.rb:536:21:536:32 | call to source | array_flow.rb:536:9:538:7 | call to find | +| array_flow.rb:536:41:536:41 | x | array_flow.rb:537:14:537:14 | x | +| array_flow.rb:536:41:536:41 | x | array_flow.rb:537:14:537:14 | x | +| array_flow.rb:543:5:543:5 | a [element 3] | array_flow.rb:544:9:544:9 | a [element 3] | +| array_flow.rb:543:5:543:5 | a [element 3] | array_flow.rb:544:9:544:9 | a [element 3] | +| array_flow.rb:543:19:543:28 | call to source | array_flow.rb:543:5:543:5 | a [element 3] | +| array_flow.rb:543:19:543:28 | call to source | array_flow.rb:543:5:543:5 | a [element 3] | +| array_flow.rb:544:5:544:5 | b [element] | array_flow.rb:547:10:547:10 | b [element] | +| array_flow.rb:544:5:544:5 | b [element] | array_flow.rb:547:10:547:10 | b [element] | +| array_flow.rb:544:9:544:9 | a [element 3] | array_flow.rb:544:9:546:7 | call to find_all [element] | +| array_flow.rb:544:9:544:9 | a [element 3] | array_flow.rb:544:9:546:7 | call to find_all [element] | +| array_flow.rb:544:9:544:9 | a [element 3] | array_flow.rb:544:24:544:24 | x | +| array_flow.rb:544:9:544:9 | a [element 3] | array_flow.rb:544:24:544:24 | x | +| array_flow.rb:544:9:546:7 | call to find_all [element] | array_flow.rb:544:5:544:5 | b [element] | +| array_flow.rb:544:9:546:7 | call to find_all [element] | array_flow.rb:544:5:544:5 | b [element] | +| array_flow.rb:544:24:544:24 | x | array_flow.rb:545:14:545:14 | x | +| array_flow.rb:544:24:544:24 | x | array_flow.rb:545:14:545:14 | x | +| array_flow.rb:547:10:547:10 | b [element] | array_flow.rb:547:10:547:13 | ...[...] | +| array_flow.rb:547:10:547:10 | b [element] | array_flow.rb:547:10:547:13 | ...[...] | +| array_flow.rb:551:5:551:5 | a [element 3] | array_flow.rb:552:5:552:5 | a [element 3] | +| array_flow.rb:551:5:551:5 | a [element 3] | array_flow.rb:552:5:552:5 | a [element 3] | +| array_flow.rb:551:19:551:28 | call to source | array_flow.rb:551:5:551:5 | a [element 3] | +| array_flow.rb:551:19:551:28 | call to source | array_flow.rb:551:5:551:5 | a [element 3] | +| array_flow.rb:552:5:552:5 | a [element 3] | array_flow.rb:552:22:552:22 | x | +| array_flow.rb:552:5:552:5 | a [element 3] | array_flow.rb:552:22:552:22 | x | +| array_flow.rb:552:22:552:22 | x | array_flow.rb:553:14:553:14 | x | +| array_flow.rb:552:22:552:22 | x | array_flow.rb:553:14:553:14 | x | +| array_flow.rb:558:5:558:5 | a [element 0] | array_flow.rb:560:10:560:10 | a [element 0] | +| array_flow.rb:558:5:558:5 | a [element 0] | array_flow.rb:560:10:560:10 | a [element 0] | +| array_flow.rb:558:5:558:5 | a [element 0] | array_flow.rb:561:9:561:9 | a [element 0] | +| array_flow.rb:558:5:558:5 | a [element 0] | array_flow.rb:561:9:561:9 | a [element 0] | +| array_flow.rb:558:5:558:5 | a [element 0] | array_flow.rb:564:9:564:9 | a [element 0] | +| array_flow.rb:558:5:558:5 | a [element 0] | array_flow.rb:564:9:564:9 | a [element 0] | +| array_flow.rb:558:5:558:5 | a [element 3] | array_flow.rb:564:9:564:9 | a [element 3] | +| array_flow.rb:558:5:558:5 | a [element 3] | array_flow.rb:564:9:564:9 | a [element 3] | +| array_flow.rb:558:10:558:21 | call to source | array_flow.rb:558:5:558:5 | a [element 0] | +| array_flow.rb:558:10:558:21 | call to source | array_flow.rb:558:5:558:5 | a [element 0] | +| array_flow.rb:558:30:558:41 | call to source | array_flow.rb:558:5:558:5 | a [element 3] | +| array_flow.rb:558:30:558:41 | call to source | array_flow.rb:558:5:558:5 | a [element 3] | +| array_flow.rb:559:5:559:5 | [post] a [element] | array_flow.rb:560:10:560:10 | a [element] | +| array_flow.rb:559:5:559:5 | [post] a [element] | array_flow.rb:560:10:560:10 | a [element] | +| array_flow.rb:559:5:559:5 | [post] a [element] | array_flow.rb:561:9:561:9 | a [element] | +| array_flow.rb:559:5:559:5 | [post] a [element] | array_flow.rb:561:9:561:9 | a [element] | +| array_flow.rb:559:5:559:5 | [post] a [element] | array_flow.rb:564:9:564:9 | a [element] | +| array_flow.rb:559:5:559:5 | [post] a [element] | array_flow.rb:564:9:564:9 | a [element] | +| array_flow.rb:559:12:559:23 | call to source | array_flow.rb:559:5:559:5 | [post] a [element] | +| array_flow.rb:559:12:559:23 | call to source | array_flow.rb:559:5:559:5 | [post] a [element] | +| array_flow.rb:560:10:560:10 | a [element 0] | array_flow.rb:560:10:560:16 | call to first | +| array_flow.rb:560:10:560:10 | a [element 0] | array_flow.rb:560:10:560:16 | call to first | +| array_flow.rb:560:10:560:10 | a [element] | array_flow.rb:560:10:560:16 | call to first | +| array_flow.rb:560:10:560:10 | a [element] | array_flow.rb:560:10:560:16 | call to first | +| array_flow.rb:561:5:561:5 | b [element 0] | array_flow.rb:562:10:562:10 | b [element 0] | +| array_flow.rb:561:5:561:5 | b [element 0] | array_flow.rb:562:10:562:10 | b [element 0] | +| array_flow.rb:561:5:561:5 | b [element] | array_flow.rb:562:10:562:10 | b [element] | +| array_flow.rb:561:5:561:5 | b [element] | array_flow.rb:562:10:562:10 | b [element] | +| array_flow.rb:561:5:561:5 | b [element] | array_flow.rb:563:10:563:10 | b [element] | +| array_flow.rb:561:5:561:5 | b [element] | array_flow.rb:563:10:563:10 | b [element] | +| array_flow.rb:561:9:561:9 | a [element 0] | array_flow.rb:561:9:561:18 | call to first [element 0] | +| array_flow.rb:561:9:561:9 | a [element 0] | array_flow.rb:561:9:561:18 | call to first [element 0] | +| array_flow.rb:561:9:561:9 | a [element] | array_flow.rb:561:9:561:18 | call to first [element] | +| array_flow.rb:561:9:561:9 | a [element] | array_flow.rb:561:9:561:18 | call to first [element] | +| array_flow.rb:561:9:561:18 | call to first [element 0] | array_flow.rb:561:5:561:5 | b [element 0] | +| array_flow.rb:561:9:561:18 | call to first [element 0] | array_flow.rb:561:5:561:5 | b [element 0] | +| array_flow.rb:561:9:561:18 | call to first [element] | array_flow.rb:561:5:561:5 | b [element] | +| array_flow.rb:561:9:561:18 | call to first [element] | array_flow.rb:561:5:561:5 | b [element] | +| array_flow.rb:562:10:562:10 | b [element 0] | array_flow.rb:562:10:562:13 | ...[...] | +| array_flow.rb:562:10:562:10 | b [element 0] | array_flow.rb:562:10:562:13 | ...[...] | +| array_flow.rb:562:10:562:10 | b [element] | array_flow.rb:562:10:562:13 | ...[...] | +| array_flow.rb:562:10:562:10 | b [element] | array_flow.rb:562:10:562:13 | ...[...] | +| array_flow.rb:563:10:563:10 | b [element] | array_flow.rb:563:10:563:13 | ...[...] | +| array_flow.rb:563:10:563:10 | b [element] | array_flow.rb:563:10:563:13 | ...[...] | +| array_flow.rb:564:5:564:5 | c [element 0] | array_flow.rb:565:10:565:10 | c [element 0] | +| array_flow.rb:564:5:564:5 | c [element 0] | array_flow.rb:565:10:565:10 | c [element 0] | +| array_flow.rb:564:5:564:5 | c [element 3] | array_flow.rb:566:10:566:10 | c [element 3] | +| array_flow.rb:564:5:564:5 | c [element 3] | array_flow.rb:566:10:566:10 | c [element 3] | +| array_flow.rb:564:5:564:5 | c [element] | array_flow.rb:565:10:565:10 | c [element] | +| array_flow.rb:564:5:564:5 | c [element] | array_flow.rb:565:10:565:10 | c [element] | +| array_flow.rb:564:5:564:5 | c [element] | array_flow.rb:566:10:566:10 | c [element] | +| array_flow.rb:564:5:564:5 | c [element] | array_flow.rb:566:10:566:10 | c [element] | +| array_flow.rb:564:9:564:9 | a [element 0] | array_flow.rb:564:9:564:18 | call to first [element 0] | +| array_flow.rb:564:9:564:9 | a [element 0] | array_flow.rb:564:9:564:18 | call to first [element 0] | +| array_flow.rb:564:9:564:9 | a [element 3] | array_flow.rb:564:9:564:18 | call to first [element 3] | +| array_flow.rb:564:9:564:9 | a [element 3] | array_flow.rb:564:9:564:18 | call to first [element 3] | +| array_flow.rb:564:9:564:9 | a [element] | array_flow.rb:564:9:564:18 | call to first [element] | +| array_flow.rb:564:9:564:9 | a [element] | array_flow.rb:564:9:564:18 | call to first [element] | +| array_flow.rb:564:9:564:18 | call to first [element 0] | array_flow.rb:564:5:564:5 | c [element 0] | +| array_flow.rb:564:9:564:18 | call to first [element 0] | array_flow.rb:564:5:564:5 | c [element 0] | +| array_flow.rb:564:9:564:18 | call to first [element 3] | array_flow.rb:564:5:564:5 | c [element 3] | +| array_flow.rb:564:9:564:18 | call to first [element 3] | array_flow.rb:564:5:564:5 | c [element 3] | +| array_flow.rb:564:9:564:18 | call to first [element] | array_flow.rb:564:5:564:5 | c [element] | +| array_flow.rb:564:9:564:18 | call to first [element] | array_flow.rb:564:5:564:5 | c [element] | +| array_flow.rb:565:10:565:10 | c [element 0] | array_flow.rb:565:10:565:13 | ...[...] | +| array_flow.rb:565:10:565:10 | c [element 0] | array_flow.rb:565:10:565:13 | ...[...] | +| array_flow.rb:565:10:565:10 | c [element] | array_flow.rb:565:10:565:13 | ...[...] | +| array_flow.rb:565:10:565:10 | c [element] | array_flow.rb:565:10:565:13 | ...[...] | +| array_flow.rb:566:10:566:10 | c [element 3] | array_flow.rb:566:10:566:13 | ...[...] | +| array_flow.rb:566:10:566:10 | c [element 3] | array_flow.rb:566:10:566:13 | ...[...] | +| array_flow.rb:566:10:566:10 | c [element] | array_flow.rb:566:10:566:13 | ...[...] | +| array_flow.rb:566:10:566:10 | c [element] | array_flow.rb:566:10:566:13 | ...[...] | +| array_flow.rb:570:5:570:5 | a [element 2] | array_flow.rb:571:9:571:9 | a [element 2] | +| array_flow.rb:570:5:570:5 | a [element 2] | array_flow.rb:571:9:571:9 | a [element 2] | +| array_flow.rb:570:5:570:5 | a [element 2] | array_flow.rb:576:9:576:9 | a [element 2] | +| array_flow.rb:570:5:570:5 | a [element 2] | array_flow.rb:576:9:576:9 | a [element 2] | +| array_flow.rb:570:16:570:27 | call to source | array_flow.rb:570:5:570:5 | a [element 2] | +| array_flow.rb:570:16:570:27 | call to source | array_flow.rb:570:5:570:5 | a [element 2] | +| array_flow.rb:571:5:571:5 | b [element] | array_flow.rb:575:10:575:10 | b [element] | +| array_flow.rb:571:5:571:5 | b [element] | array_flow.rb:575:10:575:10 | b [element] | +| array_flow.rb:571:9:571:9 | a [element 2] | array_flow.rb:571:9:574:7 | call to flat_map [element] | +| array_flow.rb:571:9:571:9 | a [element 2] | array_flow.rb:571:9:574:7 | call to flat_map [element] | +| array_flow.rb:571:9:571:9 | a [element 2] | array_flow.rb:571:24:571:24 | x | +| array_flow.rb:571:9:571:9 | a [element 2] | array_flow.rb:571:24:571:24 | x | +| array_flow.rb:571:9:574:7 | call to flat_map [element] | array_flow.rb:571:5:571:5 | b [element] | +| array_flow.rb:571:9:574:7 | call to flat_map [element] | array_flow.rb:571:5:571:5 | b [element] | +| array_flow.rb:571:24:571:24 | x | array_flow.rb:572:14:572:14 | x | +| array_flow.rb:571:24:571:24 | x | array_flow.rb:572:14:572:14 | x | +| array_flow.rb:573:13:573:24 | call to source | array_flow.rb:571:9:574:7 | call to flat_map [element] | +| array_flow.rb:573:13:573:24 | call to source | array_flow.rb:571:9:574:7 | call to flat_map [element] | | array_flow.rb:575:10:575:10 | b [element] | array_flow.rb:575:10:575:13 | ...[...] | | array_flow.rb:575:10:575:10 | b [element] | array_flow.rb:575:10:575:13 | ...[...] | -| array_flow.rb:579:5:579:5 | a [element 2, element 1] | array_flow.rb:580:10:580:10 | a [element 2, element 1] | -| array_flow.rb:579:5:579:5 | a [element 2, element 1] | array_flow.rb:580:10:580:10 | a [element 2, element 1] | -| array_flow.rb:579:5:579:5 | a [element 2, element 1] | array_flow.rb:581:9:581:9 | a [element 2, element 1] | -| array_flow.rb:579:5:579:5 | a [element 2, element 1] | array_flow.rb:581:9:581:9 | a [element 2, element 1] | -| array_flow.rb:579:20:579:29 | call to source | array_flow.rb:579:5:579:5 | a [element 2, element 1] | -| array_flow.rb:579:20:579:29 | call to source | array_flow.rb:579:5:579:5 | a [element 2, element 1] | -| array_flow.rb:580:10:580:10 | a [element 2, element 1] | array_flow.rb:580:10:580:13 | ...[...] [element 1] | -| array_flow.rb:580:10:580:10 | a [element 2, element 1] | array_flow.rb:580:10:580:13 | ...[...] [element 1] | -| array_flow.rb:580:10:580:13 | ...[...] [element 1] | array_flow.rb:580:10:580:16 | ...[...] | -| array_flow.rb:580:10:580:13 | ...[...] [element 1] | array_flow.rb:580:10:580:16 | ...[...] | -| array_flow.rb:581:5:581:5 | b [element, element 1] | array_flow.rb:585:10:585:10 | b [element, element 1] | -| array_flow.rb:581:5:581:5 | b [element, element 1] | array_flow.rb:585:10:585:10 | b [element, element 1] | -| array_flow.rb:581:5:581:5 | b [element] | array_flow.rb:584:10:584:10 | b [element] | -| array_flow.rb:581:5:581:5 | b [element] | array_flow.rb:584:10:584:10 | b [element] | -| array_flow.rb:581:5:581:5 | b [element] | array_flow.rb:585:10:585:10 | b [element] | -| array_flow.rb:581:9:581:9 | [post] a [element, element 1] | array_flow.rb:583:10:583:10 | a [element, element 1] | -| array_flow.rb:581:9:581:9 | [post] a [element, element 1] | array_flow.rb:583:10:583:10 | a [element, element 1] | -| array_flow.rb:581:9:581:9 | [post] a [element] | array_flow.rb:582:10:582:10 | a [element] | -| array_flow.rb:581:9:581:9 | [post] a [element] | array_flow.rb:582:10:582:10 | a [element] | -| array_flow.rb:581:9:581:9 | [post] a [element] | array_flow.rb:583:10:583:10 | a [element] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | array_flow.rb:581:9:581:9 | [post] a [element, element 1] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | array_flow.rb:581:9:581:9 | [post] a [element, element 1] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | array_flow.rb:581:9:581:9 | [post] a [element] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | array_flow.rb:581:9:581:9 | [post] a [element] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | array_flow.rb:581:9:581:18 | call to flatten! [element] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | array_flow.rb:581:9:581:18 | call to flatten! [element] | -| array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] | array_flow.rb:581:5:581:5 | b [element, element 1] | -| array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] | array_flow.rb:581:5:581:5 | b [element, element 1] | -| array_flow.rb:581:9:581:18 | call to flatten! [element] | array_flow.rb:581:5:581:5 | b [element] | -| array_flow.rb:581:9:581:18 | call to flatten! [element] | array_flow.rb:581:5:581:5 | b [element] | -| array_flow.rb:582:10:582:10 | a [element] | array_flow.rb:582:10:582:13 | ...[...] | -| array_flow.rb:582:10:582:10 | a [element] | array_flow.rb:582:10:582:13 | ...[...] | -| array_flow.rb:583:10:583:10 | a [element, element 1] | array_flow.rb:583:10:583:13 | ...[...] [element 1] | -| array_flow.rb:583:10:583:10 | a [element, element 1] | array_flow.rb:583:10:583:13 | ...[...] [element 1] | -| array_flow.rb:583:10:583:10 | a [element] | array_flow.rb:583:10:583:13 | ...[...] | -| array_flow.rb:583:10:583:13 | ...[...] | array_flow.rb:583:10:583:16 | ...[...] | -| array_flow.rb:583:10:583:13 | ...[...] [element 1] | array_flow.rb:583:10:583:16 | ...[...] | -| array_flow.rb:583:10:583:13 | ...[...] [element 1] | array_flow.rb:583:10:583:16 | ...[...] | -| array_flow.rb:584:10:584:10 | b [element] | array_flow.rb:584:10:584:13 | ...[...] | -| array_flow.rb:584:10:584:10 | b [element] | array_flow.rb:584:10:584:13 | ...[...] | -| array_flow.rb:585:10:585:10 | b [element, element 1] | array_flow.rb:585:10:585:13 | ...[...] [element 1] | -| array_flow.rb:585:10:585:10 | b [element, element 1] | array_flow.rb:585:10:585:13 | ...[...] [element 1] | -| array_flow.rb:585:10:585:10 | b [element] | array_flow.rb:585:10:585:13 | ...[...] | -| array_flow.rb:585:10:585:13 | ...[...] | array_flow.rb:585:10:585:16 | ...[...] | -| array_flow.rb:585:10:585:13 | ...[...] [element 1] | array_flow.rb:585:10:585:16 | ...[...] | -| array_flow.rb:585:10:585:13 | ...[...] [element 1] | array_flow.rb:585:10:585:16 | ...[...] | -| array_flow.rb:589:5:589:5 | a [element 3] | array_flow.rb:590:9:590:9 | a [element 3] | -| array_flow.rb:589:5:589:5 | a [element 3] | array_flow.rb:590:9:590:9 | a [element 3] | -| array_flow.rb:589:5:589:5 | a [element 3] | array_flow.rb:592:9:592:9 | a [element 3] | -| array_flow.rb:589:5:589:5 | a [element 3] | array_flow.rb:592:9:592:9 | a [element 3] | -| array_flow.rb:589:19:589:30 | call to source | array_flow.rb:589:5:589:5 | a [element 3] | -| array_flow.rb:589:19:589:30 | call to source | array_flow.rb:589:5:589:5 | a [element 3] | -| array_flow.rb:590:5:590:5 | b [element] | array_flow.rb:591:10:591:10 | b [element] | -| array_flow.rb:590:5:590:5 | b [element] | array_flow.rb:591:10:591:10 | b [element] | -| array_flow.rb:590:9:590:9 | a [element 3] | array_flow.rb:590:9:590:20 | call to grep [element] | -| array_flow.rb:590:9:590:9 | a [element 3] | array_flow.rb:590:9:590:20 | call to grep [element] | -| array_flow.rb:590:9:590:20 | call to grep [element] | array_flow.rb:590:5:590:5 | b [element] | -| array_flow.rb:590:9:590:20 | call to grep [element] | array_flow.rb:590:5:590:5 | b [element] | -| array_flow.rb:591:10:591:10 | b [element] | array_flow.rb:591:10:591:13 | ...[...] | -| array_flow.rb:591:10:591:10 | b [element] | array_flow.rb:591:10:591:13 | ...[...] | +| array_flow.rb:576:5:576:5 | b [element] | array_flow.rb:580:10:580:10 | b [element] | +| array_flow.rb:576:5:576:5 | b [element] | array_flow.rb:580:10:580:10 | b [element] | +| array_flow.rb:576:9:576:9 | a [element 2] | array_flow.rb:576:24:576:24 | x | +| array_flow.rb:576:9:576:9 | a [element 2] | array_flow.rb:576:24:576:24 | x | +| array_flow.rb:576:9:579:7 | call to flat_map [element] | array_flow.rb:576:5:576:5 | b [element] | +| array_flow.rb:576:9:579:7 | call to flat_map [element] | array_flow.rb:576:5:576:5 | b [element] | +| array_flow.rb:576:24:576:24 | x | array_flow.rb:577:14:577:14 | x | +| array_flow.rb:576:24:576:24 | x | array_flow.rb:577:14:577:14 | x | +| array_flow.rb:578:9:578:20 | call to source | array_flow.rb:576:9:579:7 | call to flat_map [element] | +| array_flow.rb:578:9:578:20 | call to source | array_flow.rb:576:9:579:7 | call to flat_map [element] | +| array_flow.rb:580:10:580:10 | b [element] | array_flow.rb:580:10:580:13 | ...[...] | +| array_flow.rb:580:10:580:10 | b [element] | array_flow.rb:580:10:580:13 | ...[...] | +| array_flow.rb:584:5:584:5 | a [element 2, element 1] | array_flow.rb:585:9:585:9 | a [element 2, element 1] | +| array_flow.rb:584:5:584:5 | a [element 2, element 1] | array_flow.rb:585:9:585:9 | a [element 2, element 1] | +| array_flow.rb:584:20:584:29 | call to source | array_flow.rb:584:5:584:5 | a [element 2, element 1] | +| array_flow.rb:584:20:584:29 | call to source | array_flow.rb:584:5:584:5 | a [element 2, element 1] | +| array_flow.rb:585:5:585:5 | b [element] | array_flow.rb:586:10:586:10 | b [element] | +| array_flow.rb:585:5:585:5 | b [element] | array_flow.rb:586:10:586:10 | b [element] | +| array_flow.rb:585:9:585:9 | a [element 2, element 1] | array_flow.rb:585:9:585:17 | call to flatten [element] | +| array_flow.rb:585:9:585:9 | a [element 2, element 1] | array_flow.rb:585:9:585:17 | call to flatten [element] | +| array_flow.rb:585:9:585:17 | call to flatten [element] | array_flow.rb:585:5:585:5 | b [element] | +| array_flow.rb:585:9:585:17 | call to flatten [element] | array_flow.rb:585:5:585:5 | b [element] | +| array_flow.rb:586:10:586:10 | b [element] | array_flow.rb:586:10:586:13 | ...[...] | +| array_flow.rb:586:10:586:10 | b [element] | array_flow.rb:586:10:586:13 | ...[...] | +| array_flow.rb:590:5:590:5 | a [element 2, element 1] | array_flow.rb:591:10:591:10 | a [element 2, element 1] | +| array_flow.rb:590:5:590:5 | a [element 2, element 1] | array_flow.rb:591:10:591:10 | a [element 2, element 1] | +| array_flow.rb:590:5:590:5 | a [element 2, element 1] | array_flow.rb:592:9:592:9 | a [element 2, element 1] | +| array_flow.rb:590:5:590:5 | a [element 2, element 1] | array_flow.rb:592:9:592:9 | a [element 2, element 1] | +| array_flow.rb:590:20:590:29 | call to source | array_flow.rb:590:5:590:5 | a [element 2, element 1] | +| array_flow.rb:590:20:590:29 | call to source | array_flow.rb:590:5:590:5 | a [element 2, element 1] | +| array_flow.rb:591:10:591:10 | a [element 2, element 1] | array_flow.rb:591:10:591:13 | ...[...] [element 1] | +| array_flow.rb:591:10:591:10 | a [element 2, element 1] | array_flow.rb:591:10:591:13 | ...[...] [element 1] | +| array_flow.rb:591:10:591:13 | ...[...] [element 1] | array_flow.rb:591:10:591:16 | ...[...] | +| array_flow.rb:591:10:591:13 | ...[...] [element 1] | array_flow.rb:591:10:591:16 | ...[...] | +| array_flow.rb:592:5:592:5 | b [element, element 1] | array_flow.rb:596:10:596:10 | b [element, element 1] | +| array_flow.rb:592:5:592:5 | b [element, element 1] | array_flow.rb:596:10:596:10 | b [element, element 1] | +| array_flow.rb:592:5:592:5 | b [element] | array_flow.rb:595:10:595:10 | b [element] | +| array_flow.rb:592:5:592:5 | b [element] | array_flow.rb:595:10:595:10 | b [element] | | array_flow.rb:592:5:592:5 | b [element] | array_flow.rb:596:10:596:10 | b [element] | -| array_flow.rb:592:5:592:5 | b [element] | array_flow.rb:596:10:596:10 | b [element] | -| array_flow.rb:592:9:592:9 | a [element 3] | array_flow.rb:592:26:592:26 | x | -| array_flow.rb:592:9:592:9 | a [element 3] | array_flow.rb:592:26:592:26 | x | -| array_flow.rb:592:9:595:7 | call to grep [element] | array_flow.rb:592:5:592:5 | b [element] | -| array_flow.rb:592:9:595:7 | call to grep [element] | array_flow.rb:592:5:592:5 | b [element] | -| array_flow.rb:592:26:592:26 | x | array_flow.rb:593:14:593:14 | x | -| array_flow.rb:592:26:592:26 | x | array_flow.rb:593:14:593:14 | x | -| array_flow.rb:594:9:594:20 | call to source | array_flow.rb:592:9:595:7 | call to grep [element] | -| array_flow.rb:594:9:594:20 | call to source | array_flow.rb:592:9:595:7 | call to grep [element] | -| array_flow.rb:596:10:596:10 | b [element] | array_flow.rb:596:10:596:13 | ...[...] | +| array_flow.rb:592:9:592:9 | [post] a [element, element 1] | array_flow.rb:594:10:594:10 | a [element, element 1] | +| array_flow.rb:592:9:592:9 | [post] a [element, element 1] | array_flow.rb:594:10:594:10 | a [element, element 1] | +| array_flow.rb:592:9:592:9 | [post] a [element] | array_flow.rb:593:10:593:10 | a [element] | +| array_flow.rb:592:9:592:9 | [post] a [element] | array_flow.rb:593:10:593:10 | a [element] | +| array_flow.rb:592:9:592:9 | [post] a [element] | array_flow.rb:594:10:594:10 | a [element] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | array_flow.rb:592:9:592:9 | [post] a [element, element 1] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | array_flow.rb:592:9:592:9 | [post] a [element, element 1] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | array_flow.rb:592:9:592:9 | [post] a [element] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | array_flow.rb:592:9:592:9 | [post] a [element] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | array_flow.rb:592:9:592:18 | call to flatten! [element, element 1] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | array_flow.rb:592:9:592:18 | call to flatten! [element, element 1] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | array_flow.rb:592:9:592:18 | call to flatten! [element] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | array_flow.rb:592:9:592:18 | call to flatten! [element] | +| array_flow.rb:592:9:592:18 | call to flatten! [element, element 1] | array_flow.rb:592:5:592:5 | b [element, element 1] | +| array_flow.rb:592:9:592:18 | call to flatten! [element, element 1] | array_flow.rb:592:5:592:5 | b [element, element 1] | +| array_flow.rb:592:9:592:18 | call to flatten! [element] | array_flow.rb:592:5:592:5 | b [element] | +| array_flow.rb:592:9:592:18 | call to flatten! [element] | array_flow.rb:592:5:592:5 | b [element] | +| array_flow.rb:593:10:593:10 | a [element] | array_flow.rb:593:10:593:13 | ...[...] | +| array_flow.rb:593:10:593:10 | a [element] | array_flow.rb:593:10:593:13 | ...[...] | +| array_flow.rb:594:10:594:10 | a [element, element 1] | array_flow.rb:594:10:594:13 | ...[...] [element 1] | +| array_flow.rb:594:10:594:10 | a [element, element 1] | array_flow.rb:594:10:594:13 | ...[...] [element 1] | +| array_flow.rb:594:10:594:10 | a [element] | array_flow.rb:594:10:594:13 | ...[...] | +| array_flow.rb:594:10:594:13 | ...[...] | array_flow.rb:594:10:594:16 | ...[...] | +| array_flow.rb:594:10:594:13 | ...[...] [element 1] | array_flow.rb:594:10:594:16 | ...[...] | +| array_flow.rb:594:10:594:13 | ...[...] [element 1] | array_flow.rb:594:10:594:16 | ...[...] | +| array_flow.rb:595:10:595:10 | b [element] | array_flow.rb:595:10:595:13 | ...[...] | +| array_flow.rb:595:10:595:10 | b [element] | array_flow.rb:595:10:595:13 | ...[...] | +| array_flow.rb:596:10:596:10 | b [element, element 1] | array_flow.rb:596:10:596:13 | ...[...] [element 1] | +| array_flow.rb:596:10:596:10 | b [element, element 1] | array_flow.rb:596:10:596:13 | ...[...] [element 1] | | array_flow.rb:596:10:596:10 | b [element] | array_flow.rb:596:10:596:13 | ...[...] | +| array_flow.rb:596:10:596:13 | ...[...] | array_flow.rb:596:10:596:16 | ...[...] | +| array_flow.rb:596:10:596:13 | ...[...] [element 1] | array_flow.rb:596:10:596:16 | ...[...] | +| array_flow.rb:596:10:596:13 | ...[...] [element 1] | array_flow.rb:596:10:596:16 | ...[...] | | array_flow.rb:600:5:600:5 | a [element 3] | array_flow.rb:601:9:601:9 | a [element 3] | | array_flow.rb:600:5:600:5 | a [element 3] | array_flow.rb:601:9:601:9 | a [element 3] | | array_flow.rb:600:5:600:5 | a [element 3] | array_flow.rb:603:9:603:9 | a [element 3] | @@ -1397,897 +1379,889 @@ edges | array_flow.rb:600:19:600:30 | call to source | array_flow.rb:600:5:600:5 | a [element 3] | | array_flow.rb:601:5:601:5 | b [element] | array_flow.rb:602:10:602:10 | b [element] | | array_flow.rb:601:5:601:5 | b [element] | array_flow.rb:602:10:602:10 | b [element] | -| array_flow.rb:601:9:601:9 | a [element 3] | array_flow.rb:601:9:601:21 | call to grep_v [element] | -| array_flow.rb:601:9:601:9 | a [element 3] | array_flow.rb:601:9:601:21 | call to grep_v [element] | -| array_flow.rb:601:9:601:21 | call to grep_v [element] | array_flow.rb:601:5:601:5 | b [element] | -| array_flow.rb:601:9:601:21 | call to grep_v [element] | array_flow.rb:601:5:601:5 | b [element] | +| array_flow.rb:601:9:601:9 | a [element 3] | array_flow.rb:601:9:601:20 | call to grep [element] | +| array_flow.rb:601:9:601:9 | a [element 3] | array_flow.rb:601:9:601:20 | call to grep [element] | +| array_flow.rb:601:9:601:20 | call to grep [element] | array_flow.rb:601:5:601:5 | b [element] | +| array_flow.rb:601:9:601:20 | call to grep [element] | array_flow.rb:601:5:601:5 | b [element] | | array_flow.rb:602:10:602:10 | b [element] | array_flow.rb:602:10:602:13 | ...[...] | | array_flow.rb:602:10:602:10 | b [element] | array_flow.rb:602:10:602:13 | ...[...] | | array_flow.rb:603:5:603:5 | b [element] | array_flow.rb:607:10:607:10 | b [element] | | array_flow.rb:603:5:603:5 | b [element] | array_flow.rb:607:10:607:10 | b [element] | -| array_flow.rb:603:9:603:9 | a [element 3] | array_flow.rb:603:27:603:27 | x | -| array_flow.rb:603:9:603:9 | a [element 3] | array_flow.rb:603:27:603:27 | x | -| array_flow.rb:603:9:606:7 | call to grep_v [element] | array_flow.rb:603:5:603:5 | b [element] | -| array_flow.rb:603:9:606:7 | call to grep_v [element] | array_flow.rb:603:5:603:5 | b [element] | -| array_flow.rb:603:27:603:27 | x | array_flow.rb:604:14:604:14 | x | -| array_flow.rb:603:27:603:27 | x | array_flow.rb:604:14:604:14 | x | -| array_flow.rb:605:9:605:20 | call to source | array_flow.rb:603:9:606:7 | call to grep_v [element] | -| array_flow.rb:605:9:605:20 | call to source | array_flow.rb:603:9:606:7 | call to grep_v [element] | +| array_flow.rb:603:9:603:9 | a [element 3] | array_flow.rb:603:26:603:26 | x | +| array_flow.rb:603:9:603:9 | a [element 3] | array_flow.rb:603:26:603:26 | x | +| array_flow.rb:603:9:606:7 | call to grep [element] | array_flow.rb:603:5:603:5 | b [element] | +| array_flow.rb:603:9:606:7 | call to grep [element] | array_flow.rb:603:5:603:5 | b [element] | +| array_flow.rb:603:26:603:26 | x | array_flow.rb:604:14:604:14 | x | +| array_flow.rb:603:26:603:26 | x | array_flow.rb:604:14:604:14 | x | +| array_flow.rb:605:9:605:20 | call to source | array_flow.rb:603:9:606:7 | call to grep [element] | +| array_flow.rb:605:9:605:20 | call to source | array_flow.rb:603:9:606:7 | call to grep [element] | | array_flow.rb:607:10:607:10 | b [element] | array_flow.rb:607:10:607:13 | ...[...] | | array_flow.rb:607:10:607:10 | b [element] | array_flow.rb:607:10:607:13 | ...[...] | | array_flow.rb:611:5:611:5 | a [element 3] | array_flow.rb:612:9:612:9 | a [element 3] | | array_flow.rb:611:5:611:5 | a [element 3] | array_flow.rb:612:9:612:9 | a [element 3] | +| array_flow.rb:611:5:611:5 | a [element 3] | array_flow.rb:614:9:614:9 | a [element 3] | +| array_flow.rb:611:5:611:5 | a [element 3] | array_flow.rb:614:9:614:9 | a [element 3] | | array_flow.rb:611:19:611:30 | call to source | array_flow.rb:611:5:611:5 | a [element 3] | | array_flow.rb:611:19:611:30 | call to source | array_flow.rb:611:5:611:5 | a [element 3] | -| array_flow.rb:612:9:612:9 | a [element 3] | array_flow.rb:612:24:612:24 | x | -| array_flow.rb:612:9:612:9 | a [element 3] | array_flow.rb:612:24:612:24 | x | -| array_flow.rb:612:24:612:24 | x | array_flow.rb:613:14:613:14 | x | -| array_flow.rb:612:24:612:24 | x | array_flow.rb:613:14:613:14 | x | -| array_flow.rb:620:5:620:5 | a [element 3] | array_flow.rb:621:5:621:5 | a [element 3] | -| array_flow.rb:620:5:620:5 | a [element 3] | array_flow.rb:621:5:621:5 | a [element 3] | -| array_flow.rb:620:19:620:28 | call to source | array_flow.rb:620:5:620:5 | a [element 3] | -| array_flow.rb:620:19:620:28 | call to source | array_flow.rb:620:5:620:5 | a [element 3] | -| array_flow.rb:621:5:621:5 | a [element 3] | array_flow.rb:621:17:621:17 | x | -| array_flow.rb:621:5:621:5 | a [element 3] | array_flow.rb:621:17:621:17 | x | -| array_flow.rb:621:17:621:17 | x | array_flow.rb:622:14:622:14 | x | -| array_flow.rb:621:17:621:17 | x | array_flow.rb:622:14:622:14 | x | -| array_flow.rb:627:5:627:5 | a [element 0] | array_flow.rb:628:9:628:9 | a [element 0] | -| array_flow.rb:627:5:627:5 | a [element 0] | array_flow.rb:628:9:628:9 | a [element 0] | -| array_flow.rb:627:5:627:5 | a [element 0] | array_flow.rb:634:9:634:9 | a [element 0] | -| array_flow.rb:627:5:627:5 | a [element 0] | array_flow.rb:634:9:634:9 | a [element 0] | -| array_flow.rb:627:5:627:5 | a [element 2] | array_flow.rb:628:9:628:9 | a [element 2] | -| array_flow.rb:627:5:627:5 | a [element 2] | array_flow.rb:628:9:628:9 | a [element 2] | -| array_flow.rb:627:5:627:5 | a [element 2] | array_flow.rb:634:9:634:9 | a [element 2] | -| array_flow.rb:627:5:627:5 | a [element 2] | array_flow.rb:634:9:634:9 | a [element 2] | -| array_flow.rb:627:10:627:21 | call to source | array_flow.rb:627:5:627:5 | a [element 0] | -| array_flow.rb:627:10:627:21 | call to source | array_flow.rb:627:5:627:5 | a [element 0] | -| array_flow.rb:627:27:627:38 | call to source | array_flow.rb:627:5:627:5 | a [element 2] | -| array_flow.rb:627:27:627:38 | call to source | array_flow.rb:627:5:627:5 | a [element 2] | -| array_flow.rb:628:5:628:5 | b | array_flow.rb:633:10:633:10 | b | -| array_flow.rb:628:5:628:5 | b | array_flow.rb:633:10:633:10 | b | -| array_flow.rb:628:9:628:9 | a [element 0] | array_flow.rb:628:22:628:22 | x | -| array_flow.rb:628:9:628:9 | a [element 0] | array_flow.rb:628:22:628:22 | x | -| array_flow.rb:628:9:628:9 | a [element 2] | array_flow.rb:628:25:628:25 | y | -| array_flow.rb:628:9:628:9 | a [element 2] | array_flow.rb:628:25:628:25 | y | -| array_flow.rb:628:9:632:7 | call to inject | array_flow.rb:628:5:628:5 | b | -| array_flow.rb:628:9:632:7 | call to inject | array_flow.rb:628:5:628:5 | b | -| array_flow.rb:628:22:628:22 | x | array_flow.rb:629:14:629:14 | x | -| array_flow.rb:628:22:628:22 | x | array_flow.rb:629:14:629:14 | x | -| array_flow.rb:628:25:628:25 | y | array_flow.rb:630:14:630:14 | y | -| array_flow.rb:628:25:628:25 | y | array_flow.rb:630:14:630:14 | y | -| array_flow.rb:631:9:631:19 | call to source | array_flow.rb:628:9:632:7 | call to inject | -| array_flow.rb:631:9:631:19 | call to source | array_flow.rb:628:9:632:7 | call to inject | -| array_flow.rb:634:5:634:5 | c | array_flow.rb:639:10:639:10 | c | -| array_flow.rb:634:5:634:5 | c | array_flow.rb:639:10:639:10 | c | -| array_flow.rb:634:9:634:9 | a [element 0] | array_flow.rb:634:28:634:28 | y | -| array_flow.rb:634:9:634:9 | a [element 0] | array_flow.rb:634:28:634:28 | y | -| array_flow.rb:634:9:634:9 | a [element 2] | array_flow.rb:634:28:634:28 | y | -| array_flow.rb:634:9:634:9 | a [element 2] | array_flow.rb:634:28:634:28 | y | -| array_flow.rb:634:9:638:7 | call to inject | array_flow.rb:634:5:634:5 | c | -| array_flow.rb:634:9:638:7 | call to inject | array_flow.rb:634:5:634:5 | c | -| array_flow.rb:634:28:634:28 | y | array_flow.rb:636:14:636:14 | y | -| array_flow.rb:634:28:634:28 | y | array_flow.rb:636:14:636:14 | y | -| array_flow.rb:637:9:637:19 | call to source | array_flow.rb:634:9:638:7 | call to inject | -| array_flow.rb:637:9:637:19 | call to source | array_flow.rb:634:9:638:7 | call to inject | -| array_flow.rb:644:5:644:5 | a [element 2] | array_flow.rb:645:9:645:9 | a [element 2] | -| array_flow.rb:644:5:644:5 | a [element 2] | array_flow.rb:645:9:645:9 | a [element 2] | -| array_flow.rb:644:16:644:27 | call to source | array_flow.rb:644:5:644:5 | a [element 2] | -| array_flow.rb:644:16:644:27 | call to source | array_flow.rb:644:5:644:5 | a [element 2] | -| array_flow.rb:645:5:645:5 | b [element 1] | array_flow.rb:652:10:652:10 | b [element 1] | -| array_flow.rb:645:5:645:5 | b [element 1] | array_flow.rb:652:10:652:10 | b [element 1] | -| array_flow.rb:645:5:645:5 | b [element 2] | array_flow.rb:653:10:653:10 | b [element 2] | -| array_flow.rb:645:5:645:5 | b [element 2] | array_flow.rb:653:10:653:10 | b [element 2] | -| array_flow.rb:645:5:645:5 | b [element 4] | array_flow.rb:655:10:655:10 | b [element 4] | -| array_flow.rb:645:5:645:5 | b [element 4] | array_flow.rb:655:10:655:10 | b [element 4] | -| array_flow.rb:645:9:645:9 | [post] a [element 1] | array_flow.rb:647:10:647:10 | a [element 1] | -| array_flow.rb:645:9:645:9 | [post] a [element 1] | array_flow.rb:647:10:647:10 | a [element 1] | -| array_flow.rb:645:9:645:9 | [post] a [element 2] | array_flow.rb:648:10:648:10 | a [element 2] | -| array_flow.rb:645:9:645:9 | [post] a [element 2] | array_flow.rb:648:10:648:10 | a [element 2] | -| array_flow.rb:645:9:645:9 | [post] a [element 4] | array_flow.rb:650:10:650:10 | a [element 4] | -| array_flow.rb:645:9:645:9 | [post] a [element 4] | array_flow.rb:650:10:650:10 | a [element 4] | -| array_flow.rb:645:9:645:9 | a [element 2] | array_flow.rb:645:9:645:9 | [post] a [element 4] | -| array_flow.rb:645:9:645:9 | a [element 2] | array_flow.rb:645:9:645:9 | [post] a [element 4] | -| array_flow.rb:645:9:645:9 | a [element 2] | array_flow.rb:645:9:645:47 | call to insert [element 4] | -| array_flow.rb:645:9:645:9 | a [element 2] | array_flow.rb:645:9:645:47 | call to insert [element 4] | -| array_flow.rb:645:9:645:47 | call to insert [element 1] | array_flow.rb:645:5:645:5 | b [element 1] | -| array_flow.rb:645:9:645:47 | call to insert [element 1] | array_flow.rb:645:5:645:5 | b [element 1] | -| array_flow.rb:645:9:645:47 | call to insert [element 2] | array_flow.rb:645:5:645:5 | b [element 2] | -| array_flow.rb:645:9:645:47 | call to insert [element 2] | array_flow.rb:645:5:645:5 | b [element 2] | -| array_flow.rb:645:9:645:47 | call to insert [element 4] | array_flow.rb:645:5:645:5 | b [element 4] | -| array_flow.rb:645:9:645:47 | call to insert [element 4] | array_flow.rb:645:5:645:5 | b [element 4] | -| array_flow.rb:645:21:645:32 | call to source | array_flow.rb:645:9:645:9 | [post] a [element 1] | -| array_flow.rb:645:21:645:32 | call to source | array_flow.rb:645:9:645:9 | [post] a [element 1] | -| array_flow.rb:645:21:645:32 | call to source | array_flow.rb:645:9:645:47 | call to insert [element 1] | -| array_flow.rb:645:21:645:32 | call to source | array_flow.rb:645:9:645:47 | call to insert [element 1] | -| array_flow.rb:645:35:645:46 | call to source | array_flow.rb:645:9:645:9 | [post] a [element 2] | -| array_flow.rb:645:35:645:46 | call to source | array_flow.rb:645:9:645:9 | [post] a [element 2] | -| array_flow.rb:645:35:645:46 | call to source | array_flow.rb:645:9:645:47 | call to insert [element 2] | -| array_flow.rb:645:35:645:46 | call to source | array_flow.rb:645:9:645:47 | call to insert [element 2] | -| array_flow.rb:647:10:647:10 | a [element 1] | array_flow.rb:647:10:647:13 | ...[...] | -| array_flow.rb:647:10:647:10 | a [element 1] | array_flow.rb:647:10:647:13 | ...[...] | -| array_flow.rb:648:10:648:10 | a [element 2] | array_flow.rb:648:10:648:13 | ...[...] | -| array_flow.rb:648:10:648:10 | a [element 2] | array_flow.rb:648:10:648:13 | ...[...] | -| array_flow.rb:650:10:650:10 | a [element 4] | array_flow.rb:650:10:650:13 | ...[...] | -| array_flow.rb:650:10:650:10 | a [element 4] | array_flow.rb:650:10:650:13 | ...[...] | -| array_flow.rb:652:10:652:10 | b [element 1] | array_flow.rb:652:10:652:13 | ...[...] | -| array_flow.rb:652:10:652:10 | b [element 1] | array_flow.rb:652:10:652:13 | ...[...] | -| array_flow.rb:653:10:653:10 | b [element 2] | array_flow.rb:653:10:653:13 | ...[...] | -| array_flow.rb:653:10:653:10 | b [element 2] | array_flow.rb:653:10:653:13 | ...[...] | -| array_flow.rb:655:10:655:10 | b [element 4] | array_flow.rb:655:10:655:13 | ...[...] | -| array_flow.rb:655:10:655:10 | b [element 4] | array_flow.rb:655:10:655:13 | ...[...] | -| array_flow.rb:658:5:658:5 | c [element 2] | array_flow.rb:659:9:659:9 | c [element 2] | -| array_flow.rb:658:5:658:5 | c [element 2] | array_flow.rb:659:9:659:9 | c [element 2] | -| array_flow.rb:658:16:658:27 | call to source | array_flow.rb:658:5:658:5 | c [element 2] | -| array_flow.rb:658:16:658:27 | call to source | array_flow.rb:658:5:658:5 | c [element 2] | -| array_flow.rb:659:5:659:5 | d [element] | array_flow.rb:661:10:661:10 | d [element] | -| array_flow.rb:659:5:659:5 | d [element] | array_flow.rb:661:10:661:10 | d [element] | -| array_flow.rb:659:9:659:9 | [post] c [element] | array_flow.rb:660:10:660:10 | c [element] | -| array_flow.rb:659:9:659:9 | [post] c [element] | array_flow.rb:660:10:660:10 | c [element] | -| array_flow.rb:659:9:659:9 | c [element 2] | array_flow.rb:659:9:659:9 | [post] c [element] | -| array_flow.rb:659:9:659:9 | c [element 2] | array_flow.rb:659:9:659:9 | [post] c [element] | -| array_flow.rb:659:9:659:9 | c [element 2] | array_flow.rb:659:9:659:47 | call to insert [element] | -| array_flow.rb:659:9:659:9 | c [element 2] | array_flow.rb:659:9:659:47 | call to insert [element] | -| array_flow.rb:659:9:659:47 | call to insert [element] | array_flow.rb:659:5:659:5 | d [element] | -| array_flow.rb:659:9:659:47 | call to insert [element] | array_flow.rb:659:5:659:5 | d [element] | -| array_flow.rb:659:21:659:32 | call to source | array_flow.rb:659:9:659:9 | [post] c [element] | -| array_flow.rb:659:21:659:32 | call to source | array_flow.rb:659:9:659:9 | [post] c [element] | -| array_flow.rb:659:21:659:32 | call to source | array_flow.rb:659:9:659:47 | call to insert [element] | -| array_flow.rb:659:21:659:32 | call to source | array_flow.rb:659:9:659:47 | call to insert [element] | -| array_flow.rb:659:35:659:46 | call to source | array_flow.rb:659:9:659:9 | [post] c [element] | -| array_flow.rb:659:35:659:46 | call to source | array_flow.rb:659:9:659:9 | [post] c [element] | -| array_flow.rb:659:35:659:46 | call to source | array_flow.rb:659:9:659:47 | call to insert [element] | -| array_flow.rb:659:35:659:46 | call to source | array_flow.rb:659:9:659:47 | call to insert [element] | -| array_flow.rb:660:10:660:10 | c [element] | array_flow.rb:660:10:660:13 | ...[...] | -| array_flow.rb:660:10:660:10 | c [element] | array_flow.rb:660:10:660:13 | ...[...] | -| array_flow.rb:661:10:661:10 | d [element] | array_flow.rb:661:10:661:13 | ...[...] | -| array_flow.rb:661:10:661:10 | d [element] | array_flow.rb:661:10:661:13 | ...[...] | -| array_flow.rb:672:5:672:5 | a [element 2] | array_flow.rb:673:9:673:9 | a [element 2] | -| array_flow.rb:672:5:672:5 | a [element 2] | array_flow.rb:673:9:673:9 | a [element 2] | -| array_flow.rb:672:16:672:27 | call to source | array_flow.rb:672:5:672:5 | a [element 2] | -| array_flow.rb:672:16:672:27 | call to source | array_flow.rb:672:5:672:5 | a [element 2] | -| array_flow.rb:673:5:673:5 | b [element] | array_flow.rb:674:10:674:10 | b [element] | -| array_flow.rb:673:5:673:5 | b [element] | array_flow.rb:674:10:674:10 | b [element] | -| array_flow.rb:673:9:673:9 | a [element 2] | array_flow.rb:673:9:673:60 | call to intersection [element] | -| array_flow.rb:673:9:673:9 | a [element 2] | array_flow.rb:673:9:673:60 | call to intersection [element] | -| array_flow.rb:673:9:673:60 | call to intersection [element] | array_flow.rb:673:5:673:5 | b [element] | -| array_flow.rb:673:9:673:60 | call to intersection [element] | array_flow.rb:673:5:673:5 | b [element] | -| array_flow.rb:673:31:673:42 | call to source | array_flow.rb:673:9:673:60 | call to intersection [element] | -| array_flow.rb:673:31:673:42 | call to source | array_flow.rb:673:9:673:60 | call to intersection [element] | -| array_flow.rb:673:47:673:58 | call to source | array_flow.rb:673:9:673:60 | call to intersection [element] | -| array_flow.rb:673:47:673:58 | call to source | array_flow.rb:673:9:673:60 | call to intersection [element] | -| array_flow.rb:674:10:674:10 | b [element] | array_flow.rb:674:10:674:13 | ...[...] | -| array_flow.rb:674:10:674:10 | b [element] | array_flow.rb:674:10:674:13 | ...[...] | -| array_flow.rb:678:5:678:5 | a [element 2] | array_flow.rb:679:9:679:9 | a [element 2] | -| array_flow.rb:678:5:678:5 | a [element 2] | array_flow.rb:679:9:679:9 | a [element 2] | -| array_flow.rb:678:16:678:25 | call to source | array_flow.rb:678:5:678:5 | a [element 2] | -| array_flow.rb:678:16:678:25 | call to source | array_flow.rb:678:5:678:5 | a [element 2] | -| array_flow.rb:679:5:679:5 | b [element] | array_flow.rb:684:10:684:10 | b [element] | -| array_flow.rb:679:5:679:5 | b [element] | array_flow.rb:684:10:684:10 | b [element] | -| array_flow.rb:679:9:679:9 | [post] a [element] | array_flow.rb:683:10:683:10 | a [element] | -| array_flow.rb:679:9:679:9 | [post] a [element] | array_flow.rb:683:10:683:10 | a [element] | -| array_flow.rb:679:9:679:9 | a [element 2] | array_flow.rb:679:9:679:9 | [post] a [element] | -| array_flow.rb:679:9:679:9 | a [element 2] | array_flow.rb:679:9:679:9 | [post] a [element] | -| array_flow.rb:679:9:679:9 | a [element 2] | array_flow.rb:679:9:682:7 | call to keep_if [element] | -| array_flow.rb:679:9:679:9 | a [element 2] | array_flow.rb:679:9:682:7 | call to keep_if [element] | -| array_flow.rb:679:9:679:9 | a [element 2] | array_flow.rb:679:23:679:23 | x | -| array_flow.rb:679:9:679:9 | a [element 2] | array_flow.rb:679:23:679:23 | x | -| array_flow.rb:679:9:682:7 | call to keep_if [element] | array_flow.rb:679:5:679:5 | b [element] | -| array_flow.rb:679:9:682:7 | call to keep_if [element] | array_flow.rb:679:5:679:5 | b [element] | -| array_flow.rb:679:23:679:23 | x | array_flow.rb:680:14:680:14 | x | -| array_flow.rb:679:23:679:23 | x | array_flow.rb:680:14:680:14 | x | -| array_flow.rb:683:10:683:10 | a [element] | array_flow.rb:683:10:683:13 | ...[...] | -| array_flow.rb:683:10:683:10 | a [element] | array_flow.rb:683:10:683:13 | ...[...] | -| array_flow.rb:684:10:684:10 | b [element] | array_flow.rb:684:10:684:13 | ...[...] | -| array_flow.rb:684:10:684:10 | b [element] | array_flow.rb:684:10:684:13 | ...[...] | -| array_flow.rb:688:5:688:5 | a [element 2] | array_flow.rb:690:10:690:10 | a [element 2] | -| array_flow.rb:688:5:688:5 | a [element 2] | array_flow.rb:690:10:690:10 | a [element 2] | -| array_flow.rb:688:5:688:5 | a [element 2] | array_flow.rb:691:9:691:9 | a [element 2] | -| array_flow.rb:688:5:688:5 | a [element 2] | array_flow.rb:691:9:691:9 | a [element 2] | -| array_flow.rb:688:16:688:27 | call to source | array_flow.rb:688:5:688:5 | a [element 2] | -| array_flow.rb:688:16:688:27 | call to source | array_flow.rb:688:5:688:5 | a [element 2] | -| array_flow.rb:689:5:689:5 | [post] a [element] | array_flow.rb:690:10:690:10 | a [element] | -| array_flow.rb:689:5:689:5 | [post] a [element] | array_flow.rb:690:10:690:10 | a [element] | -| array_flow.rb:689:5:689:5 | [post] a [element] | array_flow.rb:691:9:691:9 | a [element] | -| array_flow.rb:689:5:689:5 | [post] a [element] | array_flow.rb:691:9:691:9 | a [element] | -| array_flow.rb:689:12:689:23 | call to source | array_flow.rb:689:5:689:5 | [post] a [element] | -| array_flow.rb:689:12:689:23 | call to source | array_flow.rb:689:5:689:5 | [post] a [element] | -| array_flow.rb:690:10:690:10 | a [element 2] | array_flow.rb:690:10:690:15 | call to last | -| array_flow.rb:690:10:690:10 | a [element 2] | array_flow.rb:690:10:690:15 | call to last | -| array_flow.rb:690:10:690:10 | a [element] | array_flow.rb:690:10:690:15 | call to last | -| array_flow.rb:690:10:690:10 | a [element] | array_flow.rb:690:10:690:15 | call to last | -| array_flow.rb:691:5:691:5 | b [element] | array_flow.rb:692:10:692:10 | b [element] | -| array_flow.rb:691:5:691:5 | b [element] | array_flow.rb:692:10:692:10 | b [element] | -| array_flow.rb:691:5:691:5 | b [element] | array_flow.rb:693:10:693:10 | b [element] | -| array_flow.rb:691:5:691:5 | b [element] | array_flow.rb:693:10:693:10 | b [element] | -| array_flow.rb:691:9:691:9 | a [element 2] | array_flow.rb:691:9:691:17 | call to last [element] | -| array_flow.rb:691:9:691:9 | a [element 2] | array_flow.rb:691:9:691:17 | call to last [element] | -| array_flow.rb:691:9:691:9 | a [element] | array_flow.rb:691:9:691:17 | call to last [element] | -| array_flow.rb:691:9:691:9 | a [element] | array_flow.rb:691:9:691:17 | call to last [element] | -| array_flow.rb:691:9:691:17 | call to last [element] | array_flow.rb:691:5:691:5 | b [element] | -| array_flow.rb:691:9:691:17 | call to last [element] | array_flow.rb:691:5:691:5 | b [element] | -| array_flow.rb:692:10:692:10 | b [element] | array_flow.rb:692:10:692:13 | ...[...] | -| array_flow.rb:692:10:692:10 | b [element] | array_flow.rb:692:10:692:13 | ...[...] | -| array_flow.rb:693:10:693:10 | b [element] | array_flow.rb:693:10:693:13 | ...[...] | -| array_flow.rb:693:10:693:10 | b [element] | array_flow.rb:693:10:693:13 | ...[...] | -| array_flow.rb:697:5:697:5 | a [element 2] | array_flow.rb:698:9:698:9 | a [element 2] | -| array_flow.rb:697:5:697:5 | a [element 2] | array_flow.rb:698:9:698:9 | a [element 2] | -| array_flow.rb:697:16:697:27 | call to source | array_flow.rb:697:5:697:5 | a [element 2] | -| array_flow.rb:697:16:697:27 | call to source | array_flow.rb:697:5:697:5 | a [element 2] | -| array_flow.rb:698:5:698:5 | b [element] | array_flow.rb:702:10:702:10 | b [element] | -| array_flow.rb:698:5:698:5 | b [element] | array_flow.rb:702:10:702:10 | b [element] | -| array_flow.rb:698:9:698:9 | a [element 2] | array_flow.rb:698:19:698:19 | x | -| array_flow.rb:698:9:698:9 | a [element 2] | array_flow.rb:698:19:698:19 | x | -| array_flow.rb:698:9:701:7 | call to map [element] | array_flow.rb:698:5:698:5 | b [element] | -| array_flow.rb:698:9:701:7 | call to map [element] | array_flow.rb:698:5:698:5 | b [element] | -| array_flow.rb:698:19:698:19 | x | array_flow.rb:699:14:699:14 | x | -| array_flow.rb:698:19:698:19 | x | array_flow.rb:699:14:699:14 | x | -| array_flow.rb:700:9:700:19 | call to source | array_flow.rb:698:9:701:7 | call to map [element] | -| array_flow.rb:700:9:700:19 | call to source | array_flow.rb:698:9:701:7 | call to map [element] | -| array_flow.rb:702:10:702:10 | b [element] | array_flow.rb:702:10:702:13 | ...[...] | -| array_flow.rb:702:10:702:10 | b [element] | array_flow.rb:702:10:702:13 | ...[...] | -| array_flow.rb:706:5:706:5 | a [element 2] | array_flow.rb:707:9:707:9 | a [element 2] | -| array_flow.rb:706:5:706:5 | a [element 2] | array_flow.rb:707:9:707:9 | a [element 2] | -| array_flow.rb:706:16:706:27 | call to source | array_flow.rb:706:5:706:5 | a [element 2] | -| array_flow.rb:706:16:706:27 | call to source | array_flow.rb:706:5:706:5 | a [element 2] | -| array_flow.rb:707:5:707:5 | b [element] | array_flow.rb:711:10:711:10 | b [element] | -| array_flow.rb:707:5:707:5 | b [element] | array_flow.rb:711:10:711:10 | b [element] | -| array_flow.rb:707:9:707:9 | a [element 2] | array_flow.rb:707:20:707:20 | x | -| array_flow.rb:707:9:707:9 | a [element 2] | array_flow.rb:707:20:707:20 | x | -| array_flow.rb:707:9:710:7 | call to map! [element] | array_flow.rb:707:5:707:5 | b [element] | -| array_flow.rb:707:9:710:7 | call to map! [element] | array_flow.rb:707:5:707:5 | b [element] | -| array_flow.rb:707:20:707:20 | x | array_flow.rb:708:14:708:14 | x | -| array_flow.rb:707:20:707:20 | x | array_flow.rb:708:14:708:14 | x | -| array_flow.rb:709:9:709:19 | call to source | array_flow.rb:707:9:710:7 | call to map! [element] | -| array_flow.rb:709:9:709:19 | call to source | array_flow.rb:707:9:710:7 | call to map! [element] | -| array_flow.rb:711:10:711:10 | b [element] | array_flow.rb:711:10:711:13 | ...[...] | -| array_flow.rb:711:10:711:10 | b [element] | array_flow.rb:711:10:711:13 | ...[...] | -| array_flow.rb:715:5:715:5 | a [element 2] | array_flow.rb:718:9:718:9 | a [element 2] | -| array_flow.rb:715:5:715:5 | a [element 2] | array_flow.rb:718:9:718:9 | a [element 2] | -| array_flow.rb:715:5:715:5 | a [element 2] | array_flow.rb:722:9:722:9 | a [element 2] | -| array_flow.rb:715:5:715:5 | a [element 2] | array_flow.rb:722:9:722:9 | a [element 2] | -| array_flow.rb:715:5:715:5 | a [element 2] | array_flow.rb:726:9:726:9 | a [element 2] | -| array_flow.rb:715:5:715:5 | a [element 2] | array_flow.rb:726:9:726:9 | a [element 2] | -| array_flow.rb:715:5:715:5 | a [element 2] | array_flow.rb:734:9:734:9 | a [element 2] | -| array_flow.rb:715:5:715:5 | a [element 2] | array_flow.rb:734:9:734:9 | a [element 2] | -| array_flow.rb:715:16:715:25 | call to source | array_flow.rb:715:5:715:5 | a [element 2] | -| array_flow.rb:715:16:715:25 | call to source | array_flow.rb:715:5:715:5 | a [element 2] | -| array_flow.rb:718:5:718:5 | b | array_flow.rb:719:10:719:10 | b | -| array_flow.rb:718:5:718:5 | b | array_flow.rb:719:10:719:10 | b | -| array_flow.rb:718:9:718:9 | a [element 2] | array_flow.rb:718:9:718:13 | call to max | -| array_flow.rb:718:9:718:9 | a [element 2] | array_flow.rb:718:9:718:13 | call to max | -| array_flow.rb:718:9:718:13 | call to max | array_flow.rb:718:5:718:5 | b | -| array_flow.rb:718:9:718:13 | call to max | array_flow.rb:718:5:718:5 | b | -| array_flow.rb:722:5:722:5 | c [element] | array_flow.rb:723:10:723:10 | c [element] | -| array_flow.rb:722:5:722:5 | c [element] | array_flow.rb:723:10:723:10 | c [element] | -| array_flow.rb:722:9:722:9 | a [element 2] | array_flow.rb:722:9:722:16 | call to max [element] | -| array_flow.rb:722:9:722:9 | a [element 2] | array_flow.rb:722:9:722:16 | call to max [element] | -| array_flow.rb:722:9:722:16 | call to max [element] | array_flow.rb:722:5:722:5 | c [element] | -| array_flow.rb:722:9:722:16 | call to max [element] | array_flow.rb:722:5:722:5 | c [element] | -| array_flow.rb:723:10:723:10 | c [element] | array_flow.rb:723:10:723:13 | ...[...] | -| array_flow.rb:723:10:723:10 | c [element] | array_flow.rb:723:10:723:13 | ...[...] | -| array_flow.rb:726:5:726:5 | d | array_flow.rb:731:10:731:10 | d | -| array_flow.rb:726:5:726:5 | d | array_flow.rb:731:10:731:10 | d | -| array_flow.rb:726:9:726:9 | a [element 2] | array_flow.rb:726:9:730:7 | call to max | -| array_flow.rb:726:9:726:9 | a [element 2] | array_flow.rb:726:9:730:7 | call to max | -| array_flow.rb:726:9:726:9 | a [element 2] | array_flow.rb:726:19:726:19 | x | -| array_flow.rb:726:9:726:9 | a [element 2] | array_flow.rb:726:19:726:19 | x | -| array_flow.rb:726:9:726:9 | a [element 2] | array_flow.rb:726:22:726:22 | y | -| array_flow.rb:726:9:726:9 | a [element 2] | array_flow.rb:726:22:726:22 | y | -| array_flow.rb:726:9:730:7 | call to max | array_flow.rb:726:5:726:5 | d | -| array_flow.rb:726:9:730:7 | call to max | array_flow.rb:726:5:726:5 | d | -| array_flow.rb:726:19:726:19 | x | array_flow.rb:727:14:727:14 | x | -| array_flow.rb:726:19:726:19 | x | array_flow.rb:727:14:727:14 | x | -| array_flow.rb:726:22:726:22 | y | array_flow.rb:728:14:728:14 | y | -| array_flow.rb:726:22:726:22 | y | array_flow.rb:728:14:728:14 | y | -| array_flow.rb:734:5:734:5 | e [element] | array_flow.rb:739:10:739:10 | e [element] | -| array_flow.rb:734:5:734:5 | e [element] | array_flow.rb:739:10:739:10 | e [element] | -| array_flow.rb:734:9:734:9 | a [element 2] | array_flow.rb:734:9:738:7 | call to max [element] | -| array_flow.rb:734:9:734:9 | a [element 2] | array_flow.rb:734:9:738:7 | call to max [element] | -| array_flow.rb:734:9:734:9 | a [element 2] | array_flow.rb:734:22:734:22 | x | -| array_flow.rb:734:9:734:9 | a [element 2] | array_flow.rb:734:22:734:22 | x | -| array_flow.rb:734:9:734:9 | a [element 2] | array_flow.rb:734:25:734:25 | y | -| array_flow.rb:734:9:734:9 | a [element 2] | array_flow.rb:734:25:734:25 | y | -| array_flow.rb:734:9:738:7 | call to max [element] | array_flow.rb:734:5:734:5 | e [element] | -| array_flow.rb:734:9:738:7 | call to max [element] | array_flow.rb:734:5:734:5 | e [element] | -| array_flow.rb:734:22:734:22 | x | array_flow.rb:735:14:735:14 | x | -| array_flow.rb:734:22:734:22 | x | array_flow.rb:735:14:735:14 | x | -| array_flow.rb:734:25:734:25 | y | array_flow.rb:736:14:736:14 | y | -| array_flow.rb:734:25:734:25 | y | array_flow.rb:736:14:736:14 | y | -| array_flow.rb:739:10:739:10 | e [element] | array_flow.rb:739:10:739:13 | ...[...] | -| array_flow.rb:739:10:739:10 | e [element] | array_flow.rb:739:10:739:13 | ...[...] | -| array_flow.rb:743:5:743:5 | a [element 2] | array_flow.rb:746:9:746:9 | a [element 2] | -| array_flow.rb:743:5:743:5 | a [element 2] | array_flow.rb:746:9:746:9 | a [element 2] | -| array_flow.rb:743:5:743:5 | a [element 2] | array_flow.rb:753:9:753:9 | a [element 2] | -| array_flow.rb:743:5:743:5 | a [element 2] | array_flow.rb:753:9:753:9 | a [element 2] | -| array_flow.rb:743:16:743:25 | call to source | array_flow.rb:743:5:743:5 | a [element 2] | -| array_flow.rb:743:16:743:25 | call to source | array_flow.rb:743:5:743:5 | a [element 2] | -| array_flow.rb:746:5:746:5 | b | array_flow.rb:750:10:750:10 | b | -| array_flow.rb:746:5:746:5 | b | array_flow.rb:750:10:750:10 | b | -| array_flow.rb:746:9:746:9 | a [element 2] | array_flow.rb:746:9:749:7 | call to max_by | -| array_flow.rb:746:9:746:9 | a [element 2] | array_flow.rb:746:9:749:7 | call to max_by | -| array_flow.rb:746:9:746:9 | a [element 2] | array_flow.rb:746:22:746:22 | x | -| array_flow.rb:746:9:746:9 | a [element 2] | array_flow.rb:746:22:746:22 | x | -| array_flow.rb:746:9:749:7 | call to max_by | array_flow.rb:746:5:746:5 | b | -| array_flow.rb:746:9:749:7 | call to max_by | array_flow.rb:746:5:746:5 | b | -| array_flow.rb:746:22:746:22 | x | array_flow.rb:747:14:747:14 | x | -| array_flow.rb:746:22:746:22 | x | array_flow.rb:747:14:747:14 | x | -| array_flow.rb:753:5:753:5 | c [element] | array_flow.rb:757:10:757:10 | c [element] | -| array_flow.rb:753:5:753:5 | c [element] | array_flow.rb:757:10:757:10 | c [element] | -| array_flow.rb:753:9:753:9 | a [element 2] | array_flow.rb:753:9:756:7 | call to max_by [element] | -| array_flow.rb:753:9:753:9 | a [element 2] | array_flow.rb:753:9:756:7 | call to max_by [element] | -| array_flow.rb:753:9:753:9 | a [element 2] | array_flow.rb:753:25:753:25 | x | -| array_flow.rb:753:9:753:9 | a [element 2] | array_flow.rb:753:25:753:25 | x | -| array_flow.rb:753:9:756:7 | call to max_by [element] | array_flow.rb:753:5:753:5 | c [element] | -| array_flow.rb:753:9:756:7 | call to max_by [element] | array_flow.rb:753:5:753:5 | c [element] | -| array_flow.rb:753:25:753:25 | x | array_flow.rb:754:14:754:14 | x | -| array_flow.rb:753:25:753:25 | x | array_flow.rb:754:14:754:14 | x | -| array_flow.rb:757:10:757:10 | c [element] | array_flow.rb:757:10:757:13 | ...[...] | -| array_flow.rb:757:10:757:10 | c [element] | array_flow.rb:757:10:757:13 | ...[...] | -| array_flow.rb:761:5:761:5 | a [element 2] | array_flow.rb:764:9:764:9 | a [element 2] | -| array_flow.rb:761:5:761:5 | a [element 2] | array_flow.rb:764:9:764:9 | a [element 2] | -| array_flow.rb:761:5:761:5 | a [element 2] | array_flow.rb:768:9:768:9 | a [element 2] | -| array_flow.rb:761:5:761:5 | a [element 2] | array_flow.rb:768:9:768:9 | a [element 2] | -| array_flow.rb:761:5:761:5 | a [element 2] | array_flow.rb:772:9:772:9 | a [element 2] | -| array_flow.rb:761:5:761:5 | a [element 2] | array_flow.rb:772:9:772:9 | a [element 2] | -| array_flow.rb:761:5:761:5 | a [element 2] | array_flow.rb:780:9:780:9 | a [element 2] | -| array_flow.rb:761:5:761:5 | a [element 2] | array_flow.rb:780:9:780:9 | a [element 2] | -| array_flow.rb:761:16:761:25 | call to source | array_flow.rb:761:5:761:5 | a [element 2] | -| array_flow.rb:761:16:761:25 | call to source | array_flow.rb:761:5:761:5 | a [element 2] | -| array_flow.rb:764:5:764:5 | b | array_flow.rb:765:10:765:10 | b | -| array_flow.rb:764:5:764:5 | b | array_flow.rb:765:10:765:10 | b | -| array_flow.rb:764:9:764:9 | a [element 2] | array_flow.rb:764:9:764:13 | call to min | -| array_flow.rb:764:9:764:9 | a [element 2] | array_flow.rb:764:9:764:13 | call to min | -| array_flow.rb:764:9:764:13 | call to min | array_flow.rb:764:5:764:5 | b | -| array_flow.rb:764:9:764:13 | call to min | array_flow.rb:764:5:764:5 | b | -| array_flow.rb:768:5:768:5 | c [element] | array_flow.rb:769:10:769:10 | c [element] | -| array_flow.rb:768:5:768:5 | c [element] | array_flow.rb:769:10:769:10 | c [element] | -| array_flow.rb:768:9:768:9 | a [element 2] | array_flow.rb:768:9:768:16 | call to min [element] | -| array_flow.rb:768:9:768:9 | a [element 2] | array_flow.rb:768:9:768:16 | call to min [element] | -| array_flow.rb:768:9:768:16 | call to min [element] | array_flow.rb:768:5:768:5 | c [element] | -| array_flow.rb:768:9:768:16 | call to min [element] | array_flow.rb:768:5:768:5 | c [element] | -| array_flow.rb:769:10:769:10 | c [element] | array_flow.rb:769:10:769:13 | ...[...] | -| array_flow.rb:769:10:769:10 | c [element] | array_flow.rb:769:10:769:13 | ...[...] | -| array_flow.rb:772:5:772:5 | d | array_flow.rb:777:10:777:10 | d | -| array_flow.rb:772:5:772:5 | d | array_flow.rb:777:10:777:10 | d | -| array_flow.rb:772:9:772:9 | a [element 2] | array_flow.rb:772:9:776:7 | call to min | -| array_flow.rb:772:9:772:9 | a [element 2] | array_flow.rb:772:9:776:7 | call to min | -| array_flow.rb:772:9:772:9 | a [element 2] | array_flow.rb:772:19:772:19 | x | -| array_flow.rb:772:9:772:9 | a [element 2] | array_flow.rb:772:19:772:19 | x | -| array_flow.rb:772:9:772:9 | a [element 2] | array_flow.rb:772:22:772:22 | y | -| array_flow.rb:772:9:772:9 | a [element 2] | array_flow.rb:772:22:772:22 | y | -| array_flow.rb:772:9:776:7 | call to min | array_flow.rb:772:5:772:5 | d | -| array_flow.rb:772:9:776:7 | call to min | array_flow.rb:772:5:772:5 | d | -| array_flow.rb:772:19:772:19 | x | array_flow.rb:773:14:773:14 | x | -| array_flow.rb:772:19:772:19 | x | array_flow.rb:773:14:773:14 | x | -| array_flow.rb:772:22:772:22 | y | array_flow.rb:774:14:774:14 | y | -| array_flow.rb:772:22:772:22 | y | array_flow.rb:774:14:774:14 | y | -| array_flow.rb:780:5:780:5 | e [element] | array_flow.rb:785:10:785:10 | e [element] | -| array_flow.rb:780:5:780:5 | e [element] | array_flow.rb:785:10:785:10 | e [element] | -| array_flow.rb:780:9:780:9 | a [element 2] | array_flow.rb:780:9:784:7 | call to min [element] | -| array_flow.rb:780:9:780:9 | a [element 2] | array_flow.rb:780:9:784:7 | call to min [element] | -| array_flow.rb:780:9:780:9 | a [element 2] | array_flow.rb:780:22:780:22 | x | -| array_flow.rb:780:9:780:9 | a [element 2] | array_flow.rb:780:22:780:22 | x | -| array_flow.rb:780:9:780:9 | a [element 2] | array_flow.rb:780:25:780:25 | y | -| array_flow.rb:780:9:780:9 | a [element 2] | array_flow.rb:780:25:780:25 | y | -| array_flow.rb:780:9:784:7 | call to min [element] | array_flow.rb:780:5:780:5 | e [element] | -| array_flow.rb:780:9:784:7 | call to min [element] | array_flow.rb:780:5:780:5 | e [element] | -| array_flow.rb:780:22:780:22 | x | array_flow.rb:781:14:781:14 | x | -| array_flow.rb:780:22:780:22 | x | array_flow.rb:781:14:781:14 | x | -| array_flow.rb:780:25:780:25 | y | array_flow.rb:782:14:782:14 | y | -| array_flow.rb:780:25:780:25 | y | array_flow.rb:782:14:782:14 | y | -| array_flow.rb:785:10:785:10 | e [element] | array_flow.rb:785:10:785:13 | ...[...] | -| array_flow.rb:785:10:785:10 | e [element] | array_flow.rb:785:10:785:13 | ...[...] | -| array_flow.rb:789:5:789:5 | a [element 2] | array_flow.rb:792:9:792:9 | a [element 2] | -| array_flow.rb:789:5:789:5 | a [element 2] | array_flow.rb:792:9:792:9 | a [element 2] | -| array_flow.rb:789:5:789:5 | a [element 2] | array_flow.rb:799:9:799:9 | a [element 2] | -| array_flow.rb:789:5:789:5 | a [element 2] | array_flow.rb:799:9:799:9 | a [element 2] | -| array_flow.rb:789:16:789:25 | call to source | array_flow.rb:789:5:789:5 | a [element 2] | -| array_flow.rb:789:16:789:25 | call to source | array_flow.rb:789:5:789:5 | a [element 2] | -| array_flow.rb:792:5:792:5 | b | array_flow.rb:796:10:796:10 | b | -| array_flow.rb:792:5:792:5 | b | array_flow.rb:796:10:796:10 | b | -| array_flow.rb:792:9:792:9 | a [element 2] | array_flow.rb:792:9:795:7 | call to min_by | -| array_flow.rb:792:9:792:9 | a [element 2] | array_flow.rb:792:9:795:7 | call to min_by | -| array_flow.rb:792:9:792:9 | a [element 2] | array_flow.rb:792:22:792:22 | x | -| array_flow.rb:792:9:792:9 | a [element 2] | array_flow.rb:792:22:792:22 | x | -| array_flow.rb:792:9:795:7 | call to min_by | array_flow.rb:792:5:792:5 | b | -| array_flow.rb:792:9:795:7 | call to min_by | array_flow.rb:792:5:792:5 | b | -| array_flow.rb:792:22:792:22 | x | array_flow.rb:793:14:793:14 | x | -| array_flow.rb:792:22:792:22 | x | array_flow.rb:793:14:793:14 | x | -| array_flow.rb:799:5:799:5 | c [element] | array_flow.rb:803:10:803:10 | c [element] | -| array_flow.rb:799:5:799:5 | c [element] | array_flow.rb:803:10:803:10 | c [element] | -| array_flow.rb:799:9:799:9 | a [element 2] | array_flow.rb:799:9:802:7 | call to min_by [element] | -| array_flow.rb:799:9:799:9 | a [element 2] | array_flow.rb:799:9:802:7 | call to min_by [element] | -| array_flow.rb:799:9:799:9 | a [element 2] | array_flow.rb:799:25:799:25 | x | -| array_flow.rb:799:9:799:9 | a [element 2] | array_flow.rb:799:25:799:25 | x | -| array_flow.rb:799:9:802:7 | call to min_by [element] | array_flow.rb:799:5:799:5 | c [element] | -| array_flow.rb:799:9:802:7 | call to min_by [element] | array_flow.rb:799:5:799:5 | c [element] | -| array_flow.rb:799:25:799:25 | x | array_flow.rb:800:14:800:14 | x | -| array_flow.rb:799:25:799:25 | x | array_flow.rb:800:14:800:14 | x | -| array_flow.rb:803:10:803:10 | c [element] | array_flow.rb:803:10:803:13 | ...[...] | -| array_flow.rb:803:10:803:10 | c [element] | array_flow.rb:803:10:803:13 | ...[...] | -| array_flow.rb:807:5:807:5 | a [element 2] | array_flow.rb:809:9:809:9 | a [element 2] | -| array_flow.rb:807:5:807:5 | a [element 2] | array_flow.rb:809:9:809:9 | a [element 2] | -| array_flow.rb:807:5:807:5 | a [element 2] | array_flow.rb:813:9:813:9 | a [element 2] | -| array_flow.rb:807:5:807:5 | a [element 2] | array_flow.rb:813:9:813:9 | a [element 2] | -| array_flow.rb:807:16:807:25 | call to source | array_flow.rb:807:5:807:5 | a [element 2] | -| array_flow.rb:807:16:807:25 | call to source | array_flow.rb:807:5:807:5 | a [element 2] | -| array_flow.rb:809:5:809:5 | b [element] | array_flow.rb:810:10:810:10 | b [element] | -| array_flow.rb:809:5:809:5 | b [element] | array_flow.rb:810:10:810:10 | b [element] | -| array_flow.rb:809:5:809:5 | b [element] | array_flow.rb:811:10:811:10 | b [element] | -| array_flow.rb:809:5:809:5 | b [element] | array_flow.rb:811:10:811:10 | b [element] | -| array_flow.rb:809:9:809:9 | a [element 2] | array_flow.rb:809:9:809:16 | call to minmax [element] | -| array_flow.rb:809:9:809:9 | a [element 2] | array_flow.rb:809:9:809:16 | call to minmax [element] | -| array_flow.rb:809:9:809:16 | call to minmax [element] | array_flow.rb:809:5:809:5 | b [element] | -| array_flow.rb:809:9:809:16 | call to minmax [element] | array_flow.rb:809:5:809:5 | b [element] | -| array_flow.rb:810:10:810:10 | b [element] | array_flow.rb:810:10:810:13 | ...[...] | -| array_flow.rb:810:10:810:10 | b [element] | array_flow.rb:810:10:810:13 | ...[...] | -| array_flow.rb:811:10:811:10 | b [element] | array_flow.rb:811:10:811:13 | ...[...] | -| array_flow.rb:811:10:811:10 | b [element] | array_flow.rb:811:10:811:13 | ...[...] | -| array_flow.rb:813:5:813:5 | c [element] | array_flow.rb:818:10:818:10 | c [element] | -| array_flow.rb:813:5:813:5 | c [element] | array_flow.rb:818:10:818:10 | c [element] | -| array_flow.rb:813:5:813:5 | c [element] | array_flow.rb:819:10:819:10 | c [element] | -| array_flow.rb:813:5:813:5 | c [element] | array_flow.rb:819:10:819:10 | c [element] | -| array_flow.rb:813:9:813:9 | a [element 2] | array_flow.rb:813:9:817:7 | call to minmax [element] | -| array_flow.rb:813:9:813:9 | a [element 2] | array_flow.rb:813:9:817:7 | call to minmax [element] | -| array_flow.rb:813:9:813:9 | a [element 2] | array_flow.rb:813:22:813:22 | x | -| array_flow.rb:813:9:813:9 | a [element 2] | array_flow.rb:813:22:813:22 | x | -| array_flow.rb:813:9:813:9 | a [element 2] | array_flow.rb:813:25:813:25 | y | -| array_flow.rb:813:9:813:9 | a [element 2] | array_flow.rb:813:25:813:25 | y | -| array_flow.rb:813:9:817:7 | call to minmax [element] | array_flow.rb:813:5:813:5 | c [element] | -| array_flow.rb:813:9:817:7 | call to minmax [element] | array_flow.rb:813:5:813:5 | c [element] | -| array_flow.rb:813:22:813:22 | x | array_flow.rb:814:14:814:14 | x | -| array_flow.rb:813:22:813:22 | x | array_flow.rb:814:14:814:14 | x | -| array_flow.rb:813:25:813:25 | y | array_flow.rb:815:14:815:14 | y | -| array_flow.rb:813:25:813:25 | y | array_flow.rb:815:14:815:14 | y | -| array_flow.rb:818:10:818:10 | c [element] | array_flow.rb:818:10:818:13 | ...[...] | -| array_flow.rb:818:10:818:10 | c [element] | array_flow.rb:818:10:818:13 | ...[...] | -| array_flow.rb:819:10:819:10 | c [element] | array_flow.rb:819:10:819:13 | ...[...] | -| array_flow.rb:819:10:819:10 | c [element] | array_flow.rb:819:10:819:13 | ...[...] | -| array_flow.rb:823:5:823:5 | a [element 2] | array_flow.rb:824:9:824:9 | a [element 2] | -| array_flow.rb:823:5:823:5 | a [element 2] | array_flow.rb:824:9:824:9 | a [element 2] | -| array_flow.rb:823:16:823:25 | call to source | array_flow.rb:823:5:823:5 | a [element 2] | -| array_flow.rb:823:16:823:25 | call to source | array_flow.rb:823:5:823:5 | a [element 2] | -| array_flow.rb:824:5:824:5 | b [element] | array_flow.rb:828:10:828:10 | b [element] | -| array_flow.rb:824:5:824:5 | b [element] | array_flow.rb:828:10:828:10 | b [element] | -| array_flow.rb:824:5:824:5 | b [element] | array_flow.rb:829:10:829:10 | b [element] | -| array_flow.rb:824:5:824:5 | b [element] | array_flow.rb:829:10:829:10 | b [element] | -| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:9:827:7 | call to minmax_by [element] | -| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:9:827:7 | call to minmax_by [element] | -| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:25:824:25 | x | -| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:25:824:25 | x | -| array_flow.rb:824:9:827:7 | call to minmax_by [element] | array_flow.rb:824:5:824:5 | b [element] | -| array_flow.rb:824:9:827:7 | call to minmax_by [element] | array_flow.rb:824:5:824:5 | b [element] | -| array_flow.rb:824:25:824:25 | x | array_flow.rb:825:14:825:14 | x | -| array_flow.rb:824:25:824:25 | x | array_flow.rb:825:14:825:14 | x | -| array_flow.rb:828:10:828:10 | b [element] | array_flow.rb:828:10:828:13 | ...[...] | -| array_flow.rb:828:10:828:10 | b [element] | array_flow.rb:828:10:828:13 | ...[...] | -| array_flow.rb:829:10:829:10 | b [element] | array_flow.rb:829:10:829:13 | ...[...] | -| array_flow.rb:829:10:829:10 | b [element] | array_flow.rb:829:10:829:13 | ...[...] | -| array_flow.rb:833:5:833:5 | a [element 2] | array_flow.rb:834:5:834:5 | a [element 2] | -| array_flow.rb:833:5:833:5 | a [element 2] | array_flow.rb:834:5:834:5 | a [element 2] | -| array_flow.rb:833:16:833:25 | call to source | array_flow.rb:833:5:833:5 | a [element 2] | -| array_flow.rb:833:16:833:25 | call to source | array_flow.rb:833:5:833:5 | a [element 2] | -| array_flow.rb:834:5:834:5 | a [element 2] | array_flow.rb:834:17:834:17 | x | -| array_flow.rb:834:5:834:5 | a [element 2] | array_flow.rb:834:17:834:17 | x | -| array_flow.rb:834:17:834:17 | x | array_flow.rb:835:14:835:14 | x | -| array_flow.rb:834:17:834:17 | x | array_flow.rb:835:14:835:14 | x | -| array_flow.rb:842:5:842:5 | a [element 2] | array_flow.rb:843:5:843:5 | a [element 2] | -| array_flow.rb:842:5:842:5 | a [element 2] | array_flow.rb:843:5:843:5 | a [element 2] | -| array_flow.rb:842:16:842:25 | call to source | array_flow.rb:842:5:842:5 | a [element 2] | -| array_flow.rb:842:16:842:25 | call to source | array_flow.rb:842:5:842:5 | a [element 2] | -| array_flow.rb:843:5:843:5 | a [element 2] | array_flow.rb:843:16:843:16 | x | -| array_flow.rb:843:5:843:5 | a [element 2] | array_flow.rb:843:16:843:16 | x | -| array_flow.rb:843:16:843:16 | x | array_flow.rb:844:14:844:14 | x | -| array_flow.rb:843:16:843:16 | x | array_flow.rb:844:14:844:14 | x | -| array_flow.rb:849:5:849:5 | a [element 2] | array_flow.rb:850:9:850:9 | a [element 2] | -| array_flow.rb:849:16:849:25 | call to source | array_flow.rb:849:5:849:5 | a [element 2] | -| array_flow.rb:850:5:850:5 | b | array_flow.rb:851:10:851:10 | b | -| array_flow.rb:850:9:850:9 | a [element 2] | array_flow.rb:850:9:850:20 | call to pack | -| array_flow.rb:850:9:850:20 | call to pack | array_flow.rb:850:5:850:5 | b | -| array_flow.rb:855:5:855:5 | a [element 2] | array_flow.rb:856:9:856:9 | a [element 2] | -| array_flow.rb:855:5:855:5 | a [element 2] | array_flow.rb:856:9:856:9 | a [element 2] | -| array_flow.rb:855:16:855:25 | call to source | array_flow.rb:855:5:855:5 | a [element 2] | -| array_flow.rb:855:16:855:25 | call to source | array_flow.rb:855:5:855:5 | a [element 2] | -| array_flow.rb:856:5:856:5 | b [element, element] | array_flow.rb:860:10:860:10 | b [element, element] | -| array_flow.rb:856:5:856:5 | b [element, element] | array_flow.rb:860:10:860:10 | b [element, element] | -| array_flow.rb:856:5:856:5 | b [element, element] | array_flow.rb:861:10:861:10 | b [element, element] | -| array_flow.rb:856:5:856:5 | b [element, element] | array_flow.rb:861:10:861:10 | b [element, element] | -| array_flow.rb:856:9:856:9 | a [element 2] | array_flow.rb:856:9:859:7 | call to partition [element, element] | -| array_flow.rb:856:9:856:9 | a [element 2] | array_flow.rb:856:9:859:7 | call to partition [element, element] | -| array_flow.rb:856:9:856:9 | a [element 2] | array_flow.rb:856:25:856:25 | x | -| array_flow.rb:856:9:856:9 | a [element 2] | array_flow.rb:856:25:856:25 | x | -| array_flow.rb:856:9:859:7 | call to partition [element, element] | array_flow.rb:856:5:856:5 | b [element, element] | -| array_flow.rb:856:9:859:7 | call to partition [element, element] | array_flow.rb:856:5:856:5 | b [element, element] | -| array_flow.rb:856:25:856:25 | x | array_flow.rb:857:14:857:14 | x | -| array_flow.rb:856:25:856:25 | x | array_flow.rb:857:14:857:14 | x | -| array_flow.rb:860:10:860:10 | b [element, element] | array_flow.rb:860:10:860:13 | ...[...] [element] | -| array_flow.rb:860:10:860:10 | b [element, element] | array_flow.rb:860:10:860:13 | ...[...] [element] | -| array_flow.rb:860:10:860:13 | ...[...] [element] | array_flow.rb:860:10:860:16 | ...[...] | -| array_flow.rb:860:10:860:13 | ...[...] [element] | array_flow.rb:860:10:860:16 | ...[...] | -| array_flow.rb:861:10:861:10 | b [element, element] | array_flow.rb:861:10:861:13 | ...[...] [element] | -| array_flow.rb:861:10:861:10 | b [element, element] | array_flow.rb:861:10:861:13 | ...[...] [element] | -| array_flow.rb:861:10:861:13 | ...[...] [element] | array_flow.rb:861:10:861:16 | ...[...] | -| array_flow.rb:861:10:861:13 | ...[...] [element] | array_flow.rb:861:10:861:16 | ...[...] | -| array_flow.rb:865:5:865:5 | a [element 2] | array_flow.rb:867:9:867:9 | a [element 2] | -| array_flow.rb:865:5:865:5 | a [element 2] | array_flow.rb:867:9:867:9 | a [element 2] | -| array_flow.rb:865:5:865:5 | a [element 2] | array_flow.rb:875:9:875:9 | a [element 2] | -| array_flow.rb:865:5:865:5 | a [element 2] | array_flow.rb:875:9:875:9 | a [element 2] | -| array_flow.rb:865:5:865:5 | a [element 2] | array_flow.rb:882:9:882:9 | a [element 2] | -| array_flow.rb:865:5:865:5 | a [element 2] | array_flow.rb:882:9:882:9 | a [element 2] | -| array_flow.rb:865:16:865:25 | call to source | array_flow.rb:865:5:865:5 | a [element 2] | -| array_flow.rb:865:16:865:25 | call to source | array_flow.rb:865:5:865:5 | a [element 2] | -| array_flow.rb:867:5:867:5 | b [element 2] | array_flow.rb:873:10:873:10 | b [element 2] | -| array_flow.rb:867:5:867:5 | b [element 2] | array_flow.rb:873:10:873:10 | b [element 2] | -| array_flow.rb:867:9:867:9 | a [element 2] | array_flow.rb:867:9:871:7 | call to permutation [element 2] | -| array_flow.rb:867:9:867:9 | a [element 2] | array_flow.rb:867:9:871:7 | call to permutation [element 2] | -| array_flow.rb:867:9:867:9 | a [element 2] | array_flow.rb:867:27:867:27 | x [element] | -| array_flow.rb:867:9:867:9 | a [element 2] | array_flow.rb:867:27:867:27 | x [element] | -| array_flow.rb:867:9:871:7 | call to permutation [element 2] | array_flow.rb:867:5:867:5 | b [element 2] | -| array_flow.rb:867:9:871:7 | call to permutation [element 2] | array_flow.rb:867:5:867:5 | b [element 2] | -| array_flow.rb:867:27:867:27 | x [element] | array_flow.rb:868:14:868:14 | x [element] | -| array_flow.rb:867:27:867:27 | x [element] | array_flow.rb:868:14:868:14 | x [element] | -| array_flow.rb:867:27:867:27 | x [element] | array_flow.rb:869:14:869:14 | x [element] | -| array_flow.rb:867:27:867:27 | x [element] | array_flow.rb:869:14:869:14 | x [element] | -| array_flow.rb:867:27:867:27 | x [element] | array_flow.rb:870:14:870:14 | x [element] | -| array_flow.rb:867:27:867:27 | x [element] | array_flow.rb:870:14:870:14 | x [element] | -| array_flow.rb:868:14:868:14 | x [element] | array_flow.rb:868:14:868:17 | ...[...] | -| array_flow.rb:868:14:868:14 | x [element] | array_flow.rb:868:14:868:17 | ...[...] | -| array_flow.rb:869:14:869:14 | x [element] | array_flow.rb:869:14:869:17 | ...[...] | -| array_flow.rb:869:14:869:14 | x [element] | array_flow.rb:869:14:869:17 | ...[...] | -| array_flow.rb:870:14:870:14 | x [element] | array_flow.rb:870:14:870:17 | ...[...] | -| array_flow.rb:870:14:870:14 | x [element] | array_flow.rb:870:14:870:17 | ...[...] | -| array_flow.rb:873:10:873:10 | b [element 2] | array_flow.rb:873:10:873:13 | ...[...] | -| array_flow.rb:873:10:873:10 | b [element 2] | array_flow.rb:873:10:873:13 | ...[...] | -| array_flow.rb:875:5:875:5 | c [element 2] | array_flow.rb:880:10:880:10 | c [element 2] | -| array_flow.rb:875:5:875:5 | c [element 2] | array_flow.rb:880:10:880:10 | c [element 2] | -| array_flow.rb:875:5:875:5 | c [element 2] | array_flow.rb:887:10:887:10 | c [element 2] | -| array_flow.rb:875:5:875:5 | c [element 2] | array_flow.rb:887:10:887:10 | c [element 2] | -| array_flow.rb:875:9:875:9 | a [element 2] | array_flow.rb:875:9:878:7 | call to permutation [element 2] | -| array_flow.rb:875:9:875:9 | a [element 2] | array_flow.rb:875:9:878:7 | call to permutation [element 2] | -| array_flow.rb:875:9:875:9 | a [element 2] | array_flow.rb:875:30:875:30 | x [element] | -| array_flow.rb:875:9:875:9 | a [element 2] | array_flow.rb:875:30:875:30 | x [element] | -| array_flow.rb:875:9:878:7 | call to permutation [element 2] | array_flow.rb:875:5:875:5 | c [element 2] | -| array_flow.rb:875:9:878:7 | call to permutation [element 2] | array_flow.rb:875:5:875:5 | c [element 2] | -| array_flow.rb:875:30:875:30 | x [element] | array_flow.rb:876:14:876:14 | x [element] | -| array_flow.rb:875:30:875:30 | x [element] | array_flow.rb:876:14:876:14 | x [element] | -| array_flow.rb:875:30:875:30 | x [element] | array_flow.rb:877:14:877:14 | x [element] | -| array_flow.rb:875:30:875:30 | x [element] | array_flow.rb:877:14:877:14 | x [element] | -| array_flow.rb:876:14:876:14 | x [element] | array_flow.rb:876:14:876:17 | ...[...] | -| array_flow.rb:876:14:876:14 | x [element] | array_flow.rb:876:14:876:17 | ...[...] | -| array_flow.rb:877:14:877:14 | x [element] | array_flow.rb:877:14:877:17 | ...[...] | -| array_flow.rb:877:14:877:14 | x [element] | array_flow.rb:877:14:877:17 | ...[...] | -| array_flow.rb:880:10:880:10 | c [element 2] | array_flow.rb:880:10:880:13 | ...[...] | -| array_flow.rb:880:10:880:10 | c [element 2] | array_flow.rb:880:10:880:13 | ...[...] | -| array_flow.rb:882:9:882:9 | a [element 2] | array_flow.rb:882:30:882:30 | x [element] | -| array_flow.rb:882:9:882:9 | a [element 2] | array_flow.rb:882:30:882:30 | x [element] | -| array_flow.rb:882:30:882:30 | x [element] | array_flow.rb:883:14:883:14 | x [element] | -| array_flow.rb:882:30:882:30 | x [element] | array_flow.rb:883:14:883:14 | x [element] | -| array_flow.rb:882:30:882:30 | x [element] | array_flow.rb:884:14:884:14 | x [element] | -| array_flow.rb:882:30:882:30 | x [element] | array_flow.rb:884:14:884:14 | x [element] | -| array_flow.rb:883:14:883:14 | x [element] | array_flow.rb:883:14:883:17 | ...[...] | -| array_flow.rb:883:14:883:14 | x [element] | array_flow.rb:883:14:883:17 | ...[...] | -| array_flow.rb:884:14:884:14 | x [element] | array_flow.rb:884:14:884:17 | ...[...] | -| array_flow.rb:884:14:884:14 | x [element] | array_flow.rb:884:14:884:17 | ...[...] | -| array_flow.rb:887:10:887:10 | c [element 2] | array_flow.rb:887:10:887:13 | ...[...] | -| array_flow.rb:887:10:887:10 | c [element 2] | array_flow.rb:887:10:887:13 | ...[...] | -| array_flow.rb:894:5:894:5 | a [element 1] | array_flow.rb:895:9:895:9 | a [element 1] | -| array_flow.rb:894:5:894:5 | a [element 1] | array_flow.rb:895:9:895:9 | a [element 1] | -| array_flow.rb:894:5:894:5 | a [element 1] | array_flow.rb:898:10:898:10 | a [element 1] | -| array_flow.rb:894:5:894:5 | a [element 1] | array_flow.rb:898:10:898:10 | a [element 1] | -| array_flow.rb:894:5:894:5 | a [element 3] | array_flow.rb:895:9:895:9 | a [element 3] | -| array_flow.rb:894:5:894:5 | a [element 3] | array_flow.rb:895:9:895:9 | a [element 3] | -| array_flow.rb:894:5:894:5 | a [element 3] | array_flow.rb:900:10:900:10 | a [element 3] | -| array_flow.rb:894:5:894:5 | a [element 3] | array_flow.rb:900:10:900:10 | a [element 3] | -| array_flow.rb:894:13:894:24 | call to source | array_flow.rb:894:5:894:5 | a [element 1] | -| array_flow.rb:894:13:894:24 | call to source | array_flow.rb:894:5:894:5 | a [element 1] | -| array_flow.rb:894:30:894:41 | call to source | array_flow.rb:894:5:894:5 | a [element 3] | -| array_flow.rb:894:30:894:41 | call to source | array_flow.rb:894:5:894:5 | a [element 3] | -| array_flow.rb:895:5:895:5 | b | array_flow.rb:896:10:896:10 | b | -| array_flow.rb:895:5:895:5 | b | array_flow.rb:896:10:896:10 | b | -| array_flow.rb:895:9:895:9 | a [element 1] | array_flow.rb:895:9:895:13 | call to pop | -| array_flow.rb:895:9:895:9 | a [element 1] | array_flow.rb:895:9:895:13 | call to pop | -| array_flow.rb:895:9:895:9 | a [element 3] | array_flow.rb:895:9:895:13 | call to pop | -| array_flow.rb:895:9:895:9 | a [element 3] | array_flow.rb:895:9:895:13 | call to pop | -| array_flow.rb:895:9:895:13 | call to pop | array_flow.rb:895:5:895:5 | b | -| array_flow.rb:895:9:895:13 | call to pop | array_flow.rb:895:5:895:5 | b | -| array_flow.rb:898:10:898:10 | a [element 1] | array_flow.rb:898:10:898:13 | ...[...] | -| array_flow.rb:898:10:898:10 | a [element 1] | array_flow.rb:898:10:898:13 | ...[...] | -| array_flow.rb:900:10:900:10 | a [element 3] | array_flow.rb:900:10:900:13 | ...[...] | -| array_flow.rb:900:10:900:10 | a [element 3] | array_flow.rb:900:10:900:13 | ...[...] | -| array_flow.rb:902:5:902:5 | a [element 1] | array_flow.rb:903:9:903:9 | a [element 1] | -| array_flow.rb:902:5:902:5 | a [element 1] | array_flow.rb:903:9:903:9 | a [element 1] | -| array_flow.rb:902:5:902:5 | a [element 1] | array_flow.rb:907:10:907:10 | a [element 1] | -| array_flow.rb:902:5:902:5 | a [element 1] | array_flow.rb:907:10:907:10 | a [element 1] | -| array_flow.rb:902:5:902:5 | a [element 3] | array_flow.rb:903:9:903:9 | a [element 3] | -| array_flow.rb:902:5:902:5 | a [element 3] | array_flow.rb:903:9:903:9 | a [element 3] | -| array_flow.rb:902:5:902:5 | a [element 3] | array_flow.rb:909:10:909:10 | a [element 3] | -| array_flow.rb:902:5:902:5 | a [element 3] | array_flow.rb:909:10:909:10 | a [element 3] | -| array_flow.rb:902:13:902:24 | call to source | array_flow.rb:902:5:902:5 | a [element 1] | -| array_flow.rb:902:13:902:24 | call to source | array_flow.rb:902:5:902:5 | a [element 1] | -| array_flow.rb:902:30:902:41 | call to source | array_flow.rb:902:5:902:5 | a [element 3] | -| array_flow.rb:902:30:902:41 | call to source | array_flow.rb:902:5:902:5 | a [element 3] | -| array_flow.rb:903:5:903:5 | b [element] | array_flow.rb:904:10:904:10 | b [element] | -| array_flow.rb:903:5:903:5 | b [element] | array_flow.rb:904:10:904:10 | b [element] | -| array_flow.rb:903:5:903:5 | b [element] | array_flow.rb:905:10:905:10 | b [element] | -| array_flow.rb:903:5:903:5 | b [element] | array_flow.rb:905:10:905:10 | b [element] | -| array_flow.rb:903:9:903:9 | a [element 1] | array_flow.rb:903:9:903:16 | call to pop [element] | -| array_flow.rb:903:9:903:9 | a [element 1] | array_flow.rb:903:9:903:16 | call to pop [element] | -| array_flow.rb:903:9:903:9 | a [element 3] | array_flow.rb:903:9:903:16 | call to pop [element] | -| array_flow.rb:903:9:903:9 | a [element 3] | array_flow.rb:903:9:903:16 | call to pop [element] | -| array_flow.rb:903:9:903:16 | call to pop [element] | array_flow.rb:903:5:903:5 | b [element] | -| array_flow.rb:903:9:903:16 | call to pop [element] | array_flow.rb:903:5:903:5 | b [element] | -| array_flow.rb:904:10:904:10 | b [element] | array_flow.rb:904:10:904:13 | ...[...] | -| array_flow.rb:904:10:904:10 | b [element] | array_flow.rb:904:10:904:13 | ...[...] | -| array_flow.rb:905:10:905:10 | b [element] | array_flow.rb:905:10:905:13 | ...[...] | -| array_flow.rb:905:10:905:10 | b [element] | array_flow.rb:905:10:905:13 | ...[...] | -| array_flow.rb:907:10:907:10 | a [element 1] | array_flow.rb:907:10:907:13 | ...[...] | -| array_flow.rb:907:10:907:10 | a [element 1] | array_flow.rb:907:10:907:13 | ...[...] | -| array_flow.rb:909:10:909:10 | a [element 3] | array_flow.rb:909:10:909:13 | ...[...] | -| array_flow.rb:909:10:909:10 | a [element 3] | array_flow.rb:909:10:909:13 | ...[...] | -| array_flow.rb:913:5:913:5 | a [element 2] | array_flow.rb:914:5:914:5 | a [element 2] | -| array_flow.rb:913:5:913:5 | a [element 2] | array_flow.rb:914:5:914:5 | a [element 2] | -| array_flow.rb:913:16:913:27 | call to source | array_flow.rb:913:5:913:5 | a [element 2] | -| array_flow.rb:913:16:913:27 | call to source | array_flow.rb:913:5:913:5 | a [element 2] | -| array_flow.rb:914:5:914:5 | [post] a [element 2] | array_flow.rb:917:10:917:10 | a [element 2] | -| array_flow.rb:914:5:914:5 | [post] a [element 2] | array_flow.rb:917:10:917:10 | a [element 2] | -| array_flow.rb:914:5:914:5 | [post] a [element 5] | array_flow.rb:920:10:920:10 | a [element 5] | -| array_flow.rb:914:5:914:5 | [post] a [element 5] | array_flow.rb:920:10:920:10 | a [element 5] | -| array_flow.rb:914:5:914:5 | a [element 2] | array_flow.rb:914:5:914:5 | [post] a [element 5] | -| array_flow.rb:914:5:914:5 | a [element 2] | array_flow.rb:914:5:914:5 | [post] a [element 5] | -| array_flow.rb:914:21:914:32 | call to source | array_flow.rb:914:5:914:5 | [post] a [element 2] | -| array_flow.rb:914:21:914:32 | call to source | array_flow.rb:914:5:914:5 | [post] a [element 2] | -| array_flow.rb:917:10:917:10 | a [element 2] | array_flow.rb:917:10:917:13 | ...[...] | -| array_flow.rb:917:10:917:10 | a [element 2] | array_flow.rb:917:10:917:13 | ...[...] | -| array_flow.rb:920:10:920:10 | a [element 5] | array_flow.rb:920:10:920:13 | ...[...] | -| array_flow.rb:920:10:920:10 | a [element 5] | array_flow.rb:920:10:920:13 | ...[...] | -| array_flow.rb:924:5:924:5 | a [element 2] | array_flow.rb:927:9:927:9 | a [element 2] | -| array_flow.rb:924:5:924:5 | a [element 2] | array_flow.rb:927:9:927:9 | a [element 2] | +| array_flow.rb:612:5:612:5 | b [element] | array_flow.rb:613:10:613:10 | b [element] | +| array_flow.rb:612:5:612:5 | b [element] | array_flow.rb:613:10:613:10 | b [element] | +| array_flow.rb:612:9:612:9 | a [element 3] | array_flow.rb:612:9:612:21 | call to grep_v [element] | +| array_flow.rb:612:9:612:9 | a [element 3] | array_flow.rb:612:9:612:21 | call to grep_v [element] | +| array_flow.rb:612:9:612:21 | call to grep_v [element] | array_flow.rb:612:5:612:5 | b [element] | +| array_flow.rb:612:9:612:21 | call to grep_v [element] | array_flow.rb:612:5:612:5 | b [element] | +| array_flow.rb:613:10:613:10 | b [element] | array_flow.rb:613:10:613:13 | ...[...] | +| array_flow.rb:613:10:613:10 | b [element] | array_flow.rb:613:10:613:13 | ...[...] | +| array_flow.rb:614:5:614:5 | b [element] | array_flow.rb:618:10:618:10 | b [element] | +| array_flow.rb:614:5:614:5 | b [element] | array_flow.rb:618:10:618:10 | b [element] | +| array_flow.rb:614:9:614:9 | a [element 3] | array_flow.rb:614:27:614:27 | x | +| array_flow.rb:614:9:614:9 | a [element 3] | array_flow.rb:614:27:614:27 | x | +| array_flow.rb:614:9:617:7 | call to grep_v [element] | array_flow.rb:614:5:614:5 | b [element] | +| array_flow.rb:614:9:617:7 | call to grep_v [element] | array_flow.rb:614:5:614:5 | b [element] | +| array_flow.rb:614:27:614:27 | x | array_flow.rb:615:14:615:14 | x | +| array_flow.rb:614:27:614:27 | x | array_flow.rb:615:14:615:14 | x | +| array_flow.rb:616:9:616:20 | call to source | array_flow.rb:614:9:617:7 | call to grep_v [element] | +| array_flow.rb:616:9:616:20 | call to source | array_flow.rb:614:9:617:7 | call to grep_v [element] | +| array_flow.rb:618:10:618:10 | b [element] | array_flow.rb:618:10:618:13 | ...[...] | +| array_flow.rb:618:10:618:10 | b [element] | array_flow.rb:618:10:618:13 | ...[...] | +| array_flow.rb:622:5:622:5 | a [element 3] | array_flow.rb:623:9:623:9 | a [element 3] | +| array_flow.rb:622:5:622:5 | a [element 3] | array_flow.rb:623:9:623:9 | a [element 3] | +| array_flow.rb:622:19:622:30 | call to source | array_flow.rb:622:5:622:5 | a [element 3] | +| array_flow.rb:622:19:622:30 | call to source | array_flow.rb:622:5:622:5 | a [element 3] | +| array_flow.rb:623:9:623:9 | a [element 3] | array_flow.rb:623:24:623:24 | x | +| array_flow.rb:623:9:623:9 | a [element 3] | array_flow.rb:623:24:623:24 | x | +| array_flow.rb:623:24:623:24 | x | array_flow.rb:624:14:624:14 | x | +| array_flow.rb:623:24:623:24 | x | array_flow.rb:624:14:624:14 | x | +| array_flow.rb:631:5:631:5 | a [element 3] | array_flow.rb:632:5:632:5 | a [element 3] | +| array_flow.rb:631:5:631:5 | a [element 3] | array_flow.rb:632:5:632:5 | a [element 3] | +| array_flow.rb:631:19:631:28 | call to source | array_flow.rb:631:5:631:5 | a [element 3] | +| array_flow.rb:631:19:631:28 | call to source | array_flow.rb:631:5:631:5 | a [element 3] | +| array_flow.rb:632:5:632:5 | a [element 3] | array_flow.rb:632:17:632:17 | x | +| array_flow.rb:632:5:632:5 | a [element 3] | array_flow.rb:632:17:632:17 | x | +| array_flow.rb:632:17:632:17 | x | array_flow.rb:633:14:633:14 | x | +| array_flow.rb:632:17:632:17 | x | array_flow.rb:633:14:633:14 | x | +| array_flow.rb:638:5:638:5 | a [element 0] | array_flow.rb:639:9:639:9 | a [element 0] | +| array_flow.rb:638:5:638:5 | a [element 0] | array_flow.rb:639:9:639:9 | a [element 0] | +| array_flow.rb:638:5:638:5 | a [element 0] | array_flow.rb:645:9:645:9 | a [element 0] | +| array_flow.rb:638:5:638:5 | a [element 0] | array_flow.rb:645:9:645:9 | a [element 0] | +| array_flow.rb:638:5:638:5 | a [element 2] | array_flow.rb:639:9:639:9 | a [element 2] | +| array_flow.rb:638:5:638:5 | a [element 2] | array_flow.rb:639:9:639:9 | a [element 2] | +| array_flow.rb:638:5:638:5 | a [element 2] | array_flow.rb:645:9:645:9 | a [element 2] | +| array_flow.rb:638:5:638:5 | a [element 2] | array_flow.rb:645:9:645:9 | a [element 2] | +| array_flow.rb:638:10:638:21 | call to source | array_flow.rb:638:5:638:5 | a [element 0] | +| array_flow.rb:638:10:638:21 | call to source | array_flow.rb:638:5:638:5 | a [element 0] | +| array_flow.rb:638:27:638:38 | call to source | array_flow.rb:638:5:638:5 | a [element 2] | +| array_flow.rb:638:27:638:38 | call to source | array_flow.rb:638:5:638:5 | a [element 2] | +| array_flow.rb:639:5:639:5 | b | array_flow.rb:644:10:644:10 | b | +| array_flow.rb:639:5:639:5 | b | array_flow.rb:644:10:644:10 | b | +| array_flow.rb:639:9:639:9 | a [element 0] | array_flow.rb:639:22:639:22 | x | +| array_flow.rb:639:9:639:9 | a [element 0] | array_flow.rb:639:22:639:22 | x | +| array_flow.rb:639:9:639:9 | a [element 2] | array_flow.rb:639:25:639:25 | y | +| array_flow.rb:639:9:639:9 | a [element 2] | array_flow.rb:639:25:639:25 | y | +| array_flow.rb:639:9:643:7 | call to inject | array_flow.rb:639:5:639:5 | b | +| array_flow.rb:639:9:643:7 | call to inject | array_flow.rb:639:5:639:5 | b | +| array_flow.rb:639:22:639:22 | x | array_flow.rb:640:14:640:14 | x | +| array_flow.rb:639:22:639:22 | x | array_flow.rb:640:14:640:14 | x | +| array_flow.rb:639:25:639:25 | y | array_flow.rb:641:14:641:14 | y | +| array_flow.rb:639:25:639:25 | y | array_flow.rb:641:14:641:14 | y | +| array_flow.rb:642:9:642:19 | call to source | array_flow.rb:639:9:643:7 | call to inject | +| array_flow.rb:642:9:642:19 | call to source | array_flow.rb:639:9:643:7 | call to inject | +| array_flow.rb:645:5:645:5 | c | array_flow.rb:650:10:650:10 | c | +| array_flow.rb:645:5:645:5 | c | array_flow.rb:650:10:650:10 | c | +| array_flow.rb:645:9:645:9 | a [element 0] | array_flow.rb:645:28:645:28 | y | +| array_flow.rb:645:9:645:9 | a [element 0] | array_flow.rb:645:28:645:28 | y | +| array_flow.rb:645:9:645:9 | a [element 2] | array_flow.rb:645:28:645:28 | y | +| array_flow.rb:645:9:645:9 | a [element 2] | array_flow.rb:645:28:645:28 | y | +| array_flow.rb:645:9:649:7 | call to inject | array_flow.rb:645:5:645:5 | c | +| array_flow.rb:645:9:649:7 | call to inject | array_flow.rb:645:5:645:5 | c | +| array_flow.rb:645:28:645:28 | y | array_flow.rb:647:14:647:14 | y | +| array_flow.rb:645:28:645:28 | y | array_flow.rb:647:14:647:14 | y | +| array_flow.rb:648:9:648:19 | call to source | array_flow.rb:645:9:649:7 | call to inject | +| array_flow.rb:648:9:648:19 | call to source | array_flow.rb:645:9:649:7 | call to inject | +| array_flow.rb:655:5:655:5 | a [element 2] | array_flow.rb:656:9:656:9 | a [element 2] | +| array_flow.rb:655:5:655:5 | a [element 2] | array_flow.rb:656:9:656:9 | a [element 2] | +| array_flow.rb:655:16:655:27 | call to source | array_flow.rb:655:5:655:5 | a [element 2] | +| array_flow.rb:655:16:655:27 | call to source | array_flow.rb:655:5:655:5 | a [element 2] | +| array_flow.rb:656:5:656:5 | b [element 1] | array_flow.rb:663:10:663:10 | b [element 1] | +| array_flow.rb:656:5:656:5 | b [element 1] | array_flow.rb:663:10:663:10 | b [element 1] | +| array_flow.rb:656:5:656:5 | b [element 2] | array_flow.rb:664:10:664:10 | b [element 2] | +| array_flow.rb:656:5:656:5 | b [element 2] | array_flow.rb:664:10:664:10 | b [element 2] | +| array_flow.rb:656:5:656:5 | b [element 4] | array_flow.rb:666:10:666:10 | b [element 4] | +| array_flow.rb:656:5:656:5 | b [element 4] | array_flow.rb:666:10:666:10 | b [element 4] | +| array_flow.rb:656:9:656:9 | [post] a [element 1] | array_flow.rb:658:10:658:10 | a [element 1] | +| array_flow.rb:656:9:656:9 | [post] a [element 1] | array_flow.rb:658:10:658:10 | a [element 1] | +| array_flow.rb:656:9:656:9 | [post] a [element 2] | array_flow.rb:659:10:659:10 | a [element 2] | +| array_flow.rb:656:9:656:9 | [post] a [element 2] | array_flow.rb:659:10:659:10 | a [element 2] | +| array_flow.rb:656:9:656:9 | [post] a [element 4] | array_flow.rb:661:10:661:10 | a [element 4] | +| array_flow.rb:656:9:656:9 | [post] a [element 4] | array_flow.rb:661:10:661:10 | a [element 4] | +| array_flow.rb:656:9:656:9 | a [element 2] | array_flow.rb:656:9:656:9 | [post] a [element 4] | +| array_flow.rb:656:9:656:9 | a [element 2] | array_flow.rb:656:9:656:9 | [post] a [element 4] | +| array_flow.rb:656:9:656:9 | a [element 2] | array_flow.rb:656:9:656:47 | call to insert [element 4] | +| array_flow.rb:656:9:656:9 | a [element 2] | array_flow.rb:656:9:656:47 | call to insert [element 4] | +| array_flow.rb:656:9:656:47 | call to insert [element 1] | array_flow.rb:656:5:656:5 | b [element 1] | +| array_flow.rb:656:9:656:47 | call to insert [element 1] | array_flow.rb:656:5:656:5 | b [element 1] | +| array_flow.rb:656:9:656:47 | call to insert [element 2] | array_flow.rb:656:5:656:5 | b [element 2] | +| array_flow.rb:656:9:656:47 | call to insert [element 2] | array_flow.rb:656:5:656:5 | b [element 2] | +| array_flow.rb:656:9:656:47 | call to insert [element 4] | array_flow.rb:656:5:656:5 | b [element 4] | +| array_flow.rb:656:9:656:47 | call to insert [element 4] | array_flow.rb:656:5:656:5 | b [element 4] | +| array_flow.rb:656:21:656:32 | call to source | array_flow.rb:656:9:656:9 | [post] a [element 1] | +| array_flow.rb:656:21:656:32 | call to source | array_flow.rb:656:9:656:9 | [post] a [element 1] | +| array_flow.rb:656:21:656:32 | call to source | array_flow.rb:656:9:656:47 | call to insert [element 1] | +| array_flow.rb:656:21:656:32 | call to source | array_flow.rb:656:9:656:47 | call to insert [element 1] | +| array_flow.rb:656:35:656:46 | call to source | array_flow.rb:656:9:656:9 | [post] a [element 2] | +| array_flow.rb:656:35:656:46 | call to source | array_flow.rb:656:9:656:9 | [post] a [element 2] | +| array_flow.rb:656:35:656:46 | call to source | array_flow.rb:656:9:656:47 | call to insert [element 2] | +| array_flow.rb:656:35:656:46 | call to source | array_flow.rb:656:9:656:47 | call to insert [element 2] | +| array_flow.rb:658:10:658:10 | a [element 1] | array_flow.rb:658:10:658:13 | ...[...] | +| array_flow.rb:658:10:658:10 | a [element 1] | array_flow.rb:658:10:658:13 | ...[...] | +| array_flow.rb:659:10:659:10 | a [element 2] | array_flow.rb:659:10:659:13 | ...[...] | +| array_flow.rb:659:10:659:10 | a [element 2] | array_flow.rb:659:10:659:13 | ...[...] | +| array_flow.rb:661:10:661:10 | a [element 4] | array_flow.rb:661:10:661:13 | ...[...] | +| array_flow.rb:661:10:661:10 | a [element 4] | array_flow.rb:661:10:661:13 | ...[...] | +| array_flow.rb:663:10:663:10 | b [element 1] | array_flow.rb:663:10:663:13 | ...[...] | +| array_flow.rb:663:10:663:10 | b [element 1] | array_flow.rb:663:10:663:13 | ...[...] | +| array_flow.rb:664:10:664:10 | b [element 2] | array_flow.rb:664:10:664:13 | ...[...] | +| array_flow.rb:664:10:664:10 | b [element 2] | array_flow.rb:664:10:664:13 | ...[...] | +| array_flow.rb:666:10:666:10 | b [element 4] | array_flow.rb:666:10:666:13 | ...[...] | +| array_flow.rb:666:10:666:10 | b [element 4] | array_flow.rb:666:10:666:13 | ...[...] | +| array_flow.rb:669:5:669:5 | c [element 2] | array_flow.rb:670:9:670:9 | c [element 2] | +| array_flow.rb:669:5:669:5 | c [element 2] | array_flow.rb:670:9:670:9 | c [element 2] | +| array_flow.rb:669:16:669:27 | call to source | array_flow.rb:669:5:669:5 | c [element 2] | +| array_flow.rb:669:16:669:27 | call to source | array_flow.rb:669:5:669:5 | c [element 2] | +| array_flow.rb:670:5:670:5 | d [element] | array_flow.rb:672:10:672:10 | d [element] | +| array_flow.rb:670:5:670:5 | d [element] | array_flow.rb:672:10:672:10 | d [element] | +| array_flow.rb:670:9:670:9 | [post] c [element] | array_flow.rb:671:10:671:10 | c [element] | +| array_flow.rb:670:9:670:9 | [post] c [element] | array_flow.rb:671:10:671:10 | c [element] | +| array_flow.rb:670:9:670:9 | c [element 2] | array_flow.rb:670:9:670:9 | [post] c [element] | +| array_flow.rb:670:9:670:9 | c [element 2] | array_flow.rb:670:9:670:9 | [post] c [element] | +| array_flow.rb:670:9:670:9 | c [element 2] | array_flow.rb:670:9:670:47 | call to insert [element] | +| array_flow.rb:670:9:670:9 | c [element 2] | array_flow.rb:670:9:670:47 | call to insert [element] | +| array_flow.rb:670:9:670:47 | call to insert [element] | array_flow.rb:670:5:670:5 | d [element] | +| array_flow.rb:670:9:670:47 | call to insert [element] | array_flow.rb:670:5:670:5 | d [element] | +| array_flow.rb:670:21:670:32 | call to source | array_flow.rb:670:9:670:9 | [post] c [element] | +| array_flow.rb:670:21:670:32 | call to source | array_flow.rb:670:9:670:9 | [post] c [element] | +| array_flow.rb:670:21:670:32 | call to source | array_flow.rb:670:9:670:47 | call to insert [element] | +| array_flow.rb:670:21:670:32 | call to source | array_flow.rb:670:9:670:47 | call to insert [element] | +| array_flow.rb:670:35:670:46 | call to source | array_flow.rb:670:9:670:9 | [post] c [element] | +| array_flow.rb:670:35:670:46 | call to source | array_flow.rb:670:9:670:9 | [post] c [element] | +| array_flow.rb:670:35:670:46 | call to source | array_flow.rb:670:9:670:47 | call to insert [element] | +| array_flow.rb:670:35:670:46 | call to source | array_flow.rb:670:9:670:47 | call to insert [element] | +| array_flow.rb:671:10:671:10 | c [element] | array_flow.rb:671:10:671:13 | ...[...] | +| array_flow.rb:671:10:671:10 | c [element] | array_flow.rb:671:10:671:13 | ...[...] | +| array_flow.rb:672:10:672:10 | d [element] | array_flow.rb:672:10:672:13 | ...[...] | +| array_flow.rb:672:10:672:10 | d [element] | array_flow.rb:672:10:672:13 | ...[...] | +| array_flow.rb:683:5:683:5 | a [element 2] | array_flow.rb:684:9:684:9 | a [element 2] | +| array_flow.rb:683:5:683:5 | a [element 2] | array_flow.rb:684:9:684:9 | a [element 2] | +| array_flow.rb:683:16:683:27 | call to source | array_flow.rb:683:5:683:5 | a [element 2] | +| array_flow.rb:683:16:683:27 | call to source | array_flow.rb:683:5:683:5 | a [element 2] | +| array_flow.rb:684:5:684:5 | b [element] | array_flow.rb:685:10:685:10 | b [element] | +| array_flow.rb:684:5:684:5 | b [element] | array_flow.rb:685:10:685:10 | b [element] | +| array_flow.rb:684:9:684:9 | a [element 2] | array_flow.rb:684:9:684:60 | call to intersection [element] | +| array_flow.rb:684:9:684:9 | a [element 2] | array_flow.rb:684:9:684:60 | call to intersection [element] | +| array_flow.rb:684:9:684:60 | call to intersection [element] | array_flow.rb:684:5:684:5 | b [element] | +| array_flow.rb:684:9:684:60 | call to intersection [element] | array_flow.rb:684:5:684:5 | b [element] | +| array_flow.rb:684:31:684:42 | call to source | array_flow.rb:684:9:684:60 | call to intersection [element] | +| array_flow.rb:684:31:684:42 | call to source | array_flow.rb:684:9:684:60 | call to intersection [element] | +| array_flow.rb:684:47:684:58 | call to source | array_flow.rb:684:9:684:60 | call to intersection [element] | +| array_flow.rb:684:47:684:58 | call to source | array_flow.rb:684:9:684:60 | call to intersection [element] | +| array_flow.rb:685:10:685:10 | b [element] | array_flow.rb:685:10:685:13 | ...[...] | +| array_flow.rb:685:10:685:10 | b [element] | array_flow.rb:685:10:685:13 | ...[...] | +| array_flow.rb:689:5:689:5 | a [element 2] | array_flow.rb:690:9:690:9 | a [element 2] | +| array_flow.rb:689:5:689:5 | a [element 2] | array_flow.rb:690:9:690:9 | a [element 2] | +| array_flow.rb:689:16:689:25 | call to source | array_flow.rb:689:5:689:5 | a [element 2] | +| array_flow.rb:689:16:689:25 | call to source | array_flow.rb:689:5:689:5 | a [element 2] | +| array_flow.rb:690:5:690:5 | b [element] | array_flow.rb:695:10:695:10 | b [element] | +| array_flow.rb:690:5:690:5 | b [element] | array_flow.rb:695:10:695:10 | b [element] | +| array_flow.rb:690:9:690:9 | [post] a [element] | array_flow.rb:694:10:694:10 | a [element] | +| array_flow.rb:690:9:690:9 | [post] a [element] | array_flow.rb:694:10:694:10 | a [element] | +| array_flow.rb:690:9:690:9 | a [element 2] | array_flow.rb:690:9:690:9 | [post] a [element] | +| array_flow.rb:690:9:690:9 | a [element 2] | array_flow.rb:690:9:690:9 | [post] a [element] | +| array_flow.rb:690:9:690:9 | a [element 2] | array_flow.rb:690:9:693:7 | call to keep_if [element] | +| array_flow.rb:690:9:690:9 | a [element 2] | array_flow.rb:690:9:693:7 | call to keep_if [element] | +| array_flow.rb:690:9:690:9 | a [element 2] | array_flow.rb:690:23:690:23 | x | +| array_flow.rb:690:9:690:9 | a [element 2] | array_flow.rb:690:23:690:23 | x | +| array_flow.rb:690:9:693:7 | call to keep_if [element] | array_flow.rb:690:5:690:5 | b [element] | +| array_flow.rb:690:9:693:7 | call to keep_if [element] | array_flow.rb:690:5:690:5 | b [element] | +| array_flow.rb:690:23:690:23 | x | array_flow.rb:691:14:691:14 | x | +| array_flow.rb:690:23:690:23 | x | array_flow.rb:691:14:691:14 | x | +| array_flow.rb:694:10:694:10 | a [element] | array_flow.rb:694:10:694:13 | ...[...] | +| array_flow.rb:694:10:694:10 | a [element] | array_flow.rb:694:10:694:13 | ...[...] | +| array_flow.rb:695:10:695:10 | b [element] | array_flow.rb:695:10:695:13 | ...[...] | +| array_flow.rb:695:10:695:10 | b [element] | array_flow.rb:695:10:695:13 | ...[...] | +| array_flow.rb:699:5:699:5 | a [element 2] | array_flow.rb:701:10:701:10 | a [element 2] | +| array_flow.rb:699:5:699:5 | a [element 2] | array_flow.rb:701:10:701:10 | a [element 2] | +| array_flow.rb:699:5:699:5 | a [element 2] | array_flow.rb:702:9:702:9 | a [element 2] | +| array_flow.rb:699:5:699:5 | a [element 2] | array_flow.rb:702:9:702:9 | a [element 2] | +| array_flow.rb:699:16:699:27 | call to source | array_flow.rb:699:5:699:5 | a [element 2] | +| array_flow.rb:699:16:699:27 | call to source | array_flow.rb:699:5:699:5 | a [element 2] | +| array_flow.rb:700:5:700:5 | [post] a [element] | array_flow.rb:701:10:701:10 | a [element] | +| array_flow.rb:700:5:700:5 | [post] a [element] | array_flow.rb:701:10:701:10 | a [element] | +| array_flow.rb:700:5:700:5 | [post] a [element] | array_flow.rb:702:9:702:9 | a [element] | +| array_flow.rb:700:5:700:5 | [post] a [element] | array_flow.rb:702:9:702:9 | a [element] | +| array_flow.rb:700:12:700:23 | call to source | array_flow.rb:700:5:700:5 | [post] a [element] | +| array_flow.rb:700:12:700:23 | call to source | array_flow.rb:700:5:700:5 | [post] a [element] | +| array_flow.rb:701:10:701:10 | a [element 2] | array_flow.rb:701:10:701:15 | call to last | +| array_flow.rb:701:10:701:10 | a [element 2] | array_flow.rb:701:10:701:15 | call to last | +| array_flow.rb:701:10:701:10 | a [element] | array_flow.rb:701:10:701:15 | call to last | +| array_flow.rb:701:10:701:10 | a [element] | array_flow.rb:701:10:701:15 | call to last | +| array_flow.rb:702:5:702:5 | b [element] | array_flow.rb:703:10:703:10 | b [element] | +| array_flow.rb:702:5:702:5 | b [element] | array_flow.rb:703:10:703:10 | b [element] | +| array_flow.rb:702:5:702:5 | b [element] | array_flow.rb:704:10:704:10 | b [element] | +| array_flow.rb:702:5:702:5 | b [element] | array_flow.rb:704:10:704:10 | b [element] | +| array_flow.rb:702:9:702:9 | a [element 2] | array_flow.rb:702:9:702:17 | call to last [element] | +| array_flow.rb:702:9:702:9 | a [element 2] | array_flow.rb:702:9:702:17 | call to last [element] | +| array_flow.rb:702:9:702:9 | a [element] | array_flow.rb:702:9:702:17 | call to last [element] | +| array_flow.rb:702:9:702:9 | a [element] | array_flow.rb:702:9:702:17 | call to last [element] | +| array_flow.rb:702:9:702:17 | call to last [element] | array_flow.rb:702:5:702:5 | b [element] | +| array_flow.rb:702:9:702:17 | call to last [element] | array_flow.rb:702:5:702:5 | b [element] | +| array_flow.rb:703:10:703:10 | b [element] | array_flow.rb:703:10:703:13 | ...[...] | +| array_flow.rb:703:10:703:10 | b [element] | array_flow.rb:703:10:703:13 | ...[...] | +| array_flow.rb:704:10:704:10 | b [element] | array_flow.rb:704:10:704:13 | ...[...] | +| array_flow.rb:704:10:704:10 | b [element] | array_flow.rb:704:10:704:13 | ...[...] | +| array_flow.rb:708:5:708:5 | a [element 2] | array_flow.rb:709:9:709:9 | a [element 2] | +| array_flow.rb:708:5:708:5 | a [element 2] | array_flow.rb:709:9:709:9 | a [element 2] | +| array_flow.rb:708:16:708:27 | call to source | array_flow.rb:708:5:708:5 | a [element 2] | +| array_flow.rb:708:16:708:27 | call to source | array_flow.rb:708:5:708:5 | a [element 2] | +| array_flow.rb:709:5:709:5 | b [element] | array_flow.rb:713:10:713:10 | b [element] | +| array_flow.rb:709:5:709:5 | b [element] | array_flow.rb:713:10:713:10 | b [element] | +| array_flow.rb:709:9:709:9 | a [element 2] | array_flow.rb:709:19:709:19 | x | +| array_flow.rb:709:9:709:9 | a [element 2] | array_flow.rb:709:19:709:19 | x | +| array_flow.rb:709:9:712:7 | call to map [element] | array_flow.rb:709:5:709:5 | b [element] | +| array_flow.rb:709:9:712:7 | call to map [element] | array_flow.rb:709:5:709:5 | b [element] | +| array_flow.rb:709:19:709:19 | x | array_flow.rb:710:14:710:14 | x | +| array_flow.rb:709:19:709:19 | x | array_flow.rb:710:14:710:14 | x | +| array_flow.rb:711:9:711:19 | call to source | array_flow.rb:709:9:712:7 | call to map [element] | +| array_flow.rb:711:9:711:19 | call to source | array_flow.rb:709:9:712:7 | call to map [element] | +| array_flow.rb:713:10:713:10 | b [element] | array_flow.rb:713:10:713:13 | ...[...] | +| array_flow.rb:713:10:713:10 | b [element] | array_flow.rb:713:10:713:13 | ...[...] | +| array_flow.rb:717:5:717:5 | a [element 2] | array_flow.rb:718:9:718:9 | a [element 2] | +| array_flow.rb:717:5:717:5 | a [element 2] | array_flow.rb:718:9:718:9 | a [element 2] | +| array_flow.rb:717:16:717:27 | call to source | array_flow.rb:717:5:717:5 | a [element 2] | +| array_flow.rb:717:16:717:27 | call to source | array_flow.rb:717:5:717:5 | a [element 2] | +| array_flow.rb:718:5:718:5 | b [element] | array_flow.rb:722:10:722:10 | b [element] | +| array_flow.rb:718:5:718:5 | b [element] | array_flow.rb:722:10:722:10 | b [element] | +| array_flow.rb:718:9:718:9 | a [element 2] | array_flow.rb:718:20:718:20 | x | +| array_flow.rb:718:9:718:9 | a [element 2] | array_flow.rb:718:20:718:20 | x | +| array_flow.rb:718:9:721:7 | call to map! [element] | array_flow.rb:718:5:718:5 | b [element] | +| array_flow.rb:718:9:721:7 | call to map! [element] | array_flow.rb:718:5:718:5 | b [element] | +| array_flow.rb:718:20:718:20 | x | array_flow.rb:719:14:719:14 | x | +| array_flow.rb:718:20:718:20 | x | array_flow.rb:719:14:719:14 | x | +| array_flow.rb:720:9:720:19 | call to source | array_flow.rb:718:9:721:7 | call to map! [element] | +| array_flow.rb:720:9:720:19 | call to source | array_flow.rb:718:9:721:7 | call to map! [element] | +| array_flow.rb:722:10:722:10 | b [element] | array_flow.rb:722:10:722:13 | ...[...] | +| array_flow.rb:722:10:722:10 | b [element] | array_flow.rb:722:10:722:13 | ...[...] | +| array_flow.rb:726:5:726:5 | a [element 2] | array_flow.rb:729:9:729:9 | a [element 2] | +| array_flow.rb:726:5:726:5 | a [element 2] | array_flow.rb:729:9:729:9 | a [element 2] | +| array_flow.rb:726:5:726:5 | a [element 2] | array_flow.rb:733:9:733:9 | a [element 2] | +| array_flow.rb:726:5:726:5 | a [element 2] | array_flow.rb:733:9:733:9 | a [element 2] | +| array_flow.rb:726:5:726:5 | a [element 2] | array_flow.rb:737:9:737:9 | a [element 2] | +| array_flow.rb:726:5:726:5 | a [element 2] | array_flow.rb:737:9:737:9 | a [element 2] | +| array_flow.rb:726:5:726:5 | a [element 2] | array_flow.rb:745:9:745:9 | a [element 2] | +| array_flow.rb:726:5:726:5 | a [element 2] | array_flow.rb:745:9:745:9 | a [element 2] | +| array_flow.rb:726:16:726:25 | call to source | array_flow.rb:726:5:726:5 | a [element 2] | +| array_flow.rb:726:16:726:25 | call to source | array_flow.rb:726:5:726:5 | a [element 2] | +| array_flow.rb:729:5:729:5 | b | array_flow.rb:730:10:730:10 | b | +| array_flow.rb:729:5:729:5 | b | array_flow.rb:730:10:730:10 | b | +| array_flow.rb:729:9:729:9 | a [element 2] | array_flow.rb:729:9:729:13 | call to max | +| array_flow.rb:729:9:729:9 | a [element 2] | array_flow.rb:729:9:729:13 | call to max | +| array_flow.rb:729:9:729:13 | call to max | array_flow.rb:729:5:729:5 | b | +| array_flow.rb:729:9:729:13 | call to max | array_flow.rb:729:5:729:5 | b | +| array_flow.rb:733:5:733:5 | c [element] | array_flow.rb:734:10:734:10 | c [element] | +| array_flow.rb:733:5:733:5 | c [element] | array_flow.rb:734:10:734:10 | c [element] | +| array_flow.rb:733:9:733:9 | a [element 2] | array_flow.rb:733:9:733:16 | call to max [element] | +| array_flow.rb:733:9:733:9 | a [element 2] | array_flow.rb:733:9:733:16 | call to max [element] | +| array_flow.rb:733:9:733:16 | call to max [element] | array_flow.rb:733:5:733:5 | c [element] | +| array_flow.rb:733:9:733:16 | call to max [element] | array_flow.rb:733:5:733:5 | c [element] | +| array_flow.rb:734:10:734:10 | c [element] | array_flow.rb:734:10:734:13 | ...[...] | +| array_flow.rb:734:10:734:10 | c [element] | array_flow.rb:734:10:734:13 | ...[...] | +| array_flow.rb:737:5:737:5 | d | array_flow.rb:742:10:742:10 | d | +| array_flow.rb:737:5:737:5 | d | array_flow.rb:742:10:742:10 | d | +| array_flow.rb:737:9:737:9 | a [element 2] | array_flow.rb:737:9:741:7 | call to max | +| array_flow.rb:737:9:737:9 | a [element 2] | array_flow.rb:737:9:741:7 | call to max | +| array_flow.rb:737:9:737:9 | a [element 2] | array_flow.rb:737:19:737:19 | x | +| array_flow.rb:737:9:737:9 | a [element 2] | array_flow.rb:737:19:737:19 | x | +| array_flow.rb:737:9:737:9 | a [element 2] | array_flow.rb:737:22:737:22 | y | +| array_flow.rb:737:9:737:9 | a [element 2] | array_flow.rb:737:22:737:22 | y | +| array_flow.rb:737:9:741:7 | call to max | array_flow.rb:737:5:737:5 | d | +| array_flow.rb:737:9:741:7 | call to max | array_flow.rb:737:5:737:5 | d | +| array_flow.rb:737:19:737:19 | x | array_flow.rb:738:14:738:14 | x | +| array_flow.rb:737:19:737:19 | x | array_flow.rb:738:14:738:14 | x | +| array_flow.rb:737:22:737:22 | y | array_flow.rb:739:14:739:14 | y | +| array_flow.rb:737:22:737:22 | y | array_flow.rb:739:14:739:14 | y | +| array_flow.rb:745:5:745:5 | e [element] | array_flow.rb:750:10:750:10 | e [element] | +| array_flow.rb:745:5:745:5 | e [element] | array_flow.rb:750:10:750:10 | e [element] | +| array_flow.rb:745:9:745:9 | a [element 2] | array_flow.rb:745:9:749:7 | call to max [element] | +| array_flow.rb:745:9:745:9 | a [element 2] | array_flow.rb:745:9:749:7 | call to max [element] | +| array_flow.rb:745:9:745:9 | a [element 2] | array_flow.rb:745:22:745:22 | x | +| array_flow.rb:745:9:745:9 | a [element 2] | array_flow.rb:745:22:745:22 | x | +| array_flow.rb:745:9:745:9 | a [element 2] | array_flow.rb:745:25:745:25 | y | +| array_flow.rb:745:9:745:9 | a [element 2] | array_flow.rb:745:25:745:25 | y | +| array_flow.rb:745:9:749:7 | call to max [element] | array_flow.rb:745:5:745:5 | e [element] | +| array_flow.rb:745:9:749:7 | call to max [element] | array_flow.rb:745:5:745:5 | e [element] | +| array_flow.rb:745:22:745:22 | x | array_flow.rb:746:14:746:14 | x | +| array_flow.rb:745:22:745:22 | x | array_flow.rb:746:14:746:14 | x | +| array_flow.rb:745:25:745:25 | y | array_flow.rb:747:14:747:14 | y | +| array_flow.rb:745:25:745:25 | y | array_flow.rb:747:14:747:14 | y | +| array_flow.rb:750:10:750:10 | e [element] | array_flow.rb:750:10:750:13 | ...[...] | +| array_flow.rb:750:10:750:10 | e [element] | array_flow.rb:750:10:750:13 | ...[...] | +| array_flow.rb:754:5:754:5 | a [element 2] | array_flow.rb:757:9:757:9 | a [element 2] | +| array_flow.rb:754:5:754:5 | a [element 2] | array_flow.rb:757:9:757:9 | a [element 2] | +| array_flow.rb:754:5:754:5 | a [element 2] | array_flow.rb:764:9:764:9 | a [element 2] | +| array_flow.rb:754:5:754:5 | a [element 2] | array_flow.rb:764:9:764:9 | a [element 2] | +| array_flow.rb:754:16:754:25 | call to source | array_flow.rb:754:5:754:5 | a [element 2] | +| array_flow.rb:754:16:754:25 | call to source | array_flow.rb:754:5:754:5 | a [element 2] | +| array_flow.rb:757:5:757:5 | b | array_flow.rb:761:10:761:10 | b | +| array_flow.rb:757:5:757:5 | b | array_flow.rb:761:10:761:10 | b | +| array_flow.rb:757:9:757:9 | a [element 2] | array_flow.rb:757:9:760:7 | call to max_by | +| array_flow.rb:757:9:757:9 | a [element 2] | array_flow.rb:757:9:760:7 | call to max_by | +| array_flow.rb:757:9:757:9 | a [element 2] | array_flow.rb:757:22:757:22 | x | +| array_flow.rb:757:9:757:9 | a [element 2] | array_flow.rb:757:22:757:22 | x | +| array_flow.rb:757:9:760:7 | call to max_by | array_flow.rb:757:5:757:5 | b | +| array_flow.rb:757:9:760:7 | call to max_by | array_flow.rb:757:5:757:5 | b | +| array_flow.rb:757:22:757:22 | x | array_flow.rb:758:14:758:14 | x | +| array_flow.rb:757:22:757:22 | x | array_flow.rb:758:14:758:14 | x | +| array_flow.rb:764:5:764:5 | c [element] | array_flow.rb:768:10:768:10 | c [element] | +| array_flow.rb:764:5:764:5 | c [element] | array_flow.rb:768:10:768:10 | c [element] | +| array_flow.rb:764:9:764:9 | a [element 2] | array_flow.rb:764:9:767:7 | call to max_by [element] | +| array_flow.rb:764:9:764:9 | a [element 2] | array_flow.rb:764:9:767:7 | call to max_by [element] | +| array_flow.rb:764:9:764:9 | a [element 2] | array_flow.rb:764:25:764:25 | x | +| array_flow.rb:764:9:764:9 | a [element 2] | array_flow.rb:764:25:764:25 | x | +| array_flow.rb:764:9:767:7 | call to max_by [element] | array_flow.rb:764:5:764:5 | c [element] | +| array_flow.rb:764:9:767:7 | call to max_by [element] | array_flow.rb:764:5:764:5 | c [element] | +| array_flow.rb:764:25:764:25 | x | array_flow.rb:765:14:765:14 | x | +| array_flow.rb:764:25:764:25 | x | array_flow.rb:765:14:765:14 | x | +| array_flow.rb:768:10:768:10 | c [element] | array_flow.rb:768:10:768:13 | ...[...] | +| array_flow.rb:768:10:768:10 | c [element] | array_flow.rb:768:10:768:13 | ...[...] | +| array_flow.rb:772:5:772:5 | a [element 2] | array_flow.rb:775:9:775:9 | a [element 2] | +| array_flow.rb:772:5:772:5 | a [element 2] | array_flow.rb:775:9:775:9 | a [element 2] | +| array_flow.rb:772:5:772:5 | a [element 2] | array_flow.rb:779:9:779:9 | a [element 2] | +| array_flow.rb:772:5:772:5 | a [element 2] | array_flow.rb:779:9:779:9 | a [element 2] | +| array_flow.rb:772:5:772:5 | a [element 2] | array_flow.rb:783:9:783:9 | a [element 2] | +| array_flow.rb:772:5:772:5 | a [element 2] | array_flow.rb:783:9:783:9 | a [element 2] | +| array_flow.rb:772:5:772:5 | a [element 2] | array_flow.rb:791:9:791:9 | a [element 2] | +| array_flow.rb:772:5:772:5 | a [element 2] | array_flow.rb:791:9:791:9 | a [element 2] | +| array_flow.rb:772:16:772:25 | call to source | array_flow.rb:772:5:772:5 | a [element 2] | +| array_flow.rb:772:16:772:25 | call to source | array_flow.rb:772:5:772:5 | a [element 2] | +| array_flow.rb:775:5:775:5 | b | array_flow.rb:776:10:776:10 | b | +| array_flow.rb:775:5:775:5 | b | array_flow.rb:776:10:776:10 | b | +| array_flow.rb:775:9:775:9 | a [element 2] | array_flow.rb:775:9:775:13 | call to min | +| array_flow.rb:775:9:775:9 | a [element 2] | array_flow.rb:775:9:775:13 | call to min | +| array_flow.rb:775:9:775:13 | call to min | array_flow.rb:775:5:775:5 | b | +| array_flow.rb:775:9:775:13 | call to min | array_flow.rb:775:5:775:5 | b | +| array_flow.rb:779:5:779:5 | c [element] | array_flow.rb:780:10:780:10 | c [element] | +| array_flow.rb:779:5:779:5 | c [element] | array_flow.rb:780:10:780:10 | c [element] | +| array_flow.rb:779:9:779:9 | a [element 2] | array_flow.rb:779:9:779:16 | call to min [element] | +| array_flow.rb:779:9:779:9 | a [element 2] | array_flow.rb:779:9:779:16 | call to min [element] | +| array_flow.rb:779:9:779:16 | call to min [element] | array_flow.rb:779:5:779:5 | c [element] | +| array_flow.rb:779:9:779:16 | call to min [element] | array_flow.rb:779:5:779:5 | c [element] | +| array_flow.rb:780:10:780:10 | c [element] | array_flow.rb:780:10:780:13 | ...[...] | +| array_flow.rb:780:10:780:10 | c [element] | array_flow.rb:780:10:780:13 | ...[...] | +| array_flow.rb:783:5:783:5 | d | array_flow.rb:788:10:788:10 | d | +| array_flow.rb:783:5:783:5 | d | array_flow.rb:788:10:788:10 | d | +| array_flow.rb:783:9:783:9 | a [element 2] | array_flow.rb:783:9:787:7 | call to min | +| array_flow.rb:783:9:783:9 | a [element 2] | array_flow.rb:783:9:787:7 | call to min | +| array_flow.rb:783:9:783:9 | a [element 2] | array_flow.rb:783:19:783:19 | x | +| array_flow.rb:783:9:783:9 | a [element 2] | array_flow.rb:783:19:783:19 | x | +| array_flow.rb:783:9:783:9 | a [element 2] | array_flow.rb:783:22:783:22 | y | +| array_flow.rb:783:9:783:9 | a [element 2] | array_flow.rb:783:22:783:22 | y | +| array_flow.rb:783:9:787:7 | call to min | array_flow.rb:783:5:783:5 | d | +| array_flow.rb:783:9:787:7 | call to min | array_flow.rb:783:5:783:5 | d | +| array_flow.rb:783:19:783:19 | x | array_flow.rb:784:14:784:14 | x | +| array_flow.rb:783:19:783:19 | x | array_flow.rb:784:14:784:14 | x | +| array_flow.rb:783:22:783:22 | y | array_flow.rb:785:14:785:14 | y | +| array_flow.rb:783:22:783:22 | y | array_flow.rb:785:14:785:14 | y | +| array_flow.rb:791:5:791:5 | e [element] | array_flow.rb:796:10:796:10 | e [element] | +| array_flow.rb:791:5:791:5 | e [element] | array_flow.rb:796:10:796:10 | e [element] | +| array_flow.rb:791:9:791:9 | a [element 2] | array_flow.rb:791:9:795:7 | call to min [element] | +| array_flow.rb:791:9:791:9 | a [element 2] | array_flow.rb:791:9:795:7 | call to min [element] | +| array_flow.rb:791:9:791:9 | a [element 2] | array_flow.rb:791:22:791:22 | x | +| array_flow.rb:791:9:791:9 | a [element 2] | array_flow.rb:791:22:791:22 | x | +| array_flow.rb:791:9:791:9 | a [element 2] | array_flow.rb:791:25:791:25 | y | +| array_flow.rb:791:9:791:9 | a [element 2] | array_flow.rb:791:25:791:25 | y | +| array_flow.rb:791:9:795:7 | call to min [element] | array_flow.rb:791:5:791:5 | e [element] | +| array_flow.rb:791:9:795:7 | call to min [element] | array_flow.rb:791:5:791:5 | e [element] | +| array_flow.rb:791:22:791:22 | x | array_flow.rb:792:14:792:14 | x | +| array_flow.rb:791:22:791:22 | x | array_flow.rb:792:14:792:14 | x | +| array_flow.rb:791:25:791:25 | y | array_flow.rb:793:14:793:14 | y | +| array_flow.rb:791:25:791:25 | y | array_flow.rb:793:14:793:14 | y | +| array_flow.rb:796:10:796:10 | e [element] | array_flow.rb:796:10:796:13 | ...[...] | +| array_flow.rb:796:10:796:10 | e [element] | array_flow.rb:796:10:796:13 | ...[...] | +| array_flow.rb:800:5:800:5 | a [element 2] | array_flow.rb:803:9:803:9 | a [element 2] | +| array_flow.rb:800:5:800:5 | a [element 2] | array_flow.rb:803:9:803:9 | a [element 2] | +| array_flow.rb:800:5:800:5 | a [element 2] | array_flow.rb:810:9:810:9 | a [element 2] | +| array_flow.rb:800:5:800:5 | a [element 2] | array_flow.rb:810:9:810:9 | a [element 2] | +| array_flow.rb:800:16:800:25 | call to source | array_flow.rb:800:5:800:5 | a [element 2] | +| array_flow.rb:800:16:800:25 | call to source | array_flow.rb:800:5:800:5 | a [element 2] | +| array_flow.rb:803:5:803:5 | b | array_flow.rb:807:10:807:10 | b | +| array_flow.rb:803:5:803:5 | b | array_flow.rb:807:10:807:10 | b | +| array_flow.rb:803:9:803:9 | a [element 2] | array_flow.rb:803:9:806:7 | call to min_by | +| array_flow.rb:803:9:803:9 | a [element 2] | array_flow.rb:803:9:806:7 | call to min_by | +| array_flow.rb:803:9:803:9 | a [element 2] | array_flow.rb:803:22:803:22 | x | +| array_flow.rb:803:9:803:9 | a [element 2] | array_flow.rb:803:22:803:22 | x | +| array_flow.rb:803:9:806:7 | call to min_by | array_flow.rb:803:5:803:5 | b | +| array_flow.rb:803:9:806:7 | call to min_by | array_flow.rb:803:5:803:5 | b | +| array_flow.rb:803:22:803:22 | x | array_flow.rb:804:14:804:14 | x | +| array_flow.rb:803:22:803:22 | x | array_flow.rb:804:14:804:14 | x | +| array_flow.rb:810:5:810:5 | c [element] | array_flow.rb:814:10:814:10 | c [element] | +| array_flow.rb:810:5:810:5 | c [element] | array_flow.rb:814:10:814:10 | c [element] | +| array_flow.rb:810:9:810:9 | a [element 2] | array_flow.rb:810:9:813:7 | call to min_by [element] | +| array_flow.rb:810:9:810:9 | a [element 2] | array_flow.rb:810:9:813:7 | call to min_by [element] | +| array_flow.rb:810:9:810:9 | a [element 2] | array_flow.rb:810:25:810:25 | x | +| array_flow.rb:810:9:810:9 | a [element 2] | array_flow.rb:810:25:810:25 | x | +| array_flow.rb:810:9:813:7 | call to min_by [element] | array_flow.rb:810:5:810:5 | c [element] | +| array_flow.rb:810:9:813:7 | call to min_by [element] | array_flow.rb:810:5:810:5 | c [element] | +| array_flow.rb:810:25:810:25 | x | array_flow.rb:811:14:811:14 | x | +| array_flow.rb:810:25:810:25 | x | array_flow.rb:811:14:811:14 | x | +| array_flow.rb:814:10:814:10 | c [element] | array_flow.rb:814:10:814:13 | ...[...] | +| array_flow.rb:814:10:814:10 | c [element] | array_flow.rb:814:10:814:13 | ...[...] | +| array_flow.rb:818:5:818:5 | a [element 2] | array_flow.rb:820:9:820:9 | a [element 2] | +| array_flow.rb:818:5:818:5 | a [element 2] | array_flow.rb:820:9:820:9 | a [element 2] | +| array_flow.rb:818:5:818:5 | a [element 2] | array_flow.rb:824:9:824:9 | a [element 2] | +| array_flow.rb:818:5:818:5 | a [element 2] | array_flow.rb:824:9:824:9 | a [element 2] | +| array_flow.rb:818:16:818:25 | call to source | array_flow.rb:818:5:818:5 | a [element 2] | +| array_flow.rb:818:16:818:25 | call to source | array_flow.rb:818:5:818:5 | a [element 2] | +| array_flow.rb:820:5:820:5 | b [element] | array_flow.rb:821:10:821:10 | b [element] | +| array_flow.rb:820:5:820:5 | b [element] | array_flow.rb:821:10:821:10 | b [element] | +| array_flow.rb:820:5:820:5 | b [element] | array_flow.rb:822:10:822:10 | b [element] | +| array_flow.rb:820:5:820:5 | b [element] | array_flow.rb:822:10:822:10 | b [element] | +| array_flow.rb:820:9:820:9 | a [element 2] | array_flow.rb:820:9:820:16 | call to minmax [element] | +| array_flow.rb:820:9:820:9 | a [element 2] | array_flow.rb:820:9:820:16 | call to minmax [element] | +| array_flow.rb:820:9:820:16 | call to minmax [element] | array_flow.rb:820:5:820:5 | b [element] | +| array_flow.rb:820:9:820:16 | call to minmax [element] | array_flow.rb:820:5:820:5 | b [element] | +| array_flow.rb:821:10:821:10 | b [element] | array_flow.rb:821:10:821:13 | ...[...] | +| array_flow.rb:821:10:821:10 | b [element] | array_flow.rb:821:10:821:13 | ...[...] | +| array_flow.rb:822:10:822:10 | b [element] | array_flow.rb:822:10:822:13 | ...[...] | +| array_flow.rb:822:10:822:10 | b [element] | array_flow.rb:822:10:822:13 | ...[...] | +| array_flow.rb:824:5:824:5 | c [element] | array_flow.rb:829:10:829:10 | c [element] | +| array_flow.rb:824:5:824:5 | c [element] | array_flow.rb:829:10:829:10 | c [element] | +| array_flow.rb:824:5:824:5 | c [element] | array_flow.rb:830:10:830:10 | c [element] | +| array_flow.rb:824:5:824:5 | c [element] | array_flow.rb:830:10:830:10 | c [element] | +| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:9:828:7 | call to minmax [element] | +| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:9:828:7 | call to minmax [element] | +| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:22:824:22 | x | +| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:22:824:22 | x | +| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:25:824:25 | y | +| array_flow.rb:824:9:824:9 | a [element 2] | array_flow.rb:824:25:824:25 | y | +| array_flow.rb:824:9:828:7 | call to minmax [element] | array_flow.rb:824:5:824:5 | c [element] | +| array_flow.rb:824:9:828:7 | call to minmax [element] | array_flow.rb:824:5:824:5 | c [element] | +| array_flow.rb:824:22:824:22 | x | array_flow.rb:825:14:825:14 | x | +| array_flow.rb:824:22:824:22 | x | array_flow.rb:825:14:825:14 | x | +| array_flow.rb:824:25:824:25 | y | array_flow.rb:826:14:826:14 | y | +| array_flow.rb:824:25:824:25 | y | array_flow.rb:826:14:826:14 | y | +| array_flow.rb:829:10:829:10 | c [element] | array_flow.rb:829:10:829:13 | ...[...] | +| array_flow.rb:829:10:829:10 | c [element] | array_flow.rb:829:10:829:13 | ...[...] | +| array_flow.rb:830:10:830:10 | c [element] | array_flow.rb:830:10:830:13 | ...[...] | +| array_flow.rb:830:10:830:10 | c [element] | array_flow.rb:830:10:830:13 | ...[...] | +| array_flow.rb:834:5:834:5 | a [element 2] | array_flow.rb:835:9:835:9 | a [element 2] | +| array_flow.rb:834:5:834:5 | a [element 2] | array_flow.rb:835:9:835:9 | a [element 2] | +| array_flow.rb:834:16:834:25 | call to source | array_flow.rb:834:5:834:5 | a [element 2] | +| array_flow.rb:834:16:834:25 | call to source | array_flow.rb:834:5:834:5 | a [element 2] | +| array_flow.rb:835:5:835:5 | b [element] | array_flow.rb:839:10:839:10 | b [element] | +| array_flow.rb:835:5:835:5 | b [element] | array_flow.rb:839:10:839:10 | b [element] | +| array_flow.rb:835:5:835:5 | b [element] | array_flow.rb:840:10:840:10 | b [element] | +| array_flow.rb:835:5:835:5 | b [element] | array_flow.rb:840:10:840:10 | b [element] | +| array_flow.rb:835:9:835:9 | a [element 2] | array_flow.rb:835:9:838:7 | call to minmax_by [element] | +| array_flow.rb:835:9:835:9 | a [element 2] | array_flow.rb:835:9:838:7 | call to minmax_by [element] | +| array_flow.rb:835:9:835:9 | a [element 2] | array_flow.rb:835:25:835:25 | x | +| array_flow.rb:835:9:835:9 | a [element 2] | array_flow.rb:835:25:835:25 | x | +| array_flow.rb:835:9:838:7 | call to minmax_by [element] | array_flow.rb:835:5:835:5 | b [element] | +| array_flow.rb:835:9:838:7 | call to minmax_by [element] | array_flow.rb:835:5:835:5 | b [element] | +| array_flow.rb:835:25:835:25 | x | array_flow.rb:836:14:836:14 | x | +| array_flow.rb:835:25:835:25 | x | array_flow.rb:836:14:836:14 | x | +| array_flow.rb:839:10:839:10 | b [element] | array_flow.rb:839:10:839:13 | ...[...] | +| array_flow.rb:839:10:839:10 | b [element] | array_flow.rb:839:10:839:13 | ...[...] | +| array_flow.rb:840:10:840:10 | b [element] | array_flow.rb:840:10:840:13 | ...[...] | +| array_flow.rb:840:10:840:10 | b [element] | array_flow.rb:840:10:840:13 | ...[...] | +| array_flow.rb:844:5:844:5 | a [element 2] | array_flow.rb:845:5:845:5 | a [element 2] | +| array_flow.rb:844:5:844:5 | a [element 2] | array_flow.rb:845:5:845:5 | a [element 2] | +| array_flow.rb:844:16:844:25 | call to source | array_flow.rb:844:5:844:5 | a [element 2] | +| array_flow.rb:844:16:844:25 | call to source | array_flow.rb:844:5:844:5 | a [element 2] | +| array_flow.rb:845:5:845:5 | a [element 2] | array_flow.rb:845:17:845:17 | x | +| array_flow.rb:845:5:845:5 | a [element 2] | array_flow.rb:845:17:845:17 | x | +| array_flow.rb:845:17:845:17 | x | array_flow.rb:846:14:846:14 | x | +| array_flow.rb:845:17:845:17 | x | array_flow.rb:846:14:846:14 | x | +| array_flow.rb:853:5:853:5 | a [element 2] | array_flow.rb:854:5:854:5 | a [element 2] | +| array_flow.rb:853:5:853:5 | a [element 2] | array_flow.rb:854:5:854:5 | a [element 2] | +| array_flow.rb:853:16:853:25 | call to source | array_flow.rb:853:5:853:5 | a [element 2] | +| array_flow.rb:853:16:853:25 | call to source | array_flow.rb:853:5:853:5 | a [element 2] | +| array_flow.rb:854:5:854:5 | a [element 2] | array_flow.rb:854:16:854:16 | x | +| array_flow.rb:854:5:854:5 | a [element 2] | array_flow.rb:854:16:854:16 | x | +| array_flow.rb:854:16:854:16 | x | array_flow.rb:855:14:855:14 | x | +| array_flow.rb:854:16:854:16 | x | array_flow.rb:855:14:855:14 | x | +| array_flow.rb:860:5:860:5 | a [element 2] | array_flow.rb:861:9:861:9 | a [element 2] | +| array_flow.rb:860:16:860:25 | call to source | array_flow.rb:860:5:860:5 | a [element 2] | +| array_flow.rb:861:5:861:5 | b | array_flow.rb:862:10:862:10 | b | +| array_flow.rb:861:9:861:9 | a [element 2] | array_flow.rb:861:9:861:20 | call to pack | +| array_flow.rb:861:9:861:20 | call to pack | array_flow.rb:861:5:861:5 | b | +| array_flow.rb:866:5:866:5 | a [element 2] | array_flow.rb:867:9:867:9 | a [element 2] | +| array_flow.rb:866:5:866:5 | a [element 2] | array_flow.rb:867:9:867:9 | a [element 2] | +| array_flow.rb:866:16:866:25 | call to source | array_flow.rb:866:5:866:5 | a [element 2] | +| array_flow.rb:866:16:866:25 | call to source | array_flow.rb:866:5:866:5 | a [element 2] | +| array_flow.rb:867:5:867:5 | b [element, element] | array_flow.rb:871:10:871:10 | b [element, element] | +| array_flow.rb:867:5:867:5 | b [element, element] | array_flow.rb:871:10:871:10 | b [element, element] | +| array_flow.rb:867:5:867:5 | b [element, element] | array_flow.rb:872:10:872:10 | b [element, element] | +| array_flow.rb:867:5:867:5 | b [element, element] | array_flow.rb:872:10:872:10 | b [element, element] | +| array_flow.rb:867:9:867:9 | a [element 2] | array_flow.rb:867:9:870:7 | call to partition [element, element] | +| array_flow.rb:867:9:867:9 | a [element 2] | array_flow.rb:867:9:870:7 | call to partition [element, element] | +| array_flow.rb:867:9:867:9 | a [element 2] | array_flow.rb:867:25:867:25 | x | +| array_flow.rb:867:9:867:9 | a [element 2] | array_flow.rb:867:25:867:25 | x | +| array_flow.rb:867:9:870:7 | call to partition [element, element] | array_flow.rb:867:5:867:5 | b [element, element] | +| array_flow.rb:867:9:870:7 | call to partition [element, element] | array_flow.rb:867:5:867:5 | b [element, element] | +| array_flow.rb:867:25:867:25 | x | array_flow.rb:868:14:868:14 | x | +| array_flow.rb:867:25:867:25 | x | array_flow.rb:868:14:868:14 | x | +| array_flow.rb:871:10:871:10 | b [element, element] | array_flow.rb:871:10:871:13 | ...[...] [element] | +| array_flow.rb:871:10:871:10 | b [element, element] | array_flow.rb:871:10:871:13 | ...[...] [element] | +| array_flow.rb:871:10:871:13 | ...[...] [element] | array_flow.rb:871:10:871:16 | ...[...] | +| array_flow.rb:871:10:871:13 | ...[...] [element] | array_flow.rb:871:10:871:16 | ...[...] | +| array_flow.rb:872:10:872:10 | b [element, element] | array_flow.rb:872:10:872:13 | ...[...] [element] | +| array_flow.rb:872:10:872:10 | b [element, element] | array_flow.rb:872:10:872:13 | ...[...] [element] | +| array_flow.rb:872:10:872:13 | ...[...] [element] | array_flow.rb:872:10:872:16 | ...[...] | +| array_flow.rb:872:10:872:13 | ...[...] [element] | array_flow.rb:872:10:872:16 | ...[...] | +| array_flow.rb:876:5:876:5 | a [element 2] | array_flow.rb:878:9:878:9 | a [element 2] | +| array_flow.rb:876:5:876:5 | a [element 2] | array_flow.rb:878:9:878:9 | a [element 2] | +| array_flow.rb:876:5:876:5 | a [element 2] | array_flow.rb:886:9:886:9 | a [element 2] | +| array_flow.rb:876:5:876:5 | a [element 2] | array_flow.rb:886:9:886:9 | a [element 2] | +| array_flow.rb:876:5:876:5 | a [element 2] | array_flow.rb:893:9:893:9 | a [element 2] | +| array_flow.rb:876:5:876:5 | a [element 2] | array_flow.rb:893:9:893:9 | a [element 2] | +| array_flow.rb:876:16:876:25 | call to source | array_flow.rb:876:5:876:5 | a [element 2] | +| array_flow.rb:876:16:876:25 | call to source | array_flow.rb:876:5:876:5 | a [element 2] | +| array_flow.rb:878:5:878:5 | b [element 2] | array_flow.rb:884:10:884:10 | b [element 2] | +| array_flow.rb:878:5:878:5 | b [element 2] | array_flow.rb:884:10:884:10 | b [element 2] | +| array_flow.rb:878:9:878:9 | a [element 2] | array_flow.rb:878:9:882:7 | call to permutation [element 2] | +| array_flow.rb:878:9:878:9 | a [element 2] | array_flow.rb:878:9:882:7 | call to permutation [element 2] | +| array_flow.rb:878:9:878:9 | a [element 2] | array_flow.rb:878:27:878:27 | x [element] | +| array_flow.rb:878:9:878:9 | a [element 2] | array_flow.rb:878:27:878:27 | x [element] | +| array_flow.rb:878:9:882:7 | call to permutation [element 2] | array_flow.rb:878:5:878:5 | b [element 2] | +| array_flow.rb:878:9:882:7 | call to permutation [element 2] | array_flow.rb:878:5:878:5 | b [element 2] | +| array_flow.rb:878:27:878:27 | x [element] | array_flow.rb:879:14:879:14 | x [element] | +| array_flow.rb:878:27:878:27 | x [element] | array_flow.rb:879:14:879:14 | x [element] | +| array_flow.rb:878:27:878:27 | x [element] | array_flow.rb:880:14:880:14 | x [element] | +| array_flow.rb:878:27:878:27 | x [element] | array_flow.rb:880:14:880:14 | x [element] | +| array_flow.rb:878:27:878:27 | x [element] | array_flow.rb:881:14:881:14 | x [element] | +| array_flow.rb:878:27:878:27 | x [element] | array_flow.rb:881:14:881:14 | x [element] | +| array_flow.rb:879:14:879:14 | x [element] | array_flow.rb:879:14:879:17 | ...[...] | +| array_flow.rb:879:14:879:14 | x [element] | array_flow.rb:879:14:879:17 | ...[...] | +| array_flow.rb:880:14:880:14 | x [element] | array_flow.rb:880:14:880:17 | ...[...] | +| array_flow.rb:880:14:880:14 | x [element] | array_flow.rb:880:14:880:17 | ...[...] | +| array_flow.rb:881:14:881:14 | x [element] | array_flow.rb:881:14:881:17 | ...[...] | +| array_flow.rb:881:14:881:14 | x [element] | array_flow.rb:881:14:881:17 | ...[...] | +| array_flow.rb:884:10:884:10 | b [element 2] | array_flow.rb:884:10:884:13 | ...[...] | +| array_flow.rb:884:10:884:10 | b [element 2] | array_flow.rb:884:10:884:13 | ...[...] | +| array_flow.rb:886:5:886:5 | c [element 2] | array_flow.rb:891:10:891:10 | c [element 2] | +| array_flow.rb:886:5:886:5 | c [element 2] | array_flow.rb:891:10:891:10 | c [element 2] | +| array_flow.rb:886:5:886:5 | c [element 2] | array_flow.rb:898:10:898:10 | c [element 2] | +| array_flow.rb:886:5:886:5 | c [element 2] | array_flow.rb:898:10:898:10 | c [element 2] | +| array_flow.rb:886:9:886:9 | a [element 2] | array_flow.rb:886:9:889:7 | call to permutation [element 2] | +| array_flow.rb:886:9:886:9 | a [element 2] | array_flow.rb:886:9:889:7 | call to permutation [element 2] | +| array_flow.rb:886:9:886:9 | a [element 2] | array_flow.rb:886:30:886:30 | x [element] | +| array_flow.rb:886:9:886:9 | a [element 2] | array_flow.rb:886:30:886:30 | x [element] | +| array_flow.rb:886:9:889:7 | call to permutation [element 2] | array_flow.rb:886:5:886:5 | c [element 2] | +| array_flow.rb:886:9:889:7 | call to permutation [element 2] | array_flow.rb:886:5:886:5 | c [element 2] | +| array_flow.rb:886:30:886:30 | x [element] | array_flow.rb:887:14:887:14 | x [element] | +| array_flow.rb:886:30:886:30 | x [element] | array_flow.rb:887:14:887:14 | x [element] | +| array_flow.rb:886:30:886:30 | x [element] | array_flow.rb:888:14:888:14 | x [element] | +| array_flow.rb:886:30:886:30 | x [element] | array_flow.rb:888:14:888:14 | x [element] | +| array_flow.rb:887:14:887:14 | x [element] | array_flow.rb:887:14:887:17 | ...[...] | +| array_flow.rb:887:14:887:14 | x [element] | array_flow.rb:887:14:887:17 | ...[...] | +| array_flow.rb:888:14:888:14 | x [element] | array_flow.rb:888:14:888:17 | ...[...] | +| array_flow.rb:888:14:888:14 | x [element] | array_flow.rb:888:14:888:17 | ...[...] | +| array_flow.rb:891:10:891:10 | c [element 2] | array_flow.rb:891:10:891:13 | ...[...] | +| array_flow.rb:891:10:891:10 | c [element 2] | array_flow.rb:891:10:891:13 | ...[...] | +| array_flow.rb:893:9:893:9 | a [element 2] | array_flow.rb:893:30:893:30 | x [element] | +| array_flow.rb:893:9:893:9 | a [element 2] | array_flow.rb:893:30:893:30 | x [element] | +| array_flow.rb:893:30:893:30 | x [element] | array_flow.rb:894:14:894:14 | x [element] | +| array_flow.rb:893:30:893:30 | x [element] | array_flow.rb:894:14:894:14 | x [element] | +| array_flow.rb:893:30:893:30 | x [element] | array_flow.rb:895:14:895:14 | x [element] | +| array_flow.rb:893:30:893:30 | x [element] | array_flow.rb:895:14:895:14 | x [element] | +| array_flow.rb:894:14:894:14 | x [element] | array_flow.rb:894:14:894:17 | ...[...] | +| array_flow.rb:894:14:894:14 | x [element] | array_flow.rb:894:14:894:17 | ...[...] | +| array_flow.rb:895:14:895:14 | x [element] | array_flow.rb:895:14:895:17 | ...[...] | +| array_flow.rb:895:14:895:14 | x [element] | array_flow.rb:895:14:895:17 | ...[...] | +| array_flow.rb:898:10:898:10 | c [element 2] | array_flow.rb:898:10:898:13 | ...[...] | +| array_flow.rb:898:10:898:10 | c [element 2] | array_flow.rb:898:10:898:13 | ...[...] | +| array_flow.rb:905:5:905:5 | a [element 1] | array_flow.rb:906:9:906:9 | a [element 1] | +| array_flow.rb:905:5:905:5 | a [element 1] | array_flow.rb:906:9:906:9 | a [element 1] | +| array_flow.rb:905:5:905:5 | a [element 1] | array_flow.rb:909:10:909:10 | a [element 1] | +| array_flow.rb:905:5:905:5 | a [element 1] | array_flow.rb:909:10:909:10 | a [element 1] | +| array_flow.rb:905:5:905:5 | a [element 3] | array_flow.rb:906:9:906:9 | a [element 3] | +| array_flow.rb:905:5:905:5 | a [element 3] | array_flow.rb:906:9:906:9 | a [element 3] | +| array_flow.rb:905:5:905:5 | a [element 3] | array_flow.rb:911:10:911:10 | a [element 3] | +| array_flow.rb:905:5:905:5 | a [element 3] | array_flow.rb:911:10:911:10 | a [element 3] | +| array_flow.rb:905:13:905:24 | call to source | array_flow.rb:905:5:905:5 | a [element 1] | +| array_flow.rb:905:13:905:24 | call to source | array_flow.rb:905:5:905:5 | a [element 1] | +| array_flow.rb:905:30:905:41 | call to source | array_flow.rb:905:5:905:5 | a [element 3] | +| array_flow.rb:905:30:905:41 | call to source | array_flow.rb:905:5:905:5 | a [element 3] | +| array_flow.rb:906:5:906:5 | b | array_flow.rb:907:10:907:10 | b | +| array_flow.rb:906:5:906:5 | b | array_flow.rb:907:10:907:10 | b | +| array_flow.rb:906:9:906:9 | a [element 1] | array_flow.rb:906:9:906:13 | call to pop | +| array_flow.rb:906:9:906:9 | a [element 1] | array_flow.rb:906:9:906:13 | call to pop | +| array_flow.rb:906:9:906:9 | a [element 3] | array_flow.rb:906:9:906:13 | call to pop | +| array_flow.rb:906:9:906:9 | a [element 3] | array_flow.rb:906:9:906:13 | call to pop | +| array_flow.rb:906:9:906:13 | call to pop | array_flow.rb:906:5:906:5 | b | +| array_flow.rb:906:9:906:13 | call to pop | array_flow.rb:906:5:906:5 | b | +| array_flow.rb:909:10:909:10 | a [element 1] | array_flow.rb:909:10:909:13 | ...[...] | +| array_flow.rb:909:10:909:10 | a [element 1] | array_flow.rb:909:10:909:13 | ...[...] | +| array_flow.rb:911:10:911:10 | a [element 3] | array_flow.rb:911:10:911:13 | ...[...] | +| array_flow.rb:911:10:911:10 | a [element 3] | array_flow.rb:911:10:911:13 | ...[...] | +| array_flow.rb:913:5:913:5 | a [element 1] | array_flow.rb:914:9:914:9 | a [element 1] | +| array_flow.rb:913:5:913:5 | a [element 1] | array_flow.rb:914:9:914:9 | a [element 1] | +| array_flow.rb:913:5:913:5 | a [element 1] | array_flow.rb:918:10:918:10 | a [element 1] | +| array_flow.rb:913:5:913:5 | a [element 1] | array_flow.rb:918:10:918:10 | a [element 1] | +| array_flow.rb:913:5:913:5 | a [element 3] | array_flow.rb:914:9:914:9 | a [element 3] | +| array_flow.rb:913:5:913:5 | a [element 3] | array_flow.rb:914:9:914:9 | a [element 3] | +| array_flow.rb:913:5:913:5 | a [element 3] | array_flow.rb:920:10:920:10 | a [element 3] | +| array_flow.rb:913:5:913:5 | a [element 3] | array_flow.rb:920:10:920:10 | a [element 3] | +| array_flow.rb:913:13:913:24 | call to source | array_flow.rb:913:5:913:5 | a [element 1] | +| array_flow.rb:913:13:913:24 | call to source | array_flow.rb:913:5:913:5 | a [element 1] | +| array_flow.rb:913:30:913:41 | call to source | array_flow.rb:913:5:913:5 | a [element 3] | +| array_flow.rb:913:30:913:41 | call to source | array_flow.rb:913:5:913:5 | a [element 3] | +| array_flow.rb:914:5:914:5 | b [element] | array_flow.rb:915:10:915:10 | b [element] | +| array_flow.rb:914:5:914:5 | b [element] | array_flow.rb:915:10:915:10 | b [element] | +| array_flow.rb:914:5:914:5 | b [element] | array_flow.rb:916:10:916:10 | b [element] | +| array_flow.rb:914:5:914:5 | b [element] | array_flow.rb:916:10:916:10 | b [element] | +| array_flow.rb:914:9:914:9 | a [element 1] | array_flow.rb:914:9:914:16 | call to pop [element] | +| array_flow.rb:914:9:914:9 | a [element 1] | array_flow.rb:914:9:914:16 | call to pop [element] | +| array_flow.rb:914:9:914:9 | a [element 3] | array_flow.rb:914:9:914:16 | call to pop [element] | +| array_flow.rb:914:9:914:9 | a [element 3] | array_flow.rb:914:9:914:16 | call to pop [element] | +| array_flow.rb:914:9:914:16 | call to pop [element] | array_flow.rb:914:5:914:5 | b [element] | +| array_flow.rb:914:9:914:16 | call to pop [element] | array_flow.rb:914:5:914:5 | b [element] | +| array_flow.rb:915:10:915:10 | b [element] | array_flow.rb:915:10:915:13 | ...[...] | +| array_flow.rb:915:10:915:10 | b [element] | array_flow.rb:915:10:915:13 | ...[...] | +| array_flow.rb:916:10:916:10 | b [element] | array_flow.rb:916:10:916:13 | ...[...] | +| array_flow.rb:916:10:916:10 | b [element] | array_flow.rb:916:10:916:13 | ...[...] | +| array_flow.rb:918:10:918:10 | a [element 1] | array_flow.rb:918:10:918:13 | ...[...] | +| array_flow.rb:918:10:918:10 | a [element 1] | array_flow.rb:918:10:918:13 | ...[...] | +| array_flow.rb:920:10:920:10 | a [element 3] | array_flow.rb:920:10:920:13 | ...[...] | +| array_flow.rb:920:10:920:10 | a [element 3] | array_flow.rb:920:10:920:13 | ...[...] | +| array_flow.rb:924:5:924:5 | a [element 2] | array_flow.rb:925:5:925:5 | a [element 2] | +| array_flow.rb:924:5:924:5 | a [element 2] | array_flow.rb:925:5:925:5 | a [element 2] | | array_flow.rb:924:16:924:27 | call to source | array_flow.rb:924:5:924:5 | a [element 2] | | array_flow.rb:924:16:924:27 | call to source | array_flow.rb:924:5:924:5 | a [element 2] | -| array_flow.rb:925:5:925:5 | b [element 1] | array_flow.rb:927:19:927:19 | b [element 1] | -| array_flow.rb:925:5:925:5 | b [element 1] | array_flow.rb:927:19:927:19 | b [element 1] | -| array_flow.rb:925:13:925:24 | call to source | array_flow.rb:925:5:925:5 | b [element 1] | -| array_flow.rb:925:13:925:24 | call to source | array_flow.rb:925:5:925:5 | b [element 1] | -| array_flow.rb:926:5:926:5 | c [element 0] | array_flow.rb:927:22:927:22 | c [element 0] | -| array_flow.rb:926:5:926:5 | c [element 0] | array_flow.rb:927:22:927:22 | c [element 0] | -| array_flow.rb:926:10:926:21 | call to source | array_flow.rb:926:5:926:5 | c [element 0] | -| array_flow.rb:926:10:926:21 | call to source | array_flow.rb:926:5:926:5 | c [element 0] | -| array_flow.rb:927:5:927:5 | d [element, element] | array_flow.rb:928:10:928:10 | d [element, element] | -| array_flow.rb:927:5:927:5 | d [element, element] | array_flow.rb:928:10:928:10 | d [element, element] | -| array_flow.rb:927:5:927:5 | d [element, element] | array_flow.rb:929:10:929:10 | d [element, element] | -| array_flow.rb:927:5:927:5 | d [element, element] | array_flow.rb:929:10:929:10 | d [element, element] | -| array_flow.rb:927:9:927:9 | a [element 2] | array_flow.rb:927:9:927:22 | call to product [element, element] | -| array_flow.rb:927:9:927:9 | a [element 2] | array_flow.rb:927:9:927:22 | call to product [element, element] | -| array_flow.rb:927:9:927:22 | call to product [element, element] | array_flow.rb:927:5:927:5 | d [element, element] | -| array_flow.rb:927:9:927:22 | call to product [element, element] | array_flow.rb:927:5:927:5 | d [element, element] | -| array_flow.rb:927:19:927:19 | b [element 1] | array_flow.rb:927:9:927:22 | call to product [element, element] | -| array_flow.rb:927:19:927:19 | b [element 1] | array_flow.rb:927:9:927:22 | call to product [element, element] | -| array_flow.rb:927:22:927:22 | c [element 0] | array_flow.rb:927:9:927:22 | call to product [element, element] | -| array_flow.rb:927:22:927:22 | c [element 0] | array_flow.rb:927:9:927:22 | call to product [element, element] | -| array_flow.rb:928:10:928:10 | d [element, element] | array_flow.rb:928:10:928:13 | ...[...] [element] | -| array_flow.rb:928:10:928:10 | d [element, element] | array_flow.rb:928:10:928:13 | ...[...] [element] | -| array_flow.rb:928:10:928:13 | ...[...] [element] | array_flow.rb:928:10:928:16 | ...[...] | -| array_flow.rb:928:10:928:13 | ...[...] [element] | array_flow.rb:928:10:928:16 | ...[...] | -| array_flow.rb:929:10:929:10 | d [element, element] | array_flow.rb:929:10:929:13 | ...[...] [element] | -| array_flow.rb:929:10:929:10 | d [element, element] | array_flow.rb:929:10:929:13 | ...[...] [element] | -| array_flow.rb:929:10:929:13 | ...[...] [element] | array_flow.rb:929:10:929:16 | ...[...] | -| array_flow.rb:929:10:929:13 | ...[...] [element] | array_flow.rb:929:10:929:16 | ...[...] | -| array_flow.rb:933:5:933:5 | a [element 0] | array_flow.rb:934:9:934:9 | a [element 0] | -| array_flow.rb:933:5:933:5 | a [element 0] | array_flow.rb:934:9:934:9 | a [element 0] | -| array_flow.rb:933:5:933:5 | a [element 0] | array_flow.rb:935:10:935:10 | a [element 0] | -| array_flow.rb:933:5:933:5 | a [element 0] | array_flow.rb:935:10:935:10 | a [element 0] | -| array_flow.rb:933:10:933:21 | call to source | array_flow.rb:933:5:933:5 | a [element 0] | -| array_flow.rb:933:10:933:21 | call to source | array_flow.rb:933:5:933:5 | a [element 0] | -| array_flow.rb:934:5:934:5 | b [element 0] | array_flow.rb:937:10:937:10 | b [element 0] | -| array_flow.rb:934:5:934:5 | b [element 0] | array_flow.rb:937:10:937:10 | b [element 0] | -| array_flow.rb:934:5:934:5 | b [element] | array_flow.rb:937:10:937:10 | b [element] | -| array_flow.rb:934:5:934:5 | b [element] | array_flow.rb:937:10:937:10 | b [element] | -| array_flow.rb:934:5:934:5 | b [element] | array_flow.rb:938:10:938:10 | b [element] | -| array_flow.rb:934:5:934:5 | b [element] | array_flow.rb:938:10:938:10 | b [element] | -| array_flow.rb:934:9:934:9 | [post] a [element] | array_flow.rb:935:10:935:10 | a [element] | -| array_flow.rb:934:9:934:9 | [post] a [element] | array_flow.rb:935:10:935:10 | a [element] | -| array_flow.rb:934:9:934:9 | [post] a [element] | array_flow.rb:936:10:936:10 | a [element] | -| array_flow.rb:934:9:934:9 | [post] a [element] | array_flow.rb:936:10:936:10 | a [element] | -| array_flow.rb:934:9:934:9 | a [element 0] | array_flow.rb:934:9:934:44 | call to append [element 0] | -| array_flow.rb:934:9:934:9 | a [element 0] | array_flow.rb:934:9:934:44 | call to append [element 0] | -| array_flow.rb:934:9:934:44 | call to append [element 0] | array_flow.rb:934:5:934:5 | b [element 0] | -| array_flow.rb:934:9:934:44 | call to append [element 0] | array_flow.rb:934:5:934:5 | b [element 0] | -| array_flow.rb:934:9:934:44 | call to append [element] | array_flow.rb:934:5:934:5 | b [element] | -| array_flow.rb:934:9:934:44 | call to append [element] | array_flow.rb:934:5:934:5 | b [element] | -| array_flow.rb:934:18:934:29 | call to source | array_flow.rb:934:9:934:9 | [post] a [element] | -| array_flow.rb:934:18:934:29 | call to source | array_flow.rb:934:9:934:9 | [post] a [element] | -| array_flow.rb:934:18:934:29 | call to source | array_flow.rb:934:9:934:44 | call to append [element] | -| array_flow.rb:934:18:934:29 | call to source | array_flow.rb:934:9:934:44 | call to append [element] | -| array_flow.rb:934:32:934:43 | call to source | array_flow.rb:934:9:934:9 | [post] a [element] | -| array_flow.rb:934:32:934:43 | call to source | array_flow.rb:934:9:934:9 | [post] a [element] | -| array_flow.rb:934:32:934:43 | call to source | array_flow.rb:934:9:934:44 | call to append [element] | -| array_flow.rb:934:32:934:43 | call to source | array_flow.rb:934:9:934:44 | call to append [element] | -| array_flow.rb:935:10:935:10 | a [element 0] | array_flow.rb:935:10:935:13 | ...[...] | -| array_flow.rb:935:10:935:10 | a [element 0] | array_flow.rb:935:10:935:13 | ...[...] | -| array_flow.rb:935:10:935:10 | a [element] | array_flow.rb:935:10:935:13 | ...[...] | -| array_flow.rb:935:10:935:10 | a [element] | array_flow.rb:935:10:935:13 | ...[...] | -| array_flow.rb:936:10:936:10 | a [element] | array_flow.rb:936:10:936:13 | ...[...] | -| array_flow.rb:936:10:936:10 | a [element] | array_flow.rb:936:10:936:13 | ...[...] | -| array_flow.rb:937:10:937:10 | b [element 0] | array_flow.rb:937:10:937:13 | ...[...] | -| array_flow.rb:937:10:937:10 | b [element 0] | array_flow.rb:937:10:937:13 | ...[...] | -| array_flow.rb:937:10:937:10 | b [element] | array_flow.rb:937:10:937:13 | ...[...] | -| array_flow.rb:937:10:937:10 | b [element] | array_flow.rb:937:10:937:13 | ...[...] | -| array_flow.rb:938:10:938:10 | b [element] | array_flow.rb:938:10:938:13 | ...[...] | -| array_flow.rb:938:10:938:10 | b [element] | array_flow.rb:938:10:938:13 | ...[...] | -| array_flow.rb:944:5:944:5 | c [element 0] | array_flow.rb:945:16:945:16 | c [element 0] | -| array_flow.rb:944:5:944:5 | c [element 0] | array_flow.rb:945:16:945:16 | c [element 0] | -| array_flow.rb:944:10:944:19 | call to source | array_flow.rb:944:5:944:5 | c [element 0] | -| array_flow.rb:944:10:944:19 | call to source | array_flow.rb:944:5:944:5 | c [element 0] | -| array_flow.rb:945:5:945:5 | d [element 2, element 0] | array_flow.rb:946:10:946:10 | d [element 2, element 0] | -| array_flow.rb:945:5:945:5 | d [element 2, element 0] | array_flow.rb:946:10:946:10 | d [element 2, element 0] | -| array_flow.rb:945:5:945:5 | d [element 2, element 0] | array_flow.rb:947:10:947:10 | d [element 2, element 0] | -| array_flow.rb:945:5:945:5 | d [element 2, element 0] | array_flow.rb:947:10:947:10 | d [element 2, element 0] | -| array_flow.rb:945:16:945:16 | c [element 0] | array_flow.rb:945:5:945:5 | d [element 2, element 0] | -| array_flow.rb:945:16:945:16 | c [element 0] | array_flow.rb:945:5:945:5 | d [element 2, element 0] | -| array_flow.rb:946:10:946:10 | d [element 2, element 0] | array_flow.rb:946:10:946:22 | call to rassoc [element 0] | -| array_flow.rb:946:10:946:10 | d [element 2, element 0] | array_flow.rb:946:10:946:22 | call to rassoc [element 0] | -| array_flow.rb:946:10:946:22 | call to rassoc [element 0] | array_flow.rb:946:10:946:25 | ...[...] | -| array_flow.rb:946:10:946:22 | call to rassoc [element 0] | array_flow.rb:946:10:946:25 | ...[...] | -| array_flow.rb:947:10:947:10 | d [element 2, element 0] | array_flow.rb:947:10:947:22 | call to rassoc [element 0] | -| array_flow.rb:947:10:947:10 | d [element 2, element 0] | array_flow.rb:947:10:947:22 | call to rassoc [element 0] | -| array_flow.rb:947:10:947:22 | call to rassoc [element 0] | array_flow.rb:947:10:947:25 | ...[...] | -| array_flow.rb:947:10:947:22 | call to rassoc [element 0] | array_flow.rb:947:10:947:25 | ...[...] | -| array_flow.rb:951:5:951:5 | a [element 0] | array_flow.rb:952:9:952:9 | a [element 0] | -| array_flow.rb:951:5:951:5 | a [element 0] | array_flow.rb:952:9:952:9 | a [element 0] | -| array_flow.rb:951:5:951:5 | a [element 0] | array_flow.rb:957:9:957:9 | a [element 0] | -| array_flow.rb:951:5:951:5 | a [element 0] | array_flow.rb:957:9:957:9 | a [element 0] | -| array_flow.rb:951:5:951:5 | a [element 2] | array_flow.rb:952:9:952:9 | a [element 2] | -| array_flow.rb:951:5:951:5 | a [element 2] | array_flow.rb:952:9:952:9 | a [element 2] | -| array_flow.rb:951:5:951:5 | a [element 2] | array_flow.rb:957:9:957:9 | a [element 2] | -| array_flow.rb:951:5:951:5 | a [element 2] | array_flow.rb:957:9:957:9 | a [element 2] | -| array_flow.rb:951:10:951:21 | call to source | array_flow.rb:951:5:951:5 | a [element 0] | -| array_flow.rb:951:10:951:21 | call to source | array_flow.rb:951:5:951:5 | a [element 0] | -| array_flow.rb:951:27:951:38 | call to source | array_flow.rb:951:5:951:5 | a [element 2] | -| array_flow.rb:951:27:951:38 | call to source | array_flow.rb:951:5:951:5 | a [element 2] | -| array_flow.rb:952:9:952:9 | a [element 0] | array_flow.rb:952:22:952:22 | x | -| array_flow.rb:952:9:952:9 | a [element 0] | array_flow.rb:952:22:952:22 | x | -| array_flow.rb:952:9:952:9 | a [element 2] | array_flow.rb:952:25:952:25 | y | -| array_flow.rb:952:9:952:9 | a [element 2] | array_flow.rb:952:25:952:25 | y | -| array_flow.rb:952:22:952:22 | x | array_flow.rb:953:14:953:14 | x | -| array_flow.rb:952:22:952:22 | x | array_flow.rb:953:14:953:14 | x | -| array_flow.rb:952:25:952:25 | y | array_flow.rb:954:14:954:14 | y | -| array_flow.rb:952:25:952:25 | y | array_flow.rb:954:14:954:14 | y | -| array_flow.rb:957:9:957:9 | a [element 0] | array_flow.rb:957:28:957:28 | y | -| array_flow.rb:957:9:957:9 | a [element 0] | array_flow.rb:957:28:957:28 | y | -| array_flow.rb:957:9:957:9 | a [element 2] | array_flow.rb:957:28:957:28 | y | -| array_flow.rb:957:9:957:9 | a [element 2] | array_flow.rb:957:28:957:28 | y | -| array_flow.rb:957:28:957:28 | y | array_flow.rb:959:14:959:14 | y | -| array_flow.rb:957:28:957:28 | y | array_flow.rb:959:14:959:14 | y | -| array_flow.rb:965:5:965:5 | a [element 2] | array_flow.rb:966:9:966:9 | a [element 2] | -| array_flow.rb:965:5:965:5 | a [element 2] | array_flow.rb:966:9:966:9 | a [element 2] | -| array_flow.rb:965:16:965:25 | call to source | array_flow.rb:965:5:965:5 | a [element 2] | -| array_flow.rb:965:16:965:25 | call to source | array_flow.rb:965:5:965:5 | a [element 2] | -| array_flow.rb:966:5:966:5 | b [element] | array_flow.rb:970:10:970:10 | b [element] | -| array_flow.rb:966:5:966:5 | b [element] | array_flow.rb:970:10:970:10 | b [element] | -| array_flow.rb:966:9:966:9 | a [element 2] | array_flow.rb:966:9:969:7 | call to reject [element] | -| array_flow.rb:966:9:966:9 | a [element 2] | array_flow.rb:966:9:969:7 | call to reject [element] | -| array_flow.rb:966:9:966:9 | a [element 2] | array_flow.rb:966:22:966:22 | x | -| array_flow.rb:966:9:966:9 | a [element 2] | array_flow.rb:966:22:966:22 | x | -| array_flow.rb:966:9:969:7 | call to reject [element] | array_flow.rb:966:5:966:5 | b [element] | -| array_flow.rb:966:9:969:7 | call to reject [element] | array_flow.rb:966:5:966:5 | b [element] | -| array_flow.rb:966:22:966:22 | x | array_flow.rb:967:14:967:14 | x | -| array_flow.rb:966:22:966:22 | x | array_flow.rb:967:14:967:14 | x | -| array_flow.rb:970:10:970:10 | b [element] | array_flow.rb:970:10:970:13 | ...[...] | -| array_flow.rb:970:10:970:10 | b [element] | array_flow.rb:970:10:970:13 | ...[...] | -| array_flow.rb:974:5:974:5 | a [element 2] | array_flow.rb:975:9:975:9 | a [element 2] | -| array_flow.rb:974:5:974:5 | a [element 2] | array_flow.rb:975:9:975:9 | a [element 2] | -| array_flow.rb:974:16:974:25 | call to source | array_flow.rb:974:5:974:5 | a [element 2] | -| array_flow.rb:974:16:974:25 | call to source | array_flow.rb:974:5:974:5 | a [element 2] | -| array_flow.rb:975:5:975:5 | b [element] | array_flow.rb:980:10:980:10 | b [element] | -| array_flow.rb:975:5:975:5 | b [element] | array_flow.rb:980:10:980:10 | b [element] | -| array_flow.rb:975:9:975:9 | [post] a [element] | array_flow.rb:979:10:979:10 | a [element] | -| array_flow.rb:975:9:975:9 | [post] a [element] | array_flow.rb:979:10:979:10 | a [element] | -| array_flow.rb:975:9:975:9 | a [element 2] | array_flow.rb:975:9:975:9 | [post] a [element] | -| array_flow.rb:975:9:975:9 | a [element 2] | array_flow.rb:975:9:975:9 | [post] a [element] | -| array_flow.rb:975:9:975:9 | a [element 2] | array_flow.rb:975:9:978:7 | call to reject! [element] | -| array_flow.rb:975:9:975:9 | a [element 2] | array_flow.rb:975:9:978:7 | call to reject! [element] | -| array_flow.rb:975:9:975:9 | a [element 2] | array_flow.rb:975:23:975:23 | x | -| array_flow.rb:975:9:975:9 | a [element 2] | array_flow.rb:975:23:975:23 | x | -| array_flow.rb:975:9:978:7 | call to reject! [element] | array_flow.rb:975:5:975:5 | b [element] | -| array_flow.rb:975:9:978:7 | call to reject! [element] | array_flow.rb:975:5:975:5 | b [element] | -| array_flow.rb:975:23:975:23 | x | array_flow.rb:976:14:976:14 | x | -| array_flow.rb:975:23:975:23 | x | array_flow.rb:976:14:976:14 | x | -| array_flow.rb:979:10:979:10 | a [element] | array_flow.rb:979:10:979:13 | ...[...] | -| array_flow.rb:979:10:979:10 | a [element] | array_flow.rb:979:10:979:13 | ...[...] | -| array_flow.rb:980:10:980:10 | b [element] | array_flow.rb:980:10:980:13 | ...[...] | -| array_flow.rb:980:10:980:10 | b [element] | array_flow.rb:980:10:980:13 | ...[...] | -| array_flow.rb:984:5:984:5 | a [element 2] | array_flow.rb:985:9:985:9 | a [element 2] | -| array_flow.rb:984:5:984:5 | a [element 2] | array_flow.rb:985:9:985:9 | a [element 2] | -| array_flow.rb:984:16:984:25 | call to source | array_flow.rb:984:5:984:5 | a [element 2] | -| array_flow.rb:984:16:984:25 | call to source | array_flow.rb:984:5:984:5 | a [element 2] | -| array_flow.rb:985:5:985:5 | b [element 2] | array_flow.rb:990:10:990:10 | b [element 2] | -| array_flow.rb:985:5:985:5 | b [element 2] | array_flow.rb:990:10:990:10 | b [element 2] | -| array_flow.rb:985:9:985:9 | a [element 2] | array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] | -| array_flow.rb:985:9:985:9 | a [element 2] | array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] | -| array_flow.rb:985:9:985:9 | a [element 2] | array_flow.rb:985:39:985:39 | x [element] | -| array_flow.rb:985:9:985:9 | a [element 2] | array_flow.rb:985:39:985:39 | x [element] | -| array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] | array_flow.rb:985:5:985:5 | b [element 2] | -| array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] | array_flow.rb:985:5:985:5 | b [element 2] | -| array_flow.rb:985:39:985:39 | x [element] | array_flow.rb:986:14:986:14 | x [element] | -| array_flow.rb:985:39:985:39 | x [element] | array_flow.rb:986:14:986:14 | x [element] | -| array_flow.rb:985:39:985:39 | x [element] | array_flow.rb:987:14:987:14 | x [element] | -| array_flow.rb:985:39:985:39 | x [element] | array_flow.rb:987:14:987:14 | x [element] | -| array_flow.rb:986:14:986:14 | x [element] | array_flow.rb:986:14:986:17 | ...[...] | -| array_flow.rb:986:14:986:14 | x [element] | array_flow.rb:986:14:986:17 | ...[...] | -| array_flow.rb:987:14:987:14 | x [element] | array_flow.rb:987:14:987:17 | ...[...] | -| array_flow.rb:987:14:987:14 | x [element] | array_flow.rb:987:14:987:17 | ...[...] | -| array_flow.rb:990:10:990:10 | b [element 2] | array_flow.rb:990:10:990:13 | ...[...] | -| array_flow.rb:990:10:990:10 | b [element 2] | array_flow.rb:990:10:990:13 | ...[...] | -| array_flow.rb:994:5:994:5 | a [element 2] | array_flow.rb:995:9:995:9 | a [element 2] | -| array_flow.rb:994:5:994:5 | a [element 2] | array_flow.rb:995:9:995:9 | a [element 2] | -| array_flow.rb:994:16:994:25 | call to source | array_flow.rb:994:5:994:5 | a [element 2] | -| array_flow.rb:994:16:994:25 | call to source | array_flow.rb:994:5:994:5 | a [element 2] | -| array_flow.rb:995:5:995:5 | b [element 2] | array_flow.rb:1000:10:1000:10 | b [element 2] | -| array_flow.rb:995:5:995:5 | b [element 2] | array_flow.rb:1000:10:1000:10 | b [element 2] | -| array_flow.rb:995:9:995:9 | a [element 2] | array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] | -| array_flow.rb:995:9:995:9 | a [element 2] | array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] | -| array_flow.rb:995:9:995:9 | a [element 2] | array_flow.rb:995:39:995:39 | x [element] | -| array_flow.rb:995:9:995:9 | a [element 2] | array_flow.rb:995:39:995:39 | x [element] | -| array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] | array_flow.rb:995:5:995:5 | b [element 2] | -| array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] | array_flow.rb:995:5:995:5 | b [element 2] | -| array_flow.rb:995:39:995:39 | x [element] | array_flow.rb:996:14:996:14 | x [element] | -| array_flow.rb:995:39:995:39 | x [element] | array_flow.rb:996:14:996:14 | x [element] | -| array_flow.rb:995:39:995:39 | x [element] | array_flow.rb:997:14:997:14 | x [element] | -| array_flow.rb:995:39:995:39 | x [element] | array_flow.rb:997:14:997:14 | x [element] | -| array_flow.rb:996:14:996:14 | x [element] | array_flow.rb:996:14:996:17 | ...[...] | -| array_flow.rb:996:14:996:14 | x [element] | array_flow.rb:996:14:996:17 | ...[...] | +| array_flow.rb:925:5:925:5 | [post] a [element 2] | array_flow.rb:928:10:928:10 | a [element 2] | +| array_flow.rb:925:5:925:5 | [post] a [element 2] | array_flow.rb:928:10:928:10 | a [element 2] | +| array_flow.rb:925:5:925:5 | [post] a [element 5] | array_flow.rb:931:10:931:10 | a [element 5] | +| array_flow.rb:925:5:925:5 | [post] a [element 5] | array_flow.rb:931:10:931:10 | a [element 5] | +| array_flow.rb:925:5:925:5 | a [element 2] | array_flow.rb:925:5:925:5 | [post] a [element 5] | +| array_flow.rb:925:5:925:5 | a [element 2] | array_flow.rb:925:5:925:5 | [post] a [element 5] | +| array_flow.rb:925:21:925:32 | call to source | array_flow.rb:925:5:925:5 | [post] a [element 2] | +| array_flow.rb:925:21:925:32 | call to source | array_flow.rb:925:5:925:5 | [post] a [element 2] | +| array_flow.rb:928:10:928:10 | a [element 2] | array_flow.rb:928:10:928:13 | ...[...] | +| array_flow.rb:928:10:928:10 | a [element 2] | array_flow.rb:928:10:928:13 | ...[...] | +| array_flow.rb:931:10:931:10 | a [element 5] | array_flow.rb:931:10:931:13 | ...[...] | +| array_flow.rb:931:10:931:10 | a [element 5] | array_flow.rb:931:10:931:13 | ...[...] | +| array_flow.rb:935:5:935:5 | a [element 2] | array_flow.rb:938:9:938:9 | a [element 2] | +| array_flow.rb:935:5:935:5 | a [element 2] | array_flow.rb:938:9:938:9 | a [element 2] | +| array_flow.rb:935:16:935:27 | call to source | array_flow.rb:935:5:935:5 | a [element 2] | +| array_flow.rb:935:16:935:27 | call to source | array_flow.rb:935:5:935:5 | a [element 2] | +| array_flow.rb:936:5:936:5 | b [element 1] | array_flow.rb:938:19:938:19 | b [element 1] | +| array_flow.rb:936:5:936:5 | b [element 1] | array_flow.rb:938:19:938:19 | b [element 1] | +| array_flow.rb:936:13:936:24 | call to source | array_flow.rb:936:5:936:5 | b [element 1] | +| array_flow.rb:936:13:936:24 | call to source | array_flow.rb:936:5:936:5 | b [element 1] | +| array_flow.rb:937:5:937:5 | c [element 0] | array_flow.rb:938:22:938:22 | c [element 0] | +| array_flow.rb:937:5:937:5 | c [element 0] | array_flow.rb:938:22:938:22 | c [element 0] | +| array_flow.rb:937:10:937:21 | call to source | array_flow.rb:937:5:937:5 | c [element 0] | +| array_flow.rb:937:10:937:21 | call to source | array_flow.rb:937:5:937:5 | c [element 0] | +| array_flow.rb:938:5:938:5 | d [element, element] | array_flow.rb:939:10:939:10 | d [element, element] | +| array_flow.rb:938:5:938:5 | d [element, element] | array_flow.rb:939:10:939:10 | d [element, element] | +| array_flow.rb:938:5:938:5 | d [element, element] | array_flow.rb:940:10:940:10 | d [element, element] | +| array_flow.rb:938:5:938:5 | d [element, element] | array_flow.rb:940:10:940:10 | d [element, element] | +| array_flow.rb:938:9:938:9 | a [element 2] | array_flow.rb:938:9:938:22 | call to product [element, element] | +| array_flow.rb:938:9:938:9 | a [element 2] | array_flow.rb:938:9:938:22 | call to product [element, element] | +| array_flow.rb:938:9:938:22 | call to product [element, element] | array_flow.rb:938:5:938:5 | d [element, element] | +| array_flow.rb:938:9:938:22 | call to product [element, element] | array_flow.rb:938:5:938:5 | d [element, element] | +| array_flow.rb:938:19:938:19 | b [element 1] | array_flow.rb:938:9:938:22 | call to product [element, element] | +| array_flow.rb:938:19:938:19 | b [element 1] | array_flow.rb:938:9:938:22 | call to product [element, element] | +| array_flow.rb:938:22:938:22 | c [element 0] | array_flow.rb:938:9:938:22 | call to product [element, element] | +| array_flow.rb:938:22:938:22 | c [element 0] | array_flow.rb:938:9:938:22 | call to product [element, element] | +| array_flow.rb:939:10:939:10 | d [element, element] | array_flow.rb:939:10:939:13 | ...[...] [element] | +| array_flow.rb:939:10:939:10 | d [element, element] | array_flow.rb:939:10:939:13 | ...[...] [element] | +| array_flow.rb:939:10:939:13 | ...[...] [element] | array_flow.rb:939:10:939:16 | ...[...] | +| array_flow.rb:939:10:939:13 | ...[...] [element] | array_flow.rb:939:10:939:16 | ...[...] | +| array_flow.rb:940:10:940:10 | d [element, element] | array_flow.rb:940:10:940:13 | ...[...] [element] | +| array_flow.rb:940:10:940:10 | d [element, element] | array_flow.rb:940:10:940:13 | ...[...] [element] | +| array_flow.rb:940:10:940:13 | ...[...] [element] | array_flow.rb:940:10:940:16 | ...[...] | +| array_flow.rb:940:10:940:13 | ...[...] [element] | array_flow.rb:940:10:940:16 | ...[...] | +| array_flow.rb:944:5:944:5 | a [element 0] | array_flow.rb:945:9:945:9 | a [element 0] | +| array_flow.rb:944:5:944:5 | a [element 0] | array_flow.rb:945:9:945:9 | a [element 0] | +| array_flow.rb:944:5:944:5 | a [element 0] | array_flow.rb:946:10:946:10 | a [element 0] | +| array_flow.rb:944:5:944:5 | a [element 0] | array_flow.rb:946:10:946:10 | a [element 0] | +| array_flow.rb:944:10:944:21 | call to source | array_flow.rb:944:5:944:5 | a [element 0] | +| array_flow.rb:944:10:944:21 | call to source | array_flow.rb:944:5:944:5 | a [element 0] | +| array_flow.rb:945:5:945:5 | b [element 0] | array_flow.rb:948:10:948:10 | b [element 0] | +| array_flow.rb:945:5:945:5 | b [element 0] | array_flow.rb:948:10:948:10 | b [element 0] | +| array_flow.rb:945:5:945:5 | b [element] | array_flow.rb:948:10:948:10 | b [element] | +| array_flow.rb:945:5:945:5 | b [element] | array_flow.rb:948:10:948:10 | b [element] | +| array_flow.rb:945:5:945:5 | b [element] | array_flow.rb:949:10:949:10 | b [element] | +| array_flow.rb:945:5:945:5 | b [element] | array_flow.rb:949:10:949:10 | b [element] | +| array_flow.rb:945:9:945:9 | [post] a [element] | array_flow.rb:946:10:946:10 | a [element] | +| array_flow.rb:945:9:945:9 | [post] a [element] | array_flow.rb:946:10:946:10 | a [element] | +| array_flow.rb:945:9:945:9 | [post] a [element] | array_flow.rb:947:10:947:10 | a [element] | +| array_flow.rb:945:9:945:9 | [post] a [element] | array_flow.rb:947:10:947:10 | a [element] | +| array_flow.rb:945:9:945:9 | a [element 0] | array_flow.rb:945:9:945:44 | call to append [element 0] | +| array_flow.rb:945:9:945:9 | a [element 0] | array_flow.rb:945:9:945:44 | call to append [element 0] | +| array_flow.rb:945:9:945:44 | call to append [element 0] | array_flow.rb:945:5:945:5 | b [element 0] | +| array_flow.rb:945:9:945:44 | call to append [element 0] | array_flow.rb:945:5:945:5 | b [element 0] | +| array_flow.rb:945:9:945:44 | call to append [element] | array_flow.rb:945:5:945:5 | b [element] | +| array_flow.rb:945:9:945:44 | call to append [element] | array_flow.rb:945:5:945:5 | b [element] | +| array_flow.rb:945:18:945:29 | call to source | array_flow.rb:945:9:945:9 | [post] a [element] | +| array_flow.rb:945:18:945:29 | call to source | array_flow.rb:945:9:945:9 | [post] a [element] | +| array_flow.rb:945:18:945:29 | call to source | array_flow.rb:945:9:945:44 | call to append [element] | +| array_flow.rb:945:18:945:29 | call to source | array_flow.rb:945:9:945:44 | call to append [element] | +| array_flow.rb:945:32:945:43 | call to source | array_flow.rb:945:9:945:9 | [post] a [element] | +| array_flow.rb:945:32:945:43 | call to source | array_flow.rb:945:9:945:9 | [post] a [element] | +| array_flow.rb:945:32:945:43 | call to source | array_flow.rb:945:9:945:44 | call to append [element] | +| array_flow.rb:945:32:945:43 | call to source | array_flow.rb:945:9:945:44 | call to append [element] | +| array_flow.rb:946:10:946:10 | a [element 0] | array_flow.rb:946:10:946:13 | ...[...] | +| array_flow.rb:946:10:946:10 | a [element 0] | array_flow.rb:946:10:946:13 | ...[...] | +| array_flow.rb:946:10:946:10 | a [element] | array_flow.rb:946:10:946:13 | ...[...] | +| array_flow.rb:946:10:946:10 | a [element] | array_flow.rb:946:10:946:13 | ...[...] | +| array_flow.rb:947:10:947:10 | a [element] | array_flow.rb:947:10:947:13 | ...[...] | +| array_flow.rb:947:10:947:10 | a [element] | array_flow.rb:947:10:947:13 | ...[...] | +| array_flow.rb:948:10:948:10 | b [element 0] | array_flow.rb:948:10:948:13 | ...[...] | +| array_flow.rb:948:10:948:10 | b [element 0] | array_flow.rb:948:10:948:13 | ...[...] | +| array_flow.rb:948:10:948:10 | b [element] | array_flow.rb:948:10:948:13 | ...[...] | +| array_flow.rb:948:10:948:10 | b [element] | array_flow.rb:948:10:948:13 | ...[...] | +| array_flow.rb:949:10:949:10 | b [element] | array_flow.rb:949:10:949:13 | ...[...] | +| array_flow.rb:949:10:949:10 | b [element] | array_flow.rb:949:10:949:13 | ...[...] | +| array_flow.rb:955:5:955:5 | c [element 0] | array_flow.rb:956:16:956:16 | c [element 0] | +| array_flow.rb:955:5:955:5 | c [element 0] | array_flow.rb:956:16:956:16 | c [element 0] | +| array_flow.rb:955:10:955:19 | call to source | array_flow.rb:955:5:955:5 | c [element 0] | +| array_flow.rb:955:10:955:19 | call to source | array_flow.rb:955:5:955:5 | c [element 0] | +| array_flow.rb:956:5:956:5 | d [element 2, element 0] | array_flow.rb:957:10:957:10 | d [element 2, element 0] | +| array_flow.rb:956:5:956:5 | d [element 2, element 0] | array_flow.rb:957:10:957:10 | d [element 2, element 0] | +| array_flow.rb:956:5:956:5 | d [element 2, element 0] | array_flow.rb:958:10:958:10 | d [element 2, element 0] | +| array_flow.rb:956:5:956:5 | d [element 2, element 0] | array_flow.rb:958:10:958:10 | d [element 2, element 0] | +| array_flow.rb:956:16:956:16 | c [element 0] | array_flow.rb:956:5:956:5 | d [element 2, element 0] | +| array_flow.rb:956:16:956:16 | c [element 0] | array_flow.rb:956:5:956:5 | d [element 2, element 0] | +| array_flow.rb:957:10:957:10 | d [element 2, element 0] | array_flow.rb:957:10:957:22 | call to rassoc [element 0] | +| array_flow.rb:957:10:957:10 | d [element 2, element 0] | array_flow.rb:957:10:957:22 | call to rassoc [element 0] | +| array_flow.rb:957:10:957:22 | call to rassoc [element 0] | array_flow.rb:957:10:957:25 | ...[...] | +| array_flow.rb:957:10:957:22 | call to rassoc [element 0] | array_flow.rb:957:10:957:25 | ...[...] | +| array_flow.rb:958:10:958:10 | d [element 2, element 0] | array_flow.rb:958:10:958:22 | call to rassoc [element 0] | +| array_flow.rb:958:10:958:10 | d [element 2, element 0] | array_flow.rb:958:10:958:22 | call to rassoc [element 0] | +| array_flow.rb:958:10:958:22 | call to rassoc [element 0] | array_flow.rb:958:10:958:25 | ...[...] | +| array_flow.rb:958:10:958:22 | call to rassoc [element 0] | array_flow.rb:958:10:958:25 | ...[...] | +| array_flow.rb:962:5:962:5 | a [element 0] | array_flow.rb:963:9:963:9 | a [element 0] | +| array_flow.rb:962:5:962:5 | a [element 0] | array_flow.rb:963:9:963:9 | a [element 0] | +| array_flow.rb:962:5:962:5 | a [element 0] | array_flow.rb:968:9:968:9 | a [element 0] | +| array_flow.rb:962:5:962:5 | a [element 0] | array_flow.rb:968:9:968:9 | a [element 0] | +| array_flow.rb:962:5:962:5 | a [element 2] | array_flow.rb:963:9:963:9 | a [element 2] | +| array_flow.rb:962:5:962:5 | a [element 2] | array_flow.rb:963:9:963:9 | a [element 2] | +| array_flow.rb:962:5:962:5 | a [element 2] | array_flow.rb:968:9:968:9 | a [element 2] | +| array_flow.rb:962:5:962:5 | a [element 2] | array_flow.rb:968:9:968:9 | a [element 2] | +| array_flow.rb:962:10:962:21 | call to source | array_flow.rb:962:5:962:5 | a [element 0] | +| array_flow.rb:962:10:962:21 | call to source | array_flow.rb:962:5:962:5 | a [element 0] | +| array_flow.rb:962:27:962:38 | call to source | array_flow.rb:962:5:962:5 | a [element 2] | +| array_flow.rb:962:27:962:38 | call to source | array_flow.rb:962:5:962:5 | a [element 2] | +| array_flow.rb:963:9:963:9 | a [element 0] | array_flow.rb:963:22:963:22 | x | +| array_flow.rb:963:9:963:9 | a [element 0] | array_flow.rb:963:22:963:22 | x | +| array_flow.rb:963:9:963:9 | a [element 2] | array_flow.rb:963:25:963:25 | y | +| array_flow.rb:963:9:963:9 | a [element 2] | array_flow.rb:963:25:963:25 | y | +| array_flow.rb:963:22:963:22 | x | array_flow.rb:964:14:964:14 | x | +| array_flow.rb:963:22:963:22 | x | array_flow.rb:964:14:964:14 | x | +| array_flow.rb:963:25:963:25 | y | array_flow.rb:965:14:965:14 | y | +| array_flow.rb:963:25:963:25 | y | array_flow.rb:965:14:965:14 | y | +| array_flow.rb:968:9:968:9 | a [element 0] | array_flow.rb:968:28:968:28 | y | +| array_flow.rb:968:9:968:9 | a [element 0] | array_flow.rb:968:28:968:28 | y | +| array_flow.rb:968:9:968:9 | a [element 2] | array_flow.rb:968:28:968:28 | y | +| array_flow.rb:968:9:968:9 | a [element 2] | array_flow.rb:968:28:968:28 | y | +| array_flow.rb:968:28:968:28 | y | array_flow.rb:970:14:970:14 | y | +| array_flow.rb:968:28:968:28 | y | array_flow.rb:970:14:970:14 | y | +| array_flow.rb:976:5:976:5 | a [element 2] | array_flow.rb:977:9:977:9 | a [element 2] | +| array_flow.rb:976:5:976:5 | a [element 2] | array_flow.rb:977:9:977:9 | a [element 2] | +| array_flow.rb:976:16:976:25 | call to source | array_flow.rb:976:5:976:5 | a [element 2] | +| array_flow.rb:976:16:976:25 | call to source | array_flow.rb:976:5:976:5 | a [element 2] | +| array_flow.rb:977:5:977:5 | b [element] | array_flow.rb:981:10:981:10 | b [element] | +| array_flow.rb:977:5:977:5 | b [element] | array_flow.rb:981:10:981:10 | b [element] | +| array_flow.rb:977:9:977:9 | a [element 2] | array_flow.rb:977:9:980:7 | call to reject [element] | +| array_flow.rb:977:9:977:9 | a [element 2] | array_flow.rb:977:9:980:7 | call to reject [element] | +| array_flow.rb:977:9:977:9 | a [element 2] | array_flow.rb:977:22:977:22 | x | +| array_flow.rb:977:9:977:9 | a [element 2] | array_flow.rb:977:22:977:22 | x | +| array_flow.rb:977:9:980:7 | call to reject [element] | array_flow.rb:977:5:977:5 | b [element] | +| array_flow.rb:977:9:980:7 | call to reject [element] | array_flow.rb:977:5:977:5 | b [element] | +| array_flow.rb:977:22:977:22 | x | array_flow.rb:978:14:978:14 | x | +| array_flow.rb:977:22:977:22 | x | array_flow.rb:978:14:978:14 | x | +| array_flow.rb:981:10:981:10 | b [element] | array_flow.rb:981:10:981:13 | ...[...] | +| array_flow.rb:981:10:981:10 | b [element] | array_flow.rb:981:10:981:13 | ...[...] | +| array_flow.rb:985:5:985:5 | a [element 2] | array_flow.rb:986:9:986:9 | a [element 2] | +| array_flow.rb:985:5:985:5 | a [element 2] | array_flow.rb:986:9:986:9 | a [element 2] | +| array_flow.rb:985:16:985:25 | call to source | array_flow.rb:985:5:985:5 | a [element 2] | +| array_flow.rb:985:16:985:25 | call to source | array_flow.rb:985:5:985:5 | a [element 2] | +| array_flow.rb:986:5:986:5 | b [element] | array_flow.rb:991:10:991:10 | b [element] | +| array_flow.rb:986:5:986:5 | b [element] | array_flow.rb:991:10:991:10 | b [element] | +| array_flow.rb:986:9:986:9 | [post] a [element] | array_flow.rb:990:10:990:10 | a [element] | +| array_flow.rb:986:9:986:9 | [post] a [element] | array_flow.rb:990:10:990:10 | a [element] | +| array_flow.rb:986:9:986:9 | a [element 2] | array_flow.rb:986:9:986:9 | [post] a [element] | +| array_flow.rb:986:9:986:9 | a [element 2] | array_flow.rb:986:9:986:9 | [post] a [element] | +| array_flow.rb:986:9:986:9 | a [element 2] | array_flow.rb:986:9:989:7 | call to reject! [element] | +| array_flow.rb:986:9:986:9 | a [element 2] | array_flow.rb:986:9:989:7 | call to reject! [element] | +| array_flow.rb:986:9:986:9 | a [element 2] | array_flow.rb:986:23:986:23 | x | +| array_flow.rb:986:9:986:9 | a [element 2] | array_flow.rb:986:23:986:23 | x | +| array_flow.rb:986:9:989:7 | call to reject! [element] | array_flow.rb:986:5:986:5 | b [element] | +| array_flow.rb:986:9:989:7 | call to reject! [element] | array_flow.rb:986:5:986:5 | b [element] | +| array_flow.rb:986:23:986:23 | x | array_flow.rb:987:14:987:14 | x | +| array_flow.rb:986:23:986:23 | x | array_flow.rb:987:14:987:14 | x | +| array_flow.rb:990:10:990:10 | a [element] | array_flow.rb:990:10:990:13 | ...[...] | +| array_flow.rb:990:10:990:10 | a [element] | array_flow.rb:990:10:990:13 | ...[...] | +| array_flow.rb:991:10:991:10 | b [element] | array_flow.rb:991:10:991:13 | ...[...] | +| array_flow.rb:991:10:991:10 | b [element] | array_flow.rb:991:10:991:13 | ...[...] | +| array_flow.rb:995:5:995:5 | a [element 2] | array_flow.rb:996:9:996:9 | a [element 2] | +| array_flow.rb:995:5:995:5 | a [element 2] | array_flow.rb:996:9:996:9 | a [element 2] | +| array_flow.rb:995:16:995:25 | call to source | array_flow.rb:995:5:995:5 | a [element 2] | +| array_flow.rb:995:16:995:25 | call to source | array_flow.rb:995:5:995:5 | a [element 2] | +| array_flow.rb:996:5:996:5 | b [element 2] | array_flow.rb:1001:10:1001:10 | b [element 2] | +| array_flow.rb:996:5:996:5 | b [element 2] | array_flow.rb:1001:10:1001:10 | b [element 2] | +| array_flow.rb:996:9:996:9 | a [element 2] | array_flow.rb:996:9:999:7 | call to repeated_combination [element 2] | +| array_flow.rb:996:9:996:9 | a [element 2] | array_flow.rb:996:9:999:7 | call to repeated_combination [element 2] | +| array_flow.rb:996:9:996:9 | a [element 2] | array_flow.rb:996:39:996:39 | x [element] | +| array_flow.rb:996:9:996:9 | a [element 2] | array_flow.rb:996:39:996:39 | x [element] | +| array_flow.rb:996:9:999:7 | call to repeated_combination [element 2] | array_flow.rb:996:5:996:5 | b [element 2] | +| array_flow.rb:996:9:999:7 | call to repeated_combination [element 2] | array_flow.rb:996:5:996:5 | b [element 2] | +| array_flow.rb:996:39:996:39 | x [element] | array_flow.rb:997:14:997:14 | x [element] | +| array_flow.rb:996:39:996:39 | x [element] | array_flow.rb:997:14:997:14 | x [element] | +| array_flow.rb:996:39:996:39 | x [element] | array_flow.rb:998:14:998:14 | x [element] | +| array_flow.rb:996:39:996:39 | x [element] | array_flow.rb:998:14:998:14 | x [element] | | array_flow.rb:997:14:997:14 | x [element] | array_flow.rb:997:14:997:17 | ...[...] | | array_flow.rb:997:14:997:14 | x [element] | array_flow.rb:997:14:997:17 | ...[...] | -| array_flow.rb:1000:10:1000:10 | b [element 2] | array_flow.rb:1000:10:1000:13 | ...[...] | -| array_flow.rb:1000:10:1000:10 | b [element 2] | array_flow.rb:1000:10:1000:13 | ...[...] | -| array_flow.rb:1006:5:1006:5 | b [element 0] | array_flow.rb:1008:10:1008:10 | b [element 0] | -| array_flow.rb:1006:5:1006:5 | b [element 0] | array_flow.rb:1008:10:1008:10 | b [element 0] | -| array_flow.rb:1006:9:1006:9 | [post] a [element 0] | array_flow.rb:1007:10:1007:10 | a [element 0] | -| array_flow.rb:1006:9:1006:9 | [post] a [element 0] | array_flow.rb:1007:10:1007:10 | a [element 0] | -| array_flow.rb:1006:9:1006:33 | call to replace [element 0] | array_flow.rb:1006:5:1006:5 | b [element 0] | -| array_flow.rb:1006:9:1006:33 | call to replace [element 0] | array_flow.rb:1006:5:1006:5 | b [element 0] | -| array_flow.rb:1006:20:1006:31 | call to source | array_flow.rb:1006:9:1006:9 | [post] a [element 0] | -| array_flow.rb:1006:20:1006:31 | call to source | array_flow.rb:1006:9:1006:9 | [post] a [element 0] | -| array_flow.rb:1006:20:1006:31 | call to source | array_flow.rb:1006:9:1006:33 | call to replace [element 0] | -| array_flow.rb:1006:20:1006:31 | call to source | array_flow.rb:1006:9:1006:33 | call to replace [element 0] | -| array_flow.rb:1007:10:1007:10 | a [element 0] | array_flow.rb:1007:10:1007:13 | ...[...] | -| array_flow.rb:1007:10:1007:10 | a [element 0] | array_flow.rb:1007:10:1007:13 | ...[...] | -| array_flow.rb:1008:10:1008:10 | b [element 0] | array_flow.rb:1008:10:1008:13 | ...[...] | -| array_flow.rb:1008:10:1008:10 | b [element 0] | array_flow.rb:1008:10:1008:13 | ...[...] | -| array_flow.rb:1012:5:1012:5 | a [element 2] | array_flow.rb:1013:9:1013:9 | a [element 2] | -| array_flow.rb:1012:5:1012:5 | a [element 2] | array_flow.rb:1013:9:1013:9 | a [element 2] | -| array_flow.rb:1012:5:1012:5 | a [element 2] | array_flow.rb:1018:10:1018:10 | a [element 2] | -| array_flow.rb:1012:5:1012:5 | a [element 2] | array_flow.rb:1018:10:1018:10 | a [element 2] | -| array_flow.rb:1012:5:1012:5 | a [element 3] | array_flow.rb:1013:9:1013:9 | a [element 3] | -| array_flow.rb:1012:5:1012:5 | a [element 3] | array_flow.rb:1013:9:1013:9 | a [element 3] | -| array_flow.rb:1012:5:1012:5 | a [element 3] | array_flow.rb:1019:10:1019:10 | a [element 3] | -| array_flow.rb:1012:5:1012:5 | a [element 3] | array_flow.rb:1019:10:1019:10 | a [element 3] | -| array_flow.rb:1012:16:1012:28 | call to source | array_flow.rb:1012:5:1012:5 | a [element 2] | -| array_flow.rb:1012:16:1012:28 | call to source | array_flow.rb:1012:5:1012:5 | a [element 2] | -| array_flow.rb:1012:31:1012:43 | call to source | array_flow.rb:1012:5:1012:5 | a [element 3] | -| array_flow.rb:1012:31:1012:43 | call to source | array_flow.rb:1012:5:1012:5 | a [element 3] | -| array_flow.rb:1013:5:1013:5 | b [element] | array_flow.rb:1014:10:1014:10 | b [element] | -| array_flow.rb:1013:5:1013:5 | b [element] | array_flow.rb:1014:10:1014:10 | b [element] | -| array_flow.rb:1013:5:1013:5 | b [element] | array_flow.rb:1015:10:1015:10 | b [element] | -| array_flow.rb:1013:5:1013:5 | b [element] | array_flow.rb:1015:10:1015:10 | b [element] | -| array_flow.rb:1013:5:1013:5 | b [element] | array_flow.rb:1016:10:1016:10 | b [element] | -| array_flow.rb:1013:5:1013:5 | b [element] | array_flow.rb:1016:10:1016:10 | b [element] | -| array_flow.rb:1013:9:1013:9 | a [element 2] | array_flow.rb:1013:9:1013:17 | call to reverse [element] | -| array_flow.rb:1013:9:1013:9 | a [element 2] | array_flow.rb:1013:9:1013:17 | call to reverse [element] | -| array_flow.rb:1013:9:1013:9 | a [element 3] | array_flow.rb:1013:9:1013:17 | call to reverse [element] | -| array_flow.rb:1013:9:1013:9 | a [element 3] | array_flow.rb:1013:9:1013:17 | call to reverse [element] | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] | array_flow.rb:1013:5:1013:5 | b [element] | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] | array_flow.rb:1013:5:1013:5 | b [element] | -| array_flow.rb:1014:10:1014:10 | b [element] | array_flow.rb:1014:10:1014:13 | ...[...] | -| array_flow.rb:1014:10:1014:10 | b [element] | array_flow.rb:1014:10:1014:13 | ...[...] | -| array_flow.rb:1015:10:1015:10 | b [element] | array_flow.rb:1015:10:1015:13 | ...[...] | -| array_flow.rb:1015:10:1015:10 | b [element] | array_flow.rb:1015:10:1015:13 | ...[...] | -| array_flow.rb:1016:10:1016:10 | b [element] | array_flow.rb:1016:10:1016:13 | ...[...] | -| array_flow.rb:1016:10:1016:10 | b [element] | array_flow.rb:1016:10:1016:13 | ...[...] | -| array_flow.rb:1018:10:1018:10 | a [element 2] | array_flow.rb:1018:10:1018:13 | ...[...] | -| array_flow.rb:1018:10:1018:10 | a [element 2] | array_flow.rb:1018:10:1018:13 | ...[...] | -| array_flow.rb:1019:10:1019:10 | a [element 3] | array_flow.rb:1019:10:1019:13 | ...[...] | -| array_flow.rb:1019:10:1019:10 | a [element 3] | array_flow.rb:1019:10:1019:13 | ...[...] | +| array_flow.rb:998:14:998:14 | x [element] | array_flow.rb:998:14:998:17 | ...[...] | +| array_flow.rb:998:14:998:14 | x [element] | array_flow.rb:998:14:998:17 | ...[...] | +| array_flow.rb:1001:10:1001:10 | b [element 2] | array_flow.rb:1001:10:1001:13 | ...[...] | +| array_flow.rb:1001:10:1001:10 | b [element 2] | array_flow.rb:1001:10:1001:13 | ...[...] | +| array_flow.rb:1005:5:1005:5 | a [element 2] | array_flow.rb:1006:9:1006:9 | a [element 2] | +| array_flow.rb:1005:5:1005:5 | a [element 2] | array_flow.rb:1006:9:1006:9 | a [element 2] | +| array_flow.rb:1005:16:1005:25 | call to source | array_flow.rb:1005:5:1005:5 | a [element 2] | +| array_flow.rb:1005:16:1005:25 | call to source | array_flow.rb:1005:5:1005:5 | a [element 2] | +| array_flow.rb:1006:5:1006:5 | b [element 2] | array_flow.rb:1011:10:1011:10 | b [element 2] | +| array_flow.rb:1006:5:1006:5 | b [element 2] | array_flow.rb:1011:10:1011:10 | b [element 2] | +| array_flow.rb:1006:9:1006:9 | a [element 2] | array_flow.rb:1006:9:1009:7 | call to repeated_permutation [element 2] | +| array_flow.rb:1006:9:1006:9 | a [element 2] | array_flow.rb:1006:9:1009:7 | call to repeated_permutation [element 2] | +| array_flow.rb:1006:9:1006:9 | a [element 2] | array_flow.rb:1006:39:1006:39 | x [element] | +| array_flow.rb:1006:9:1006:9 | a [element 2] | array_flow.rb:1006:39:1006:39 | x [element] | +| array_flow.rb:1006:9:1009:7 | call to repeated_permutation [element 2] | array_flow.rb:1006:5:1006:5 | b [element 2] | +| array_flow.rb:1006:9:1009:7 | call to repeated_permutation [element 2] | array_flow.rb:1006:5:1006:5 | b [element 2] | +| array_flow.rb:1006:39:1006:39 | x [element] | array_flow.rb:1007:14:1007:14 | x [element] | +| array_flow.rb:1006:39:1006:39 | x [element] | array_flow.rb:1007:14:1007:14 | x [element] | +| array_flow.rb:1006:39:1006:39 | x [element] | array_flow.rb:1008:14:1008:14 | x [element] | +| array_flow.rb:1006:39:1006:39 | x [element] | array_flow.rb:1008:14:1008:14 | x [element] | +| array_flow.rb:1007:14:1007:14 | x [element] | array_flow.rb:1007:14:1007:17 | ...[...] | +| array_flow.rb:1007:14:1007:14 | x [element] | array_flow.rb:1007:14:1007:17 | ...[...] | +| array_flow.rb:1008:14:1008:14 | x [element] | array_flow.rb:1008:14:1008:17 | ...[...] | +| array_flow.rb:1008:14:1008:14 | x [element] | array_flow.rb:1008:14:1008:17 | ...[...] | +| array_flow.rb:1011:10:1011:10 | b [element 2] | array_flow.rb:1011:10:1011:13 | ...[...] | +| array_flow.rb:1011:10:1011:10 | b [element 2] | array_flow.rb:1011:10:1011:13 | ...[...] | +| array_flow.rb:1017:5:1017:5 | b [element 0] | array_flow.rb:1019:10:1019:10 | b [element 0] | +| array_flow.rb:1017:5:1017:5 | b [element 0] | array_flow.rb:1019:10:1019:10 | b [element 0] | +| array_flow.rb:1017:9:1017:9 | [post] a [element 0] | array_flow.rb:1018:10:1018:10 | a [element 0] | +| array_flow.rb:1017:9:1017:9 | [post] a [element 0] | array_flow.rb:1018:10:1018:10 | a [element 0] | +| array_flow.rb:1017:9:1017:33 | call to replace [element 0] | array_flow.rb:1017:5:1017:5 | b [element 0] | +| array_flow.rb:1017:9:1017:33 | call to replace [element 0] | array_flow.rb:1017:5:1017:5 | b [element 0] | +| array_flow.rb:1017:20:1017:31 | call to source | array_flow.rb:1017:9:1017:9 | [post] a [element 0] | +| array_flow.rb:1017:20:1017:31 | call to source | array_flow.rb:1017:9:1017:9 | [post] a [element 0] | +| array_flow.rb:1017:20:1017:31 | call to source | array_flow.rb:1017:9:1017:33 | call to replace [element 0] | +| array_flow.rb:1017:20:1017:31 | call to source | array_flow.rb:1017:9:1017:33 | call to replace [element 0] | +| array_flow.rb:1018:10:1018:10 | a [element 0] | array_flow.rb:1018:10:1018:13 | ...[...] | +| array_flow.rb:1018:10:1018:10 | a [element 0] | array_flow.rb:1018:10:1018:13 | ...[...] | +| array_flow.rb:1019:10:1019:10 | b [element 0] | array_flow.rb:1019:10:1019:13 | ...[...] | +| array_flow.rb:1019:10:1019:10 | b [element 0] | array_flow.rb:1019:10:1019:13 | ...[...] | | array_flow.rb:1023:5:1023:5 | a [element 2] | array_flow.rb:1024:9:1024:9 | a [element 2] | | array_flow.rb:1023:5:1023:5 | a [element 2] | array_flow.rb:1024:9:1024:9 | a [element 2] | | array_flow.rb:1023:5:1023:5 | a [element 2] | array_flow.rb:1029:10:1029:10 | a [element 2] | @@ -2306,290 +2280,246 @@ edges | array_flow.rb:1024:5:1024:5 | b [element] | array_flow.rb:1026:10:1026:10 | b [element] | | array_flow.rb:1024:5:1024:5 | b [element] | array_flow.rb:1027:10:1027:10 | b [element] | | array_flow.rb:1024:5:1024:5 | b [element] | array_flow.rb:1027:10:1027:10 | b [element] | -| array_flow.rb:1024:9:1024:9 | [post] a [element] | array_flow.rb:1028:10:1028:10 | a [element] | -| array_flow.rb:1024:9:1024:9 | [post] a [element] | array_flow.rb:1028:10:1028:10 | a [element] | -| array_flow.rb:1024:9:1024:9 | [post] a [element] | array_flow.rb:1029:10:1029:10 | a [element] | -| array_flow.rb:1024:9:1024:9 | [post] a [element] | array_flow.rb:1029:10:1029:10 | a [element] | -| array_flow.rb:1024:9:1024:9 | [post] a [element] | array_flow.rb:1030:10:1030:10 | a [element] | -| array_flow.rb:1024:9:1024:9 | [post] a [element] | array_flow.rb:1030:10:1030:10 | a [element] | -| array_flow.rb:1024:9:1024:9 | a [element 2] | array_flow.rb:1024:9:1024:9 | [post] a [element] | -| array_flow.rb:1024:9:1024:9 | a [element 2] | array_flow.rb:1024:9:1024:9 | [post] a [element] | -| array_flow.rb:1024:9:1024:9 | a [element 2] | array_flow.rb:1024:9:1024:18 | call to reverse! [element] | -| array_flow.rb:1024:9:1024:9 | a [element 2] | array_flow.rb:1024:9:1024:18 | call to reverse! [element] | -| array_flow.rb:1024:9:1024:9 | a [element 3] | array_flow.rb:1024:9:1024:9 | [post] a [element] | -| array_flow.rb:1024:9:1024:9 | a [element 3] | array_flow.rb:1024:9:1024:9 | [post] a [element] | -| array_flow.rb:1024:9:1024:9 | a [element 3] | array_flow.rb:1024:9:1024:18 | call to reverse! [element] | -| array_flow.rb:1024:9:1024:9 | a [element 3] | array_flow.rb:1024:9:1024:18 | call to reverse! [element] | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] | array_flow.rb:1024:5:1024:5 | b [element] | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] | array_flow.rb:1024:5:1024:5 | b [element] | +| array_flow.rb:1024:9:1024:9 | a [element 2] | array_flow.rb:1024:9:1024:17 | call to reverse [element] | +| array_flow.rb:1024:9:1024:9 | a [element 2] | array_flow.rb:1024:9:1024:17 | call to reverse [element] | +| array_flow.rb:1024:9:1024:9 | a [element 3] | array_flow.rb:1024:9:1024:17 | call to reverse [element] | +| array_flow.rb:1024:9:1024:9 | a [element 3] | array_flow.rb:1024:9:1024:17 | call to reverse [element] | +| array_flow.rb:1024:9:1024:17 | call to reverse [element] | array_flow.rb:1024:5:1024:5 | b [element] | +| array_flow.rb:1024:9:1024:17 | call to reverse [element] | array_flow.rb:1024:5:1024:5 | b [element] | | array_flow.rb:1025:10:1025:10 | b [element] | array_flow.rb:1025:10:1025:13 | ...[...] | | array_flow.rb:1025:10:1025:10 | b [element] | array_flow.rb:1025:10:1025:13 | ...[...] | | array_flow.rb:1026:10:1026:10 | b [element] | array_flow.rb:1026:10:1026:13 | ...[...] | | array_flow.rb:1026:10:1026:10 | b [element] | array_flow.rb:1026:10:1026:13 | ...[...] | | array_flow.rb:1027:10:1027:10 | b [element] | array_flow.rb:1027:10:1027:13 | ...[...] | | array_flow.rb:1027:10:1027:10 | b [element] | array_flow.rb:1027:10:1027:13 | ...[...] | -| array_flow.rb:1028:10:1028:10 | a [element] | array_flow.rb:1028:10:1028:13 | ...[...] | -| array_flow.rb:1028:10:1028:10 | a [element] | array_flow.rb:1028:10:1028:13 | ...[...] | | array_flow.rb:1029:10:1029:10 | a [element 2] | array_flow.rb:1029:10:1029:13 | ...[...] | | array_flow.rb:1029:10:1029:10 | a [element 2] | array_flow.rb:1029:10:1029:13 | ...[...] | -| array_flow.rb:1029:10:1029:10 | a [element] | array_flow.rb:1029:10:1029:13 | ...[...] | -| array_flow.rb:1029:10:1029:10 | a [element] | array_flow.rb:1029:10:1029:13 | ...[...] | | array_flow.rb:1030:10:1030:10 | a [element 3] | array_flow.rb:1030:10:1030:13 | ...[...] | | array_flow.rb:1030:10:1030:10 | a [element 3] | array_flow.rb:1030:10:1030:13 | ...[...] | -| array_flow.rb:1030:10:1030:10 | a [element] | array_flow.rb:1030:10:1030:13 | ...[...] | -| array_flow.rb:1030:10:1030:10 | a [element] | array_flow.rb:1030:10:1030:13 | ...[...] | | array_flow.rb:1034:5:1034:5 | a [element 2] | array_flow.rb:1035:9:1035:9 | a [element 2] | | array_flow.rb:1034:5:1034:5 | a [element 2] | array_flow.rb:1035:9:1035:9 | a [element 2] | -| array_flow.rb:1034:16:1034:26 | call to source | array_flow.rb:1034:5:1034:5 | a [element 2] | -| array_flow.rb:1034:16:1034:26 | call to source | array_flow.rb:1034:5:1034:5 | a [element 2] | -| array_flow.rb:1035:5:1035:5 | b [element 2] | array_flow.rb:1038:10:1038:10 | b [element 2] | -| array_flow.rb:1035:5:1035:5 | b [element 2] | array_flow.rb:1038:10:1038:10 | b [element 2] | -| array_flow.rb:1035:9:1035:9 | a [element 2] | array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] | -| array_flow.rb:1035:9:1035:9 | a [element 2] | array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] | -| array_flow.rb:1035:9:1035:9 | a [element 2] | array_flow.rb:1035:28:1035:28 | x | -| array_flow.rb:1035:9:1035:9 | a [element 2] | array_flow.rb:1035:28:1035:28 | x | -| array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] | array_flow.rb:1035:5:1035:5 | b [element 2] | -| array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] | array_flow.rb:1035:5:1035:5 | b [element 2] | -| array_flow.rb:1035:28:1035:28 | x | array_flow.rb:1036:14:1036:14 | x | -| array_flow.rb:1035:28:1035:28 | x | array_flow.rb:1036:14:1036:14 | x | -| array_flow.rb:1038:10:1038:10 | b [element 2] | array_flow.rb:1038:10:1038:13 | ...[...] | -| array_flow.rb:1038:10:1038:10 | b [element 2] | array_flow.rb:1038:10:1038:13 | ...[...] | -| array_flow.rb:1042:5:1042:5 | a [element 2] | array_flow.rb:1043:5:1043:5 | a [element 2] | -| array_flow.rb:1042:5:1042:5 | a [element 2] | array_flow.rb:1043:5:1043:5 | a [element 2] | -| array_flow.rb:1042:16:1042:26 | call to source | array_flow.rb:1042:5:1042:5 | a [element 2] | -| array_flow.rb:1042:16:1042:26 | call to source | array_flow.rb:1042:5:1042:5 | a [element 2] | -| array_flow.rb:1043:5:1043:5 | a [element 2] | array_flow.rb:1043:18:1043:18 | x | -| array_flow.rb:1043:5:1043:5 | a [element 2] | array_flow.rb:1043:18:1043:18 | x | -| array_flow.rb:1043:18:1043:18 | x | array_flow.rb:1044:14:1044:14 | x | -| array_flow.rb:1043:18:1043:18 | x | array_flow.rb:1044:14:1044:14 | x | -| array_flow.rb:1052:5:1052:5 | a [element 0] | array_flow.rb:1054:9:1054:9 | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 0] | array_flow.rb:1054:9:1054:9 | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 0] | array_flow.rb:1060:9:1060:9 | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 0] | array_flow.rb:1060:9:1060:9 | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 0] | array_flow.rb:1066:9:1066:9 | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 0] | array_flow.rb:1066:9:1066:9 | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 0] | array_flow.rb:1072:9:1072:9 | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 0] | array_flow.rb:1072:9:1072:9 | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | array_flow.rb:1054:9:1054:9 | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | array_flow.rb:1054:9:1054:9 | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | array_flow.rb:1060:9:1060:9 | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | array_flow.rb:1060:9:1060:9 | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | array_flow.rb:1066:9:1066:9 | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | array_flow.rb:1066:9:1066:9 | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | array_flow.rb:1072:9:1072:9 | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | array_flow.rb:1072:9:1072:9 | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | array_flow.rb:1054:9:1054:9 | a [element 3] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | array_flow.rb:1054:9:1054:9 | a [element 3] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | array_flow.rb:1060:9:1060:9 | a [element 3] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | array_flow.rb:1060:9:1060:9 | a [element 3] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | array_flow.rb:1066:9:1066:9 | a [element 3] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | array_flow.rb:1066:9:1066:9 | a [element 3] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | array_flow.rb:1072:9:1072:9 | a [element 3] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | array_flow.rb:1072:9:1072:9 | a [element 3] | -| array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1052:5:1052:5 | a [element 0] | -| array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1052:5:1052:5 | a [element 0] | -| array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1052:5:1052:5 | a [element 2] | -| array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1052:5:1052:5 | a [element 2] | -| array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1052:5:1052:5 | a [element 3] | -| array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1052:5:1052:5 | a [element 3] | -| array_flow.rb:1054:5:1054:5 | b [element 1] | array_flow.rb:1056:10:1056:10 | b [element 1] | -| array_flow.rb:1054:5:1054:5 | b [element 1] | array_flow.rb:1056:10:1056:10 | b [element 1] | -| array_flow.rb:1054:5:1054:5 | b [element 2] | array_flow.rb:1057:10:1057:10 | b [element 2] | -| array_flow.rb:1054:5:1054:5 | b [element 2] | array_flow.rb:1057:10:1057:10 | b [element 2] | -| array_flow.rb:1054:5:1054:5 | b [element] | array_flow.rb:1055:10:1055:10 | b [element] | -| array_flow.rb:1054:5:1054:5 | b [element] | array_flow.rb:1055:10:1055:10 | b [element] | -| array_flow.rb:1054:5:1054:5 | b [element] | array_flow.rb:1056:10:1056:10 | b [element] | -| array_flow.rb:1054:5:1054:5 | b [element] | array_flow.rb:1056:10:1056:10 | b [element] | -| array_flow.rb:1054:5:1054:5 | b [element] | array_flow.rb:1057:10:1057:10 | b [element] | -| array_flow.rb:1054:5:1054:5 | b [element] | array_flow.rb:1057:10:1057:10 | b [element] | -| array_flow.rb:1054:5:1054:5 | b [element] | array_flow.rb:1058:10:1058:10 | b [element] | -| array_flow.rb:1054:5:1054:5 | b [element] | array_flow.rb:1058:10:1058:10 | b [element] | -| array_flow.rb:1054:9:1054:9 | a [element 0] | array_flow.rb:1054:9:1054:16 | call to rotate [element] | -| array_flow.rb:1054:9:1054:9 | a [element 0] | array_flow.rb:1054:9:1054:16 | call to rotate [element] | -| array_flow.rb:1054:9:1054:9 | a [element 2] | array_flow.rb:1054:9:1054:16 | call to rotate [element 1] | -| array_flow.rb:1054:9:1054:9 | a [element 2] | array_flow.rb:1054:9:1054:16 | call to rotate [element 1] | -| array_flow.rb:1054:9:1054:9 | a [element 3] | array_flow.rb:1054:9:1054:16 | call to rotate [element 2] | -| array_flow.rb:1054:9:1054:9 | a [element 3] | array_flow.rb:1054:9:1054:16 | call to rotate [element 2] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 1] | array_flow.rb:1054:5:1054:5 | b [element 1] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 1] | array_flow.rb:1054:5:1054:5 | b [element 1] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 2] | array_flow.rb:1054:5:1054:5 | b [element 2] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 2] | array_flow.rb:1054:5:1054:5 | b [element 2] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] | array_flow.rb:1054:5:1054:5 | b [element] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] | array_flow.rb:1054:5:1054:5 | b [element] | -| array_flow.rb:1055:10:1055:10 | b [element] | array_flow.rb:1055:10:1055:13 | ...[...] | -| array_flow.rb:1055:10:1055:10 | b [element] | array_flow.rb:1055:10:1055:13 | ...[...] | -| array_flow.rb:1056:10:1056:10 | b [element 1] | array_flow.rb:1056:10:1056:13 | ...[...] | -| array_flow.rb:1056:10:1056:10 | b [element 1] | array_flow.rb:1056:10:1056:13 | ...[...] | -| array_flow.rb:1056:10:1056:10 | b [element] | array_flow.rb:1056:10:1056:13 | ...[...] | -| array_flow.rb:1056:10:1056:10 | b [element] | array_flow.rb:1056:10:1056:13 | ...[...] | -| array_flow.rb:1057:10:1057:10 | b [element 2] | array_flow.rb:1057:10:1057:13 | ...[...] | -| array_flow.rb:1057:10:1057:10 | b [element 2] | array_flow.rb:1057:10:1057:13 | ...[...] | -| array_flow.rb:1057:10:1057:10 | b [element] | array_flow.rb:1057:10:1057:13 | ...[...] | -| array_flow.rb:1057:10:1057:10 | b [element] | array_flow.rb:1057:10:1057:13 | ...[...] | -| array_flow.rb:1058:10:1058:10 | b [element] | array_flow.rb:1058:10:1058:13 | ...[...] | -| array_flow.rb:1058:10:1058:10 | b [element] | array_flow.rb:1058:10:1058:13 | ...[...] | -| array_flow.rb:1060:5:1060:5 | b [element 0] | array_flow.rb:1061:10:1061:10 | b [element 0] | -| array_flow.rb:1060:5:1060:5 | b [element 0] | array_flow.rb:1061:10:1061:10 | b [element 0] | -| array_flow.rb:1060:5:1060:5 | b [element 1] | array_flow.rb:1062:10:1062:10 | b [element 1] | -| array_flow.rb:1060:5:1060:5 | b [element 1] | array_flow.rb:1062:10:1062:10 | b [element 1] | -| array_flow.rb:1060:5:1060:5 | b [element] | array_flow.rb:1061:10:1061:10 | b [element] | -| array_flow.rb:1060:5:1060:5 | b [element] | array_flow.rb:1061:10:1061:10 | b [element] | -| array_flow.rb:1060:5:1060:5 | b [element] | array_flow.rb:1062:10:1062:10 | b [element] | -| array_flow.rb:1060:5:1060:5 | b [element] | array_flow.rb:1062:10:1062:10 | b [element] | -| array_flow.rb:1060:5:1060:5 | b [element] | array_flow.rb:1063:10:1063:10 | b [element] | -| array_flow.rb:1060:5:1060:5 | b [element] | array_flow.rb:1063:10:1063:10 | b [element] | -| array_flow.rb:1060:5:1060:5 | b [element] | array_flow.rb:1064:10:1064:10 | b [element] | -| array_flow.rb:1060:5:1060:5 | b [element] | array_flow.rb:1064:10:1064:10 | b [element] | -| array_flow.rb:1060:9:1060:9 | a [element 0] | array_flow.rb:1060:9:1060:19 | call to rotate [element] | -| array_flow.rb:1060:9:1060:9 | a [element 0] | array_flow.rb:1060:9:1060:19 | call to rotate [element] | -| array_flow.rb:1060:9:1060:9 | a [element 2] | array_flow.rb:1060:9:1060:19 | call to rotate [element 0] | -| array_flow.rb:1060:9:1060:9 | a [element 2] | array_flow.rb:1060:9:1060:19 | call to rotate [element 0] | -| array_flow.rb:1060:9:1060:9 | a [element 3] | array_flow.rb:1060:9:1060:19 | call to rotate [element 1] | -| array_flow.rb:1060:9:1060:9 | a [element 3] | array_flow.rb:1060:9:1060:19 | call to rotate [element 1] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 0] | array_flow.rb:1060:5:1060:5 | b [element 0] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 0] | array_flow.rb:1060:5:1060:5 | b [element 0] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 1] | array_flow.rb:1060:5:1060:5 | b [element 1] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 1] | array_flow.rb:1060:5:1060:5 | b [element 1] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] | array_flow.rb:1060:5:1060:5 | b [element] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] | array_flow.rb:1060:5:1060:5 | b [element] | -| array_flow.rb:1061:10:1061:10 | b [element 0] | array_flow.rb:1061:10:1061:13 | ...[...] | -| array_flow.rb:1061:10:1061:10 | b [element 0] | array_flow.rb:1061:10:1061:13 | ...[...] | -| array_flow.rb:1061:10:1061:10 | b [element] | array_flow.rb:1061:10:1061:13 | ...[...] | -| array_flow.rb:1061:10:1061:10 | b [element] | array_flow.rb:1061:10:1061:13 | ...[...] | -| array_flow.rb:1062:10:1062:10 | b [element 1] | array_flow.rb:1062:10:1062:13 | ...[...] | -| array_flow.rb:1062:10:1062:10 | b [element 1] | array_flow.rb:1062:10:1062:13 | ...[...] | -| array_flow.rb:1062:10:1062:10 | b [element] | array_flow.rb:1062:10:1062:13 | ...[...] | -| array_flow.rb:1062:10:1062:10 | b [element] | array_flow.rb:1062:10:1062:13 | ...[...] | -| array_flow.rb:1063:10:1063:10 | b [element] | array_flow.rb:1063:10:1063:13 | ...[...] | -| array_flow.rb:1063:10:1063:10 | b [element] | array_flow.rb:1063:10:1063:13 | ...[...] | -| array_flow.rb:1064:10:1064:10 | b [element] | array_flow.rb:1064:10:1064:13 | ...[...] | -| array_flow.rb:1064:10:1064:10 | b [element] | array_flow.rb:1064:10:1064:13 | ...[...] | -| array_flow.rb:1066:5:1066:5 | b [element 0] | array_flow.rb:1067:10:1067:10 | b [element 0] | -| array_flow.rb:1066:5:1066:5 | b [element 0] | array_flow.rb:1067:10:1067:10 | b [element 0] | -| array_flow.rb:1066:5:1066:5 | b [element 2] | array_flow.rb:1069:10:1069:10 | b [element 2] | -| array_flow.rb:1066:5:1066:5 | b [element 2] | array_flow.rb:1069:10:1069:10 | b [element 2] | -| array_flow.rb:1066:5:1066:5 | b [element 3] | array_flow.rb:1070:10:1070:10 | b [element 3] | -| array_flow.rb:1066:5:1066:5 | b [element 3] | array_flow.rb:1070:10:1070:10 | b [element 3] | -| array_flow.rb:1066:9:1066:9 | a [element 0] | array_flow.rb:1066:9:1066:19 | call to rotate [element 0] | -| array_flow.rb:1066:9:1066:9 | a [element 0] | array_flow.rb:1066:9:1066:19 | call to rotate [element 0] | -| array_flow.rb:1066:9:1066:9 | a [element 2] | array_flow.rb:1066:9:1066:19 | call to rotate [element 2] | -| array_flow.rb:1066:9:1066:9 | a [element 2] | array_flow.rb:1066:9:1066:19 | call to rotate [element 2] | -| array_flow.rb:1066:9:1066:9 | a [element 3] | array_flow.rb:1066:9:1066:19 | call to rotate [element 3] | -| array_flow.rb:1066:9:1066:9 | a [element 3] | array_flow.rb:1066:9:1066:19 | call to rotate [element 3] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 0] | array_flow.rb:1066:5:1066:5 | b [element 0] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 0] | array_flow.rb:1066:5:1066:5 | b [element 0] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 2] | array_flow.rb:1066:5:1066:5 | b [element 2] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 2] | array_flow.rb:1066:5:1066:5 | b [element 2] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 3] | array_flow.rb:1066:5:1066:5 | b [element 3] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 3] | array_flow.rb:1066:5:1066:5 | b [element 3] | -| array_flow.rb:1067:10:1067:10 | b [element 0] | array_flow.rb:1067:10:1067:13 | ...[...] | -| array_flow.rb:1067:10:1067:10 | b [element 0] | array_flow.rb:1067:10:1067:13 | ...[...] | -| array_flow.rb:1069:10:1069:10 | b [element 2] | array_flow.rb:1069:10:1069:13 | ...[...] | -| array_flow.rb:1069:10:1069:10 | b [element 2] | array_flow.rb:1069:10:1069:13 | ...[...] | -| array_flow.rb:1070:10:1070:10 | b [element 3] | array_flow.rb:1070:10:1070:13 | ...[...] | -| array_flow.rb:1070:10:1070:10 | b [element 3] | array_flow.rb:1070:10:1070:13 | ...[...] | -| array_flow.rb:1072:5:1072:5 | b [element] | array_flow.rb:1073:10:1073:10 | b [element] | -| array_flow.rb:1072:5:1072:5 | b [element] | array_flow.rb:1073:10:1073:10 | b [element] | -| array_flow.rb:1072:5:1072:5 | b [element] | array_flow.rb:1074:10:1074:10 | b [element] | -| array_flow.rb:1072:5:1072:5 | b [element] | array_flow.rb:1074:10:1074:10 | b [element] | -| array_flow.rb:1072:5:1072:5 | b [element] | array_flow.rb:1075:10:1075:10 | b [element] | -| array_flow.rb:1072:5:1072:5 | b [element] | array_flow.rb:1075:10:1075:10 | b [element] | -| array_flow.rb:1072:5:1072:5 | b [element] | array_flow.rb:1076:10:1076:10 | b [element] | -| array_flow.rb:1072:5:1072:5 | b [element] | array_flow.rb:1076:10:1076:10 | b [element] | -| array_flow.rb:1072:9:1072:9 | a [element 0] | array_flow.rb:1072:9:1072:19 | call to rotate [element] | -| array_flow.rb:1072:9:1072:9 | a [element 0] | array_flow.rb:1072:9:1072:19 | call to rotate [element] | -| array_flow.rb:1072:9:1072:9 | a [element 2] | array_flow.rb:1072:9:1072:19 | call to rotate [element] | -| array_flow.rb:1072:9:1072:9 | a [element 2] | array_flow.rb:1072:9:1072:19 | call to rotate [element] | -| array_flow.rb:1072:9:1072:9 | a [element 3] | array_flow.rb:1072:9:1072:19 | call to rotate [element] | -| array_flow.rb:1072:9:1072:9 | a [element 3] | array_flow.rb:1072:9:1072:19 | call to rotate [element] | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] | array_flow.rb:1072:5:1072:5 | b [element] | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] | array_flow.rb:1072:5:1072:5 | b [element] | +| array_flow.rb:1034:5:1034:5 | a [element 2] | array_flow.rb:1040:10:1040:10 | a [element 2] | +| array_flow.rb:1034:5:1034:5 | a [element 2] | array_flow.rb:1040:10:1040:10 | a [element 2] | +| array_flow.rb:1034:5:1034:5 | a [element 3] | array_flow.rb:1035:9:1035:9 | a [element 3] | +| array_flow.rb:1034:5:1034:5 | a [element 3] | array_flow.rb:1035:9:1035:9 | a [element 3] | +| array_flow.rb:1034:5:1034:5 | a [element 3] | array_flow.rb:1041:10:1041:10 | a [element 3] | +| array_flow.rb:1034:5:1034:5 | a [element 3] | array_flow.rb:1041:10:1041:10 | a [element 3] | +| array_flow.rb:1034:16:1034:28 | call to source | array_flow.rb:1034:5:1034:5 | a [element 2] | +| array_flow.rb:1034:16:1034:28 | call to source | array_flow.rb:1034:5:1034:5 | a [element 2] | +| array_flow.rb:1034:31:1034:43 | call to source | array_flow.rb:1034:5:1034:5 | a [element 3] | +| array_flow.rb:1034:31:1034:43 | call to source | array_flow.rb:1034:5:1034:5 | a [element 3] | +| array_flow.rb:1035:5:1035:5 | b [element] | array_flow.rb:1036:10:1036:10 | b [element] | +| array_flow.rb:1035:5:1035:5 | b [element] | array_flow.rb:1036:10:1036:10 | b [element] | +| array_flow.rb:1035:5:1035:5 | b [element] | array_flow.rb:1037:10:1037:10 | b [element] | +| array_flow.rb:1035:5:1035:5 | b [element] | array_flow.rb:1037:10:1037:10 | b [element] | +| array_flow.rb:1035:5:1035:5 | b [element] | array_flow.rb:1038:10:1038:10 | b [element] | +| array_flow.rb:1035:5:1035:5 | b [element] | array_flow.rb:1038:10:1038:10 | b [element] | +| array_flow.rb:1035:9:1035:9 | [post] a [element] | array_flow.rb:1039:10:1039:10 | a [element] | +| array_flow.rb:1035:9:1035:9 | [post] a [element] | array_flow.rb:1039:10:1039:10 | a [element] | +| array_flow.rb:1035:9:1035:9 | [post] a [element] | array_flow.rb:1040:10:1040:10 | a [element] | +| array_flow.rb:1035:9:1035:9 | [post] a [element] | array_flow.rb:1040:10:1040:10 | a [element] | +| array_flow.rb:1035:9:1035:9 | [post] a [element] | array_flow.rb:1041:10:1041:10 | a [element] | +| array_flow.rb:1035:9:1035:9 | [post] a [element] | array_flow.rb:1041:10:1041:10 | a [element] | +| array_flow.rb:1035:9:1035:9 | a [element 2] | array_flow.rb:1035:9:1035:9 | [post] a [element] | +| array_flow.rb:1035:9:1035:9 | a [element 2] | array_flow.rb:1035:9:1035:9 | [post] a [element] | +| array_flow.rb:1035:9:1035:9 | a [element 2] | array_flow.rb:1035:9:1035:18 | call to reverse! [element] | +| array_flow.rb:1035:9:1035:9 | a [element 2] | array_flow.rb:1035:9:1035:18 | call to reverse! [element] | +| array_flow.rb:1035:9:1035:9 | a [element 3] | array_flow.rb:1035:9:1035:9 | [post] a [element] | +| array_flow.rb:1035:9:1035:9 | a [element 3] | array_flow.rb:1035:9:1035:9 | [post] a [element] | +| array_flow.rb:1035:9:1035:9 | a [element 3] | array_flow.rb:1035:9:1035:18 | call to reverse! [element] | +| array_flow.rb:1035:9:1035:9 | a [element 3] | array_flow.rb:1035:9:1035:18 | call to reverse! [element] | +| array_flow.rb:1035:9:1035:18 | call to reverse! [element] | array_flow.rb:1035:5:1035:5 | b [element] | +| array_flow.rb:1035:9:1035:18 | call to reverse! [element] | array_flow.rb:1035:5:1035:5 | b [element] | +| array_flow.rb:1036:10:1036:10 | b [element] | array_flow.rb:1036:10:1036:13 | ...[...] | +| array_flow.rb:1036:10:1036:10 | b [element] | array_flow.rb:1036:10:1036:13 | ...[...] | +| array_flow.rb:1037:10:1037:10 | b [element] | array_flow.rb:1037:10:1037:13 | ...[...] | +| array_flow.rb:1037:10:1037:10 | b [element] | array_flow.rb:1037:10:1037:13 | ...[...] | +| array_flow.rb:1038:10:1038:10 | b [element] | array_flow.rb:1038:10:1038:13 | ...[...] | +| array_flow.rb:1038:10:1038:10 | b [element] | array_flow.rb:1038:10:1038:13 | ...[...] | +| array_flow.rb:1039:10:1039:10 | a [element] | array_flow.rb:1039:10:1039:13 | ...[...] | +| array_flow.rb:1039:10:1039:10 | a [element] | array_flow.rb:1039:10:1039:13 | ...[...] | +| array_flow.rb:1040:10:1040:10 | a [element 2] | array_flow.rb:1040:10:1040:13 | ...[...] | +| array_flow.rb:1040:10:1040:10 | a [element 2] | array_flow.rb:1040:10:1040:13 | ...[...] | +| array_flow.rb:1040:10:1040:10 | a [element] | array_flow.rb:1040:10:1040:13 | ...[...] | +| array_flow.rb:1040:10:1040:10 | a [element] | array_flow.rb:1040:10:1040:13 | ...[...] | +| array_flow.rb:1041:10:1041:10 | a [element 3] | array_flow.rb:1041:10:1041:13 | ...[...] | +| array_flow.rb:1041:10:1041:10 | a [element 3] | array_flow.rb:1041:10:1041:13 | ...[...] | +| array_flow.rb:1041:10:1041:10 | a [element] | array_flow.rb:1041:10:1041:13 | ...[...] | +| array_flow.rb:1041:10:1041:10 | a [element] | array_flow.rb:1041:10:1041:13 | ...[...] | +| array_flow.rb:1045:5:1045:5 | a [element 2] | array_flow.rb:1046:9:1046:9 | a [element 2] | +| array_flow.rb:1045:5:1045:5 | a [element 2] | array_flow.rb:1046:9:1046:9 | a [element 2] | +| array_flow.rb:1045:16:1045:26 | call to source | array_flow.rb:1045:5:1045:5 | a [element 2] | +| array_flow.rb:1045:16:1045:26 | call to source | array_flow.rb:1045:5:1045:5 | a [element 2] | +| array_flow.rb:1046:5:1046:5 | b [element 2] | array_flow.rb:1049:10:1049:10 | b [element 2] | +| array_flow.rb:1046:5:1046:5 | b [element 2] | array_flow.rb:1049:10:1049:10 | b [element 2] | +| array_flow.rb:1046:9:1046:9 | a [element 2] | array_flow.rb:1046:9:1048:7 | call to reverse_each [element 2] | +| array_flow.rb:1046:9:1046:9 | a [element 2] | array_flow.rb:1046:9:1048:7 | call to reverse_each [element 2] | +| array_flow.rb:1046:9:1046:9 | a [element 2] | array_flow.rb:1046:28:1046:28 | x | +| array_flow.rb:1046:9:1046:9 | a [element 2] | array_flow.rb:1046:28:1046:28 | x | +| array_flow.rb:1046:9:1048:7 | call to reverse_each [element 2] | array_flow.rb:1046:5:1046:5 | b [element 2] | +| array_flow.rb:1046:9:1048:7 | call to reverse_each [element 2] | array_flow.rb:1046:5:1046:5 | b [element 2] | +| array_flow.rb:1046:28:1046:28 | x | array_flow.rb:1047:14:1047:14 | x | +| array_flow.rb:1046:28:1046:28 | x | array_flow.rb:1047:14:1047:14 | x | +| array_flow.rb:1049:10:1049:10 | b [element 2] | array_flow.rb:1049:10:1049:13 | ...[...] | +| array_flow.rb:1049:10:1049:10 | b [element 2] | array_flow.rb:1049:10:1049:13 | ...[...] | +| array_flow.rb:1053:5:1053:5 | a [element 2] | array_flow.rb:1054:5:1054:5 | a [element 2] | +| array_flow.rb:1053:5:1053:5 | a [element 2] | array_flow.rb:1054:5:1054:5 | a [element 2] | +| array_flow.rb:1053:16:1053:26 | call to source | array_flow.rb:1053:5:1053:5 | a [element 2] | +| array_flow.rb:1053:16:1053:26 | call to source | array_flow.rb:1053:5:1053:5 | a [element 2] | +| array_flow.rb:1054:5:1054:5 | a [element 2] | array_flow.rb:1054:18:1054:18 | x | +| array_flow.rb:1054:5:1054:5 | a [element 2] | array_flow.rb:1054:18:1054:18 | x | +| array_flow.rb:1054:18:1054:18 | x | array_flow.rb:1055:14:1055:14 | x | +| array_flow.rb:1054:18:1054:18 | x | array_flow.rb:1055:14:1055:14 | x | +| array_flow.rb:1063:5:1063:5 | a [element 0] | array_flow.rb:1065:9:1065:9 | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 0] | array_flow.rb:1065:9:1065:9 | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 0] | array_flow.rb:1071:9:1071:9 | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 0] | array_flow.rb:1071:9:1071:9 | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 0] | array_flow.rb:1077:9:1077:9 | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 0] | array_flow.rb:1077:9:1077:9 | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 0] | array_flow.rb:1083:9:1083:9 | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 0] | array_flow.rb:1083:9:1083:9 | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | array_flow.rb:1065:9:1065:9 | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | array_flow.rb:1065:9:1065:9 | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | array_flow.rb:1071:9:1071:9 | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | array_flow.rb:1071:9:1071:9 | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | array_flow.rb:1077:9:1077:9 | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | array_flow.rb:1077:9:1077:9 | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | array_flow.rb:1083:9:1083:9 | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | array_flow.rb:1083:9:1083:9 | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | array_flow.rb:1065:9:1065:9 | a [element 3] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | array_flow.rb:1065:9:1065:9 | a [element 3] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | array_flow.rb:1071:9:1071:9 | a [element 3] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | array_flow.rb:1071:9:1071:9 | a [element 3] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | array_flow.rb:1077:9:1077:9 | a [element 3] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | array_flow.rb:1077:9:1077:9 | a [element 3] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | array_flow.rb:1083:9:1083:9 | a [element 3] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | array_flow.rb:1083:9:1083:9 | a [element 3] | +| array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1063:5:1063:5 | a [element 0] | +| array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1063:5:1063:5 | a [element 0] | +| array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1063:5:1063:5 | a [element 2] | +| array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1063:5:1063:5 | a [element 2] | +| array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1063:5:1063:5 | a [element 3] | +| array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1063:5:1063:5 | a [element 3] | +| array_flow.rb:1065:5:1065:5 | b [element 1] | array_flow.rb:1067:10:1067:10 | b [element 1] | +| array_flow.rb:1065:5:1065:5 | b [element 1] | array_flow.rb:1067:10:1067:10 | b [element 1] | +| array_flow.rb:1065:5:1065:5 | b [element 2] | array_flow.rb:1068:10:1068:10 | b [element 2] | +| array_flow.rb:1065:5:1065:5 | b [element 2] | array_flow.rb:1068:10:1068:10 | b [element 2] | +| array_flow.rb:1065:5:1065:5 | b [element] | array_flow.rb:1066:10:1066:10 | b [element] | +| array_flow.rb:1065:5:1065:5 | b [element] | array_flow.rb:1066:10:1066:10 | b [element] | +| array_flow.rb:1065:5:1065:5 | b [element] | array_flow.rb:1067:10:1067:10 | b [element] | +| array_flow.rb:1065:5:1065:5 | b [element] | array_flow.rb:1067:10:1067:10 | b [element] | +| array_flow.rb:1065:5:1065:5 | b [element] | array_flow.rb:1068:10:1068:10 | b [element] | +| array_flow.rb:1065:5:1065:5 | b [element] | array_flow.rb:1068:10:1068:10 | b [element] | +| array_flow.rb:1065:5:1065:5 | b [element] | array_flow.rb:1069:10:1069:10 | b [element] | +| array_flow.rb:1065:5:1065:5 | b [element] | array_flow.rb:1069:10:1069:10 | b [element] | +| array_flow.rb:1065:9:1065:9 | a [element 0] | array_flow.rb:1065:9:1065:16 | call to rotate [element] | +| array_flow.rb:1065:9:1065:9 | a [element 0] | array_flow.rb:1065:9:1065:16 | call to rotate [element] | +| array_flow.rb:1065:9:1065:9 | a [element 2] | array_flow.rb:1065:9:1065:16 | call to rotate [element 1] | +| array_flow.rb:1065:9:1065:9 | a [element 2] | array_flow.rb:1065:9:1065:16 | call to rotate [element 1] | +| array_flow.rb:1065:9:1065:9 | a [element 3] | array_flow.rb:1065:9:1065:16 | call to rotate [element 2] | +| array_flow.rb:1065:9:1065:9 | a [element 3] | array_flow.rb:1065:9:1065:16 | call to rotate [element 2] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element 1] | array_flow.rb:1065:5:1065:5 | b [element 1] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element 1] | array_flow.rb:1065:5:1065:5 | b [element 1] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element 2] | array_flow.rb:1065:5:1065:5 | b [element 2] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element 2] | array_flow.rb:1065:5:1065:5 | b [element 2] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element] | array_flow.rb:1065:5:1065:5 | b [element] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element] | array_flow.rb:1065:5:1065:5 | b [element] | +| array_flow.rb:1066:10:1066:10 | b [element] | array_flow.rb:1066:10:1066:13 | ...[...] | +| array_flow.rb:1066:10:1066:10 | b [element] | array_flow.rb:1066:10:1066:13 | ...[...] | +| array_flow.rb:1067:10:1067:10 | b [element 1] | array_flow.rb:1067:10:1067:13 | ...[...] | +| array_flow.rb:1067:10:1067:10 | b [element 1] | array_flow.rb:1067:10:1067:13 | ...[...] | +| array_flow.rb:1067:10:1067:10 | b [element] | array_flow.rb:1067:10:1067:13 | ...[...] | +| array_flow.rb:1067:10:1067:10 | b [element] | array_flow.rb:1067:10:1067:13 | ...[...] | +| array_flow.rb:1068:10:1068:10 | b [element 2] | array_flow.rb:1068:10:1068:13 | ...[...] | +| array_flow.rb:1068:10:1068:10 | b [element 2] | array_flow.rb:1068:10:1068:13 | ...[...] | +| array_flow.rb:1068:10:1068:10 | b [element] | array_flow.rb:1068:10:1068:13 | ...[...] | +| array_flow.rb:1068:10:1068:10 | b [element] | array_flow.rb:1068:10:1068:13 | ...[...] | +| array_flow.rb:1069:10:1069:10 | b [element] | array_flow.rb:1069:10:1069:13 | ...[...] | +| array_flow.rb:1069:10:1069:10 | b [element] | array_flow.rb:1069:10:1069:13 | ...[...] | +| array_flow.rb:1071:5:1071:5 | b [element 0] | array_flow.rb:1072:10:1072:10 | b [element 0] | +| array_flow.rb:1071:5:1071:5 | b [element 0] | array_flow.rb:1072:10:1072:10 | b [element 0] | +| array_flow.rb:1071:5:1071:5 | b [element 1] | array_flow.rb:1073:10:1073:10 | b [element 1] | +| array_flow.rb:1071:5:1071:5 | b [element 1] | array_flow.rb:1073:10:1073:10 | b [element 1] | +| array_flow.rb:1071:5:1071:5 | b [element] | array_flow.rb:1072:10:1072:10 | b [element] | +| array_flow.rb:1071:5:1071:5 | b [element] | array_flow.rb:1072:10:1072:10 | b [element] | +| array_flow.rb:1071:5:1071:5 | b [element] | array_flow.rb:1073:10:1073:10 | b [element] | +| array_flow.rb:1071:5:1071:5 | b [element] | array_flow.rb:1073:10:1073:10 | b [element] | +| array_flow.rb:1071:5:1071:5 | b [element] | array_flow.rb:1074:10:1074:10 | b [element] | +| array_flow.rb:1071:5:1071:5 | b [element] | array_flow.rb:1074:10:1074:10 | b [element] | +| array_flow.rb:1071:5:1071:5 | b [element] | array_flow.rb:1075:10:1075:10 | b [element] | +| array_flow.rb:1071:5:1071:5 | b [element] | array_flow.rb:1075:10:1075:10 | b [element] | +| array_flow.rb:1071:9:1071:9 | a [element 0] | array_flow.rb:1071:9:1071:19 | call to rotate [element] | +| array_flow.rb:1071:9:1071:9 | a [element 0] | array_flow.rb:1071:9:1071:19 | call to rotate [element] | +| array_flow.rb:1071:9:1071:9 | a [element 2] | array_flow.rb:1071:9:1071:19 | call to rotate [element 0] | +| array_flow.rb:1071:9:1071:9 | a [element 2] | array_flow.rb:1071:9:1071:19 | call to rotate [element 0] | +| array_flow.rb:1071:9:1071:9 | a [element 3] | array_flow.rb:1071:9:1071:19 | call to rotate [element 1] | +| array_flow.rb:1071:9:1071:9 | a [element 3] | array_flow.rb:1071:9:1071:19 | call to rotate [element 1] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element 0] | array_flow.rb:1071:5:1071:5 | b [element 0] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element 0] | array_flow.rb:1071:5:1071:5 | b [element 0] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element 1] | array_flow.rb:1071:5:1071:5 | b [element 1] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element 1] | array_flow.rb:1071:5:1071:5 | b [element 1] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element] | array_flow.rb:1071:5:1071:5 | b [element] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element] | array_flow.rb:1071:5:1071:5 | b [element] | +| array_flow.rb:1072:10:1072:10 | b [element 0] | array_flow.rb:1072:10:1072:13 | ...[...] | +| array_flow.rb:1072:10:1072:10 | b [element 0] | array_flow.rb:1072:10:1072:13 | ...[...] | +| array_flow.rb:1072:10:1072:10 | b [element] | array_flow.rb:1072:10:1072:13 | ...[...] | +| array_flow.rb:1072:10:1072:10 | b [element] | array_flow.rb:1072:10:1072:13 | ...[...] | +| array_flow.rb:1073:10:1073:10 | b [element 1] | array_flow.rb:1073:10:1073:13 | ...[...] | +| array_flow.rb:1073:10:1073:10 | b [element 1] | array_flow.rb:1073:10:1073:13 | ...[...] | | array_flow.rb:1073:10:1073:10 | b [element] | array_flow.rb:1073:10:1073:13 | ...[...] | | array_flow.rb:1073:10:1073:10 | b [element] | array_flow.rb:1073:10:1073:13 | ...[...] | | array_flow.rb:1074:10:1074:10 | b [element] | array_flow.rb:1074:10:1074:13 | ...[...] | | array_flow.rb:1074:10:1074:10 | b [element] | array_flow.rb:1074:10:1074:13 | ...[...] | | array_flow.rb:1075:10:1075:10 | b [element] | array_flow.rb:1075:10:1075:13 | ...[...] | | array_flow.rb:1075:10:1075:10 | b [element] | array_flow.rb:1075:10:1075:13 | ...[...] | -| array_flow.rb:1076:10:1076:10 | b [element] | array_flow.rb:1076:10:1076:13 | ...[...] | -| array_flow.rb:1076:10:1076:10 | b [element] | array_flow.rb:1076:10:1076:13 | ...[...] | -| array_flow.rb:1084:5:1084:5 | a [element 0] | array_flow.rb:1085:9:1085:9 | a [element 0] | -| array_flow.rb:1084:5:1084:5 | a [element 0] | array_flow.rb:1085:9:1085:9 | a [element 0] | -| array_flow.rb:1084:5:1084:5 | a [element 2] | array_flow.rb:1085:9:1085:9 | a [element 2] | -| array_flow.rb:1084:5:1084:5 | a [element 2] | array_flow.rb:1085:9:1085:9 | a [element 2] | -| array_flow.rb:1084:5:1084:5 | a [element 3] | array_flow.rb:1085:9:1085:9 | a [element 3] | -| array_flow.rb:1084:5:1084:5 | a [element 3] | array_flow.rb:1085:9:1085:9 | a [element 3] | -| array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1084:5:1084:5 | a [element 0] | -| array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1084:5:1084:5 | a [element 0] | -| array_flow.rb:1084:28:1084:40 | call to source | array_flow.rb:1084:5:1084:5 | a [element 2] | -| array_flow.rb:1084:28:1084:40 | call to source | array_flow.rb:1084:5:1084:5 | a [element 2] | -| array_flow.rb:1084:43:1084:55 | call to source | array_flow.rb:1084:5:1084:5 | a [element 3] | -| array_flow.rb:1084:43:1084:55 | call to source | array_flow.rb:1084:5:1084:5 | a [element 3] | -| array_flow.rb:1085:5:1085:5 | b [element 1] | array_flow.rb:1091:10:1091:10 | b [element 1] | -| array_flow.rb:1085:5:1085:5 | b [element 1] | array_flow.rb:1091:10:1091:10 | b [element 1] | -| array_flow.rb:1085:5:1085:5 | b [element 2] | array_flow.rb:1092:10:1092:10 | b [element 2] | -| array_flow.rb:1085:5:1085:5 | b [element 2] | array_flow.rb:1092:10:1092:10 | b [element 2] | -| array_flow.rb:1085:5:1085:5 | b [element] | array_flow.rb:1090:10:1090:10 | b [element] | -| array_flow.rb:1085:5:1085:5 | b [element] | array_flow.rb:1090:10:1090:10 | b [element] | -| array_flow.rb:1085:5:1085:5 | b [element] | array_flow.rb:1091:10:1091:10 | b [element] | -| array_flow.rb:1085:5:1085:5 | b [element] | array_flow.rb:1091:10:1091:10 | b [element] | -| array_flow.rb:1085:5:1085:5 | b [element] | array_flow.rb:1092:10:1092:10 | b [element] | -| array_flow.rb:1085:5:1085:5 | b [element] | array_flow.rb:1092:10:1092:10 | b [element] | -| array_flow.rb:1085:5:1085:5 | b [element] | array_flow.rb:1093:10:1093:10 | b [element] | -| array_flow.rb:1085:5:1085:5 | b [element] | array_flow.rb:1093:10:1093:10 | b [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element 1] | array_flow.rb:1087:10:1087:10 | a [element 1] | -| array_flow.rb:1085:9:1085:9 | [post] a [element 1] | array_flow.rb:1087:10:1087:10 | a [element 1] | -| array_flow.rb:1085:9:1085:9 | [post] a [element 2] | array_flow.rb:1088:10:1088:10 | a [element 2] | -| array_flow.rb:1085:9:1085:9 | [post] a [element 2] | array_flow.rb:1088:10:1088:10 | a [element 2] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | array_flow.rb:1086:10:1086:10 | a [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | array_flow.rb:1086:10:1086:10 | a [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | array_flow.rb:1087:10:1087:10 | a [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | array_flow.rb:1087:10:1087:10 | a [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | array_flow.rb:1088:10:1088:10 | a [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | array_flow.rb:1088:10:1088:10 | a [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | array_flow.rb:1089:10:1089:10 | a [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | array_flow.rb:1089:10:1089:10 | a [element] | -| array_flow.rb:1085:9:1085:9 | a [element 0] | array_flow.rb:1085:9:1085:9 | [post] a [element] | -| array_flow.rb:1085:9:1085:9 | a [element 0] | array_flow.rb:1085:9:1085:9 | [post] a [element] | -| array_flow.rb:1085:9:1085:9 | a [element 0] | array_flow.rb:1085:9:1085:17 | call to rotate! [element] | -| array_flow.rb:1085:9:1085:9 | a [element 0] | array_flow.rb:1085:9:1085:17 | call to rotate! [element] | -| array_flow.rb:1085:9:1085:9 | a [element 2] | array_flow.rb:1085:9:1085:9 | [post] a [element 1] | -| array_flow.rb:1085:9:1085:9 | a [element 2] | array_flow.rb:1085:9:1085:9 | [post] a [element 1] | -| array_flow.rb:1085:9:1085:9 | a [element 2] | array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] | -| array_flow.rb:1085:9:1085:9 | a [element 2] | array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] | -| array_flow.rb:1085:9:1085:9 | a [element 3] | array_flow.rb:1085:9:1085:9 | [post] a [element 2] | -| array_flow.rb:1085:9:1085:9 | a [element 3] | array_flow.rb:1085:9:1085:9 | [post] a [element 2] | -| array_flow.rb:1085:9:1085:9 | a [element 3] | array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] | -| array_flow.rb:1085:9:1085:9 | a [element 3] | array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] | array_flow.rb:1085:5:1085:5 | b [element 1] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] | array_flow.rb:1085:5:1085:5 | b [element 1] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] | array_flow.rb:1085:5:1085:5 | b [element 2] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] | array_flow.rb:1085:5:1085:5 | b [element 2] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] | array_flow.rb:1085:5:1085:5 | b [element] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] | array_flow.rb:1085:5:1085:5 | b [element] | -| array_flow.rb:1086:10:1086:10 | a [element] | array_flow.rb:1086:10:1086:13 | ...[...] | -| array_flow.rb:1086:10:1086:10 | a [element] | array_flow.rb:1086:10:1086:13 | ...[...] | -| array_flow.rb:1087:10:1087:10 | a [element 1] | array_flow.rb:1087:10:1087:13 | ...[...] | -| array_flow.rb:1087:10:1087:10 | a [element 1] | array_flow.rb:1087:10:1087:13 | ...[...] | -| array_flow.rb:1087:10:1087:10 | a [element] | array_flow.rb:1087:10:1087:13 | ...[...] | -| array_flow.rb:1087:10:1087:10 | a [element] | array_flow.rb:1087:10:1087:13 | ...[...] | -| array_flow.rb:1088:10:1088:10 | a [element 2] | array_flow.rb:1088:10:1088:13 | ...[...] | -| array_flow.rb:1088:10:1088:10 | a [element 2] | array_flow.rb:1088:10:1088:13 | ...[...] | -| array_flow.rb:1088:10:1088:10 | a [element] | array_flow.rb:1088:10:1088:13 | ...[...] | -| array_flow.rb:1088:10:1088:10 | a [element] | array_flow.rb:1088:10:1088:13 | ...[...] | -| array_flow.rb:1089:10:1089:10 | a [element] | array_flow.rb:1089:10:1089:13 | ...[...] | -| array_flow.rb:1089:10:1089:10 | a [element] | array_flow.rb:1089:10:1089:13 | ...[...] | -| array_flow.rb:1090:10:1090:10 | b [element] | array_flow.rb:1090:10:1090:13 | ...[...] | -| array_flow.rb:1090:10:1090:10 | b [element] | array_flow.rb:1090:10:1090:13 | ...[...] | -| array_flow.rb:1091:10:1091:10 | b [element 1] | array_flow.rb:1091:10:1091:13 | ...[...] | -| array_flow.rb:1091:10:1091:10 | b [element 1] | array_flow.rb:1091:10:1091:13 | ...[...] | -| array_flow.rb:1091:10:1091:10 | b [element] | array_flow.rb:1091:10:1091:13 | ...[...] | -| array_flow.rb:1091:10:1091:10 | b [element] | array_flow.rb:1091:10:1091:13 | ...[...] | -| array_flow.rb:1092:10:1092:10 | b [element 2] | array_flow.rb:1092:10:1092:13 | ...[...] | -| array_flow.rb:1092:10:1092:10 | b [element 2] | array_flow.rb:1092:10:1092:13 | ...[...] | -| array_flow.rb:1092:10:1092:10 | b [element] | array_flow.rb:1092:10:1092:13 | ...[...] | -| array_flow.rb:1092:10:1092:10 | b [element] | array_flow.rb:1092:10:1092:13 | ...[...] | -| array_flow.rb:1093:10:1093:10 | b [element] | array_flow.rb:1093:10:1093:13 | ...[...] | -| array_flow.rb:1093:10:1093:10 | b [element] | array_flow.rb:1093:10:1093:13 | ...[...] | +| array_flow.rb:1077:5:1077:5 | b [element 0] | array_flow.rb:1078:10:1078:10 | b [element 0] | +| array_flow.rb:1077:5:1077:5 | b [element 0] | array_flow.rb:1078:10:1078:10 | b [element 0] | +| array_flow.rb:1077:5:1077:5 | b [element 2] | array_flow.rb:1080:10:1080:10 | b [element 2] | +| array_flow.rb:1077:5:1077:5 | b [element 2] | array_flow.rb:1080:10:1080:10 | b [element 2] | +| array_flow.rb:1077:5:1077:5 | b [element 3] | array_flow.rb:1081:10:1081:10 | b [element 3] | +| array_flow.rb:1077:5:1077:5 | b [element 3] | array_flow.rb:1081:10:1081:10 | b [element 3] | +| array_flow.rb:1077:9:1077:9 | a [element 0] | array_flow.rb:1077:9:1077:19 | call to rotate [element 0] | +| array_flow.rb:1077:9:1077:9 | a [element 0] | array_flow.rb:1077:9:1077:19 | call to rotate [element 0] | +| array_flow.rb:1077:9:1077:9 | a [element 2] | array_flow.rb:1077:9:1077:19 | call to rotate [element 2] | +| array_flow.rb:1077:9:1077:9 | a [element 2] | array_flow.rb:1077:9:1077:19 | call to rotate [element 2] | +| array_flow.rb:1077:9:1077:9 | a [element 3] | array_flow.rb:1077:9:1077:19 | call to rotate [element 3] | +| array_flow.rb:1077:9:1077:9 | a [element 3] | array_flow.rb:1077:9:1077:19 | call to rotate [element 3] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 0] | array_flow.rb:1077:5:1077:5 | b [element 0] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 0] | array_flow.rb:1077:5:1077:5 | b [element 0] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 2] | array_flow.rb:1077:5:1077:5 | b [element 2] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 2] | array_flow.rb:1077:5:1077:5 | b [element 2] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 3] | array_flow.rb:1077:5:1077:5 | b [element 3] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 3] | array_flow.rb:1077:5:1077:5 | b [element 3] | +| array_flow.rb:1078:10:1078:10 | b [element 0] | array_flow.rb:1078:10:1078:13 | ...[...] | +| array_flow.rb:1078:10:1078:10 | b [element 0] | array_flow.rb:1078:10:1078:13 | ...[...] | +| array_flow.rb:1080:10:1080:10 | b [element 2] | array_flow.rb:1080:10:1080:13 | ...[...] | +| array_flow.rb:1080:10:1080:10 | b [element 2] | array_flow.rb:1080:10:1080:13 | ...[...] | +| array_flow.rb:1081:10:1081:10 | b [element 3] | array_flow.rb:1081:10:1081:13 | ...[...] | +| array_flow.rb:1081:10:1081:10 | b [element 3] | array_flow.rb:1081:10:1081:13 | ...[...] | +| array_flow.rb:1083:5:1083:5 | b [element] | array_flow.rb:1084:10:1084:10 | b [element] | +| array_flow.rb:1083:5:1083:5 | b [element] | array_flow.rb:1084:10:1084:10 | b [element] | +| array_flow.rb:1083:5:1083:5 | b [element] | array_flow.rb:1085:10:1085:10 | b [element] | +| array_flow.rb:1083:5:1083:5 | b [element] | array_flow.rb:1085:10:1085:10 | b [element] | +| array_flow.rb:1083:5:1083:5 | b [element] | array_flow.rb:1086:10:1086:10 | b [element] | +| array_flow.rb:1083:5:1083:5 | b [element] | array_flow.rb:1086:10:1086:10 | b [element] | +| array_flow.rb:1083:5:1083:5 | b [element] | array_flow.rb:1087:10:1087:10 | b [element] | +| array_flow.rb:1083:5:1083:5 | b [element] | array_flow.rb:1087:10:1087:10 | b [element] | +| array_flow.rb:1083:9:1083:9 | a [element 0] | array_flow.rb:1083:9:1083:19 | call to rotate [element] | +| array_flow.rb:1083:9:1083:9 | a [element 0] | array_flow.rb:1083:9:1083:19 | call to rotate [element] | +| array_flow.rb:1083:9:1083:9 | a [element 2] | array_flow.rb:1083:9:1083:19 | call to rotate [element] | +| array_flow.rb:1083:9:1083:9 | a [element 2] | array_flow.rb:1083:9:1083:19 | call to rotate [element] | +| array_flow.rb:1083:9:1083:9 | a [element 3] | array_flow.rb:1083:9:1083:19 | call to rotate [element] | +| array_flow.rb:1083:9:1083:9 | a [element 3] | array_flow.rb:1083:9:1083:19 | call to rotate [element] | +| array_flow.rb:1083:9:1083:19 | call to rotate [element] | array_flow.rb:1083:5:1083:5 | b [element] | +| array_flow.rb:1083:9:1083:19 | call to rotate [element] | array_flow.rb:1083:5:1083:5 | b [element] | +| array_flow.rb:1084:10:1084:10 | b [element] | array_flow.rb:1084:10:1084:13 | ...[...] | +| array_flow.rb:1084:10:1084:10 | b [element] | array_flow.rb:1084:10:1084:13 | ...[...] | +| array_flow.rb:1085:10:1085:10 | b [element] | array_flow.rb:1085:10:1085:13 | ...[...] | +| array_flow.rb:1085:10:1085:10 | b [element] | array_flow.rb:1085:10:1085:13 | ...[...] | +| array_flow.rb:1086:10:1086:10 | b [element] | array_flow.rb:1086:10:1086:13 | ...[...] | +| array_flow.rb:1086:10:1086:10 | b [element] | array_flow.rb:1086:10:1086:13 | ...[...] | +| array_flow.rb:1087:10:1087:10 | b [element] | array_flow.rb:1087:10:1087:13 | ...[...] | +| array_flow.rb:1087:10:1087:10 | b [element] | array_flow.rb:1087:10:1087:13 | ...[...] | | array_flow.rb:1095:5:1095:5 | a [element 0] | array_flow.rb:1096:9:1096:9 | a [element 0] | | array_flow.rb:1095:5:1095:5 | a [element 0] | array_flow.rb:1096:9:1096:9 | a [element 0] | | array_flow.rb:1095:5:1095:5 | a [element 2] | array_flow.rb:1096:9:1096:9 | a [element 2] | @@ -2602,10 +2532,10 @@ edges | array_flow.rb:1095:28:1095:40 | call to source | array_flow.rb:1095:5:1095:5 | a [element 2] | | array_flow.rb:1095:43:1095:55 | call to source | array_flow.rb:1095:5:1095:5 | a [element 3] | | array_flow.rb:1095:43:1095:55 | call to source | array_flow.rb:1095:5:1095:5 | a [element 3] | -| array_flow.rb:1096:5:1096:5 | b [element 0] | array_flow.rb:1101:10:1101:10 | b [element 0] | -| array_flow.rb:1096:5:1096:5 | b [element 0] | array_flow.rb:1101:10:1101:10 | b [element 0] | | array_flow.rb:1096:5:1096:5 | b [element 1] | array_flow.rb:1102:10:1102:10 | b [element 1] | | array_flow.rb:1096:5:1096:5 | b [element 1] | array_flow.rb:1102:10:1102:10 | b [element 1] | +| array_flow.rb:1096:5:1096:5 | b [element 2] | array_flow.rb:1103:10:1103:10 | b [element 2] | +| array_flow.rb:1096:5:1096:5 | b [element 2] | array_flow.rb:1103:10:1103:10 | b [element 2] | | array_flow.rb:1096:5:1096:5 | b [element] | array_flow.rb:1101:10:1101:10 | b [element] | | array_flow.rb:1096:5:1096:5 | b [element] | array_flow.rb:1101:10:1101:10 | b [element] | | array_flow.rb:1096:5:1096:5 | b [element] | array_flow.rb:1102:10:1102:10 | b [element] | @@ -2614,10 +2544,10 @@ edges | array_flow.rb:1096:5:1096:5 | b [element] | array_flow.rb:1103:10:1103:10 | b [element] | | array_flow.rb:1096:5:1096:5 | b [element] | array_flow.rb:1104:10:1104:10 | b [element] | | array_flow.rb:1096:5:1096:5 | b [element] | array_flow.rb:1104:10:1104:10 | b [element] | -| array_flow.rb:1096:9:1096:9 | [post] a [element 0] | array_flow.rb:1097:10:1097:10 | a [element 0] | -| array_flow.rb:1096:9:1096:9 | [post] a [element 0] | array_flow.rb:1097:10:1097:10 | a [element 0] | | array_flow.rb:1096:9:1096:9 | [post] a [element 1] | array_flow.rb:1098:10:1098:10 | a [element 1] | | array_flow.rb:1096:9:1096:9 | [post] a [element 1] | array_flow.rb:1098:10:1098:10 | a [element 1] | +| array_flow.rb:1096:9:1096:9 | [post] a [element 2] | array_flow.rb:1099:10:1099:10 | a [element 2] | +| array_flow.rb:1096:9:1096:9 | [post] a [element 2] | array_flow.rb:1099:10:1099:10 | a [element 2] | | array_flow.rb:1096:9:1096:9 | [post] a [element] | array_flow.rb:1097:10:1097:10 | a [element] | | array_flow.rb:1096:9:1096:9 | [post] a [element] | array_flow.rb:1097:10:1097:10 | a [element] | | array_flow.rb:1096:9:1096:9 | [post] a [element] | array_flow.rb:1098:10:1098:10 | a [element] | @@ -2628,42 +2558,42 @@ edges | array_flow.rb:1096:9:1096:9 | [post] a [element] | array_flow.rb:1100:10:1100:10 | a [element] | | array_flow.rb:1096:9:1096:9 | a [element 0] | array_flow.rb:1096:9:1096:9 | [post] a [element] | | array_flow.rb:1096:9:1096:9 | a [element 0] | array_flow.rb:1096:9:1096:9 | [post] a [element] | -| array_flow.rb:1096:9:1096:9 | a [element 0] | array_flow.rb:1096:9:1096:20 | call to rotate! [element] | -| array_flow.rb:1096:9:1096:9 | a [element 0] | array_flow.rb:1096:9:1096:20 | call to rotate! [element] | -| array_flow.rb:1096:9:1096:9 | a [element 2] | array_flow.rb:1096:9:1096:9 | [post] a [element 0] | -| array_flow.rb:1096:9:1096:9 | a [element 2] | array_flow.rb:1096:9:1096:9 | [post] a [element 0] | -| array_flow.rb:1096:9:1096:9 | a [element 2] | array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] | -| array_flow.rb:1096:9:1096:9 | a [element 2] | array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] | -| array_flow.rb:1096:9:1096:9 | a [element 3] | array_flow.rb:1096:9:1096:9 | [post] a [element 1] | -| array_flow.rb:1096:9:1096:9 | a [element 3] | array_flow.rb:1096:9:1096:9 | [post] a [element 1] | -| array_flow.rb:1096:9:1096:9 | a [element 3] | array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] | -| array_flow.rb:1096:9:1096:9 | a [element 3] | array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] | array_flow.rb:1096:5:1096:5 | b [element 0] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] | array_flow.rb:1096:5:1096:5 | b [element 0] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] | array_flow.rb:1096:5:1096:5 | b [element 1] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] | array_flow.rb:1096:5:1096:5 | b [element 1] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] | array_flow.rb:1096:5:1096:5 | b [element] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] | array_flow.rb:1096:5:1096:5 | b [element] | -| array_flow.rb:1097:10:1097:10 | a [element 0] | array_flow.rb:1097:10:1097:13 | ...[...] | -| array_flow.rb:1097:10:1097:10 | a [element 0] | array_flow.rb:1097:10:1097:13 | ...[...] | +| array_flow.rb:1096:9:1096:9 | a [element 0] | array_flow.rb:1096:9:1096:17 | call to rotate! [element] | +| array_flow.rb:1096:9:1096:9 | a [element 0] | array_flow.rb:1096:9:1096:17 | call to rotate! [element] | +| array_flow.rb:1096:9:1096:9 | a [element 2] | array_flow.rb:1096:9:1096:9 | [post] a [element 1] | +| array_flow.rb:1096:9:1096:9 | a [element 2] | array_flow.rb:1096:9:1096:9 | [post] a [element 1] | +| array_flow.rb:1096:9:1096:9 | a [element 2] | array_flow.rb:1096:9:1096:17 | call to rotate! [element 1] | +| array_flow.rb:1096:9:1096:9 | a [element 2] | array_flow.rb:1096:9:1096:17 | call to rotate! [element 1] | +| array_flow.rb:1096:9:1096:9 | a [element 3] | array_flow.rb:1096:9:1096:9 | [post] a [element 2] | +| array_flow.rb:1096:9:1096:9 | a [element 3] | array_flow.rb:1096:9:1096:9 | [post] a [element 2] | +| array_flow.rb:1096:9:1096:9 | a [element 3] | array_flow.rb:1096:9:1096:17 | call to rotate! [element 2] | +| array_flow.rb:1096:9:1096:9 | a [element 3] | array_flow.rb:1096:9:1096:17 | call to rotate! [element 2] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element 1] | array_flow.rb:1096:5:1096:5 | b [element 1] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element 1] | array_flow.rb:1096:5:1096:5 | b [element 1] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element 2] | array_flow.rb:1096:5:1096:5 | b [element 2] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element 2] | array_flow.rb:1096:5:1096:5 | b [element 2] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element] | array_flow.rb:1096:5:1096:5 | b [element] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element] | array_flow.rb:1096:5:1096:5 | b [element] | | array_flow.rb:1097:10:1097:10 | a [element] | array_flow.rb:1097:10:1097:13 | ...[...] | | array_flow.rb:1097:10:1097:10 | a [element] | array_flow.rb:1097:10:1097:13 | ...[...] | | array_flow.rb:1098:10:1098:10 | a [element 1] | array_flow.rb:1098:10:1098:13 | ...[...] | | array_flow.rb:1098:10:1098:10 | a [element 1] | array_flow.rb:1098:10:1098:13 | ...[...] | | array_flow.rb:1098:10:1098:10 | a [element] | array_flow.rb:1098:10:1098:13 | ...[...] | | array_flow.rb:1098:10:1098:10 | a [element] | array_flow.rb:1098:10:1098:13 | ...[...] | +| array_flow.rb:1099:10:1099:10 | a [element 2] | array_flow.rb:1099:10:1099:13 | ...[...] | +| array_flow.rb:1099:10:1099:10 | a [element 2] | array_flow.rb:1099:10:1099:13 | ...[...] | | array_flow.rb:1099:10:1099:10 | a [element] | array_flow.rb:1099:10:1099:13 | ...[...] | | array_flow.rb:1099:10:1099:10 | a [element] | array_flow.rb:1099:10:1099:13 | ...[...] | | array_flow.rb:1100:10:1100:10 | a [element] | array_flow.rb:1100:10:1100:13 | ...[...] | | array_flow.rb:1100:10:1100:10 | a [element] | array_flow.rb:1100:10:1100:13 | ...[...] | -| array_flow.rb:1101:10:1101:10 | b [element 0] | array_flow.rb:1101:10:1101:13 | ...[...] | -| array_flow.rb:1101:10:1101:10 | b [element 0] | array_flow.rb:1101:10:1101:13 | ...[...] | | array_flow.rb:1101:10:1101:10 | b [element] | array_flow.rb:1101:10:1101:13 | ...[...] | | array_flow.rb:1101:10:1101:10 | b [element] | array_flow.rb:1101:10:1101:13 | ...[...] | | array_flow.rb:1102:10:1102:10 | b [element 1] | array_flow.rb:1102:10:1102:13 | ...[...] | | array_flow.rb:1102:10:1102:10 | b [element 1] | array_flow.rb:1102:10:1102:13 | ...[...] | | array_flow.rb:1102:10:1102:10 | b [element] | array_flow.rb:1102:10:1102:13 | ...[...] | | array_flow.rb:1102:10:1102:10 | b [element] | array_flow.rb:1102:10:1102:13 | ...[...] | +| array_flow.rb:1103:10:1103:10 | b [element 2] | array_flow.rb:1103:10:1103:13 | ...[...] | +| array_flow.rb:1103:10:1103:10 | b [element 2] | array_flow.rb:1103:10:1103:13 | ...[...] | | array_flow.rb:1103:10:1103:10 | b [element] | array_flow.rb:1103:10:1103:13 | ...[...] | | array_flow.rb:1103:10:1103:10 | b [element] | array_flow.rb:1103:10:1103:13 | ...[...] | | array_flow.rb:1104:10:1104:10 | b [element] | array_flow.rb:1104:10:1104:13 | ...[...] | @@ -2682,46 +2612,70 @@ edges | array_flow.rb:1106:43:1106:55 | call to source | array_flow.rb:1106:5:1106:5 | a [element 3] | | array_flow.rb:1107:5:1107:5 | b [element 0] | array_flow.rb:1112:10:1112:10 | b [element 0] | | array_flow.rb:1107:5:1107:5 | b [element 0] | array_flow.rb:1112:10:1112:10 | b [element 0] | -| array_flow.rb:1107:5:1107:5 | b [element 2] | array_flow.rb:1114:10:1114:10 | b [element 2] | -| array_flow.rb:1107:5:1107:5 | b [element 2] | array_flow.rb:1114:10:1114:10 | b [element 2] | -| array_flow.rb:1107:5:1107:5 | b [element 3] | array_flow.rb:1115:10:1115:10 | b [element 3] | -| array_flow.rb:1107:5:1107:5 | b [element 3] | array_flow.rb:1115:10:1115:10 | b [element 3] | +| array_flow.rb:1107:5:1107:5 | b [element 1] | array_flow.rb:1113:10:1113:10 | b [element 1] | +| array_flow.rb:1107:5:1107:5 | b [element 1] | array_flow.rb:1113:10:1113:10 | b [element 1] | +| array_flow.rb:1107:5:1107:5 | b [element] | array_flow.rb:1112:10:1112:10 | b [element] | +| array_flow.rb:1107:5:1107:5 | b [element] | array_flow.rb:1112:10:1112:10 | b [element] | +| array_flow.rb:1107:5:1107:5 | b [element] | array_flow.rb:1113:10:1113:10 | b [element] | +| array_flow.rb:1107:5:1107:5 | b [element] | array_flow.rb:1113:10:1113:10 | b [element] | +| array_flow.rb:1107:5:1107:5 | b [element] | array_flow.rb:1114:10:1114:10 | b [element] | +| array_flow.rb:1107:5:1107:5 | b [element] | array_flow.rb:1114:10:1114:10 | b [element] | +| array_flow.rb:1107:5:1107:5 | b [element] | array_flow.rb:1115:10:1115:10 | b [element] | +| array_flow.rb:1107:5:1107:5 | b [element] | array_flow.rb:1115:10:1115:10 | b [element] | | array_flow.rb:1107:9:1107:9 | [post] a [element 0] | array_flow.rb:1108:10:1108:10 | a [element 0] | | array_flow.rb:1107:9:1107:9 | [post] a [element 0] | array_flow.rb:1108:10:1108:10 | a [element 0] | -| array_flow.rb:1107:9:1107:9 | [post] a [element 2] | array_flow.rb:1110:10:1110:10 | a [element 2] | -| array_flow.rb:1107:9:1107:9 | [post] a [element 2] | array_flow.rb:1110:10:1110:10 | a [element 2] | -| array_flow.rb:1107:9:1107:9 | [post] a [element 3] | array_flow.rb:1111:10:1111:10 | a [element 3] | -| array_flow.rb:1107:9:1107:9 | [post] a [element 3] | array_flow.rb:1111:10:1111:10 | a [element 3] | -| array_flow.rb:1107:9:1107:9 | a [element 0] | array_flow.rb:1107:9:1107:9 | [post] a [element 0] | -| array_flow.rb:1107:9:1107:9 | a [element 0] | array_flow.rb:1107:9:1107:9 | [post] a [element 0] | -| array_flow.rb:1107:9:1107:9 | a [element 0] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] | -| array_flow.rb:1107:9:1107:9 | a [element 0] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] | -| array_flow.rb:1107:9:1107:9 | a [element 2] | array_flow.rb:1107:9:1107:9 | [post] a [element 2] | -| array_flow.rb:1107:9:1107:9 | a [element 2] | array_flow.rb:1107:9:1107:9 | [post] a [element 2] | -| array_flow.rb:1107:9:1107:9 | a [element 2] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] | -| array_flow.rb:1107:9:1107:9 | a [element 2] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] | -| array_flow.rb:1107:9:1107:9 | a [element 3] | array_flow.rb:1107:9:1107:9 | [post] a [element 3] | -| array_flow.rb:1107:9:1107:9 | a [element 3] | array_flow.rb:1107:9:1107:9 | [post] a [element 3] | -| array_flow.rb:1107:9:1107:9 | a [element 3] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] | -| array_flow.rb:1107:9:1107:9 | a [element 3] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] | +| array_flow.rb:1107:9:1107:9 | [post] a [element 1] | array_flow.rb:1109:10:1109:10 | a [element 1] | +| array_flow.rb:1107:9:1107:9 | [post] a [element 1] | array_flow.rb:1109:10:1109:10 | a [element 1] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | array_flow.rb:1108:10:1108:10 | a [element] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | array_flow.rb:1108:10:1108:10 | a [element] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | array_flow.rb:1109:10:1109:10 | a [element] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | array_flow.rb:1109:10:1109:10 | a [element] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | array_flow.rb:1110:10:1110:10 | a [element] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | array_flow.rb:1110:10:1110:10 | a [element] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | array_flow.rb:1111:10:1111:10 | a [element] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | array_flow.rb:1111:10:1111:10 | a [element] | +| array_flow.rb:1107:9:1107:9 | a [element 0] | array_flow.rb:1107:9:1107:9 | [post] a [element] | +| array_flow.rb:1107:9:1107:9 | a [element 0] | array_flow.rb:1107:9:1107:9 | [post] a [element] | +| array_flow.rb:1107:9:1107:9 | a [element 0] | array_flow.rb:1107:9:1107:20 | call to rotate! [element] | +| array_flow.rb:1107:9:1107:9 | a [element 0] | array_flow.rb:1107:9:1107:20 | call to rotate! [element] | +| array_flow.rb:1107:9:1107:9 | a [element 2] | array_flow.rb:1107:9:1107:9 | [post] a [element 0] | +| array_flow.rb:1107:9:1107:9 | a [element 2] | array_flow.rb:1107:9:1107:9 | [post] a [element 0] | +| array_flow.rb:1107:9:1107:9 | a [element 2] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] | +| array_flow.rb:1107:9:1107:9 | a [element 2] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] | +| array_flow.rb:1107:9:1107:9 | a [element 3] | array_flow.rb:1107:9:1107:9 | [post] a [element 1] | +| array_flow.rb:1107:9:1107:9 | a [element 3] | array_flow.rb:1107:9:1107:9 | [post] a [element 1] | +| array_flow.rb:1107:9:1107:9 | a [element 3] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 1] | +| array_flow.rb:1107:9:1107:9 | a [element 3] | array_flow.rb:1107:9:1107:20 | call to rotate! [element 1] | | array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] | array_flow.rb:1107:5:1107:5 | b [element 0] | | array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] | array_flow.rb:1107:5:1107:5 | b [element 0] | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] | array_flow.rb:1107:5:1107:5 | b [element 2] | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] | array_flow.rb:1107:5:1107:5 | b [element 2] | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] | array_flow.rb:1107:5:1107:5 | b [element 3] | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] | array_flow.rb:1107:5:1107:5 | b [element 3] | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 1] | array_flow.rb:1107:5:1107:5 | b [element 1] | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 1] | array_flow.rb:1107:5:1107:5 | b [element 1] | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element] | array_flow.rb:1107:5:1107:5 | b [element] | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element] | array_flow.rb:1107:5:1107:5 | b [element] | | array_flow.rb:1108:10:1108:10 | a [element 0] | array_flow.rb:1108:10:1108:13 | ...[...] | | array_flow.rb:1108:10:1108:10 | a [element 0] | array_flow.rb:1108:10:1108:13 | ...[...] | -| array_flow.rb:1110:10:1110:10 | a [element 2] | array_flow.rb:1110:10:1110:13 | ...[...] | -| array_flow.rb:1110:10:1110:10 | a [element 2] | array_flow.rb:1110:10:1110:13 | ...[...] | -| array_flow.rb:1111:10:1111:10 | a [element 3] | array_flow.rb:1111:10:1111:13 | ...[...] | -| array_flow.rb:1111:10:1111:10 | a [element 3] | array_flow.rb:1111:10:1111:13 | ...[...] | +| array_flow.rb:1108:10:1108:10 | a [element] | array_flow.rb:1108:10:1108:13 | ...[...] | +| array_flow.rb:1108:10:1108:10 | a [element] | array_flow.rb:1108:10:1108:13 | ...[...] | +| array_flow.rb:1109:10:1109:10 | a [element 1] | array_flow.rb:1109:10:1109:13 | ...[...] | +| array_flow.rb:1109:10:1109:10 | a [element 1] | array_flow.rb:1109:10:1109:13 | ...[...] | +| array_flow.rb:1109:10:1109:10 | a [element] | array_flow.rb:1109:10:1109:13 | ...[...] | +| array_flow.rb:1109:10:1109:10 | a [element] | array_flow.rb:1109:10:1109:13 | ...[...] | +| array_flow.rb:1110:10:1110:10 | a [element] | array_flow.rb:1110:10:1110:13 | ...[...] | +| array_flow.rb:1110:10:1110:10 | a [element] | array_flow.rb:1110:10:1110:13 | ...[...] | +| array_flow.rb:1111:10:1111:10 | a [element] | array_flow.rb:1111:10:1111:13 | ...[...] | +| array_flow.rb:1111:10:1111:10 | a [element] | array_flow.rb:1111:10:1111:13 | ...[...] | | array_flow.rb:1112:10:1112:10 | b [element 0] | array_flow.rb:1112:10:1112:13 | ...[...] | | array_flow.rb:1112:10:1112:10 | b [element 0] | array_flow.rb:1112:10:1112:13 | ...[...] | -| array_flow.rb:1114:10:1114:10 | b [element 2] | array_flow.rb:1114:10:1114:13 | ...[...] | -| array_flow.rb:1114:10:1114:10 | b [element 2] | array_flow.rb:1114:10:1114:13 | ...[...] | -| array_flow.rb:1115:10:1115:10 | b [element 3] | array_flow.rb:1115:10:1115:13 | ...[...] | -| array_flow.rb:1115:10:1115:10 | b [element 3] | array_flow.rb:1115:10:1115:13 | ...[...] | +| array_flow.rb:1112:10:1112:10 | b [element] | array_flow.rb:1112:10:1112:13 | ...[...] | +| array_flow.rb:1112:10:1112:10 | b [element] | array_flow.rb:1112:10:1112:13 | ...[...] | +| array_flow.rb:1113:10:1113:10 | b [element 1] | array_flow.rb:1113:10:1113:13 | ...[...] | +| array_flow.rb:1113:10:1113:10 | b [element 1] | array_flow.rb:1113:10:1113:13 | ...[...] | +| array_flow.rb:1113:10:1113:10 | b [element] | array_flow.rb:1113:10:1113:13 | ...[...] | +| array_flow.rb:1113:10:1113:10 | b [element] | array_flow.rb:1113:10:1113:13 | ...[...] | +| array_flow.rb:1114:10:1114:10 | b [element] | array_flow.rb:1114:10:1114:13 | ...[...] | +| array_flow.rb:1114:10:1114:10 | b [element] | array_flow.rb:1114:10:1114:13 | ...[...] | +| array_flow.rb:1115:10:1115:10 | b [element] | array_flow.rb:1115:10:1115:13 | ...[...] | +| array_flow.rb:1115:10:1115:10 | b [element] | array_flow.rb:1115:10:1115:13 | ...[...] | | array_flow.rb:1117:5:1117:5 | a [element 0] | array_flow.rb:1118:9:1118:9 | a [element 0] | | array_flow.rb:1117:5:1117:5 | a [element 0] | array_flow.rb:1118:9:1118:9 | a [element 0] | | array_flow.rb:1117:5:1117:5 | a [element 2] | array_flow.rb:1118:9:1118:9 | a [element 2] | @@ -2734,202 +2688,232 @@ edges | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1117:5:1117:5 | a [element 2] | | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1117:5:1117:5 | a [element 3] | | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1117:5:1117:5 | a [element 3] | -| array_flow.rb:1118:5:1118:5 | b [element] | array_flow.rb:1123:10:1123:10 | b [element] | -| array_flow.rb:1118:5:1118:5 | b [element] | array_flow.rb:1123:10:1123:10 | b [element] | -| array_flow.rb:1118:5:1118:5 | b [element] | array_flow.rb:1124:10:1124:10 | b [element] | -| array_flow.rb:1118:5:1118:5 | b [element] | array_flow.rb:1124:10:1124:10 | b [element] | -| array_flow.rb:1118:5:1118:5 | b [element] | array_flow.rb:1125:10:1125:10 | b [element] | -| array_flow.rb:1118:5:1118:5 | b [element] | array_flow.rb:1125:10:1125:10 | b [element] | -| array_flow.rb:1118:5:1118:5 | b [element] | array_flow.rb:1126:10:1126:10 | b [element] | -| array_flow.rb:1118:5:1118:5 | b [element] | array_flow.rb:1126:10:1126:10 | b [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | array_flow.rb:1119:10:1119:10 | a [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | array_flow.rb:1119:10:1119:10 | a [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | array_flow.rb:1120:10:1120:10 | a [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | array_flow.rb:1120:10:1120:10 | a [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | array_flow.rb:1121:10:1121:10 | a [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | array_flow.rb:1121:10:1121:10 | a [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | array_flow.rb:1122:10:1122:10 | a [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | array_flow.rb:1122:10:1122:10 | a [element] | -| array_flow.rb:1118:9:1118:9 | a [element 0] | array_flow.rb:1118:9:1118:9 | [post] a [element] | -| array_flow.rb:1118:9:1118:9 | a [element 0] | array_flow.rb:1118:9:1118:9 | [post] a [element] | -| array_flow.rb:1118:9:1118:9 | a [element 0] | array_flow.rb:1118:9:1118:20 | call to rotate! [element] | -| array_flow.rb:1118:9:1118:9 | a [element 0] | array_flow.rb:1118:9:1118:20 | call to rotate! [element] | -| array_flow.rb:1118:9:1118:9 | a [element 2] | array_flow.rb:1118:9:1118:9 | [post] a [element] | -| array_flow.rb:1118:9:1118:9 | a [element 2] | array_flow.rb:1118:9:1118:9 | [post] a [element] | -| array_flow.rb:1118:9:1118:9 | a [element 2] | array_flow.rb:1118:9:1118:20 | call to rotate! [element] | -| array_flow.rb:1118:9:1118:9 | a [element 2] | array_flow.rb:1118:9:1118:20 | call to rotate! [element] | -| array_flow.rb:1118:9:1118:9 | a [element 3] | array_flow.rb:1118:9:1118:9 | [post] a [element] | -| array_flow.rb:1118:9:1118:9 | a [element 3] | array_flow.rb:1118:9:1118:9 | [post] a [element] | -| array_flow.rb:1118:9:1118:9 | a [element 3] | array_flow.rb:1118:9:1118:20 | call to rotate! [element] | -| array_flow.rb:1118:9:1118:9 | a [element 3] | array_flow.rb:1118:9:1118:20 | call to rotate! [element] | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] | array_flow.rb:1118:5:1118:5 | b [element] | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] | array_flow.rb:1118:5:1118:5 | b [element] | -| array_flow.rb:1119:10:1119:10 | a [element] | array_flow.rb:1119:10:1119:13 | ...[...] | -| array_flow.rb:1119:10:1119:10 | a [element] | array_flow.rb:1119:10:1119:13 | ...[...] | -| array_flow.rb:1120:10:1120:10 | a [element] | array_flow.rb:1120:10:1120:13 | ...[...] | -| array_flow.rb:1120:10:1120:10 | a [element] | array_flow.rb:1120:10:1120:13 | ...[...] | -| array_flow.rb:1121:10:1121:10 | a [element] | array_flow.rb:1121:10:1121:13 | ...[...] | -| array_flow.rb:1121:10:1121:10 | a [element] | array_flow.rb:1121:10:1121:13 | ...[...] | -| array_flow.rb:1122:10:1122:10 | a [element] | array_flow.rb:1122:10:1122:13 | ...[...] | -| array_flow.rb:1122:10:1122:10 | a [element] | array_flow.rb:1122:10:1122:13 | ...[...] | -| array_flow.rb:1123:10:1123:10 | b [element] | array_flow.rb:1123:10:1123:13 | ...[...] | -| array_flow.rb:1123:10:1123:10 | b [element] | array_flow.rb:1123:10:1123:13 | ...[...] | -| array_flow.rb:1124:10:1124:10 | b [element] | array_flow.rb:1124:10:1124:13 | ...[...] | -| array_flow.rb:1124:10:1124:10 | b [element] | array_flow.rb:1124:10:1124:13 | ...[...] | -| array_flow.rb:1125:10:1125:10 | b [element] | array_flow.rb:1125:10:1125:13 | ...[...] | -| array_flow.rb:1125:10:1125:10 | b [element] | array_flow.rb:1125:10:1125:13 | ...[...] | -| array_flow.rb:1126:10:1126:10 | b [element] | array_flow.rb:1126:10:1126:13 | ...[...] | -| array_flow.rb:1126:10:1126:10 | b [element] | array_flow.rb:1126:10:1126:13 | ...[...] | -| array_flow.rb:1130:5:1130:5 | a [element 3] | array_flow.rb:1131:9:1131:9 | a [element 3] | -| array_flow.rb:1130:5:1130:5 | a [element 3] | array_flow.rb:1131:9:1131:9 | a [element 3] | -| array_flow.rb:1130:19:1130:29 | call to source | array_flow.rb:1130:5:1130:5 | a [element 3] | -| array_flow.rb:1130:19:1130:29 | call to source | array_flow.rb:1130:5:1130:5 | a [element 3] | -| array_flow.rb:1131:5:1131:5 | b [element] | array_flow.rb:1134:10:1134:10 | b [element] | -| array_flow.rb:1131:5:1131:5 | b [element] | array_flow.rb:1134:10:1134:10 | b [element] | -| array_flow.rb:1131:9:1131:9 | a [element 3] | array_flow.rb:1131:9:1133:7 | call to select [element] | -| array_flow.rb:1131:9:1131:9 | a [element 3] | array_flow.rb:1131:9:1133:7 | call to select [element] | -| array_flow.rb:1131:9:1131:9 | a [element 3] | array_flow.rb:1131:22:1131:22 | x | -| array_flow.rb:1131:9:1131:9 | a [element 3] | array_flow.rb:1131:22:1131:22 | x | -| array_flow.rb:1131:9:1133:7 | call to select [element] | array_flow.rb:1131:5:1131:5 | b [element] | -| array_flow.rb:1131:9:1133:7 | call to select [element] | array_flow.rb:1131:5:1131:5 | b [element] | -| array_flow.rb:1131:22:1131:22 | x | array_flow.rb:1132:14:1132:14 | x | -| array_flow.rb:1131:22:1131:22 | x | array_flow.rb:1132:14:1132:14 | x | +| array_flow.rb:1118:5:1118:5 | b [element 0] | array_flow.rb:1123:10:1123:10 | b [element 0] | +| array_flow.rb:1118:5:1118:5 | b [element 0] | array_flow.rb:1123:10:1123:10 | b [element 0] | +| array_flow.rb:1118:5:1118:5 | b [element 2] | array_flow.rb:1125:10:1125:10 | b [element 2] | +| array_flow.rb:1118:5:1118:5 | b [element 2] | array_flow.rb:1125:10:1125:10 | b [element 2] | +| array_flow.rb:1118:5:1118:5 | b [element 3] | array_flow.rb:1126:10:1126:10 | b [element 3] | +| array_flow.rb:1118:5:1118:5 | b [element 3] | array_flow.rb:1126:10:1126:10 | b [element 3] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 0] | array_flow.rb:1119:10:1119:10 | a [element 0] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 0] | array_flow.rb:1119:10:1119:10 | a [element 0] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 2] | array_flow.rb:1121:10:1121:10 | a [element 2] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 2] | array_flow.rb:1121:10:1121:10 | a [element 2] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 3] | array_flow.rb:1122:10:1122:10 | a [element 3] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 3] | array_flow.rb:1122:10:1122:10 | a [element 3] | +| array_flow.rb:1118:9:1118:9 | a [element 0] | array_flow.rb:1118:9:1118:9 | [post] a [element 0] | +| array_flow.rb:1118:9:1118:9 | a [element 0] | array_flow.rb:1118:9:1118:9 | [post] a [element 0] | +| array_flow.rb:1118:9:1118:9 | a [element 0] | array_flow.rb:1118:9:1118:20 | call to rotate! [element 0] | +| array_flow.rb:1118:9:1118:9 | a [element 0] | array_flow.rb:1118:9:1118:20 | call to rotate! [element 0] | +| array_flow.rb:1118:9:1118:9 | a [element 2] | array_flow.rb:1118:9:1118:9 | [post] a [element 2] | +| array_flow.rb:1118:9:1118:9 | a [element 2] | array_flow.rb:1118:9:1118:9 | [post] a [element 2] | +| array_flow.rb:1118:9:1118:9 | a [element 2] | array_flow.rb:1118:9:1118:20 | call to rotate! [element 2] | +| array_flow.rb:1118:9:1118:9 | a [element 2] | array_flow.rb:1118:9:1118:20 | call to rotate! [element 2] | +| array_flow.rb:1118:9:1118:9 | a [element 3] | array_flow.rb:1118:9:1118:9 | [post] a [element 3] | +| array_flow.rb:1118:9:1118:9 | a [element 3] | array_flow.rb:1118:9:1118:9 | [post] a [element 3] | +| array_flow.rb:1118:9:1118:9 | a [element 3] | array_flow.rb:1118:9:1118:20 | call to rotate! [element 3] | +| array_flow.rb:1118:9:1118:9 | a [element 3] | array_flow.rb:1118:9:1118:20 | call to rotate! [element 3] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 0] | array_flow.rb:1118:5:1118:5 | b [element 0] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 0] | array_flow.rb:1118:5:1118:5 | b [element 0] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 2] | array_flow.rb:1118:5:1118:5 | b [element 2] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 2] | array_flow.rb:1118:5:1118:5 | b [element 2] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 3] | array_flow.rb:1118:5:1118:5 | b [element 3] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 3] | array_flow.rb:1118:5:1118:5 | b [element 3] | +| array_flow.rb:1119:10:1119:10 | a [element 0] | array_flow.rb:1119:10:1119:13 | ...[...] | +| array_flow.rb:1119:10:1119:10 | a [element 0] | array_flow.rb:1119:10:1119:13 | ...[...] | +| array_flow.rb:1121:10:1121:10 | a [element 2] | array_flow.rb:1121:10:1121:13 | ...[...] | +| array_flow.rb:1121:10:1121:10 | a [element 2] | array_flow.rb:1121:10:1121:13 | ...[...] | +| array_flow.rb:1122:10:1122:10 | a [element 3] | array_flow.rb:1122:10:1122:13 | ...[...] | +| array_flow.rb:1122:10:1122:10 | a [element 3] | array_flow.rb:1122:10:1122:13 | ...[...] | +| array_flow.rb:1123:10:1123:10 | b [element 0] | array_flow.rb:1123:10:1123:13 | ...[...] | +| array_flow.rb:1123:10:1123:10 | b [element 0] | array_flow.rb:1123:10:1123:13 | ...[...] | +| array_flow.rb:1125:10:1125:10 | b [element 2] | array_flow.rb:1125:10:1125:13 | ...[...] | +| array_flow.rb:1125:10:1125:10 | b [element 2] | array_flow.rb:1125:10:1125:13 | ...[...] | +| array_flow.rb:1126:10:1126:10 | b [element 3] | array_flow.rb:1126:10:1126:13 | ...[...] | +| array_flow.rb:1126:10:1126:10 | b [element 3] | array_flow.rb:1126:10:1126:13 | ...[...] | +| array_flow.rb:1128:5:1128:5 | a [element 0] | array_flow.rb:1129:9:1129:9 | a [element 0] | +| array_flow.rb:1128:5:1128:5 | a [element 0] | array_flow.rb:1129:9:1129:9 | a [element 0] | +| array_flow.rb:1128:5:1128:5 | a [element 2] | array_flow.rb:1129:9:1129:9 | a [element 2] | +| array_flow.rb:1128:5:1128:5 | a [element 2] | array_flow.rb:1129:9:1129:9 | a [element 2] | +| array_flow.rb:1128:5:1128:5 | a [element 3] | array_flow.rb:1129:9:1129:9 | a [element 3] | +| array_flow.rb:1128:5:1128:5 | a [element 3] | array_flow.rb:1129:9:1129:9 | a [element 3] | +| array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1128:5:1128:5 | a [element 0] | +| array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1128:5:1128:5 | a [element 0] | +| array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1128:5:1128:5 | a [element 2] | +| array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1128:5:1128:5 | a [element 2] | +| array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1128:5:1128:5 | a [element 3] | +| array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1128:5:1128:5 | a [element 3] | +| array_flow.rb:1129:5:1129:5 | b [element] | array_flow.rb:1134:10:1134:10 | b [element] | +| array_flow.rb:1129:5:1129:5 | b [element] | array_flow.rb:1134:10:1134:10 | b [element] | +| array_flow.rb:1129:5:1129:5 | b [element] | array_flow.rb:1135:10:1135:10 | b [element] | +| array_flow.rb:1129:5:1129:5 | b [element] | array_flow.rb:1135:10:1135:10 | b [element] | +| array_flow.rb:1129:5:1129:5 | b [element] | array_flow.rb:1136:10:1136:10 | b [element] | +| array_flow.rb:1129:5:1129:5 | b [element] | array_flow.rb:1136:10:1136:10 | b [element] | +| array_flow.rb:1129:5:1129:5 | b [element] | array_flow.rb:1137:10:1137:10 | b [element] | +| array_flow.rb:1129:5:1129:5 | b [element] | array_flow.rb:1137:10:1137:10 | b [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | array_flow.rb:1130:10:1130:10 | a [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | array_flow.rb:1130:10:1130:10 | a [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | array_flow.rb:1131:10:1131:10 | a [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | array_flow.rb:1131:10:1131:10 | a [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | array_flow.rb:1132:10:1132:10 | a [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | array_flow.rb:1132:10:1132:10 | a [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | array_flow.rb:1133:10:1133:10 | a [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | array_flow.rb:1133:10:1133:10 | a [element] | +| array_flow.rb:1129:9:1129:9 | a [element 0] | array_flow.rb:1129:9:1129:9 | [post] a [element] | +| array_flow.rb:1129:9:1129:9 | a [element 0] | array_flow.rb:1129:9:1129:9 | [post] a [element] | +| array_flow.rb:1129:9:1129:9 | a [element 0] | array_flow.rb:1129:9:1129:20 | call to rotate! [element] | +| array_flow.rb:1129:9:1129:9 | a [element 0] | array_flow.rb:1129:9:1129:20 | call to rotate! [element] | +| array_flow.rb:1129:9:1129:9 | a [element 2] | array_flow.rb:1129:9:1129:9 | [post] a [element] | +| array_flow.rb:1129:9:1129:9 | a [element 2] | array_flow.rb:1129:9:1129:9 | [post] a [element] | +| array_flow.rb:1129:9:1129:9 | a [element 2] | array_flow.rb:1129:9:1129:20 | call to rotate! [element] | +| array_flow.rb:1129:9:1129:9 | a [element 2] | array_flow.rb:1129:9:1129:20 | call to rotate! [element] | +| array_flow.rb:1129:9:1129:9 | a [element 3] | array_flow.rb:1129:9:1129:9 | [post] a [element] | +| array_flow.rb:1129:9:1129:9 | a [element 3] | array_flow.rb:1129:9:1129:9 | [post] a [element] | +| array_flow.rb:1129:9:1129:9 | a [element 3] | array_flow.rb:1129:9:1129:20 | call to rotate! [element] | +| array_flow.rb:1129:9:1129:9 | a [element 3] | array_flow.rb:1129:9:1129:20 | call to rotate! [element] | +| array_flow.rb:1129:9:1129:20 | call to rotate! [element] | array_flow.rb:1129:5:1129:5 | b [element] | +| array_flow.rb:1129:9:1129:20 | call to rotate! [element] | array_flow.rb:1129:5:1129:5 | b [element] | +| array_flow.rb:1130:10:1130:10 | a [element] | array_flow.rb:1130:10:1130:13 | ...[...] | +| array_flow.rb:1130:10:1130:10 | a [element] | array_flow.rb:1130:10:1130:13 | ...[...] | +| array_flow.rb:1131:10:1131:10 | a [element] | array_flow.rb:1131:10:1131:13 | ...[...] | +| array_flow.rb:1131:10:1131:10 | a [element] | array_flow.rb:1131:10:1131:13 | ...[...] | +| array_flow.rb:1132:10:1132:10 | a [element] | array_flow.rb:1132:10:1132:13 | ...[...] | +| array_flow.rb:1132:10:1132:10 | a [element] | array_flow.rb:1132:10:1132:13 | ...[...] | +| array_flow.rb:1133:10:1133:10 | a [element] | array_flow.rb:1133:10:1133:13 | ...[...] | +| array_flow.rb:1133:10:1133:10 | a [element] | array_flow.rb:1133:10:1133:13 | ...[...] | | array_flow.rb:1134:10:1134:10 | b [element] | array_flow.rb:1134:10:1134:13 | ...[...] | | array_flow.rb:1134:10:1134:10 | b [element] | array_flow.rb:1134:10:1134:13 | ...[...] | -| array_flow.rb:1138:5:1138:5 | a [element 2] | array_flow.rb:1139:9:1139:9 | a [element 2] | -| array_flow.rb:1138:5:1138:5 | a [element 2] | array_flow.rb:1139:9:1139:9 | a [element 2] | -| array_flow.rb:1138:16:1138:26 | call to source | array_flow.rb:1138:5:1138:5 | a [element 2] | -| array_flow.rb:1138:16:1138:26 | call to source | array_flow.rb:1138:5:1138:5 | a [element 2] | -| array_flow.rb:1139:5:1139:5 | b [element] | array_flow.rb:1144:10:1144:10 | b [element] | -| array_flow.rb:1139:5:1139:5 | b [element] | array_flow.rb:1144:10:1144:10 | b [element] | -| array_flow.rb:1139:9:1139:9 | [post] a [element] | array_flow.rb:1143:10:1143:10 | a [element] | -| array_flow.rb:1139:9:1139:9 | [post] a [element] | array_flow.rb:1143:10:1143:10 | a [element] | -| array_flow.rb:1139:9:1139:9 | a [element 2] | array_flow.rb:1139:9:1139:9 | [post] a [element] | -| array_flow.rb:1139:9:1139:9 | a [element 2] | array_flow.rb:1139:9:1139:9 | [post] a [element] | -| array_flow.rb:1139:9:1139:9 | a [element 2] | array_flow.rb:1139:9:1142:7 | call to select! [element] | -| array_flow.rb:1139:9:1139:9 | a [element 2] | array_flow.rb:1139:9:1142:7 | call to select! [element] | -| array_flow.rb:1139:9:1139:9 | a [element 2] | array_flow.rb:1139:23:1139:23 | x | -| array_flow.rb:1139:9:1139:9 | a [element 2] | array_flow.rb:1139:23:1139:23 | x | -| array_flow.rb:1139:9:1142:7 | call to select! [element] | array_flow.rb:1139:5:1139:5 | b [element] | -| array_flow.rb:1139:9:1142:7 | call to select! [element] | array_flow.rb:1139:5:1139:5 | b [element] | -| array_flow.rb:1139:23:1139:23 | x | array_flow.rb:1140:14:1140:14 | x | -| array_flow.rb:1139:23:1139:23 | x | array_flow.rb:1140:14:1140:14 | x | -| array_flow.rb:1143:10:1143:10 | a [element] | array_flow.rb:1143:10:1143:13 | ...[...] | -| array_flow.rb:1143:10:1143:10 | a [element] | array_flow.rb:1143:10:1143:13 | ...[...] | -| array_flow.rb:1144:10:1144:10 | b [element] | array_flow.rb:1144:10:1144:13 | ...[...] | -| array_flow.rb:1144:10:1144:10 | b [element] | array_flow.rb:1144:10:1144:13 | ...[...] | -| array_flow.rb:1148:5:1148:5 | a [element 0] | array_flow.rb:1149:9:1149:9 | a [element 0] | -| array_flow.rb:1148:5:1148:5 | a [element 0] | array_flow.rb:1149:9:1149:9 | a [element 0] | -| array_flow.rb:1148:5:1148:5 | a [element 2] | array_flow.rb:1149:9:1149:9 | a [element 2] | -| array_flow.rb:1148:5:1148:5 | a [element 2] | array_flow.rb:1149:9:1149:9 | a [element 2] | -| array_flow.rb:1148:10:1148:22 | call to source | array_flow.rb:1148:5:1148:5 | a [element 0] | -| array_flow.rb:1148:10:1148:22 | call to source | array_flow.rb:1148:5:1148:5 | a [element 0] | -| array_flow.rb:1148:28:1148:40 | call to source | array_flow.rb:1148:5:1148:5 | a [element 2] | -| array_flow.rb:1148:28:1148:40 | call to source | array_flow.rb:1148:5:1148:5 | a [element 2] | -| array_flow.rb:1149:5:1149:5 | b | array_flow.rb:1150:10:1150:10 | b | -| array_flow.rb:1149:5:1149:5 | b | array_flow.rb:1150:10:1150:10 | b | -| array_flow.rb:1149:9:1149:9 | [post] a [element 1] | array_flow.rb:1152:10:1152:10 | a [element 1] | -| array_flow.rb:1149:9:1149:9 | [post] a [element 1] | array_flow.rb:1152:10:1152:10 | a [element 1] | -| array_flow.rb:1149:9:1149:9 | a [element 0] | array_flow.rb:1149:9:1149:15 | call to shift | -| array_flow.rb:1149:9:1149:9 | a [element 0] | array_flow.rb:1149:9:1149:15 | call to shift | -| array_flow.rb:1149:9:1149:9 | a [element 2] | array_flow.rb:1149:9:1149:9 | [post] a [element 1] | -| array_flow.rb:1149:9:1149:9 | a [element 2] | array_flow.rb:1149:9:1149:9 | [post] a [element 1] | -| array_flow.rb:1149:9:1149:15 | call to shift | array_flow.rb:1149:5:1149:5 | b | -| array_flow.rb:1149:9:1149:15 | call to shift | array_flow.rb:1149:5:1149:5 | b | -| array_flow.rb:1152:10:1152:10 | a [element 1] | array_flow.rb:1152:10:1152:13 | ...[...] | -| array_flow.rb:1152:10:1152:10 | a [element 1] | array_flow.rb:1152:10:1152:13 | ...[...] | -| array_flow.rb:1155:5:1155:5 | a [element 0] | array_flow.rb:1156:9:1156:9 | a [element 0] | -| array_flow.rb:1155:5:1155:5 | a [element 0] | array_flow.rb:1156:9:1156:9 | a [element 0] | -| array_flow.rb:1155:5:1155:5 | a [element 2] | array_flow.rb:1156:9:1156:9 | a [element 2] | -| array_flow.rb:1155:5:1155:5 | a [element 2] | array_flow.rb:1156:9:1156:9 | a [element 2] | -| array_flow.rb:1155:10:1155:22 | call to source | array_flow.rb:1155:5:1155:5 | a [element 0] | -| array_flow.rb:1155:10:1155:22 | call to source | array_flow.rb:1155:5:1155:5 | a [element 0] | -| array_flow.rb:1155:28:1155:40 | call to source | array_flow.rb:1155:5:1155:5 | a [element 2] | -| array_flow.rb:1155:28:1155:40 | call to source | array_flow.rb:1155:5:1155:5 | a [element 2] | -| array_flow.rb:1156:5:1156:5 | b [element 0] | array_flow.rb:1157:10:1157:10 | b [element 0] | -| array_flow.rb:1156:5:1156:5 | b [element 0] | array_flow.rb:1157:10:1157:10 | b [element 0] | -| array_flow.rb:1156:9:1156:9 | [post] a [element 0] | array_flow.rb:1159:10:1159:10 | a [element 0] | -| array_flow.rb:1156:9:1156:9 | [post] a [element 0] | array_flow.rb:1159:10:1159:10 | a [element 0] | -| array_flow.rb:1156:9:1156:9 | a [element 0] | array_flow.rb:1156:9:1156:18 | call to shift [element 0] | -| array_flow.rb:1156:9:1156:9 | a [element 0] | array_flow.rb:1156:9:1156:18 | call to shift [element 0] | -| array_flow.rb:1156:9:1156:9 | a [element 2] | array_flow.rb:1156:9:1156:9 | [post] a [element 0] | -| array_flow.rb:1156:9:1156:9 | a [element 2] | array_flow.rb:1156:9:1156:9 | [post] a [element 0] | -| array_flow.rb:1156:9:1156:18 | call to shift [element 0] | array_flow.rb:1156:5:1156:5 | b [element 0] | -| array_flow.rb:1156:9:1156:18 | call to shift [element 0] | array_flow.rb:1156:5:1156:5 | b [element 0] | -| array_flow.rb:1157:10:1157:10 | b [element 0] | array_flow.rb:1157:10:1157:13 | ...[...] | -| array_flow.rb:1157:10:1157:10 | b [element 0] | array_flow.rb:1157:10:1157:13 | ...[...] | -| array_flow.rb:1159:10:1159:10 | a [element 0] | array_flow.rb:1159:10:1159:13 | ...[...] | -| array_flow.rb:1159:10:1159:10 | a [element 0] | array_flow.rb:1159:10:1159:13 | ...[...] | -| array_flow.rb:1163:5:1163:5 | a [element 0] | array_flow.rb:1164:9:1164:9 | a [element 0] | -| array_flow.rb:1163:5:1163:5 | a [element 0] | array_flow.rb:1164:9:1164:9 | a [element 0] | -| array_flow.rb:1163:5:1163:5 | a [element 0] | array_flow.rb:1167:10:1167:10 | a [element 0] | -| array_flow.rb:1163:5:1163:5 | a [element 0] | array_flow.rb:1167:10:1167:10 | a [element 0] | -| array_flow.rb:1163:5:1163:5 | a [element 2] | array_flow.rb:1164:9:1164:9 | a [element 2] | -| array_flow.rb:1163:5:1163:5 | a [element 2] | array_flow.rb:1164:9:1164:9 | a [element 2] | -| array_flow.rb:1163:5:1163:5 | a [element 2] | array_flow.rb:1169:10:1169:10 | a [element 2] | -| array_flow.rb:1163:5:1163:5 | a [element 2] | array_flow.rb:1169:10:1169:10 | a [element 2] | -| array_flow.rb:1163:10:1163:22 | call to source | array_flow.rb:1163:5:1163:5 | a [element 0] | -| array_flow.rb:1163:10:1163:22 | call to source | array_flow.rb:1163:5:1163:5 | a [element 0] | -| array_flow.rb:1163:28:1163:40 | call to source | array_flow.rb:1163:5:1163:5 | a [element 2] | -| array_flow.rb:1163:28:1163:40 | call to source | array_flow.rb:1163:5:1163:5 | a [element 2] | -| array_flow.rb:1164:5:1164:5 | b [element] | array_flow.rb:1165:10:1165:10 | b [element] | -| array_flow.rb:1164:5:1164:5 | b [element] | array_flow.rb:1165:10:1165:10 | b [element] | -| array_flow.rb:1164:5:1164:5 | b [element] | array_flow.rb:1166:10:1166:10 | b [element] | -| array_flow.rb:1164:5:1164:5 | b [element] | array_flow.rb:1166:10:1166:10 | b [element] | -| array_flow.rb:1164:9:1164:9 | [post] a [element] | array_flow.rb:1167:10:1167:10 | a [element] | -| array_flow.rb:1164:9:1164:9 | [post] a [element] | array_flow.rb:1167:10:1167:10 | a [element] | -| array_flow.rb:1164:9:1164:9 | [post] a [element] | array_flow.rb:1168:10:1168:10 | a [element] | -| array_flow.rb:1164:9:1164:9 | [post] a [element] | array_flow.rb:1168:10:1168:10 | a [element] | -| array_flow.rb:1164:9:1164:9 | [post] a [element] | array_flow.rb:1169:10:1169:10 | a [element] | -| array_flow.rb:1164:9:1164:9 | [post] a [element] | array_flow.rb:1169:10:1169:10 | a [element] | -| array_flow.rb:1164:9:1164:9 | a [element 0] | array_flow.rb:1164:9:1164:9 | [post] a [element] | -| array_flow.rb:1164:9:1164:9 | a [element 0] | array_flow.rb:1164:9:1164:9 | [post] a [element] | -| array_flow.rb:1164:9:1164:9 | a [element 0] | array_flow.rb:1164:9:1164:18 | call to shift [element] | -| array_flow.rb:1164:9:1164:9 | a [element 0] | array_flow.rb:1164:9:1164:18 | call to shift [element] | -| array_flow.rb:1164:9:1164:9 | a [element 2] | array_flow.rb:1164:9:1164:9 | [post] a [element] | -| array_flow.rb:1164:9:1164:9 | a [element 2] | array_flow.rb:1164:9:1164:9 | [post] a [element] | -| array_flow.rb:1164:9:1164:9 | a [element 2] | array_flow.rb:1164:9:1164:18 | call to shift [element] | -| array_flow.rb:1164:9:1164:9 | a [element 2] | array_flow.rb:1164:9:1164:18 | call to shift [element] | -| array_flow.rb:1164:9:1164:18 | call to shift [element] | array_flow.rb:1164:5:1164:5 | b [element] | -| array_flow.rb:1164:9:1164:18 | call to shift [element] | array_flow.rb:1164:5:1164:5 | b [element] | -| array_flow.rb:1165:10:1165:10 | b [element] | array_flow.rb:1165:10:1165:13 | ...[...] | -| array_flow.rb:1165:10:1165:10 | b [element] | array_flow.rb:1165:10:1165:13 | ...[...] | -| array_flow.rb:1166:10:1166:10 | b [element] | array_flow.rb:1166:10:1166:13 | ...[...] | -| array_flow.rb:1166:10:1166:10 | b [element] | array_flow.rb:1166:10:1166:13 | ...[...] | -| array_flow.rb:1167:10:1167:10 | a [element 0] | array_flow.rb:1167:10:1167:13 | ...[...] | -| array_flow.rb:1167:10:1167:10 | a [element 0] | array_flow.rb:1167:10:1167:13 | ...[...] | -| array_flow.rb:1167:10:1167:10 | a [element] | array_flow.rb:1167:10:1167:13 | ...[...] | -| array_flow.rb:1167:10:1167:10 | a [element] | array_flow.rb:1167:10:1167:13 | ...[...] | -| array_flow.rb:1168:10:1168:10 | a [element] | array_flow.rb:1168:10:1168:13 | ...[...] | -| array_flow.rb:1168:10:1168:10 | a [element] | array_flow.rb:1168:10:1168:13 | ...[...] | -| array_flow.rb:1169:10:1169:10 | a [element 2] | array_flow.rb:1169:10:1169:13 | ...[...] | -| array_flow.rb:1169:10:1169:10 | a [element 2] | array_flow.rb:1169:10:1169:13 | ...[...] | -| array_flow.rb:1169:10:1169:10 | a [element] | array_flow.rb:1169:10:1169:13 | ...[...] | -| array_flow.rb:1169:10:1169:10 | a [element] | array_flow.rb:1169:10:1169:13 | ...[...] | -| array_flow.rb:1173:5:1173:5 | a [element 2] | array_flow.rb:1174:9:1174:9 | a [element 2] | -| array_flow.rb:1173:5:1173:5 | a [element 2] | array_flow.rb:1174:9:1174:9 | a [element 2] | -| array_flow.rb:1173:5:1173:5 | a [element 2] | array_flow.rb:1177:10:1177:10 | a [element 2] | -| array_flow.rb:1173:5:1173:5 | a [element 2] | array_flow.rb:1177:10:1177:10 | a [element 2] | -| array_flow.rb:1173:16:1173:26 | call to source | array_flow.rb:1173:5:1173:5 | a [element 2] | -| array_flow.rb:1173:16:1173:26 | call to source | array_flow.rb:1173:5:1173:5 | a [element 2] | -| array_flow.rb:1174:5:1174:5 | b [element] | array_flow.rb:1178:10:1178:10 | b [element] | -| array_flow.rb:1174:5:1174:5 | b [element] | array_flow.rb:1178:10:1178:10 | b [element] | -| array_flow.rb:1174:5:1174:5 | b [element] | array_flow.rb:1179:10:1179:10 | b [element] | -| array_flow.rb:1174:5:1174:5 | b [element] | array_flow.rb:1179:10:1179:10 | b [element] | -| array_flow.rb:1174:5:1174:5 | b [element] | array_flow.rb:1180:10:1180:10 | b [element] | -| array_flow.rb:1174:5:1174:5 | b [element] | array_flow.rb:1180:10:1180:10 | b [element] | -| array_flow.rb:1174:9:1174:9 | a [element 2] | array_flow.rb:1174:9:1174:17 | call to shuffle [element] | -| array_flow.rb:1174:9:1174:9 | a [element 2] | array_flow.rb:1174:9:1174:17 | call to shuffle [element] | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] | array_flow.rb:1174:5:1174:5 | b [element] | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] | array_flow.rb:1174:5:1174:5 | b [element] | -| array_flow.rb:1177:10:1177:10 | a [element 2] | array_flow.rb:1177:10:1177:13 | ...[...] | -| array_flow.rb:1177:10:1177:10 | a [element 2] | array_flow.rb:1177:10:1177:13 | ...[...] | -| array_flow.rb:1178:10:1178:10 | b [element] | array_flow.rb:1178:10:1178:13 | ...[...] | -| array_flow.rb:1178:10:1178:10 | b [element] | array_flow.rb:1178:10:1178:13 | ...[...] | -| array_flow.rb:1179:10:1179:10 | b [element] | array_flow.rb:1179:10:1179:13 | ...[...] | -| array_flow.rb:1179:10:1179:10 | b [element] | array_flow.rb:1179:10:1179:13 | ...[...] | -| array_flow.rb:1180:10:1180:10 | b [element] | array_flow.rb:1180:10:1180:13 | ...[...] | -| array_flow.rb:1180:10:1180:10 | b [element] | array_flow.rb:1180:10:1180:13 | ...[...] | +| array_flow.rb:1135:10:1135:10 | b [element] | array_flow.rb:1135:10:1135:13 | ...[...] | +| array_flow.rb:1135:10:1135:10 | b [element] | array_flow.rb:1135:10:1135:13 | ...[...] | +| array_flow.rb:1136:10:1136:10 | b [element] | array_flow.rb:1136:10:1136:13 | ...[...] | +| array_flow.rb:1136:10:1136:10 | b [element] | array_flow.rb:1136:10:1136:13 | ...[...] | +| array_flow.rb:1137:10:1137:10 | b [element] | array_flow.rb:1137:10:1137:13 | ...[...] | +| array_flow.rb:1137:10:1137:10 | b [element] | array_flow.rb:1137:10:1137:13 | ...[...] | +| array_flow.rb:1141:5:1141:5 | a [element 3] | array_flow.rb:1142:9:1142:9 | a [element 3] | +| array_flow.rb:1141:5:1141:5 | a [element 3] | array_flow.rb:1142:9:1142:9 | a [element 3] | +| array_flow.rb:1141:19:1141:29 | call to source | array_flow.rb:1141:5:1141:5 | a [element 3] | +| array_flow.rb:1141:19:1141:29 | call to source | array_flow.rb:1141:5:1141:5 | a [element 3] | +| array_flow.rb:1142:5:1142:5 | b [element] | array_flow.rb:1145:10:1145:10 | b [element] | +| array_flow.rb:1142:5:1142:5 | b [element] | array_flow.rb:1145:10:1145:10 | b [element] | +| array_flow.rb:1142:9:1142:9 | a [element 3] | array_flow.rb:1142:9:1144:7 | call to select [element] | +| array_flow.rb:1142:9:1142:9 | a [element 3] | array_flow.rb:1142:9:1144:7 | call to select [element] | +| array_flow.rb:1142:9:1142:9 | a [element 3] | array_flow.rb:1142:22:1142:22 | x | +| array_flow.rb:1142:9:1142:9 | a [element 3] | array_flow.rb:1142:22:1142:22 | x | +| array_flow.rb:1142:9:1144:7 | call to select [element] | array_flow.rb:1142:5:1142:5 | b [element] | +| array_flow.rb:1142:9:1144:7 | call to select [element] | array_flow.rb:1142:5:1142:5 | b [element] | +| array_flow.rb:1142:22:1142:22 | x | array_flow.rb:1143:14:1143:14 | x | +| array_flow.rb:1142:22:1142:22 | x | array_flow.rb:1143:14:1143:14 | x | +| array_flow.rb:1145:10:1145:10 | b [element] | array_flow.rb:1145:10:1145:13 | ...[...] | +| array_flow.rb:1145:10:1145:10 | b [element] | array_flow.rb:1145:10:1145:13 | ...[...] | +| array_flow.rb:1149:5:1149:5 | a [element 2] | array_flow.rb:1150:9:1150:9 | a [element 2] | +| array_flow.rb:1149:5:1149:5 | a [element 2] | array_flow.rb:1150:9:1150:9 | a [element 2] | +| array_flow.rb:1149:16:1149:26 | call to source | array_flow.rb:1149:5:1149:5 | a [element 2] | +| array_flow.rb:1149:16:1149:26 | call to source | array_flow.rb:1149:5:1149:5 | a [element 2] | +| array_flow.rb:1150:5:1150:5 | b [element] | array_flow.rb:1155:10:1155:10 | b [element] | +| array_flow.rb:1150:5:1150:5 | b [element] | array_flow.rb:1155:10:1155:10 | b [element] | +| array_flow.rb:1150:9:1150:9 | [post] a [element] | array_flow.rb:1154:10:1154:10 | a [element] | +| array_flow.rb:1150:9:1150:9 | [post] a [element] | array_flow.rb:1154:10:1154:10 | a [element] | +| array_flow.rb:1150:9:1150:9 | a [element 2] | array_flow.rb:1150:9:1150:9 | [post] a [element] | +| array_flow.rb:1150:9:1150:9 | a [element 2] | array_flow.rb:1150:9:1150:9 | [post] a [element] | +| array_flow.rb:1150:9:1150:9 | a [element 2] | array_flow.rb:1150:9:1153:7 | call to select! [element] | +| array_flow.rb:1150:9:1150:9 | a [element 2] | array_flow.rb:1150:9:1153:7 | call to select! [element] | +| array_flow.rb:1150:9:1150:9 | a [element 2] | array_flow.rb:1150:23:1150:23 | x | +| array_flow.rb:1150:9:1150:9 | a [element 2] | array_flow.rb:1150:23:1150:23 | x | +| array_flow.rb:1150:9:1153:7 | call to select! [element] | array_flow.rb:1150:5:1150:5 | b [element] | +| array_flow.rb:1150:9:1153:7 | call to select! [element] | array_flow.rb:1150:5:1150:5 | b [element] | +| array_flow.rb:1150:23:1150:23 | x | array_flow.rb:1151:14:1151:14 | x | +| array_flow.rb:1150:23:1150:23 | x | array_flow.rb:1151:14:1151:14 | x | +| array_flow.rb:1154:10:1154:10 | a [element] | array_flow.rb:1154:10:1154:13 | ...[...] | +| array_flow.rb:1154:10:1154:10 | a [element] | array_flow.rb:1154:10:1154:13 | ...[...] | +| array_flow.rb:1155:10:1155:10 | b [element] | array_flow.rb:1155:10:1155:13 | ...[...] | +| array_flow.rb:1155:10:1155:10 | b [element] | array_flow.rb:1155:10:1155:13 | ...[...] | +| array_flow.rb:1159:5:1159:5 | a [element 0] | array_flow.rb:1160:9:1160:9 | a [element 0] | +| array_flow.rb:1159:5:1159:5 | a [element 0] | array_flow.rb:1160:9:1160:9 | a [element 0] | +| array_flow.rb:1159:5:1159:5 | a [element 2] | array_flow.rb:1160:9:1160:9 | a [element 2] | +| array_flow.rb:1159:5:1159:5 | a [element 2] | array_flow.rb:1160:9:1160:9 | a [element 2] | +| array_flow.rb:1159:10:1159:22 | call to source | array_flow.rb:1159:5:1159:5 | a [element 0] | +| array_flow.rb:1159:10:1159:22 | call to source | array_flow.rb:1159:5:1159:5 | a [element 0] | +| array_flow.rb:1159:28:1159:40 | call to source | array_flow.rb:1159:5:1159:5 | a [element 2] | +| array_flow.rb:1159:28:1159:40 | call to source | array_flow.rb:1159:5:1159:5 | a [element 2] | +| array_flow.rb:1160:5:1160:5 | b | array_flow.rb:1161:10:1161:10 | b | +| array_flow.rb:1160:5:1160:5 | b | array_flow.rb:1161:10:1161:10 | b | +| array_flow.rb:1160:9:1160:9 | [post] a [element 1] | array_flow.rb:1163:10:1163:10 | a [element 1] | +| array_flow.rb:1160:9:1160:9 | [post] a [element 1] | array_flow.rb:1163:10:1163:10 | a [element 1] | +| array_flow.rb:1160:9:1160:9 | a [element 0] | array_flow.rb:1160:9:1160:15 | call to shift | +| array_flow.rb:1160:9:1160:9 | a [element 0] | array_flow.rb:1160:9:1160:15 | call to shift | +| array_flow.rb:1160:9:1160:9 | a [element 2] | array_flow.rb:1160:9:1160:9 | [post] a [element 1] | +| array_flow.rb:1160:9:1160:9 | a [element 2] | array_flow.rb:1160:9:1160:9 | [post] a [element 1] | +| array_flow.rb:1160:9:1160:15 | call to shift | array_flow.rb:1160:5:1160:5 | b | +| array_flow.rb:1160:9:1160:15 | call to shift | array_flow.rb:1160:5:1160:5 | b | +| array_flow.rb:1163:10:1163:10 | a [element 1] | array_flow.rb:1163:10:1163:13 | ...[...] | +| array_flow.rb:1163:10:1163:10 | a [element 1] | array_flow.rb:1163:10:1163:13 | ...[...] | +| array_flow.rb:1166:5:1166:5 | a [element 0] | array_flow.rb:1167:9:1167:9 | a [element 0] | +| array_flow.rb:1166:5:1166:5 | a [element 0] | array_flow.rb:1167:9:1167:9 | a [element 0] | +| array_flow.rb:1166:5:1166:5 | a [element 2] | array_flow.rb:1167:9:1167:9 | a [element 2] | +| array_flow.rb:1166:5:1166:5 | a [element 2] | array_flow.rb:1167:9:1167:9 | a [element 2] | +| array_flow.rb:1166:10:1166:22 | call to source | array_flow.rb:1166:5:1166:5 | a [element 0] | +| array_flow.rb:1166:10:1166:22 | call to source | array_flow.rb:1166:5:1166:5 | a [element 0] | +| array_flow.rb:1166:28:1166:40 | call to source | array_flow.rb:1166:5:1166:5 | a [element 2] | +| array_flow.rb:1166:28:1166:40 | call to source | array_flow.rb:1166:5:1166:5 | a [element 2] | +| array_flow.rb:1167:5:1167:5 | b [element 0] | array_flow.rb:1168:10:1168:10 | b [element 0] | +| array_flow.rb:1167:5:1167:5 | b [element 0] | array_flow.rb:1168:10:1168:10 | b [element 0] | +| array_flow.rb:1167:9:1167:9 | [post] a [element 0] | array_flow.rb:1170:10:1170:10 | a [element 0] | +| array_flow.rb:1167:9:1167:9 | [post] a [element 0] | array_flow.rb:1170:10:1170:10 | a [element 0] | +| array_flow.rb:1167:9:1167:9 | a [element 0] | array_flow.rb:1167:9:1167:18 | call to shift [element 0] | +| array_flow.rb:1167:9:1167:9 | a [element 0] | array_flow.rb:1167:9:1167:18 | call to shift [element 0] | +| array_flow.rb:1167:9:1167:9 | a [element 2] | array_flow.rb:1167:9:1167:9 | [post] a [element 0] | +| array_flow.rb:1167:9:1167:9 | a [element 2] | array_flow.rb:1167:9:1167:9 | [post] a [element 0] | +| array_flow.rb:1167:9:1167:18 | call to shift [element 0] | array_flow.rb:1167:5:1167:5 | b [element 0] | +| array_flow.rb:1167:9:1167:18 | call to shift [element 0] | array_flow.rb:1167:5:1167:5 | b [element 0] | +| array_flow.rb:1168:10:1168:10 | b [element 0] | array_flow.rb:1168:10:1168:13 | ...[...] | +| array_flow.rb:1168:10:1168:10 | b [element 0] | array_flow.rb:1168:10:1168:13 | ...[...] | +| array_flow.rb:1170:10:1170:10 | a [element 0] | array_flow.rb:1170:10:1170:13 | ...[...] | +| array_flow.rb:1170:10:1170:10 | a [element 0] | array_flow.rb:1170:10:1170:13 | ...[...] | +| array_flow.rb:1174:5:1174:5 | a [element 0] | array_flow.rb:1175:9:1175:9 | a [element 0] | +| array_flow.rb:1174:5:1174:5 | a [element 0] | array_flow.rb:1175:9:1175:9 | a [element 0] | +| array_flow.rb:1174:5:1174:5 | a [element 0] | array_flow.rb:1178:10:1178:10 | a [element 0] | +| array_flow.rb:1174:5:1174:5 | a [element 0] | array_flow.rb:1178:10:1178:10 | a [element 0] | +| array_flow.rb:1174:5:1174:5 | a [element 2] | array_flow.rb:1175:9:1175:9 | a [element 2] | +| array_flow.rb:1174:5:1174:5 | a [element 2] | array_flow.rb:1175:9:1175:9 | a [element 2] | +| array_flow.rb:1174:5:1174:5 | a [element 2] | array_flow.rb:1180:10:1180:10 | a [element 2] | +| array_flow.rb:1174:5:1174:5 | a [element 2] | array_flow.rb:1180:10:1180:10 | a [element 2] | +| array_flow.rb:1174:10:1174:22 | call to source | array_flow.rb:1174:5:1174:5 | a [element 0] | +| array_flow.rb:1174:10:1174:22 | call to source | array_flow.rb:1174:5:1174:5 | a [element 0] | +| array_flow.rb:1174:28:1174:40 | call to source | array_flow.rb:1174:5:1174:5 | a [element 2] | +| array_flow.rb:1174:28:1174:40 | call to source | array_flow.rb:1174:5:1174:5 | a [element 2] | +| array_flow.rb:1175:5:1175:5 | b [element] | array_flow.rb:1176:10:1176:10 | b [element] | +| array_flow.rb:1175:5:1175:5 | b [element] | array_flow.rb:1176:10:1176:10 | b [element] | +| array_flow.rb:1175:5:1175:5 | b [element] | array_flow.rb:1177:10:1177:10 | b [element] | +| array_flow.rb:1175:5:1175:5 | b [element] | array_flow.rb:1177:10:1177:10 | b [element] | +| array_flow.rb:1175:9:1175:9 | [post] a [element] | array_flow.rb:1178:10:1178:10 | a [element] | +| array_flow.rb:1175:9:1175:9 | [post] a [element] | array_flow.rb:1178:10:1178:10 | a [element] | +| array_flow.rb:1175:9:1175:9 | [post] a [element] | array_flow.rb:1179:10:1179:10 | a [element] | +| array_flow.rb:1175:9:1175:9 | [post] a [element] | array_flow.rb:1179:10:1179:10 | a [element] | +| array_flow.rb:1175:9:1175:9 | [post] a [element] | array_flow.rb:1180:10:1180:10 | a [element] | +| array_flow.rb:1175:9:1175:9 | [post] a [element] | array_flow.rb:1180:10:1180:10 | a [element] | +| array_flow.rb:1175:9:1175:9 | a [element 0] | array_flow.rb:1175:9:1175:9 | [post] a [element] | +| array_flow.rb:1175:9:1175:9 | a [element 0] | array_flow.rb:1175:9:1175:9 | [post] a [element] | +| array_flow.rb:1175:9:1175:9 | a [element 0] | array_flow.rb:1175:9:1175:18 | call to shift [element] | +| array_flow.rb:1175:9:1175:9 | a [element 0] | array_flow.rb:1175:9:1175:18 | call to shift [element] | +| array_flow.rb:1175:9:1175:9 | a [element 2] | array_flow.rb:1175:9:1175:9 | [post] a [element] | +| array_flow.rb:1175:9:1175:9 | a [element 2] | array_flow.rb:1175:9:1175:9 | [post] a [element] | +| array_flow.rb:1175:9:1175:9 | a [element 2] | array_flow.rb:1175:9:1175:18 | call to shift [element] | +| array_flow.rb:1175:9:1175:9 | a [element 2] | array_flow.rb:1175:9:1175:18 | call to shift [element] | +| array_flow.rb:1175:9:1175:18 | call to shift [element] | array_flow.rb:1175:5:1175:5 | b [element] | +| array_flow.rb:1175:9:1175:18 | call to shift [element] | array_flow.rb:1175:5:1175:5 | b [element] | +| array_flow.rb:1176:10:1176:10 | b [element] | array_flow.rb:1176:10:1176:13 | ...[...] | +| array_flow.rb:1176:10:1176:10 | b [element] | array_flow.rb:1176:10:1176:13 | ...[...] | +| array_flow.rb:1177:10:1177:10 | b [element] | array_flow.rb:1177:10:1177:13 | ...[...] | +| array_flow.rb:1177:10:1177:10 | b [element] | array_flow.rb:1177:10:1177:13 | ...[...] | +| array_flow.rb:1178:10:1178:10 | a [element 0] | array_flow.rb:1178:10:1178:13 | ...[...] | +| array_flow.rb:1178:10:1178:10 | a [element 0] | array_flow.rb:1178:10:1178:13 | ...[...] | +| array_flow.rb:1178:10:1178:10 | a [element] | array_flow.rb:1178:10:1178:13 | ...[...] | +| array_flow.rb:1178:10:1178:10 | a [element] | array_flow.rb:1178:10:1178:13 | ...[...] | +| array_flow.rb:1179:10:1179:10 | a [element] | array_flow.rb:1179:10:1179:13 | ...[...] | +| array_flow.rb:1179:10:1179:10 | a [element] | array_flow.rb:1179:10:1179:13 | ...[...] | +| array_flow.rb:1180:10:1180:10 | a [element 2] | array_flow.rb:1180:10:1180:13 | ...[...] | +| array_flow.rb:1180:10:1180:10 | a [element 2] | array_flow.rb:1180:10:1180:13 | ...[...] | +| array_flow.rb:1180:10:1180:10 | a [element] | array_flow.rb:1180:10:1180:13 | ...[...] | +| array_flow.rb:1180:10:1180:10 | a [element] | array_flow.rb:1180:10:1180:13 | ...[...] | | array_flow.rb:1184:5:1184:5 | a [element 2] | array_flow.rb:1185:9:1185:9 | a [element 2] | | array_flow.rb:1184:5:1184:5 | a [element 2] | array_flow.rb:1185:9:1185:9 | a [element 2] | | array_flow.rb:1184:5:1184:5 | a [element 2] | array_flow.rb:1188:10:1188:10 | a [element 2] | @@ -2942,274 +2926,250 @@ edges | array_flow.rb:1185:5:1185:5 | b [element] | array_flow.rb:1190:10:1190:10 | b [element] | | array_flow.rb:1185:5:1185:5 | b [element] | array_flow.rb:1191:10:1191:10 | b [element] | | array_flow.rb:1185:5:1185:5 | b [element] | array_flow.rb:1191:10:1191:10 | b [element] | -| array_flow.rb:1185:9:1185:9 | [post] a [element] | array_flow.rb:1186:10:1186:10 | a [element] | -| array_flow.rb:1185:9:1185:9 | [post] a [element] | array_flow.rb:1186:10:1186:10 | a [element] | -| array_flow.rb:1185:9:1185:9 | [post] a [element] | array_flow.rb:1187:10:1187:10 | a [element] | -| array_flow.rb:1185:9:1185:9 | [post] a [element] | array_flow.rb:1187:10:1187:10 | a [element] | -| array_flow.rb:1185:9:1185:9 | [post] a [element] | array_flow.rb:1188:10:1188:10 | a [element] | -| array_flow.rb:1185:9:1185:9 | [post] a [element] | array_flow.rb:1188:10:1188:10 | a [element] | -| array_flow.rb:1185:9:1185:9 | a [element 2] | array_flow.rb:1185:9:1185:9 | [post] a [element] | -| array_flow.rb:1185:9:1185:9 | a [element 2] | array_flow.rb:1185:9:1185:9 | [post] a [element] | -| array_flow.rb:1185:9:1185:9 | a [element 2] | array_flow.rb:1185:9:1185:18 | call to shuffle! [element] | -| array_flow.rb:1185:9:1185:9 | a [element 2] | array_flow.rb:1185:9:1185:18 | call to shuffle! [element] | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] | array_flow.rb:1185:5:1185:5 | b [element] | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] | array_flow.rb:1185:5:1185:5 | b [element] | -| array_flow.rb:1186:10:1186:10 | a [element] | array_flow.rb:1186:10:1186:13 | ...[...] | -| array_flow.rb:1186:10:1186:10 | a [element] | array_flow.rb:1186:10:1186:13 | ...[...] | -| array_flow.rb:1187:10:1187:10 | a [element] | array_flow.rb:1187:10:1187:13 | ...[...] | -| array_flow.rb:1187:10:1187:10 | a [element] | array_flow.rb:1187:10:1187:13 | ...[...] | +| array_flow.rb:1185:9:1185:9 | a [element 2] | array_flow.rb:1185:9:1185:17 | call to shuffle [element] | +| array_flow.rb:1185:9:1185:9 | a [element 2] | array_flow.rb:1185:9:1185:17 | call to shuffle [element] | +| array_flow.rb:1185:9:1185:17 | call to shuffle [element] | array_flow.rb:1185:5:1185:5 | b [element] | +| array_flow.rb:1185:9:1185:17 | call to shuffle [element] | array_flow.rb:1185:5:1185:5 | b [element] | | array_flow.rb:1188:10:1188:10 | a [element 2] | array_flow.rb:1188:10:1188:13 | ...[...] | | array_flow.rb:1188:10:1188:10 | a [element 2] | array_flow.rb:1188:10:1188:13 | ...[...] | -| array_flow.rb:1188:10:1188:10 | a [element] | array_flow.rb:1188:10:1188:13 | ...[...] | -| array_flow.rb:1188:10:1188:10 | a [element] | array_flow.rb:1188:10:1188:13 | ...[...] | | array_flow.rb:1189:10:1189:10 | b [element] | array_flow.rb:1189:10:1189:13 | ...[...] | | array_flow.rb:1189:10:1189:10 | b [element] | array_flow.rb:1189:10:1189:13 | ...[...] | | array_flow.rb:1190:10:1190:10 | b [element] | array_flow.rb:1190:10:1190:13 | ...[...] | | array_flow.rb:1190:10:1190:10 | b [element] | array_flow.rb:1190:10:1190:13 | ...[...] | | array_flow.rb:1191:10:1191:10 | b [element] | array_flow.rb:1191:10:1191:13 | ...[...] | | array_flow.rb:1191:10:1191:10 | b [element] | array_flow.rb:1191:10:1191:13 | ...[...] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1200:9:1200:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1200:9:1200:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1203:9:1203:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1203:9:1203:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1209:9:1209:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1209:9:1209:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1214:9:1214:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1214:9:1214:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1218:9:1218:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1218:9:1218:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1223:9:1223:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1223:9:1223:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1228:9:1228:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1228:9:1228:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1232:9:1232:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1232:9:1232:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1236:9:1236:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1236:9:1236:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1241:9:1241:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1241:9:1241:9 | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1197:9:1197:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1197:9:1197:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1200:9:1200:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1200:9:1200:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1203:9:1203:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1203:9:1203:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1209:9:1209:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1209:9:1209:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1214:9:1214:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1214:9:1214:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1228:9:1228:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1228:9:1228:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1232:9:1232:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1232:9:1232:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1241:9:1241:9 | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | array_flow.rb:1241:9:1241:9 | a [element 4] | -| array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1195:5:1195:5 | a [element 2] | -| array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1195:5:1195:5 | a [element 2] | -| array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1195:5:1195:5 | a [element 4] | -| array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1195:5:1195:5 | a [element 4] | -| array_flow.rb:1197:5:1197:5 | b | array_flow.rb:1198:10:1198:10 | b | -| array_flow.rb:1197:5:1197:5 | b | array_flow.rb:1198:10:1198:10 | b | -| array_flow.rb:1197:9:1197:9 | a [element 4] | array_flow.rb:1197:9:1197:17 | call to slice | -| array_flow.rb:1197:9:1197:9 | a [element 4] | array_flow.rb:1197:9:1197:17 | call to slice | -| array_flow.rb:1197:9:1197:17 | call to slice | array_flow.rb:1197:5:1197:5 | b | -| array_flow.rb:1197:9:1197:17 | call to slice | array_flow.rb:1197:5:1197:5 | b | -| array_flow.rb:1200:5:1200:5 | b | array_flow.rb:1201:10:1201:10 | b | -| array_flow.rb:1200:5:1200:5 | b | array_flow.rb:1201:10:1201:10 | b | -| array_flow.rb:1200:9:1200:9 | a [element 2] | array_flow.rb:1200:9:1200:19 | call to slice | -| array_flow.rb:1200:9:1200:9 | a [element 2] | array_flow.rb:1200:9:1200:19 | call to slice | -| array_flow.rb:1200:9:1200:9 | a [element 4] | array_flow.rb:1200:9:1200:19 | call to slice | -| array_flow.rb:1200:9:1200:9 | a [element 4] | array_flow.rb:1200:9:1200:19 | call to slice | -| array_flow.rb:1200:9:1200:19 | call to slice | array_flow.rb:1200:5:1200:5 | b | -| array_flow.rb:1200:9:1200:19 | call to slice | array_flow.rb:1200:5:1200:5 | b | -| array_flow.rb:1203:5:1203:5 | b | array_flow.rb:1205:10:1205:10 | b | -| array_flow.rb:1203:5:1203:5 | b | array_flow.rb:1205:10:1205:10 | b | -| array_flow.rb:1203:5:1203:5 | b | array_flow.rb:1207:10:1207:10 | b | -| array_flow.rb:1203:5:1203:5 | b [element] | array_flow.rb:1207:10:1207:10 | b [element] | -| array_flow.rb:1203:5:1203:5 | b [element] | array_flow.rb:1207:10:1207:10 | b [element] | -| array_flow.rb:1203:9:1203:9 | a [element 2] | array_flow.rb:1203:9:1203:17 | call to slice | -| array_flow.rb:1203:9:1203:9 | a [element 2] | array_flow.rb:1203:9:1203:17 | call to slice | -| array_flow.rb:1203:9:1203:9 | a [element 2] | array_flow.rb:1203:9:1203:17 | call to slice [element] | -| array_flow.rb:1203:9:1203:9 | a [element 2] | array_flow.rb:1203:9:1203:17 | call to slice [element] | -| array_flow.rb:1203:9:1203:9 | a [element 4] | array_flow.rb:1203:9:1203:17 | call to slice | -| array_flow.rb:1203:9:1203:9 | a [element 4] | array_flow.rb:1203:9:1203:17 | call to slice | -| array_flow.rb:1203:9:1203:9 | a [element 4] | array_flow.rb:1203:9:1203:17 | call to slice [element] | -| array_flow.rb:1203:9:1203:9 | a [element 4] | array_flow.rb:1203:9:1203:17 | call to slice [element] | -| array_flow.rb:1203:9:1203:17 | call to slice | array_flow.rb:1203:5:1203:5 | b | -| array_flow.rb:1203:9:1203:17 | call to slice | array_flow.rb:1203:5:1203:5 | b | -| array_flow.rb:1203:9:1203:17 | call to slice [element] | array_flow.rb:1203:5:1203:5 | b [element] | -| array_flow.rb:1203:9:1203:17 | call to slice [element] | array_flow.rb:1203:5:1203:5 | b [element] | -| array_flow.rb:1207:10:1207:10 | b | array_flow.rb:1207:10:1207:13 | ...[...] | -| array_flow.rb:1207:10:1207:10 | b [element] | array_flow.rb:1207:10:1207:13 | ...[...] | -| array_flow.rb:1207:10:1207:10 | b [element] | array_flow.rb:1207:10:1207:13 | ...[...] | -| array_flow.rb:1209:5:1209:5 | b [element 0] | array_flow.rb:1210:10:1210:10 | b [element 0] | -| array_flow.rb:1209:5:1209:5 | b [element 0] | array_flow.rb:1210:10:1210:10 | b [element 0] | -| array_flow.rb:1209:5:1209:5 | b [element 2] | array_flow.rb:1212:10:1212:10 | b [element 2] | -| array_flow.rb:1209:5:1209:5 | b [element 2] | array_flow.rb:1212:10:1212:10 | b [element 2] | -| array_flow.rb:1209:9:1209:9 | a [element 2] | array_flow.rb:1209:9:1209:21 | call to slice [element 0] | -| array_flow.rb:1209:9:1209:9 | a [element 2] | array_flow.rb:1209:9:1209:21 | call to slice [element 0] | -| array_flow.rb:1209:9:1209:9 | a [element 4] | array_flow.rb:1209:9:1209:21 | call to slice [element 2] | -| array_flow.rb:1209:9:1209:9 | a [element 4] | array_flow.rb:1209:9:1209:21 | call to slice [element 2] | -| array_flow.rb:1209:9:1209:21 | call to slice [element 0] | array_flow.rb:1209:5:1209:5 | b [element 0] | -| array_flow.rb:1209:9:1209:21 | call to slice [element 0] | array_flow.rb:1209:5:1209:5 | b [element 0] | -| array_flow.rb:1209:9:1209:21 | call to slice [element 2] | array_flow.rb:1209:5:1209:5 | b [element 2] | -| array_flow.rb:1209:9:1209:21 | call to slice [element 2] | array_flow.rb:1209:5:1209:5 | b [element 2] | -| array_flow.rb:1210:10:1210:10 | b [element 0] | array_flow.rb:1210:10:1210:13 | ...[...] | -| array_flow.rb:1210:10:1210:10 | b [element 0] | array_flow.rb:1210:10:1210:13 | ...[...] | -| array_flow.rb:1212:10:1212:10 | b [element 2] | array_flow.rb:1212:10:1212:13 | ...[...] | -| array_flow.rb:1212:10:1212:10 | b [element 2] | array_flow.rb:1212:10:1212:13 | ...[...] | -| array_flow.rb:1214:5:1214:5 | b [element] | array_flow.rb:1215:10:1215:10 | b [element] | -| array_flow.rb:1214:5:1214:5 | b [element] | array_flow.rb:1215:10:1215:10 | b [element] | -| array_flow.rb:1214:5:1214:5 | b [element] | array_flow.rb:1216:10:1216:10 | b [element] | -| array_flow.rb:1214:5:1214:5 | b [element] | array_flow.rb:1216:10:1216:10 | b [element] | -| array_flow.rb:1214:9:1214:9 | a [element 2] | array_flow.rb:1214:9:1214:21 | call to slice [element] | -| array_flow.rb:1214:9:1214:9 | a [element 2] | array_flow.rb:1214:9:1214:21 | call to slice [element] | -| array_flow.rb:1214:9:1214:9 | a [element 4] | array_flow.rb:1214:9:1214:21 | call to slice [element] | -| array_flow.rb:1214:9:1214:9 | a [element 4] | array_flow.rb:1214:9:1214:21 | call to slice [element] | -| array_flow.rb:1214:9:1214:21 | call to slice [element] | array_flow.rb:1214:5:1214:5 | b [element] | -| array_flow.rb:1214:9:1214:21 | call to slice [element] | array_flow.rb:1214:5:1214:5 | b [element] | -| array_flow.rb:1215:10:1215:10 | b [element] | array_flow.rb:1215:10:1215:13 | ...[...] | -| array_flow.rb:1215:10:1215:10 | b [element] | array_flow.rb:1215:10:1215:13 | ...[...] | -| array_flow.rb:1216:10:1216:10 | b [element] | array_flow.rb:1216:10:1216:13 | ...[...] | -| array_flow.rb:1216:10:1216:10 | b [element] | array_flow.rb:1216:10:1216:13 | ...[...] | -| array_flow.rb:1218:5:1218:5 | b [element 0] | array_flow.rb:1219:10:1219:10 | b [element 0] | -| array_flow.rb:1218:5:1218:5 | b [element 0] | array_flow.rb:1219:10:1219:10 | b [element 0] | -| array_flow.rb:1218:9:1218:9 | a [element 2] | array_flow.rb:1218:9:1218:21 | call to slice [element 0] | -| array_flow.rb:1218:9:1218:9 | a [element 2] | array_flow.rb:1218:9:1218:21 | call to slice [element 0] | -| array_flow.rb:1218:9:1218:21 | call to slice [element 0] | array_flow.rb:1218:5:1218:5 | b [element 0] | -| array_flow.rb:1218:9:1218:21 | call to slice [element 0] | array_flow.rb:1218:5:1218:5 | b [element 0] | -| array_flow.rb:1219:10:1219:10 | b [element 0] | array_flow.rb:1219:10:1219:13 | ...[...] | -| array_flow.rb:1219:10:1219:10 | b [element 0] | array_flow.rb:1219:10:1219:13 | ...[...] | -| array_flow.rb:1223:5:1223:5 | b [element 0] | array_flow.rb:1224:10:1224:10 | b [element 0] | -| array_flow.rb:1223:5:1223:5 | b [element 0] | array_flow.rb:1224:10:1224:10 | b [element 0] | -| array_flow.rb:1223:9:1223:9 | a [element 2] | array_flow.rb:1223:9:1223:22 | call to slice [element 0] | -| array_flow.rb:1223:9:1223:9 | a [element 2] | array_flow.rb:1223:9:1223:22 | call to slice [element 0] | -| array_flow.rb:1223:9:1223:22 | call to slice [element 0] | array_flow.rb:1223:5:1223:5 | b [element 0] | -| array_flow.rb:1223:9:1223:22 | call to slice [element 0] | array_flow.rb:1223:5:1223:5 | b [element 0] | -| array_flow.rb:1224:10:1224:10 | b [element 0] | array_flow.rb:1224:10:1224:13 | ...[...] | -| array_flow.rb:1224:10:1224:10 | b [element 0] | array_flow.rb:1224:10:1224:13 | ...[...] | -| array_flow.rb:1228:5:1228:5 | b [element] | array_flow.rb:1229:10:1229:10 | b [element] | -| array_flow.rb:1228:5:1228:5 | b [element] | array_flow.rb:1229:10:1229:10 | b [element] | -| array_flow.rb:1228:5:1228:5 | b [element] | array_flow.rb:1230:10:1230:10 | b [element] | -| array_flow.rb:1228:5:1228:5 | b [element] | array_flow.rb:1230:10:1230:10 | b [element] | -| array_flow.rb:1228:9:1228:9 | a [element 2] | array_flow.rb:1228:9:1228:21 | call to slice [element] | -| array_flow.rb:1228:9:1228:9 | a [element 2] | array_flow.rb:1228:9:1228:21 | call to slice [element] | -| array_flow.rb:1228:9:1228:9 | a [element 4] | array_flow.rb:1228:9:1228:21 | call to slice [element] | -| array_flow.rb:1228:9:1228:9 | a [element 4] | array_flow.rb:1228:9:1228:21 | call to slice [element] | -| array_flow.rb:1228:9:1228:21 | call to slice [element] | array_flow.rb:1228:5:1228:5 | b [element] | -| array_flow.rb:1228:9:1228:21 | call to slice [element] | array_flow.rb:1228:5:1228:5 | b [element] | -| array_flow.rb:1229:10:1229:10 | b [element] | array_flow.rb:1229:10:1229:13 | ...[...] | -| array_flow.rb:1229:10:1229:10 | b [element] | array_flow.rb:1229:10:1229:13 | ...[...] | -| array_flow.rb:1230:10:1230:10 | b [element] | array_flow.rb:1230:10:1230:13 | ...[...] | -| array_flow.rb:1230:10:1230:10 | b [element] | array_flow.rb:1230:10:1230:13 | ...[...] | -| array_flow.rb:1232:5:1232:5 | b [element] | array_flow.rb:1233:10:1233:10 | b [element] | -| array_flow.rb:1232:5:1232:5 | b [element] | array_flow.rb:1233:10:1233:10 | b [element] | -| array_flow.rb:1232:5:1232:5 | b [element] | array_flow.rb:1234:10:1234:10 | b [element] | -| array_flow.rb:1232:5:1232:5 | b [element] | array_flow.rb:1234:10:1234:10 | b [element] | -| array_flow.rb:1232:9:1232:9 | a [element 2] | array_flow.rb:1232:9:1232:24 | call to slice [element] | -| array_flow.rb:1232:9:1232:9 | a [element 2] | array_flow.rb:1232:9:1232:24 | call to slice [element] | -| array_flow.rb:1232:9:1232:9 | a [element 4] | array_flow.rb:1232:9:1232:24 | call to slice [element] | -| array_flow.rb:1232:9:1232:9 | a [element 4] | array_flow.rb:1232:9:1232:24 | call to slice [element] | -| array_flow.rb:1232:9:1232:24 | call to slice [element] | array_flow.rb:1232:5:1232:5 | b [element] | -| array_flow.rb:1232:9:1232:24 | call to slice [element] | array_flow.rb:1232:5:1232:5 | b [element] | -| array_flow.rb:1233:10:1233:10 | b [element] | array_flow.rb:1233:10:1233:13 | ...[...] | -| array_flow.rb:1233:10:1233:10 | b [element] | array_flow.rb:1233:10:1233:13 | ...[...] | -| array_flow.rb:1234:10:1234:10 | b [element] | array_flow.rb:1234:10:1234:13 | ...[...] | -| array_flow.rb:1234:10:1234:10 | b [element] | array_flow.rb:1234:10:1234:13 | ...[...] | -| array_flow.rb:1236:5:1236:5 | b [element 2] | array_flow.rb:1239:10:1239:10 | b [element 2] | -| array_flow.rb:1236:5:1236:5 | b [element 2] | array_flow.rb:1239:10:1239:10 | b [element 2] | -| array_flow.rb:1236:9:1236:9 | a [element 2] | array_flow.rb:1236:9:1236:20 | call to slice [element 2] | -| array_flow.rb:1236:9:1236:9 | a [element 2] | array_flow.rb:1236:9:1236:20 | call to slice [element 2] | -| array_flow.rb:1236:9:1236:20 | call to slice [element 2] | array_flow.rb:1236:5:1236:5 | b [element 2] | -| array_flow.rb:1236:9:1236:20 | call to slice [element 2] | array_flow.rb:1236:5:1236:5 | b [element 2] | -| array_flow.rb:1239:10:1239:10 | b [element 2] | array_flow.rb:1239:10:1239:13 | ...[...] | -| array_flow.rb:1239:10:1239:10 | b [element 2] | array_flow.rb:1239:10:1239:13 | ...[...] | -| array_flow.rb:1241:5:1241:5 | b [element] | array_flow.rb:1242:10:1242:10 | b [element] | -| array_flow.rb:1241:5:1241:5 | b [element] | array_flow.rb:1242:10:1242:10 | b [element] | -| array_flow.rb:1241:5:1241:5 | b [element] | array_flow.rb:1243:10:1243:10 | b [element] | -| array_flow.rb:1241:5:1241:5 | b [element] | array_flow.rb:1243:10:1243:10 | b [element] | -| array_flow.rb:1241:5:1241:5 | b [element] | array_flow.rb:1244:10:1244:10 | b [element] | -| array_flow.rb:1241:5:1241:5 | b [element] | array_flow.rb:1244:10:1244:10 | b [element] | -| array_flow.rb:1241:9:1241:9 | a [element 2] | array_flow.rb:1241:9:1241:20 | call to slice [element] | -| array_flow.rb:1241:9:1241:9 | a [element 2] | array_flow.rb:1241:9:1241:20 | call to slice [element] | -| array_flow.rb:1241:9:1241:9 | a [element 4] | array_flow.rb:1241:9:1241:20 | call to slice [element] | -| array_flow.rb:1241:9:1241:9 | a [element 4] | array_flow.rb:1241:9:1241:20 | call to slice [element] | -| array_flow.rb:1241:9:1241:20 | call to slice [element] | array_flow.rb:1241:5:1241:5 | b [element] | -| array_flow.rb:1241:9:1241:20 | call to slice [element] | array_flow.rb:1241:5:1241:5 | b [element] | -| array_flow.rb:1242:10:1242:10 | b [element] | array_flow.rb:1242:10:1242:13 | ...[...] | -| array_flow.rb:1242:10:1242:10 | b [element] | array_flow.rb:1242:10:1242:13 | ...[...] | -| array_flow.rb:1243:10:1243:10 | b [element] | array_flow.rb:1243:10:1243:13 | ...[...] | -| array_flow.rb:1243:10:1243:10 | b [element] | array_flow.rb:1243:10:1243:13 | ...[...] | +| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1196:9:1196:9 | a [element 2] | +| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1196:9:1196:9 | a [element 2] | +| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1199:10:1199:10 | a [element 2] | +| array_flow.rb:1195:5:1195:5 | a [element 2] | array_flow.rb:1199:10:1199:10 | a [element 2] | +| array_flow.rb:1195:16:1195:26 | call to source | array_flow.rb:1195:5:1195:5 | a [element 2] | +| array_flow.rb:1195:16:1195:26 | call to source | array_flow.rb:1195:5:1195:5 | a [element 2] | +| array_flow.rb:1196:5:1196:5 | b [element] | array_flow.rb:1200:10:1200:10 | b [element] | +| array_flow.rb:1196:5:1196:5 | b [element] | array_flow.rb:1200:10:1200:10 | b [element] | +| array_flow.rb:1196:5:1196:5 | b [element] | array_flow.rb:1201:10:1201:10 | b [element] | +| array_flow.rb:1196:5:1196:5 | b [element] | array_flow.rb:1201:10:1201:10 | b [element] | +| array_flow.rb:1196:5:1196:5 | b [element] | array_flow.rb:1202:10:1202:10 | b [element] | +| array_flow.rb:1196:5:1196:5 | b [element] | array_flow.rb:1202:10:1202:10 | b [element] | +| array_flow.rb:1196:9:1196:9 | [post] a [element] | array_flow.rb:1197:10:1197:10 | a [element] | +| array_flow.rb:1196:9:1196:9 | [post] a [element] | array_flow.rb:1197:10:1197:10 | a [element] | +| array_flow.rb:1196:9:1196:9 | [post] a [element] | array_flow.rb:1198:10:1198:10 | a [element] | +| array_flow.rb:1196:9:1196:9 | [post] a [element] | array_flow.rb:1198:10:1198:10 | a [element] | +| array_flow.rb:1196:9:1196:9 | [post] a [element] | array_flow.rb:1199:10:1199:10 | a [element] | +| array_flow.rb:1196:9:1196:9 | [post] a [element] | array_flow.rb:1199:10:1199:10 | a [element] | +| array_flow.rb:1196:9:1196:9 | a [element 2] | array_flow.rb:1196:9:1196:9 | [post] a [element] | +| array_flow.rb:1196:9:1196:9 | a [element 2] | array_flow.rb:1196:9:1196:9 | [post] a [element] | +| array_flow.rb:1196:9:1196:9 | a [element 2] | array_flow.rb:1196:9:1196:18 | call to shuffle! [element] | +| array_flow.rb:1196:9:1196:9 | a [element 2] | array_flow.rb:1196:9:1196:18 | call to shuffle! [element] | +| array_flow.rb:1196:9:1196:18 | call to shuffle! [element] | array_flow.rb:1196:5:1196:5 | b [element] | +| array_flow.rb:1196:9:1196:18 | call to shuffle! [element] | array_flow.rb:1196:5:1196:5 | b [element] | +| array_flow.rb:1197:10:1197:10 | a [element] | array_flow.rb:1197:10:1197:13 | ...[...] | +| array_flow.rb:1197:10:1197:10 | a [element] | array_flow.rb:1197:10:1197:13 | ...[...] | +| array_flow.rb:1198:10:1198:10 | a [element] | array_flow.rb:1198:10:1198:13 | ...[...] | +| array_flow.rb:1198:10:1198:10 | a [element] | array_flow.rb:1198:10:1198:13 | ...[...] | +| array_flow.rb:1199:10:1199:10 | a [element 2] | array_flow.rb:1199:10:1199:13 | ...[...] | +| array_flow.rb:1199:10:1199:10 | a [element 2] | array_flow.rb:1199:10:1199:13 | ...[...] | +| array_flow.rb:1199:10:1199:10 | a [element] | array_flow.rb:1199:10:1199:13 | ...[...] | +| array_flow.rb:1199:10:1199:10 | a [element] | array_flow.rb:1199:10:1199:13 | ...[...] | +| array_flow.rb:1200:10:1200:10 | b [element] | array_flow.rb:1200:10:1200:13 | ...[...] | +| array_flow.rb:1200:10:1200:10 | b [element] | array_flow.rb:1200:10:1200:13 | ...[...] | +| array_flow.rb:1201:10:1201:10 | b [element] | array_flow.rb:1201:10:1201:13 | ...[...] | +| array_flow.rb:1201:10:1201:10 | b [element] | array_flow.rb:1201:10:1201:13 | ...[...] | +| array_flow.rb:1202:10:1202:10 | b [element] | array_flow.rb:1202:10:1202:13 | ...[...] | +| array_flow.rb:1202:10:1202:10 | b [element] | array_flow.rb:1202:10:1202:13 | ...[...] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1211:9:1211:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1211:9:1211:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1214:9:1214:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1214:9:1214:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1220:9:1220:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1220:9:1220:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1225:9:1225:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1225:9:1225:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1229:9:1229:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1229:9:1229:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1234:9:1234:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1234:9:1234:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1239:9:1239:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1239:9:1239:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1243:9:1243:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1243:9:1243:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1247:9:1247:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1247:9:1247:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1252:9:1252:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | array_flow.rb:1252:9:1252:9 | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1208:9:1208:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1208:9:1208:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1211:9:1211:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1211:9:1211:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1214:9:1214:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1214:9:1214:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1220:9:1220:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1220:9:1220:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1225:9:1225:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1225:9:1225:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1239:9:1239:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1239:9:1239:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1243:9:1243:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1243:9:1243:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1252:9:1252:9 | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | array_flow.rb:1252:9:1252:9 | a [element 4] | +| array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1206:5:1206:5 | a [element 2] | +| array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1206:5:1206:5 | a [element 2] | +| array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1206:5:1206:5 | a [element 4] | +| array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1206:5:1206:5 | a [element 4] | +| array_flow.rb:1208:5:1208:5 | b | array_flow.rb:1209:10:1209:10 | b | +| array_flow.rb:1208:5:1208:5 | b | array_flow.rb:1209:10:1209:10 | b | +| array_flow.rb:1208:9:1208:9 | a [element 4] | array_flow.rb:1208:9:1208:17 | call to slice | +| array_flow.rb:1208:9:1208:9 | a [element 4] | array_flow.rb:1208:9:1208:17 | call to slice | +| array_flow.rb:1208:9:1208:17 | call to slice | array_flow.rb:1208:5:1208:5 | b | +| array_flow.rb:1208:9:1208:17 | call to slice | array_flow.rb:1208:5:1208:5 | b | +| array_flow.rb:1211:5:1211:5 | b | array_flow.rb:1212:10:1212:10 | b | +| array_flow.rb:1211:5:1211:5 | b | array_flow.rb:1212:10:1212:10 | b | +| array_flow.rb:1211:9:1211:9 | a [element 2] | array_flow.rb:1211:9:1211:19 | call to slice | +| array_flow.rb:1211:9:1211:9 | a [element 2] | array_flow.rb:1211:9:1211:19 | call to slice | +| array_flow.rb:1211:9:1211:9 | a [element 4] | array_flow.rb:1211:9:1211:19 | call to slice | +| array_flow.rb:1211:9:1211:9 | a [element 4] | array_flow.rb:1211:9:1211:19 | call to slice | +| array_flow.rb:1211:9:1211:19 | call to slice | array_flow.rb:1211:5:1211:5 | b | +| array_flow.rb:1211:9:1211:19 | call to slice | array_flow.rb:1211:5:1211:5 | b | +| array_flow.rb:1214:5:1214:5 | b | array_flow.rb:1216:10:1216:10 | b | +| array_flow.rb:1214:5:1214:5 | b | array_flow.rb:1216:10:1216:10 | b | +| array_flow.rb:1214:5:1214:5 | b | array_flow.rb:1218:10:1218:10 | b | +| array_flow.rb:1214:5:1214:5 | b [element] | array_flow.rb:1218:10:1218:10 | b [element] | +| array_flow.rb:1214:5:1214:5 | b [element] | array_flow.rb:1218:10:1218:10 | b [element] | +| array_flow.rb:1214:9:1214:9 | a [element 2] | array_flow.rb:1214:9:1214:17 | call to slice | +| array_flow.rb:1214:9:1214:9 | a [element 2] | array_flow.rb:1214:9:1214:17 | call to slice | +| array_flow.rb:1214:9:1214:9 | a [element 2] | array_flow.rb:1214:9:1214:17 | call to slice [element] | +| array_flow.rb:1214:9:1214:9 | a [element 2] | array_flow.rb:1214:9:1214:17 | call to slice [element] | +| array_flow.rb:1214:9:1214:9 | a [element 4] | array_flow.rb:1214:9:1214:17 | call to slice | +| array_flow.rb:1214:9:1214:9 | a [element 4] | array_flow.rb:1214:9:1214:17 | call to slice | +| array_flow.rb:1214:9:1214:9 | a [element 4] | array_flow.rb:1214:9:1214:17 | call to slice [element] | +| array_flow.rb:1214:9:1214:9 | a [element 4] | array_flow.rb:1214:9:1214:17 | call to slice [element] | +| array_flow.rb:1214:9:1214:17 | call to slice | array_flow.rb:1214:5:1214:5 | b | +| array_flow.rb:1214:9:1214:17 | call to slice | array_flow.rb:1214:5:1214:5 | b | +| array_flow.rb:1214:9:1214:17 | call to slice [element] | array_flow.rb:1214:5:1214:5 | b [element] | +| array_flow.rb:1214:9:1214:17 | call to slice [element] | array_flow.rb:1214:5:1214:5 | b [element] | +| array_flow.rb:1218:10:1218:10 | b | array_flow.rb:1218:10:1218:13 | ...[...] | +| array_flow.rb:1218:10:1218:10 | b [element] | array_flow.rb:1218:10:1218:13 | ...[...] | +| array_flow.rb:1218:10:1218:10 | b [element] | array_flow.rb:1218:10:1218:13 | ...[...] | +| array_flow.rb:1220:5:1220:5 | b [element 0] | array_flow.rb:1221:10:1221:10 | b [element 0] | +| array_flow.rb:1220:5:1220:5 | b [element 0] | array_flow.rb:1221:10:1221:10 | b [element 0] | +| array_flow.rb:1220:5:1220:5 | b [element 2] | array_flow.rb:1223:10:1223:10 | b [element 2] | +| array_flow.rb:1220:5:1220:5 | b [element 2] | array_flow.rb:1223:10:1223:10 | b [element 2] | +| array_flow.rb:1220:9:1220:9 | a [element 2] | array_flow.rb:1220:9:1220:21 | call to slice [element 0] | +| array_flow.rb:1220:9:1220:9 | a [element 2] | array_flow.rb:1220:9:1220:21 | call to slice [element 0] | +| array_flow.rb:1220:9:1220:9 | a [element 4] | array_flow.rb:1220:9:1220:21 | call to slice [element 2] | +| array_flow.rb:1220:9:1220:9 | a [element 4] | array_flow.rb:1220:9:1220:21 | call to slice [element 2] | +| array_flow.rb:1220:9:1220:21 | call to slice [element 0] | array_flow.rb:1220:5:1220:5 | b [element 0] | +| array_flow.rb:1220:9:1220:21 | call to slice [element 0] | array_flow.rb:1220:5:1220:5 | b [element 0] | +| array_flow.rb:1220:9:1220:21 | call to slice [element 2] | array_flow.rb:1220:5:1220:5 | b [element 2] | +| array_flow.rb:1220:9:1220:21 | call to slice [element 2] | array_flow.rb:1220:5:1220:5 | b [element 2] | +| array_flow.rb:1221:10:1221:10 | b [element 0] | array_flow.rb:1221:10:1221:13 | ...[...] | +| array_flow.rb:1221:10:1221:10 | b [element 0] | array_flow.rb:1221:10:1221:13 | ...[...] | +| array_flow.rb:1223:10:1223:10 | b [element 2] | array_flow.rb:1223:10:1223:13 | ...[...] | +| array_flow.rb:1223:10:1223:10 | b [element 2] | array_flow.rb:1223:10:1223:13 | ...[...] | +| array_flow.rb:1225:5:1225:5 | b [element] | array_flow.rb:1226:10:1226:10 | b [element] | +| array_flow.rb:1225:5:1225:5 | b [element] | array_flow.rb:1226:10:1226:10 | b [element] | +| array_flow.rb:1225:5:1225:5 | b [element] | array_flow.rb:1227:10:1227:10 | b [element] | +| array_flow.rb:1225:5:1225:5 | b [element] | array_flow.rb:1227:10:1227:10 | b [element] | +| array_flow.rb:1225:9:1225:9 | a [element 2] | array_flow.rb:1225:9:1225:21 | call to slice [element] | +| array_flow.rb:1225:9:1225:9 | a [element 2] | array_flow.rb:1225:9:1225:21 | call to slice [element] | +| array_flow.rb:1225:9:1225:9 | a [element 4] | array_flow.rb:1225:9:1225:21 | call to slice [element] | +| array_flow.rb:1225:9:1225:9 | a [element 4] | array_flow.rb:1225:9:1225:21 | call to slice [element] | +| array_flow.rb:1225:9:1225:21 | call to slice [element] | array_flow.rb:1225:5:1225:5 | b [element] | +| array_flow.rb:1225:9:1225:21 | call to slice [element] | array_flow.rb:1225:5:1225:5 | b [element] | +| array_flow.rb:1226:10:1226:10 | b [element] | array_flow.rb:1226:10:1226:13 | ...[...] | +| array_flow.rb:1226:10:1226:10 | b [element] | array_flow.rb:1226:10:1226:13 | ...[...] | +| array_flow.rb:1227:10:1227:10 | b [element] | array_flow.rb:1227:10:1227:13 | ...[...] | +| array_flow.rb:1227:10:1227:10 | b [element] | array_flow.rb:1227:10:1227:13 | ...[...] | +| array_flow.rb:1229:5:1229:5 | b [element 0] | array_flow.rb:1230:10:1230:10 | b [element 0] | +| array_flow.rb:1229:5:1229:5 | b [element 0] | array_flow.rb:1230:10:1230:10 | b [element 0] | +| array_flow.rb:1229:9:1229:9 | a [element 2] | array_flow.rb:1229:9:1229:21 | call to slice [element 0] | +| array_flow.rb:1229:9:1229:9 | a [element 2] | array_flow.rb:1229:9:1229:21 | call to slice [element 0] | +| array_flow.rb:1229:9:1229:21 | call to slice [element 0] | array_flow.rb:1229:5:1229:5 | b [element 0] | +| array_flow.rb:1229:9:1229:21 | call to slice [element 0] | array_flow.rb:1229:5:1229:5 | b [element 0] | +| array_flow.rb:1230:10:1230:10 | b [element 0] | array_flow.rb:1230:10:1230:13 | ...[...] | +| array_flow.rb:1230:10:1230:10 | b [element 0] | array_flow.rb:1230:10:1230:13 | ...[...] | +| array_flow.rb:1234:5:1234:5 | b [element 0] | array_flow.rb:1235:10:1235:10 | b [element 0] | +| array_flow.rb:1234:5:1234:5 | b [element 0] | array_flow.rb:1235:10:1235:10 | b [element 0] | +| array_flow.rb:1234:9:1234:9 | a [element 2] | array_flow.rb:1234:9:1234:22 | call to slice [element 0] | +| array_flow.rb:1234:9:1234:9 | a [element 2] | array_flow.rb:1234:9:1234:22 | call to slice [element 0] | +| array_flow.rb:1234:9:1234:22 | call to slice [element 0] | array_flow.rb:1234:5:1234:5 | b [element 0] | +| array_flow.rb:1234:9:1234:22 | call to slice [element 0] | array_flow.rb:1234:5:1234:5 | b [element 0] | +| array_flow.rb:1235:10:1235:10 | b [element 0] | array_flow.rb:1235:10:1235:13 | ...[...] | +| array_flow.rb:1235:10:1235:10 | b [element 0] | array_flow.rb:1235:10:1235:13 | ...[...] | +| array_flow.rb:1239:5:1239:5 | b [element] | array_flow.rb:1240:10:1240:10 | b [element] | +| array_flow.rb:1239:5:1239:5 | b [element] | array_flow.rb:1240:10:1240:10 | b [element] | +| array_flow.rb:1239:5:1239:5 | b [element] | array_flow.rb:1241:10:1241:10 | b [element] | +| array_flow.rb:1239:5:1239:5 | b [element] | array_flow.rb:1241:10:1241:10 | b [element] | +| array_flow.rb:1239:9:1239:9 | a [element 2] | array_flow.rb:1239:9:1239:21 | call to slice [element] | +| array_flow.rb:1239:9:1239:9 | a [element 2] | array_flow.rb:1239:9:1239:21 | call to slice [element] | +| array_flow.rb:1239:9:1239:9 | a [element 4] | array_flow.rb:1239:9:1239:21 | call to slice [element] | +| array_flow.rb:1239:9:1239:9 | a [element 4] | array_flow.rb:1239:9:1239:21 | call to slice [element] | +| array_flow.rb:1239:9:1239:21 | call to slice [element] | array_flow.rb:1239:5:1239:5 | b [element] | +| array_flow.rb:1239:9:1239:21 | call to slice [element] | array_flow.rb:1239:5:1239:5 | b [element] | +| array_flow.rb:1240:10:1240:10 | b [element] | array_flow.rb:1240:10:1240:13 | ...[...] | +| array_flow.rb:1240:10:1240:10 | b [element] | array_flow.rb:1240:10:1240:13 | ...[...] | +| array_flow.rb:1241:10:1241:10 | b [element] | array_flow.rb:1241:10:1241:13 | ...[...] | +| array_flow.rb:1241:10:1241:10 | b [element] | array_flow.rb:1241:10:1241:13 | ...[...] | +| array_flow.rb:1243:5:1243:5 | b [element] | array_flow.rb:1244:10:1244:10 | b [element] | +| array_flow.rb:1243:5:1243:5 | b [element] | array_flow.rb:1244:10:1244:10 | b [element] | +| array_flow.rb:1243:5:1243:5 | b [element] | array_flow.rb:1245:10:1245:10 | b [element] | +| array_flow.rb:1243:5:1243:5 | b [element] | array_flow.rb:1245:10:1245:10 | b [element] | +| array_flow.rb:1243:9:1243:9 | a [element 2] | array_flow.rb:1243:9:1243:24 | call to slice [element] | +| array_flow.rb:1243:9:1243:9 | a [element 2] | array_flow.rb:1243:9:1243:24 | call to slice [element] | +| array_flow.rb:1243:9:1243:9 | a [element 4] | array_flow.rb:1243:9:1243:24 | call to slice [element] | +| array_flow.rb:1243:9:1243:9 | a [element 4] | array_flow.rb:1243:9:1243:24 | call to slice [element] | +| array_flow.rb:1243:9:1243:24 | call to slice [element] | array_flow.rb:1243:5:1243:5 | b [element] | +| array_flow.rb:1243:9:1243:24 | call to slice [element] | array_flow.rb:1243:5:1243:5 | b [element] | | array_flow.rb:1244:10:1244:10 | b [element] | array_flow.rb:1244:10:1244:13 | ...[...] | | array_flow.rb:1244:10:1244:10 | b [element] | array_flow.rb:1244:10:1244:13 | ...[...] | -| array_flow.rb:1248:5:1248:5 | a [element 2] | array_flow.rb:1249:9:1249:9 | a [element 2] | -| array_flow.rb:1248:5:1248:5 | a [element 2] | array_flow.rb:1249:9:1249:9 | a [element 2] | -| array_flow.rb:1248:5:1248:5 | a [element 4] | array_flow.rb:1249:9:1249:9 | a [element 4] | -| array_flow.rb:1248:5:1248:5 | a [element 4] | array_flow.rb:1249:9:1249:9 | a [element 4] | -| array_flow.rb:1248:16:1248:28 | call to source | array_flow.rb:1248:5:1248:5 | a [element 2] | -| array_flow.rb:1248:16:1248:28 | call to source | array_flow.rb:1248:5:1248:5 | a [element 2] | -| array_flow.rb:1248:34:1248:46 | call to source | array_flow.rb:1248:5:1248:5 | a [element 4] | -| array_flow.rb:1248:34:1248:46 | call to source | array_flow.rb:1248:5:1248:5 | a [element 4] | -| array_flow.rb:1249:5:1249:5 | b | array_flow.rb:1250:10:1250:10 | b | -| array_flow.rb:1249:5:1249:5 | b | array_flow.rb:1250:10:1250:10 | b | -| array_flow.rb:1249:9:1249:9 | [post] a [element 3] | array_flow.rb:1254:10:1254:10 | a [element 3] | -| array_flow.rb:1249:9:1249:9 | [post] a [element 3] | array_flow.rb:1254:10:1254:10 | a [element 3] | -| array_flow.rb:1249:9:1249:9 | a [element 2] | array_flow.rb:1249:9:1249:19 | call to slice! | -| array_flow.rb:1249:9:1249:9 | a [element 2] | array_flow.rb:1249:9:1249:19 | call to slice! | -| array_flow.rb:1249:9:1249:9 | a [element 4] | array_flow.rb:1249:9:1249:9 | [post] a [element 3] | -| array_flow.rb:1249:9:1249:9 | a [element 4] | array_flow.rb:1249:9:1249:9 | [post] a [element 3] | -| array_flow.rb:1249:9:1249:19 | call to slice! | array_flow.rb:1249:5:1249:5 | b | -| array_flow.rb:1249:9:1249:19 | call to slice! | array_flow.rb:1249:5:1249:5 | b | -| array_flow.rb:1254:10:1254:10 | a [element 3] | array_flow.rb:1254:10:1254:13 | ...[...] | -| array_flow.rb:1254:10:1254:10 | a [element 3] | array_flow.rb:1254:10:1254:13 | ...[...] | -| array_flow.rb:1256:5:1256:5 | a [element 2] | array_flow.rb:1257:9:1257:9 | a [element 2] | -| array_flow.rb:1256:5:1256:5 | a [element 2] | array_flow.rb:1257:9:1257:9 | a [element 2] | -| array_flow.rb:1256:5:1256:5 | a [element 4] | array_flow.rb:1257:9:1257:9 | a [element 4] | -| array_flow.rb:1256:5:1256:5 | a [element 4] | array_flow.rb:1257:9:1257:9 | a [element 4] | -| array_flow.rb:1256:16:1256:28 | call to source | array_flow.rb:1256:5:1256:5 | a [element 2] | -| array_flow.rb:1256:16:1256:28 | call to source | array_flow.rb:1256:5:1256:5 | a [element 2] | -| array_flow.rb:1256:34:1256:46 | call to source | array_flow.rb:1256:5:1256:5 | a [element 4] | -| array_flow.rb:1256:34:1256:46 | call to source | array_flow.rb:1256:5:1256:5 | a [element 4] | -| array_flow.rb:1257:5:1257:5 | b | array_flow.rb:1263:10:1263:10 | b | -| array_flow.rb:1257:5:1257:5 | b | array_flow.rb:1263:10:1263:10 | b | -| array_flow.rb:1257:5:1257:5 | b | array_flow.rb:1265:10:1265:10 | b | -| array_flow.rb:1257:5:1257:5 | b [element] | array_flow.rb:1265:10:1265:10 | b [element] | -| array_flow.rb:1257:5:1257:5 | b [element] | array_flow.rb:1265:10:1265:10 | b [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | array_flow.rb:1258:10:1258:10 | a [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | array_flow.rb:1258:10:1258:10 | a [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | array_flow.rb:1259:10:1259:10 | a [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | array_flow.rb:1259:10:1259:10 | a [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | array_flow.rb:1260:10:1260:10 | a [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | array_flow.rb:1260:10:1260:10 | a [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | array_flow.rb:1261:10:1261:10 | a [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | array_flow.rb:1261:10:1261:10 | a [element] | -| array_flow.rb:1257:9:1257:9 | a [element 2] | array_flow.rb:1257:9:1257:9 | [post] a [element] | -| array_flow.rb:1257:9:1257:9 | a [element 2] | array_flow.rb:1257:9:1257:9 | [post] a [element] | -| array_flow.rb:1257:9:1257:9 | a [element 2] | array_flow.rb:1257:9:1257:19 | call to slice! | -| array_flow.rb:1257:9:1257:9 | a [element 2] | array_flow.rb:1257:9:1257:19 | call to slice! | -| array_flow.rb:1257:9:1257:9 | a [element 2] | array_flow.rb:1257:9:1257:19 | call to slice! [element] | -| array_flow.rb:1257:9:1257:9 | a [element 2] | array_flow.rb:1257:9:1257:19 | call to slice! [element] | -| array_flow.rb:1257:9:1257:9 | a [element 4] | array_flow.rb:1257:9:1257:9 | [post] a [element] | -| array_flow.rb:1257:9:1257:9 | a [element 4] | array_flow.rb:1257:9:1257:9 | [post] a [element] | -| array_flow.rb:1257:9:1257:9 | a [element 4] | array_flow.rb:1257:9:1257:19 | call to slice! | -| array_flow.rb:1257:9:1257:9 | a [element 4] | array_flow.rb:1257:9:1257:19 | call to slice! | -| array_flow.rb:1257:9:1257:9 | a [element 4] | array_flow.rb:1257:9:1257:19 | call to slice! [element] | -| array_flow.rb:1257:9:1257:9 | a [element 4] | array_flow.rb:1257:9:1257:19 | call to slice! [element] | -| array_flow.rb:1257:9:1257:19 | call to slice! | array_flow.rb:1257:5:1257:5 | b | -| array_flow.rb:1257:9:1257:19 | call to slice! | array_flow.rb:1257:5:1257:5 | b | -| array_flow.rb:1257:9:1257:19 | call to slice! [element] | array_flow.rb:1257:5:1257:5 | b [element] | -| array_flow.rb:1257:9:1257:19 | call to slice! [element] | array_flow.rb:1257:5:1257:5 | b [element] | -| array_flow.rb:1258:10:1258:10 | a [element] | array_flow.rb:1258:10:1258:13 | ...[...] | -| array_flow.rb:1258:10:1258:10 | a [element] | array_flow.rb:1258:10:1258:13 | ...[...] | -| array_flow.rb:1259:10:1259:10 | a [element] | array_flow.rb:1259:10:1259:13 | ...[...] | -| array_flow.rb:1259:10:1259:10 | a [element] | array_flow.rb:1259:10:1259:13 | ...[...] | -| array_flow.rb:1260:10:1260:10 | a [element] | array_flow.rb:1260:10:1260:13 | ...[...] | -| array_flow.rb:1260:10:1260:10 | a [element] | array_flow.rb:1260:10:1260:13 | ...[...] | -| array_flow.rb:1261:10:1261:10 | a [element] | array_flow.rb:1261:10:1261:13 | ...[...] | -| array_flow.rb:1261:10:1261:10 | a [element] | array_flow.rb:1261:10:1261:13 | ...[...] | -| array_flow.rb:1265:10:1265:10 | b | array_flow.rb:1265:10:1265:13 | ...[...] | -| array_flow.rb:1265:10:1265:10 | b [element] | array_flow.rb:1265:10:1265:13 | ...[...] | -| array_flow.rb:1265:10:1265:10 | b [element] | array_flow.rb:1265:10:1265:13 | ...[...] | +| array_flow.rb:1245:10:1245:10 | b [element] | array_flow.rb:1245:10:1245:13 | ...[...] | +| array_flow.rb:1245:10:1245:10 | b [element] | array_flow.rb:1245:10:1245:13 | ...[...] | +| array_flow.rb:1247:5:1247:5 | b [element 2] | array_flow.rb:1250:10:1250:10 | b [element 2] | +| array_flow.rb:1247:5:1247:5 | b [element 2] | array_flow.rb:1250:10:1250:10 | b [element 2] | +| array_flow.rb:1247:9:1247:9 | a [element 2] | array_flow.rb:1247:9:1247:20 | call to slice [element 2] | +| array_flow.rb:1247:9:1247:9 | a [element 2] | array_flow.rb:1247:9:1247:20 | call to slice [element 2] | +| array_flow.rb:1247:9:1247:20 | call to slice [element 2] | array_flow.rb:1247:5:1247:5 | b [element 2] | +| array_flow.rb:1247:9:1247:20 | call to slice [element 2] | array_flow.rb:1247:5:1247:5 | b [element 2] | +| array_flow.rb:1250:10:1250:10 | b [element 2] | array_flow.rb:1250:10:1250:13 | ...[...] | +| array_flow.rb:1250:10:1250:10 | b [element 2] | array_flow.rb:1250:10:1250:13 | ...[...] | +| array_flow.rb:1252:5:1252:5 | b [element] | array_flow.rb:1253:10:1253:10 | b [element] | +| array_flow.rb:1252:5:1252:5 | b [element] | array_flow.rb:1253:10:1253:10 | b [element] | +| array_flow.rb:1252:5:1252:5 | b [element] | array_flow.rb:1254:10:1254:10 | b [element] | +| array_flow.rb:1252:5:1252:5 | b [element] | array_flow.rb:1254:10:1254:10 | b [element] | +| array_flow.rb:1252:5:1252:5 | b [element] | array_flow.rb:1255:10:1255:10 | b [element] | +| array_flow.rb:1252:5:1252:5 | b [element] | array_flow.rb:1255:10:1255:10 | b [element] | +| array_flow.rb:1252:9:1252:9 | a [element 2] | array_flow.rb:1252:9:1252:20 | call to slice [element] | +| array_flow.rb:1252:9:1252:9 | a [element 2] | array_flow.rb:1252:9:1252:20 | call to slice [element] | +| array_flow.rb:1252:9:1252:9 | a [element 4] | array_flow.rb:1252:9:1252:20 | call to slice [element] | +| array_flow.rb:1252:9:1252:9 | a [element 4] | array_flow.rb:1252:9:1252:20 | call to slice [element] | +| array_flow.rb:1252:9:1252:20 | call to slice [element] | array_flow.rb:1252:5:1252:5 | b [element] | +| array_flow.rb:1252:9:1252:20 | call to slice [element] | array_flow.rb:1252:5:1252:5 | b [element] | +| array_flow.rb:1253:10:1253:10 | b [element] | array_flow.rb:1253:10:1253:13 | ...[...] | +| array_flow.rb:1253:10:1253:10 | b [element] | array_flow.rb:1253:10:1253:13 | ...[...] | +| array_flow.rb:1254:10:1254:10 | b [element] | array_flow.rb:1254:10:1254:13 | ...[...] | +| array_flow.rb:1254:10:1254:10 | b [element] | array_flow.rb:1254:10:1254:13 | ...[...] | +| array_flow.rb:1255:10:1255:10 | b [element] | array_flow.rb:1255:10:1255:13 | ...[...] | +| array_flow.rb:1255:10:1255:10 | b [element] | array_flow.rb:1255:10:1255:13 | ...[...] | +| array_flow.rb:1259:5:1259:5 | a [element 2] | array_flow.rb:1260:9:1260:9 | a [element 2] | +| array_flow.rb:1259:5:1259:5 | a [element 2] | array_flow.rb:1260:9:1260:9 | a [element 2] | +| array_flow.rb:1259:5:1259:5 | a [element 4] | array_flow.rb:1260:9:1260:9 | a [element 4] | +| array_flow.rb:1259:5:1259:5 | a [element 4] | array_flow.rb:1260:9:1260:9 | a [element 4] | +| array_flow.rb:1259:16:1259:28 | call to source | array_flow.rb:1259:5:1259:5 | a [element 2] | +| array_flow.rb:1259:16:1259:28 | call to source | array_flow.rb:1259:5:1259:5 | a [element 2] | +| array_flow.rb:1259:34:1259:46 | call to source | array_flow.rb:1259:5:1259:5 | a [element 4] | +| array_flow.rb:1259:34:1259:46 | call to source | array_flow.rb:1259:5:1259:5 | a [element 4] | +| array_flow.rb:1260:5:1260:5 | b | array_flow.rb:1261:10:1261:10 | b | +| array_flow.rb:1260:5:1260:5 | b | array_flow.rb:1261:10:1261:10 | b | +| array_flow.rb:1260:9:1260:9 | [post] a [element 3] | array_flow.rb:1265:10:1265:10 | a [element 3] | +| array_flow.rb:1260:9:1260:9 | [post] a [element 3] | array_flow.rb:1265:10:1265:10 | a [element 3] | +| array_flow.rb:1260:9:1260:9 | a [element 2] | array_flow.rb:1260:9:1260:19 | call to slice! | +| array_flow.rb:1260:9:1260:9 | a [element 2] | array_flow.rb:1260:9:1260:19 | call to slice! | +| array_flow.rb:1260:9:1260:9 | a [element 4] | array_flow.rb:1260:9:1260:9 | [post] a [element 3] | +| array_flow.rb:1260:9:1260:9 | a [element 4] | array_flow.rb:1260:9:1260:9 | [post] a [element 3] | +| array_flow.rb:1260:9:1260:19 | call to slice! | array_flow.rb:1260:5:1260:5 | b | +| array_flow.rb:1260:9:1260:19 | call to slice! | array_flow.rb:1260:5:1260:5 | b | +| array_flow.rb:1265:10:1265:10 | a [element 3] | array_flow.rb:1265:10:1265:13 | ...[...] | +| array_flow.rb:1265:10:1265:10 | a [element 3] | array_flow.rb:1265:10:1265:13 | ...[...] | | array_flow.rb:1267:5:1267:5 | a [element 2] | array_flow.rb:1268:9:1268:9 | a [element 2] | | array_flow.rb:1267:5:1267:5 | a [element 2] | array_flow.rb:1268:9:1268:9 | a [element 2] | | array_flow.rb:1267:5:1267:5 | a [element 4] | array_flow.rb:1268:9:1268:9 | a [element 4] | @@ -3218,22 +3178,46 @@ edges | array_flow.rb:1267:16:1267:28 | call to source | array_flow.rb:1267:5:1267:5 | a [element 2] | | array_flow.rb:1267:34:1267:46 | call to source | array_flow.rb:1267:5:1267:5 | a [element 4] | | array_flow.rb:1267:34:1267:46 | call to source | array_flow.rb:1267:5:1267:5 | a [element 4] | -| array_flow.rb:1268:5:1268:5 | b [element 0] | array_flow.rb:1269:10:1269:10 | b [element 0] | -| array_flow.rb:1268:5:1268:5 | b [element 0] | array_flow.rb:1269:10:1269:10 | b [element 0] | -| array_flow.rb:1268:5:1268:5 | b [element 2] | array_flow.rb:1271:10:1271:10 | b [element 2] | -| array_flow.rb:1268:5:1268:5 | b [element 2] | array_flow.rb:1271:10:1271:10 | b [element 2] | -| array_flow.rb:1268:9:1268:9 | a [element 2] | array_flow.rb:1268:9:1268:22 | call to slice! [element 0] | -| array_flow.rb:1268:9:1268:9 | a [element 2] | array_flow.rb:1268:9:1268:22 | call to slice! [element 0] | -| array_flow.rb:1268:9:1268:9 | a [element 4] | array_flow.rb:1268:9:1268:22 | call to slice! [element 2] | -| array_flow.rb:1268:9:1268:9 | a [element 4] | array_flow.rb:1268:9:1268:22 | call to slice! [element 2] | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 0] | array_flow.rb:1268:5:1268:5 | b [element 0] | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 0] | array_flow.rb:1268:5:1268:5 | b [element 0] | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 2] | array_flow.rb:1268:5:1268:5 | b [element 2] | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 2] | array_flow.rb:1268:5:1268:5 | b [element 2] | -| array_flow.rb:1269:10:1269:10 | b [element 0] | array_flow.rb:1269:10:1269:13 | ...[...] | -| array_flow.rb:1269:10:1269:10 | b [element 0] | array_flow.rb:1269:10:1269:13 | ...[...] | -| array_flow.rb:1271:10:1271:10 | b [element 2] | array_flow.rb:1271:10:1271:13 | ...[...] | -| array_flow.rb:1271:10:1271:10 | b [element 2] | array_flow.rb:1271:10:1271:13 | ...[...] | +| array_flow.rb:1268:5:1268:5 | b | array_flow.rb:1274:10:1274:10 | b | +| array_flow.rb:1268:5:1268:5 | b | array_flow.rb:1274:10:1274:10 | b | +| array_flow.rb:1268:5:1268:5 | b | array_flow.rb:1276:10:1276:10 | b | +| array_flow.rb:1268:5:1268:5 | b [element] | array_flow.rb:1276:10:1276:10 | b [element] | +| array_flow.rb:1268:5:1268:5 | b [element] | array_flow.rb:1276:10:1276:10 | b [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | array_flow.rb:1269:10:1269:10 | a [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | array_flow.rb:1269:10:1269:10 | a [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | array_flow.rb:1270:10:1270:10 | a [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | array_flow.rb:1270:10:1270:10 | a [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | array_flow.rb:1271:10:1271:10 | a [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | array_flow.rb:1271:10:1271:10 | a [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | array_flow.rb:1272:10:1272:10 | a [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | array_flow.rb:1272:10:1272:10 | a [element] | +| array_flow.rb:1268:9:1268:9 | a [element 2] | array_flow.rb:1268:9:1268:9 | [post] a [element] | +| array_flow.rb:1268:9:1268:9 | a [element 2] | array_flow.rb:1268:9:1268:9 | [post] a [element] | +| array_flow.rb:1268:9:1268:9 | a [element 2] | array_flow.rb:1268:9:1268:19 | call to slice! | +| array_flow.rb:1268:9:1268:9 | a [element 2] | array_flow.rb:1268:9:1268:19 | call to slice! | +| array_flow.rb:1268:9:1268:9 | a [element 2] | array_flow.rb:1268:9:1268:19 | call to slice! [element] | +| array_flow.rb:1268:9:1268:9 | a [element 2] | array_flow.rb:1268:9:1268:19 | call to slice! [element] | +| array_flow.rb:1268:9:1268:9 | a [element 4] | array_flow.rb:1268:9:1268:9 | [post] a [element] | +| array_flow.rb:1268:9:1268:9 | a [element 4] | array_flow.rb:1268:9:1268:9 | [post] a [element] | +| array_flow.rb:1268:9:1268:9 | a [element 4] | array_flow.rb:1268:9:1268:19 | call to slice! | +| array_flow.rb:1268:9:1268:9 | a [element 4] | array_flow.rb:1268:9:1268:19 | call to slice! | +| array_flow.rb:1268:9:1268:9 | a [element 4] | array_flow.rb:1268:9:1268:19 | call to slice! [element] | +| array_flow.rb:1268:9:1268:9 | a [element 4] | array_flow.rb:1268:9:1268:19 | call to slice! [element] | +| array_flow.rb:1268:9:1268:19 | call to slice! | array_flow.rb:1268:5:1268:5 | b | +| array_flow.rb:1268:9:1268:19 | call to slice! | array_flow.rb:1268:5:1268:5 | b | +| array_flow.rb:1268:9:1268:19 | call to slice! [element] | array_flow.rb:1268:5:1268:5 | b [element] | +| array_flow.rb:1268:9:1268:19 | call to slice! [element] | array_flow.rb:1268:5:1268:5 | b [element] | +| array_flow.rb:1269:10:1269:10 | a [element] | array_flow.rb:1269:10:1269:13 | ...[...] | +| array_flow.rb:1269:10:1269:10 | a [element] | array_flow.rb:1269:10:1269:13 | ...[...] | +| array_flow.rb:1270:10:1270:10 | a [element] | array_flow.rb:1270:10:1270:13 | ...[...] | +| array_flow.rb:1270:10:1270:10 | a [element] | array_flow.rb:1270:10:1270:13 | ...[...] | +| array_flow.rb:1271:10:1271:10 | a [element] | array_flow.rb:1271:10:1271:13 | ...[...] | +| array_flow.rb:1271:10:1271:10 | a [element] | array_flow.rb:1271:10:1271:13 | ...[...] | +| array_flow.rb:1272:10:1272:10 | a [element] | array_flow.rb:1272:10:1272:13 | ...[...] | +| array_flow.rb:1272:10:1272:10 | a [element] | array_flow.rb:1272:10:1272:13 | ...[...] | +| array_flow.rb:1276:10:1276:10 | b | array_flow.rb:1276:10:1276:13 | ...[...] | +| array_flow.rb:1276:10:1276:10 | b [element] | array_flow.rb:1276:10:1276:13 | ...[...] | +| array_flow.rb:1276:10:1276:10 | b [element] | array_flow.rb:1276:10:1276:13 | ...[...] | | array_flow.rb:1278:5:1278:5 | a [element 2] | array_flow.rb:1279:9:1279:9 | a [element 2] | | array_flow.rb:1278:5:1278:5 | a [element 2] | array_flow.rb:1279:9:1279:9 | a [element 2] | | array_flow.rb:1278:5:1278:5 | a [element 4] | array_flow.rb:1279:9:1279:9 | a [element 4] | @@ -3244,18 +3228,20 @@ edges | array_flow.rb:1278:34:1278:46 | call to source | array_flow.rb:1278:5:1278:5 | a [element 4] | | array_flow.rb:1279:5:1279:5 | b [element 0] | array_flow.rb:1280:10:1280:10 | b [element 0] | | array_flow.rb:1279:5:1279:5 | b [element 0] | array_flow.rb:1280:10:1280:10 | b [element 0] | -| array_flow.rb:1279:9:1279:9 | [post] a [element 2] | array_flow.rb:1285:10:1285:10 | a [element 2] | -| array_flow.rb:1279:9:1279:9 | [post] a [element 2] | array_flow.rb:1285:10:1285:10 | a [element 2] | +| array_flow.rb:1279:5:1279:5 | b [element 2] | array_flow.rb:1282:10:1282:10 | b [element 2] | +| array_flow.rb:1279:5:1279:5 | b [element 2] | array_flow.rb:1282:10:1282:10 | b [element 2] | | array_flow.rb:1279:9:1279:9 | a [element 2] | array_flow.rb:1279:9:1279:22 | call to slice! [element 0] | | array_flow.rb:1279:9:1279:9 | a [element 2] | array_flow.rb:1279:9:1279:22 | call to slice! [element 0] | -| array_flow.rb:1279:9:1279:9 | a [element 4] | array_flow.rb:1279:9:1279:9 | [post] a [element 2] | -| array_flow.rb:1279:9:1279:9 | a [element 4] | array_flow.rb:1279:9:1279:9 | [post] a [element 2] | +| array_flow.rb:1279:9:1279:9 | a [element 4] | array_flow.rb:1279:9:1279:22 | call to slice! [element 2] | +| array_flow.rb:1279:9:1279:9 | a [element 4] | array_flow.rb:1279:9:1279:22 | call to slice! [element 2] | | array_flow.rb:1279:9:1279:22 | call to slice! [element 0] | array_flow.rb:1279:5:1279:5 | b [element 0] | | array_flow.rb:1279:9:1279:22 | call to slice! [element 0] | array_flow.rb:1279:5:1279:5 | b [element 0] | +| array_flow.rb:1279:9:1279:22 | call to slice! [element 2] | array_flow.rb:1279:5:1279:5 | b [element 2] | +| array_flow.rb:1279:9:1279:22 | call to slice! [element 2] | array_flow.rb:1279:5:1279:5 | b [element 2] | | array_flow.rb:1280:10:1280:10 | b [element 0] | array_flow.rb:1280:10:1280:13 | ...[...] | | array_flow.rb:1280:10:1280:10 | b [element 0] | array_flow.rb:1280:10:1280:13 | ...[...] | -| array_flow.rb:1285:10:1285:10 | a [element 2] | array_flow.rb:1285:10:1285:13 | ...[...] | -| array_flow.rb:1285:10:1285:10 | a [element 2] | array_flow.rb:1285:10:1285:13 | ...[...] | +| array_flow.rb:1282:10:1282:10 | b [element 2] | array_flow.rb:1282:10:1282:13 | ...[...] | +| array_flow.rb:1282:10:1282:10 | b [element 2] | array_flow.rb:1282:10:1282:13 | ...[...] | | array_flow.rb:1289:5:1289:5 | a [element 2] | array_flow.rb:1290:9:1290:9 | a [element 2] | | array_flow.rb:1289:5:1289:5 | a [element 2] | array_flow.rb:1290:9:1290:9 | a [element 2] | | array_flow.rb:1289:5:1289:5 | a [element 4] | array_flow.rb:1290:9:1290:9 | a [element 4] | @@ -3268,12 +3254,12 @@ edges | array_flow.rb:1290:5:1290:5 | b [element 0] | array_flow.rb:1291:10:1291:10 | b [element 0] | | array_flow.rb:1290:9:1290:9 | [post] a [element 2] | array_flow.rb:1296:10:1296:10 | a [element 2] | | array_flow.rb:1290:9:1290:9 | [post] a [element 2] | array_flow.rb:1296:10:1296:10 | a [element 2] | -| array_flow.rb:1290:9:1290:9 | a [element 2] | array_flow.rb:1290:9:1290:23 | call to slice! [element 0] | -| array_flow.rb:1290:9:1290:9 | a [element 2] | array_flow.rb:1290:9:1290:23 | call to slice! [element 0] | +| array_flow.rb:1290:9:1290:9 | a [element 2] | array_flow.rb:1290:9:1290:22 | call to slice! [element 0] | +| array_flow.rb:1290:9:1290:9 | a [element 2] | array_flow.rb:1290:9:1290:22 | call to slice! [element 0] | | array_flow.rb:1290:9:1290:9 | a [element 4] | array_flow.rb:1290:9:1290:9 | [post] a [element 2] | | array_flow.rb:1290:9:1290:9 | a [element 4] | array_flow.rb:1290:9:1290:9 | [post] a [element 2] | -| array_flow.rb:1290:9:1290:23 | call to slice! [element 0] | array_flow.rb:1290:5:1290:5 | b [element 0] | -| array_flow.rb:1290:9:1290:23 | call to slice! [element 0] | array_flow.rb:1290:5:1290:5 | b [element 0] | +| array_flow.rb:1290:9:1290:22 | call to slice! [element 0] | array_flow.rb:1290:5:1290:5 | b [element 0] | +| array_flow.rb:1290:9:1290:22 | call to slice! [element 0] | array_flow.rb:1290:5:1290:5 | b [element 0] | | array_flow.rb:1291:10:1291:10 | b [element 0] | array_flow.rb:1291:10:1291:13 | ...[...] | | array_flow.rb:1291:10:1291:10 | b [element 0] | array_flow.rb:1291:10:1291:13 | ...[...] | | array_flow.rb:1296:10:1296:10 | a [element 2] | array_flow.rb:1296:10:1296:13 | ...[...] | @@ -3286,306 +3272,294 @@ edges | array_flow.rb:1300:16:1300:28 | call to source | array_flow.rb:1300:5:1300:5 | a [element 2] | | array_flow.rb:1300:34:1300:46 | call to source | array_flow.rb:1300:5:1300:5 | a [element 4] | | array_flow.rb:1300:34:1300:46 | call to source | array_flow.rb:1300:5:1300:5 | a [element 4] | -| array_flow.rb:1301:5:1301:5 | b [element] | array_flow.rb:1302:10:1302:10 | b [element] | -| array_flow.rb:1301:5:1301:5 | b [element] | array_flow.rb:1302:10:1302:10 | b [element] | -| array_flow.rb:1301:5:1301:5 | b [element] | array_flow.rb:1303:10:1303:10 | b [element] | -| array_flow.rb:1301:5:1301:5 | b [element] | array_flow.rb:1303:10:1303:10 | b [element] | -| array_flow.rb:1301:5:1301:5 | b [element] | array_flow.rb:1304:10:1304:10 | b [element] | -| array_flow.rb:1301:5:1301:5 | b [element] | array_flow.rb:1304:10:1304:10 | b [element] | -| array_flow.rb:1301:9:1301:9 | [post] a [element] | array_flow.rb:1305:10:1305:10 | a [element] | -| array_flow.rb:1301:9:1301:9 | [post] a [element] | array_flow.rb:1305:10:1305:10 | a [element] | -| array_flow.rb:1301:9:1301:9 | [post] a [element] | array_flow.rb:1306:10:1306:10 | a [element] | -| array_flow.rb:1301:9:1301:9 | [post] a [element] | array_flow.rb:1306:10:1306:10 | a [element] | -| array_flow.rb:1301:9:1301:9 | [post] a [element] | array_flow.rb:1307:10:1307:10 | a [element] | -| array_flow.rb:1301:9:1301:9 | [post] a [element] | array_flow.rb:1307:10:1307:10 | a [element] | -| array_flow.rb:1301:9:1301:9 | a [element 2] | array_flow.rb:1301:9:1301:9 | [post] a [element] | -| array_flow.rb:1301:9:1301:9 | a [element 2] | array_flow.rb:1301:9:1301:9 | [post] a [element] | -| array_flow.rb:1301:9:1301:9 | a [element 2] | array_flow.rb:1301:9:1301:22 | call to slice! [element] | -| array_flow.rb:1301:9:1301:9 | a [element 2] | array_flow.rb:1301:9:1301:22 | call to slice! [element] | -| array_flow.rb:1301:9:1301:9 | a [element 4] | array_flow.rb:1301:9:1301:9 | [post] a [element] | -| array_flow.rb:1301:9:1301:9 | a [element 4] | array_flow.rb:1301:9:1301:9 | [post] a [element] | -| array_flow.rb:1301:9:1301:9 | a [element 4] | array_flow.rb:1301:9:1301:22 | call to slice! [element] | -| array_flow.rb:1301:9:1301:9 | a [element 4] | array_flow.rb:1301:9:1301:22 | call to slice! [element] | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] | array_flow.rb:1301:5:1301:5 | b [element] | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] | array_flow.rb:1301:5:1301:5 | b [element] | -| array_flow.rb:1302:10:1302:10 | b [element] | array_flow.rb:1302:10:1302:13 | ...[...] | -| array_flow.rb:1302:10:1302:10 | b [element] | array_flow.rb:1302:10:1302:13 | ...[...] | -| array_flow.rb:1303:10:1303:10 | b [element] | array_flow.rb:1303:10:1303:13 | ...[...] | -| array_flow.rb:1303:10:1303:10 | b [element] | array_flow.rb:1303:10:1303:13 | ...[...] | -| array_flow.rb:1304:10:1304:10 | b [element] | array_flow.rb:1304:10:1304:13 | ...[...] | -| array_flow.rb:1304:10:1304:10 | b [element] | array_flow.rb:1304:10:1304:13 | ...[...] | -| array_flow.rb:1305:10:1305:10 | a [element] | array_flow.rb:1305:10:1305:13 | ...[...] | -| array_flow.rb:1305:10:1305:10 | a [element] | array_flow.rb:1305:10:1305:13 | ...[...] | -| array_flow.rb:1306:10:1306:10 | a [element] | array_flow.rb:1306:10:1306:13 | ...[...] | -| array_flow.rb:1306:10:1306:10 | a [element] | array_flow.rb:1306:10:1306:13 | ...[...] | -| array_flow.rb:1307:10:1307:10 | a [element] | array_flow.rb:1307:10:1307:13 | ...[...] | -| array_flow.rb:1307:10:1307:10 | a [element] | array_flow.rb:1307:10:1307:13 | ...[...] | -| array_flow.rb:1309:5:1309:5 | a [element 2] | array_flow.rb:1310:9:1310:9 | a [element 2] | -| array_flow.rb:1309:5:1309:5 | a [element 2] | array_flow.rb:1310:9:1310:9 | a [element 2] | -| array_flow.rb:1309:5:1309:5 | a [element 4] | array_flow.rb:1310:9:1310:9 | a [element 4] | -| array_flow.rb:1309:5:1309:5 | a [element 4] | array_flow.rb:1310:9:1310:9 | a [element 4] | -| array_flow.rb:1309:16:1309:28 | call to source | array_flow.rb:1309:5:1309:5 | a [element 2] | -| array_flow.rb:1309:16:1309:28 | call to source | array_flow.rb:1309:5:1309:5 | a [element 2] | -| array_flow.rb:1309:34:1309:46 | call to source | array_flow.rb:1309:5:1309:5 | a [element 4] | -| array_flow.rb:1309:34:1309:46 | call to source | array_flow.rb:1309:5:1309:5 | a [element 4] | -| array_flow.rb:1310:5:1310:5 | b [element] | array_flow.rb:1311:10:1311:10 | b [element] | -| array_flow.rb:1310:5:1310:5 | b [element] | array_flow.rb:1311:10:1311:10 | b [element] | -| array_flow.rb:1310:5:1310:5 | b [element] | array_flow.rb:1312:10:1312:10 | b [element] | -| array_flow.rb:1310:5:1310:5 | b [element] | array_flow.rb:1312:10:1312:10 | b [element] | -| array_flow.rb:1310:5:1310:5 | b [element] | array_flow.rb:1313:10:1313:10 | b [element] | -| array_flow.rb:1310:5:1310:5 | b [element] | array_flow.rb:1313:10:1313:10 | b [element] | -| array_flow.rb:1310:9:1310:9 | [post] a [element] | array_flow.rb:1314:10:1314:10 | a [element] | -| array_flow.rb:1310:9:1310:9 | [post] a [element] | array_flow.rb:1314:10:1314:10 | a [element] | -| array_flow.rb:1310:9:1310:9 | [post] a [element] | array_flow.rb:1315:10:1315:10 | a [element] | -| array_flow.rb:1310:9:1310:9 | [post] a [element] | array_flow.rb:1315:10:1315:10 | a [element] | -| array_flow.rb:1310:9:1310:9 | [post] a [element] | array_flow.rb:1316:10:1316:10 | a [element] | -| array_flow.rb:1310:9:1310:9 | [post] a [element] | array_flow.rb:1316:10:1316:10 | a [element] | -| array_flow.rb:1310:9:1310:9 | a [element 2] | array_flow.rb:1310:9:1310:9 | [post] a [element] | -| array_flow.rb:1310:9:1310:9 | a [element 2] | array_flow.rb:1310:9:1310:9 | [post] a [element] | -| array_flow.rb:1310:9:1310:9 | a [element 2] | array_flow.rb:1310:9:1310:22 | call to slice! [element] | -| array_flow.rb:1310:9:1310:9 | a [element 2] | array_flow.rb:1310:9:1310:22 | call to slice! [element] | -| array_flow.rb:1310:9:1310:9 | a [element 4] | array_flow.rb:1310:9:1310:9 | [post] a [element] | -| array_flow.rb:1310:9:1310:9 | a [element 4] | array_flow.rb:1310:9:1310:9 | [post] a [element] | -| array_flow.rb:1310:9:1310:9 | a [element 4] | array_flow.rb:1310:9:1310:22 | call to slice! [element] | -| array_flow.rb:1310:9:1310:9 | a [element 4] | array_flow.rb:1310:9:1310:22 | call to slice! [element] | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] | array_flow.rb:1310:5:1310:5 | b [element] | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] | array_flow.rb:1310:5:1310:5 | b [element] | -| array_flow.rb:1311:10:1311:10 | b [element] | array_flow.rb:1311:10:1311:13 | ...[...] | -| array_flow.rb:1311:10:1311:10 | b [element] | array_flow.rb:1311:10:1311:13 | ...[...] | -| array_flow.rb:1312:10:1312:10 | b [element] | array_flow.rb:1312:10:1312:13 | ...[...] | -| array_flow.rb:1312:10:1312:10 | b [element] | array_flow.rb:1312:10:1312:13 | ...[...] | +| array_flow.rb:1301:5:1301:5 | b [element 0] | array_flow.rb:1302:10:1302:10 | b [element 0] | +| array_flow.rb:1301:5:1301:5 | b [element 0] | array_flow.rb:1302:10:1302:10 | b [element 0] | +| array_flow.rb:1301:9:1301:9 | [post] a [element 2] | array_flow.rb:1307:10:1307:10 | a [element 2] | +| array_flow.rb:1301:9:1301:9 | [post] a [element 2] | array_flow.rb:1307:10:1307:10 | a [element 2] | +| array_flow.rb:1301:9:1301:9 | a [element 2] | array_flow.rb:1301:9:1301:23 | call to slice! [element 0] | +| array_flow.rb:1301:9:1301:9 | a [element 2] | array_flow.rb:1301:9:1301:23 | call to slice! [element 0] | +| array_flow.rb:1301:9:1301:9 | a [element 4] | array_flow.rb:1301:9:1301:9 | [post] a [element 2] | +| array_flow.rb:1301:9:1301:9 | a [element 4] | array_flow.rb:1301:9:1301:9 | [post] a [element 2] | +| array_flow.rb:1301:9:1301:23 | call to slice! [element 0] | array_flow.rb:1301:5:1301:5 | b [element 0] | +| array_flow.rb:1301:9:1301:23 | call to slice! [element 0] | array_flow.rb:1301:5:1301:5 | b [element 0] | +| array_flow.rb:1302:10:1302:10 | b [element 0] | array_flow.rb:1302:10:1302:13 | ...[...] | +| array_flow.rb:1302:10:1302:10 | b [element 0] | array_flow.rb:1302:10:1302:13 | ...[...] | +| array_flow.rb:1307:10:1307:10 | a [element 2] | array_flow.rb:1307:10:1307:13 | ...[...] | +| array_flow.rb:1307:10:1307:10 | a [element 2] | array_flow.rb:1307:10:1307:13 | ...[...] | +| array_flow.rb:1311:5:1311:5 | a [element 2] | array_flow.rb:1312:9:1312:9 | a [element 2] | +| array_flow.rb:1311:5:1311:5 | a [element 2] | array_flow.rb:1312:9:1312:9 | a [element 2] | +| array_flow.rb:1311:5:1311:5 | a [element 4] | array_flow.rb:1312:9:1312:9 | a [element 4] | +| array_flow.rb:1311:5:1311:5 | a [element 4] | array_flow.rb:1312:9:1312:9 | a [element 4] | +| array_flow.rb:1311:16:1311:28 | call to source | array_flow.rb:1311:5:1311:5 | a [element 2] | +| array_flow.rb:1311:16:1311:28 | call to source | array_flow.rb:1311:5:1311:5 | a [element 2] | +| array_flow.rb:1311:34:1311:46 | call to source | array_flow.rb:1311:5:1311:5 | a [element 4] | +| array_flow.rb:1311:34:1311:46 | call to source | array_flow.rb:1311:5:1311:5 | a [element 4] | +| array_flow.rb:1312:5:1312:5 | b [element] | array_flow.rb:1313:10:1313:10 | b [element] | +| array_flow.rb:1312:5:1312:5 | b [element] | array_flow.rb:1313:10:1313:10 | b [element] | +| array_flow.rb:1312:5:1312:5 | b [element] | array_flow.rb:1314:10:1314:10 | b [element] | +| array_flow.rb:1312:5:1312:5 | b [element] | array_flow.rb:1314:10:1314:10 | b [element] | +| array_flow.rb:1312:5:1312:5 | b [element] | array_flow.rb:1315:10:1315:10 | b [element] | +| array_flow.rb:1312:5:1312:5 | b [element] | array_flow.rb:1315:10:1315:10 | b [element] | +| array_flow.rb:1312:9:1312:9 | [post] a [element] | array_flow.rb:1316:10:1316:10 | a [element] | +| array_flow.rb:1312:9:1312:9 | [post] a [element] | array_flow.rb:1316:10:1316:10 | a [element] | +| array_flow.rb:1312:9:1312:9 | [post] a [element] | array_flow.rb:1317:10:1317:10 | a [element] | +| array_flow.rb:1312:9:1312:9 | [post] a [element] | array_flow.rb:1317:10:1317:10 | a [element] | +| array_flow.rb:1312:9:1312:9 | [post] a [element] | array_flow.rb:1318:10:1318:10 | a [element] | +| array_flow.rb:1312:9:1312:9 | [post] a [element] | array_flow.rb:1318:10:1318:10 | a [element] | +| array_flow.rb:1312:9:1312:9 | a [element 2] | array_flow.rb:1312:9:1312:9 | [post] a [element] | +| array_flow.rb:1312:9:1312:9 | a [element 2] | array_flow.rb:1312:9:1312:9 | [post] a [element] | +| array_flow.rb:1312:9:1312:9 | a [element 2] | array_flow.rb:1312:9:1312:22 | call to slice! [element] | +| array_flow.rb:1312:9:1312:9 | a [element 2] | array_flow.rb:1312:9:1312:22 | call to slice! [element] | +| array_flow.rb:1312:9:1312:9 | a [element 4] | array_flow.rb:1312:9:1312:9 | [post] a [element] | +| array_flow.rb:1312:9:1312:9 | a [element 4] | array_flow.rb:1312:9:1312:9 | [post] a [element] | +| array_flow.rb:1312:9:1312:9 | a [element 4] | array_flow.rb:1312:9:1312:22 | call to slice! [element] | +| array_flow.rb:1312:9:1312:9 | a [element 4] | array_flow.rb:1312:9:1312:22 | call to slice! [element] | +| array_flow.rb:1312:9:1312:22 | call to slice! [element] | array_flow.rb:1312:5:1312:5 | b [element] | +| array_flow.rb:1312:9:1312:22 | call to slice! [element] | array_flow.rb:1312:5:1312:5 | b [element] | | array_flow.rb:1313:10:1313:10 | b [element] | array_flow.rb:1313:10:1313:13 | ...[...] | | array_flow.rb:1313:10:1313:10 | b [element] | array_flow.rb:1313:10:1313:13 | ...[...] | -| array_flow.rb:1314:10:1314:10 | a [element] | array_flow.rb:1314:10:1314:13 | ...[...] | -| array_flow.rb:1314:10:1314:10 | a [element] | array_flow.rb:1314:10:1314:13 | ...[...] | -| array_flow.rb:1315:10:1315:10 | a [element] | array_flow.rb:1315:10:1315:13 | ...[...] | -| array_flow.rb:1315:10:1315:10 | a [element] | array_flow.rb:1315:10:1315:13 | ...[...] | +| array_flow.rb:1314:10:1314:10 | b [element] | array_flow.rb:1314:10:1314:13 | ...[...] | +| array_flow.rb:1314:10:1314:10 | b [element] | array_flow.rb:1314:10:1314:13 | ...[...] | +| array_flow.rb:1315:10:1315:10 | b [element] | array_flow.rb:1315:10:1315:13 | ...[...] | +| array_flow.rb:1315:10:1315:10 | b [element] | array_flow.rb:1315:10:1315:13 | ...[...] | | array_flow.rb:1316:10:1316:10 | a [element] | array_flow.rb:1316:10:1316:13 | ...[...] | | array_flow.rb:1316:10:1316:10 | a [element] | array_flow.rb:1316:10:1316:13 | ...[...] | -| array_flow.rb:1318:5:1318:5 | a [element 2] | array_flow.rb:1319:9:1319:9 | a [element 2] | -| array_flow.rb:1318:5:1318:5 | a [element 2] | array_flow.rb:1319:9:1319:9 | a [element 2] | -| array_flow.rb:1318:5:1318:5 | a [element 4] | array_flow.rb:1319:9:1319:9 | a [element 4] | -| array_flow.rb:1318:5:1318:5 | a [element 4] | array_flow.rb:1319:9:1319:9 | a [element 4] | -| array_flow.rb:1318:16:1318:28 | call to source | array_flow.rb:1318:5:1318:5 | a [element 2] | -| array_flow.rb:1318:16:1318:28 | call to source | array_flow.rb:1318:5:1318:5 | a [element 2] | -| array_flow.rb:1318:34:1318:46 | call to source | array_flow.rb:1318:5:1318:5 | a [element 4] | -| array_flow.rb:1318:34:1318:46 | call to source | array_flow.rb:1318:5:1318:5 | a [element 4] | -| array_flow.rb:1319:5:1319:5 | b [element] | array_flow.rb:1320:10:1320:10 | b [element] | -| array_flow.rb:1319:5:1319:5 | b [element] | array_flow.rb:1320:10:1320:10 | b [element] | -| array_flow.rb:1319:5:1319:5 | b [element] | array_flow.rb:1321:10:1321:10 | b [element] | -| array_flow.rb:1319:5:1319:5 | b [element] | array_flow.rb:1321:10:1321:10 | b [element] | -| array_flow.rb:1319:5:1319:5 | b [element] | array_flow.rb:1322:10:1322:10 | b [element] | -| array_flow.rb:1319:5:1319:5 | b [element] | array_flow.rb:1322:10:1322:10 | b [element] | -| array_flow.rb:1319:9:1319:9 | [post] a [element] | array_flow.rb:1323:10:1323:10 | a [element] | -| array_flow.rb:1319:9:1319:9 | [post] a [element] | array_flow.rb:1323:10:1323:10 | a [element] | -| array_flow.rb:1319:9:1319:9 | [post] a [element] | array_flow.rb:1324:10:1324:10 | a [element] | -| array_flow.rb:1319:9:1319:9 | [post] a [element] | array_flow.rb:1324:10:1324:10 | a [element] | -| array_flow.rb:1319:9:1319:9 | [post] a [element] | array_flow.rb:1325:10:1325:10 | a [element] | -| array_flow.rb:1319:9:1319:9 | [post] a [element] | array_flow.rb:1325:10:1325:10 | a [element] | -| array_flow.rb:1319:9:1319:9 | a [element 2] | array_flow.rb:1319:9:1319:9 | [post] a [element] | -| array_flow.rb:1319:9:1319:9 | a [element 2] | array_flow.rb:1319:9:1319:9 | [post] a [element] | -| array_flow.rb:1319:9:1319:9 | a [element 2] | array_flow.rb:1319:9:1319:25 | call to slice! [element] | -| array_flow.rb:1319:9:1319:9 | a [element 2] | array_flow.rb:1319:9:1319:25 | call to slice! [element] | -| array_flow.rb:1319:9:1319:9 | a [element 4] | array_flow.rb:1319:9:1319:9 | [post] a [element] | -| array_flow.rb:1319:9:1319:9 | a [element 4] | array_flow.rb:1319:9:1319:9 | [post] a [element] | -| array_flow.rb:1319:9:1319:9 | a [element 4] | array_flow.rb:1319:9:1319:25 | call to slice! [element] | -| array_flow.rb:1319:9:1319:9 | a [element 4] | array_flow.rb:1319:9:1319:25 | call to slice! [element] | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] | array_flow.rb:1319:5:1319:5 | b [element] | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] | array_flow.rb:1319:5:1319:5 | b [element] | -| array_flow.rb:1320:10:1320:10 | b [element] | array_flow.rb:1320:10:1320:13 | ...[...] | -| array_flow.rb:1320:10:1320:10 | b [element] | array_flow.rb:1320:10:1320:13 | ...[...] | -| array_flow.rb:1321:10:1321:10 | b [element] | array_flow.rb:1321:10:1321:13 | ...[...] | -| array_flow.rb:1321:10:1321:10 | b [element] | array_flow.rb:1321:10:1321:13 | ...[...] | +| array_flow.rb:1317:10:1317:10 | a [element] | array_flow.rb:1317:10:1317:13 | ...[...] | +| array_flow.rb:1317:10:1317:10 | a [element] | array_flow.rb:1317:10:1317:13 | ...[...] | +| array_flow.rb:1318:10:1318:10 | a [element] | array_flow.rb:1318:10:1318:13 | ...[...] | +| array_flow.rb:1318:10:1318:10 | a [element] | array_flow.rb:1318:10:1318:13 | ...[...] | +| array_flow.rb:1320:5:1320:5 | a [element 2] | array_flow.rb:1321:9:1321:9 | a [element 2] | +| array_flow.rb:1320:5:1320:5 | a [element 2] | array_flow.rb:1321:9:1321:9 | a [element 2] | +| array_flow.rb:1320:5:1320:5 | a [element 4] | array_flow.rb:1321:9:1321:9 | a [element 4] | +| array_flow.rb:1320:5:1320:5 | a [element 4] | array_flow.rb:1321:9:1321:9 | a [element 4] | +| array_flow.rb:1320:16:1320:28 | call to source | array_flow.rb:1320:5:1320:5 | a [element 2] | +| array_flow.rb:1320:16:1320:28 | call to source | array_flow.rb:1320:5:1320:5 | a [element 2] | +| array_flow.rb:1320:34:1320:46 | call to source | array_flow.rb:1320:5:1320:5 | a [element 4] | +| array_flow.rb:1320:34:1320:46 | call to source | array_flow.rb:1320:5:1320:5 | a [element 4] | +| array_flow.rb:1321:5:1321:5 | b [element] | array_flow.rb:1322:10:1322:10 | b [element] | +| array_flow.rb:1321:5:1321:5 | b [element] | array_flow.rb:1322:10:1322:10 | b [element] | +| array_flow.rb:1321:5:1321:5 | b [element] | array_flow.rb:1323:10:1323:10 | b [element] | +| array_flow.rb:1321:5:1321:5 | b [element] | array_flow.rb:1323:10:1323:10 | b [element] | +| array_flow.rb:1321:5:1321:5 | b [element] | array_flow.rb:1324:10:1324:10 | b [element] | +| array_flow.rb:1321:5:1321:5 | b [element] | array_flow.rb:1324:10:1324:10 | b [element] | +| array_flow.rb:1321:9:1321:9 | [post] a [element] | array_flow.rb:1325:10:1325:10 | a [element] | +| array_flow.rb:1321:9:1321:9 | [post] a [element] | array_flow.rb:1325:10:1325:10 | a [element] | +| array_flow.rb:1321:9:1321:9 | [post] a [element] | array_flow.rb:1326:10:1326:10 | a [element] | +| array_flow.rb:1321:9:1321:9 | [post] a [element] | array_flow.rb:1326:10:1326:10 | a [element] | +| array_flow.rb:1321:9:1321:9 | [post] a [element] | array_flow.rb:1327:10:1327:10 | a [element] | +| array_flow.rb:1321:9:1321:9 | [post] a [element] | array_flow.rb:1327:10:1327:10 | a [element] | +| array_flow.rb:1321:9:1321:9 | a [element 2] | array_flow.rb:1321:9:1321:9 | [post] a [element] | +| array_flow.rb:1321:9:1321:9 | a [element 2] | array_flow.rb:1321:9:1321:9 | [post] a [element] | +| array_flow.rb:1321:9:1321:9 | a [element 2] | array_flow.rb:1321:9:1321:22 | call to slice! [element] | +| array_flow.rb:1321:9:1321:9 | a [element 2] | array_flow.rb:1321:9:1321:22 | call to slice! [element] | +| array_flow.rb:1321:9:1321:9 | a [element 4] | array_flow.rb:1321:9:1321:9 | [post] a [element] | +| array_flow.rb:1321:9:1321:9 | a [element 4] | array_flow.rb:1321:9:1321:9 | [post] a [element] | +| array_flow.rb:1321:9:1321:9 | a [element 4] | array_flow.rb:1321:9:1321:22 | call to slice! [element] | +| array_flow.rb:1321:9:1321:9 | a [element 4] | array_flow.rb:1321:9:1321:22 | call to slice! [element] | +| array_flow.rb:1321:9:1321:22 | call to slice! [element] | array_flow.rb:1321:5:1321:5 | b [element] | +| array_flow.rb:1321:9:1321:22 | call to slice! [element] | array_flow.rb:1321:5:1321:5 | b [element] | | array_flow.rb:1322:10:1322:10 | b [element] | array_flow.rb:1322:10:1322:13 | ...[...] | | array_flow.rb:1322:10:1322:10 | b [element] | array_flow.rb:1322:10:1322:13 | ...[...] | -| array_flow.rb:1323:10:1323:10 | a [element] | array_flow.rb:1323:10:1323:13 | ...[...] | -| array_flow.rb:1323:10:1323:10 | a [element] | array_flow.rb:1323:10:1323:13 | ...[...] | -| array_flow.rb:1324:10:1324:10 | a [element] | array_flow.rb:1324:10:1324:13 | ...[...] | -| array_flow.rb:1324:10:1324:10 | a [element] | array_flow.rb:1324:10:1324:13 | ...[...] | +| array_flow.rb:1323:10:1323:10 | b [element] | array_flow.rb:1323:10:1323:13 | ...[...] | +| array_flow.rb:1323:10:1323:10 | b [element] | array_flow.rb:1323:10:1323:13 | ...[...] | +| array_flow.rb:1324:10:1324:10 | b [element] | array_flow.rb:1324:10:1324:13 | ...[...] | +| array_flow.rb:1324:10:1324:10 | b [element] | array_flow.rb:1324:10:1324:13 | ...[...] | | array_flow.rb:1325:10:1325:10 | a [element] | array_flow.rb:1325:10:1325:13 | ...[...] | | array_flow.rb:1325:10:1325:10 | a [element] | array_flow.rb:1325:10:1325:13 | ...[...] | -| array_flow.rb:1327:5:1327:5 | a [element 2] | array_flow.rb:1328:9:1328:9 | a [element 2] | -| array_flow.rb:1327:5:1327:5 | a [element 2] | array_flow.rb:1328:9:1328:9 | a [element 2] | -| array_flow.rb:1327:5:1327:5 | a [element 4] | array_flow.rb:1328:9:1328:9 | a [element 4] | -| array_flow.rb:1327:5:1327:5 | a [element 4] | array_flow.rb:1328:9:1328:9 | a [element 4] | -| array_flow.rb:1327:16:1327:28 | call to source | array_flow.rb:1327:5:1327:5 | a [element 2] | -| array_flow.rb:1327:16:1327:28 | call to source | array_flow.rb:1327:5:1327:5 | a [element 2] | -| array_flow.rb:1327:34:1327:46 | call to source | array_flow.rb:1327:5:1327:5 | a [element 4] | -| array_flow.rb:1327:34:1327:46 | call to source | array_flow.rb:1327:5:1327:5 | a [element 4] | -| array_flow.rb:1328:5:1328:5 | b [element 2] | array_flow.rb:1331:10:1331:10 | b [element 2] | -| array_flow.rb:1328:5:1328:5 | b [element 2] | array_flow.rb:1331:10:1331:10 | b [element 2] | -| array_flow.rb:1328:9:1328:9 | [post] a [element 1] | array_flow.rb:1333:10:1333:10 | a [element 1] | -| array_flow.rb:1328:9:1328:9 | [post] a [element 1] | array_flow.rb:1333:10:1333:10 | a [element 1] | -| array_flow.rb:1328:9:1328:9 | a [element 2] | array_flow.rb:1328:9:1328:21 | call to slice! [element 2] | -| array_flow.rb:1328:9:1328:9 | a [element 2] | array_flow.rb:1328:9:1328:21 | call to slice! [element 2] | -| array_flow.rb:1328:9:1328:9 | a [element 4] | array_flow.rb:1328:9:1328:9 | [post] a [element 1] | -| array_flow.rb:1328:9:1328:9 | a [element 4] | array_flow.rb:1328:9:1328:9 | [post] a [element 1] | -| array_flow.rb:1328:9:1328:21 | call to slice! [element 2] | array_flow.rb:1328:5:1328:5 | b [element 2] | -| array_flow.rb:1328:9:1328:21 | call to slice! [element 2] | array_flow.rb:1328:5:1328:5 | b [element 2] | -| array_flow.rb:1331:10:1331:10 | b [element 2] | array_flow.rb:1331:10:1331:13 | ...[...] | -| array_flow.rb:1331:10:1331:10 | b [element 2] | array_flow.rb:1331:10:1331:13 | ...[...] | -| array_flow.rb:1333:10:1333:10 | a [element 1] | array_flow.rb:1333:10:1333:13 | ...[...] | -| array_flow.rb:1333:10:1333:10 | a [element 1] | array_flow.rb:1333:10:1333:13 | ...[...] | -| array_flow.rb:1336:5:1336:5 | a [element 2] | array_flow.rb:1337:9:1337:9 | a [element 2] | -| array_flow.rb:1336:5:1336:5 | a [element 2] | array_flow.rb:1337:9:1337:9 | a [element 2] | -| array_flow.rb:1336:5:1336:5 | a [element 4] | array_flow.rb:1337:9:1337:9 | a [element 4] | -| array_flow.rb:1336:5:1336:5 | a [element 4] | array_flow.rb:1337:9:1337:9 | a [element 4] | -| array_flow.rb:1336:16:1336:28 | call to source | array_flow.rb:1336:5:1336:5 | a [element 2] | -| array_flow.rb:1336:16:1336:28 | call to source | array_flow.rb:1336:5:1336:5 | a [element 2] | -| array_flow.rb:1336:34:1336:46 | call to source | array_flow.rb:1336:5:1336:5 | a [element 4] | -| array_flow.rb:1336:34:1336:46 | call to source | array_flow.rb:1336:5:1336:5 | a [element 4] | -| array_flow.rb:1337:5:1337:5 | b [element] | array_flow.rb:1338:10:1338:10 | b [element] | -| array_flow.rb:1337:5:1337:5 | b [element] | array_flow.rb:1338:10:1338:10 | b [element] | -| array_flow.rb:1337:5:1337:5 | b [element] | array_flow.rb:1339:10:1339:10 | b [element] | -| array_flow.rb:1337:5:1337:5 | b [element] | array_flow.rb:1339:10:1339:10 | b [element] | -| array_flow.rb:1337:5:1337:5 | b [element] | array_flow.rb:1340:10:1340:10 | b [element] | -| array_flow.rb:1337:5:1337:5 | b [element] | array_flow.rb:1340:10:1340:10 | b [element] | -| array_flow.rb:1337:9:1337:9 | [post] a [element] | array_flow.rb:1341:10:1341:10 | a [element] | -| array_flow.rb:1337:9:1337:9 | [post] a [element] | array_flow.rb:1341:10:1341:10 | a [element] | -| array_flow.rb:1337:9:1337:9 | [post] a [element] | array_flow.rb:1342:10:1342:10 | a [element] | -| array_flow.rb:1337:9:1337:9 | [post] a [element] | array_flow.rb:1342:10:1342:10 | a [element] | -| array_flow.rb:1337:9:1337:9 | [post] a [element] | array_flow.rb:1343:10:1343:10 | a [element] | -| array_flow.rb:1337:9:1337:9 | [post] a [element] | array_flow.rb:1343:10:1343:10 | a [element] | -| array_flow.rb:1337:9:1337:9 | a [element 2] | array_flow.rb:1337:9:1337:9 | [post] a [element] | -| array_flow.rb:1337:9:1337:9 | a [element 2] | array_flow.rb:1337:9:1337:9 | [post] a [element] | -| array_flow.rb:1337:9:1337:9 | a [element 2] | array_flow.rb:1337:9:1337:21 | call to slice! [element] | -| array_flow.rb:1337:9:1337:9 | a [element 2] | array_flow.rb:1337:9:1337:21 | call to slice! [element] | -| array_flow.rb:1337:9:1337:9 | a [element 4] | array_flow.rb:1337:9:1337:9 | [post] a [element] | -| array_flow.rb:1337:9:1337:9 | a [element 4] | array_flow.rb:1337:9:1337:9 | [post] a [element] | -| array_flow.rb:1337:9:1337:9 | a [element 4] | array_flow.rb:1337:9:1337:21 | call to slice! [element] | -| array_flow.rb:1337:9:1337:9 | a [element 4] | array_flow.rb:1337:9:1337:21 | call to slice! [element] | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] | array_flow.rb:1337:5:1337:5 | b [element] | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] | array_flow.rb:1337:5:1337:5 | b [element] | -| array_flow.rb:1338:10:1338:10 | b [element] | array_flow.rb:1338:10:1338:13 | ...[...] | -| array_flow.rb:1338:10:1338:10 | b [element] | array_flow.rb:1338:10:1338:13 | ...[...] | -| array_flow.rb:1339:10:1339:10 | b [element] | array_flow.rb:1339:10:1339:13 | ...[...] | -| array_flow.rb:1339:10:1339:10 | b [element] | array_flow.rb:1339:10:1339:13 | ...[...] | -| array_flow.rb:1340:10:1340:10 | b [element] | array_flow.rb:1340:10:1340:13 | ...[...] | -| array_flow.rb:1340:10:1340:10 | b [element] | array_flow.rb:1340:10:1340:13 | ...[...] | -| array_flow.rb:1341:10:1341:10 | a [element] | array_flow.rb:1341:10:1341:13 | ...[...] | -| array_flow.rb:1341:10:1341:10 | a [element] | array_flow.rb:1341:10:1341:13 | ...[...] | -| array_flow.rb:1342:10:1342:10 | a [element] | array_flow.rb:1342:10:1342:13 | ...[...] | -| array_flow.rb:1342:10:1342:10 | a [element] | array_flow.rb:1342:10:1342:13 | ...[...] | -| array_flow.rb:1343:10:1343:10 | a [element] | array_flow.rb:1343:10:1343:13 | ...[...] | -| array_flow.rb:1343:10:1343:10 | a [element] | array_flow.rb:1343:10:1343:13 | ...[...] | +| array_flow.rb:1326:10:1326:10 | a [element] | array_flow.rb:1326:10:1326:13 | ...[...] | +| array_flow.rb:1326:10:1326:10 | a [element] | array_flow.rb:1326:10:1326:13 | ...[...] | +| array_flow.rb:1327:10:1327:10 | a [element] | array_flow.rb:1327:10:1327:13 | ...[...] | +| array_flow.rb:1327:10:1327:10 | a [element] | array_flow.rb:1327:10:1327:13 | ...[...] | +| array_flow.rb:1329:5:1329:5 | a [element 2] | array_flow.rb:1330:9:1330:9 | a [element 2] | +| array_flow.rb:1329:5:1329:5 | a [element 2] | array_flow.rb:1330:9:1330:9 | a [element 2] | +| array_flow.rb:1329:5:1329:5 | a [element 4] | array_flow.rb:1330:9:1330:9 | a [element 4] | +| array_flow.rb:1329:5:1329:5 | a [element 4] | array_flow.rb:1330:9:1330:9 | a [element 4] | +| array_flow.rb:1329:16:1329:28 | call to source | array_flow.rb:1329:5:1329:5 | a [element 2] | +| array_flow.rb:1329:16:1329:28 | call to source | array_flow.rb:1329:5:1329:5 | a [element 2] | +| array_flow.rb:1329:34:1329:46 | call to source | array_flow.rb:1329:5:1329:5 | a [element 4] | +| array_flow.rb:1329:34:1329:46 | call to source | array_flow.rb:1329:5:1329:5 | a [element 4] | +| array_flow.rb:1330:5:1330:5 | b [element] | array_flow.rb:1331:10:1331:10 | b [element] | +| array_flow.rb:1330:5:1330:5 | b [element] | array_flow.rb:1331:10:1331:10 | b [element] | +| array_flow.rb:1330:5:1330:5 | b [element] | array_flow.rb:1332:10:1332:10 | b [element] | +| array_flow.rb:1330:5:1330:5 | b [element] | array_flow.rb:1332:10:1332:10 | b [element] | +| array_flow.rb:1330:5:1330:5 | b [element] | array_flow.rb:1333:10:1333:10 | b [element] | +| array_flow.rb:1330:5:1330:5 | b [element] | array_flow.rb:1333:10:1333:10 | b [element] | +| array_flow.rb:1330:9:1330:9 | [post] a [element] | array_flow.rb:1334:10:1334:10 | a [element] | +| array_flow.rb:1330:9:1330:9 | [post] a [element] | array_flow.rb:1334:10:1334:10 | a [element] | +| array_flow.rb:1330:9:1330:9 | [post] a [element] | array_flow.rb:1335:10:1335:10 | a [element] | +| array_flow.rb:1330:9:1330:9 | [post] a [element] | array_flow.rb:1335:10:1335:10 | a [element] | +| array_flow.rb:1330:9:1330:9 | [post] a [element] | array_flow.rb:1336:10:1336:10 | a [element] | +| array_flow.rb:1330:9:1330:9 | [post] a [element] | array_flow.rb:1336:10:1336:10 | a [element] | +| array_flow.rb:1330:9:1330:9 | a [element 2] | array_flow.rb:1330:9:1330:9 | [post] a [element] | +| array_flow.rb:1330:9:1330:9 | a [element 2] | array_flow.rb:1330:9:1330:9 | [post] a [element] | +| array_flow.rb:1330:9:1330:9 | a [element 2] | array_flow.rb:1330:9:1330:25 | call to slice! [element] | +| array_flow.rb:1330:9:1330:9 | a [element 2] | array_flow.rb:1330:9:1330:25 | call to slice! [element] | +| array_flow.rb:1330:9:1330:9 | a [element 4] | array_flow.rb:1330:9:1330:9 | [post] a [element] | +| array_flow.rb:1330:9:1330:9 | a [element 4] | array_flow.rb:1330:9:1330:9 | [post] a [element] | +| array_flow.rb:1330:9:1330:9 | a [element 4] | array_flow.rb:1330:9:1330:25 | call to slice! [element] | +| array_flow.rb:1330:9:1330:9 | a [element 4] | array_flow.rb:1330:9:1330:25 | call to slice! [element] | +| array_flow.rb:1330:9:1330:25 | call to slice! [element] | array_flow.rb:1330:5:1330:5 | b [element] | +| array_flow.rb:1330:9:1330:25 | call to slice! [element] | array_flow.rb:1330:5:1330:5 | b [element] | +| array_flow.rb:1331:10:1331:10 | b [element] | array_flow.rb:1331:10:1331:13 | ...[...] | +| array_flow.rb:1331:10:1331:10 | b [element] | array_flow.rb:1331:10:1331:13 | ...[...] | +| array_flow.rb:1332:10:1332:10 | b [element] | array_flow.rb:1332:10:1332:13 | ...[...] | +| array_flow.rb:1332:10:1332:10 | b [element] | array_flow.rb:1332:10:1332:13 | ...[...] | +| array_flow.rb:1333:10:1333:10 | b [element] | array_flow.rb:1333:10:1333:13 | ...[...] | +| array_flow.rb:1333:10:1333:10 | b [element] | array_flow.rb:1333:10:1333:13 | ...[...] | +| array_flow.rb:1334:10:1334:10 | a [element] | array_flow.rb:1334:10:1334:13 | ...[...] | +| array_flow.rb:1334:10:1334:10 | a [element] | array_flow.rb:1334:10:1334:13 | ...[...] | +| array_flow.rb:1335:10:1335:10 | a [element] | array_flow.rb:1335:10:1335:13 | ...[...] | +| array_flow.rb:1335:10:1335:10 | a [element] | array_flow.rb:1335:10:1335:13 | ...[...] | +| array_flow.rb:1336:10:1336:10 | a [element] | array_flow.rb:1336:10:1336:13 | ...[...] | +| array_flow.rb:1336:10:1336:10 | a [element] | array_flow.rb:1336:10:1336:13 | ...[...] | +| array_flow.rb:1338:5:1338:5 | a [element 2] | array_flow.rb:1339:9:1339:9 | a [element 2] | +| array_flow.rb:1338:5:1338:5 | a [element 2] | array_flow.rb:1339:9:1339:9 | a [element 2] | +| array_flow.rb:1338:5:1338:5 | a [element 4] | array_flow.rb:1339:9:1339:9 | a [element 4] | +| array_flow.rb:1338:5:1338:5 | a [element 4] | array_flow.rb:1339:9:1339:9 | a [element 4] | +| array_flow.rb:1338:16:1338:28 | call to source | array_flow.rb:1338:5:1338:5 | a [element 2] | +| array_flow.rb:1338:16:1338:28 | call to source | array_flow.rb:1338:5:1338:5 | a [element 2] | +| array_flow.rb:1338:34:1338:46 | call to source | array_flow.rb:1338:5:1338:5 | a [element 4] | +| array_flow.rb:1338:34:1338:46 | call to source | array_flow.rb:1338:5:1338:5 | a [element 4] | +| array_flow.rb:1339:5:1339:5 | b [element 2] | array_flow.rb:1342:10:1342:10 | b [element 2] | +| array_flow.rb:1339:5:1339:5 | b [element 2] | array_flow.rb:1342:10:1342:10 | b [element 2] | +| array_flow.rb:1339:9:1339:9 | [post] a [element 1] | array_flow.rb:1344:10:1344:10 | a [element 1] | +| array_flow.rb:1339:9:1339:9 | [post] a [element 1] | array_flow.rb:1344:10:1344:10 | a [element 1] | +| array_flow.rb:1339:9:1339:9 | a [element 2] | array_flow.rb:1339:9:1339:21 | call to slice! [element 2] | +| array_flow.rb:1339:9:1339:9 | a [element 2] | array_flow.rb:1339:9:1339:21 | call to slice! [element 2] | +| array_flow.rb:1339:9:1339:9 | a [element 4] | array_flow.rb:1339:9:1339:9 | [post] a [element 1] | +| array_flow.rb:1339:9:1339:9 | a [element 4] | array_flow.rb:1339:9:1339:9 | [post] a [element 1] | +| array_flow.rb:1339:9:1339:21 | call to slice! [element 2] | array_flow.rb:1339:5:1339:5 | b [element 2] | +| array_flow.rb:1339:9:1339:21 | call to slice! [element 2] | array_flow.rb:1339:5:1339:5 | b [element 2] | +| array_flow.rb:1342:10:1342:10 | b [element 2] | array_flow.rb:1342:10:1342:13 | ...[...] | +| array_flow.rb:1342:10:1342:10 | b [element 2] | array_flow.rb:1342:10:1342:13 | ...[...] | +| array_flow.rb:1344:10:1344:10 | a [element 1] | array_flow.rb:1344:10:1344:13 | ...[...] | +| array_flow.rb:1344:10:1344:10 | a [element 1] | array_flow.rb:1344:10:1344:13 | ...[...] | | array_flow.rb:1347:5:1347:5 | a [element 2] | array_flow.rb:1348:9:1348:9 | a [element 2] | | array_flow.rb:1347:5:1347:5 | a [element 2] | array_flow.rb:1348:9:1348:9 | a [element 2] | -| array_flow.rb:1347:16:1347:26 | call to source | array_flow.rb:1347:5:1347:5 | a [element 2] | -| array_flow.rb:1347:16:1347:26 | call to source | array_flow.rb:1347:5:1347:5 | a [element 2] | -| array_flow.rb:1348:9:1348:9 | a [element 2] | array_flow.rb:1348:27:1348:27 | x | -| array_flow.rb:1348:9:1348:9 | a [element 2] | array_flow.rb:1348:27:1348:27 | x | -| array_flow.rb:1348:27:1348:27 | x | array_flow.rb:1349:14:1349:14 | x | -| array_flow.rb:1348:27:1348:27 | x | array_flow.rb:1349:14:1349:14 | x | -| array_flow.rb:1355:5:1355:5 | a [element 2] | array_flow.rb:1356:9:1356:9 | a [element 2] | -| array_flow.rb:1355:5:1355:5 | a [element 2] | array_flow.rb:1356:9:1356:9 | a [element 2] | -| array_flow.rb:1355:16:1355:26 | call to source | array_flow.rb:1355:5:1355:5 | a [element 2] | -| array_flow.rb:1355:16:1355:26 | call to source | array_flow.rb:1355:5:1355:5 | a [element 2] | -| array_flow.rb:1356:9:1356:9 | a [element 2] | array_flow.rb:1356:28:1356:28 | x | -| array_flow.rb:1356:9:1356:9 | a [element 2] | array_flow.rb:1356:28:1356:28 | x | -| array_flow.rb:1356:28:1356:28 | x | array_flow.rb:1357:14:1357:14 | x | -| array_flow.rb:1356:28:1356:28 | x | array_flow.rb:1357:14:1357:14 | x | -| array_flow.rb:1363:5:1363:5 | a [element 2] | array_flow.rb:1364:9:1364:9 | a [element 2] | -| array_flow.rb:1363:5:1363:5 | a [element 2] | array_flow.rb:1364:9:1364:9 | a [element 2] | -| array_flow.rb:1363:16:1363:26 | call to source | array_flow.rb:1363:5:1363:5 | a [element 2] | -| array_flow.rb:1363:16:1363:26 | call to source | array_flow.rb:1363:5:1363:5 | a [element 2] | -| array_flow.rb:1364:9:1364:9 | a [element 2] | array_flow.rb:1364:26:1364:26 | x | -| array_flow.rb:1364:9:1364:9 | a [element 2] | array_flow.rb:1364:26:1364:26 | x | -| array_flow.rb:1364:9:1364:9 | a [element 2] | array_flow.rb:1364:29:1364:29 | y | -| array_flow.rb:1364:9:1364:9 | a [element 2] | array_flow.rb:1364:29:1364:29 | y | -| array_flow.rb:1364:26:1364:26 | x | array_flow.rb:1365:14:1365:14 | x | -| array_flow.rb:1364:26:1364:26 | x | array_flow.rb:1365:14:1365:14 | x | -| array_flow.rb:1364:29:1364:29 | y | array_flow.rb:1366:14:1366:14 | y | -| array_flow.rb:1364:29:1364:29 | y | array_flow.rb:1366:14:1366:14 | y | -| array_flow.rb:1371:5:1371:5 | a [element 2] | array_flow.rb:1372:9:1372:9 | a [element 2] | -| array_flow.rb:1371:5:1371:5 | a [element 2] | array_flow.rb:1372:9:1372:9 | a [element 2] | -| array_flow.rb:1371:5:1371:5 | a [element 2] | array_flow.rb:1375:9:1375:9 | a [element 2] | -| array_flow.rb:1371:5:1371:5 | a [element 2] | array_flow.rb:1375:9:1375:9 | a [element 2] | -| array_flow.rb:1371:16:1371:26 | call to source | array_flow.rb:1371:5:1371:5 | a [element 2] | -| array_flow.rb:1371:16:1371:26 | call to source | array_flow.rb:1371:5:1371:5 | a [element 2] | -| array_flow.rb:1372:5:1372:5 | b [element] | array_flow.rb:1373:10:1373:10 | b [element] | -| array_flow.rb:1372:5:1372:5 | b [element] | array_flow.rb:1373:10:1373:10 | b [element] | -| array_flow.rb:1372:5:1372:5 | b [element] | array_flow.rb:1374:10:1374:10 | b [element] | -| array_flow.rb:1372:5:1372:5 | b [element] | array_flow.rb:1374:10:1374:10 | b [element] | -| array_flow.rb:1372:9:1372:9 | a [element 2] | array_flow.rb:1372:9:1372:14 | call to sort [element] | -| array_flow.rb:1372:9:1372:9 | a [element 2] | array_flow.rb:1372:9:1372:14 | call to sort [element] | -| array_flow.rb:1372:9:1372:14 | call to sort [element] | array_flow.rb:1372:5:1372:5 | b [element] | -| array_flow.rb:1372:9:1372:14 | call to sort [element] | array_flow.rb:1372:5:1372:5 | b [element] | -| array_flow.rb:1373:10:1373:10 | b [element] | array_flow.rb:1373:10:1373:13 | ...[...] | -| array_flow.rb:1373:10:1373:10 | b [element] | array_flow.rb:1373:10:1373:13 | ...[...] | -| array_flow.rb:1374:10:1374:10 | b [element] | array_flow.rb:1374:10:1374:13 | ...[...] | -| array_flow.rb:1374:10:1374:10 | b [element] | array_flow.rb:1374:10:1374:13 | ...[...] | -| array_flow.rb:1375:5:1375:5 | c [element] | array_flow.rb:1380:10:1380:10 | c [element] | -| array_flow.rb:1375:5:1375:5 | c [element] | array_flow.rb:1380:10:1380:10 | c [element] | -| array_flow.rb:1375:5:1375:5 | c [element] | array_flow.rb:1381:10:1381:10 | c [element] | -| array_flow.rb:1375:5:1375:5 | c [element] | array_flow.rb:1381:10:1381:10 | c [element] | -| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:9:1379:7 | call to sort [element] | -| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:9:1379:7 | call to sort [element] | -| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:20:1375:20 | x | -| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:20:1375:20 | x | -| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:23:1375:23 | y | -| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:23:1375:23 | y | -| array_flow.rb:1375:9:1379:7 | call to sort [element] | array_flow.rb:1375:5:1375:5 | c [element] | -| array_flow.rb:1375:9:1379:7 | call to sort [element] | array_flow.rb:1375:5:1375:5 | c [element] | -| array_flow.rb:1375:20:1375:20 | x | array_flow.rb:1376:14:1376:14 | x | -| array_flow.rb:1375:20:1375:20 | x | array_flow.rb:1376:14:1376:14 | x | -| array_flow.rb:1375:23:1375:23 | y | array_flow.rb:1377:14:1377:14 | y | -| array_flow.rb:1375:23:1375:23 | y | array_flow.rb:1377:14:1377:14 | y | -| array_flow.rb:1380:10:1380:10 | c [element] | array_flow.rb:1380:10:1380:13 | ...[...] | -| array_flow.rb:1380:10:1380:10 | c [element] | array_flow.rb:1380:10:1380:13 | ...[...] | -| array_flow.rb:1381:10:1381:10 | c [element] | array_flow.rb:1381:10:1381:13 | ...[...] | -| array_flow.rb:1381:10:1381:10 | c [element] | array_flow.rb:1381:10:1381:13 | ...[...] | -| array_flow.rb:1385:5:1385:5 | a [element 2] | array_flow.rb:1386:9:1386:9 | a [element 2] | -| array_flow.rb:1385:5:1385:5 | a [element 2] | array_flow.rb:1386:9:1386:9 | a [element 2] | -| array_flow.rb:1385:16:1385:26 | call to source | array_flow.rb:1385:5:1385:5 | a [element 2] | -| array_flow.rb:1385:16:1385:26 | call to source | array_flow.rb:1385:5:1385:5 | a [element 2] | -| array_flow.rb:1386:5:1386:5 | b [element] | array_flow.rb:1387:10:1387:10 | b [element] | -| array_flow.rb:1386:5:1386:5 | b [element] | array_flow.rb:1387:10:1387:10 | b [element] | -| array_flow.rb:1386:5:1386:5 | b [element] | array_flow.rb:1388:10:1388:10 | b [element] | -| array_flow.rb:1386:5:1386:5 | b [element] | array_flow.rb:1388:10:1388:10 | b [element] | -| array_flow.rb:1386:9:1386:9 | [post] a [element] | array_flow.rb:1389:10:1389:10 | a [element] | -| array_flow.rb:1386:9:1386:9 | [post] a [element] | array_flow.rb:1389:10:1389:10 | a [element] | -| array_flow.rb:1386:9:1386:9 | [post] a [element] | array_flow.rb:1390:10:1390:10 | a [element] | -| array_flow.rb:1386:9:1386:9 | [post] a [element] | array_flow.rb:1390:10:1390:10 | a [element] | -| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:9:1386:9 | [post] a [element] | -| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:9:1386:9 | [post] a [element] | -| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:9:1386:15 | call to sort! [element] | -| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:9:1386:15 | call to sort! [element] | -| array_flow.rb:1386:9:1386:15 | call to sort! [element] | array_flow.rb:1386:5:1386:5 | b [element] | -| array_flow.rb:1386:9:1386:15 | call to sort! [element] | array_flow.rb:1386:5:1386:5 | b [element] | -| array_flow.rb:1387:10:1387:10 | b [element] | array_flow.rb:1387:10:1387:13 | ...[...] | -| array_flow.rb:1387:10:1387:10 | b [element] | array_flow.rb:1387:10:1387:13 | ...[...] | -| array_flow.rb:1388:10:1388:10 | b [element] | array_flow.rb:1388:10:1388:13 | ...[...] | -| array_flow.rb:1388:10:1388:10 | b [element] | array_flow.rb:1388:10:1388:13 | ...[...] | -| array_flow.rb:1389:10:1389:10 | a [element] | array_flow.rb:1389:10:1389:13 | ...[...] | -| array_flow.rb:1389:10:1389:10 | a [element] | array_flow.rb:1389:10:1389:13 | ...[...] | -| array_flow.rb:1390:10:1390:10 | a [element] | array_flow.rb:1390:10:1390:13 | ...[...] | -| array_flow.rb:1390:10:1390:10 | a [element] | array_flow.rb:1390:10:1390:13 | ...[...] | -| array_flow.rb:1392:5:1392:5 | a [element 2] | array_flow.rb:1393:9:1393:9 | a [element 2] | -| array_flow.rb:1392:5:1392:5 | a [element 2] | array_flow.rb:1393:9:1393:9 | a [element 2] | -| array_flow.rb:1392:16:1392:26 | call to source | array_flow.rb:1392:5:1392:5 | a [element 2] | -| array_flow.rb:1392:16:1392:26 | call to source | array_flow.rb:1392:5:1392:5 | a [element 2] | -| array_flow.rb:1393:5:1393:5 | b [element] | array_flow.rb:1398:10:1398:10 | b [element] | -| array_flow.rb:1393:5:1393:5 | b [element] | array_flow.rb:1398:10:1398:10 | b [element] | -| array_flow.rb:1393:5:1393:5 | b [element] | array_flow.rb:1399:10:1399:10 | b [element] | -| array_flow.rb:1393:5:1393:5 | b [element] | array_flow.rb:1399:10:1399:10 | b [element] | -| array_flow.rb:1393:9:1393:9 | [post] a [element] | array_flow.rb:1400:10:1400:10 | a [element] | -| array_flow.rb:1393:9:1393:9 | [post] a [element] | array_flow.rb:1400:10:1400:10 | a [element] | -| array_flow.rb:1393:9:1393:9 | [post] a [element] | array_flow.rb:1401:10:1401:10 | a [element] | -| array_flow.rb:1393:9:1393:9 | [post] a [element] | array_flow.rb:1401:10:1401:10 | a [element] | -| array_flow.rb:1393:9:1393:9 | a [element 2] | array_flow.rb:1393:9:1393:9 | [post] a [element] | -| array_flow.rb:1393:9:1393:9 | a [element 2] | array_flow.rb:1393:9:1393:9 | [post] a [element] | -| array_flow.rb:1393:9:1393:9 | a [element 2] | array_flow.rb:1393:9:1397:7 | call to sort! [element] | -| array_flow.rb:1393:9:1393:9 | a [element 2] | array_flow.rb:1393:9:1397:7 | call to sort! [element] | -| array_flow.rb:1393:9:1393:9 | a [element 2] | array_flow.rb:1393:21:1393:21 | x | -| array_flow.rb:1393:9:1393:9 | a [element 2] | array_flow.rb:1393:21:1393:21 | x | -| array_flow.rb:1393:9:1393:9 | a [element 2] | array_flow.rb:1393:24:1393:24 | y | -| array_flow.rb:1393:9:1393:9 | a [element 2] | array_flow.rb:1393:24:1393:24 | y | -| array_flow.rb:1393:9:1397:7 | call to sort! [element] | array_flow.rb:1393:5:1393:5 | b [element] | -| array_flow.rb:1393:9:1397:7 | call to sort! [element] | array_flow.rb:1393:5:1393:5 | b [element] | -| array_flow.rb:1393:21:1393:21 | x | array_flow.rb:1394:14:1394:14 | x | -| array_flow.rb:1393:21:1393:21 | x | array_flow.rb:1394:14:1394:14 | x | -| array_flow.rb:1393:24:1393:24 | y | array_flow.rb:1395:14:1395:14 | y | -| array_flow.rb:1393:24:1393:24 | y | array_flow.rb:1395:14:1395:14 | y | +| array_flow.rb:1347:5:1347:5 | a [element 4] | array_flow.rb:1348:9:1348:9 | a [element 4] | +| array_flow.rb:1347:5:1347:5 | a [element 4] | array_flow.rb:1348:9:1348:9 | a [element 4] | +| array_flow.rb:1347:16:1347:28 | call to source | array_flow.rb:1347:5:1347:5 | a [element 2] | +| array_flow.rb:1347:16:1347:28 | call to source | array_flow.rb:1347:5:1347:5 | a [element 2] | +| array_flow.rb:1347:34:1347:46 | call to source | array_flow.rb:1347:5:1347:5 | a [element 4] | +| array_flow.rb:1347:34:1347:46 | call to source | array_flow.rb:1347:5:1347:5 | a [element 4] | +| array_flow.rb:1348:5:1348:5 | b [element] | array_flow.rb:1349:10:1349:10 | b [element] | +| array_flow.rb:1348:5:1348:5 | b [element] | array_flow.rb:1349:10:1349:10 | b [element] | +| array_flow.rb:1348:5:1348:5 | b [element] | array_flow.rb:1350:10:1350:10 | b [element] | +| array_flow.rb:1348:5:1348:5 | b [element] | array_flow.rb:1350:10:1350:10 | b [element] | +| array_flow.rb:1348:5:1348:5 | b [element] | array_flow.rb:1351:10:1351:10 | b [element] | +| array_flow.rb:1348:5:1348:5 | b [element] | array_flow.rb:1351:10:1351:10 | b [element] | +| array_flow.rb:1348:9:1348:9 | [post] a [element] | array_flow.rb:1352:10:1352:10 | a [element] | +| array_flow.rb:1348:9:1348:9 | [post] a [element] | array_flow.rb:1352:10:1352:10 | a [element] | +| array_flow.rb:1348:9:1348:9 | [post] a [element] | array_flow.rb:1353:10:1353:10 | a [element] | +| array_flow.rb:1348:9:1348:9 | [post] a [element] | array_flow.rb:1353:10:1353:10 | a [element] | +| array_flow.rb:1348:9:1348:9 | [post] a [element] | array_flow.rb:1354:10:1354:10 | a [element] | +| array_flow.rb:1348:9:1348:9 | [post] a [element] | array_flow.rb:1354:10:1354:10 | a [element] | +| array_flow.rb:1348:9:1348:9 | a [element 2] | array_flow.rb:1348:9:1348:9 | [post] a [element] | +| array_flow.rb:1348:9:1348:9 | a [element 2] | array_flow.rb:1348:9:1348:9 | [post] a [element] | +| array_flow.rb:1348:9:1348:9 | a [element 2] | array_flow.rb:1348:9:1348:21 | call to slice! [element] | +| array_flow.rb:1348:9:1348:9 | a [element 2] | array_flow.rb:1348:9:1348:21 | call to slice! [element] | +| array_flow.rb:1348:9:1348:9 | a [element 4] | array_flow.rb:1348:9:1348:9 | [post] a [element] | +| array_flow.rb:1348:9:1348:9 | a [element 4] | array_flow.rb:1348:9:1348:9 | [post] a [element] | +| array_flow.rb:1348:9:1348:9 | a [element 4] | array_flow.rb:1348:9:1348:21 | call to slice! [element] | +| array_flow.rb:1348:9:1348:9 | a [element 4] | array_flow.rb:1348:9:1348:21 | call to slice! [element] | +| array_flow.rb:1348:9:1348:21 | call to slice! [element] | array_flow.rb:1348:5:1348:5 | b [element] | +| array_flow.rb:1348:9:1348:21 | call to slice! [element] | array_flow.rb:1348:5:1348:5 | b [element] | +| array_flow.rb:1349:10:1349:10 | b [element] | array_flow.rb:1349:10:1349:13 | ...[...] | +| array_flow.rb:1349:10:1349:10 | b [element] | array_flow.rb:1349:10:1349:13 | ...[...] | +| array_flow.rb:1350:10:1350:10 | b [element] | array_flow.rb:1350:10:1350:13 | ...[...] | +| array_flow.rb:1350:10:1350:10 | b [element] | array_flow.rb:1350:10:1350:13 | ...[...] | +| array_flow.rb:1351:10:1351:10 | b [element] | array_flow.rb:1351:10:1351:13 | ...[...] | +| array_flow.rb:1351:10:1351:10 | b [element] | array_flow.rb:1351:10:1351:13 | ...[...] | +| array_flow.rb:1352:10:1352:10 | a [element] | array_flow.rb:1352:10:1352:13 | ...[...] | +| array_flow.rb:1352:10:1352:10 | a [element] | array_flow.rb:1352:10:1352:13 | ...[...] | +| array_flow.rb:1353:10:1353:10 | a [element] | array_flow.rb:1353:10:1353:13 | ...[...] | +| array_flow.rb:1353:10:1353:10 | a [element] | array_flow.rb:1353:10:1353:13 | ...[...] | +| array_flow.rb:1354:10:1354:10 | a [element] | array_flow.rb:1354:10:1354:13 | ...[...] | +| array_flow.rb:1354:10:1354:10 | a [element] | array_flow.rb:1354:10:1354:13 | ...[...] | +| array_flow.rb:1358:5:1358:5 | a [element 2] | array_flow.rb:1359:9:1359:9 | a [element 2] | +| array_flow.rb:1358:5:1358:5 | a [element 2] | array_flow.rb:1359:9:1359:9 | a [element 2] | +| array_flow.rb:1358:16:1358:26 | call to source | array_flow.rb:1358:5:1358:5 | a [element 2] | +| array_flow.rb:1358:16:1358:26 | call to source | array_flow.rb:1358:5:1358:5 | a [element 2] | +| array_flow.rb:1359:9:1359:9 | a [element 2] | array_flow.rb:1359:27:1359:27 | x | +| array_flow.rb:1359:9:1359:9 | a [element 2] | array_flow.rb:1359:27:1359:27 | x | +| array_flow.rb:1359:27:1359:27 | x | array_flow.rb:1360:14:1360:14 | x | +| array_flow.rb:1359:27:1359:27 | x | array_flow.rb:1360:14:1360:14 | x | +| array_flow.rb:1366:5:1366:5 | a [element 2] | array_flow.rb:1367:9:1367:9 | a [element 2] | +| array_flow.rb:1366:5:1366:5 | a [element 2] | array_flow.rb:1367:9:1367:9 | a [element 2] | +| array_flow.rb:1366:16:1366:26 | call to source | array_flow.rb:1366:5:1366:5 | a [element 2] | +| array_flow.rb:1366:16:1366:26 | call to source | array_flow.rb:1366:5:1366:5 | a [element 2] | +| array_flow.rb:1367:9:1367:9 | a [element 2] | array_flow.rb:1367:28:1367:28 | x | +| array_flow.rb:1367:9:1367:9 | a [element 2] | array_flow.rb:1367:28:1367:28 | x | +| array_flow.rb:1367:28:1367:28 | x | array_flow.rb:1368:14:1368:14 | x | +| array_flow.rb:1367:28:1367:28 | x | array_flow.rb:1368:14:1368:14 | x | +| array_flow.rb:1374:5:1374:5 | a [element 2] | array_flow.rb:1375:9:1375:9 | a [element 2] | +| array_flow.rb:1374:5:1374:5 | a [element 2] | array_flow.rb:1375:9:1375:9 | a [element 2] | +| array_flow.rb:1374:16:1374:26 | call to source | array_flow.rb:1374:5:1374:5 | a [element 2] | +| array_flow.rb:1374:16:1374:26 | call to source | array_flow.rb:1374:5:1374:5 | a [element 2] | +| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:26:1375:26 | x | +| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:26:1375:26 | x | +| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:29:1375:29 | y | +| array_flow.rb:1375:9:1375:9 | a [element 2] | array_flow.rb:1375:29:1375:29 | y | +| array_flow.rb:1375:26:1375:26 | x | array_flow.rb:1376:14:1376:14 | x | +| array_flow.rb:1375:26:1375:26 | x | array_flow.rb:1376:14:1376:14 | x | +| array_flow.rb:1375:29:1375:29 | y | array_flow.rb:1377:14:1377:14 | y | +| array_flow.rb:1375:29:1375:29 | y | array_flow.rb:1377:14:1377:14 | y | +| array_flow.rb:1382:5:1382:5 | a [element 2] | array_flow.rb:1383:9:1383:9 | a [element 2] | +| array_flow.rb:1382:5:1382:5 | a [element 2] | array_flow.rb:1383:9:1383:9 | a [element 2] | +| array_flow.rb:1382:5:1382:5 | a [element 2] | array_flow.rb:1386:9:1386:9 | a [element 2] | +| array_flow.rb:1382:5:1382:5 | a [element 2] | array_flow.rb:1386:9:1386:9 | a [element 2] | +| array_flow.rb:1382:16:1382:26 | call to source | array_flow.rb:1382:5:1382:5 | a [element 2] | +| array_flow.rb:1382:16:1382:26 | call to source | array_flow.rb:1382:5:1382:5 | a [element 2] | +| array_flow.rb:1383:5:1383:5 | b [element] | array_flow.rb:1384:10:1384:10 | b [element] | +| array_flow.rb:1383:5:1383:5 | b [element] | array_flow.rb:1384:10:1384:10 | b [element] | +| array_flow.rb:1383:5:1383:5 | b [element] | array_flow.rb:1385:10:1385:10 | b [element] | +| array_flow.rb:1383:5:1383:5 | b [element] | array_flow.rb:1385:10:1385:10 | b [element] | +| array_flow.rb:1383:9:1383:9 | a [element 2] | array_flow.rb:1383:9:1383:14 | call to sort [element] | +| array_flow.rb:1383:9:1383:9 | a [element 2] | array_flow.rb:1383:9:1383:14 | call to sort [element] | +| array_flow.rb:1383:9:1383:14 | call to sort [element] | array_flow.rb:1383:5:1383:5 | b [element] | +| array_flow.rb:1383:9:1383:14 | call to sort [element] | array_flow.rb:1383:5:1383:5 | b [element] | +| array_flow.rb:1384:10:1384:10 | b [element] | array_flow.rb:1384:10:1384:13 | ...[...] | +| array_flow.rb:1384:10:1384:10 | b [element] | array_flow.rb:1384:10:1384:13 | ...[...] | +| array_flow.rb:1385:10:1385:10 | b [element] | array_flow.rb:1385:10:1385:13 | ...[...] | +| array_flow.rb:1385:10:1385:10 | b [element] | array_flow.rb:1385:10:1385:13 | ...[...] | +| array_flow.rb:1386:5:1386:5 | c [element] | array_flow.rb:1391:10:1391:10 | c [element] | +| array_flow.rb:1386:5:1386:5 | c [element] | array_flow.rb:1391:10:1391:10 | c [element] | +| array_flow.rb:1386:5:1386:5 | c [element] | array_flow.rb:1392:10:1392:10 | c [element] | +| array_flow.rb:1386:5:1386:5 | c [element] | array_flow.rb:1392:10:1392:10 | c [element] | +| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:9:1390:7 | call to sort [element] | +| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:9:1390:7 | call to sort [element] | +| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:20:1386:20 | x | +| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:20:1386:20 | x | +| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:23:1386:23 | y | +| array_flow.rb:1386:9:1386:9 | a [element 2] | array_flow.rb:1386:23:1386:23 | y | +| array_flow.rb:1386:9:1390:7 | call to sort [element] | array_flow.rb:1386:5:1386:5 | c [element] | +| array_flow.rb:1386:9:1390:7 | call to sort [element] | array_flow.rb:1386:5:1386:5 | c [element] | +| array_flow.rb:1386:20:1386:20 | x | array_flow.rb:1387:14:1387:14 | x | +| array_flow.rb:1386:20:1386:20 | x | array_flow.rb:1387:14:1387:14 | x | +| array_flow.rb:1386:23:1386:23 | y | array_flow.rb:1388:14:1388:14 | y | +| array_flow.rb:1386:23:1386:23 | y | array_flow.rb:1388:14:1388:14 | y | +| array_flow.rb:1391:10:1391:10 | c [element] | array_flow.rb:1391:10:1391:13 | ...[...] | +| array_flow.rb:1391:10:1391:10 | c [element] | array_flow.rb:1391:10:1391:13 | ...[...] | +| array_flow.rb:1392:10:1392:10 | c [element] | array_flow.rb:1392:10:1392:13 | ...[...] | +| array_flow.rb:1392:10:1392:10 | c [element] | array_flow.rb:1392:10:1392:13 | ...[...] | +| array_flow.rb:1396:5:1396:5 | a [element 2] | array_flow.rb:1397:9:1397:9 | a [element 2] | +| array_flow.rb:1396:5:1396:5 | a [element 2] | array_flow.rb:1397:9:1397:9 | a [element 2] | +| array_flow.rb:1396:16:1396:26 | call to source | array_flow.rb:1396:5:1396:5 | a [element 2] | +| array_flow.rb:1396:16:1396:26 | call to source | array_flow.rb:1396:5:1396:5 | a [element 2] | +| array_flow.rb:1397:5:1397:5 | b [element] | array_flow.rb:1398:10:1398:10 | b [element] | +| array_flow.rb:1397:5:1397:5 | b [element] | array_flow.rb:1398:10:1398:10 | b [element] | +| array_flow.rb:1397:5:1397:5 | b [element] | array_flow.rb:1399:10:1399:10 | b [element] | +| array_flow.rb:1397:5:1397:5 | b [element] | array_flow.rb:1399:10:1399:10 | b [element] | +| array_flow.rb:1397:9:1397:9 | [post] a [element] | array_flow.rb:1400:10:1400:10 | a [element] | +| array_flow.rb:1397:9:1397:9 | [post] a [element] | array_flow.rb:1400:10:1400:10 | a [element] | +| array_flow.rb:1397:9:1397:9 | [post] a [element] | array_flow.rb:1401:10:1401:10 | a [element] | +| array_flow.rb:1397:9:1397:9 | [post] a [element] | array_flow.rb:1401:10:1401:10 | a [element] | +| array_flow.rb:1397:9:1397:9 | a [element 2] | array_flow.rb:1397:9:1397:9 | [post] a [element] | +| array_flow.rb:1397:9:1397:9 | a [element 2] | array_flow.rb:1397:9:1397:9 | [post] a [element] | +| array_flow.rb:1397:9:1397:9 | a [element 2] | array_flow.rb:1397:9:1397:15 | call to sort! [element] | +| array_flow.rb:1397:9:1397:9 | a [element 2] | array_flow.rb:1397:9:1397:15 | call to sort! [element] | +| array_flow.rb:1397:9:1397:15 | call to sort! [element] | array_flow.rb:1397:5:1397:5 | b [element] | +| array_flow.rb:1397:9:1397:15 | call to sort! [element] | array_flow.rb:1397:5:1397:5 | b [element] | | array_flow.rb:1398:10:1398:10 | b [element] | array_flow.rb:1398:10:1398:13 | ...[...] | | array_flow.rb:1398:10:1398:10 | b [element] | array_flow.rb:1398:10:1398:13 | ...[...] | | array_flow.rb:1399:10:1399:10 | b [element] | array_flow.rb:1399:10:1399:13 | ...[...] | @@ -3594,652 +3568,686 @@ edges | array_flow.rb:1400:10:1400:10 | a [element] | array_flow.rb:1400:10:1400:13 | ...[...] | | array_flow.rb:1401:10:1401:10 | a [element] | array_flow.rb:1401:10:1401:13 | ...[...] | | array_flow.rb:1401:10:1401:10 | a [element] | array_flow.rb:1401:10:1401:13 | ...[...] | -| array_flow.rb:1405:5:1405:5 | a [element 2] | array_flow.rb:1406:9:1406:9 | a [element 2] | -| array_flow.rb:1405:5:1405:5 | a [element 2] | array_flow.rb:1406:9:1406:9 | a [element 2] | -| array_flow.rb:1405:16:1405:26 | call to source | array_flow.rb:1405:5:1405:5 | a [element 2] | -| array_flow.rb:1405:16:1405:26 | call to source | array_flow.rb:1405:5:1405:5 | a [element 2] | -| array_flow.rb:1406:5:1406:5 | b [element] | array_flow.rb:1410:10:1410:10 | b [element] | -| array_flow.rb:1406:5:1406:5 | b [element] | array_flow.rb:1410:10:1410:10 | b [element] | -| array_flow.rb:1406:5:1406:5 | b [element] | array_flow.rb:1411:10:1411:10 | b [element] | -| array_flow.rb:1406:5:1406:5 | b [element] | array_flow.rb:1411:10:1411:10 | b [element] | -| array_flow.rb:1406:9:1406:9 | a [element 2] | array_flow.rb:1406:9:1409:7 | call to sort_by [element] | -| array_flow.rb:1406:9:1406:9 | a [element 2] | array_flow.rb:1406:9:1409:7 | call to sort_by [element] | -| array_flow.rb:1406:9:1406:9 | a [element 2] | array_flow.rb:1406:23:1406:23 | x | -| array_flow.rb:1406:9:1406:9 | a [element 2] | array_flow.rb:1406:23:1406:23 | x | -| array_flow.rb:1406:9:1409:7 | call to sort_by [element] | array_flow.rb:1406:5:1406:5 | b [element] | -| array_flow.rb:1406:9:1409:7 | call to sort_by [element] | array_flow.rb:1406:5:1406:5 | b [element] | -| array_flow.rb:1406:23:1406:23 | x | array_flow.rb:1407:14:1407:14 | x | -| array_flow.rb:1406:23:1406:23 | x | array_flow.rb:1407:14:1407:14 | x | +| array_flow.rb:1403:5:1403:5 | a [element 2] | array_flow.rb:1404:9:1404:9 | a [element 2] | +| array_flow.rb:1403:5:1403:5 | a [element 2] | array_flow.rb:1404:9:1404:9 | a [element 2] | +| array_flow.rb:1403:16:1403:26 | call to source | array_flow.rb:1403:5:1403:5 | a [element 2] | +| array_flow.rb:1403:16:1403:26 | call to source | array_flow.rb:1403:5:1403:5 | a [element 2] | +| array_flow.rb:1404:5:1404:5 | b [element] | array_flow.rb:1409:10:1409:10 | b [element] | +| array_flow.rb:1404:5:1404:5 | b [element] | array_flow.rb:1409:10:1409:10 | b [element] | +| array_flow.rb:1404:5:1404:5 | b [element] | array_flow.rb:1410:10:1410:10 | b [element] | +| array_flow.rb:1404:5:1404:5 | b [element] | array_flow.rb:1410:10:1410:10 | b [element] | +| array_flow.rb:1404:9:1404:9 | [post] a [element] | array_flow.rb:1411:10:1411:10 | a [element] | +| array_flow.rb:1404:9:1404:9 | [post] a [element] | array_flow.rb:1411:10:1411:10 | a [element] | +| array_flow.rb:1404:9:1404:9 | [post] a [element] | array_flow.rb:1412:10:1412:10 | a [element] | +| array_flow.rb:1404:9:1404:9 | [post] a [element] | array_flow.rb:1412:10:1412:10 | a [element] | +| array_flow.rb:1404:9:1404:9 | a [element 2] | array_flow.rb:1404:9:1404:9 | [post] a [element] | +| array_flow.rb:1404:9:1404:9 | a [element 2] | array_flow.rb:1404:9:1404:9 | [post] a [element] | +| array_flow.rb:1404:9:1404:9 | a [element 2] | array_flow.rb:1404:9:1408:7 | call to sort! [element] | +| array_flow.rb:1404:9:1404:9 | a [element 2] | array_flow.rb:1404:9:1408:7 | call to sort! [element] | +| array_flow.rb:1404:9:1404:9 | a [element 2] | array_flow.rb:1404:21:1404:21 | x | +| array_flow.rb:1404:9:1404:9 | a [element 2] | array_flow.rb:1404:21:1404:21 | x | +| array_flow.rb:1404:9:1404:9 | a [element 2] | array_flow.rb:1404:24:1404:24 | y | +| array_flow.rb:1404:9:1404:9 | a [element 2] | array_flow.rb:1404:24:1404:24 | y | +| array_flow.rb:1404:9:1408:7 | call to sort! [element] | array_flow.rb:1404:5:1404:5 | b [element] | +| array_flow.rb:1404:9:1408:7 | call to sort! [element] | array_flow.rb:1404:5:1404:5 | b [element] | +| array_flow.rb:1404:21:1404:21 | x | array_flow.rb:1405:14:1405:14 | x | +| array_flow.rb:1404:21:1404:21 | x | array_flow.rb:1405:14:1405:14 | x | +| array_flow.rb:1404:24:1404:24 | y | array_flow.rb:1406:14:1406:14 | y | +| array_flow.rb:1404:24:1404:24 | y | array_flow.rb:1406:14:1406:14 | y | +| array_flow.rb:1409:10:1409:10 | b [element] | array_flow.rb:1409:10:1409:13 | ...[...] | +| array_flow.rb:1409:10:1409:10 | b [element] | array_flow.rb:1409:10:1409:13 | ...[...] | | array_flow.rb:1410:10:1410:10 | b [element] | array_flow.rb:1410:10:1410:13 | ...[...] | | array_flow.rb:1410:10:1410:10 | b [element] | array_flow.rb:1410:10:1410:13 | ...[...] | -| array_flow.rb:1411:10:1411:10 | b [element] | array_flow.rb:1411:10:1411:13 | ...[...] | -| array_flow.rb:1411:10:1411:10 | b [element] | array_flow.rb:1411:10:1411:13 | ...[...] | -| array_flow.rb:1415:5:1415:5 | a [element 2] | array_flow.rb:1416:9:1416:9 | a [element 2] | -| array_flow.rb:1415:5:1415:5 | a [element 2] | array_flow.rb:1416:9:1416:9 | a [element 2] | -| array_flow.rb:1415:16:1415:26 | call to source | array_flow.rb:1415:5:1415:5 | a [element 2] | -| array_flow.rb:1415:16:1415:26 | call to source | array_flow.rb:1415:5:1415:5 | a [element 2] | -| array_flow.rb:1416:5:1416:5 | b [element] | array_flow.rb:1422:10:1422:10 | b [element] | -| array_flow.rb:1416:5:1416:5 | b [element] | array_flow.rb:1422:10:1422:10 | b [element] | -| array_flow.rb:1416:5:1416:5 | b [element] | array_flow.rb:1423:10:1423:10 | b [element] | -| array_flow.rb:1416:5:1416:5 | b [element] | array_flow.rb:1423:10:1423:10 | b [element] | -| array_flow.rb:1416:9:1416:9 | [post] a [element] | array_flow.rb:1420:10:1420:10 | a [element] | -| array_flow.rb:1416:9:1416:9 | [post] a [element] | array_flow.rb:1420:10:1420:10 | a [element] | -| array_flow.rb:1416:9:1416:9 | [post] a [element] | array_flow.rb:1421:10:1421:10 | a [element] | -| array_flow.rb:1416:9:1416:9 | [post] a [element] | array_flow.rb:1421:10:1421:10 | a [element] | -| array_flow.rb:1416:9:1416:9 | a [element 2] | array_flow.rb:1416:9:1416:9 | [post] a [element] | -| array_flow.rb:1416:9:1416:9 | a [element 2] | array_flow.rb:1416:9:1416:9 | [post] a [element] | -| array_flow.rb:1416:9:1416:9 | a [element 2] | array_flow.rb:1416:9:1419:7 | call to sort_by! [element] | -| array_flow.rb:1416:9:1416:9 | a [element 2] | array_flow.rb:1416:9:1419:7 | call to sort_by! [element] | -| array_flow.rb:1416:9:1416:9 | a [element 2] | array_flow.rb:1416:24:1416:24 | x | -| array_flow.rb:1416:9:1416:9 | a [element 2] | array_flow.rb:1416:24:1416:24 | x | -| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] | array_flow.rb:1416:5:1416:5 | b [element] | -| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] | array_flow.rb:1416:5:1416:5 | b [element] | -| array_flow.rb:1416:24:1416:24 | x | array_flow.rb:1417:14:1417:14 | x | -| array_flow.rb:1416:24:1416:24 | x | array_flow.rb:1417:14:1417:14 | x | -| array_flow.rb:1420:10:1420:10 | a [element] | array_flow.rb:1420:10:1420:13 | ...[...] | -| array_flow.rb:1420:10:1420:10 | a [element] | array_flow.rb:1420:10:1420:13 | ...[...] | -| array_flow.rb:1421:10:1421:10 | a [element] | array_flow.rb:1421:10:1421:13 | ...[...] | -| array_flow.rb:1421:10:1421:10 | a [element] | array_flow.rb:1421:10:1421:13 | ...[...] | +| array_flow.rb:1411:10:1411:10 | a [element] | array_flow.rb:1411:10:1411:13 | ...[...] | +| array_flow.rb:1411:10:1411:10 | a [element] | array_flow.rb:1411:10:1411:13 | ...[...] | +| array_flow.rb:1412:10:1412:10 | a [element] | array_flow.rb:1412:10:1412:13 | ...[...] | +| array_flow.rb:1412:10:1412:10 | a [element] | array_flow.rb:1412:10:1412:13 | ...[...] | +| array_flow.rb:1416:5:1416:5 | a [element 2] | array_flow.rb:1417:9:1417:9 | a [element 2] | +| array_flow.rb:1416:5:1416:5 | a [element 2] | array_flow.rb:1417:9:1417:9 | a [element 2] | +| array_flow.rb:1416:16:1416:26 | call to source | array_flow.rb:1416:5:1416:5 | a [element 2] | +| array_flow.rb:1416:16:1416:26 | call to source | array_flow.rb:1416:5:1416:5 | a [element 2] | +| array_flow.rb:1417:5:1417:5 | b [element] | array_flow.rb:1421:10:1421:10 | b [element] | +| array_flow.rb:1417:5:1417:5 | b [element] | array_flow.rb:1421:10:1421:10 | b [element] | +| array_flow.rb:1417:5:1417:5 | b [element] | array_flow.rb:1422:10:1422:10 | b [element] | +| array_flow.rb:1417:5:1417:5 | b [element] | array_flow.rb:1422:10:1422:10 | b [element] | +| array_flow.rb:1417:9:1417:9 | a [element 2] | array_flow.rb:1417:9:1420:7 | call to sort_by [element] | +| array_flow.rb:1417:9:1417:9 | a [element 2] | array_flow.rb:1417:9:1420:7 | call to sort_by [element] | +| array_flow.rb:1417:9:1417:9 | a [element 2] | array_flow.rb:1417:23:1417:23 | x | +| array_flow.rb:1417:9:1417:9 | a [element 2] | array_flow.rb:1417:23:1417:23 | x | +| array_flow.rb:1417:9:1420:7 | call to sort_by [element] | array_flow.rb:1417:5:1417:5 | b [element] | +| array_flow.rb:1417:9:1420:7 | call to sort_by [element] | array_flow.rb:1417:5:1417:5 | b [element] | +| array_flow.rb:1417:23:1417:23 | x | array_flow.rb:1418:14:1418:14 | x | +| array_flow.rb:1417:23:1417:23 | x | array_flow.rb:1418:14:1418:14 | x | +| array_flow.rb:1421:10:1421:10 | b [element] | array_flow.rb:1421:10:1421:13 | ...[...] | +| array_flow.rb:1421:10:1421:10 | b [element] | array_flow.rb:1421:10:1421:13 | ...[...] | | array_flow.rb:1422:10:1422:10 | b [element] | array_flow.rb:1422:10:1422:13 | ...[...] | | array_flow.rb:1422:10:1422:10 | b [element] | array_flow.rb:1422:10:1422:13 | ...[...] | -| array_flow.rb:1423:10:1423:10 | b [element] | array_flow.rb:1423:10:1423:13 | ...[...] | -| array_flow.rb:1423:10:1423:10 | b [element] | array_flow.rb:1423:10:1423:13 | ...[...] | -| array_flow.rb:1427:5:1427:5 | a [element 2] | array_flow.rb:1428:9:1428:9 | a [element 2] | -| array_flow.rb:1427:5:1427:5 | a [element 2] | array_flow.rb:1428:9:1428:9 | a [element 2] | -| array_flow.rb:1427:16:1427:26 | call to source | array_flow.rb:1427:5:1427:5 | a [element 2] | -| array_flow.rb:1427:16:1427:26 | call to source | array_flow.rb:1427:5:1427:5 | a [element 2] | -| array_flow.rb:1428:9:1428:9 | a [element 2] | array_flow.rb:1428:19:1428:19 | x | -| array_flow.rb:1428:9:1428:9 | a [element 2] | array_flow.rb:1428:19:1428:19 | x | -| array_flow.rb:1428:19:1428:19 | x | array_flow.rb:1429:14:1429:14 | x | -| array_flow.rb:1428:19:1428:19 | x | array_flow.rb:1429:14:1429:14 | x | -| array_flow.rb:1435:5:1435:5 | a [element 2] | array_flow.rb:1436:9:1436:9 | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 2] | array_flow.rb:1436:9:1436:9 | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 2] | array_flow.rb:1441:9:1441:9 | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 2] | array_flow.rb:1441:9:1441:9 | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 2] | array_flow.rb:1447:9:1447:9 | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 2] | array_flow.rb:1447:9:1447:9 | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 2] | array_flow.rb:1454:9:1454:9 | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 2] | array_flow.rb:1454:9:1454:9 | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 3] | array_flow.rb:1436:9:1436:9 | a [element 3] | -| array_flow.rb:1435:5:1435:5 | a [element 3] | array_flow.rb:1436:9:1436:9 | a [element 3] | -| array_flow.rb:1435:5:1435:5 | a [element 3] | array_flow.rb:1447:9:1447:9 | a [element 3] | -| array_flow.rb:1435:5:1435:5 | a [element 3] | array_flow.rb:1447:9:1447:9 | a [element 3] | -| array_flow.rb:1435:16:1435:28 | call to source | array_flow.rb:1435:5:1435:5 | a [element 2] | -| array_flow.rb:1435:16:1435:28 | call to source | array_flow.rb:1435:5:1435:5 | a [element 2] | -| array_flow.rb:1435:31:1435:43 | call to source | array_flow.rb:1435:5:1435:5 | a [element 3] | -| array_flow.rb:1435:31:1435:43 | call to source | array_flow.rb:1435:5:1435:5 | a [element 3] | -| array_flow.rb:1436:5:1436:5 | b [element 2] | array_flow.rb:1439:10:1439:10 | b [element 2] | -| array_flow.rb:1436:5:1436:5 | b [element 2] | array_flow.rb:1439:10:1439:10 | b [element 2] | -| array_flow.rb:1436:5:1436:5 | b [element 3] | array_flow.rb:1440:10:1440:10 | b [element 3] | -| array_flow.rb:1436:5:1436:5 | b [element 3] | array_flow.rb:1440:10:1440:10 | b [element 3] | -| array_flow.rb:1436:9:1436:9 | a [element 2] | array_flow.rb:1436:9:1436:17 | call to take [element 2] | -| array_flow.rb:1436:9:1436:9 | a [element 2] | array_flow.rb:1436:9:1436:17 | call to take [element 2] | -| array_flow.rb:1436:9:1436:9 | a [element 3] | array_flow.rb:1436:9:1436:17 | call to take [element 3] | -| array_flow.rb:1436:9:1436:9 | a [element 3] | array_flow.rb:1436:9:1436:17 | call to take [element 3] | -| array_flow.rb:1436:9:1436:17 | call to take [element 2] | array_flow.rb:1436:5:1436:5 | b [element 2] | -| array_flow.rb:1436:9:1436:17 | call to take [element 2] | array_flow.rb:1436:5:1436:5 | b [element 2] | -| array_flow.rb:1436:9:1436:17 | call to take [element 3] | array_flow.rb:1436:5:1436:5 | b [element 3] | -| array_flow.rb:1436:9:1436:17 | call to take [element 3] | array_flow.rb:1436:5:1436:5 | b [element 3] | -| array_flow.rb:1439:10:1439:10 | b [element 2] | array_flow.rb:1439:10:1439:13 | ...[...] | -| array_flow.rb:1439:10:1439:10 | b [element 2] | array_flow.rb:1439:10:1439:13 | ...[...] | -| array_flow.rb:1440:10:1440:10 | b [element 3] | array_flow.rb:1440:10:1440:13 | ...[...] | -| array_flow.rb:1440:10:1440:10 | b [element 3] | array_flow.rb:1440:10:1440:13 | ...[...] | -| array_flow.rb:1441:5:1441:5 | b [element 2] | array_flow.rb:1444:10:1444:10 | b [element 2] | -| array_flow.rb:1441:5:1441:5 | b [element 2] | array_flow.rb:1444:10:1444:10 | b [element 2] | -| array_flow.rb:1441:5:1441:5 | b [element 2] | array_flow.rb:1446:10:1446:10 | b [element 2] | -| array_flow.rb:1441:5:1441:5 | b [element 2] | array_flow.rb:1446:10:1446:10 | b [element 2] | -| array_flow.rb:1441:9:1441:9 | a [element 2] | array_flow.rb:1441:9:1441:17 | call to take [element 2] | -| array_flow.rb:1441:9:1441:9 | a [element 2] | array_flow.rb:1441:9:1441:17 | call to take [element 2] | -| array_flow.rb:1441:9:1441:17 | call to take [element 2] | array_flow.rb:1441:5:1441:5 | b [element 2] | -| array_flow.rb:1441:9:1441:17 | call to take [element 2] | array_flow.rb:1441:5:1441:5 | b [element 2] | -| array_flow.rb:1444:10:1444:10 | b [element 2] | array_flow.rb:1444:10:1444:13 | ...[...] | -| array_flow.rb:1444:10:1444:10 | b [element 2] | array_flow.rb:1444:10:1444:13 | ...[...] | -| array_flow.rb:1446:10:1446:10 | b [element 2] | array_flow.rb:1446:10:1446:13 | ...[...] | -| array_flow.rb:1446:10:1446:10 | b [element 2] | array_flow.rb:1446:10:1446:13 | ...[...] | +| array_flow.rb:1426:5:1426:5 | a [element 2] | array_flow.rb:1427:9:1427:9 | a [element 2] | +| array_flow.rb:1426:5:1426:5 | a [element 2] | array_flow.rb:1427:9:1427:9 | a [element 2] | +| array_flow.rb:1426:16:1426:26 | call to source | array_flow.rb:1426:5:1426:5 | a [element 2] | +| array_flow.rb:1426:16:1426:26 | call to source | array_flow.rb:1426:5:1426:5 | a [element 2] | +| array_flow.rb:1427:5:1427:5 | b [element] | array_flow.rb:1433:10:1433:10 | b [element] | +| array_flow.rb:1427:5:1427:5 | b [element] | array_flow.rb:1433:10:1433:10 | b [element] | +| array_flow.rb:1427:5:1427:5 | b [element] | array_flow.rb:1434:10:1434:10 | b [element] | +| array_flow.rb:1427:5:1427:5 | b [element] | array_flow.rb:1434:10:1434:10 | b [element] | +| array_flow.rb:1427:9:1427:9 | [post] a [element] | array_flow.rb:1431:10:1431:10 | a [element] | +| array_flow.rb:1427:9:1427:9 | [post] a [element] | array_flow.rb:1431:10:1431:10 | a [element] | +| array_flow.rb:1427:9:1427:9 | [post] a [element] | array_flow.rb:1432:10:1432:10 | a [element] | +| array_flow.rb:1427:9:1427:9 | [post] a [element] | array_flow.rb:1432:10:1432:10 | a [element] | +| array_flow.rb:1427:9:1427:9 | a [element 2] | array_flow.rb:1427:9:1427:9 | [post] a [element] | +| array_flow.rb:1427:9:1427:9 | a [element 2] | array_flow.rb:1427:9:1427:9 | [post] a [element] | +| array_flow.rb:1427:9:1427:9 | a [element 2] | array_flow.rb:1427:9:1430:7 | call to sort_by! [element] | +| array_flow.rb:1427:9:1427:9 | a [element 2] | array_flow.rb:1427:9:1430:7 | call to sort_by! [element] | +| array_flow.rb:1427:9:1427:9 | a [element 2] | array_flow.rb:1427:24:1427:24 | x | +| array_flow.rb:1427:9:1427:9 | a [element 2] | array_flow.rb:1427:24:1427:24 | x | +| array_flow.rb:1427:9:1430:7 | call to sort_by! [element] | array_flow.rb:1427:5:1427:5 | b [element] | +| array_flow.rb:1427:9:1430:7 | call to sort_by! [element] | array_flow.rb:1427:5:1427:5 | b [element] | +| array_flow.rb:1427:24:1427:24 | x | array_flow.rb:1428:14:1428:14 | x | +| array_flow.rb:1427:24:1427:24 | x | array_flow.rb:1428:14:1428:14 | x | +| array_flow.rb:1431:10:1431:10 | a [element] | array_flow.rb:1431:10:1431:13 | ...[...] | +| array_flow.rb:1431:10:1431:10 | a [element] | array_flow.rb:1431:10:1431:13 | ...[...] | +| array_flow.rb:1432:10:1432:10 | a [element] | array_flow.rb:1432:10:1432:13 | ...[...] | +| array_flow.rb:1432:10:1432:10 | a [element] | array_flow.rb:1432:10:1432:13 | ...[...] | +| array_flow.rb:1433:10:1433:10 | b [element] | array_flow.rb:1433:10:1433:13 | ...[...] | +| array_flow.rb:1433:10:1433:10 | b [element] | array_flow.rb:1433:10:1433:13 | ...[...] | +| array_flow.rb:1434:10:1434:10 | b [element] | array_flow.rb:1434:10:1434:13 | ...[...] | +| array_flow.rb:1434:10:1434:10 | b [element] | array_flow.rb:1434:10:1434:13 | ...[...] | +| array_flow.rb:1438:5:1438:5 | a [element 2] | array_flow.rb:1439:9:1439:9 | a [element 2] | +| array_flow.rb:1438:5:1438:5 | a [element 2] | array_flow.rb:1439:9:1439:9 | a [element 2] | +| array_flow.rb:1438:16:1438:26 | call to source | array_flow.rb:1438:5:1438:5 | a [element 2] | +| array_flow.rb:1438:16:1438:26 | call to source | array_flow.rb:1438:5:1438:5 | a [element 2] | +| array_flow.rb:1439:9:1439:9 | a [element 2] | array_flow.rb:1439:19:1439:19 | x | +| array_flow.rb:1439:9:1439:9 | a [element 2] | array_flow.rb:1439:19:1439:19 | x | +| array_flow.rb:1439:19:1439:19 | x | array_flow.rb:1440:14:1440:14 | x | +| array_flow.rb:1439:19:1439:19 | x | array_flow.rb:1440:14:1440:14 | x | +| array_flow.rb:1446:5:1446:5 | a [element 2] | array_flow.rb:1447:9:1447:9 | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 2] | array_flow.rb:1447:9:1447:9 | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 2] | array_flow.rb:1452:9:1452:9 | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 2] | array_flow.rb:1452:9:1452:9 | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 2] | array_flow.rb:1458:9:1458:9 | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 2] | array_flow.rb:1458:9:1458:9 | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 2] | array_flow.rb:1465:9:1465:9 | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 2] | array_flow.rb:1465:9:1465:9 | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 3] | array_flow.rb:1447:9:1447:9 | a [element 3] | +| array_flow.rb:1446:5:1446:5 | a [element 3] | array_flow.rb:1447:9:1447:9 | a [element 3] | +| array_flow.rb:1446:5:1446:5 | a [element 3] | array_flow.rb:1458:9:1458:9 | a [element 3] | +| array_flow.rb:1446:5:1446:5 | a [element 3] | array_flow.rb:1458:9:1458:9 | a [element 3] | +| array_flow.rb:1446:16:1446:28 | call to source | array_flow.rb:1446:5:1446:5 | a [element 2] | +| array_flow.rb:1446:16:1446:28 | call to source | array_flow.rb:1446:5:1446:5 | a [element 2] | +| array_flow.rb:1446:31:1446:43 | call to source | array_flow.rb:1446:5:1446:5 | a [element 3] | +| array_flow.rb:1446:31:1446:43 | call to source | array_flow.rb:1446:5:1446:5 | a [element 3] | | array_flow.rb:1447:5:1447:5 | b [element 2] | array_flow.rb:1450:10:1450:10 | b [element 2] | | array_flow.rb:1447:5:1447:5 | b [element 2] | array_flow.rb:1450:10:1450:10 | b [element 2] | -| array_flow.rb:1447:5:1447:5 | b [element 2] | array_flow.rb:1452:10:1452:10 | b [element 2] | -| array_flow.rb:1447:5:1447:5 | b [element 2] | array_flow.rb:1452:10:1452:10 | b [element 2] | | array_flow.rb:1447:5:1447:5 | b [element 3] | array_flow.rb:1451:10:1451:10 | b [element 3] | | array_flow.rb:1447:5:1447:5 | b [element 3] | array_flow.rb:1451:10:1451:10 | b [element 3] | -| array_flow.rb:1447:5:1447:5 | b [element 3] | array_flow.rb:1452:10:1452:10 | b [element 3] | -| array_flow.rb:1447:5:1447:5 | b [element 3] | array_flow.rb:1452:10:1452:10 | b [element 3] | -| array_flow.rb:1447:9:1447:9 | a [element 2] | array_flow.rb:1447:9:1447:19 | call to take [element 2] | -| array_flow.rb:1447:9:1447:9 | a [element 2] | array_flow.rb:1447:9:1447:19 | call to take [element 2] | -| array_flow.rb:1447:9:1447:9 | a [element 3] | array_flow.rb:1447:9:1447:19 | call to take [element 3] | -| array_flow.rb:1447:9:1447:9 | a [element 3] | array_flow.rb:1447:9:1447:19 | call to take [element 3] | -| array_flow.rb:1447:9:1447:19 | call to take [element 2] | array_flow.rb:1447:5:1447:5 | b [element 2] | -| array_flow.rb:1447:9:1447:19 | call to take [element 2] | array_flow.rb:1447:5:1447:5 | b [element 2] | -| array_flow.rb:1447:9:1447:19 | call to take [element 3] | array_flow.rb:1447:5:1447:5 | b [element 3] | -| array_flow.rb:1447:9:1447:19 | call to take [element 3] | array_flow.rb:1447:5:1447:5 | b [element 3] | +| array_flow.rb:1447:9:1447:9 | a [element 2] | array_flow.rb:1447:9:1447:17 | call to take [element 2] | +| array_flow.rb:1447:9:1447:9 | a [element 2] | array_flow.rb:1447:9:1447:17 | call to take [element 2] | +| array_flow.rb:1447:9:1447:9 | a [element 3] | array_flow.rb:1447:9:1447:17 | call to take [element 3] | +| array_flow.rb:1447:9:1447:9 | a [element 3] | array_flow.rb:1447:9:1447:17 | call to take [element 3] | +| array_flow.rb:1447:9:1447:17 | call to take [element 2] | array_flow.rb:1447:5:1447:5 | b [element 2] | +| array_flow.rb:1447:9:1447:17 | call to take [element 2] | array_flow.rb:1447:5:1447:5 | b [element 2] | +| array_flow.rb:1447:9:1447:17 | call to take [element 3] | array_flow.rb:1447:5:1447:5 | b [element 3] | +| array_flow.rb:1447:9:1447:17 | call to take [element 3] | array_flow.rb:1447:5:1447:5 | b [element 3] | | array_flow.rb:1450:10:1450:10 | b [element 2] | array_flow.rb:1450:10:1450:13 | ...[...] | | array_flow.rb:1450:10:1450:10 | b [element 2] | array_flow.rb:1450:10:1450:13 | ...[...] | | array_flow.rb:1451:10:1451:10 | b [element 3] | array_flow.rb:1451:10:1451:13 | ...[...] | | array_flow.rb:1451:10:1451:10 | b [element 3] | array_flow.rb:1451:10:1451:13 | ...[...] | -| array_flow.rb:1452:10:1452:10 | b [element 2] | array_flow.rb:1452:10:1452:13 | ...[...] | -| array_flow.rb:1452:10:1452:10 | b [element 2] | array_flow.rb:1452:10:1452:13 | ...[...] | -| array_flow.rb:1452:10:1452:10 | b [element 3] | array_flow.rb:1452:10:1452:13 | ...[...] | -| array_flow.rb:1452:10:1452:10 | b [element 3] | array_flow.rb:1452:10:1452:13 | ...[...] | -| array_flow.rb:1453:5:1453:5 | [post] a [element] | array_flow.rb:1454:9:1454:9 | a [element] | -| array_flow.rb:1453:5:1453:5 | [post] a [element] | array_flow.rb:1454:9:1454:9 | a [element] | -| array_flow.rb:1453:12:1453:24 | call to source | array_flow.rb:1453:5:1453:5 | [post] a [element] | -| array_flow.rb:1453:12:1453:24 | call to source | array_flow.rb:1453:5:1453:5 | [post] a [element] | -| array_flow.rb:1454:5:1454:5 | b [element 2] | array_flow.rb:1455:10:1455:10 | b [element 2] | -| array_flow.rb:1454:5:1454:5 | b [element 2] | array_flow.rb:1455:10:1455:10 | b [element 2] | -| array_flow.rb:1454:5:1454:5 | b [element] | array_flow.rb:1455:10:1455:10 | b [element] | -| array_flow.rb:1454:5:1454:5 | b [element] | array_flow.rb:1455:10:1455:10 | b [element] | -| array_flow.rb:1454:9:1454:9 | a [element 2] | array_flow.rb:1454:9:1454:17 | call to take [element 2] | -| array_flow.rb:1454:9:1454:9 | a [element 2] | array_flow.rb:1454:9:1454:17 | call to take [element 2] | -| array_flow.rb:1454:9:1454:9 | a [element] | array_flow.rb:1454:9:1454:17 | call to take [element] | -| array_flow.rb:1454:9:1454:9 | a [element] | array_flow.rb:1454:9:1454:17 | call to take [element] | -| array_flow.rb:1454:9:1454:17 | call to take [element 2] | array_flow.rb:1454:5:1454:5 | b [element 2] | -| array_flow.rb:1454:9:1454:17 | call to take [element 2] | array_flow.rb:1454:5:1454:5 | b [element 2] | -| array_flow.rb:1454:9:1454:17 | call to take [element] | array_flow.rb:1454:5:1454:5 | b [element] | -| array_flow.rb:1454:9:1454:17 | call to take [element] | array_flow.rb:1454:5:1454:5 | b [element] | +| array_flow.rb:1452:5:1452:5 | b [element 2] | array_flow.rb:1455:10:1455:10 | b [element 2] | +| array_flow.rb:1452:5:1452:5 | b [element 2] | array_flow.rb:1455:10:1455:10 | b [element 2] | +| array_flow.rb:1452:5:1452:5 | b [element 2] | array_flow.rb:1457:10:1457:10 | b [element 2] | +| array_flow.rb:1452:5:1452:5 | b [element 2] | array_flow.rb:1457:10:1457:10 | b [element 2] | +| array_flow.rb:1452:9:1452:9 | a [element 2] | array_flow.rb:1452:9:1452:17 | call to take [element 2] | +| array_flow.rb:1452:9:1452:9 | a [element 2] | array_flow.rb:1452:9:1452:17 | call to take [element 2] | +| array_flow.rb:1452:9:1452:17 | call to take [element 2] | array_flow.rb:1452:5:1452:5 | b [element 2] | +| array_flow.rb:1452:9:1452:17 | call to take [element 2] | array_flow.rb:1452:5:1452:5 | b [element 2] | | array_flow.rb:1455:10:1455:10 | b [element 2] | array_flow.rb:1455:10:1455:13 | ...[...] | | array_flow.rb:1455:10:1455:10 | b [element 2] | array_flow.rb:1455:10:1455:13 | ...[...] | -| array_flow.rb:1455:10:1455:10 | b [element] | array_flow.rb:1455:10:1455:13 | ...[...] | -| array_flow.rb:1455:10:1455:10 | b [element] | array_flow.rb:1455:10:1455:13 | ...[...] | -| array_flow.rb:1459:5:1459:5 | a [element 2] | array_flow.rb:1460:9:1460:9 | a [element 2] | -| array_flow.rb:1459:5:1459:5 | a [element 2] | array_flow.rb:1460:9:1460:9 | a [element 2] | -| array_flow.rb:1459:16:1459:26 | call to source | array_flow.rb:1459:5:1459:5 | a [element 2] | -| array_flow.rb:1459:16:1459:26 | call to source | array_flow.rb:1459:5:1459:5 | a [element 2] | -| array_flow.rb:1460:5:1460:5 | b [element 2] | array_flow.rb:1466:10:1466:10 | b [element 2] | -| array_flow.rb:1460:5:1460:5 | b [element 2] | array_flow.rb:1466:10:1466:10 | b [element 2] | -| array_flow.rb:1460:9:1460:9 | a [element 2] | array_flow.rb:1460:9:1463:7 | call to take_while [element 2] | -| array_flow.rb:1460:9:1460:9 | a [element 2] | array_flow.rb:1460:9:1463:7 | call to take_while [element 2] | -| array_flow.rb:1460:9:1460:9 | a [element 2] | array_flow.rb:1460:26:1460:26 | x | -| array_flow.rb:1460:9:1460:9 | a [element 2] | array_flow.rb:1460:26:1460:26 | x | -| array_flow.rb:1460:9:1463:7 | call to take_while [element 2] | array_flow.rb:1460:5:1460:5 | b [element 2] | -| array_flow.rb:1460:9:1463:7 | call to take_while [element 2] | array_flow.rb:1460:5:1460:5 | b [element 2] | -| array_flow.rb:1460:26:1460:26 | x | array_flow.rb:1461:14:1461:14 | x | -| array_flow.rb:1460:26:1460:26 | x | array_flow.rb:1461:14:1461:14 | x | +| array_flow.rb:1457:10:1457:10 | b [element 2] | array_flow.rb:1457:10:1457:13 | ...[...] | +| array_flow.rb:1457:10:1457:10 | b [element 2] | array_flow.rb:1457:10:1457:13 | ...[...] | +| array_flow.rb:1458:5:1458:5 | b [element 2] | array_flow.rb:1461:10:1461:10 | b [element 2] | +| array_flow.rb:1458:5:1458:5 | b [element 2] | array_flow.rb:1461:10:1461:10 | b [element 2] | +| array_flow.rb:1458:5:1458:5 | b [element 2] | array_flow.rb:1463:10:1463:10 | b [element 2] | +| array_flow.rb:1458:5:1458:5 | b [element 2] | array_flow.rb:1463:10:1463:10 | b [element 2] | +| array_flow.rb:1458:5:1458:5 | b [element 3] | array_flow.rb:1462:10:1462:10 | b [element 3] | +| array_flow.rb:1458:5:1458:5 | b [element 3] | array_flow.rb:1462:10:1462:10 | b [element 3] | +| array_flow.rb:1458:5:1458:5 | b [element 3] | array_flow.rb:1463:10:1463:10 | b [element 3] | +| array_flow.rb:1458:5:1458:5 | b [element 3] | array_flow.rb:1463:10:1463:10 | b [element 3] | +| array_flow.rb:1458:9:1458:9 | a [element 2] | array_flow.rb:1458:9:1458:19 | call to take [element 2] | +| array_flow.rb:1458:9:1458:9 | a [element 2] | array_flow.rb:1458:9:1458:19 | call to take [element 2] | +| array_flow.rb:1458:9:1458:9 | a [element 3] | array_flow.rb:1458:9:1458:19 | call to take [element 3] | +| array_flow.rb:1458:9:1458:9 | a [element 3] | array_flow.rb:1458:9:1458:19 | call to take [element 3] | +| array_flow.rb:1458:9:1458:19 | call to take [element 2] | array_flow.rb:1458:5:1458:5 | b [element 2] | +| array_flow.rb:1458:9:1458:19 | call to take [element 2] | array_flow.rb:1458:5:1458:5 | b [element 2] | +| array_flow.rb:1458:9:1458:19 | call to take [element 3] | array_flow.rb:1458:5:1458:5 | b [element 3] | +| array_flow.rb:1458:9:1458:19 | call to take [element 3] | array_flow.rb:1458:5:1458:5 | b [element 3] | +| array_flow.rb:1461:10:1461:10 | b [element 2] | array_flow.rb:1461:10:1461:13 | ...[...] | +| array_flow.rb:1461:10:1461:10 | b [element 2] | array_flow.rb:1461:10:1461:13 | ...[...] | +| array_flow.rb:1462:10:1462:10 | b [element 3] | array_flow.rb:1462:10:1462:13 | ...[...] | +| array_flow.rb:1462:10:1462:10 | b [element 3] | array_flow.rb:1462:10:1462:13 | ...[...] | +| array_flow.rb:1463:10:1463:10 | b [element 2] | array_flow.rb:1463:10:1463:13 | ...[...] | +| array_flow.rb:1463:10:1463:10 | b [element 2] | array_flow.rb:1463:10:1463:13 | ...[...] | +| array_flow.rb:1463:10:1463:10 | b [element 3] | array_flow.rb:1463:10:1463:13 | ...[...] | +| array_flow.rb:1463:10:1463:10 | b [element 3] | array_flow.rb:1463:10:1463:13 | ...[...] | +| array_flow.rb:1464:5:1464:5 | [post] a [element] | array_flow.rb:1465:9:1465:9 | a [element] | +| array_flow.rb:1464:5:1464:5 | [post] a [element] | array_flow.rb:1465:9:1465:9 | a [element] | +| array_flow.rb:1464:12:1464:24 | call to source | array_flow.rb:1464:5:1464:5 | [post] a [element] | +| array_flow.rb:1464:12:1464:24 | call to source | array_flow.rb:1464:5:1464:5 | [post] a [element] | +| array_flow.rb:1465:5:1465:5 | b [element 2] | array_flow.rb:1466:10:1466:10 | b [element 2] | +| array_flow.rb:1465:5:1465:5 | b [element 2] | array_flow.rb:1466:10:1466:10 | b [element 2] | +| array_flow.rb:1465:5:1465:5 | b [element] | array_flow.rb:1466:10:1466:10 | b [element] | +| array_flow.rb:1465:5:1465:5 | b [element] | array_flow.rb:1466:10:1466:10 | b [element] | +| array_flow.rb:1465:9:1465:9 | a [element 2] | array_flow.rb:1465:9:1465:17 | call to take [element 2] | +| array_flow.rb:1465:9:1465:9 | a [element 2] | array_flow.rb:1465:9:1465:17 | call to take [element 2] | +| array_flow.rb:1465:9:1465:9 | a [element] | array_flow.rb:1465:9:1465:17 | call to take [element] | +| array_flow.rb:1465:9:1465:9 | a [element] | array_flow.rb:1465:9:1465:17 | call to take [element] | +| array_flow.rb:1465:9:1465:17 | call to take [element 2] | array_flow.rb:1465:5:1465:5 | b [element 2] | +| array_flow.rb:1465:9:1465:17 | call to take [element 2] | array_flow.rb:1465:5:1465:5 | b [element 2] | +| array_flow.rb:1465:9:1465:17 | call to take [element] | array_flow.rb:1465:5:1465:5 | b [element] | +| array_flow.rb:1465:9:1465:17 | call to take [element] | array_flow.rb:1465:5:1465:5 | b [element] | | array_flow.rb:1466:10:1466:10 | b [element 2] | array_flow.rb:1466:10:1466:13 | ...[...] | | array_flow.rb:1466:10:1466:10 | b [element 2] | array_flow.rb:1466:10:1466:13 | ...[...] | -| array_flow.rb:1472:5:1472:5 | a [element 3] | array_flow.rb:1473:9:1473:9 | a [element 3] | -| array_flow.rb:1472:5:1472:5 | a [element 3] | array_flow.rb:1473:9:1473:9 | a [element 3] | -| array_flow.rb:1472:19:1472:29 | call to source | array_flow.rb:1472:5:1472:5 | a [element 3] | -| array_flow.rb:1472:19:1472:29 | call to source | array_flow.rb:1472:5:1472:5 | a [element 3] | -| array_flow.rb:1473:5:1473:5 | b [element 3] | array_flow.rb:1474:10:1474:10 | b [element 3] | -| array_flow.rb:1473:5:1473:5 | b [element 3] | array_flow.rb:1474:10:1474:10 | b [element 3] | -| array_flow.rb:1473:9:1473:9 | a [element 3] | array_flow.rb:1473:9:1473:14 | call to to_a [element 3] | -| array_flow.rb:1473:9:1473:9 | a [element 3] | array_flow.rb:1473:9:1473:14 | call to to_a [element 3] | -| array_flow.rb:1473:9:1473:14 | call to to_a [element 3] | array_flow.rb:1473:5:1473:5 | b [element 3] | -| array_flow.rb:1473:9:1473:14 | call to to_a [element 3] | array_flow.rb:1473:5:1473:5 | b [element 3] | -| array_flow.rb:1474:10:1474:10 | b [element 3] | array_flow.rb:1474:10:1474:13 | ...[...] | -| array_flow.rb:1474:10:1474:10 | b [element 3] | array_flow.rb:1474:10:1474:13 | ...[...] | -| array_flow.rb:1478:5:1478:5 | a [element 2] | array_flow.rb:1479:9:1479:9 | a [element 2] | -| array_flow.rb:1478:5:1478:5 | a [element 2] | array_flow.rb:1479:9:1479:9 | a [element 2] | -| array_flow.rb:1478:16:1478:26 | call to source | array_flow.rb:1478:5:1478:5 | a [element 2] | -| array_flow.rb:1478:16:1478:26 | call to source | array_flow.rb:1478:5:1478:5 | a [element 2] | -| array_flow.rb:1479:5:1479:5 | b [element 2] | array_flow.rb:1482:10:1482:10 | b [element 2] | -| array_flow.rb:1479:5:1479:5 | b [element 2] | array_flow.rb:1482:10:1482:10 | b [element 2] | -| array_flow.rb:1479:9:1479:9 | a [element 2] | array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] | -| array_flow.rb:1479:9:1479:9 | a [element 2] | array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] | -| array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] | array_flow.rb:1479:5:1479:5 | b [element 2] | -| array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] | array_flow.rb:1479:5:1479:5 | b [element 2] | -| array_flow.rb:1482:10:1482:10 | b [element 2] | array_flow.rb:1482:10:1482:13 | ...[...] | -| array_flow.rb:1482:10:1482:10 | b [element 2] | array_flow.rb:1482:10:1482:13 | ...[...] | -| array_flow.rb:1495:5:1495:5 | a [element 0, element 1] | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 0, element 1] | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 1, element 1] | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 1, element 1] | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 2, element 1] | array_flow.rb:1496:9:1496:9 | a [element 2, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 2, element 1] | array_flow.rb:1496:9:1496:9 | a [element 2, element 1] | -| array_flow.rb:1495:14:1495:26 | call to source | array_flow.rb:1495:5:1495:5 | a [element 0, element 1] | -| array_flow.rb:1495:14:1495:26 | call to source | array_flow.rb:1495:5:1495:5 | a [element 0, element 1] | -| array_flow.rb:1495:34:1495:46 | call to source | array_flow.rb:1495:5:1495:5 | a [element 1, element 1] | -| array_flow.rb:1495:34:1495:46 | call to source | array_flow.rb:1495:5:1495:5 | a [element 1, element 1] | -| array_flow.rb:1495:54:1495:66 | call to source | array_flow.rb:1495:5:1495:5 | a [element 2, element 1] | -| array_flow.rb:1495:54:1495:66 | call to source | array_flow.rb:1495:5:1495:5 | a [element 2, element 1] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 0] | array_flow.rb:1500:10:1500:10 | b [element 1, element 0] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 0] | array_flow.rb:1500:10:1500:10 | b [element 1, element 0] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 1] | array_flow.rb:1501:10:1501:10 | b [element 1, element 1] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 1] | array_flow.rb:1501:10:1501:10 | b [element 1, element 1] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 2] | array_flow.rb:1502:10:1502:10 | b [element 1, element 2] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 2] | array_flow.rb:1502:10:1502:10 | b [element 1, element 2] | -| array_flow.rb:1496:9:1496:9 | a [element 0, element 1] | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] | -| array_flow.rb:1496:9:1496:9 | a [element 0, element 1] | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] | -| array_flow.rb:1496:9:1496:9 | a [element 1, element 1] | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] | -| array_flow.rb:1496:9:1496:9 | a [element 1, element 1] | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] | -| array_flow.rb:1496:9:1496:9 | a [element 2, element 1] | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] | -| array_flow.rb:1496:9:1496:9 | a [element 2, element 1] | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] | array_flow.rb:1496:5:1496:5 | b [element 1, element 0] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] | array_flow.rb:1496:5:1496:5 | b [element 1, element 0] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] | array_flow.rb:1496:5:1496:5 | b [element 1, element 1] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] | array_flow.rb:1496:5:1496:5 | b [element 1, element 1] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] | array_flow.rb:1496:5:1496:5 | b [element 1, element 2] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] | array_flow.rb:1496:5:1496:5 | b [element 1, element 2] | -| array_flow.rb:1500:10:1500:10 | b [element 1, element 0] | array_flow.rb:1500:10:1500:13 | ...[...] [element 0] | -| array_flow.rb:1500:10:1500:10 | b [element 1, element 0] | array_flow.rb:1500:10:1500:13 | ...[...] [element 0] | -| array_flow.rb:1500:10:1500:13 | ...[...] [element 0] | array_flow.rb:1500:10:1500:16 | ...[...] | -| array_flow.rb:1500:10:1500:13 | ...[...] [element 0] | array_flow.rb:1500:10:1500:16 | ...[...] | -| array_flow.rb:1501:10:1501:10 | b [element 1, element 1] | array_flow.rb:1501:10:1501:13 | ...[...] [element 1] | -| array_flow.rb:1501:10:1501:10 | b [element 1, element 1] | array_flow.rb:1501:10:1501:13 | ...[...] [element 1] | -| array_flow.rb:1501:10:1501:13 | ...[...] [element 1] | array_flow.rb:1501:10:1501:16 | ...[...] | -| array_flow.rb:1501:10:1501:13 | ...[...] [element 1] | array_flow.rb:1501:10:1501:16 | ...[...] | -| array_flow.rb:1502:10:1502:10 | b [element 1, element 2] | array_flow.rb:1502:10:1502:13 | ...[...] [element 2] | -| array_flow.rb:1502:10:1502:10 | b [element 1, element 2] | array_flow.rb:1502:10:1502:13 | ...[...] [element 2] | -| array_flow.rb:1502:10:1502:13 | ...[...] [element 2] | array_flow.rb:1502:10:1502:16 | ...[...] | -| array_flow.rb:1502:10:1502:13 | ...[...] [element 2] | array_flow.rb:1502:10:1502:16 | ...[...] | -| array_flow.rb:1506:5:1506:5 | a [element 2] | array_flow.rb:1509:9:1509:9 | a [element 2] | -| array_flow.rb:1506:5:1506:5 | a [element 2] | array_flow.rb:1509:9:1509:9 | a [element 2] | -| array_flow.rb:1506:16:1506:28 | call to source | array_flow.rb:1506:5:1506:5 | a [element 2] | -| array_flow.rb:1506:16:1506:28 | call to source | array_flow.rb:1506:5:1506:5 | a [element 2] | -| array_flow.rb:1507:5:1507:5 | b [element 1] | array_flow.rb:1509:17:1509:17 | b [element 1] | -| array_flow.rb:1507:5:1507:5 | b [element 1] | array_flow.rb:1509:17:1509:17 | b [element 1] | -| array_flow.rb:1507:13:1507:25 | call to source | array_flow.rb:1507:5:1507:5 | b [element 1] | -| array_flow.rb:1507:13:1507:25 | call to source | array_flow.rb:1507:5:1507:5 | b [element 1] | -| array_flow.rb:1508:5:1508:5 | c [element 1] | array_flow.rb:1509:20:1509:20 | c [element 1] | -| array_flow.rb:1508:5:1508:5 | c [element 1] | array_flow.rb:1509:20:1509:20 | c [element 1] | -| array_flow.rb:1508:13:1508:25 | call to source | array_flow.rb:1508:5:1508:5 | c [element 1] | -| array_flow.rb:1508:13:1508:25 | call to source | array_flow.rb:1508:5:1508:5 | c [element 1] | -| array_flow.rb:1509:5:1509:5 | d [element] | array_flow.rb:1510:10:1510:10 | d [element] | -| array_flow.rb:1509:5:1509:5 | d [element] | array_flow.rb:1510:10:1510:10 | d [element] | -| array_flow.rb:1509:5:1509:5 | d [element] | array_flow.rb:1511:10:1511:10 | d [element] | -| array_flow.rb:1509:5:1509:5 | d [element] | array_flow.rb:1511:10:1511:10 | d [element] | -| array_flow.rb:1509:5:1509:5 | d [element] | array_flow.rb:1512:10:1512:10 | d [element] | -| array_flow.rb:1509:5:1509:5 | d [element] | array_flow.rb:1512:10:1512:10 | d [element] | -| array_flow.rb:1509:9:1509:9 | a [element 2] | array_flow.rb:1509:9:1509:21 | call to union [element] | -| array_flow.rb:1509:9:1509:9 | a [element 2] | array_flow.rb:1509:9:1509:21 | call to union [element] | -| array_flow.rb:1509:9:1509:21 | call to union [element] | array_flow.rb:1509:5:1509:5 | d [element] | -| array_flow.rb:1509:9:1509:21 | call to union [element] | array_flow.rb:1509:5:1509:5 | d [element] | -| array_flow.rb:1509:17:1509:17 | b [element 1] | array_flow.rb:1509:9:1509:21 | call to union [element] | -| array_flow.rb:1509:17:1509:17 | b [element 1] | array_flow.rb:1509:9:1509:21 | call to union [element] | -| array_flow.rb:1509:20:1509:20 | c [element 1] | array_flow.rb:1509:9:1509:21 | call to union [element] | -| array_flow.rb:1509:20:1509:20 | c [element 1] | array_flow.rb:1509:9:1509:21 | call to union [element] | -| array_flow.rb:1510:10:1510:10 | d [element] | array_flow.rb:1510:10:1510:13 | ...[...] | -| array_flow.rb:1510:10:1510:10 | d [element] | array_flow.rb:1510:10:1510:13 | ...[...] | -| array_flow.rb:1511:10:1511:10 | d [element] | array_flow.rb:1511:10:1511:13 | ...[...] | -| array_flow.rb:1511:10:1511:10 | d [element] | array_flow.rb:1511:10:1511:13 | ...[...] | -| array_flow.rb:1512:10:1512:10 | d [element] | array_flow.rb:1512:10:1512:13 | ...[...] | -| array_flow.rb:1512:10:1512:10 | d [element] | array_flow.rb:1512:10:1512:13 | ...[...] | -| array_flow.rb:1516:5:1516:5 | a [element 3] | array_flow.rb:1518:9:1518:9 | a [element 3] | -| array_flow.rb:1516:5:1516:5 | a [element 3] | array_flow.rb:1518:9:1518:9 | a [element 3] | -| array_flow.rb:1516:5:1516:5 | a [element 3] | array_flow.rb:1522:9:1522:9 | a [element 3] | -| array_flow.rb:1516:5:1516:5 | a [element 3] | array_flow.rb:1522:9:1522:9 | a [element 3] | -| array_flow.rb:1516:5:1516:5 | a [element 4] | array_flow.rb:1518:9:1518:9 | a [element 4] | -| array_flow.rb:1516:5:1516:5 | a [element 4] | array_flow.rb:1518:9:1518:9 | a [element 4] | -| array_flow.rb:1516:5:1516:5 | a [element 4] | array_flow.rb:1522:9:1522:9 | a [element 4] | -| array_flow.rb:1516:5:1516:5 | a [element 4] | array_flow.rb:1522:9:1522:9 | a [element 4] | -| array_flow.rb:1516:19:1516:31 | call to source | array_flow.rb:1516:5:1516:5 | a [element 3] | -| array_flow.rb:1516:19:1516:31 | call to source | array_flow.rb:1516:5:1516:5 | a [element 3] | -| array_flow.rb:1516:34:1516:46 | call to source | array_flow.rb:1516:5:1516:5 | a [element 4] | -| array_flow.rb:1516:34:1516:46 | call to source | array_flow.rb:1516:5:1516:5 | a [element 4] | -| array_flow.rb:1518:5:1518:5 | b [element] | array_flow.rb:1519:10:1519:10 | b [element] | -| array_flow.rb:1518:5:1518:5 | b [element] | array_flow.rb:1519:10:1519:10 | b [element] | -| array_flow.rb:1518:5:1518:5 | b [element] | array_flow.rb:1520:10:1520:10 | b [element] | -| array_flow.rb:1518:5:1518:5 | b [element] | array_flow.rb:1520:10:1520:10 | b [element] | -| array_flow.rb:1518:9:1518:9 | a [element 3] | array_flow.rb:1518:9:1518:14 | call to uniq [element] | -| array_flow.rb:1518:9:1518:9 | a [element 3] | array_flow.rb:1518:9:1518:14 | call to uniq [element] | -| array_flow.rb:1518:9:1518:9 | a [element 4] | array_flow.rb:1518:9:1518:14 | call to uniq [element] | -| array_flow.rb:1518:9:1518:9 | a [element 4] | array_flow.rb:1518:9:1518:14 | call to uniq [element] | -| array_flow.rb:1518:9:1518:14 | call to uniq [element] | array_flow.rb:1518:5:1518:5 | b [element] | -| array_flow.rb:1518:9:1518:14 | call to uniq [element] | array_flow.rb:1518:5:1518:5 | b [element] | -| array_flow.rb:1519:10:1519:10 | b [element] | array_flow.rb:1519:10:1519:13 | ...[...] | -| array_flow.rb:1519:10:1519:10 | b [element] | array_flow.rb:1519:10:1519:13 | ...[...] | -| array_flow.rb:1520:10:1520:10 | b [element] | array_flow.rb:1520:10:1520:13 | ...[...] | -| array_flow.rb:1520:10:1520:10 | b [element] | array_flow.rb:1520:10:1520:13 | ...[...] | -| array_flow.rb:1522:5:1522:5 | c [element] | array_flow.rb:1526:10:1526:10 | c [element] | -| array_flow.rb:1522:5:1522:5 | c [element] | array_flow.rb:1526:10:1526:10 | c [element] | -| array_flow.rb:1522:9:1522:9 | a [element 3] | array_flow.rb:1522:9:1525:7 | call to uniq [element] | -| array_flow.rb:1522:9:1522:9 | a [element 3] | array_flow.rb:1522:9:1525:7 | call to uniq [element] | -| array_flow.rb:1522:9:1522:9 | a [element 3] | array_flow.rb:1522:20:1522:20 | x | -| array_flow.rb:1522:9:1522:9 | a [element 3] | array_flow.rb:1522:20:1522:20 | x | -| array_flow.rb:1522:9:1522:9 | a [element 4] | array_flow.rb:1522:9:1525:7 | call to uniq [element] | -| array_flow.rb:1522:9:1522:9 | a [element 4] | array_flow.rb:1522:9:1525:7 | call to uniq [element] | -| array_flow.rb:1522:9:1522:9 | a [element 4] | array_flow.rb:1522:20:1522:20 | x | -| array_flow.rb:1522:9:1522:9 | a [element 4] | array_flow.rb:1522:20:1522:20 | x | -| array_flow.rb:1522:9:1525:7 | call to uniq [element] | array_flow.rb:1522:5:1522:5 | c [element] | -| array_flow.rb:1522:9:1525:7 | call to uniq [element] | array_flow.rb:1522:5:1522:5 | c [element] | -| array_flow.rb:1522:20:1522:20 | x | array_flow.rb:1523:14:1523:14 | x | -| array_flow.rb:1522:20:1522:20 | x | array_flow.rb:1523:14:1523:14 | x | -| array_flow.rb:1526:10:1526:10 | c [element] | array_flow.rb:1526:10:1526:13 | ...[...] | -| array_flow.rb:1526:10:1526:10 | c [element] | array_flow.rb:1526:10:1526:13 | ...[...] | -| array_flow.rb:1530:5:1530:5 | a [element 2] | array_flow.rb:1531:9:1531:9 | a [element 2] | -| array_flow.rb:1530:5:1530:5 | a [element 2] | array_flow.rb:1531:9:1531:9 | a [element 2] | -| array_flow.rb:1530:5:1530:5 | a [element 3] | array_flow.rb:1531:9:1531:9 | a [element 3] | -| array_flow.rb:1530:5:1530:5 | a [element 3] | array_flow.rb:1531:9:1531:9 | a [element 3] | -| array_flow.rb:1530:16:1530:28 | call to source | array_flow.rb:1530:5:1530:5 | a [element 2] | -| array_flow.rb:1530:16:1530:28 | call to source | array_flow.rb:1530:5:1530:5 | a [element 2] | -| array_flow.rb:1530:31:1530:43 | call to source | array_flow.rb:1530:5:1530:5 | a [element 3] | -| array_flow.rb:1530:31:1530:43 | call to source | array_flow.rb:1530:5:1530:5 | a [element 3] | -| array_flow.rb:1531:5:1531:5 | b [element] | array_flow.rb:1532:10:1532:10 | b [element] | -| array_flow.rb:1531:5:1531:5 | b [element] | array_flow.rb:1532:10:1532:10 | b [element] | -| array_flow.rb:1531:5:1531:5 | b [element] | array_flow.rb:1533:10:1533:10 | b [element] | -| array_flow.rb:1531:5:1531:5 | b [element] | array_flow.rb:1533:10:1533:10 | b [element] | -| array_flow.rb:1531:9:1531:9 | [post] a [element] | array_flow.rb:1534:10:1534:10 | a [element] | -| array_flow.rb:1531:9:1531:9 | [post] a [element] | array_flow.rb:1534:10:1534:10 | a [element] | -| array_flow.rb:1531:9:1531:9 | [post] a [element] | array_flow.rb:1535:10:1535:10 | a [element] | -| array_flow.rb:1531:9:1531:9 | [post] a [element] | array_flow.rb:1535:10:1535:10 | a [element] | -| array_flow.rb:1531:9:1531:9 | a [element 2] | array_flow.rb:1531:9:1531:9 | [post] a [element] | -| array_flow.rb:1531:9:1531:9 | a [element 2] | array_flow.rb:1531:9:1531:9 | [post] a [element] | -| array_flow.rb:1531:9:1531:9 | a [element 2] | array_flow.rb:1531:9:1531:15 | call to uniq! [element] | -| array_flow.rb:1531:9:1531:9 | a [element 2] | array_flow.rb:1531:9:1531:15 | call to uniq! [element] | -| array_flow.rb:1531:9:1531:9 | a [element 3] | array_flow.rb:1531:9:1531:9 | [post] a [element] | -| array_flow.rb:1531:9:1531:9 | a [element 3] | array_flow.rb:1531:9:1531:9 | [post] a [element] | -| array_flow.rb:1531:9:1531:9 | a [element 3] | array_flow.rb:1531:9:1531:15 | call to uniq! [element] | -| array_flow.rb:1531:9:1531:9 | a [element 3] | array_flow.rb:1531:9:1531:15 | call to uniq! [element] | -| array_flow.rb:1531:9:1531:15 | call to uniq! [element] | array_flow.rb:1531:5:1531:5 | b [element] | -| array_flow.rb:1531:9:1531:15 | call to uniq! [element] | array_flow.rb:1531:5:1531:5 | b [element] | -| array_flow.rb:1532:10:1532:10 | b [element] | array_flow.rb:1532:10:1532:13 | ...[...] | -| array_flow.rb:1532:10:1532:10 | b [element] | array_flow.rb:1532:10:1532:13 | ...[...] | -| array_flow.rb:1533:10:1533:10 | b [element] | array_flow.rb:1533:10:1533:13 | ...[...] | -| array_flow.rb:1533:10:1533:10 | b [element] | array_flow.rb:1533:10:1533:13 | ...[...] | -| array_flow.rb:1534:10:1534:10 | a [element] | array_flow.rb:1534:10:1534:13 | ...[...] | -| array_flow.rb:1534:10:1534:10 | a [element] | array_flow.rb:1534:10:1534:13 | ...[...] | -| array_flow.rb:1535:10:1535:10 | a [element] | array_flow.rb:1535:10:1535:13 | ...[...] | -| array_flow.rb:1535:10:1535:10 | a [element] | array_flow.rb:1535:10:1535:13 | ...[...] | -| array_flow.rb:1537:5:1537:5 | a [element 2] | array_flow.rb:1538:9:1538:9 | a [element 2] | -| array_flow.rb:1537:5:1537:5 | a [element 2] | array_flow.rb:1538:9:1538:9 | a [element 2] | -| array_flow.rb:1537:5:1537:5 | a [element 3] | array_flow.rb:1538:9:1538:9 | a [element 3] | -| array_flow.rb:1537:5:1537:5 | a [element 3] | array_flow.rb:1538:9:1538:9 | a [element 3] | -| array_flow.rb:1537:16:1537:28 | call to source | array_flow.rb:1537:5:1537:5 | a [element 2] | -| array_flow.rb:1537:16:1537:28 | call to source | array_flow.rb:1537:5:1537:5 | a [element 2] | -| array_flow.rb:1537:31:1537:43 | call to source | array_flow.rb:1537:5:1537:5 | a [element 3] | -| array_flow.rb:1537:31:1537:43 | call to source | array_flow.rb:1537:5:1537:5 | a [element 3] | -| array_flow.rb:1538:5:1538:5 | b [element] | array_flow.rb:1542:10:1542:10 | b [element] | -| array_flow.rb:1538:5:1538:5 | b [element] | array_flow.rb:1542:10:1542:10 | b [element] | -| array_flow.rb:1538:5:1538:5 | b [element] | array_flow.rb:1543:10:1543:10 | b [element] | -| array_flow.rb:1538:5:1538:5 | b [element] | array_flow.rb:1543:10:1543:10 | b [element] | -| array_flow.rb:1538:9:1538:9 | [post] a [element] | array_flow.rb:1544:10:1544:10 | a [element] | -| array_flow.rb:1538:9:1538:9 | [post] a [element] | array_flow.rb:1544:10:1544:10 | a [element] | -| array_flow.rb:1538:9:1538:9 | [post] a [element] | array_flow.rb:1545:10:1545:10 | a [element] | -| array_flow.rb:1538:9:1538:9 | [post] a [element] | array_flow.rb:1545:10:1545:10 | a [element] | -| array_flow.rb:1538:9:1538:9 | a [element 2] | array_flow.rb:1538:9:1538:9 | [post] a [element] | -| array_flow.rb:1538:9:1538:9 | a [element 2] | array_flow.rb:1538:9:1538:9 | [post] a [element] | -| array_flow.rb:1538:9:1538:9 | a [element 2] | array_flow.rb:1538:9:1541:7 | call to uniq! [element] | -| array_flow.rb:1538:9:1538:9 | a [element 2] | array_flow.rb:1538:9:1541:7 | call to uniq! [element] | -| array_flow.rb:1538:9:1538:9 | a [element 2] | array_flow.rb:1538:21:1538:21 | x | -| array_flow.rb:1538:9:1538:9 | a [element 2] | array_flow.rb:1538:21:1538:21 | x | -| array_flow.rb:1538:9:1538:9 | a [element 3] | array_flow.rb:1538:9:1538:9 | [post] a [element] | -| array_flow.rb:1538:9:1538:9 | a [element 3] | array_flow.rb:1538:9:1538:9 | [post] a [element] | -| array_flow.rb:1538:9:1538:9 | a [element 3] | array_flow.rb:1538:9:1541:7 | call to uniq! [element] | -| array_flow.rb:1538:9:1538:9 | a [element 3] | array_flow.rb:1538:9:1541:7 | call to uniq! [element] | -| array_flow.rb:1538:9:1538:9 | a [element 3] | array_flow.rb:1538:21:1538:21 | x | -| array_flow.rb:1538:9:1538:9 | a [element 3] | array_flow.rb:1538:21:1538:21 | x | -| array_flow.rb:1538:9:1541:7 | call to uniq! [element] | array_flow.rb:1538:5:1538:5 | b [element] | -| array_flow.rb:1538:9:1541:7 | call to uniq! [element] | array_flow.rb:1538:5:1538:5 | b [element] | -| array_flow.rb:1538:21:1538:21 | x | array_flow.rb:1539:14:1539:14 | x | -| array_flow.rb:1538:21:1538:21 | x | array_flow.rb:1539:14:1539:14 | x | -| array_flow.rb:1542:10:1542:10 | b [element] | array_flow.rb:1542:10:1542:13 | ...[...] | -| array_flow.rb:1542:10:1542:10 | b [element] | array_flow.rb:1542:10:1542:13 | ...[...] | +| array_flow.rb:1466:10:1466:10 | b [element] | array_flow.rb:1466:10:1466:13 | ...[...] | +| array_flow.rb:1466:10:1466:10 | b [element] | array_flow.rb:1466:10:1466:13 | ...[...] | +| array_flow.rb:1470:5:1470:5 | a [element 2] | array_flow.rb:1471:9:1471:9 | a [element 2] | +| array_flow.rb:1470:5:1470:5 | a [element 2] | array_flow.rb:1471:9:1471:9 | a [element 2] | +| array_flow.rb:1470:16:1470:26 | call to source | array_flow.rb:1470:5:1470:5 | a [element 2] | +| array_flow.rb:1470:16:1470:26 | call to source | array_flow.rb:1470:5:1470:5 | a [element 2] | +| array_flow.rb:1471:5:1471:5 | b [element 2] | array_flow.rb:1477:10:1477:10 | b [element 2] | +| array_flow.rb:1471:5:1471:5 | b [element 2] | array_flow.rb:1477:10:1477:10 | b [element 2] | +| array_flow.rb:1471:9:1471:9 | a [element 2] | array_flow.rb:1471:9:1474:7 | call to take_while [element 2] | +| array_flow.rb:1471:9:1471:9 | a [element 2] | array_flow.rb:1471:9:1474:7 | call to take_while [element 2] | +| array_flow.rb:1471:9:1471:9 | a [element 2] | array_flow.rb:1471:26:1471:26 | x | +| array_flow.rb:1471:9:1471:9 | a [element 2] | array_flow.rb:1471:26:1471:26 | x | +| array_flow.rb:1471:9:1474:7 | call to take_while [element 2] | array_flow.rb:1471:5:1471:5 | b [element 2] | +| array_flow.rb:1471:9:1474:7 | call to take_while [element 2] | array_flow.rb:1471:5:1471:5 | b [element 2] | +| array_flow.rb:1471:26:1471:26 | x | array_flow.rb:1472:14:1472:14 | x | +| array_flow.rb:1471:26:1471:26 | x | array_flow.rb:1472:14:1472:14 | x | +| array_flow.rb:1477:10:1477:10 | b [element 2] | array_flow.rb:1477:10:1477:13 | ...[...] | +| array_flow.rb:1477:10:1477:10 | b [element 2] | array_flow.rb:1477:10:1477:13 | ...[...] | +| array_flow.rb:1483:5:1483:5 | a [element 3] | array_flow.rb:1484:9:1484:9 | a [element 3] | +| array_flow.rb:1483:5:1483:5 | a [element 3] | array_flow.rb:1484:9:1484:9 | a [element 3] | +| array_flow.rb:1483:19:1483:29 | call to source | array_flow.rb:1483:5:1483:5 | a [element 3] | +| array_flow.rb:1483:19:1483:29 | call to source | array_flow.rb:1483:5:1483:5 | a [element 3] | +| array_flow.rb:1484:5:1484:5 | b [element 3] | array_flow.rb:1485:10:1485:10 | b [element 3] | +| array_flow.rb:1484:5:1484:5 | b [element 3] | array_flow.rb:1485:10:1485:10 | b [element 3] | +| array_flow.rb:1484:9:1484:9 | a [element 3] | array_flow.rb:1484:9:1484:14 | call to to_a [element 3] | +| array_flow.rb:1484:9:1484:9 | a [element 3] | array_flow.rb:1484:9:1484:14 | call to to_a [element 3] | +| array_flow.rb:1484:9:1484:14 | call to to_a [element 3] | array_flow.rb:1484:5:1484:5 | b [element 3] | +| array_flow.rb:1484:9:1484:14 | call to to_a [element 3] | array_flow.rb:1484:5:1484:5 | b [element 3] | +| array_flow.rb:1485:10:1485:10 | b [element 3] | array_flow.rb:1485:10:1485:13 | ...[...] | +| array_flow.rb:1485:10:1485:10 | b [element 3] | array_flow.rb:1485:10:1485:13 | ...[...] | +| array_flow.rb:1489:5:1489:5 | a [element 2] | array_flow.rb:1490:9:1490:9 | a [element 2] | +| array_flow.rb:1489:5:1489:5 | a [element 2] | array_flow.rb:1490:9:1490:9 | a [element 2] | +| array_flow.rb:1489:16:1489:26 | call to source | array_flow.rb:1489:5:1489:5 | a [element 2] | +| array_flow.rb:1489:16:1489:26 | call to source | array_flow.rb:1489:5:1489:5 | a [element 2] | +| array_flow.rb:1490:5:1490:5 | b [element 2] | array_flow.rb:1493:10:1493:10 | b [element 2] | +| array_flow.rb:1490:5:1490:5 | b [element 2] | array_flow.rb:1493:10:1493:10 | b [element 2] | +| array_flow.rb:1490:9:1490:9 | a [element 2] | array_flow.rb:1490:9:1490:16 | call to to_ary [element 2] | +| array_flow.rb:1490:9:1490:9 | a [element 2] | array_flow.rb:1490:9:1490:16 | call to to_ary [element 2] | +| array_flow.rb:1490:9:1490:16 | call to to_ary [element 2] | array_flow.rb:1490:5:1490:5 | b [element 2] | +| array_flow.rb:1490:9:1490:16 | call to to_ary [element 2] | array_flow.rb:1490:5:1490:5 | b [element 2] | +| array_flow.rb:1493:10:1493:10 | b [element 2] | array_flow.rb:1493:10:1493:13 | ...[...] | +| array_flow.rb:1493:10:1493:10 | b [element 2] | array_flow.rb:1493:10:1493:13 | ...[...] | +| array_flow.rb:1506:5:1506:5 | a [element 0, element 1] | array_flow.rb:1507:9:1507:9 | a [element 0, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 0, element 1] | array_flow.rb:1507:9:1507:9 | a [element 0, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 1, element 1] | array_flow.rb:1507:9:1507:9 | a [element 1, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 1, element 1] | array_flow.rb:1507:9:1507:9 | a [element 1, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 2, element 1] | array_flow.rb:1507:9:1507:9 | a [element 2, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 2, element 1] | array_flow.rb:1507:9:1507:9 | a [element 2, element 1] | +| array_flow.rb:1506:14:1506:26 | call to source | array_flow.rb:1506:5:1506:5 | a [element 0, element 1] | +| array_flow.rb:1506:14:1506:26 | call to source | array_flow.rb:1506:5:1506:5 | a [element 0, element 1] | +| array_flow.rb:1506:34:1506:46 | call to source | array_flow.rb:1506:5:1506:5 | a [element 1, element 1] | +| array_flow.rb:1506:34:1506:46 | call to source | array_flow.rb:1506:5:1506:5 | a [element 1, element 1] | +| array_flow.rb:1506:54:1506:66 | call to source | array_flow.rb:1506:5:1506:5 | a [element 2, element 1] | +| array_flow.rb:1506:54:1506:66 | call to source | array_flow.rb:1506:5:1506:5 | a [element 2, element 1] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 0] | array_flow.rb:1511:10:1511:10 | b [element 1, element 0] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 0] | array_flow.rb:1511:10:1511:10 | b [element 1, element 0] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 1] | array_flow.rb:1512:10:1512:10 | b [element 1, element 1] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 1] | array_flow.rb:1512:10:1512:10 | b [element 1, element 1] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 2] | array_flow.rb:1513:10:1513:10 | b [element 1, element 2] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 2] | array_flow.rb:1513:10:1513:10 | b [element 1, element 2] | +| array_flow.rb:1507:9:1507:9 | a [element 0, element 1] | array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 0] | +| array_flow.rb:1507:9:1507:9 | a [element 0, element 1] | array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 0] | +| array_flow.rb:1507:9:1507:9 | a [element 1, element 1] | array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 1] | +| array_flow.rb:1507:9:1507:9 | a [element 1, element 1] | array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 1] | +| array_flow.rb:1507:9:1507:9 | a [element 2, element 1] | array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 2] | +| array_flow.rb:1507:9:1507:9 | a [element 2, element 1] | array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 2] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 0] | array_flow.rb:1507:5:1507:5 | b [element 1, element 0] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 0] | array_flow.rb:1507:5:1507:5 | b [element 1, element 0] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 1] | array_flow.rb:1507:5:1507:5 | b [element 1, element 1] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 1] | array_flow.rb:1507:5:1507:5 | b [element 1, element 1] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 2] | array_flow.rb:1507:5:1507:5 | b [element 1, element 2] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 2] | array_flow.rb:1507:5:1507:5 | b [element 1, element 2] | +| array_flow.rb:1511:10:1511:10 | b [element 1, element 0] | array_flow.rb:1511:10:1511:13 | ...[...] [element 0] | +| array_flow.rb:1511:10:1511:10 | b [element 1, element 0] | array_flow.rb:1511:10:1511:13 | ...[...] [element 0] | +| array_flow.rb:1511:10:1511:13 | ...[...] [element 0] | array_flow.rb:1511:10:1511:16 | ...[...] | +| array_flow.rb:1511:10:1511:13 | ...[...] [element 0] | array_flow.rb:1511:10:1511:16 | ...[...] | +| array_flow.rb:1512:10:1512:10 | b [element 1, element 1] | array_flow.rb:1512:10:1512:13 | ...[...] [element 1] | +| array_flow.rb:1512:10:1512:10 | b [element 1, element 1] | array_flow.rb:1512:10:1512:13 | ...[...] [element 1] | +| array_flow.rb:1512:10:1512:13 | ...[...] [element 1] | array_flow.rb:1512:10:1512:16 | ...[...] | +| array_flow.rb:1512:10:1512:13 | ...[...] [element 1] | array_flow.rb:1512:10:1512:16 | ...[...] | +| array_flow.rb:1513:10:1513:10 | b [element 1, element 2] | array_flow.rb:1513:10:1513:13 | ...[...] [element 2] | +| array_flow.rb:1513:10:1513:10 | b [element 1, element 2] | array_flow.rb:1513:10:1513:13 | ...[...] [element 2] | +| array_flow.rb:1513:10:1513:13 | ...[...] [element 2] | array_flow.rb:1513:10:1513:16 | ...[...] | +| array_flow.rb:1513:10:1513:13 | ...[...] [element 2] | array_flow.rb:1513:10:1513:16 | ...[...] | +| array_flow.rb:1517:5:1517:5 | a [element 2] | array_flow.rb:1520:9:1520:9 | a [element 2] | +| array_flow.rb:1517:5:1517:5 | a [element 2] | array_flow.rb:1520:9:1520:9 | a [element 2] | +| array_flow.rb:1517:16:1517:28 | call to source | array_flow.rb:1517:5:1517:5 | a [element 2] | +| array_flow.rb:1517:16:1517:28 | call to source | array_flow.rb:1517:5:1517:5 | a [element 2] | +| array_flow.rb:1518:5:1518:5 | b [element 1] | array_flow.rb:1520:17:1520:17 | b [element 1] | +| array_flow.rb:1518:5:1518:5 | b [element 1] | array_flow.rb:1520:17:1520:17 | b [element 1] | +| array_flow.rb:1518:13:1518:25 | call to source | array_flow.rb:1518:5:1518:5 | b [element 1] | +| array_flow.rb:1518:13:1518:25 | call to source | array_flow.rb:1518:5:1518:5 | b [element 1] | +| array_flow.rb:1519:5:1519:5 | c [element 1] | array_flow.rb:1520:20:1520:20 | c [element 1] | +| array_flow.rb:1519:5:1519:5 | c [element 1] | array_flow.rb:1520:20:1520:20 | c [element 1] | +| array_flow.rb:1519:13:1519:25 | call to source | array_flow.rb:1519:5:1519:5 | c [element 1] | +| array_flow.rb:1519:13:1519:25 | call to source | array_flow.rb:1519:5:1519:5 | c [element 1] | +| array_flow.rb:1520:5:1520:5 | d [element] | array_flow.rb:1521:10:1521:10 | d [element] | +| array_flow.rb:1520:5:1520:5 | d [element] | array_flow.rb:1521:10:1521:10 | d [element] | +| array_flow.rb:1520:5:1520:5 | d [element] | array_flow.rb:1522:10:1522:10 | d [element] | +| array_flow.rb:1520:5:1520:5 | d [element] | array_flow.rb:1522:10:1522:10 | d [element] | +| array_flow.rb:1520:5:1520:5 | d [element] | array_flow.rb:1523:10:1523:10 | d [element] | +| array_flow.rb:1520:5:1520:5 | d [element] | array_flow.rb:1523:10:1523:10 | d [element] | +| array_flow.rb:1520:9:1520:9 | a [element 2] | array_flow.rb:1520:9:1520:21 | call to union [element] | +| array_flow.rb:1520:9:1520:9 | a [element 2] | array_flow.rb:1520:9:1520:21 | call to union [element] | +| array_flow.rb:1520:9:1520:21 | call to union [element] | array_flow.rb:1520:5:1520:5 | d [element] | +| array_flow.rb:1520:9:1520:21 | call to union [element] | array_flow.rb:1520:5:1520:5 | d [element] | +| array_flow.rb:1520:17:1520:17 | b [element 1] | array_flow.rb:1520:9:1520:21 | call to union [element] | +| array_flow.rb:1520:17:1520:17 | b [element 1] | array_flow.rb:1520:9:1520:21 | call to union [element] | +| array_flow.rb:1520:20:1520:20 | c [element 1] | array_flow.rb:1520:9:1520:21 | call to union [element] | +| array_flow.rb:1520:20:1520:20 | c [element 1] | array_flow.rb:1520:9:1520:21 | call to union [element] | +| array_flow.rb:1521:10:1521:10 | d [element] | array_flow.rb:1521:10:1521:13 | ...[...] | +| array_flow.rb:1521:10:1521:10 | d [element] | array_flow.rb:1521:10:1521:13 | ...[...] | +| array_flow.rb:1522:10:1522:10 | d [element] | array_flow.rb:1522:10:1522:13 | ...[...] | +| array_flow.rb:1522:10:1522:10 | d [element] | array_flow.rb:1522:10:1522:13 | ...[...] | +| array_flow.rb:1523:10:1523:10 | d [element] | array_flow.rb:1523:10:1523:13 | ...[...] | +| array_flow.rb:1523:10:1523:10 | d [element] | array_flow.rb:1523:10:1523:13 | ...[...] | +| array_flow.rb:1527:5:1527:5 | a [element 3] | array_flow.rb:1529:9:1529:9 | a [element 3] | +| array_flow.rb:1527:5:1527:5 | a [element 3] | array_flow.rb:1529:9:1529:9 | a [element 3] | +| array_flow.rb:1527:5:1527:5 | a [element 3] | array_flow.rb:1533:9:1533:9 | a [element 3] | +| array_flow.rb:1527:5:1527:5 | a [element 3] | array_flow.rb:1533:9:1533:9 | a [element 3] | +| array_flow.rb:1527:5:1527:5 | a [element 4] | array_flow.rb:1529:9:1529:9 | a [element 4] | +| array_flow.rb:1527:5:1527:5 | a [element 4] | array_flow.rb:1529:9:1529:9 | a [element 4] | +| array_flow.rb:1527:5:1527:5 | a [element 4] | array_flow.rb:1533:9:1533:9 | a [element 4] | +| array_flow.rb:1527:5:1527:5 | a [element 4] | array_flow.rb:1533:9:1533:9 | a [element 4] | +| array_flow.rb:1527:19:1527:31 | call to source | array_flow.rb:1527:5:1527:5 | a [element 3] | +| array_flow.rb:1527:19:1527:31 | call to source | array_flow.rb:1527:5:1527:5 | a [element 3] | +| array_flow.rb:1527:34:1527:46 | call to source | array_flow.rb:1527:5:1527:5 | a [element 4] | +| array_flow.rb:1527:34:1527:46 | call to source | array_flow.rb:1527:5:1527:5 | a [element 4] | +| array_flow.rb:1529:5:1529:5 | b [element] | array_flow.rb:1530:10:1530:10 | b [element] | +| array_flow.rb:1529:5:1529:5 | b [element] | array_flow.rb:1530:10:1530:10 | b [element] | +| array_flow.rb:1529:5:1529:5 | b [element] | array_flow.rb:1531:10:1531:10 | b [element] | +| array_flow.rb:1529:5:1529:5 | b [element] | array_flow.rb:1531:10:1531:10 | b [element] | +| array_flow.rb:1529:9:1529:9 | a [element 3] | array_flow.rb:1529:9:1529:14 | call to uniq [element] | +| array_flow.rb:1529:9:1529:9 | a [element 3] | array_flow.rb:1529:9:1529:14 | call to uniq [element] | +| array_flow.rb:1529:9:1529:9 | a [element 4] | array_flow.rb:1529:9:1529:14 | call to uniq [element] | +| array_flow.rb:1529:9:1529:9 | a [element 4] | array_flow.rb:1529:9:1529:14 | call to uniq [element] | +| array_flow.rb:1529:9:1529:14 | call to uniq [element] | array_flow.rb:1529:5:1529:5 | b [element] | +| array_flow.rb:1529:9:1529:14 | call to uniq [element] | array_flow.rb:1529:5:1529:5 | b [element] | +| array_flow.rb:1530:10:1530:10 | b [element] | array_flow.rb:1530:10:1530:13 | ...[...] | +| array_flow.rb:1530:10:1530:10 | b [element] | array_flow.rb:1530:10:1530:13 | ...[...] | +| array_flow.rb:1531:10:1531:10 | b [element] | array_flow.rb:1531:10:1531:13 | ...[...] | +| array_flow.rb:1531:10:1531:10 | b [element] | array_flow.rb:1531:10:1531:13 | ...[...] | +| array_flow.rb:1533:5:1533:5 | c [element] | array_flow.rb:1537:10:1537:10 | c [element] | +| array_flow.rb:1533:5:1533:5 | c [element] | array_flow.rb:1537:10:1537:10 | c [element] | +| array_flow.rb:1533:9:1533:9 | a [element 3] | array_flow.rb:1533:9:1536:7 | call to uniq [element] | +| array_flow.rb:1533:9:1533:9 | a [element 3] | array_flow.rb:1533:9:1536:7 | call to uniq [element] | +| array_flow.rb:1533:9:1533:9 | a [element 3] | array_flow.rb:1533:20:1533:20 | x | +| array_flow.rb:1533:9:1533:9 | a [element 3] | array_flow.rb:1533:20:1533:20 | x | +| array_flow.rb:1533:9:1533:9 | a [element 4] | array_flow.rb:1533:9:1536:7 | call to uniq [element] | +| array_flow.rb:1533:9:1533:9 | a [element 4] | array_flow.rb:1533:9:1536:7 | call to uniq [element] | +| array_flow.rb:1533:9:1533:9 | a [element 4] | array_flow.rb:1533:20:1533:20 | x | +| array_flow.rb:1533:9:1533:9 | a [element 4] | array_flow.rb:1533:20:1533:20 | x | +| array_flow.rb:1533:9:1536:7 | call to uniq [element] | array_flow.rb:1533:5:1533:5 | c [element] | +| array_flow.rb:1533:9:1536:7 | call to uniq [element] | array_flow.rb:1533:5:1533:5 | c [element] | +| array_flow.rb:1533:20:1533:20 | x | array_flow.rb:1534:14:1534:14 | x | +| array_flow.rb:1533:20:1533:20 | x | array_flow.rb:1534:14:1534:14 | x | +| array_flow.rb:1537:10:1537:10 | c [element] | array_flow.rb:1537:10:1537:13 | ...[...] | +| array_flow.rb:1537:10:1537:10 | c [element] | array_flow.rb:1537:10:1537:13 | ...[...] | +| array_flow.rb:1541:5:1541:5 | a [element 2] | array_flow.rb:1542:9:1542:9 | a [element 2] | +| array_flow.rb:1541:5:1541:5 | a [element 2] | array_flow.rb:1542:9:1542:9 | a [element 2] | +| array_flow.rb:1541:5:1541:5 | a [element 3] | array_flow.rb:1542:9:1542:9 | a [element 3] | +| array_flow.rb:1541:5:1541:5 | a [element 3] | array_flow.rb:1542:9:1542:9 | a [element 3] | +| array_flow.rb:1541:16:1541:28 | call to source | array_flow.rb:1541:5:1541:5 | a [element 2] | +| array_flow.rb:1541:16:1541:28 | call to source | array_flow.rb:1541:5:1541:5 | a [element 2] | +| array_flow.rb:1541:31:1541:43 | call to source | array_flow.rb:1541:5:1541:5 | a [element 3] | +| array_flow.rb:1541:31:1541:43 | call to source | array_flow.rb:1541:5:1541:5 | a [element 3] | +| array_flow.rb:1542:5:1542:5 | b [element] | array_flow.rb:1543:10:1543:10 | b [element] | +| array_flow.rb:1542:5:1542:5 | b [element] | array_flow.rb:1543:10:1543:10 | b [element] | +| array_flow.rb:1542:5:1542:5 | b [element] | array_flow.rb:1544:10:1544:10 | b [element] | +| array_flow.rb:1542:5:1542:5 | b [element] | array_flow.rb:1544:10:1544:10 | b [element] | +| array_flow.rb:1542:9:1542:9 | [post] a [element] | array_flow.rb:1545:10:1545:10 | a [element] | +| array_flow.rb:1542:9:1542:9 | [post] a [element] | array_flow.rb:1545:10:1545:10 | a [element] | +| array_flow.rb:1542:9:1542:9 | [post] a [element] | array_flow.rb:1546:10:1546:10 | a [element] | +| array_flow.rb:1542:9:1542:9 | [post] a [element] | array_flow.rb:1546:10:1546:10 | a [element] | +| array_flow.rb:1542:9:1542:9 | a [element 2] | array_flow.rb:1542:9:1542:9 | [post] a [element] | +| array_flow.rb:1542:9:1542:9 | a [element 2] | array_flow.rb:1542:9:1542:9 | [post] a [element] | +| array_flow.rb:1542:9:1542:9 | a [element 2] | array_flow.rb:1542:9:1542:15 | call to uniq! [element] | +| array_flow.rb:1542:9:1542:9 | a [element 2] | array_flow.rb:1542:9:1542:15 | call to uniq! [element] | +| array_flow.rb:1542:9:1542:9 | a [element 3] | array_flow.rb:1542:9:1542:9 | [post] a [element] | +| array_flow.rb:1542:9:1542:9 | a [element 3] | array_flow.rb:1542:9:1542:9 | [post] a [element] | +| array_flow.rb:1542:9:1542:9 | a [element 3] | array_flow.rb:1542:9:1542:15 | call to uniq! [element] | +| array_flow.rb:1542:9:1542:9 | a [element 3] | array_flow.rb:1542:9:1542:15 | call to uniq! [element] | +| array_flow.rb:1542:9:1542:15 | call to uniq! [element] | array_flow.rb:1542:5:1542:5 | b [element] | +| array_flow.rb:1542:9:1542:15 | call to uniq! [element] | array_flow.rb:1542:5:1542:5 | b [element] | | array_flow.rb:1543:10:1543:10 | b [element] | array_flow.rb:1543:10:1543:13 | ...[...] | | array_flow.rb:1543:10:1543:10 | b [element] | array_flow.rb:1543:10:1543:13 | ...[...] | -| array_flow.rb:1544:10:1544:10 | a [element] | array_flow.rb:1544:10:1544:13 | ...[...] | -| array_flow.rb:1544:10:1544:10 | a [element] | array_flow.rb:1544:10:1544:13 | ...[...] | +| array_flow.rb:1544:10:1544:10 | b [element] | array_flow.rb:1544:10:1544:13 | ...[...] | +| array_flow.rb:1544:10:1544:10 | b [element] | array_flow.rb:1544:10:1544:13 | ...[...] | | array_flow.rb:1545:10:1545:10 | a [element] | array_flow.rb:1545:10:1545:13 | ...[...] | | array_flow.rb:1545:10:1545:10 | a [element] | array_flow.rb:1545:10:1545:13 | ...[...] | -| array_flow.rb:1549:5:1549:5 | a [element 2] | array_flow.rb:1550:5:1550:5 | a [element 2] | -| array_flow.rb:1549:5:1549:5 | a [element 2] | array_flow.rb:1550:5:1550:5 | a [element 2] | -| array_flow.rb:1549:16:1549:28 | call to source | array_flow.rb:1549:5:1549:5 | a [element 2] | -| array_flow.rb:1549:16:1549:28 | call to source | array_flow.rb:1549:5:1549:5 | a [element 2] | -| array_flow.rb:1550:5:1550:5 | [post] a [element 2] | array_flow.rb:1553:10:1553:10 | a [element 2] | -| array_flow.rb:1550:5:1550:5 | [post] a [element 2] | array_flow.rb:1553:10:1553:10 | a [element 2] | -| array_flow.rb:1550:5:1550:5 | [post] a [element 5] | array_flow.rb:1556:10:1556:10 | a [element 5] | -| array_flow.rb:1550:5:1550:5 | [post] a [element 5] | array_flow.rb:1556:10:1556:10 | a [element 5] | -| array_flow.rb:1550:5:1550:5 | a [element 2] | array_flow.rb:1550:5:1550:5 | [post] a [element 5] | -| array_flow.rb:1550:5:1550:5 | a [element 2] | array_flow.rb:1550:5:1550:5 | [post] a [element 5] | -| array_flow.rb:1550:21:1550:33 | call to source | array_flow.rb:1550:5:1550:5 | [post] a [element 2] | -| array_flow.rb:1550:21:1550:33 | call to source | array_flow.rb:1550:5:1550:5 | [post] a [element 2] | -| array_flow.rb:1553:10:1553:10 | a [element 2] | array_flow.rb:1553:10:1553:13 | ...[...] | -| array_flow.rb:1553:10:1553:10 | a [element 2] | array_flow.rb:1553:10:1553:13 | ...[...] | -| array_flow.rb:1556:10:1556:10 | a [element 5] | array_flow.rb:1556:10:1556:13 | ...[...] | -| array_flow.rb:1556:10:1556:10 | a [element 5] | array_flow.rb:1556:10:1556:13 | ...[...] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | array_flow.rb:1562:9:1562:9 | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | array_flow.rb:1562:9:1562:9 | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | array_flow.rb:1568:9:1568:9 | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | array_flow.rb:1568:9:1568:9 | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | array_flow.rb:1572:9:1572:9 | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | array_flow.rb:1572:9:1572:9 | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | array_flow.rb:1576:9:1576:9 | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | array_flow.rb:1576:9:1576:9 | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 3] | array_flow.rb:1568:9:1568:9 | a [element 3] | -| array_flow.rb:1560:5:1560:5 | a [element 3] | array_flow.rb:1568:9:1568:9 | a [element 3] | -| array_flow.rb:1560:5:1560:5 | a [element 3] | array_flow.rb:1572:9:1572:9 | a [element 3] | -| array_flow.rb:1560:5:1560:5 | a [element 3] | array_flow.rb:1572:9:1572:9 | a [element 3] | -| array_flow.rb:1560:5:1560:5 | a [element 3] | array_flow.rb:1576:9:1576:9 | a [element 3] | -| array_flow.rb:1560:5:1560:5 | a [element 3] | array_flow.rb:1576:9:1576:9 | a [element 3] | -| array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1560:5:1560:5 | a [element 1] | -| array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1560:5:1560:5 | a [element 1] | -| array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1560:5:1560:5 | a [element 3] | -| array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1560:5:1560:5 | a [element 3] | -| array_flow.rb:1562:5:1562:5 | b [element 1] | array_flow.rb:1564:10:1564:10 | b [element 1] | -| array_flow.rb:1562:5:1562:5 | b [element 1] | array_flow.rb:1564:10:1564:10 | b [element 1] | -| array_flow.rb:1562:5:1562:5 | b [element 3] | array_flow.rb:1566:10:1566:10 | b [element 3] | -| array_flow.rb:1562:5:1562:5 | b [element 3] | array_flow.rb:1566:10:1566:10 | b [element 3] | -| array_flow.rb:1562:9:1562:9 | a [element 1] | array_flow.rb:1562:9:1562:31 | call to values_at [element 1] | -| array_flow.rb:1562:9:1562:9 | a [element 1] | array_flow.rb:1562:9:1562:31 | call to values_at [element 1] | -| array_flow.rb:1562:9:1562:9 | a [element 1] | array_flow.rb:1562:9:1562:31 | call to values_at [element 3] | -| array_flow.rb:1562:9:1562:9 | a [element 1] | array_flow.rb:1562:9:1562:31 | call to values_at [element 3] | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 1] | array_flow.rb:1562:5:1562:5 | b [element 1] | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 1] | array_flow.rb:1562:5:1562:5 | b [element 1] | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 3] | array_flow.rb:1562:5:1562:5 | b [element 3] | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 3] | array_flow.rb:1562:5:1562:5 | b [element 3] | -| array_flow.rb:1564:10:1564:10 | b [element 1] | array_flow.rb:1564:10:1564:13 | ...[...] | -| array_flow.rb:1564:10:1564:10 | b [element 1] | array_flow.rb:1564:10:1564:13 | ...[...] | -| array_flow.rb:1566:10:1566:10 | b [element 3] | array_flow.rb:1566:10:1566:13 | ...[...] | -| array_flow.rb:1566:10:1566:10 | b [element 3] | array_flow.rb:1566:10:1566:13 | ...[...] | -| array_flow.rb:1568:5:1568:5 | b [element] | array_flow.rb:1569:10:1569:10 | b [element] | -| array_flow.rb:1568:5:1568:5 | b [element] | array_flow.rb:1569:10:1569:10 | b [element] | -| array_flow.rb:1568:5:1568:5 | b [element] | array_flow.rb:1570:10:1570:10 | b [element] | -| array_flow.rb:1568:5:1568:5 | b [element] | array_flow.rb:1570:10:1570:10 | b [element] | -| array_flow.rb:1568:9:1568:9 | a [element 1] | array_flow.rb:1568:9:1568:25 | call to values_at [element] | -| array_flow.rb:1568:9:1568:9 | a [element 1] | array_flow.rb:1568:9:1568:25 | call to values_at [element] | -| array_flow.rb:1568:9:1568:9 | a [element 3] | array_flow.rb:1568:9:1568:25 | call to values_at [element] | -| array_flow.rb:1568:9:1568:9 | a [element 3] | array_flow.rb:1568:9:1568:25 | call to values_at [element] | -| array_flow.rb:1568:9:1568:25 | call to values_at [element] | array_flow.rb:1568:5:1568:5 | b [element] | -| array_flow.rb:1568:9:1568:25 | call to values_at [element] | array_flow.rb:1568:5:1568:5 | b [element] | -| array_flow.rb:1569:10:1569:10 | b [element] | array_flow.rb:1569:10:1569:13 | ...[...] | -| array_flow.rb:1569:10:1569:10 | b [element] | array_flow.rb:1569:10:1569:13 | ...[...] | -| array_flow.rb:1570:10:1570:10 | b [element] | array_flow.rb:1570:10:1570:13 | ...[...] | -| array_flow.rb:1570:10:1570:10 | b [element] | array_flow.rb:1570:10:1570:13 | ...[...] | -| array_flow.rb:1572:5:1572:5 | b [element] | array_flow.rb:1573:10:1573:10 | b [element] | -| array_flow.rb:1572:5:1572:5 | b [element] | array_flow.rb:1573:10:1573:10 | b [element] | -| array_flow.rb:1572:5:1572:5 | b [element] | array_flow.rb:1574:10:1574:10 | b [element] | -| array_flow.rb:1572:5:1572:5 | b [element] | array_flow.rb:1574:10:1574:10 | b [element] | -| array_flow.rb:1572:9:1572:9 | a [element 1] | array_flow.rb:1572:9:1572:26 | call to values_at [element] | -| array_flow.rb:1572:9:1572:9 | a [element 1] | array_flow.rb:1572:9:1572:26 | call to values_at [element] | -| array_flow.rb:1572:9:1572:9 | a [element 3] | array_flow.rb:1572:9:1572:26 | call to values_at [element] | -| array_flow.rb:1572:9:1572:9 | a [element 3] | array_flow.rb:1572:9:1572:26 | call to values_at [element] | -| array_flow.rb:1572:9:1572:26 | call to values_at [element] | array_flow.rb:1572:5:1572:5 | b [element] | -| array_flow.rb:1572:9:1572:26 | call to values_at [element] | array_flow.rb:1572:5:1572:5 | b [element] | -| array_flow.rb:1573:10:1573:10 | b [element] | array_flow.rb:1573:10:1573:13 | ...[...] | -| array_flow.rb:1573:10:1573:10 | b [element] | array_flow.rb:1573:10:1573:13 | ...[...] | -| array_flow.rb:1574:10:1574:10 | b [element] | array_flow.rb:1574:10:1574:13 | ...[...] | -| array_flow.rb:1574:10:1574:10 | b [element] | array_flow.rb:1574:10:1574:13 | ...[...] | -| array_flow.rb:1576:5:1576:5 | b [element 1] | array_flow.rb:1578:10:1578:10 | b [element 1] | -| array_flow.rb:1576:5:1576:5 | b [element 1] | array_flow.rb:1578:10:1578:10 | b [element 1] | -| array_flow.rb:1576:5:1576:5 | b [element] | array_flow.rb:1577:10:1577:10 | b [element] | -| array_flow.rb:1576:5:1576:5 | b [element] | array_flow.rb:1577:10:1577:10 | b [element] | -| array_flow.rb:1576:5:1576:5 | b [element] | array_flow.rb:1578:10:1578:10 | b [element] | -| array_flow.rb:1576:5:1576:5 | b [element] | array_flow.rb:1578:10:1578:10 | b [element] | -| array_flow.rb:1576:5:1576:5 | b [element] | array_flow.rb:1579:10:1579:10 | b [element] | -| array_flow.rb:1576:5:1576:5 | b [element] | array_flow.rb:1579:10:1579:10 | b [element] | -| array_flow.rb:1576:5:1576:5 | b [element] | array_flow.rb:1580:10:1580:10 | b [element] | -| array_flow.rb:1576:5:1576:5 | b [element] | array_flow.rb:1580:10:1580:10 | b [element] | -| array_flow.rb:1576:9:1576:9 | a [element 1] | array_flow.rb:1576:9:1576:28 | call to values_at [element] | -| array_flow.rb:1576:9:1576:9 | a [element 1] | array_flow.rb:1576:9:1576:28 | call to values_at [element] | -| array_flow.rb:1576:9:1576:9 | a [element 3] | array_flow.rb:1576:9:1576:28 | call to values_at [element 1] | -| array_flow.rb:1576:9:1576:9 | a [element 3] | array_flow.rb:1576:9:1576:28 | call to values_at [element 1] | -| array_flow.rb:1576:9:1576:9 | a [element 3] | array_flow.rb:1576:9:1576:28 | call to values_at [element] | -| array_flow.rb:1576:9:1576:9 | a [element 3] | array_flow.rb:1576:9:1576:28 | call to values_at [element] | -| array_flow.rb:1576:9:1576:28 | call to values_at [element 1] | array_flow.rb:1576:5:1576:5 | b [element 1] | -| array_flow.rb:1576:9:1576:28 | call to values_at [element 1] | array_flow.rb:1576:5:1576:5 | b [element 1] | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] | array_flow.rb:1576:5:1576:5 | b [element] | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] | array_flow.rb:1576:5:1576:5 | b [element] | -| array_flow.rb:1577:10:1577:10 | b [element] | array_flow.rb:1577:10:1577:13 | ...[...] | -| array_flow.rb:1577:10:1577:10 | b [element] | array_flow.rb:1577:10:1577:13 | ...[...] | -| array_flow.rb:1578:10:1578:10 | b [element 1] | array_flow.rb:1578:10:1578:13 | ...[...] | -| array_flow.rb:1578:10:1578:10 | b [element 1] | array_flow.rb:1578:10:1578:13 | ...[...] | -| array_flow.rb:1578:10:1578:10 | b [element] | array_flow.rb:1578:10:1578:13 | ...[...] | -| array_flow.rb:1578:10:1578:10 | b [element] | array_flow.rb:1578:10:1578:13 | ...[...] | -| array_flow.rb:1579:10:1579:10 | b [element] | array_flow.rb:1579:10:1579:13 | ...[...] | -| array_flow.rb:1579:10:1579:10 | b [element] | array_flow.rb:1579:10:1579:13 | ...[...] | +| array_flow.rb:1546:10:1546:10 | a [element] | array_flow.rb:1546:10:1546:13 | ...[...] | +| array_flow.rb:1546:10:1546:10 | a [element] | array_flow.rb:1546:10:1546:13 | ...[...] | +| array_flow.rb:1548:5:1548:5 | a [element 2] | array_flow.rb:1549:9:1549:9 | a [element 2] | +| array_flow.rb:1548:5:1548:5 | a [element 2] | array_flow.rb:1549:9:1549:9 | a [element 2] | +| array_flow.rb:1548:5:1548:5 | a [element 3] | array_flow.rb:1549:9:1549:9 | a [element 3] | +| array_flow.rb:1548:5:1548:5 | a [element 3] | array_flow.rb:1549:9:1549:9 | a [element 3] | +| array_flow.rb:1548:16:1548:28 | call to source | array_flow.rb:1548:5:1548:5 | a [element 2] | +| array_flow.rb:1548:16:1548:28 | call to source | array_flow.rb:1548:5:1548:5 | a [element 2] | +| array_flow.rb:1548:31:1548:43 | call to source | array_flow.rb:1548:5:1548:5 | a [element 3] | +| array_flow.rb:1548:31:1548:43 | call to source | array_flow.rb:1548:5:1548:5 | a [element 3] | +| array_flow.rb:1549:5:1549:5 | b [element] | array_flow.rb:1553:10:1553:10 | b [element] | +| array_flow.rb:1549:5:1549:5 | b [element] | array_flow.rb:1553:10:1553:10 | b [element] | +| array_flow.rb:1549:5:1549:5 | b [element] | array_flow.rb:1554:10:1554:10 | b [element] | +| array_flow.rb:1549:5:1549:5 | b [element] | array_flow.rb:1554:10:1554:10 | b [element] | +| array_flow.rb:1549:9:1549:9 | [post] a [element] | array_flow.rb:1555:10:1555:10 | a [element] | +| array_flow.rb:1549:9:1549:9 | [post] a [element] | array_flow.rb:1555:10:1555:10 | a [element] | +| array_flow.rb:1549:9:1549:9 | [post] a [element] | array_flow.rb:1556:10:1556:10 | a [element] | +| array_flow.rb:1549:9:1549:9 | [post] a [element] | array_flow.rb:1556:10:1556:10 | a [element] | +| array_flow.rb:1549:9:1549:9 | a [element 2] | array_flow.rb:1549:9:1549:9 | [post] a [element] | +| array_flow.rb:1549:9:1549:9 | a [element 2] | array_flow.rb:1549:9:1549:9 | [post] a [element] | +| array_flow.rb:1549:9:1549:9 | a [element 2] | array_flow.rb:1549:9:1552:7 | call to uniq! [element] | +| array_flow.rb:1549:9:1549:9 | a [element 2] | array_flow.rb:1549:9:1552:7 | call to uniq! [element] | +| array_flow.rb:1549:9:1549:9 | a [element 2] | array_flow.rb:1549:21:1549:21 | x | +| array_flow.rb:1549:9:1549:9 | a [element 2] | array_flow.rb:1549:21:1549:21 | x | +| array_flow.rb:1549:9:1549:9 | a [element 3] | array_flow.rb:1549:9:1549:9 | [post] a [element] | +| array_flow.rb:1549:9:1549:9 | a [element 3] | array_flow.rb:1549:9:1549:9 | [post] a [element] | +| array_flow.rb:1549:9:1549:9 | a [element 3] | array_flow.rb:1549:9:1552:7 | call to uniq! [element] | +| array_flow.rb:1549:9:1549:9 | a [element 3] | array_flow.rb:1549:9:1552:7 | call to uniq! [element] | +| array_flow.rb:1549:9:1549:9 | a [element 3] | array_flow.rb:1549:21:1549:21 | x | +| array_flow.rb:1549:9:1549:9 | a [element 3] | array_flow.rb:1549:21:1549:21 | x | +| array_flow.rb:1549:9:1552:7 | call to uniq! [element] | array_flow.rb:1549:5:1549:5 | b [element] | +| array_flow.rb:1549:9:1552:7 | call to uniq! [element] | array_flow.rb:1549:5:1549:5 | b [element] | +| array_flow.rb:1549:21:1549:21 | x | array_flow.rb:1550:14:1550:14 | x | +| array_flow.rb:1549:21:1549:21 | x | array_flow.rb:1550:14:1550:14 | x | +| array_flow.rb:1553:10:1553:10 | b [element] | array_flow.rb:1553:10:1553:13 | ...[...] | +| array_flow.rb:1553:10:1553:10 | b [element] | array_flow.rb:1553:10:1553:13 | ...[...] | +| array_flow.rb:1554:10:1554:10 | b [element] | array_flow.rb:1554:10:1554:13 | ...[...] | +| array_flow.rb:1554:10:1554:10 | b [element] | array_flow.rb:1554:10:1554:13 | ...[...] | +| array_flow.rb:1555:10:1555:10 | a [element] | array_flow.rb:1555:10:1555:13 | ...[...] | +| array_flow.rb:1555:10:1555:10 | a [element] | array_flow.rb:1555:10:1555:13 | ...[...] | +| array_flow.rb:1556:10:1556:10 | a [element] | array_flow.rb:1556:10:1556:13 | ...[...] | +| array_flow.rb:1556:10:1556:10 | a [element] | array_flow.rb:1556:10:1556:13 | ...[...] | +| array_flow.rb:1560:5:1560:5 | a [element 2] | array_flow.rb:1561:5:1561:5 | a [element 2] | +| array_flow.rb:1560:5:1560:5 | a [element 2] | array_flow.rb:1561:5:1561:5 | a [element 2] | +| array_flow.rb:1560:16:1560:28 | call to source | array_flow.rb:1560:5:1560:5 | a [element 2] | +| array_flow.rb:1560:16:1560:28 | call to source | array_flow.rb:1560:5:1560:5 | a [element 2] | +| array_flow.rb:1561:5:1561:5 | [post] a [element 2] | array_flow.rb:1564:10:1564:10 | a [element 2] | +| array_flow.rb:1561:5:1561:5 | [post] a [element 2] | array_flow.rb:1564:10:1564:10 | a [element 2] | +| array_flow.rb:1561:5:1561:5 | [post] a [element 5] | array_flow.rb:1567:10:1567:10 | a [element 5] | +| array_flow.rb:1561:5:1561:5 | [post] a [element 5] | array_flow.rb:1567:10:1567:10 | a [element 5] | +| array_flow.rb:1561:5:1561:5 | a [element 2] | array_flow.rb:1561:5:1561:5 | [post] a [element 5] | +| array_flow.rb:1561:5:1561:5 | a [element 2] | array_flow.rb:1561:5:1561:5 | [post] a [element 5] | +| array_flow.rb:1561:21:1561:33 | call to source | array_flow.rb:1561:5:1561:5 | [post] a [element 2] | +| array_flow.rb:1561:21:1561:33 | call to source | array_flow.rb:1561:5:1561:5 | [post] a [element 2] | +| array_flow.rb:1564:10:1564:10 | a [element 2] | array_flow.rb:1564:10:1564:13 | ...[...] | +| array_flow.rb:1564:10:1564:10 | a [element 2] | array_flow.rb:1564:10:1564:13 | ...[...] | +| array_flow.rb:1567:10:1567:10 | a [element 5] | array_flow.rb:1567:10:1567:13 | ...[...] | +| array_flow.rb:1567:10:1567:10 | a [element 5] | array_flow.rb:1567:10:1567:13 | ...[...] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | array_flow.rb:1573:9:1573:9 | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | array_flow.rb:1573:9:1573:9 | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | array_flow.rb:1579:9:1579:9 | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | array_flow.rb:1579:9:1579:9 | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | array_flow.rb:1583:9:1583:9 | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | array_flow.rb:1583:9:1583:9 | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | array_flow.rb:1587:9:1587:9 | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | array_flow.rb:1587:9:1587:9 | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 3] | array_flow.rb:1579:9:1579:9 | a [element 3] | +| array_flow.rb:1571:5:1571:5 | a [element 3] | array_flow.rb:1579:9:1579:9 | a [element 3] | +| array_flow.rb:1571:5:1571:5 | a [element 3] | array_flow.rb:1583:9:1583:9 | a [element 3] | +| array_flow.rb:1571:5:1571:5 | a [element 3] | array_flow.rb:1583:9:1583:9 | a [element 3] | +| array_flow.rb:1571:5:1571:5 | a [element 3] | array_flow.rb:1587:9:1587:9 | a [element 3] | +| array_flow.rb:1571:5:1571:5 | a [element 3] | array_flow.rb:1587:9:1587:9 | a [element 3] | +| array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1571:5:1571:5 | a [element 1] | +| array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1571:5:1571:5 | a [element 1] | +| array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1571:5:1571:5 | a [element 3] | +| array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1571:5:1571:5 | a [element 3] | +| array_flow.rb:1573:5:1573:5 | b [element 1] | array_flow.rb:1575:10:1575:10 | b [element 1] | +| array_flow.rb:1573:5:1573:5 | b [element 1] | array_flow.rb:1575:10:1575:10 | b [element 1] | +| array_flow.rb:1573:5:1573:5 | b [element 3] | array_flow.rb:1577:10:1577:10 | b [element 3] | +| array_flow.rb:1573:5:1573:5 | b [element 3] | array_flow.rb:1577:10:1577:10 | b [element 3] | +| array_flow.rb:1573:9:1573:9 | a [element 1] | array_flow.rb:1573:9:1573:31 | call to values_at [element 1] | +| array_flow.rb:1573:9:1573:9 | a [element 1] | array_flow.rb:1573:9:1573:31 | call to values_at [element 1] | +| array_flow.rb:1573:9:1573:9 | a [element 1] | array_flow.rb:1573:9:1573:31 | call to values_at [element 3] | +| array_flow.rb:1573:9:1573:9 | a [element 1] | array_flow.rb:1573:9:1573:31 | call to values_at [element 3] | +| array_flow.rb:1573:9:1573:31 | call to values_at [element 1] | array_flow.rb:1573:5:1573:5 | b [element 1] | +| array_flow.rb:1573:9:1573:31 | call to values_at [element 1] | array_flow.rb:1573:5:1573:5 | b [element 1] | +| array_flow.rb:1573:9:1573:31 | call to values_at [element 3] | array_flow.rb:1573:5:1573:5 | b [element 3] | +| array_flow.rb:1573:9:1573:31 | call to values_at [element 3] | array_flow.rb:1573:5:1573:5 | b [element 3] | +| array_flow.rb:1575:10:1575:10 | b [element 1] | array_flow.rb:1575:10:1575:13 | ...[...] | +| array_flow.rb:1575:10:1575:10 | b [element 1] | array_flow.rb:1575:10:1575:13 | ...[...] | +| array_flow.rb:1577:10:1577:10 | b [element 3] | array_flow.rb:1577:10:1577:13 | ...[...] | +| array_flow.rb:1577:10:1577:10 | b [element 3] | array_flow.rb:1577:10:1577:13 | ...[...] | +| array_flow.rb:1579:5:1579:5 | b [element] | array_flow.rb:1580:10:1580:10 | b [element] | +| array_flow.rb:1579:5:1579:5 | b [element] | array_flow.rb:1580:10:1580:10 | b [element] | +| array_flow.rb:1579:5:1579:5 | b [element] | array_flow.rb:1581:10:1581:10 | b [element] | +| array_flow.rb:1579:5:1579:5 | b [element] | array_flow.rb:1581:10:1581:10 | b [element] | +| array_flow.rb:1579:9:1579:9 | a [element 1] | array_flow.rb:1579:9:1579:25 | call to values_at [element] | +| array_flow.rb:1579:9:1579:9 | a [element 1] | array_flow.rb:1579:9:1579:25 | call to values_at [element] | +| array_flow.rb:1579:9:1579:9 | a [element 3] | array_flow.rb:1579:9:1579:25 | call to values_at [element] | +| array_flow.rb:1579:9:1579:9 | a [element 3] | array_flow.rb:1579:9:1579:25 | call to values_at [element] | +| array_flow.rb:1579:9:1579:25 | call to values_at [element] | array_flow.rb:1579:5:1579:5 | b [element] | +| array_flow.rb:1579:9:1579:25 | call to values_at [element] | array_flow.rb:1579:5:1579:5 | b [element] | | array_flow.rb:1580:10:1580:10 | b [element] | array_flow.rb:1580:10:1580:13 | ...[...] | | array_flow.rb:1580:10:1580:10 | b [element] | array_flow.rb:1580:10:1580:13 | ...[...] | -| array_flow.rb:1584:5:1584:5 | a [element 2] | array_flow.rb:1587:9:1587:9 | a [element 2] | -| array_flow.rb:1584:5:1584:5 | a [element 2] | array_flow.rb:1587:9:1587:9 | a [element 2] | -| array_flow.rb:1584:5:1584:5 | a [element 2] | array_flow.rb:1592:5:1592:5 | a [element 2] | -| array_flow.rb:1584:5:1584:5 | a [element 2] | array_flow.rb:1592:5:1592:5 | a [element 2] | -| array_flow.rb:1584:16:1584:28 | call to source | array_flow.rb:1584:5:1584:5 | a [element 2] | -| array_flow.rb:1584:16:1584:28 | call to source | array_flow.rb:1584:5:1584:5 | a [element 2] | -| array_flow.rb:1585:5:1585:5 | b [element 1] | array_flow.rb:1587:15:1587:15 | b [element 1] | -| array_flow.rb:1585:5:1585:5 | b [element 1] | array_flow.rb:1587:15:1587:15 | b [element 1] | -| array_flow.rb:1585:5:1585:5 | b [element 1] | array_flow.rb:1592:11:1592:11 | b [element 1] | -| array_flow.rb:1585:5:1585:5 | b [element 1] | array_flow.rb:1592:11:1592:11 | b [element 1] | -| array_flow.rb:1585:13:1585:25 | call to source | array_flow.rb:1585:5:1585:5 | b [element 1] | -| array_flow.rb:1585:13:1585:25 | call to source | array_flow.rb:1585:5:1585:5 | b [element 1] | -| array_flow.rb:1586:5:1586:5 | c [element 0] | array_flow.rb:1587:18:1587:18 | c [element 0] | -| array_flow.rb:1586:5:1586:5 | c [element 0] | array_flow.rb:1587:18:1587:18 | c [element 0] | -| array_flow.rb:1586:5:1586:5 | c [element 0] | array_flow.rb:1592:14:1592:14 | c [element 0] | -| array_flow.rb:1586:5:1586:5 | c [element 0] | array_flow.rb:1592:14:1592:14 | c [element 0] | -| array_flow.rb:1586:10:1586:22 | call to source | array_flow.rb:1586:5:1586:5 | c [element 0] | -| array_flow.rb:1586:10:1586:22 | call to source | array_flow.rb:1586:5:1586:5 | c [element 0] | -| array_flow.rb:1587:5:1587:5 | d [element 0, element 2] | array_flow.rb:1589:10:1589:10 | d [element 0, element 2] | -| array_flow.rb:1587:5:1587:5 | d [element 0, element 2] | array_flow.rb:1589:10:1589:10 | d [element 0, element 2] | -| array_flow.rb:1587:5:1587:5 | d [element 1, element 1] | array_flow.rb:1590:10:1590:10 | d [element 1, element 1] | -| array_flow.rb:1587:5:1587:5 | d [element 1, element 1] | array_flow.rb:1590:10:1590:10 | d [element 1, element 1] | -| array_flow.rb:1587:5:1587:5 | d [element 2, element 0] | array_flow.rb:1591:10:1591:10 | d [element 2, element 0] | -| array_flow.rb:1587:5:1587:5 | d [element 2, element 0] | array_flow.rb:1591:10:1591:10 | d [element 2, element 0] | -| array_flow.rb:1587:9:1587:9 | a [element 2] | array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] | -| array_flow.rb:1587:9:1587:9 | a [element 2] | array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] | array_flow.rb:1587:5:1587:5 | d [element 0, element 2] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] | array_flow.rb:1587:5:1587:5 | d [element 0, element 2] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] | array_flow.rb:1587:5:1587:5 | d [element 1, element 1] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] | array_flow.rb:1587:5:1587:5 | d [element 1, element 1] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] | array_flow.rb:1587:5:1587:5 | d [element 2, element 0] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] | array_flow.rb:1587:5:1587:5 | d [element 2, element 0] | -| array_flow.rb:1587:15:1587:15 | b [element 1] | array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] | -| array_flow.rb:1587:15:1587:15 | b [element 1] | array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] | -| array_flow.rb:1587:18:1587:18 | c [element 0] | array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] | -| array_flow.rb:1587:18:1587:18 | c [element 0] | array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] | -| array_flow.rb:1589:10:1589:10 | d [element 0, element 2] | array_flow.rb:1589:10:1589:13 | ...[...] [element 2] | -| array_flow.rb:1589:10:1589:10 | d [element 0, element 2] | array_flow.rb:1589:10:1589:13 | ...[...] [element 2] | -| array_flow.rb:1589:10:1589:13 | ...[...] [element 2] | array_flow.rb:1589:10:1589:16 | ...[...] | -| array_flow.rb:1589:10:1589:13 | ...[...] [element 2] | array_flow.rb:1589:10:1589:16 | ...[...] | -| array_flow.rb:1590:10:1590:10 | d [element 1, element 1] | array_flow.rb:1590:10:1590:13 | ...[...] [element 1] | -| array_flow.rb:1590:10:1590:10 | d [element 1, element 1] | array_flow.rb:1590:10:1590:13 | ...[...] [element 1] | -| array_flow.rb:1590:10:1590:13 | ...[...] [element 1] | array_flow.rb:1590:10:1590:16 | ...[...] | -| array_flow.rb:1590:10:1590:13 | ...[...] [element 1] | array_flow.rb:1590:10:1590:16 | ...[...] | -| array_flow.rb:1591:10:1591:10 | d [element 2, element 0] | array_flow.rb:1591:10:1591:13 | ...[...] [element 0] | -| array_flow.rb:1591:10:1591:10 | d [element 2, element 0] | array_flow.rb:1591:10:1591:13 | ...[...] [element 0] | -| array_flow.rb:1591:10:1591:13 | ...[...] [element 0] | array_flow.rb:1591:10:1591:16 | ...[...] | -| array_flow.rb:1591:10:1591:13 | ...[...] [element 0] | array_flow.rb:1591:10:1591:16 | ...[...] | -| array_flow.rb:1592:5:1592:5 | a [element 2] | array_flow.rb:1592:21:1592:21 | x [element 0] | -| array_flow.rb:1592:5:1592:5 | a [element 2] | array_flow.rb:1592:21:1592:21 | x [element 0] | -| array_flow.rb:1592:11:1592:11 | b [element 1] | array_flow.rb:1592:21:1592:21 | x [element 1] | -| array_flow.rb:1592:11:1592:11 | b [element 1] | array_flow.rb:1592:21:1592:21 | x [element 1] | -| array_flow.rb:1592:14:1592:14 | c [element 0] | array_flow.rb:1592:21:1592:21 | x [element 2] | -| array_flow.rb:1592:14:1592:14 | c [element 0] | array_flow.rb:1592:21:1592:21 | x [element 2] | -| array_flow.rb:1592:21:1592:21 | x [element 0] | array_flow.rb:1593:14:1593:14 | x [element 0] | -| array_flow.rb:1592:21:1592:21 | x [element 0] | array_flow.rb:1593:14:1593:14 | x [element 0] | -| array_flow.rb:1592:21:1592:21 | x [element 1] | array_flow.rb:1594:14:1594:14 | x [element 1] | -| array_flow.rb:1592:21:1592:21 | x [element 1] | array_flow.rb:1594:14:1594:14 | x [element 1] | -| array_flow.rb:1592:21:1592:21 | x [element 2] | array_flow.rb:1595:14:1595:14 | x [element 2] | -| array_flow.rb:1592:21:1592:21 | x [element 2] | array_flow.rb:1595:14:1595:14 | x [element 2] | -| array_flow.rb:1593:14:1593:14 | x [element 0] | array_flow.rb:1593:14:1593:17 | ...[...] | -| array_flow.rb:1593:14:1593:14 | x [element 0] | array_flow.rb:1593:14:1593:17 | ...[...] | -| array_flow.rb:1594:14:1594:14 | x [element 1] | array_flow.rb:1594:14:1594:17 | ...[...] | -| array_flow.rb:1594:14:1594:14 | x [element 1] | array_flow.rb:1594:14:1594:17 | ...[...] | -| array_flow.rb:1595:14:1595:14 | x [element 2] | array_flow.rb:1595:14:1595:17 | ...[...] | -| array_flow.rb:1595:14:1595:14 | x [element 2] | array_flow.rb:1595:14:1595:17 | ...[...] | -| array_flow.rb:1600:5:1600:5 | a [element 2] | array_flow.rb:1602:9:1602:9 | a [element 2] | -| array_flow.rb:1600:5:1600:5 | a [element 2] | array_flow.rb:1602:9:1602:9 | a [element 2] | -| array_flow.rb:1600:16:1600:28 | call to source | array_flow.rb:1600:5:1600:5 | a [element 2] | -| array_flow.rb:1600:16:1600:28 | call to source | array_flow.rb:1600:5:1600:5 | a [element 2] | -| array_flow.rb:1601:5:1601:5 | b [element 1] | array_flow.rb:1602:13:1602:13 | b [element 1] | -| array_flow.rb:1601:5:1601:5 | b [element 1] | array_flow.rb:1602:13:1602:13 | b [element 1] | -| array_flow.rb:1601:13:1601:25 | call to source | array_flow.rb:1601:5:1601:5 | b [element 1] | -| array_flow.rb:1601:13:1601:25 | call to source | array_flow.rb:1601:5:1601:5 | b [element 1] | -| array_flow.rb:1602:5:1602:5 | c [element] | array_flow.rb:1603:10:1603:10 | c [element] | -| array_flow.rb:1602:5:1602:5 | c [element] | array_flow.rb:1603:10:1603:10 | c [element] | -| array_flow.rb:1602:5:1602:5 | c [element] | array_flow.rb:1604:10:1604:10 | c [element] | -| array_flow.rb:1602:5:1602:5 | c [element] | array_flow.rb:1604:10:1604:10 | c [element] | -| array_flow.rb:1602:5:1602:5 | c [element] | array_flow.rb:1605:10:1605:10 | c [element] | -| array_flow.rb:1602:5:1602:5 | c [element] | array_flow.rb:1605:10:1605:10 | c [element] | -| array_flow.rb:1602:9:1602:9 | a [element 2] | array_flow.rb:1602:9:1602:13 | ... \| ... [element] | -| array_flow.rb:1602:9:1602:9 | a [element 2] | array_flow.rb:1602:9:1602:13 | ... \| ... [element] | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] | array_flow.rb:1602:5:1602:5 | c [element] | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] | array_flow.rb:1602:5:1602:5 | c [element] | -| array_flow.rb:1602:13:1602:13 | b [element 1] | array_flow.rb:1602:9:1602:13 | ... \| ... [element] | -| array_flow.rb:1602:13:1602:13 | b [element 1] | array_flow.rb:1602:9:1602:13 | ... \| ... [element] | -| array_flow.rb:1603:10:1603:10 | c [element] | array_flow.rb:1603:10:1603:13 | ...[...] | -| array_flow.rb:1603:10:1603:10 | c [element] | array_flow.rb:1603:10:1603:13 | ...[...] | -| array_flow.rb:1604:10:1604:10 | c [element] | array_flow.rb:1604:10:1604:13 | ...[...] | -| array_flow.rb:1604:10:1604:10 | c [element] | array_flow.rb:1604:10:1604:13 | ...[...] | -| array_flow.rb:1605:10:1605:10 | c [element] | array_flow.rb:1605:10:1605:13 | ...[...] | -| array_flow.rb:1605:10:1605:10 | c [element] | array_flow.rb:1605:10:1605:13 | ...[...] | -| array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | array_flow.rb:1611:10:1611:10 | a [element, element 0] | -| array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | array_flow.rb:1611:10:1611:10 | a [element, element 0] | -| array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | array_flow.rb:1614:10:1614:10 | a [element, element 0] | -| array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | array_flow.rb:1614:10:1614:10 | a [element, element 0] | -| array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | array_flow.rb:1615:10:1615:10 | a [element, element 0] | -| array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | array_flow.rb:1615:10:1615:10 | a [element, element 0] | -| array_flow.rb:1610:5:1610:8 | [post] ...[...] [element 0] | array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | -| array_flow.rb:1610:5:1610:8 | [post] ...[...] [element 0] | array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | -| array_flow.rb:1610:15:1610:27 | call to source | array_flow.rb:1610:5:1610:8 | [post] ...[...] [element 0] | -| array_flow.rb:1610:15:1610:27 | call to source | array_flow.rb:1610:5:1610:8 | [post] ...[...] [element 0] | -| array_flow.rb:1611:10:1611:10 | a [element, element 0] | array_flow.rb:1611:10:1611:13 | ...[...] [element 0] | -| array_flow.rb:1611:10:1611:10 | a [element, element 0] | array_flow.rb:1611:10:1611:13 | ...[...] [element 0] | -| array_flow.rb:1611:10:1611:13 | ...[...] [element 0] | array_flow.rb:1611:10:1611:16 | ...[...] | -| array_flow.rb:1611:10:1611:13 | ...[...] [element 0] | array_flow.rb:1611:10:1611:16 | ...[...] | -| array_flow.rb:1613:5:1613:5 | [post] a [element 1, element 0] | array_flow.rb:1614:10:1614:10 | a [element 1, element 0] | -| array_flow.rb:1613:5:1613:5 | [post] a [element 1, element 0] | array_flow.rb:1614:10:1614:10 | a [element 1, element 0] | -| array_flow.rb:1613:5:1613:8 | [post] ...[...] [element 0] | array_flow.rb:1613:5:1613:5 | [post] a [element 1, element 0] | -| array_flow.rb:1613:5:1613:8 | [post] ...[...] [element 0] | array_flow.rb:1613:5:1613:5 | [post] a [element 1, element 0] | -| array_flow.rb:1613:15:1613:27 | call to source | array_flow.rb:1613:5:1613:8 | [post] ...[...] [element 0] | -| array_flow.rb:1613:15:1613:27 | call to source | array_flow.rb:1613:5:1613:8 | [post] ...[...] [element 0] | -| array_flow.rb:1614:10:1614:10 | a [element 1, element 0] | array_flow.rb:1614:10:1614:13 | ...[...] [element 0] | -| array_flow.rb:1614:10:1614:10 | a [element 1, element 0] | array_flow.rb:1614:10:1614:13 | ...[...] [element 0] | -| array_flow.rb:1614:10:1614:10 | a [element, element 0] | array_flow.rb:1614:10:1614:13 | ...[...] [element 0] | -| array_flow.rb:1614:10:1614:10 | a [element, element 0] | array_flow.rb:1614:10:1614:13 | ...[...] [element 0] | -| array_flow.rb:1614:10:1614:13 | ...[...] [element 0] | array_flow.rb:1614:10:1614:16 | ...[...] | -| array_flow.rb:1614:10:1614:13 | ...[...] [element 0] | array_flow.rb:1614:10:1614:16 | ...[...] | -| array_flow.rb:1615:10:1615:10 | a [element, element 0] | array_flow.rb:1615:10:1615:13 | ...[...] [element 0] | -| array_flow.rb:1615:10:1615:10 | a [element, element 0] | array_flow.rb:1615:10:1615:13 | ...[...] [element 0] | -| array_flow.rb:1615:10:1615:13 | ...[...] [element 0] | array_flow.rb:1615:10:1615:16 | ...[...] | -| array_flow.rb:1615:10:1615:13 | ...[...] [element 0] | array_flow.rb:1615:10:1615:16 | ...[...] | -| array_flow.rb:1620:5:1620:5 | [post] a [element 0] | array_flow.rb:1629:10:1629:10 | a [element 0] | -| array_flow.rb:1620:5:1620:5 | [post] a [element 0] | array_flow.rb:1629:10:1629:10 | a [element 0] | -| array_flow.rb:1620:5:1620:5 | [post] a [element 0] | array_flow.rb:1631:10:1631:10 | a [element 0] | -| array_flow.rb:1620:5:1620:5 | [post] a [element 0] | array_flow.rb:1631:10:1631:10 | a [element 0] | -| array_flow.rb:1620:12:1620:24 | call to source | array_flow.rb:1620:5:1620:5 | [post] a [element 0] | -| array_flow.rb:1620:12:1620:24 | call to source | array_flow.rb:1620:5:1620:5 | [post] a [element 0] | -| array_flow.rb:1622:5:1622:5 | [post] a [element] | array_flow.rb:1627:10:1627:10 | a [element] | -| array_flow.rb:1622:5:1622:5 | [post] a [element] | array_flow.rb:1627:10:1627:10 | a [element] | -| array_flow.rb:1622:5:1622:5 | [post] a [element] | array_flow.rb:1629:10:1629:10 | a [element] | -| array_flow.rb:1622:5:1622:5 | [post] a [element] | array_flow.rb:1629:10:1629:10 | a [element] | -| array_flow.rb:1622:5:1622:5 | [post] a [element] | array_flow.rb:1631:10:1631:10 | a [element] | -| array_flow.rb:1622:5:1622:5 | [post] a [element] | array_flow.rb:1631:10:1631:10 | a [element] | -| array_flow.rb:1622:16:1622:28 | call to source | array_flow.rb:1622:5:1622:5 | [post] a [element] | -| array_flow.rb:1622:16:1622:28 | call to source | array_flow.rb:1622:5:1622:5 | [post] a [element] | -| array_flow.rb:1624:5:1624:5 | [post] a [element] | array_flow.rb:1627:10:1627:10 | a [element] | -| array_flow.rb:1624:5:1624:5 | [post] a [element] | array_flow.rb:1627:10:1627:10 | a [element] | -| array_flow.rb:1624:5:1624:5 | [post] a [element] | array_flow.rb:1629:10:1629:10 | a [element] | -| array_flow.rb:1624:5:1624:5 | [post] a [element] | array_flow.rb:1629:10:1629:10 | a [element] | -| array_flow.rb:1624:5:1624:5 | [post] a [element] | array_flow.rb:1631:10:1631:10 | a [element] | -| array_flow.rb:1624:5:1624:5 | [post] a [element] | array_flow.rb:1631:10:1631:10 | a [element] | -| array_flow.rb:1624:14:1624:26 | call to source | array_flow.rb:1624:5:1624:5 | [post] a [element] | -| array_flow.rb:1624:14:1624:26 | call to source | array_flow.rb:1624:5:1624:5 | [post] a [element] | -| array_flow.rb:1626:5:1626:5 | [post] a [element] | array_flow.rb:1627:10:1627:10 | a [element] | -| array_flow.rb:1626:5:1626:5 | [post] a [element] | array_flow.rb:1627:10:1627:10 | a [element] | -| array_flow.rb:1626:5:1626:5 | [post] a [element] | array_flow.rb:1629:10:1629:10 | a [element] | -| array_flow.rb:1626:5:1626:5 | [post] a [element] | array_flow.rb:1629:10:1629:10 | a [element] | -| array_flow.rb:1626:5:1626:5 | [post] a [element] | array_flow.rb:1631:10:1631:10 | a [element] | -| array_flow.rb:1626:5:1626:5 | [post] a [element] | array_flow.rb:1631:10:1631:10 | a [element] | -| array_flow.rb:1626:16:1626:28 | call to source | array_flow.rb:1626:5:1626:5 | [post] a [element] | -| array_flow.rb:1626:16:1626:28 | call to source | array_flow.rb:1626:5:1626:5 | [post] a [element] | -| array_flow.rb:1627:10:1627:10 | a [element] | array_flow.rb:1627:10:1627:13 | ...[...] | -| array_flow.rb:1627:10:1627:10 | a [element] | array_flow.rb:1627:10:1627:13 | ...[...] | -| array_flow.rb:1629:10:1629:10 | a [element 0] | array_flow.rb:1629:10:1629:17 | ...[...] | -| array_flow.rb:1629:10:1629:10 | a [element 0] | array_flow.rb:1629:10:1629:17 | ...[...] | -| array_flow.rb:1629:10:1629:10 | a [element] | array_flow.rb:1629:10:1629:17 | ...[...] | -| array_flow.rb:1629:10:1629:10 | a [element] | array_flow.rb:1629:10:1629:17 | ...[...] | -| array_flow.rb:1631:10:1631:10 | a [element 0] | array_flow.rb:1631:10:1631:15 | ...[...] | -| array_flow.rb:1631:10:1631:10 | a [element 0] | array_flow.rb:1631:10:1631:15 | ...[...] | -| array_flow.rb:1631:10:1631:10 | a [element] | array_flow.rb:1631:10:1631:15 | ...[...] | -| array_flow.rb:1631:10:1631:10 | a [element] | array_flow.rb:1631:10:1631:15 | ...[...] | +| array_flow.rb:1581:10:1581:10 | b [element] | array_flow.rb:1581:10:1581:13 | ...[...] | +| array_flow.rb:1581:10:1581:10 | b [element] | array_flow.rb:1581:10:1581:13 | ...[...] | +| array_flow.rb:1583:5:1583:5 | b [element] | array_flow.rb:1584:10:1584:10 | b [element] | +| array_flow.rb:1583:5:1583:5 | b [element] | array_flow.rb:1584:10:1584:10 | b [element] | +| array_flow.rb:1583:5:1583:5 | b [element] | array_flow.rb:1585:10:1585:10 | b [element] | +| array_flow.rb:1583:5:1583:5 | b [element] | array_flow.rb:1585:10:1585:10 | b [element] | +| array_flow.rb:1583:9:1583:9 | a [element 1] | array_flow.rb:1583:9:1583:26 | call to values_at [element] | +| array_flow.rb:1583:9:1583:9 | a [element 1] | array_flow.rb:1583:9:1583:26 | call to values_at [element] | +| array_flow.rb:1583:9:1583:9 | a [element 3] | array_flow.rb:1583:9:1583:26 | call to values_at [element] | +| array_flow.rb:1583:9:1583:9 | a [element 3] | array_flow.rb:1583:9:1583:26 | call to values_at [element] | +| array_flow.rb:1583:9:1583:26 | call to values_at [element] | array_flow.rb:1583:5:1583:5 | b [element] | +| array_flow.rb:1583:9:1583:26 | call to values_at [element] | array_flow.rb:1583:5:1583:5 | b [element] | +| array_flow.rb:1584:10:1584:10 | b [element] | array_flow.rb:1584:10:1584:13 | ...[...] | +| array_flow.rb:1584:10:1584:10 | b [element] | array_flow.rb:1584:10:1584:13 | ...[...] | +| array_flow.rb:1585:10:1585:10 | b [element] | array_flow.rb:1585:10:1585:13 | ...[...] | +| array_flow.rb:1585:10:1585:10 | b [element] | array_flow.rb:1585:10:1585:13 | ...[...] | +| array_flow.rb:1587:5:1587:5 | b [element 1] | array_flow.rb:1589:10:1589:10 | b [element 1] | +| array_flow.rb:1587:5:1587:5 | b [element 1] | array_flow.rb:1589:10:1589:10 | b [element 1] | +| array_flow.rb:1587:5:1587:5 | b [element] | array_flow.rb:1588:10:1588:10 | b [element] | +| array_flow.rb:1587:5:1587:5 | b [element] | array_flow.rb:1588:10:1588:10 | b [element] | +| array_flow.rb:1587:5:1587:5 | b [element] | array_flow.rb:1589:10:1589:10 | b [element] | +| array_flow.rb:1587:5:1587:5 | b [element] | array_flow.rb:1589:10:1589:10 | b [element] | +| array_flow.rb:1587:5:1587:5 | b [element] | array_flow.rb:1590:10:1590:10 | b [element] | +| array_flow.rb:1587:5:1587:5 | b [element] | array_flow.rb:1590:10:1590:10 | b [element] | +| array_flow.rb:1587:5:1587:5 | b [element] | array_flow.rb:1591:10:1591:10 | b [element] | +| array_flow.rb:1587:5:1587:5 | b [element] | array_flow.rb:1591:10:1591:10 | b [element] | +| array_flow.rb:1587:9:1587:9 | a [element 1] | array_flow.rb:1587:9:1587:28 | call to values_at [element] | +| array_flow.rb:1587:9:1587:9 | a [element 1] | array_flow.rb:1587:9:1587:28 | call to values_at [element] | +| array_flow.rb:1587:9:1587:9 | a [element 3] | array_flow.rb:1587:9:1587:28 | call to values_at [element 1] | +| array_flow.rb:1587:9:1587:9 | a [element 3] | array_flow.rb:1587:9:1587:28 | call to values_at [element 1] | +| array_flow.rb:1587:9:1587:9 | a [element 3] | array_flow.rb:1587:9:1587:28 | call to values_at [element] | +| array_flow.rb:1587:9:1587:9 | a [element 3] | array_flow.rb:1587:9:1587:28 | call to values_at [element] | +| array_flow.rb:1587:9:1587:28 | call to values_at [element 1] | array_flow.rb:1587:5:1587:5 | b [element 1] | +| array_flow.rb:1587:9:1587:28 | call to values_at [element 1] | array_flow.rb:1587:5:1587:5 | b [element 1] | +| array_flow.rb:1587:9:1587:28 | call to values_at [element] | array_flow.rb:1587:5:1587:5 | b [element] | +| array_flow.rb:1587:9:1587:28 | call to values_at [element] | array_flow.rb:1587:5:1587:5 | b [element] | +| array_flow.rb:1588:10:1588:10 | b [element] | array_flow.rb:1588:10:1588:13 | ...[...] | +| array_flow.rb:1588:10:1588:10 | b [element] | array_flow.rb:1588:10:1588:13 | ...[...] | +| array_flow.rb:1589:10:1589:10 | b [element 1] | array_flow.rb:1589:10:1589:13 | ...[...] | +| array_flow.rb:1589:10:1589:10 | b [element 1] | array_flow.rb:1589:10:1589:13 | ...[...] | +| array_flow.rb:1589:10:1589:10 | b [element] | array_flow.rb:1589:10:1589:13 | ...[...] | +| array_flow.rb:1589:10:1589:10 | b [element] | array_flow.rb:1589:10:1589:13 | ...[...] | +| array_flow.rb:1590:10:1590:10 | b [element] | array_flow.rb:1590:10:1590:13 | ...[...] | +| array_flow.rb:1590:10:1590:10 | b [element] | array_flow.rb:1590:10:1590:13 | ...[...] | +| array_flow.rb:1591:10:1591:10 | b [element] | array_flow.rb:1591:10:1591:13 | ...[...] | +| array_flow.rb:1591:10:1591:10 | b [element] | array_flow.rb:1591:10:1591:13 | ...[...] | +| array_flow.rb:1595:5:1595:5 | a [element 2] | array_flow.rb:1598:9:1598:9 | a [element 2] | +| array_flow.rb:1595:5:1595:5 | a [element 2] | array_flow.rb:1598:9:1598:9 | a [element 2] | +| array_flow.rb:1595:5:1595:5 | a [element 2] | array_flow.rb:1603:5:1603:5 | a [element 2] | +| array_flow.rb:1595:5:1595:5 | a [element 2] | array_flow.rb:1603:5:1603:5 | a [element 2] | +| array_flow.rb:1595:16:1595:28 | call to source | array_flow.rb:1595:5:1595:5 | a [element 2] | +| array_flow.rb:1595:16:1595:28 | call to source | array_flow.rb:1595:5:1595:5 | a [element 2] | +| array_flow.rb:1596:5:1596:5 | b [element 1] | array_flow.rb:1598:15:1598:15 | b [element 1] | +| array_flow.rb:1596:5:1596:5 | b [element 1] | array_flow.rb:1598:15:1598:15 | b [element 1] | +| array_flow.rb:1596:5:1596:5 | b [element 1] | array_flow.rb:1603:11:1603:11 | b [element 1] | +| array_flow.rb:1596:5:1596:5 | b [element 1] | array_flow.rb:1603:11:1603:11 | b [element 1] | +| array_flow.rb:1596:13:1596:25 | call to source | array_flow.rb:1596:5:1596:5 | b [element 1] | +| array_flow.rb:1596:13:1596:25 | call to source | array_flow.rb:1596:5:1596:5 | b [element 1] | +| array_flow.rb:1597:5:1597:5 | c [element 0] | array_flow.rb:1598:18:1598:18 | c [element 0] | +| array_flow.rb:1597:5:1597:5 | c [element 0] | array_flow.rb:1598:18:1598:18 | c [element 0] | +| array_flow.rb:1597:5:1597:5 | c [element 0] | array_flow.rb:1603:14:1603:14 | c [element 0] | +| array_flow.rb:1597:5:1597:5 | c [element 0] | array_flow.rb:1603:14:1603:14 | c [element 0] | +| array_flow.rb:1597:10:1597:22 | call to source | array_flow.rb:1597:5:1597:5 | c [element 0] | +| array_flow.rb:1597:10:1597:22 | call to source | array_flow.rb:1597:5:1597:5 | c [element 0] | +| array_flow.rb:1598:5:1598:5 | d [element 0, element 2] | array_flow.rb:1600:10:1600:10 | d [element 0, element 2] | +| array_flow.rb:1598:5:1598:5 | d [element 0, element 2] | array_flow.rb:1600:10:1600:10 | d [element 0, element 2] | +| array_flow.rb:1598:5:1598:5 | d [element 1, element 1] | array_flow.rb:1601:10:1601:10 | d [element 1, element 1] | +| array_flow.rb:1598:5:1598:5 | d [element 1, element 1] | array_flow.rb:1601:10:1601:10 | d [element 1, element 1] | +| array_flow.rb:1598:5:1598:5 | d [element 2, element 0] | array_flow.rb:1602:10:1602:10 | d [element 2, element 0] | +| array_flow.rb:1598:5:1598:5 | d [element 2, element 0] | array_flow.rb:1602:10:1602:10 | d [element 2, element 0] | +| array_flow.rb:1598:9:1598:9 | a [element 2] | array_flow.rb:1598:9:1598:19 | call to zip [element 2, element 0] | +| array_flow.rb:1598:9:1598:9 | a [element 2] | array_flow.rb:1598:9:1598:19 | call to zip [element 2, element 0] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 0, element 2] | array_flow.rb:1598:5:1598:5 | d [element 0, element 2] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 0, element 2] | array_flow.rb:1598:5:1598:5 | d [element 0, element 2] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 1, element 1] | array_flow.rb:1598:5:1598:5 | d [element 1, element 1] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 1, element 1] | array_flow.rb:1598:5:1598:5 | d [element 1, element 1] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 2, element 0] | array_flow.rb:1598:5:1598:5 | d [element 2, element 0] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 2, element 0] | array_flow.rb:1598:5:1598:5 | d [element 2, element 0] | +| array_flow.rb:1598:15:1598:15 | b [element 1] | array_flow.rb:1598:9:1598:19 | call to zip [element 1, element 1] | +| array_flow.rb:1598:15:1598:15 | b [element 1] | array_flow.rb:1598:9:1598:19 | call to zip [element 1, element 1] | +| array_flow.rb:1598:18:1598:18 | c [element 0] | array_flow.rb:1598:9:1598:19 | call to zip [element 0, element 2] | +| array_flow.rb:1598:18:1598:18 | c [element 0] | array_flow.rb:1598:9:1598:19 | call to zip [element 0, element 2] | +| array_flow.rb:1600:10:1600:10 | d [element 0, element 2] | array_flow.rb:1600:10:1600:13 | ...[...] [element 2] | +| array_flow.rb:1600:10:1600:10 | d [element 0, element 2] | array_flow.rb:1600:10:1600:13 | ...[...] [element 2] | +| array_flow.rb:1600:10:1600:13 | ...[...] [element 2] | array_flow.rb:1600:10:1600:16 | ...[...] | +| array_flow.rb:1600:10:1600:13 | ...[...] [element 2] | array_flow.rb:1600:10:1600:16 | ...[...] | +| array_flow.rb:1601:10:1601:10 | d [element 1, element 1] | array_flow.rb:1601:10:1601:13 | ...[...] [element 1] | +| array_flow.rb:1601:10:1601:10 | d [element 1, element 1] | array_flow.rb:1601:10:1601:13 | ...[...] [element 1] | +| array_flow.rb:1601:10:1601:13 | ...[...] [element 1] | array_flow.rb:1601:10:1601:16 | ...[...] | +| array_flow.rb:1601:10:1601:13 | ...[...] [element 1] | array_flow.rb:1601:10:1601:16 | ...[...] | +| array_flow.rb:1602:10:1602:10 | d [element 2, element 0] | array_flow.rb:1602:10:1602:13 | ...[...] [element 0] | +| array_flow.rb:1602:10:1602:10 | d [element 2, element 0] | array_flow.rb:1602:10:1602:13 | ...[...] [element 0] | +| array_flow.rb:1602:10:1602:13 | ...[...] [element 0] | array_flow.rb:1602:10:1602:16 | ...[...] | +| array_flow.rb:1602:10:1602:13 | ...[...] [element 0] | array_flow.rb:1602:10:1602:16 | ...[...] | +| array_flow.rb:1603:5:1603:5 | a [element 2] | array_flow.rb:1603:21:1603:21 | x [element 0] | +| array_flow.rb:1603:5:1603:5 | a [element 2] | array_flow.rb:1603:21:1603:21 | x [element 0] | +| array_flow.rb:1603:11:1603:11 | b [element 1] | array_flow.rb:1603:21:1603:21 | x [element 1] | +| array_flow.rb:1603:11:1603:11 | b [element 1] | array_flow.rb:1603:21:1603:21 | x [element 1] | +| array_flow.rb:1603:14:1603:14 | c [element 0] | array_flow.rb:1603:21:1603:21 | x [element 2] | +| array_flow.rb:1603:14:1603:14 | c [element 0] | array_flow.rb:1603:21:1603:21 | x [element 2] | +| array_flow.rb:1603:21:1603:21 | x [element 0] | array_flow.rb:1604:14:1604:14 | x [element 0] | +| array_flow.rb:1603:21:1603:21 | x [element 0] | array_flow.rb:1604:14:1604:14 | x [element 0] | +| array_flow.rb:1603:21:1603:21 | x [element 1] | array_flow.rb:1605:14:1605:14 | x [element 1] | +| array_flow.rb:1603:21:1603:21 | x [element 1] | array_flow.rb:1605:14:1605:14 | x [element 1] | +| array_flow.rb:1603:21:1603:21 | x [element 2] | array_flow.rb:1606:14:1606:14 | x [element 2] | +| array_flow.rb:1603:21:1603:21 | x [element 2] | array_flow.rb:1606:14:1606:14 | x [element 2] | +| array_flow.rb:1604:14:1604:14 | x [element 0] | array_flow.rb:1604:14:1604:17 | ...[...] | +| array_flow.rb:1604:14:1604:14 | x [element 0] | array_flow.rb:1604:14:1604:17 | ...[...] | +| array_flow.rb:1605:14:1605:14 | x [element 1] | array_flow.rb:1605:14:1605:17 | ...[...] | +| array_flow.rb:1605:14:1605:14 | x [element 1] | array_flow.rb:1605:14:1605:17 | ...[...] | +| array_flow.rb:1606:14:1606:14 | x [element 2] | array_flow.rb:1606:14:1606:17 | ...[...] | +| array_flow.rb:1606:14:1606:14 | x [element 2] | array_flow.rb:1606:14:1606:17 | ...[...] | +| array_flow.rb:1611:5:1611:5 | a [element 2] | array_flow.rb:1613:9:1613:9 | a [element 2] | +| array_flow.rb:1611:5:1611:5 | a [element 2] | array_flow.rb:1613:9:1613:9 | a [element 2] | +| array_flow.rb:1611:16:1611:28 | call to source | array_flow.rb:1611:5:1611:5 | a [element 2] | +| array_flow.rb:1611:16:1611:28 | call to source | array_flow.rb:1611:5:1611:5 | a [element 2] | +| array_flow.rb:1612:5:1612:5 | b [element 1] | array_flow.rb:1613:13:1613:13 | b [element 1] | +| array_flow.rb:1612:5:1612:5 | b [element 1] | array_flow.rb:1613:13:1613:13 | b [element 1] | +| array_flow.rb:1612:13:1612:25 | call to source | array_flow.rb:1612:5:1612:5 | b [element 1] | +| array_flow.rb:1612:13:1612:25 | call to source | array_flow.rb:1612:5:1612:5 | b [element 1] | +| array_flow.rb:1613:5:1613:5 | c [element] | array_flow.rb:1614:10:1614:10 | c [element] | +| array_flow.rb:1613:5:1613:5 | c [element] | array_flow.rb:1614:10:1614:10 | c [element] | +| array_flow.rb:1613:5:1613:5 | c [element] | array_flow.rb:1615:10:1615:10 | c [element] | +| array_flow.rb:1613:5:1613:5 | c [element] | array_flow.rb:1615:10:1615:10 | c [element] | +| array_flow.rb:1613:5:1613:5 | c [element] | array_flow.rb:1616:10:1616:10 | c [element] | +| array_flow.rb:1613:5:1613:5 | c [element] | array_flow.rb:1616:10:1616:10 | c [element] | +| array_flow.rb:1613:9:1613:9 | a [element 2] | array_flow.rb:1613:9:1613:13 | ... \| ... [element] | +| array_flow.rb:1613:9:1613:9 | a [element 2] | array_flow.rb:1613:9:1613:13 | ... \| ... [element] | +| array_flow.rb:1613:9:1613:13 | ... \| ... [element] | array_flow.rb:1613:5:1613:5 | c [element] | +| array_flow.rb:1613:9:1613:13 | ... \| ... [element] | array_flow.rb:1613:5:1613:5 | c [element] | +| array_flow.rb:1613:13:1613:13 | b [element 1] | array_flow.rb:1613:9:1613:13 | ... \| ... [element] | +| array_flow.rb:1613:13:1613:13 | b [element 1] | array_flow.rb:1613:9:1613:13 | ... \| ... [element] | +| array_flow.rb:1614:10:1614:10 | c [element] | array_flow.rb:1614:10:1614:13 | ...[...] | +| array_flow.rb:1614:10:1614:10 | c [element] | array_flow.rb:1614:10:1614:13 | ...[...] | +| array_flow.rb:1615:10:1615:10 | c [element] | array_flow.rb:1615:10:1615:13 | ...[...] | +| array_flow.rb:1615:10:1615:10 | c [element] | array_flow.rb:1615:10:1615:13 | ...[...] | +| array_flow.rb:1616:10:1616:10 | c [element] | array_flow.rb:1616:10:1616:13 | ...[...] | +| array_flow.rb:1616:10:1616:10 | c [element] | array_flow.rb:1616:10:1616:13 | ...[...] | +| array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | array_flow.rb:1622:10:1622:10 | a [element, element 0] | +| array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | array_flow.rb:1622:10:1622:10 | a [element, element 0] | +| array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | array_flow.rb:1625:10:1625:10 | a [element, element 0] | +| array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | array_flow.rb:1625:10:1625:10 | a [element, element 0] | +| array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | array_flow.rb:1626:10:1626:10 | a [element, element 0] | +| array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | array_flow.rb:1626:10:1626:10 | a [element, element 0] | +| array_flow.rb:1621:5:1621:8 | [post] ...[...] [element 0] | array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | +| array_flow.rb:1621:5:1621:8 | [post] ...[...] [element 0] | array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | +| array_flow.rb:1621:15:1621:27 | call to source | array_flow.rb:1621:5:1621:8 | [post] ...[...] [element 0] | +| array_flow.rb:1621:15:1621:27 | call to source | array_flow.rb:1621:5:1621:8 | [post] ...[...] [element 0] | +| array_flow.rb:1622:10:1622:10 | a [element, element 0] | array_flow.rb:1622:10:1622:13 | ...[...] [element 0] | +| array_flow.rb:1622:10:1622:10 | a [element, element 0] | array_flow.rb:1622:10:1622:13 | ...[...] [element 0] | +| array_flow.rb:1622:10:1622:13 | ...[...] [element 0] | array_flow.rb:1622:10:1622:16 | ...[...] | +| array_flow.rb:1622:10:1622:13 | ...[...] [element 0] | array_flow.rb:1622:10:1622:16 | ...[...] | +| array_flow.rb:1624:5:1624:5 | [post] a [element 1, element 0] | array_flow.rb:1625:10:1625:10 | a [element 1, element 0] | +| array_flow.rb:1624:5:1624:5 | [post] a [element 1, element 0] | array_flow.rb:1625:10:1625:10 | a [element 1, element 0] | +| array_flow.rb:1624:5:1624:8 | [post] ...[...] [element 0] | array_flow.rb:1624:5:1624:5 | [post] a [element 1, element 0] | +| array_flow.rb:1624:5:1624:8 | [post] ...[...] [element 0] | array_flow.rb:1624:5:1624:5 | [post] a [element 1, element 0] | +| array_flow.rb:1624:15:1624:27 | call to source | array_flow.rb:1624:5:1624:8 | [post] ...[...] [element 0] | +| array_flow.rb:1624:15:1624:27 | call to source | array_flow.rb:1624:5:1624:8 | [post] ...[...] [element 0] | +| array_flow.rb:1625:10:1625:10 | a [element 1, element 0] | array_flow.rb:1625:10:1625:13 | ...[...] [element 0] | +| array_flow.rb:1625:10:1625:10 | a [element 1, element 0] | array_flow.rb:1625:10:1625:13 | ...[...] [element 0] | +| array_flow.rb:1625:10:1625:10 | a [element, element 0] | array_flow.rb:1625:10:1625:13 | ...[...] [element 0] | +| array_flow.rb:1625:10:1625:10 | a [element, element 0] | array_flow.rb:1625:10:1625:13 | ...[...] [element 0] | +| array_flow.rb:1625:10:1625:13 | ...[...] [element 0] | array_flow.rb:1625:10:1625:16 | ...[...] | +| array_flow.rb:1625:10:1625:13 | ...[...] [element 0] | array_flow.rb:1625:10:1625:16 | ...[...] | +| array_flow.rb:1626:10:1626:10 | a [element, element 0] | array_flow.rb:1626:10:1626:13 | ...[...] [element 0] | +| array_flow.rb:1626:10:1626:10 | a [element, element 0] | array_flow.rb:1626:10:1626:13 | ...[...] [element 0] | +| array_flow.rb:1626:10:1626:13 | ...[...] [element 0] | array_flow.rb:1626:10:1626:16 | ...[...] | +| array_flow.rb:1626:10:1626:13 | ...[...] [element 0] | array_flow.rb:1626:10:1626:16 | ...[...] | +| array_flow.rb:1631:5:1631:5 | [post] a [element 0] | array_flow.rb:1640:10:1640:10 | a [element 0] | +| array_flow.rb:1631:5:1631:5 | [post] a [element 0] | array_flow.rb:1640:10:1640:10 | a [element 0] | +| array_flow.rb:1631:5:1631:5 | [post] a [element 0] | array_flow.rb:1642:10:1642:10 | a [element 0] | +| array_flow.rb:1631:5:1631:5 | [post] a [element 0] | array_flow.rb:1642:10:1642:10 | a [element 0] | +| array_flow.rb:1631:12:1631:24 | call to source | array_flow.rb:1631:5:1631:5 | [post] a [element 0] | +| array_flow.rb:1631:12:1631:24 | call to source | array_flow.rb:1631:5:1631:5 | [post] a [element 0] | +| array_flow.rb:1633:5:1633:5 | [post] a [element] | array_flow.rb:1638:10:1638:10 | a [element] | +| array_flow.rb:1633:5:1633:5 | [post] a [element] | array_flow.rb:1638:10:1638:10 | a [element] | +| array_flow.rb:1633:5:1633:5 | [post] a [element] | array_flow.rb:1640:10:1640:10 | a [element] | +| array_flow.rb:1633:5:1633:5 | [post] a [element] | array_flow.rb:1640:10:1640:10 | a [element] | +| array_flow.rb:1633:5:1633:5 | [post] a [element] | array_flow.rb:1642:10:1642:10 | a [element] | +| array_flow.rb:1633:5:1633:5 | [post] a [element] | array_flow.rb:1642:10:1642:10 | a [element] | +| array_flow.rb:1633:16:1633:28 | call to source | array_flow.rb:1633:5:1633:5 | [post] a [element] | +| array_flow.rb:1633:16:1633:28 | call to source | array_flow.rb:1633:5:1633:5 | [post] a [element] | +| array_flow.rb:1635:5:1635:5 | [post] a [element] | array_flow.rb:1638:10:1638:10 | a [element] | +| array_flow.rb:1635:5:1635:5 | [post] a [element] | array_flow.rb:1638:10:1638:10 | a [element] | +| array_flow.rb:1635:5:1635:5 | [post] a [element] | array_flow.rb:1640:10:1640:10 | a [element] | +| array_flow.rb:1635:5:1635:5 | [post] a [element] | array_flow.rb:1640:10:1640:10 | a [element] | +| array_flow.rb:1635:5:1635:5 | [post] a [element] | array_flow.rb:1642:10:1642:10 | a [element] | +| array_flow.rb:1635:5:1635:5 | [post] a [element] | array_flow.rb:1642:10:1642:10 | a [element] | +| array_flow.rb:1635:14:1635:26 | call to source | array_flow.rb:1635:5:1635:5 | [post] a [element] | +| array_flow.rb:1635:14:1635:26 | call to source | array_flow.rb:1635:5:1635:5 | [post] a [element] | +| array_flow.rb:1637:5:1637:5 | [post] a [element] | array_flow.rb:1638:10:1638:10 | a [element] | +| array_flow.rb:1637:5:1637:5 | [post] a [element] | array_flow.rb:1638:10:1638:10 | a [element] | +| array_flow.rb:1637:5:1637:5 | [post] a [element] | array_flow.rb:1640:10:1640:10 | a [element] | +| array_flow.rb:1637:5:1637:5 | [post] a [element] | array_flow.rb:1640:10:1640:10 | a [element] | +| array_flow.rb:1637:5:1637:5 | [post] a [element] | array_flow.rb:1642:10:1642:10 | a [element] | +| array_flow.rb:1637:5:1637:5 | [post] a [element] | array_flow.rb:1642:10:1642:10 | a [element] | +| array_flow.rb:1637:16:1637:28 | call to source | array_flow.rb:1637:5:1637:5 | [post] a [element] | +| array_flow.rb:1637:16:1637:28 | call to source | array_flow.rb:1637:5:1637:5 | [post] a [element] | +| array_flow.rb:1638:10:1638:10 | a [element] | array_flow.rb:1638:10:1638:13 | ...[...] | +| array_flow.rb:1638:10:1638:10 | a [element] | array_flow.rb:1638:10:1638:13 | ...[...] | +| array_flow.rb:1640:10:1640:10 | a [element 0] | array_flow.rb:1640:10:1640:17 | ...[...] | +| array_flow.rb:1640:10:1640:10 | a [element 0] | array_flow.rb:1640:10:1640:17 | ...[...] | +| array_flow.rb:1640:10:1640:10 | a [element] | array_flow.rb:1640:10:1640:17 | ...[...] | +| array_flow.rb:1640:10:1640:10 | a [element] | array_flow.rb:1640:10:1640:17 | ...[...] | +| array_flow.rb:1642:10:1642:10 | a [element 0] | array_flow.rb:1642:10:1642:15 | ...[...] | +| array_flow.rb:1642:10:1642:10 | a [element 0] | array_flow.rb:1642:10:1642:15 | ...[...] | +| array_flow.rb:1642:10:1642:10 | a [element] | array_flow.rb:1642:10:1642:15 | ...[...] | +| array_flow.rb:1642:10:1642:10 | a [element] | array_flow.rb:1642:10:1642:15 | ...[...] | nodes | array_flow.rb:2:5:2:5 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:2:5:2:5 | a [element 0] | semmle.label | a [element 0] | @@ -5488,284 +5496,264 @@ nodes | array_flow.rb:507:5:507:5 | b [element] | semmle.label | b [element] | | array_flow.rb:507:9:507:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:507:9:507:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:507:9:509:7 | call to filter_map [element] | semmle.label | call to filter_map [element] | -| array_flow.rb:507:9:509:7 | call to filter_map [element] | semmle.label | call to filter_map [element] | +| array_flow.rb:507:9:510:7 | call to filter_map [element] | semmle.label | call to filter_map [element] | +| array_flow.rb:507:9:510:7 | call to filter_map [element] | semmle.label | call to filter_map [element] | | array_flow.rb:507:26:507:26 | x | semmle.label | x | | array_flow.rb:507:26:507:26 | x | semmle.label | x | | array_flow.rb:508:14:508:14 | x | semmle.label | x | | array_flow.rb:508:14:508:14 | x | semmle.label | x | -| array_flow.rb:510:10:510:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:510:10:510:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:510:10:510:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:510:10:510:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:514:5:514:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:514:5:514:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:514:19:514:28 | call to source | semmle.label | call to source | -| array_flow.rb:514:19:514:28 | call to source | semmle.label | call to source | -| array_flow.rb:515:5:515:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:515:5:515:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:515:9:515:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:515:9:515:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:515:9:515:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:515:9:515:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:515:9:518:7 | call to filter! [element] | semmle.label | call to filter! [element] | -| array_flow.rb:515:9:518:7 | call to filter! [element] | semmle.label | call to filter! [element] | -| array_flow.rb:515:23:515:23 | x | semmle.label | x | -| array_flow.rb:515:23:515:23 | x | semmle.label | x | -| array_flow.rb:516:14:516:14 | x | semmle.label | x | -| array_flow.rb:516:14:516:14 | x | semmle.label | x | -| array_flow.rb:519:10:519:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:519:10:519:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:519:10:519:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:519:10:519:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:520:10:520:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:520:10:520:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:520:10:520:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:520:10:520:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:524:5:524:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:524:5:524:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:524:19:524:30 | call to source | semmle.label | call to source | -| array_flow.rb:524:19:524:30 | call to source | semmle.label | call to source | -| array_flow.rb:525:5:525:5 | b | semmle.label | b | -| array_flow.rb:525:5:525:5 | b | semmle.label | b | -| array_flow.rb:525:9:525:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:525:9:525:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:525:9:527:7 | call to find | semmle.label | call to find | -| array_flow.rb:525:9:527:7 | call to find | semmle.label | call to find | -| array_flow.rb:525:21:525:32 | call to source | semmle.label | call to source | -| array_flow.rb:525:21:525:32 | call to source | semmle.label | call to source | -| array_flow.rb:525:41:525:41 | x | semmle.label | x | -| array_flow.rb:525:41:525:41 | x | semmle.label | x | -| array_flow.rb:526:14:526:14 | x | semmle.label | x | -| array_flow.rb:526:14:526:14 | x | semmle.label | x | -| array_flow.rb:528:10:528:10 | b | semmle.label | b | -| array_flow.rb:528:10:528:10 | b | semmle.label | b | -| array_flow.rb:532:5:532:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:532:5:532:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:532:19:532:28 | call to source | semmle.label | call to source | -| array_flow.rb:532:19:532:28 | call to source | semmle.label | call to source | -| array_flow.rb:533:5:533:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:533:5:533:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:533:9:533:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:533:9:533:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:533:9:535:7 | call to find_all [element] | semmle.label | call to find_all [element] | -| array_flow.rb:533:9:535:7 | call to find_all [element] | semmle.label | call to find_all [element] | -| array_flow.rb:533:24:533:24 | x | semmle.label | x | -| array_flow.rb:533:24:533:24 | x | semmle.label | x | -| array_flow.rb:534:14:534:14 | x | semmle.label | x | -| array_flow.rb:534:14:534:14 | x | semmle.label | x | -| array_flow.rb:536:10:536:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:536:10:536:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:536:10:536:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:536:10:536:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:540:5:540:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:540:5:540:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:540:19:540:28 | call to source | semmle.label | call to source | -| array_flow.rb:540:19:540:28 | call to source | semmle.label | call to source | -| array_flow.rb:541:5:541:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:541:5:541:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:541:22:541:22 | x | semmle.label | x | -| array_flow.rb:541:22:541:22 | x | semmle.label | x | -| array_flow.rb:542:14:542:14 | x | semmle.label | x | -| array_flow.rb:542:14:542:14 | x | semmle.label | x | -| array_flow.rb:547:5:547:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:547:5:547:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:547:5:547:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:547:5:547:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:547:10:547:21 | call to source | semmle.label | call to source | -| array_flow.rb:547:10:547:21 | call to source | semmle.label | call to source | -| array_flow.rb:547:30:547:41 | call to source | semmle.label | call to source | -| array_flow.rb:547:30:547:41 | call to source | semmle.label | call to source | -| array_flow.rb:548:5:548:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:548:5:548:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:548:12:548:23 | call to source | semmle.label | call to source | -| array_flow.rb:548:12:548:23 | call to source | semmle.label | call to source | -| array_flow.rb:549:10:549:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:549:10:549:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:549:10:549:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:549:10:549:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:549:10:549:16 | call to first | semmle.label | call to first | -| array_flow.rb:549:10:549:16 | call to first | semmle.label | call to first | -| array_flow.rb:550:5:550:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:550:5:550:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:550:5:550:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:550:5:550:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:550:9:550:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:550:9:550:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:550:9:550:9 | a [element] | semmle.label | a [element] | -| array_flow.rb:550:9:550:9 | a [element] | semmle.label | a [element] | -| array_flow.rb:550:9:550:18 | call to first [element 0] | semmle.label | call to first [element 0] | -| array_flow.rb:550:9:550:18 | call to first [element 0] | semmle.label | call to first [element 0] | -| array_flow.rb:550:9:550:18 | call to first [element] | semmle.label | call to first [element] | -| array_flow.rb:550:9:550:18 | call to first [element] | semmle.label | call to first [element] | -| array_flow.rb:551:10:551:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:551:10:551:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:551:10:551:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:551:10:551:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:551:10:551:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:551:10:551:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:552:10:552:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:552:10:552:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:552:10:552:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:552:10:552:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:553:5:553:5 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:553:5:553:5 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:553:5:553:5 | c [element 3] | semmle.label | c [element 3] | -| array_flow.rb:553:5:553:5 | c [element 3] | semmle.label | c [element 3] | -| array_flow.rb:553:5:553:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:553:5:553:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:553:9:553:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:553:9:553:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:553:9:553:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:553:9:553:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:553:9:553:9 | a [element] | semmle.label | a [element] | -| array_flow.rb:553:9:553:9 | a [element] | semmle.label | a [element] | -| array_flow.rb:553:9:553:18 | call to first [element 0] | semmle.label | call to first [element 0] | -| array_flow.rb:553:9:553:18 | call to first [element 0] | semmle.label | call to first [element 0] | -| array_flow.rb:553:9:553:18 | call to first [element 3] | semmle.label | call to first [element 3] | -| array_flow.rb:553:9:553:18 | call to first [element 3] | semmle.label | call to first [element 3] | -| array_flow.rb:553:9:553:18 | call to first [element] | semmle.label | call to first [element] | -| array_flow.rb:553:9:553:18 | call to first [element] | semmle.label | call to first [element] | -| array_flow.rb:554:10:554:10 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:554:10:554:10 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:554:10:554:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:554:10:554:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:554:10:554:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:554:10:554:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:555:10:555:10 | c [element 3] | semmle.label | c [element 3] | -| array_flow.rb:555:10:555:10 | c [element 3] | semmle.label | c [element 3] | -| array_flow.rb:555:10:555:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:555:10:555:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:555:10:555:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:555:10:555:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:559:5:559:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:559:5:559:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:559:16:559:27 | call to source | semmle.label | call to source | -| array_flow.rb:559:16:559:27 | call to source | semmle.label | call to source | -| array_flow.rb:560:5:560:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:560:5:560:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:560:9:560:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:560:9:560:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:560:9:563:7 | call to flat_map [element] | semmle.label | call to flat_map [element] | -| array_flow.rb:560:9:563:7 | call to flat_map [element] | semmle.label | call to flat_map [element] | -| array_flow.rb:560:24:560:24 | x | semmle.label | x | -| array_flow.rb:560:24:560:24 | x | semmle.label | x | -| array_flow.rb:561:14:561:14 | x | semmle.label | x | -| array_flow.rb:561:14:561:14 | x | semmle.label | x | -| array_flow.rb:562:13:562:24 | call to source | semmle.label | call to source | -| array_flow.rb:562:13:562:24 | call to source | semmle.label | call to source | -| array_flow.rb:564:10:564:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:564:10:564:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:564:10:564:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:564:10:564:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:565:5:565:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:565:5:565:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:565:9:565:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:565:9:565:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:565:9:568:7 | call to flat_map [element] | semmle.label | call to flat_map [element] | -| array_flow.rb:565:9:568:7 | call to flat_map [element] | semmle.label | call to flat_map [element] | -| array_flow.rb:565:24:565:24 | x | semmle.label | x | -| array_flow.rb:565:24:565:24 | x | semmle.label | x | -| array_flow.rb:566:14:566:14 | x | semmle.label | x | -| array_flow.rb:566:14:566:14 | x | semmle.label | x | -| array_flow.rb:567:9:567:20 | call to source | semmle.label | call to source | -| array_flow.rb:567:9:567:20 | call to source | semmle.label | call to source | -| array_flow.rb:569:10:569:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:569:10:569:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:569:10:569:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:569:10:569:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:573:5:573:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:573:5:573:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:573:20:573:29 | call to source | semmle.label | call to source | -| array_flow.rb:573:20:573:29 | call to source | semmle.label | call to source | -| array_flow.rb:574:5:574:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:574:5:574:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:574:9:574:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:574:9:574:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:574:9:574:17 | call to flatten [element] | semmle.label | call to flatten [element] | -| array_flow.rb:574:9:574:17 | call to flatten [element] | semmle.label | call to flatten [element] | +| array_flow.rb:511:10:511:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:511:10:511:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:511:10:511:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:511:10:511:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:518:5:518:5 | d [element] | semmle.label | d [element] | +| array_flow.rb:518:5:518:5 | d [element] | semmle.label | d [element] | +| array_flow.rb:518:9:520:7 | call to filter_map [element] | semmle.label | call to filter_map [element] | +| array_flow.rb:518:9:520:7 | call to filter_map [element] | semmle.label | call to filter_map [element] | +| array_flow.rb:519:9:519:20 | call to source | semmle.label | call to source | +| array_flow.rb:519:9:519:20 | call to source | semmle.label | call to source | +| array_flow.rb:521:10:521:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:521:10:521:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:521:10:521:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:521:10:521:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:525:5:525:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:525:5:525:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:525:19:525:28 | call to source | semmle.label | call to source | +| array_flow.rb:525:19:525:28 | call to source | semmle.label | call to source | +| array_flow.rb:526:5:526:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:526:5:526:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:526:9:526:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:526:9:526:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:526:9:526:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:526:9:526:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:526:9:529:7 | call to filter! [element] | semmle.label | call to filter! [element] | +| array_flow.rb:526:9:529:7 | call to filter! [element] | semmle.label | call to filter! [element] | +| array_flow.rb:526:23:526:23 | x | semmle.label | x | +| array_flow.rb:526:23:526:23 | x | semmle.label | x | +| array_flow.rb:527:14:527:14 | x | semmle.label | x | +| array_flow.rb:527:14:527:14 | x | semmle.label | x | +| array_flow.rb:530:10:530:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:530:10:530:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:530:10:530:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:530:10:530:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:531:10:531:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:531:10:531:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:531:10:531:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:531:10:531:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:535:5:535:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:535:5:535:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:535:19:535:30 | call to source | semmle.label | call to source | +| array_flow.rb:535:19:535:30 | call to source | semmle.label | call to source | +| array_flow.rb:536:5:536:5 | b | semmle.label | b | +| array_flow.rb:536:5:536:5 | b | semmle.label | b | +| array_flow.rb:536:9:536:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:536:9:536:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:536:9:538:7 | call to find | semmle.label | call to find | +| array_flow.rb:536:9:538:7 | call to find | semmle.label | call to find | +| array_flow.rb:536:21:536:32 | call to source | semmle.label | call to source | +| array_flow.rb:536:21:536:32 | call to source | semmle.label | call to source | +| array_flow.rb:536:41:536:41 | x | semmle.label | x | +| array_flow.rb:536:41:536:41 | x | semmle.label | x | +| array_flow.rb:537:14:537:14 | x | semmle.label | x | +| array_flow.rb:537:14:537:14 | x | semmle.label | x | +| array_flow.rb:539:10:539:10 | b | semmle.label | b | +| array_flow.rb:539:10:539:10 | b | semmle.label | b | +| array_flow.rb:543:5:543:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:543:5:543:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:543:19:543:28 | call to source | semmle.label | call to source | +| array_flow.rb:543:19:543:28 | call to source | semmle.label | call to source | +| array_flow.rb:544:5:544:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:544:5:544:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:544:9:544:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:544:9:544:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:544:9:546:7 | call to find_all [element] | semmle.label | call to find_all [element] | +| array_flow.rb:544:9:546:7 | call to find_all [element] | semmle.label | call to find_all [element] | +| array_flow.rb:544:24:544:24 | x | semmle.label | x | +| array_flow.rb:544:24:544:24 | x | semmle.label | x | +| array_flow.rb:545:14:545:14 | x | semmle.label | x | +| array_flow.rb:545:14:545:14 | x | semmle.label | x | +| array_flow.rb:547:10:547:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:547:10:547:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:547:10:547:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:547:10:547:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:551:5:551:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:551:5:551:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:551:19:551:28 | call to source | semmle.label | call to source | +| array_flow.rb:551:19:551:28 | call to source | semmle.label | call to source | +| array_flow.rb:552:5:552:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:552:5:552:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:552:22:552:22 | x | semmle.label | x | +| array_flow.rb:552:22:552:22 | x | semmle.label | x | +| array_flow.rb:553:14:553:14 | x | semmle.label | x | +| array_flow.rb:553:14:553:14 | x | semmle.label | x | +| array_flow.rb:558:5:558:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:558:5:558:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:558:5:558:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:558:5:558:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:558:10:558:21 | call to source | semmle.label | call to source | +| array_flow.rb:558:10:558:21 | call to source | semmle.label | call to source | +| array_flow.rb:558:30:558:41 | call to source | semmle.label | call to source | +| array_flow.rb:558:30:558:41 | call to source | semmle.label | call to source | +| array_flow.rb:559:5:559:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:559:5:559:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:559:12:559:23 | call to source | semmle.label | call to source | +| array_flow.rb:559:12:559:23 | call to source | semmle.label | call to source | +| array_flow.rb:560:10:560:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:560:10:560:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:560:10:560:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:560:10:560:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:560:10:560:16 | call to first | semmle.label | call to first | +| array_flow.rb:560:10:560:16 | call to first | semmle.label | call to first | +| array_flow.rb:561:5:561:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:561:5:561:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:561:5:561:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:561:5:561:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:561:9:561:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:561:9:561:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:561:9:561:9 | a [element] | semmle.label | a [element] | +| array_flow.rb:561:9:561:9 | a [element] | semmle.label | a [element] | +| array_flow.rb:561:9:561:18 | call to first [element 0] | semmle.label | call to first [element 0] | +| array_flow.rb:561:9:561:18 | call to first [element 0] | semmle.label | call to first [element 0] | +| array_flow.rb:561:9:561:18 | call to first [element] | semmle.label | call to first [element] | +| array_flow.rb:561:9:561:18 | call to first [element] | semmle.label | call to first [element] | +| array_flow.rb:562:10:562:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:562:10:562:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:562:10:562:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:562:10:562:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:562:10:562:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:562:10:562:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:563:10:563:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:563:10:563:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:563:10:563:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:563:10:563:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:564:5:564:5 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:564:5:564:5 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:564:5:564:5 | c [element 3] | semmle.label | c [element 3] | +| array_flow.rb:564:5:564:5 | c [element 3] | semmle.label | c [element 3] | +| array_flow.rb:564:5:564:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:564:5:564:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:564:9:564:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:564:9:564:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:564:9:564:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:564:9:564:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:564:9:564:9 | a [element] | semmle.label | a [element] | +| array_flow.rb:564:9:564:9 | a [element] | semmle.label | a [element] | +| array_flow.rb:564:9:564:18 | call to first [element 0] | semmle.label | call to first [element 0] | +| array_flow.rb:564:9:564:18 | call to first [element 0] | semmle.label | call to first [element 0] | +| array_flow.rb:564:9:564:18 | call to first [element 3] | semmle.label | call to first [element 3] | +| array_flow.rb:564:9:564:18 | call to first [element 3] | semmle.label | call to first [element 3] | +| array_flow.rb:564:9:564:18 | call to first [element] | semmle.label | call to first [element] | +| array_flow.rb:564:9:564:18 | call to first [element] | semmle.label | call to first [element] | +| array_flow.rb:565:10:565:10 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:565:10:565:10 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:565:10:565:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:565:10:565:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:565:10:565:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:565:10:565:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:566:10:566:10 | c [element 3] | semmle.label | c [element 3] | +| array_flow.rb:566:10:566:10 | c [element 3] | semmle.label | c [element 3] | +| array_flow.rb:566:10:566:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:566:10:566:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:566:10:566:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:566:10:566:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:570:5:570:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:570:5:570:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:570:16:570:27 | call to source | semmle.label | call to source | +| array_flow.rb:570:16:570:27 | call to source | semmle.label | call to source | +| array_flow.rb:571:5:571:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:571:5:571:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:571:9:571:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:571:9:571:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:571:9:574:7 | call to flat_map [element] | semmle.label | call to flat_map [element] | +| array_flow.rb:571:9:574:7 | call to flat_map [element] | semmle.label | call to flat_map [element] | +| array_flow.rb:571:24:571:24 | x | semmle.label | x | +| array_flow.rb:571:24:571:24 | x | semmle.label | x | +| array_flow.rb:572:14:572:14 | x | semmle.label | x | +| array_flow.rb:572:14:572:14 | x | semmle.label | x | +| array_flow.rb:573:13:573:24 | call to source | semmle.label | call to source | +| array_flow.rb:573:13:573:24 | call to source | semmle.label | call to source | | array_flow.rb:575:10:575:10 | b [element] | semmle.label | b [element] | | array_flow.rb:575:10:575:10 | b [element] | semmle.label | b [element] | | array_flow.rb:575:10:575:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:575:10:575:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:579:5:579:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:579:5:579:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:579:20:579:29 | call to source | semmle.label | call to source | -| array_flow.rb:579:20:579:29 | call to source | semmle.label | call to source | -| array_flow.rb:580:10:580:10 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:580:10:580:10 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:580:10:580:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:580:10:580:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:580:10:580:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:580:10:580:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:581:5:581:5 | b [element, element 1] | semmle.label | b [element, element 1] | -| array_flow.rb:581:5:581:5 | b [element, element 1] | semmle.label | b [element, element 1] | -| array_flow.rb:581:5:581:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:581:5:581:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:581:9:581:9 | [post] a [element, element 1] | semmle.label | [post] a [element, element 1] | -| array_flow.rb:581:9:581:9 | [post] a [element, element 1] | semmle.label | [post] a [element, element 1] | -| array_flow.rb:581:9:581:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:581:9:581:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:581:9:581:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] | semmle.label | call to flatten! [element, element 1] | -| array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] | semmle.label | call to flatten! [element, element 1] | -| array_flow.rb:581:9:581:18 | call to flatten! [element] | semmle.label | call to flatten! [element] | -| array_flow.rb:581:9:581:18 | call to flatten! [element] | semmle.label | call to flatten! [element] | -| array_flow.rb:582:10:582:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:582:10:582:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:582:10:582:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:582:10:582:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:583:10:583:10 | a [element, element 1] | semmle.label | a [element, element 1] | -| array_flow.rb:583:10:583:10 | a [element, element 1] | semmle.label | a [element, element 1] | -| array_flow.rb:583:10:583:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:583:10:583:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:583:10:583:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:583:10:583:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:583:10:583:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:583:10:583:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:584:10:584:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:584:10:584:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:584:10:584:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:584:10:584:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:585:10:585:10 | b [element, element 1] | semmle.label | b [element, element 1] | -| array_flow.rb:585:10:585:10 | b [element, element 1] | semmle.label | b [element, element 1] | -| array_flow.rb:585:10:585:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:585:10:585:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:585:10:585:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:585:10:585:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:585:10:585:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:585:10:585:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:589:5:589:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:589:5:589:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:589:19:589:30 | call to source | semmle.label | call to source | -| array_flow.rb:589:19:589:30 | call to source | semmle.label | call to source | -| array_flow.rb:590:5:590:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:590:5:590:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:590:9:590:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:590:9:590:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:590:9:590:20 | call to grep [element] | semmle.label | call to grep [element] | -| array_flow.rb:590:9:590:20 | call to grep [element] | semmle.label | call to grep [element] | -| array_flow.rb:591:10:591:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:591:10:591:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:591:10:591:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:591:10:591:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:576:5:576:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:576:5:576:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:576:9:576:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:576:9:576:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:576:9:579:7 | call to flat_map [element] | semmle.label | call to flat_map [element] | +| array_flow.rb:576:9:579:7 | call to flat_map [element] | semmle.label | call to flat_map [element] | +| array_flow.rb:576:24:576:24 | x | semmle.label | x | +| array_flow.rb:576:24:576:24 | x | semmle.label | x | +| array_flow.rb:577:14:577:14 | x | semmle.label | x | +| array_flow.rb:577:14:577:14 | x | semmle.label | x | +| array_flow.rb:578:9:578:20 | call to source | semmle.label | call to source | +| array_flow.rb:578:9:578:20 | call to source | semmle.label | call to source | +| array_flow.rb:580:10:580:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:580:10:580:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:580:10:580:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:580:10:580:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:584:5:584:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:584:5:584:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:584:20:584:29 | call to source | semmle.label | call to source | +| array_flow.rb:584:20:584:29 | call to source | semmle.label | call to source | +| array_flow.rb:585:5:585:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:585:5:585:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:585:9:585:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:585:9:585:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:585:9:585:17 | call to flatten [element] | semmle.label | call to flatten [element] | +| array_flow.rb:585:9:585:17 | call to flatten [element] | semmle.label | call to flatten [element] | +| array_flow.rb:586:10:586:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:586:10:586:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:586:10:586:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:586:10:586:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:590:5:590:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:590:5:590:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:590:20:590:29 | call to source | semmle.label | call to source | +| array_flow.rb:590:20:590:29 | call to source | semmle.label | call to source | +| array_flow.rb:591:10:591:10 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:591:10:591:10 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:591:10:591:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:591:10:591:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:591:10:591:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:591:10:591:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:592:5:592:5 | b [element, element 1] | semmle.label | b [element, element 1] | +| array_flow.rb:592:5:592:5 | b [element, element 1] | semmle.label | b [element, element 1] | | array_flow.rb:592:5:592:5 | b [element] | semmle.label | b [element] | | array_flow.rb:592:5:592:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:592:9:592:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:592:9:592:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:592:9:595:7 | call to grep [element] | semmle.label | call to grep [element] | -| array_flow.rb:592:9:595:7 | call to grep [element] | semmle.label | call to grep [element] | -| array_flow.rb:592:26:592:26 | x | semmle.label | x | -| array_flow.rb:592:26:592:26 | x | semmle.label | x | -| array_flow.rb:593:14:593:14 | x | semmle.label | x | -| array_flow.rb:593:14:593:14 | x | semmle.label | x | -| array_flow.rb:594:9:594:20 | call to source | semmle.label | call to source | -| array_flow.rb:594:9:594:20 | call to source | semmle.label | call to source | -| array_flow.rb:596:10:596:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:592:9:592:9 | [post] a [element, element 1] | semmle.label | [post] a [element, element 1] | +| array_flow.rb:592:9:592:9 | [post] a [element, element 1] | semmle.label | [post] a [element, element 1] | +| array_flow.rb:592:9:592:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:592:9:592:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:592:9:592:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:592:9:592:18 | call to flatten! [element, element 1] | semmle.label | call to flatten! [element, element 1] | +| array_flow.rb:592:9:592:18 | call to flatten! [element, element 1] | semmle.label | call to flatten! [element, element 1] | +| array_flow.rb:592:9:592:18 | call to flatten! [element] | semmle.label | call to flatten! [element] | +| array_flow.rb:592:9:592:18 | call to flatten! [element] | semmle.label | call to flatten! [element] | +| array_flow.rb:593:10:593:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:593:10:593:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:593:10:593:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:593:10:593:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:594:10:594:10 | a [element, element 1] | semmle.label | a [element, element 1] | +| array_flow.rb:594:10:594:10 | a [element, element 1] | semmle.label | a [element, element 1] | +| array_flow.rb:594:10:594:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:594:10:594:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:594:10:594:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:594:10:594:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:594:10:594:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:594:10:594:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:595:10:595:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:595:10:595:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:595:10:595:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:595:10:595:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:596:10:596:10 | b [element, element 1] | semmle.label | b [element, element 1] | +| array_flow.rb:596:10:596:10 | b [element, element 1] | semmle.label | b [element, element 1] | | array_flow.rb:596:10:596:10 | b [element] | semmle.label | b [element] | | array_flow.rb:596:10:596:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:596:10:596:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:596:10:596:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:596:10:596:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:596:10:596:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:596:10:596:16 | ...[...] | semmle.label | ...[...] | | array_flow.rb:600:5:600:5 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:600:5:600:5 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:600:19:600:30 | call to source | semmle.label | call to source | @@ -5774,8 +5762,8 @@ nodes | array_flow.rb:601:5:601:5 | b [element] | semmle.label | b [element] | | array_flow.rb:601:9:601:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:601:9:601:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:601:9:601:21 | call to grep_v [element] | semmle.label | call to grep_v [element] | -| array_flow.rb:601:9:601:21 | call to grep_v [element] | semmle.label | call to grep_v [element] | +| array_flow.rb:601:9:601:20 | call to grep [element] | semmle.label | call to grep [element] | +| array_flow.rb:601:9:601:20 | call to grep [element] | semmle.label | call to grep [element] | | array_flow.rb:602:10:602:10 | b [element] | semmle.label | b [element] | | array_flow.rb:602:10:602:10 | b [element] | semmle.label | b [element] | | array_flow.rb:602:10:602:13 | ...[...] | semmle.label | ...[...] | @@ -5784,10 +5772,10 @@ nodes | array_flow.rb:603:5:603:5 | b [element] | semmle.label | b [element] | | array_flow.rb:603:9:603:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:603:9:603:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:603:9:606:7 | call to grep_v [element] | semmle.label | call to grep_v [element] | -| array_flow.rb:603:9:606:7 | call to grep_v [element] | semmle.label | call to grep_v [element] | -| array_flow.rb:603:27:603:27 | x | semmle.label | x | -| array_flow.rb:603:27:603:27 | x | semmle.label | x | +| array_flow.rb:603:9:606:7 | call to grep [element] | semmle.label | call to grep [element] | +| array_flow.rb:603:9:606:7 | call to grep [element] | semmle.label | call to grep [element] | +| array_flow.rb:603:26:603:26 | x | semmle.label | x | +| array_flow.rb:603:26:603:26 | x | semmle.label | x | | array_flow.rb:604:14:604:14 | x | semmle.label | x | | array_flow.rb:604:14:604:14 | x | semmle.label | x | | array_flow.rb:605:9:605:20 | call to source | semmle.label | call to source | @@ -5800,944 +5788,938 @@ nodes | array_flow.rb:611:5:611:5 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:611:19:611:30 | call to source | semmle.label | call to source | | array_flow.rb:611:19:611:30 | call to source | semmle.label | call to source | +| array_flow.rb:612:5:612:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:612:5:612:5 | b [element] | semmle.label | b [element] | | array_flow.rb:612:9:612:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:612:9:612:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:612:24:612:24 | x | semmle.label | x | -| array_flow.rb:612:24:612:24 | x | semmle.label | x | -| array_flow.rb:613:14:613:14 | x | semmle.label | x | -| array_flow.rb:613:14:613:14 | x | semmle.label | x | -| array_flow.rb:620:5:620:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:620:5:620:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:620:19:620:28 | call to source | semmle.label | call to source | -| array_flow.rb:620:19:620:28 | call to source | semmle.label | call to source | -| array_flow.rb:621:5:621:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:621:5:621:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:621:17:621:17 | x | semmle.label | x | -| array_flow.rb:621:17:621:17 | x | semmle.label | x | -| array_flow.rb:622:14:622:14 | x | semmle.label | x | -| array_flow.rb:622:14:622:14 | x | semmle.label | x | -| array_flow.rb:627:5:627:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:627:5:627:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:627:5:627:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:627:5:627:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:627:10:627:21 | call to source | semmle.label | call to source | -| array_flow.rb:627:10:627:21 | call to source | semmle.label | call to source | -| array_flow.rb:627:27:627:38 | call to source | semmle.label | call to source | -| array_flow.rb:627:27:627:38 | call to source | semmle.label | call to source | -| array_flow.rb:628:5:628:5 | b | semmle.label | b | -| array_flow.rb:628:5:628:5 | b | semmle.label | b | -| array_flow.rb:628:9:628:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:628:9:628:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:628:9:628:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:628:9:628:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:628:9:632:7 | call to inject | semmle.label | call to inject | -| array_flow.rb:628:9:632:7 | call to inject | semmle.label | call to inject | -| array_flow.rb:628:22:628:22 | x | semmle.label | x | -| array_flow.rb:628:22:628:22 | x | semmle.label | x | -| array_flow.rb:628:25:628:25 | y | semmle.label | y | -| array_flow.rb:628:25:628:25 | y | semmle.label | y | -| array_flow.rb:629:14:629:14 | x | semmle.label | x | -| array_flow.rb:629:14:629:14 | x | semmle.label | x | -| array_flow.rb:630:14:630:14 | y | semmle.label | y | -| array_flow.rb:630:14:630:14 | y | semmle.label | y | -| array_flow.rb:631:9:631:19 | call to source | semmle.label | call to source | -| array_flow.rb:631:9:631:19 | call to source | semmle.label | call to source | -| array_flow.rb:633:10:633:10 | b | semmle.label | b | -| array_flow.rb:633:10:633:10 | b | semmle.label | b | -| array_flow.rb:634:5:634:5 | c | semmle.label | c | -| array_flow.rb:634:5:634:5 | c | semmle.label | c | -| array_flow.rb:634:9:634:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:634:9:634:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:634:9:634:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:634:9:634:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:634:9:638:7 | call to inject | semmle.label | call to inject | -| array_flow.rb:634:9:638:7 | call to inject | semmle.label | call to inject | -| array_flow.rb:634:28:634:28 | y | semmle.label | y | -| array_flow.rb:634:28:634:28 | y | semmle.label | y | -| array_flow.rb:636:14:636:14 | y | semmle.label | y | -| array_flow.rb:636:14:636:14 | y | semmle.label | y | -| array_flow.rb:637:9:637:19 | call to source | semmle.label | call to source | -| array_flow.rb:637:9:637:19 | call to source | semmle.label | call to source | -| array_flow.rb:639:10:639:10 | c | semmle.label | c | -| array_flow.rb:639:10:639:10 | c | semmle.label | c | -| array_flow.rb:644:5:644:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:644:5:644:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:644:16:644:27 | call to source | semmle.label | call to source | -| array_flow.rb:644:16:644:27 | call to source | semmle.label | call to source | -| array_flow.rb:645:5:645:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:645:5:645:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:645:5:645:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:645:5:645:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:645:5:645:5 | b [element 4] | semmle.label | b [element 4] | -| array_flow.rb:645:5:645:5 | b [element 4] | semmle.label | b [element 4] | -| array_flow.rb:645:9:645:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | -| array_flow.rb:645:9:645:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | -| array_flow.rb:645:9:645:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:645:9:645:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:645:9:645:9 | [post] a [element 4] | semmle.label | [post] a [element 4] | -| array_flow.rb:645:9:645:9 | [post] a [element 4] | semmle.label | [post] a [element 4] | +| array_flow.rb:612:9:612:21 | call to grep_v [element] | semmle.label | call to grep_v [element] | +| array_flow.rb:612:9:612:21 | call to grep_v [element] | semmle.label | call to grep_v [element] | +| array_flow.rb:613:10:613:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:613:10:613:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:613:10:613:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:613:10:613:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:614:5:614:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:614:5:614:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:614:9:614:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:614:9:614:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:614:9:617:7 | call to grep_v [element] | semmle.label | call to grep_v [element] | +| array_flow.rb:614:9:617:7 | call to grep_v [element] | semmle.label | call to grep_v [element] | +| array_flow.rb:614:27:614:27 | x | semmle.label | x | +| array_flow.rb:614:27:614:27 | x | semmle.label | x | +| array_flow.rb:615:14:615:14 | x | semmle.label | x | +| array_flow.rb:615:14:615:14 | x | semmle.label | x | +| array_flow.rb:616:9:616:20 | call to source | semmle.label | call to source | +| array_flow.rb:616:9:616:20 | call to source | semmle.label | call to source | +| array_flow.rb:618:10:618:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:618:10:618:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:618:10:618:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:618:10:618:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:622:5:622:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:622:5:622:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:622:19:622:30 | call to source | semmle.label | call to source | +| array_flow.rb:622:19:622:30 | call to source | semmle.label | call to source | +| array_flow.rb:623:9:623:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:623:9:623:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:623:24:623:24 | x | semmle.label | x | +| array_flow.rb:623:24:623:24 | x | semmle.label | x | +| array_flow.rb:624:14:624:14 | x | semmle.label | x | +| array_flow.rb:624:14:624:14 | x | semmle.label | x | +| array_flow.rb:631:5:631:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:631:5:631:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:631:19:631:28 | call to source | semmle.label | call to source | +| array_flow.rb:631:19:631:28 | call to source | semmle.label | call to source | +| array_flow.rb:632:5:632:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:632:5:632:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:632:17:632:17 | x | semmle.label | x | +| array_flow.rb:632:17:632:17 | x | semmle.label | x | +| array_flow.rb:633:14:633:14 | x | semmle.label | x | +| array_flow.rb:633:14:633:14 | x | semmle.label | x | +| array_flow.rb:638:5:638:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:638:5:638:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:638:5:638:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:638:5:638:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:638:10:638:21 | call to source | semmle.label | call to source | +| array_flow.rb:638:10:638:21 | call to source | semmle.label | call to source | +| array_flow.rb:638:27:638:38 | call to source | semmle.label | call to source | +| array_flow.rb:638:27:638:38 | call to source | semmle.label | call to source | +| array_flow.rb:639:5:639:5 | b | semmle.label | b | +| array_flow.rb:639:5:639:5 | b | semmle.label | b | +| array_flow.rb:639:9:639:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:639:9:639:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:639:9:639:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:639:9:639:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:639:9:643:7 | call to inject | semmle.label | call to inject | +| array_flow.rb:639:9:643:7 | call to inject | semmle.label | call to inject | +| array_flow.rb:639:22:639:22 | x | semmle.label | x | +| array_flow.rb:639:22:639:22 | x | semmle.label | x | +| array_flow.rb:639:25:639:25 | y | semmle.label | y | +| array_flow.rb:639:25:639:25 | y | semmle.label | y | +| array_flow.rb:640:14:640:14 | x | semmle.label | x | +| array_flow.rb:640:14:640:14 | x | semmle.label | x | +| array_flow.rb:641:14:641:14 | y | semmle.label | y | +| array_flow.rb:641:14:641:14 | y | semmle.label | y | +| array_flow.rb:642:9:642:19 | call to source | semmle.label | call to source | +| array_flow.rb:642:9:642:19 | call to source | semmle.label | call to source | +| array_flow.rb:644:10:644:10 | b | semmle.label | b | +| array_flow.rb:644:10:644:10 | b | semmle.label | b | +| array_flow.rb:645:5:645:5 | c | semmle.label | c | +| array_flow.rb:645:5:645:5 | c | semmle.label | c | +| array_flow.rb:645:9:645:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:645:9:645:9 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:645:9:645:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:645:9:645:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:645:9:645:47 | call to insert [element 1] | semmle.label | call to insert [element 1] | -| array_flow.rb:645:9:645:47 | call to insert [element 1] | semmle.label | call to insert [element 1] | -| array_flow.rb:645:9:645:47 | call to insert [element 2] | semmle.label | call to insert [element 2] | -| array_flow.rb:645:9:645:47 | call to insert [element 2] | semmle.label | call to insert [element 2] | -| array_flow.rb:645:9:645:47 | call to insert [element 4] | semmle.label | call to insert [element 4] | -| array_flow.rb:645:9:645:47 | call to insert [element 4] | semmle.label | call to insert [element 4] | -| array_flow.rb:645:21:645:32 | call to source | semmle.label | call to source | -| array_flow.rb:645:21:645:32 | call to source | semmle.label | call to source | -| array_flow.rb:645:35:645:46 | call to source | semmle.label | call to source | -| array_flow.rb:645:35:645:46 | call to source | semmle.label | call to source | -| array_flow.rb:647:10:647:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:647:10:647:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:647:10:647:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:647:10:647:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:648:10:648:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:648:10:648:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:648:10:648:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:648:10:648:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:650:10:650:10 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:650:10:650:10 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:650:10:650:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:650:10:650:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:652:10:652:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:652:10:652:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:652:10:652:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:652:10:652:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:653:10:653:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:653:10:653:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:653:10:653:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:653:10:653:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:655:10:655:10 | b [element 4] | semmle.label | b [element 4] | -| array_flow.rb:655:10:655:10 | b [element 4] | semmle.label | b [element 4] | -| array_flow.rb:655:10:655:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:655:10:655:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:658:5:658:5 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:658:5:658:5 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:658:16:658:27 | call to source | semmle.label | call to source | -| array_flow.rb:658:16:658:27 | call to source | semmle.label | call to source | -| array_flow.rb:659:5:659:5 | d [element] | semmle.label | d [element] | -| array_flow.rb:659:5:659:5 | d [element] | semmle.label | d [element] | -| array_flow.rb:659:9:659:9 | [post] c [element] | semmle.label | [post] c [element] | -| array_flow.rb:659:9:659:9 | [post] c [element] | semmle.label | [post] c [element] | -| array_flow.rb:659:9:659:9 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:659:9:659:9 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:659:9:659:47 | call to insert [element] | semmle.label | call to insert [element] | -| array_flow.rb:659:9:659:47 | call to insert [element] | semmle.label | call to insert [element] | -| array_flow.rb:659:21:659:32 | call to source | semmle.label | call to source | -| array_flow.rb:659:21:659:32 | call to source | semmle.label | call to source | -| array_flow.rb:659:35:659:46 | call to source | semmle.label | call to source | -| array_flow.rb:659:35:659:46 | call to source | semmle.label | call to source | -| array_flow.rb:660:10:660:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:660:10:660:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:660:10:660:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:660:10:660:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:661:10:661:10 | d [element] | semmle.label | d [element] | -| array_flow.rb:661:10:661:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:645:9:649:7 | call to inject | semmle.label | call to inject | +| array_flow.rb:645:9:649:7 | call to inject | semmle.label | call to inject | +| array_flow.rb:645:28:645:28 | y | semmle.label | y | +| array_flow.rb:645:28:645:28 | y | semmle.label | y | +| array_flow.rb:647:14:647:14 | y | semmle.label | y | +| array_flow.rb:647:14:647:14 | y | semmle.label | y | +| array_flow.rb:648:9:648:19 | call to source | semmle.label | call to source | +| array_flow.rb:648:9:648:19 | call to source | semmle.label | call to source | +| array_flow.rb:650:10:650:10 | c | semmle.label | c | +| array_flow.rb:650:10:650:10 | c | semmle.label | c | +| array_flow.rb:655:5:655:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:655:5:655:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:655:16:655:27 | call to source | semmle.label | call to source | +| array_flow.rb:655:16:655:27 | call to source | semmle.label | call to source | +| array_flow.rb:656:5:656:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:656:5:656:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:656:5:656:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:656:5:656:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:656:5:656:5 | b [element 4] | semmle.label | b [element 4] | +| array_flow.rb:656:5:656:5 | b [element 4] | semmle.label | b [element 4] | +| array_flow.rb:656:9:656:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:656:9:656:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:656:9:656:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:656:9:656:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:656:9:656:9 | [post] a [element 4] | semmle.label | [post] a [element 4] | +| array_flow.rb:656:9:656:9 | [post] a [element 4] | semmle.label | [post] a [element 4] | +| array_flow.rb:656:9:656:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:656:9:656:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:656:9:656:47 | call to insert [element 1] | semmle.label | call to insert [element 1] | +| array_flow.rb:656:9:656:47 | call to insert [element 1] | semmle.label | call to insert [element 1] | +| array_flow.rb:656:9:656:47 | call to insert [element 2] | semmle.label | call to insert [element 2] | +| array_flow.rb:656:9:656:47 | call to insert [element 2] | semmle.label | call to insert [element 2] | +| array_flow.rb:656:9:656:47 | call to insert [element 4] | semmle.label | call to insert [element 4] | +| array_flow.rb:656:9:656:47 | call to insert [element 4] | semmle.label | call to insert [element 4] | +| array_flow.rb:656:21:656:32 | call to source | semmle.label | call to source | +| array_flow.rb:656:21:656:32 | call to source | semmle.label | call to source | +| array_flow.rb:656:35:656:46 | call to source | semmle.label | call to source | +| array_flow.rb:656:35:656:46 | call to source | semmle.label | call to source | +| array_flow.rb:658:10:658:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:658:10:658:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:658:10:658:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:658:10:658:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:659:10:659:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:659:10:659:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:659:10:659:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:659:10:659:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:661:10:661:10 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:661:10:661:10 | a [element 4] | semmle.label | a [element 4] | | array_flow.rb:661:10:661:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:661:10:661:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:672:5:672:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:672:5:672:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:672:16:672:27 | call to source | semmle.label | call to source | -| array_flow.rb:672:16:672:27 | call to source | semmle.label | call to source | -| array_flow.rb:673:5:673:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:673:5:673:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:673:9:673:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:673:9:673:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:673:9:673:60 | call to intersection [element] | semmle.label | call to intersection [element] | -| array_flow.rb:673:9:673:60 | call to intersection [element] | semmle.label | call to intersection [element] | -| array_flow.rb:673:31:673:42 | call to source | semmle.label | call to source | -| array_flow.rb:673:31:673:42 | call to source | semmle.label | call to source | -| array_flow.rb:673:47:673:58 | call to source | semmle.label | call to source | -| array_flow.rb:673:47:673:58 | call to source | semmle.label | call to source | -| array_flow.rb:674:10:674:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:674:10:674:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:674:10:674:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:674:10:674:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:678:5:678:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:678:5:678:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:678:16:678:25 | call to source | semmle.label | call to source | -| array_flow.rb:678:16:678:25 | call to source | semmle.label | call to source | -| array_flow.rb:679:5:679:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:679:5:679:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:679:9:679:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:679:9:679:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:679:9:679:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:679:9:679:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:679:9:682:7 | call to keep_if [element] | semmle.label | call to keep_if [element] | -| array_flow.rb:679:9:682:7 | call to keep_if [element] | semmle.label | call to keep_if [element] | -| array_flow.rb:679:23:679:23 | x | semmle.label | x | -| array_flow.rb:679:23:679:23 | x | semmle.label | x | -| array_flow.rb:680:14:680:14 | x | semmle.label | x | -| array_flow.rb:680:14:680:14 | x | semmle.label | x | -| array_flow.rb:683:10:683:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:683:10:683:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:683:10:683:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:683:10:683:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:684:10:684:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:684:10:684:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:684:10:684:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:684:10:684:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:688:5:688:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:688:5:688:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:688:16:688:27 | call to source | semmle.label | call to source | -| array_flow.rb:688:16:688:27 | call to source | semmle.label | call to source | -| array_flow.rb:689:5:689:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:689:5:689:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:689:12:689:23 | call to source | semmle.label | call to source | -| array_flow.rb:689:12:689:23 | call to source | semmle.label | call to source | -| array_flow.rb:690:10:690:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:690:10:690:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:690:10:690:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:690:10:690:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:690:10:690:15 | call to last | semmle.label | call to last | -| array_flow.rb:690:10:690:15 | call to last | semmle.label | call to last | -| array_flow.rb:691:5:691:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:691:5:691:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:691:9:691:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:691:9:691:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:691:9:691:9 | a [element] | semmle.label | a [element] | -| array_flow.rb:691:9:691:9 | a [element] | semmle.label | a [element] | -| array_flow.rb:691:9:691:17 | call to last [element] | semmle.label | call to last [element] | -| array_flow.rb:691:9:691:17 | call to last [element] | semmle.label | call to last [element] | -| array_flow.rb:692:10:692:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:692:10:692:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:692:10:692:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:692:10:692:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:693:10:693:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:693:10:693:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:693:10:693:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:693:10:693:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:697:5:697:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:697:5:697:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:697:16:697:27 | call to source | semmle.label | call to source | -| array_flow.rb:697:16:697:27 | call to source | semmle.label | call to source | -| array_flow.rb:698:5:698:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:698:5:698:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:698:9:698:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:698:9:698:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:698:9:701:7 | call to map [element] | semmle.label | call to map [element] | -| array_flow.rb:698:9:701:7 | call to map [element] | semmle.label | call to map [element] | -| array_flow.rb:698:19:698:19 | x | semmle.label | x | -| array_flow.rb:698:19:698:19 | x | semmle.label | x | -| array_flow.rb:699:14:699:14 | x | semmle.label | x | -| array_flow.rb:699:14:699:14 | x | semmle.label | x | -| array_flow.rb:700:9:700:19 | call to source | semmle.label | call to source | -| array_flow.rb:700:9:700:19 | call to source | semmle.label | call to source | -| array_flow.rb:702:10:702:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:702:10:702:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:702:10:702:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:702:10:702:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:706:5:706:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:706:5:706:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:706:16:706:27 | call to source | semmle.label | call to source | -| array_flow.rb:706:16:706:27 | call to source | semmle.label | call to source | -| array_flow.rb:707:5:707:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:707:5:707:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:707:9:707:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:707:9:707:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:707:9:710:7 | call to map! [element] | semmle.label | call to map! [element] | -| array_flow.rb:707:9:710:7 | call to map! [element] | semmle.label | call to map! [element] | -| array_flow.rb:707:20:707:20 | x | semmle.label | x | -| array_flow.rb:707:20:707:20 | x | semmle.label | x | -| array_flow.rb:708:14:708:14 | x | semmle.label | x | -| array_flow.rb:708:14:708:14 | x | semmle.label | x | -| array_flow.rb:709:9:709:19 | call to source | semmle.label | call to source | -| array_flow.rb:709:9:709:19 | call to source | semmle.label | call to source | -| array_flow.rb:711:10:711:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:711:10:711:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:711:10:711:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:711:10:711:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:715:5:715:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:715:5:715:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:715:16:715:25 | call to source | semmle.label | call to source | -| array_flow.rb:715:16:715:25 | call to source | semmle.label | call to source | -| array_flow.rb:718:5:718:5 | b | semmle.label | b | -| array_flow.rb:718:5:718:5 | b | semmle.label | b | +| array_flow.rb:663:10:663:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:663:10:663:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:663:10:663:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:663:10:663:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:664:10:664:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:664:10:664:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:664:10:664:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:664:10:664:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:666:10:666:10 | b [element 4] | semmle.label | b [element 4] | +| array_flow.rb:666:10:666:10 | b [element 4] | semmle.label | b [element 4] | +| array_flow.rb:666:10:666:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:666:10:666:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:669:5:669:5 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:669:5:669:5 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:669:16:669:27 | call to source | semmle.label | call to source | +| array_flow.rb:669:16:669:27 | call to source | semmle.label | call to source | +| array_flow.rb:670:5:670:5 | d [element] | semmle.label | d [element] | +| array_flow.rb:670:5:670:5 | d [element] | semmle.label | d [element] | +| array_flow.rb:670:9:670:9 | [post] c [element] | semmle.label | [post] c [element] | +| array_flow.rb:670:9:670:9 | [post] c [element] | semmle.label | [post] c [element] | +| array_flow.rb:670:9:670:9 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:670:9:670:9 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:670:9:670:47 | call to insert [element] | semmle.label | call to insert [element] | +| array_flow.rb:670:9:670:47 | call to insert [element] | semmle.label | call to insert [element] | +| array_flow.rb:670:21:670:32 | call to source | semmle.label | call to source | +| array_flow.rb:670:21:670:32 | call to source | semmle.label | call to source | +| array_flow.rb:670:35:670:46 | call to source | semmle.label | call to source | +| array_flow.rb:670:35:670:46 | call to source | semmle.label | call to source | +| array_flow.rb:671:10:671:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:671:10:671:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:671:10:671:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:671:10:671:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:672:10:672:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:672:10:672:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:672:10:672:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:672:10:672:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:683:5:683:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:683:5:683:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:683:16:683:27 | call to source | semmle.label | call to source | +| array_flow.rb:683:16:683:27 | call to source | semmle.label | call to source | +| array_flow.rb:684:5:684:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:684:5:684:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:684:9:684:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:684:9:684:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:684:9:684:60 | call to intersection [element] | semmle.label | call to intersection [element] | +| array_flow.rb:684:9:684:60 | call to intersection [element] | semmle.label | call to intersection [element] | +| array_flow.rb:684:31:684:42 | call to source | semmle.label | call to source | +| array_flow.rb:684:31:684:42 | call to source | semmle.label | call to source | +| array_flow.rb:684:47:684:58 | call to source | semmle.label | call to source | +| array_flow.rb:684:47:684:58 | call to source | semmle.label | call to source | +| array_flow.rb:685:10:685:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:685:10:685:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:685:10:685:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:685:10:685:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:689:5:689:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:689:5:689:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:689:16:689:25 | call to source | semmle.label | call to source | +| array_flow.rb:689:16:689:25 | call to source | semmle.label | call to source | +| array_flow.rb:690:5:690:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:690:5:690:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:690:9:690:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:690:9:690:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:690:9:690:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:690:9:690:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:690:9:693:7 | call to keep_if [element] | semmle.label | call to keep_if [element] | +| array_flow.rb:690:9:693:7 | call to keep_if [element] | semmle.label | call to keep_if [element] | +| array_flow.rb:690:23:690:23 | x | semmle.label | x | +| array_flow.rb:690:23:690:23 | x | semmle.label | x | +| array_flow.rb:691:14:691:14 | x | semmle.label | x | +| array_flow.rb:691:14:691:14 | x | semmle.label | x | +| array_flow.rb:694:10:694:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:694:10:694:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:694:10:694:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:694:10:694:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:695:10:695:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:695:10:695:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:695:10:695:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:695:10:695:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:699:5:699:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:699:5:699:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:699:16:699:27 | call to source | semmle.label | call to source | +| array_flow.rb:699:16:699:27 | call to source | semmle.label | call to source | +| array_flow.rb:700:5:700:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:700:5:700:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:700:12:700:23 | call to source | semmle.label | call to source | +| array_flow.rb:700:12:700:23 | call to source | semmle.label | call to source | +| array_flow.rb:701:10:701:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:701:10:701:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:701:10:701:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:701:10:701:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:701:10:701:15 | call to last | semmle.label | call to last | +| array_flow.rb:701:10:701:15 | call to last | semmle.label | call to last | +| array_flow.rb:702:5:702:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:702:5:702:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:702:9:702:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:702:9:702:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:702:9:702:9 | a [element] | semmle.label | a [element] | +| array_flow.rb:702:9:702:9 | a [element] | semmle.label | a [element] | +| array_flow.rb:702:9:702:17 | call to last [element] | semmle.label | call to last [element] | +| array_flow.rb:702:9:702:17 | call to last [element] | semmle.label | call to last [element] | +| array_flow.rb:703:10:703:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:703:10:703:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:703:10:703:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:703:10:703:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:704:10:704:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:704:10:704:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:704:10:704:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:704:10:704:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:708:5:708:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:708:5:708:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:708:16:708:27 | call to source | semmle.label | call to source | +| array_flow.rb:708:16:708:27 | call to source | semmle.label | call to source | +| array_flow.rb:709:5:709:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:709:5:709:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:709:9:709:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:709:9:709:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:709:9:712:7 | call to map [element] | semmle.label | call to map [element] | +| array_flow.rb:709:9:712:7 | call to map [element] | semmle.label | call to map [element] | +| array_flow.rb:709:19:709:19 | x | semmle.label | x | +| array_flow.rb:709:19:709:19 | x | semmle.label | x | +| array_flow.rb:710:14:710:14 | x | semmle.label | x | +| array_flow.rb:710:14:710:14 | x | semmle.label | x | +| array_flow.rb:711:9:711:19 | call to source | semmle.label | call to source | +| array_flow.rb:711:9:711:19 | call to source | semmle.label | call to source | +| array_flow.rb:713:10:713:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:713:10:713:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:713:10:713:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:713:10:713:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:717:5:717:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:717:5:717:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:717:16:717:27 | call to source | semmle.label | call to source | +| array_flow.rb:717:16:717:27 | call to source | semmle.label | call to source | +| array_flow.rb:718:5:718:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:718:5:718:5 | b [element] | semmle.label | b [element] | | array_flow.rb:718:9:718:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:718:9:718:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:718:9:718:13 | call to max | semmle.label | call to max | -| array_flow.rb:718:9:718:13 | call to max | semmle.label | call to max | -| array_flow.rb:719:10:719:10 | b | semmle.label | b | -| array_flow.rb:719:10:719:10 | b | semmle.label | b | -| array_flow.rb:722:5:722:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:722:5:722:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:722:9:722:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:722:9:722:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:722:9:722:16 | call to max [element] | semmle.label | call to max [element] | -| array_flow.rb:722:9:722:16 | call to max [element] | semmle.label | call to max [element] | -| array_flow.rb:723:10:723:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:723:10:723:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:723:10:723:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:723:10:723:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:726:5:726:5 | d | semmle.label | d | -| array_flow.rb:726:5:726:5 | d | semmle.label | d | -| array_flow.rb:726:9:726:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:726:9:726:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:726:9:730:7 | call to max | semmle.label | call to max | -| array_flow.rb:726:9:730:7 | call to max | semmle.label | call to max | -| array_flow.rb:726:19:726:19 | x | semmle.label | x | -| array_flow.rb:726:19:726:19 | x | semmle.label | x | -| array_flow.rb:726:22:726:22 | y | semmle.label | y | -| array_flow.rb:726:22:726:22 | y | semmle.label | y | -| array_flow.rb:727:14:727:14 | x | semmle.label | x | -| array_flow.rb:727:14:727:14 | x | semmle.label | x | -| array_flow.rb:728:14:728:14 | y | semmle.label | y | -| array_flow.rb:728:14:728:14 | y | semmle.label | y | -| array_flow.rb:731:10:731:10 | d | semmle.label | d | -| array_flow.rb:731:10:731:10 | d | semmle.label | d | -| array_flow.rb:734:5:734:5 | e [element] | semmle.label | e [element] | -| array_flow.rb:734:5:734:5 | e [element] | semmle.label | e [element] | -| array_flow.rb:734:9:734:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:734:9:734:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:734:9:738:7 | call to max [element] | semmle.label | call to max [element] | -| array_flow.rb:734:9:738:7 | call to max [element] | semmle.label | call to max [element] | -| array_flow.rb:734:22:734:22 | x | semmle.label | x | -| array_flow.rb:734:22:734:22 | x | semmle.label | x | -| array_flow.rb:734:25:734:25 | y | semmle.label | y | -| array_flow.rb:734:25:734:25 | y | semmle.label | y | -| array_flow.rb:735:14:735:14 | x | semmle.label | x | -| array_flow.rb:735:14:735:14 | x | semmle.label | x | -| array_flow.rb:736:14:736:14 | y | semmle.label | y | -| array_flow.rb:736:14:736:14 | y | semmle.label | y | -| array_flow.rb:739:10:739:10 | e [element] | semmle.label | e [element] | -| array_flow.rb:739:10:739:10 | e [element] | semmle.label | e [element] | -| array_flow.rb:739:10:739:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:739:10:739:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:743:5:743:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:743:5:743:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:743:16:743:25 | call to source | semmle.label | call to source | -| array_flow.rb:743:16:743:25 | call to source | semmle.label | call to source | -| array_flow.rb:746:5:746:5 | b | semmle.label | b | -| array_flow.rb:746:5:746:5 | b | semmle.label | b | -| array_flow.rb:746:9:746:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:746:9:746:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:746:9:749:7 | call to max_by | semmle.label | call to max_by | -| array_flow.rb:746:9:749:7 | call to max_by | semmle.label | call to max_by | -| array_flow.rb:746:22:746:22 | x | semmle.label | x | -| array_flow.rb:746:22:746:22 | x | semmle.label | x | -| array_flow.rb:747:14:747:14 | x | semmle.label | x | -| array_flow.rb:747:14:747:14 | x | semmle.label | x | -| array_flow.rb:750:10:750:10 | b | semmle.label | b | -| array_flow.rb:750:10:750:10 | b | semmle.label | b | -| array_flow.rb:753:5:753:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:753:5:753:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:753:9:753:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:753:9:753:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:753:9:756:7 | call to max_by [element] | semmle.label | call to max_by [element] | -| array_flow.rb:753:9:756:7 | call to max_by [element] | semmle.label | call to max_by [element] | -| array_flow.rb:753:25:753:25 | x | semmle.label | x | -| array_flow.rb:753:25:753:25 | x | semmle.label | x | -| array_flow.rb:754:14:754:14 | x | semmle.label | x | -| array_flow.rb:754:14:754:14 | x | semmle.label | x | -| array_flow.rb:757:10:757:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:757:10:757:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:757:10:757:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:757:10:757:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:761:5:761:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:761:5:761:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:761:16:761:25 | call to source | semmle.label | call to source | -| array_flow.rb:761:16:761:25 | call to source | semmle.label | call to source | -| array_flow.rb:764:5:764:5 | b | semmle.label | b | -| array_flow.rb:764:5:764:5 | b | semmle.label | b | +| array_flow.rb:718:9:721:7 | call to map! [element] | semmle.label | call to map! [element] | +| array_flow.rb:718:9:721:7 | call to map! [element] | semmle.label | call to map! [element] | +| array_flow.rb:718:20:718:20 | x | semmle.label | x | +| array_flow.rb:718:20:718:20 | x | semmle.label | x | +| array_flow.rb:719:14:719:14 | x | semmle.label | x | +| array_flow.rb:719:14:719:14 | x | semmle.label | x | +| array_flow.rb:720:9:720:19 | call to source | semmle.label | call to source | +| array_flow.rb:720:9:720:19 | call to source | semmle.label | call to source | +| array_flow.rb:722:10:722:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:722:10:722:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:722:10:722:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:722:10:722:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:726:5:726:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:726:5:726:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:726:16:726:25 | call to source | semmle.label | call to source | +| array_flow.rb:726:16:726:25 | call to source | semmle.label | call to source | +| array_flow.rb:729:5:729:5 | b | semmle.label | b | +| array_flow.rb:729:5:729:5 | b | semmle.label | b | +| array_flow.rb:729:9:729:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:729:9:729:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:729:9:729:13 | call to max | semmle.label | call to max | +| array_flow.rb:729:9:729:13 | call to max | semmle.label | call to max | +| array_flow.rb:730:10:730:10 | b | semmle.label | b | +| array_flow.rb:730:10:730:10 | b | semmle.label | b | +| array_flow.rb:733:5:733:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:733:5:733:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:733:9:733:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:733:9:733:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:733:9:733:16 | call to max [element] | semmle.label | call to max [element] | +| array_flow.rb:733:9:733:16 | call to max [element] | semmle.label | call to max [element] | +| array_flow.rb:734:10:734:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:734:10:734:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:734:10:734:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:734:10:734:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:737:5:737:5 | d | semmle.label | d | +| array_flow.rb:737:5:737:5 | d | semmle.label | d | +| array_flow.rb:737:9:737:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:737:9:737:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:737:9:741:7 | call to max | semmle.label | call to max | +| array_flow.rb:737:9:741:7 | call to max | semmle.label | call to max | +| array_flow.rb:737:19:737:19 | x | semmle.label | x | +| array_flow.rb:737:19:737:19 | x | semmle.label | x | +| array_flow.rb:737:22:737:22 | y | semmle.label | y | +| array_flow.rb:737:22:737:22 | y | semmle.label | y | +| array_flow.rb:738:14:738:14 | x | semmle.label | x | +| array_flow.rb:738:14:738:14 | x | semmle.label | x | +| array_flow.rb:739:14:739:14 | y | semmle.label | y | +| array_flow.rb:739:14:739:14 | y | semmle.label | y | +| array_flow.rb:742:10:742:10 | d | semmle.label | d | +| array_flow.rb:742:10:742:10 | d | semmle.label | d | +| array_flow.rb:745:5:745:5 | e [element] | semmle.label | e [element] | +| array_flow.rb:745:5:745:5 | e [element] | semmle.label | e [element] | +| array_flow.rb:745:9:745:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:745:9:745:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:745:9:749:7 | call to max [element] | semmle.label | call to max [element] | +| array_flow.rb:745:9:749:7 | call to max [element] | semmle.label | call to max [element] | +| array_flow.rb:745:22:745:22 | x | semmle.label | x | +| array_flow.rb:745:22:745:22 | x | semmle.label | x | +| array_flow.rb:745:25:745:25 | y | semmle.label | y | +| array_flow.rb:745:25:745:25 | y | semmle.label | y | +| array_flow.rb:746:14:746:14 | x | semmle.label | x | +| array_flow.rb:746:14:746:14 | x | semmle.label | x | +| array_flow.rb:747:14:747:14 | y | semmle.label | y | +| array_flow.rb:747:14:747:14 | y | semmle.label | y | +| array_flow.rb:750:10:750:10 | e [element] | semmle.label | e [element] | +| array_flow.rb:750:10:750:10 | e [element] | semmle.label | e [element] | +| array_flow.rb:750:10:750:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:750:10:750:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:754:5:754:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:754:5:754:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:754:16:754:25 | call to source | semmle.label | call to source | +| array_flow.rb:754:16:754:25 | call to source | semmle.label | call to source | +| array_flow.rb:757:5:757:5 | b | semmle.label | b | +| array_flow.rb:757:5:757:5 | b | semmle.label | b | +| array_flow.rb:757:9:757:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:757:9:757:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:757:9:760:7 | call to max_by | semmle.label | call to max_by | +| array_flow.rb:757:9:760:7 | call to max_by | semmle.label | call to max_by | +| array_flow.rb:757:22:757:22 | x | semmle.label | x | +| array_flow.rb:757:22:757:22 | x | semmle.label | x | +| array_flow.rb:758:14:758:14 | x | semmle.label | x | +| array_flow.rb:758:14:758:14 | x | semmle.label | x | +| array_flow.rb:761:10:761:10 | b | semmle.label | b | +| array_flow.rb:761:10:761:10 | b | semmle.label | b | +| array_flow.rb:764:5:764:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:764:5:764:5 | c [element] | semmle.label | c [element] | | array_flow.rb:764:9:764:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:764:9:764:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:764:9:764:13 | call to min | semmle.label | call to min | -| array_flow.rb:764:9:764:13 | call to min | semmle.label | call to min | -| array_flow.rb:765:10:765:10 | b | semmle.label | b | -| array_flow.rb:765:10:765:10 | b | semmle.label | b | -| array_flow.rb:768:5:768:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:768:5:768:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:768:9:768:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:768:9:768:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:768:9:768:16 | call to min [element] | semmle.label | call to min [element] | -| array_flow.rb:768:9:768:16 | call to min [element] | semmle.label | call to min [element] | -| array_flow.rb:769:10:769:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:769:10:769:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:769:10:769:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:769:10:769:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:772:5:772:5 | d | semmle.label | d | -| array_flow.rb:772:5:772:5 | d | semmle.label | d | -| array_flow.rb:772:9:772:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:772:9:772:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:772:9:776:7 | call to min | semmle.label | call to min | -| array_flow.rb:772:9:776:7 | call to min | semmle.label | call to min | -| array_flow.rb:772:19:772:19 | x | semmle.label | x | -| array_flow.rb:772:19:772:19 | x | semmle.label | x | -| array_flow.rb:772:22:772:22 | y | semmle.label | y | -| array_flow.rb:772:22:772:22 | y | semmle.label | y | -| array_flow.rb:773:14:773:14 | x | semmle.label | x | -| array_flow.rb:773:14:773:14 | x | semmle.label | x | -| array_flow.rb:774:14:774:14 | y | semmle.label | y | -| array_flow.rb:774:14:774:14 | y | semmle.label | y | -| array_flow.rb:777:10:777:10 | d | semmle.label | d | -| array_flow.rb:777:10:777:10 | d | semmle.label | d | -| array_flow.rb:780:5:780:5 | e [element] | semmle.label | e [element] | -| array_flow.rb:780:5:780:5 | e [element] | semmle.label | e [element] | -| array_flow.rb:780:9:780:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:780:9:780:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:780:9:784:7 | call to min [element] | semmle.label | call to min [element] | -| array_flow.rb:780:9:784:7 | call to min [element] | semmle.label | call to min [element] | -| array_flow.rb:780:22:780:22 | x | semmle.label | x | -| array_flow.rb:780:22:780:22 | x | semmle.label | x | -| array_flow.rb:780:25:780:25 | y | semmle.label | y | -| array_flow.rb:780:25:780:25 | y | semmle.label | y | -| array_flow.rb:781:14:781:14 | x | semmle.label | x | -| array_flow.rb:781:14:781:14 | x | semmle.label | x | -| array_flow.rb:782:14:782:14 | y | semmle.label | y | -| array_flow.rb:782:14:782:14 | y | semmle.label | y | -| array_flow.rb:785:10:785:10 | e [element] | semmle.label | e [element] | -| array_flow.rb:785:10:785:10 | e [element] | semmle.label | e [element] | -| array_flow.rb:785:10:785:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:785:10:785:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:789:5:789:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:789:5:789:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:789:16:789:25 | call to source | semmle.label | call to source | -| array_flow.rb:789:16:789:25 | call to source | semmle.label | call to source | -| array_flow.rb:792:5:792:5 | b | semmle.label | b | -| array_flow.rb:792:5:792:5 | b | semmle.label | b | -| array_flow.rb:792:9:792:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:792:9:792:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:792:9:795:7 | call to min_by | semmle.label | call to min_by | -| array_flow.rb:792:9:795:7 | call to min_by | semmle.label | call to min_by | -| array_flow.rb:792:22:792:22 | x | semmle.label | x | -| array_flow.rb:792:22:792:22 | x | semmle.label | x | -| array_flow.rb:793:14:793:14 | x | semmle.label | x | -| array_flow.rb:793:14:793:14 | x | semmle.label | x | -| array_flow.rb:796:10:796:10 | b | semmle.label | b | -| array_flow.rb:796:10:796:10 | b | semmle.label | b | -| array_flow.rb:799:5:799:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:799:5:799:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:799:9:799:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:799:9:799:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:799:9:802:7 | call to min_by [element] | semmle.label | call to min_by [element] | -| array_flow.rb:799:9:802:7 | call to min_by [element] | semmle.label | call to min_by [element] | -| array_flow.rb:799:25:799:25 | x | semmle.label | x | -| array_flow.rb:799:25:799:25 | x | semmle.label | x | -| array_flow.rb:800:14:800:14 | x | semmle.label | x | -| array_flow.rb:800:14:800:14 | x | semmle.label | x | -| array_flow.rb:803:10:803:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:803:10:803:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:803:10:803:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:803:10:803:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:807:5:807:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:807:5:807:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:807:16:807:25 | call to source | semmle.label | call to source | -| array_flow.rb:807:16:807:25 | call to source | semmle.label | call to source | -| array_flow.rb:809:5:809:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:809:5:809:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:809:9:809:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:809:9:809:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:809:9:809:16 | call to minmax [element] | semmle.label | call to minmax [element] | -| array_flow.rb:809:9:809:16 | call to minmax [element] | semmle.label | call to minmax [element] | -| array_flow.rb:810:10:810:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:810:10:810:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:810:10:810:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:810:10:810:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:811:10:811:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:811:10:811:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:811:10:811:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:811:10:811:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:813:5:813:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:813:5:813:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:813:9:813:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:813:9:813:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:813:9:817:7 | call to minmax [element] | semmle.label | call to minmax [element] | -| array_flow.rb:813:9:817:7 | call to minmax [element] | semmle.label | call to minmax [element] | -| array_flow.rb:813:22:813:22 | x | semmle.label | x | -| array_flow.rb:813:22:813:22 | x | semmle.label | x | -| array_flow.rb:813:25:813:25 | y | semmle.label | y | -| array_flow.rb:813:25:813:25 | y | semmle.label | y | -| array_flow.rb:814:14:814:14 | x | semmle.label | x | -| array_flow.rb:814:14:814:14 | x | semmle.label | x | -| array_flow.rb:815:14:815:14 | y | semmle.label | y | -| array_flow.rb:815:14:815:14 | y | semmle.label | y | -| array_flow.rb:818:10:818:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:818:10:818:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:818:10:818:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:818:10:818:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:819:10:819:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:819:10:819:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:819:10:819:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:819:10:819:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:823:5:823:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:823:5:823:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:823:16:823:25 | call to source | semmle.label | call to source | -| array_flow.rb:823:16:823:25 | call to source | semmle.label | call to source | -| array_flow.rb:824:5:824:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:824:5:824:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:764:9:767:7 | call to max_by [element] | semmle.label | call to max_by [element] | +| array_flow.rb:764:9:767:7 | call to max_by [element] | semmle.label | call to max_by [element] | +| array_flow.rb:764:25:764:25 | x | semmle.label | x | +| array_flow.rb:764:25:764:25 | x | semmle.label | x | +| array_flow.rb:765:14:765:14 | x | semmle.label | x | +| array_flow.rb:765:14:765:14 | x | semmle.label | x | +| array_flow.rb:768:10:768:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:768:10:768:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:768:10:768:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:768:10:768:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:772:5:772:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:772:5:772:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:772:16:772:25 | call to source | semmle.label | call to source | +| array_flow.rb:772:16:772:25 | call to source | semmle.label | call to source | +| array_flow.rb:775:5:775:5 | b | semmle.label | b | +| array_flow.rb:775:5:775:5 | b | semmle.label | b | +| array_flow.rb:775:9:775:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:775:9:775:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:775:9:775:13 | call to min | semmle.label | call to min | +| array_flow.rb:775:9:775:13 | call to min | semmle.label | call to min | +| array_flow.rb:776:10:776:10 | b | semmle.label | b | +| array_flow.rb:776:10:776:10 | b | semmle.label | b | +| array_flow.rb:779:5:779:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:779:5:779:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:779:9:779:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:779:9:779:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:779:9:779:16 | call to min [element] | semmle.label | call to min [element] | +| array_flow.rb:779:9:779:16 | call to min [element] | semmle.label | call to min [element] | +| array_flow.rb:780:10:780:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:780:10:780:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:780:10:780:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:780:10:780:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:783:5:783:5 | d | semmle.label | d | +| array_flow.rb:783:5:783:5 | d | semmle.label | d | +| array_flow.rb:783:9:783:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:783:9:783:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:783:9:787:7 | call to min | semmle.label | call to min | +| array_flow.rb:783:9:787:7 | call to min | semmle.label | call to min | +| array_flow.rb:783:19:783:19 | x | semmle.label | x | +| array_flow.rb:783:19:783:19 | x | semmle.label | x | +| array_flow.rb:783:22:783:22 | y | semmle.label | y | +| array_flow.rb:783:22:783:22 | y | semmle.label | y | +| array_flow.rb:784:14:784:14 | x | semmle.label | x | +| array_flow.rb:784:14:784:14 | x | semmle.label | x | +| array_flow.rb:785:14:785:14 | y | semmle.label | y | +| array_flow.rb:785:14:785:14 | y | semmle.label | y | +| array_flow.rb:788:10:788:10 | d | semmle.label | d | +| array_flow.rb:788:10:788:10 | d | semmle.label | d | +| array_flow.rb:791:5:791:5 | e [element] | semmle.label | e [element] | +| array_flow.rb:791:5:791:5 | e [element] | semmle.label | e [element] | +| array_flow.rb:791:9:791:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:791:9:791:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:791:9:795:7 | call to min [element] | semmle.label | call to min [element] | +| array_flow.rb:791:9:795:7 | call to min [element] | semmle.label | call to min [element] | +| array_flow.rb:791:22:791:22 | x | semmle.label | x | +| array_flow.rb:791:22:791:22 | x | semmle.label | x | +| array_flow.rb:791:25:791:25 | y | semmle.label | y | +| array_flow.rb:791:25:791:25 | y | semmle.label | y | +| array_flow.rb:792:14:792:14 | x | semmle.label | x | +| array_flow.rb:792:14:792:14 | x | semmle.label | x | +| array_flow.rb:793:14:793:14 | y | semmle.label | y | +| array_flow.rb:793:14:793:14 | y | semmle.label | y | +| array_flow.rb:796:10:796:10 | e [element] | semmle.label | e [element] | +| array_flow.rb:796:10:796:10 | e [element] | semmle.label | e [element] | +| array_flow.rb:796:10:796:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:796:10:796:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:800:5:800:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:800:5:800:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:800:16:800:25 | call to source | semmle.label | call to source | +| array_flow.rb:800:16:800:25 | call to source | semmle.label | call to source | +| array_flow.rb:803:5:803:5 | b | semmle.label | b | +| array_flow.rb:803:5:803:5 | b | semmle.label | b | +| array_flow.rb:803:9:803:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:803:9:803:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:803:9:806:7 | call to min_by | semmle.label | call to min_by | +| array_flow.rb:803:9:806:7 | call to min_by | semmle.label | call to min_by | +| array_flow.rb:803:22:803:22 | x | semmle.label | x | +| array_flow.rb:803:22:803:22 | x | semmle.label | x | +| array_flow.rb:804:14:804:14 | x | semmle.label | x | +| array_flow.rb:804:14:804:14 | x | semmle.label | x | +| array_flow.rb:807:10:807:10 | b | semmle.label | b | +| array_flow.rb:807:10:807:10 | b | semmle.label | b | +| array_flow.rb:810:5:810:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:810:5:810:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:810:9:810:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:810:9:810:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:810:9:813:7 | call to min_by [element] | semmle.label | call to min_by [element] | +| array_flow.rb:810:9:813:7 | call to min_by [element] | semmle.label | call to min_by [element] | +| array_flow.rb:810:25:810:25 | x | semmle.label | x | +| array_flow.rb:810:25:810:25 | x | semmle.label | x | +| array_flow.rb:811:14:811:14 | x | semmle.label | x | +| array_flow.rb:811:14:811:14 | x | semmle.label | x | +| array_flow.rb:814:10:814:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:814:10:814:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:814:10:814:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:814:10:814:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:818:5:818:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:818:5:818:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:818:16:818:25 | call to source | semmle.label | call to source | +| array_flow.rb:818:16:818:25 | call to source | semmle.label | call to source | +| array_flow.rb:820:5:820:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:820:5:820:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:820:9:820:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:820:9:820:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:820:9:820:16 | call to minmax [element] | semmle.label | call to minmax [element] | +| array_flow.rb:820:9:820:16 | call to minmax [element] | semmle.label | call to minmax [element] | +| array_flow.rb:821:10:821:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:821:10:821:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:821:10:821:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:821:10:821:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:822:10:822:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:822:10:822:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:822:10:822:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:822:10:822:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:824:5:824:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:824:5:824:5 | c [element] | semmle.label | c [element] | | array_flow.rb:824:9:824:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:824:9:824:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:824:9:827:7 | call to minmax_by [element] | semmle.label | call to minmax_by [element] | -| array_flow.rb:824:9:827:7 | call to minmax_by [element] | semmle.label | call to minmax_by [element] | -| array_flow.rb:824:25:824:25 | x | semmle.label | x | -| array_flow.rb:824:25:824:25 | x | semmle.label | x | +| array_flow.rb:824:9:828:7 | call to minmax [element] | semmle.label | call to minmax [element] | +| array_flow.rb:824:9:828:7 | call to minmax [element] | semmle.label | call to minmax [element] | +| array_flow.rb:824:22:824:22 | x | semmle.label | x | +| array_flow.rb:824:22:824:22 | x | semmle.label | x | +| array_flow.rb:824:25:824:25 | y | semmle.label | y | +| array_flow.rb:824:25:824:25 | y | semmle.label | y | | array_flow.rb:825:14:825:14 | x | semmle.label | x | | array_flow.rb:825:14:825:14 | x | semmle.label | x | -| array_flow.rb:828:10:828:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:828:10:828:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:828:10:828:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:828:10:828:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:829:10:829:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:829:10:829:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:826:14:826:14 | y | semmle.label | y | +| array_flow.rb:826:14:826:14 | y | semmle.label | y | +| array_flow.rb:829:10:829:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:829:10:829:10 | c [element] | semmle.label | c [element] | | array_flow.rb:829:10:829:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:829:10:829:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:833:5:833:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:833:5:833:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:833:16:833:25 | call to source | semmle.label | call to source | -| array_flow.rb:833:16:833:25 | call to source | semmle.label | call to source | +| array_flow.rb:830:10:830:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:830:10:830:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:830:10:830:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:830:10:830:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:834:5:834:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:834:5:834:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:834:17:834:17 | x | semmle.label | x | -| array_flow.rb:834:17:834:17 | x | semmle.label | x | -| array_flow.rb:835:14:835:14 | x | semmle.label | x | -| array_flow.rb:835:14:835:14 | x | semmle.label | x | -| array_flow.rb:842:5:842:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:842:5:842:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:842:16:842:25 | call to source | semmle.label | call to source | -| array_flow.rb:842:16:842:25 | call to source | semmle.label | call to source | -| array_flow.rb:843:5:843:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:843:5:843:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:843:16:843:16 | x | semmle.label | x | -| array_flow.rb:843:16:843:16 | x | semmle.label | x | -| array_flow.rb:844:14:844:14 | x | semmle.label | x | -| array_flow.rb:844:14:844:14 | x | semmle.label | x | -| array_flow.rb:849:5:849:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:849:16:849:25 | call to source | semmle.label | call to source | -| array_flow.rb:850:5:850:5 | b | semmle.label | b | -| array_flow.rb:850:9:850:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:850:9:850:20 | call to pack | semmle.label | call to pack | -| array_flow.rb:851:10:851:10 | b | semmle.label | b | -| array_flow.rb:855:5:855:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:855:5:855:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:855:16:855:25 | call to source | semmle.label | call to source | -| array_flow.rb:855:16:855:25 | call to source | semmle.label | call to source | -| array_flow.rb:856:5:856:5 | b [element, element] | semmle.label | b [element, element] | -| array_flow.rb:856:5:856:5 | b [element, element] | semmle.label | b [element, element] | -| array_flow.rb:856:9:856:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:856:9:856:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:856:9:859:7 | call to partition [element, element] | semmle.label | call to partition [element, element] | -| array_flow.rb:856:9:859:7 | call to partition [element, element] | semmle.label | call to partition [element, element] | -| array_flow.rb:856:25:856:25 | x | semmle.label | x | -| array_flow.rb:856:25:856:25 | x | semmle.label | x | -| array_flow.rb:857:14:857:14 | x | semmle.label | x | -| array_flow.rb:857:14:857:14 | x | semmle.label | x | -| array_flow.rb:860:10:860:10 | b [element, element] | semmle.label | b [element, element] | -| array_flow.rb:860:10:860:10 | b [element, element] | semmle.label | b [element, element] | -| array_flow.rb:860:10:860:13 | ...[...] [element] | semmle.label | ...[...] [element] | -| array_flow.rb:860:10:860:13 | ...[...] [element] | semmle.label | ...[...] [element] | -| array_flow.rb:860:10:860:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:860:10:860:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:861:10:861:10 | b [element, element] | semmle.label | b [element, element] | -| array_flow.rb:861:10:861:10 | b [element, element] | semmle.label | b [element, element] | -| array_flow.rb:861:10:861:13 | ...[...] [element] | semmle.label | ...[...] [element] | -| array_flow.rb:861:10:861:13 | ...[...] [element] | semmle.label | ...[...] [element] | -| array_flow.rb:861:10:861:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:861:10:861:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:865:5:865:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:865:5:865:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:865:16:865:25 | call to source | semmle.label | call to source | -| array_flow.rb:865:16:865:25 | call to source | semmle.label | call to source | -| array_flow.rb:867:5:867:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:867:5:867:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:834:16:834:25 | call to source | semmle.label | call to source | +| array_flow.rb:834:16:834:25 | call to source | semmle.label | call to source | +| array_flow.rb:835:5:835:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:835:5:835:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:835:9:835:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:835:9:835:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:835:9:838:7 | call to minmax_by [element] | semmle.label | call to minmax_by [element] | +| array_flow.rb:835:9:838:7 | call to minmax_by [element] | semmle.label | call to minmax_by [element] | +| array_flow.rb:835:25:835:25 | x | semmle.label | x | +| array_flow.rb:835:25:835:25 | x | semmle.label | x | +| array_flow.rb:836:14:836:14 | x | semmle.label | x | +| array_flow.rb:836:14:836:14 | x | semmle.label | x | +| array_flow.rb:839:10:839:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:839:10:839:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:839:10:839:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:839:10:839:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:840:10:840:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:840:10:840:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:840:10:840:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:840:10:840:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:844:5:844:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:844:5:844:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:844:16:844:25 | call to source | semmle.label | call to source | +| array_flow.rb:844:16:844:25 | call to source | semmle.label | call to source | +| array_flow.rb:845:5:845:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:845:5:845:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:845:17:845:17 | x | semmle.label | x | +| array_flow.rb:845:17:845:17 | x | semmle.label | x | +| array_flow.rb:846:14:846:14 | x | semmle.label | x | +| array_flow.rb:846:14:846:14 | x | semmle.label | x | +| array_flow.rb:853:5:853:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:853:5:853:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:853:16:853:25 | call to source | semmle.label | call to source | +| array_flow.rb:853:16:853:25 | call to source | semmle.label | call to source | +| array_flow.rb:854:5:854:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:854:5:854:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:854:16:854:16 | x | semmle.label | x | +| array_flow.rb:854:16:854:16 | x | semmle.label | x | +| array_flow.rb:855:14:855:14 | x | semmle.label | x | +| array_flow.rb:855:14:855:14 | x | semmle.label | x | +| array_flow.rb:860:5:860:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:860:16:860:25 | call to source | semmle.label | call to source | +| array_flow.rb:861:5:861:5 | b | semmle.label | b | +| array_flow.rb:861:9:861:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:861:9:861:20 | call to pack | semmle.label | call to pack | +| array_flow.rb:862:10:862:10 | b | semmle.label | b | +| array_flow.rb:866:5:866:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:866:5:866:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:866:16:866:25 | call to source | semmle.label | call to source | +| array_flow.rb:866:16:866:25 | call to source | semmle.label | call to source | +| array_flow.rb:867:5:867:5 | b [element, element] | semmle.label | b [element, element] | +| array_flow.rb:867:5:867:5 | b [element, element] | semmle.label | b [element, element] | | array_flow.rb:867:9:867:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:867:9:867:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:867:9:871:7 | call to permutation [element 2] | semmle.label | call to permutation [element 2] | -| array_flow.rb:867:9:871:7 | call to permutation [element 2] | semmle.label | call to permutation [element 2] | -| array_flow.rb:867:27:867:27 | x [element] | semmle.label | x [element] | -| array_flow.rb:867:27:867:27 | x [element] | semmle.label | x [element] | -| array_flow.rb:868:14:868:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:868:14:868:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:868:14:868:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:868:14:868:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:869:14:869:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:869:14:869:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:869:14:869:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:869:14:869:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:870:14:870:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:870:14:870:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:870:14:870:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:870:14:870:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:873:10:873:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:873:10:873:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:873:10:873:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:873:10:873:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:875:5:875:5 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:875:5:875:5 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:875:9:875:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:875:9:875:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:875:9:878:7 | call to permutation [element 2] | semmle.label | call to permutation [element 2] | -| array_flow.rb:875:9:878:7 | call to permutation [element 2] | semmle.label | call to permutation [element 2] | -| array_flow.rb:875:30:875:30 | x [element] | semmle.label | x [element] | -| array_flow.rb:875:30:875:30 | x [element] | semmle.label | x [element] | -| array_flow.rb:876:14:876:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:876:14:876:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:876:14:876:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:876:14:876:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:877:14:877:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:877:14:877:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:877:14:877:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:877:14:877:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:880:10:880:10 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:880:10:880:10 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:880:10:880:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:880:10:880:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:882:9:882:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:882:9:882:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:882:30:882:30 | x [element] | semmle.label | x [element] | -| array_flow.rb:882:30:882:30 | x [element] | semmle.label | x [element] | -| array_flow.rb:883:14:883:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:883:14:883:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:883:14:883:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:883:14:883:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:884:14:884:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:884:14:884:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:884:14:884:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:884:14:884:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:887:10:887:10 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:887:10:887:10 | c [element 2] | semmle.label | c [element 2] | -| array_flow.rb:887:10:887:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:887:10:887:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:894:5:894:5 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:894:5:894:5 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:894:5:894:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:894:5:894:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:894:13:894:24 | call to source | semmle.label | call to source | -| array_flow.rb:894:13:894:24 | call to source | semmle.label | call to source | -| array_flow.rb:894:30:894:41 | call to source | semmle.label | call to source | -| array_flow.rb:894:30:894:41 | call to source | semmle.label | call to source | -| array_flow.rb:895:5:895:5 | b | semmle.label | b | -| array_flow.rb:895:5:895:5 | b | semmle.label | b | -| array_flow.rb:895:9:895:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:895:9:895:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:895:9:895:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:895:9:895:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:895:9:895:13 | call to pop | semmle.label | call to pop | -| array_flow.rb:895:9:895:13 | call to pop | semmle.label | call to pop | -| array_flow.rb:896:10:896:10 | b | semmle.label | b | -| array_flow.rb:896:10:896:10 | b | semmle.label | b | -| array_flow.rb:898:10:898:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:898:10:898:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:867:9:870:7 | call to partition [element, element] | semmle.label | call to partition [element, element] | +| array_flow.rb:867:9:870:7 | call to partition [element, element] | semmle.label | call to partition [element, element] | +| array_flow.rb:867:25:867:25 | x | semmle.label | x | +| array_flow.rb:867:25:867:25 | x | semmle.label | x | +| array_flow.rb:868:14:868:14 | x | semmle.label | x | +| array_flow.rb:868:14:868:14 | x | semmle.label | x | +| array_flow.rb:871:10:871:10 | b [element, element] | semmle.label | b [element, element] | +| array_flow.rb:871:10:871:10 | b [element, element] | semmle.label | b [element, element] | +| array_flow.rb:871:10:871:13 | ...[...] [element] | semmle.label | ...[...] [element] | +| array_flow.rb:871:10:871:13 | ...[...] [element] | semmle.label | ...[...] [element] | +| array_flow.rb:871:10:871:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:871:10:871:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:872:10:872:10 | b [element, element] | semmle.label | b [element, element] | +| array_flow.rb:872:10:872:10 | b [element, element] | semmle.label | b [element, element] | +| array_flow.rb:872:10:872:13 | ...[...] [element] | semmle.label | ...[...] [element] | +| array_flow.rb:872:10:872:13 | ...[...] [element] | semmle.label | ...[...] [element] | +| array_flow.rb:872:10:872:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:872:10:872:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:876:5:876:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:876:5:876:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:876:16:876:25 | call to source | semmle.label | call to source | +| array_flow.rb:876:16:876:25 | call to source | semmle.label | call to source | +| array_flow.rb:878:5:878:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:878:5:878:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:878:9:878:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:878:9:878:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:878:9:882:7 | call to permutation [element 2] | semmle.label | call to permutation [element 2] | +| array_flow.rb:878:9:882:7 | call to permutation [element 2] | semmle.label | call to permutation [element 2] | +| array_flow.rb:878:27:878:27 | x [element] | semmle.label | x [element] | +| array_flow.rb:878:27:878:27 | x [element] | semmle.label | x [element] | +| array_flow.rb:879:14:879:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:879:14:879:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:879:14:879:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:879:14:879:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:880:14:880:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:880:14:880:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:880:14:880:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:880:14:880:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:881:14:881:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:881:14:881:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:881:14:881:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:881:14:881:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:884:10:884:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:884:10:884:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:884:10:884:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:884:10:884:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:886:5:886:5 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:886:5:886:5 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:886:9:886:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:886:9:886:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:886:9:889:7 | call to permutation [element 2] | semmle.label | call to permutation [element 2] | +| array_flow.rb:886:9:889:7 | call to permutation [element 2] | semmle.label | call to permutation [element 2] | +| array_flow.rb:886:30:886:30 | x [element] | semmle.label | x [element] | +| array_flow.rb:886:30:886:30 | x [element] | semmle.label | x [element] | +| array_flow.rb:887:14:887:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:887:14:887:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:887:14:887:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:887:14:887:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:888:14:888:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:888:14:888:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:888:14:888:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:888:14:888:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:891:10:891:10 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:891:10:891:10 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:891:10:891:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:891:10:891:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:893:9:893:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:893:9:893:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:893:30:893:30 | x [element] | semmle.label | x [element] | +| array_flow.rb:893:30:893:30 | x [element] | semmle.label | x [element] | +| array_flow.rb:894:14:894:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:894:14:894:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:894:14:894:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:894:14:894:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:895:14:895:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:895:14:895:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:895:14:895:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:895:14:895:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:898:10:898:10 | c [element 2] | semmle.label | c [element 2] | +| array_flow.rb:898:10:898:10 | c [element 2] | semmle.label | c [element 2] | | array_flow.rb:898:10:898:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:898:10:898:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:900:10:900:10 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:900:10:900:10 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:900:10:900:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:900:10:900:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:902:5:902:5 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:902:5:902:5 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:902:5:902:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:902:5:902:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:902:13:902:24 | call to source | semmle.label | call to source | -| array_flow.rb:902:13:902:24 | call to source | semmle.label | call to source | -| array_flow.rb:902:30:902:41 | call to source | semmle.label | call to source | -| array_flow.rb:902:30:902:41 | call to source | semmle.label | call to source | -| array_flow.rb:903:5:903:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:903:5:903:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:903:9:903:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:903:9:903:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:903:9:903:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:903:9:903:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:903:9:903:16 | call to pop [element] | semmle.label | call to pop [element] | -| array_flow.rb:903:9:903:16 | call to pop [element] | semmle.label | call to pop [element] | -| array_flow.rb:904:10:904:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:904:10:904:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:904:10:904:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:904:10:904:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:905:10:905:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:905:10:905:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:905:10:905:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:905:10:905:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:907:10:907:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:907:10:907:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:907:10:907:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:907:10:907:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:909:10:909:10 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:909:10:909:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:905:5:905:5 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:905:5:905:5 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:905:5:905:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:905:5:905:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:905:13:905:24 | call to source | semmle.label | call to source | +| array_flow.rb:905:13:905:24 | call to source | semmle.label | call to source | +| array_flow.rb:905:30:905:41 | call to source | semmle.label | call to source | +| array_flow.rb:905:30:905:41 | call to source | semmle.label | call to source | +| array_flow.rb:906:5:906:5 | b | semmle.label | b | +| array_flow.rb:906:5:906:5 | b | semmle.label | b | +| array_flow.rb:906:9:906:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:906:9:906:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:906:9:906:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:906:9:906:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:906:9:906:13 | call to pop | semmle.label | call to pop | +| array_flow.rb:906:9:906:13 | call to pop | semmle.label | call to pop | +| array_flow.rb:907:10:907:10 | b | semmle.label | b | +| array_flow.rb:907:10:907:10 | b | semmle.label | b | +| array_flow.rb:909:10:909:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:909:10:909:10 | a [element 1] | semmle.label | a [element 1] | | array_flow.rb:909:10:909:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:909:10:909:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:913:5:913:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:913:5:913:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:913:16:913:27 | call to source | semmle.label | call to source | -| array_flow.rb:913:16:913:27 | call to source | semmle.label | call to source | -| array_flow.rb:914:5:914:5 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:914:5:914:5 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:914:5:914:5 | [post] a [element 5] | semmle.label | [post] a [element 5] | -| array_flow.rb:914:5:914:5 | [post] a [element 5] | semmle.label | [post] a [element 5] | -| array_flow.rb:914:5:914:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:914:5:914:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:914:21:914:32 | call to source | semmle.label | call to source | -| array_flow.rb:914:21:914:32 | call to source | semmle.label | call to source | -| array_flow.rb:917:10:917:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:917:10:917:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:917:10:917:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:917:10:917:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:920:10:920:10 | a [element 5] | semmle.label | a [element 5] | -| array_flow.rb:920:10:920:10 | a [element 5] | semmle.label | a [element 5] | +| array_flow.rb:911:10:911:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:911:10:911:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:911:10:911:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:911:10:911:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:913:5:913:5 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:913:5:913:5 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:913:5:913:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:913:5:913:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:913:13:913:24 | call to source | semmle.label | call to source | +| array_flow.rb:913:13:913:24 | call to source | semmle.label | call to source | +| array_flow.rb:913:30:913:41 | call to source | semmle.label | call to source | +| array_flow.rb:913:30:913:41 | call to source | semmle.label | call to source | +| array_flow.rb:914:5:914:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:914:5:914:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:914:9:914:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:914:9:914:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:914:9:914:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:914:9:914:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:914:9:914:16 | call to pop [element] | semmle.label | call to pop [element] | +| array_flow.rb:914:9:914:16 | call to pop [element] | semmle.label | call to pop [element] | +| array_flow.rb:915:10:915:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:915:10:915:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:915:10:915:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:915:10:915:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:916:10:916:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:916:10:916:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:916:10:916:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:916:10:916:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:918:10:918:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:918:10:918:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:918:10:918:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:918:10:918:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:920:10:920:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:920:10:920:10 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:920:10:920:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:920:10:920:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:924:5:924:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:924:5:924:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:924:16:924:27 | call to source | semmle.label | call to source | | array_flow.rb:924:16:924:27 | call to source | semmle.label | call to source | -| array_flow.rb:925:5:925:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:925:5:925:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:925:13:925:24 | call to source | semmle.label | call to source | -| array_flow.rb:925:13:925:24 | call to source | semmle.label | call to source | -| array_flow.rb:926:5:926:5 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:926:5:926:5 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:926:10:926:21 | call to source | semmle.label | call to source | -| array_flow.rb:926:10:926:21 | call to source | semmle.label | call to source | -| array_flow.rb:927:5:927:5 | d [element, element] | semmle.label | d [element, element] | -| array_flow.rb:927:5:927:5 | d [element, element] | semmle.label | d [element, element] | -| array_flow.rb:927:9:927:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:927:9:927:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:927:9:927:22 | call to product [element, element] | semmle.label | call to product [element, element] | -| array_flow.rb:927:9:927:22 | call to product [element, element] | semmle.label | call to product [element, element] | -| array_flow.rb:927:19:927:19 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:927:19:927:19 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:927:22:927:22 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:927:22:927:22 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:928:10:928:10 | d [element, element] | semmle.label | d [element, element] | -| array_flow.rb:928:10:928:10 | d [element, element] | semmle.label | d [element, element] | -| array_flow.rb:928:10:928:13 | ...[...] [element] | semmle.label | ...[...] [element] | -| array_flow.rb:928:10:928:13 | ...[...] [element] | semmle.label | ...[...] [element] | -| array_flow.rb:928:10:928:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:928:10:928:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:929:10:929:10 | d [element, element] | semmle.label | d [element, element] | -| array_flow.rb:929:10:929:10 | d [element, element] | semmle.label | d [element, element] | -| array_flow.rb:929:10:929:13 | ...[...] [element] | semmle.label | ...[...] [element] | -| array_flow.rb:929:10:929:13 | ...[...] [element] | semmle.label | ...[...] [element] | -| array_flow.rb:929:10:929:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:929:10:929:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:933:5:933:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:933:5:933:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:933:10:933:21 | call to source | semmle.label | call to source | -| array_flow.rb:933:10:933:21 | call to source | semmle.label | call to source | -| array_flow.rb:934:5:934:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:934:5:934:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:934:5:934:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:934:5:934:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:934:9:934:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:934:9:934:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:934:9:934:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:934:9:934:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:934:9:934:44 | call to append [element 0] | semmle.label | call to append [element 0] | -| array_flow.rb:934:9:934:44 | call to append [element 0] | semmle.label | call to append [element 0] | -| array_flow.rb:934:9:934:44 | call to append [element] | semmle.label | call to append [element] | -| array_flow.rb:934:9:934:44 | call to append [element] | semmle.label | call to append [element] | -| array_flow.rb:934:18:934:29 | call to source | semmle.label | call to source | -| array_flow.rb:934:18:934:29 | call to source | semmle.label | call to source | -| array_flow.rb:934:32:934:43 | call to source | semmle.label | call to source | -| array_flow.rb:934:32:934:43 | call to source | semmle.label | call to source | -| array_flow.rb:935:10:935:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:935:10:935:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:935:10:935:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:935:10:935:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:935:10:935:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:935:10:935:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:936:10:936:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:936:10:936:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:936:10:936:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:936:10:936:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:937:10:937:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:937:10:937:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:937:10:937:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:937:10:937:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:937:10:937:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:937:10:937:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:938:10:938:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:938:10:938:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:938:10:938:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:938:10:938:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:944:5:944:5 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:944:5:944:5 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:944:10:944:19 | call to source | semmle.label | call to source | -| array_flow.rb:944:10:944:19 | call to source | semmle.label | call to source | -| array_flow.rb:945:5:945:5 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:945:5:945:5 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:945:16:945:16 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:945:16:945:16 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:946:10:946:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:946:10:946:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:946:10:946:22 | call to rassoc [element 0] | semmle.label | call to rassoc [element 0] | -| array_flow.rb:946:10:946:22 | call to rassoc [element 0] | semmle.label | call to rassoc [element 0] | -| array_flow.rb:946:10:946:25 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:946:10:946:25 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:947:10:947:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:947:10:947:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:947:10:947:22 | call to rassoc [element 0] | semmle.label | call to rassoc [element 0] | -| array_flow.rb:947:10:947:22 | call to rassoc [element 0] | semmle.label | call to rassoc [element 0] | -| array_flow.rb:947:10:947:25 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:947:10:947:25 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:951:5:951:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:951:5:951:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:951:5:951:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:951:5:951:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:951:10:951:21 | call to source | semmle.label | call to source | -| array_flow.rb:951:10:951:21 | call to source | semmle.label | call to source | -| array_flow.rb:951:27:951:38 | call to source | semmle.label | call to source | -| array_flow.rb:951:27:951:38 | call to source | semmle.label | call to source | -| array_flow.rb:952:9:952:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:952:9:952:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:952:9:952:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:952:9:952:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:952:22:952:22 | x | semmle.label | x | -| array_flow.rb:952:22:952:22 | x | semmle.label | x | -| array_flow.rb:952:25:952:25 | y | semmle.label | y | -| array_flow.rb:952:25:952:25 | y | semmle.label | y | -| array_flow.rb:953:14:953:14 | x | semmle.label | x | -| array_flow.rb:953:14:953:14 | x | semmle.label | x | -| array_flow.rb:954:14:954:14 | y | semmle.label | y | -| array_flow.rb:954:14:954:14 | y | semmle.label | y | -| array_flow.rb:957:9:957:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:957:9:957:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:957:9:957:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:957:9:957:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:957:28:957:28 | y | semmle.label | y | -| array_flow.rb:957:28:957:28 | y | semmle.label | y | -| array_flow.rb:959:14:959:14 | y | semmle.label | y | -| array_flow.rb:959:14:959:14 | y | semmle.label | y | -| array_flow.rb:965:5:965:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:965:5:965:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:965:16:965:25 | call to source | semmle.label | call to source | -| array_flow.rb:965:16:965:25 | call to source | semmle.label | call to source | -| array_flow.rb:966:5:966:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:966:5:966:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:966:9:966:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:966:9:966:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:966:9:969:7 | call to reject [element] | semmle.label | call to reject [element] | -| array_flow.rb:966:9:969:7 | call to reject [element] | semmle.label | call to reject [element] | -| array_flow.rb:966:22:966:22 | x | semmle.label | x | -| array_flow.rb:966:22:966:22 | x | semmle.label | x | -| array_flow.rb:967:14:967:14 | x | semmle.label | x | -| array_flow.rb:967:14:967:14 | x | semmle.label | x | -| array_flow.rb:970:10:970:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:970:10:970:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:970:10:970:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:970:10:970:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:974:5:974:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:974:5:974:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:974:16:974:25 | call to source | semmle.label | call to source | -| array_flow.rb:974:16:974:25 | call to source | semmle.label | call to source | -| array_flow.rb:975:5:975:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:975:5:975:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:975:9:975:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:975:9:975:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:975:9:975:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:975:9:975:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:975:9:978:7 | call to reject! [element] | semmle.label | call to reject! [element] | -| array_flow.rb:975:9:978:7 | call to reject! [element] | semmle.label | call to reject! [element] | -| array_flow.rb:975:23:975:23 | x | semmle.label | x | -| array_flow.rb:975:23:975:23 | x | semmle.label | x | -| array_flow.rb:976:14:976:14 | x | semmle.label | x | -| array_flow.rb:976:14:976:14 | x | semmle.label | x | -| array_flow.rb:979:10:979:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:979:10:979:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:979:10:979:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:979:10:979:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:980:10:980:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:980:10:980:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:980:10:980:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:980:10:980:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:984:5:984:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:984:5:984:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:984:16:984:25 | call to source | semmle.label | call to source | -| array_flow.rb:984:16:984:25 | call to source | semmle.label | call to source | -| array_flow.rb:985:5:985:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:985:5:985:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:985:9:985:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:985:9:985:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] | semmle.label | call to repeated_combination [element 2] | -| array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] | semmle.label | call to repeated_combination [element 2] | -| array_flow.rb:985:39:985:39 | x [element] | semmle.label | x [element] | -| array_flow.rb:985:39:985:39 | x [element] | semmle.label | x [element] | -| array_flow.rb:986:14:986:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:986:14:986:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:986:14:986:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:986:14:986:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:987:14:987:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:987:14:987:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:987:14:987:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:987:14:987:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:990:10:990:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:990:10:990:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:925:5:925:5 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:925:5:925:5 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:925:5:925:5 | [post] a [element 5] | semmle.label | [post] a [element 5] | +| array_flow.rb:925:5:925:5 | [post] a [element 5] | semmle.label | [post] a [element 5] | +| array_flow.rb:925:5:925:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:925:5:925:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:925:21:925:32 | call to source | semmle.label | call to source | +| array_flow.rb:925:21:925:32 | call to source | semmle.label | call to source | +| array_flow.rb:928:10:928:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:928:10:928:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:928:10:928:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:928:10:928:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:931:10:931:10 | a [element 5] | semmle.label | a [element 5] | +| array_flow.rb:931:10:931:10 | a [element 5] | semmle.label | a [element 5] | +| array_flow.rb:931:10:931:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:931:10:931:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:935:5:935:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:935:5:935:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:935:16:935:27 | call to source | semmle.label | call to source | +| array_flow.rb:935:16:935:27 | call to source | semmle.label | call to source | +| array_flow.rb:936:5:936:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:936:5:936:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:936:13:936:24 | call to source | semmle.label | call to source | +| array_flow.rb:936:13:936:24 | call to source | semmle.label | call to source | +| array_flow.rb:937:5:937:5 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:937:5:937:5 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:937:10:937:21 | call to source | semmle.label | call to source | +| array_flow.rb:937:10:937:21 | call to source | semmle.label | call to source | +| array_flow.rb:938:5:938:5 | d [element, element] | semmle.label | d [element, element] | +| array_flow.rb:938:5:938:5 | d [element, element] | semmle.label | d [element, element] | +| array_flow.rb:938:9:938:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:938:9:938:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:938:9:938:22 | call to product [element, element] | semmle.label | call to product [element, element] | +| array_flow.rb:938:9:938:22 | call to product [element, element] | semmle.label | call to product [element, element] | +| array_flow.rb:938:19:938:19 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:938:19:938:19 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:938:22:938:22 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:938:22:938:22 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:939:10:939:10 | d [element, element] | semmle.label | d [element, element] | +| array_flow.rb:939:10:939:10 | d [element, element] | semmle.label | d [element, element] | +| array_flow.rb:939:10:939:13 | ...[...] [element] | semmle.label | ...[...] [element] | +| array_flow.rb:939:10:939:13 | ...[...] [element] | semmle.label | ...[...] [element] | +| array_flow.rb:939:10:939:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:939:10:939:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:940:10:940:10 | d [element, element] | semmle.label | d [element, element] | +| array_flow.rb:940:10:940:10 | d [element, element] | semmle.label | d [element, element] | +| array_flow.rb:940:10:940:13 | ...[...] [element] | semmle.label | ...[...] [element] | +| array_flow.rb:940:10:940:13 | ...[...] [element] | semmle.label | ...[...] [element] | +| array_flow.rb:940:10:940:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:940:10:940:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:944:5:944:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:944:5:944:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:944:10:944:21 | call to source | semmle.label | call to source | +| array_flow.rb:944:10:944:21 | call to source | semmle.label | call to source | +| array_flow.rb:945:5:945:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:945:5:945:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:945:5:945:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:945:5:945:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:945:9:945:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:945:9:945:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:945:9:945:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:945:9:945:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:945:9:945:44 | call to append [element 0] | semmle.label | call to append [element 0] | +| array_flow.rb:945:9:945:44 | call to append [element 0] | semmle.label | call to append [element 0] | +| array_flow.rb:945:9:945:44 | call to append [element] | semmle.label | call to append [element] | +| array_flow.rb:945:9:945:44 | call to append [element] | semmle.label | call to append [element] | +| array_flow.rb:945:18:945:29 | call to source | semmle.label | call to source | +| array_flow.rb:945:18:945:29 | call to source | semmle.label | call to source | +| array_flow.rb:945:32:945:43 | call to source | semmle.label | call to source | +| array_flow.rb:945:32:945:43 | call to source | semmle.label | call to source | +| array_flow.rb:946:10:946:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:946:10:946:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:946:10:946:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:946:10:946:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:946:10:946:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:946:10:946:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:947:10:947:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:947:10:947:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:947:10:947:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:947:10:947:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:948:10:948:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:948:10:948:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:948:10:948:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:948:10:948:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:948:10:948:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:948:10:948:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:949:10:949:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:949:10:949:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:949:10:949:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:949:10:949:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:955:5:955:5 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:955:5:955:5 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:955:10:955:19 | call to source | semmle.label | call to source | +| array_flow.rb:955:10:955:19 | call to source | semmle.label | call to source | +| array_flow.rb:956:5:956:5 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:956:5:956:5 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:956:16:956:16 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:956:16:956:16 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:957:10:957:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:957:10:957:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:957:10:957:22 | call to rassoc [element 0] | semmle.label | call to rassoc [element 0] | +| array_flow.rb:957:10:957:22 | call to rassoc [element 0] | semmle.label | call to rassoc [element 0] | +| array_flow.rb:957:10:957:25 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:957:10:957:25 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:958:10:958:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:958:10:958:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:958:10:958:22 | call to rassoc [element 0] | semmle.label | call to rassoc [element 0] | +| array_flow.rb:958:10:958:22 | call to rassoc [element 0] | semmle.label | call to rassoc [element 0] | +| array_flow.rb:958:10:958:25 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:958:10:958:25 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:962:5:962:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:962:5:962:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:962:5:962:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:962:5:962:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:962:10:962:21 | call to source | semmle.label | call to source | +| array_flow.rb:962:10:962:21 | call to source | semmle.label | call to source | +| array_flow.rb:962:27:962:38 | call to source | semmle.label | call to source | +| array_flow.rb:962:27:962:38 | call to source | semmle.label | call to source | +| array_flow.rb:963:9:963:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:963:9:963:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:963:9:963:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:963:9:963:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:963:22:963:22 | x | semmle.label | x | +| array_flow.rb:963:22:963:22 | x | semmle.label | x | +| array_flow.rb:963:25:963:25 | y | semmle.label | y | +| array_flow.rb:963:25:963:25 | y | semmle.label | y | +| array_flow.rb:964:14:964:14 | x | semmle.label | x | +| array_flow.rb:964:14:964:14 | x | semmle.label | x | +| array_flow.rb:965:14:965:14 | y | semmle.label | y | +| array_flow.rb:965:14:965:14 | y | semmle.label | y | +| array_flow.rb:968:9:968:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:968:9:968:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:968:9:968:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:968:9:968:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:968:28:968:28 | y | semmle.label | y | +| array_flow.rb:968:28:968:28 | y | semmle.label | y | +| array_flow.rb:970:14:970:14 | y | semmle.label | y | +| array_flow.rb:970:14:970:14 | y | semmle.label | y | +| array_flow.rb:976:5:976:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:976:5:976:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:976:16:976:25 | call to source | semmle.label | call to source | +| array_flow.rb:976:16:976:25 | call to source | semmle.label | call to source | +| array_flow.rb:977:5:977:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:977:5:977:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:977:9:977:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:977:9:977:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:977:9:980:7 | call to reject [element] | semmle.label | call to reject [element] | +| array_flow.rb:977:9:980:7 | call to reject [element] | semmle.label | call to reject [element] | +| array_flow.rb:977:22:977:22 | x | semmle.label | x | +| array_flow.rb:977:22:977:22 | x | semmle.label | x | +| array_flow.rb:978:14:978:14 | x | semmle.label | x | +| array_flow.rb:978:14:978:14 | x | semmle.label | x | +| array_flow.rb:981:10:981:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:981:10:981:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:981:10:981:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:981:10:981:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:985:5:985:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:985:5:985:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:985:16:985:25 | call to source | semmle.label | call to source | +| array_flow.rb:985:16:985:25 | call to source | semmle.label | call to source | +| array_flow.rb:986:5:986:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:986:5:986:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:986:9:986:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:986:9:986:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:986:9:986:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:986:9:986:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:986:9:989:7 | call to reject! [element] | semmle.label | call to reject! [element] | +| array_flow.rb:986:9:989:7 | call to reject! [element] | semmle.label | call to reject! [element] | +| array_flow.rb:986:23:986:23 | x | semmle.label | x | +| array_flow.rb:986:23:986:23 | x | semmle.label | x | +| array_flow.rb:987:14:987:14 | x | semmle.label | x | +| array_flow.rb:987:14:987:14 | x | semmle.label | x | +| array_flow.rb:990:10:990:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:990:10:990:10 | a [element] | semmle.label | a [element] | | array_flow.rb:990:10:990:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:990:10:990:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:994:5:994:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:994:5:994:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:994:16:994:25 | call to source | semmle.label | call to source | -| array_flow.rb:994:16:994:25 | call to source | semmle.label | call to source | -| array_flow.rb:995:5:995:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:995:5:995:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:995:9:995:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:995:9:995:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] | semmle.label | call to repeated_permutation [element 2] | -| array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] | semmle.label | call to repeated_permutation [element 2] | -| array_flow.rb:995:39:995:39 | x [element] | semmle.label | x [element] | -| array_flow.rb:995:39:995:39 | x [element] | semmle.label | x [element] | -| array_flow.rb:996:14:996:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:996:14:996:14 | x [element] | semmle.label | x [element] | -| array_flow.rb:996:14:996:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:996:14:996:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:991:10:991:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:991:10:991:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:991:10:991:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:991:10:991:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:995:5:995:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:995:5:995:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:995:16:995:25 | call to source | semmle.label | call to source | +| array_flow.rb:995:16:995:25 | call to source | semmle.label | call to source | +| array_flow.rb:996:5:996:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:996:5:996:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:996:9:996:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:996:9:996:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:996:9:999:7 | call to repeated_combination [element 2] | semmle.label | call to repeated_combination [element 2] | +| array_flow.rb:996:9:999:7 | call to repeated_combination [element 2] | semmle.label | call to repeated_combination [element 2] | +| array_flow.rb:996:39:996:39 | x [element] | semmle.label | x [element] | +| array_flow.rb:996:39:996:39 | x [element] | semmle.label | x [element] | | array_flow.rb:997:14:997:14 | x [element] | semmle.label | x [element] | | array_flow.rb:997:14:997:14 | x [element] | semmle.label | x [element] | | array_flow.rb:997:14:997:17 | ...[...] | semmle.label | ...[...] | | array_flow.rb:997:14:997:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1000:10:1000:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1000:10:1000:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1000:10:1000:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1000:10:1000:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1006:5:1006:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1006:5:1006:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1006:9:1006:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | -| array_flow.rb:1006:9:1006:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | -| array_flow.rb:1006:9:1006:33 | call to replace [element 0] | semmle.label | call to replace [element 0] | -| array_flow.rb:1006:9:1006:33 | call to replace [element 0] | semmle.label | call to replace [element 0] | -| array_flow.rb:1006:20:1006:31 | call to source | semmle.label | call to source | -| array_flow.rb:1006:20:1006:31 | call to source | semmle.label | call to source | -| array_flow.rb:1007:10:1007:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1007:10:1007:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1007:10:1007:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1007:10:1007:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1008:10:1008:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1008:10:1008:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1008:10:1008:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1008:10:1008:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1012:5:1012:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1012:5:1012:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1012:5:1012:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1012:5:1012:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1012:16:1012:28 | call to source | semmle.label | call to source | -| array_flow.rb:1012:16:1012:28 | call to source | semmle.label | call to source | -| array_flow.rb:1012:31:1012:43 | call to source | semmle.label | call to source | -| array_flow.rb:1012:31:1012:43 | call to source | semmle.label | call to source | -| array_flow.rb:1013:5:1013:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1013:5:1013:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1013:9:1013:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1013:9:1013:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1013:9:1013:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1013:9:1013:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] | semmle.label | call to reverse [element] | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] | semmle.label | call to reverse [element] | -| array_flow.rb:1014:10:1014:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1014:10:1014:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1014:10:1014:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1014:10:1014:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1015:10:1015:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1015:10:1015:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1015:10:1015:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1015:10:1015:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1016:10:1016:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1016:10:1016:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1016:10:1016:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1016:10:1016:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1018:10:1018:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1018:10:1018:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:998:14:998:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:998:14:998:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:998:14:998:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:998:14:998:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1001:10:1001:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1001:10:1001:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1001:10:1001:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1001:10:1001:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1005:5:1005:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1005:5:1005:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1005:16:1005:25 | call to source | semmle.label | call to source | +| array_flow.rb:1005:16:1005:25 | call to source | semmle.label | call to source | +| array_flow.rb:1006:5:1006:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1006:5:1006:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1006:9:1006:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1006:9:1006:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1006:9:1009:7 | call to repeated_permutation [element 2] | semmle.label | call to repeated_permutation [element 2] | +| array_flow.rb:1006:9:1009:7 | call to repeated_permutation [element 2] | semmle.label | call to repeated_permutation [element 2] | +| array_flow.rb:1006:39:1006:39 | x [element] | semmle.label | x [element] | +| array_flow.rb:1006:39:1006:39 | x [element] | semmle.label | x [element] | +| array_flow.rb:1007:14:1007:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:1007:14:1007:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:1007:14:1007:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1007:14:1007:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1008:14:1008:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:1008:14:1008:14 | x [element] | semmle.label | x [element] | +| array_flow.rb:1008:14:1008:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1008:14:1008:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1011:10:1011:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1011:10:1011:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1011:10:1011:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1011:10:1011:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1017:5:1017:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1017:5:1017:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1017:9:1017:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | +| array_flow.rb:1017:9:1017:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | +| array_flow.rb:1017:9:1017:33 | call to replace [element 0] | semmle.label | call to replace [element 0] | +| array_flow.rb:1017:9:1017:33 | call to replace [element 0] | semmle.label | call to replace [element 0] | +| array_flow.rb:1017:20:1017:31 | call to source | semmle.label | call to source | +| array_flow.rb:1017:20:1017:31 | call to source | semmle.label | call to source | +| array_flow.rb:1018:10:1018:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1018:10:1018:10 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1018:10:1018:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1018:10:1018:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1019:10:1019:10 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1019:10:1019:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1019:10:1019:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1019:10:1019:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1019:10:1019:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1019:10:1019:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1023:5:1023:5 | a [element 2] | semmle.label | a [element 2] | @@ -6750,14 +6732,12 @@ nodes | array_flow.rb:1023:31:1023:43 | call to source | semmle.label | call to source | | array_flow.rb:1024:5:1024:5 | b [element] | semmle.label | b [element] | | array_flow.rb:1024:5:1024:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1024:9:1024:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1024:9:1024:9 | [post] a [element] | semmle.label | [post] a [element] | | array_flow.rb:1024:9:1024:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1024:9:1024:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1024:9:1024:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1024:9:1024:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] | semmle.label | call to reverse! [element] | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] | semmle.label | call to reverse! [element] | +| array_flow.rb:1024:9:1024:17 | call to reverse [element] | semmle.label | call to reverse [element] | +| array_flow.rb:1024:9:1024:17 | call to reverse [element] | semmle.label | call to reverse [element] | | array_flow.rb:1025:10:1025:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1025:10:1025:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1025:10:1025:13 | ...[...] | semmle.label | ...[...] | @@ -6770,178 +6750,164 @@ nodes | array_flow.rb:1027:10:1027:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1027:10:1027:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1027:10:1027:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1028:10:1028:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1028:10:1028:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1028:10:1028:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1028:10:1028:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1029:10:1029:10 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1029:10:1029:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1029:10:1029:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1029:10:1029:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1029:10:1029:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1029:10:1029:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1030:10:1030:10 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1030:10:1030:10 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1030:10:1030:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1030:10:1030:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1030:10:1030:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1030:10:1030:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1034:5:1034:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1034:5:1034:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1034:16:1034:26 | call to source | semmle.label | call to source | -| array_flow.rb:1034:16:1034:26 | call to source | semmle.label | call to source | -| array_flow.rb:1035:5:1035:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1035:5:1035:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1034:5:1034:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1034:5:1034:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1034:16:1034:28 | call to source | semmle.label | call to source | +| array_flow.rb:1034:16:1034:28 | call to source | semmle.label | call to source | +| array_flow.rb:1034:31:1034:43 | call to source | semmle.label | call to source | +| array_flow.rb:1034:31:1034:43 | call to source | semmle.label | call to source | +| array_flow.rb:1035:5:1035:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1035:5:1035:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1035:9:1035:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1035:9:1035:9 | [post] a [element] | semmle.label | [post] a [element] | | array_flow.rb:1035:9:1035:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1035:9:1035:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] | semmle.label | call to reverse_each [element 2] | -| array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] | semmle.label | call to reverse_each [element 2] | -| array_flow.rb:1035:28:1035:28 | x | semmle.label | x | -| array_flow.rb:1035:28:1035:28 | x | semmle.label | x | -| array_flow.rb:1036:14:1036:14 | x | semmle.label | x | -| array_flow.rb:1036:14:1036:14 | x | semmle.label | x | -| array_flow.rb:1038:10:1038:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1038:10:1038:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1035:9:1035:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1035:9:1035:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1035:9:1035:18 | call to reverse! [element] | semmle.label | call to reverse! [element] | +| array_flow.rb:1035:9:1035:18 | call to reverse! [element] | semmle.label | call to reverse! [element] | +| array_flow.rb:1036:10:1036:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1036:10:1036:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1036:10:1036:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1036:10:1036:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1037:10:1037:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1037:10:1037:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1037:10:1037:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1037:10:1037:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1038:10:1038:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1038:10:1038:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1038:10:1038:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1038:10:1038:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1042:5:1042:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1042:5:1042:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1042:16:1042:26 | call to source | semmle.label | call to source | -| array_flow.rb:1042:16:1042:26 | call to source | semmle.label | call to source | -| array_flow.rb:1043:5:1043:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1043:5:1043:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1043:18:1043:18 | x | semmle.label | x | -| array_flow.rb:1043:18:1043:18 | x | semmle.label | x | -| array_flow.rb:1044:14:1044:14 | x | semmle.label | x | -| array_flow.rb:1044:14:1044:14 | x | semmle.label | x | -| array_flow.rb:1052:5:1052:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1052:5:1052:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1052:10:1052:22 | call to source | semmle.label | call to source | -| array_flow.rb:1052:10:1052:22 | call to source | semmle.label | call to source | -| array_flow.rb:1052:28:1052:40 | call to source | semmle.label | call to source | -| array_flow.rb:1052:28:1052:40 | call to source | semmle.label | call to source | -| array_flow.rb:1052:43:1052:55 | call to source | semmle.label | call to source | -| array_flow.rb:1052:43:1052:55 | call to source | semmle.label | call to source | -| array_flow.rb:1054:5:1054:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1054:5:1054:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1054:5:1054:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1054:5:1054:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1054:5:1054:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1054:5:1054:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1054:9:1054:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1054:9:1054:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1054:9:1054:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1054:9:1054:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1054:9:1054:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1054:9:1054:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 1] | semmle.label | call to rotate [element 1] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 1] | semmle.label | call to rotate [element 1] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 2] | semmle.label | call to rotate [element 2] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 2] | semmle.label | call to rotate [element 2] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] | semmle.label | call to rotate [element] | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] | semmle.label | call to rotate [element] | -| array_flow.rb:1055:10:1055:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1055:10:1055:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1055:10:1055:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1055:10:1055:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1056:10:1056:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1056:10:1056:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1056:10:1056:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1056:10:1056:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1056:10:1056:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1056:10:1056:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1057:10:1057:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1057:10:1057:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1057:10:1057:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1057:10:1057:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1057:10:1057:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1057:10:1057:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1058:10:1058:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1058:10:1058:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1058:10:1058:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1058:10:1058:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1060:5:1060:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1060:5:1060:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1060:5:1060:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1060:5:1060:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1060:5:1060:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1060:5:1060:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1060:9:1060:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1060:9:1060:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1060:9:1060:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1060:9:1060:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1060:9:1060:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1060:9:1060:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 0] | semmle.label | call to rotate [element 0] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 0] | semmle.label | call to rotate [element 0] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 1] | semmle.label | call to rotate [element 1] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 1] | semmle.label | call to rotate [element 1] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] | semmle.label | call to rotate [element] | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] | semmle.label | call to rotate [element] | -| array_flow.rb:1061:10:1061:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1061:10:1061:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1061:10:1061:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1061:10:1061:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1061:10:1061:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1061:10:1061:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1062:10:1062:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1062:10:1062:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1062:10:1062:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1062:10:1062:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1062:10:1062:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1062:10:1062:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1063:10:1063:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1063:10:1063:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1063:10:1063:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1063:10:1063:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1064:10:1064:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1064:10:1064:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1064:10:1064:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1064:10:1064:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1066:5:1066:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1066:5:1066:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1066:5:1066:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1066:5:1066:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1066:5:1066:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1066:5:1066:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1066:9:1066:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1066:9:1066:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1066:9:1066:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1066:9:1066:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1066:9:1066:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1066:9:1066:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 0] | semmle.label | call to rotate [element 0] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 0] | semmle.label | call to rotate [element 0] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 2] | semmle.label | call to rotate [element 2] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 2] | semmle.label | call to rotate [element 2] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 3] | semmle.label | call to rotate [element 3] | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 3] | semmle.label | call to rotate [element 3] | -| array_flow.rb:1067:10:1067:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1067:10:1067:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1039:10:1039:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1039:10:1039:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1039:10:1039:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1039:10:1039:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1040:10:1040:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1040:10:1040:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1040:10:1040:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1040:10:1040:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1040:10:1040:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1040:10:1040:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1041:10:1041:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1041:10:1041:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1041:10:1041:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1041:10:1041:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1041:10:1041:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1041:10:1041:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1045:5:1045:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1045:5:1045:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1045:16:1045:26 | call to source | semmle.label | call to source | +| array_flow.rb:1045:16:1045:26 | call to source | semmle.label | call to source | +| array_flow.rb:1046:5:1046:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1046:5:1046:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1046:9:1046:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1046:9:1046:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1046:9:1048:7 | call to reverse_each [element 2] | semmle.label | call to reverse_each [element 2] | +| array_flow.rb:1046:9:1048:7 | call to reverse_each [element 2] | semmle.label | call to reverse_each [element 2] | +| array_flow.rb:1046:28:1046:28 | x | semmle.label | x | +| array_flow.rb:1046:28:1046:28 | x | semmle.label | x | +| array_flow.rb:1047:14:1047:14 | x | semmle.label | x | +| array_flow.rb:1047:14:1047:14 | x | semmle.label | x | +| array_flow.rb:1049:10:1049:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1049:10:1049:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1049:10:1049:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1049:10:1049:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1053:5:1053:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1053:5:1053:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1053:16:1053:26 | call to source | semmle.label | call to source | +| array_flow.rb:1053:16:1053:26 | call to source | semmle.label | call to source | +| array_flow.rb:1054:5:1054:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1054:5:1054:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1054:18:1054:18 | x | semmle.label | x | +| array_flow.rb:1054:18:1054:18 | x | semmle.label | x | +| array_flow.rb:1055:14:1055:14 | x | semmle.label | x | +| array_flow.rb:1055:14:1055:14 | x | semmle.label | x | +| array_flow.rb:1063:5:1063:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1063:5:1063:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1063:10:1063:22 | call to source | semmle.label | call to source | +| array_flow.rb:1063:10:1063:22 | call to source | semmle.label | call to source | +| array_flow.rb:1063:28:1063:40 | call to source | semmle.label | call to source | +| array_flow.rb:1063:28:1063:40 | call to source | semmle.label | call to source | +| array_flow.rb:1063:43:1063:55 | call to source | semmle.label | call to source | +| array_flow.rb:1063:43:1063:55 | call to source | semmle.label | call to source | +| array_flow.rb:1065:5:1065:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1065:5:1065:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1065:5:1065:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1065:5:1065:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1065:5:1065:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1065:5:1065:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1065:9:1065:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1065:9:1065:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1065:9:1065:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1065:9:1065:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1065:9:1065:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1065:9:1065:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element 1] | semmle.label | call to rotate [element 1] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element 1] | semmle.label | call to rotate [element 1] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element 2] | semmle.label | call to rotate [element 2] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element 2] | semmle.label | call to rotate [element 2] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element] | semmle.label | call to rotate [element] | +| array_flow.rb:1065:9:1065:16 | call to rotate [element] | semmle.label | call to rotate [element] | +| array_flow.rb:1066:10:1066:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1066:10:1066:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1066:10:1066:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1066:10:1066:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1067:10:1067:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1067:10:1067:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1067:10:1067:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1067:10:1067:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1067:10:1067:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1067:10:1067:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1069:10:1069:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1069:10:1069:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1068:10:1068:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1068:10:1068:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1068:10:1068:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1068:10:1068:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1068:10:1068:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1068:10:1068:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1069:10:1069:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1069:10:1069:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1069:10:1069:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1069:10:1069:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1070:10:1070:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1070:10:1070:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1070:10:1070:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1070:10:1070:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1072:5:1072:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1072:5:1072:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1072:9:1072:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1072:9:1072:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1072:9:1072:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1072:9:1072:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1072:9:1072:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1072:9:1072:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] | semmle.label | call to rotate [element] | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] | semmle.label | call to rotate [element] | +| array_flow.rb:1071:5:1071:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1071:5:1071:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1071:5:1071:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1071:5:1071:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1071:5:1071:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1071:5:1071:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1071:9:1071:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1071:9:1071:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1071:9:1071:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1071:9:1071:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1071:9:1071:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1071:9:1071:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element 0] | semmle.label | call to rotate [element 0] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element 0] | semmle.label | call to rotate [element 0] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element 1] | semmle.label | call to rotate [element 1] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element 1] | semmle.label | call to rotate [element 1] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element] | semmle.label | call to rotate [element] | +| array_flow.rb:1071:9:1071:19 | call to rotate [element] | semmle.label | call to rotate [element] | +| array_flow.rb:1072:10:1072:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1072:10:1072:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1072:10:1072:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1072:10:1072:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1072:10:1072:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1072:10:1072:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1073:10:1073:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1073:10:1073:10 | b [element 1] | semmle.label | b [element 1] | | array_flow.rb:1073:10:1073:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1073:10:1073:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1073:10:1073:13 | ...[...] | semmle.label | ...[...] | @@ -6954,86 +6920,62 @@ nodes | array_flow.rb:1075:10:1075:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1075:10:1075:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1075:10:1075:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1076:10:1076:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1076:10:1076:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1076:10:1076:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1076:10:1076:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1084:5:1084:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1084:5:1084:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1084:5:1084:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1084:5:1084:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1084:5:1084:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1084:5:1084:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1084:10:1084:22 | call to source | semmle.label | call to source | -| array_flow.rb:1084:10:1084:22 | call to source | semmle.label | call to source | -| array_flow.rb:1084:28:1084:40 | call to source | semmle.label | call to source | -| array_flow.rb:1084:28:1084:40 | call to source | semmle.label | call to source | -| array_flow.rb:1084:43:1084:55 | call to source | semmle.label | call to source | -| array_flow.rb:1084:43:1084:55 | call to source | semmle.label | call to source | -| array_flow.rb:1085:5:1085:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1085:5:1085:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1085:5:1085:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1085:5:1085:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1085:5:1085:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1085:5:1085:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | -| array_flow.rb:1085:9:1085:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | -| array_flow.rb:1085:9:1085:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:1085:9:1085:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1085:9:1085:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1085:9:1085:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1085:9:1085:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1085:9:1085:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1085:9:1085:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1085:9:1085:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1085:9:1085:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] | semmle.label | call to rotate! [element 1] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] | semmle.label | call to rotate! [element 1] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] | semmle.label | call to rotate! [element 2] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] | semmle.label | call to rotate! [element 2] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] | semmle.label | call to rotate! [element] | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] | semmle.label | call to rotate! [element] | -| array_flow.rb:1086:10:1086:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1086:10:1086:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1077:5:1077:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1077:5:1077:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1077:5:1077:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1077:5:1077:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1077:5:1077:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1077:5:1077:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1077:9:1077:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1077:9:1077:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1077:9:1077:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1077:9:1077:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1077:9:1077:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1077:9:1077:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 0] | semmle.label | call to rotate [element 0] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 0] | semmle.label | call to rotate [element 0] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 2] | semmle.label | call to rotate [element 2] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 2] | semmle.label | call to rotate [element 2] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 3] | semmle.label | call to rotate [element 3] | +| array_flow.rb:1077:9:1077:19 | call to rotate [element 3] | semmle.label | call to rotate [element 3] | +| array_flow.rb:1078:10:1078:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1078:10:1078:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1078:10:1078:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1078:10:1078:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1080:10:1080:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1080:10:1080:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1080:10:1080:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1080:10:1080:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1081:10:1081:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1081:10:1081:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1081:10:1081:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1081:10:1081:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1083:5:1083:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1083:5:1083:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1083:9:1083:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1083:9:1083:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1083:9:1083:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1083:9:1083:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1083:9:1083:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1083:9:1083:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1083:9:1083:19 | call to rotate [element] | semmle.label | call to rotate [element] | +| array_flow.rb:1083:9:1083:19 | call to rotate [element] | semmle.label | call to rotate [element] | +| array_flow.rb:1084:10:1084:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1084:10:1084:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1084:10:1084:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1084:10:1084:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1085:10:1085:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1085:10:1085:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1085:10:1085:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1085:10:1085:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1086:10:1086:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1086:10:1086:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1086:10:1086:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1086:10:1086:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1087:10:1087:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1087:10:1087:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1087:10:1087:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1087:10:1087:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1087:10:1087:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1087:10:1087:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1087:10:1087:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1087:10:1087:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1088:10:1088:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1088:10:1088:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1088:10:1088:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1088:10:1088:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1088:10:1088:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1088:10:1088:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1089:10:1089:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1089:10:1089:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1089:10:1089:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1089:10:1089:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1090:10:1090:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1090:10:1090:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1090:10:1090:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1090:10:1090:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1091:10:1091:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1091:10:1091:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1091:10:1091:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1091:10:1091:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1091:10:1091:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1091:10:1091:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1092:10:1092:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1092:10:1092:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1092:10:1092:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1092:10:1092:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1092:10:1092:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1092:10:1092:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1093:10:1093:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1093:10:1093:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1093:10:1093:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1093:10:1093:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1095:5:1095:5 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1095:5:1095:5 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1095:5:1095:5 | a [element 2] | semmle.label | a [element 2] | @@ -7046,16 +6988,16 @@ nodes | array_flow.rb:1095:28:1095:40 | call to source | semmle.label | call to source | | array_flow.rb:1095:43:1095:55 | call to source | semmle.label | call to source | | array_flow.rb:1095:43:1095:55 | call to source | semmle.label | call to source | -| array_flow.rb:1096:5:1096:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1096:5:1096:5 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1096:5:1096:5 | b [element 1] | semmle.label | b [element 1] | | array_flow.rb:1096:5:1096:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1096:5:1096:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1096:5:1096:5 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1096:5:1096:5 | b [element] | semmle.label | b [element] | | array_flow.rb:1096:5:1096:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1096:9:1096:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | -| array_flow.rb:1096:9:1096:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | | array_flow.rb:1096:9:1096:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | | array_flow.rb:1096:9:1096:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:1096:9:1096:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:1096:9:1096:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | | array_flow.rb:1096:9:1096:9 | [post] a [element] | semmle.label | [post] a [element] | | array_flow.rb:1096:9:1096:9 | [post] a [element] | semmle.label | [post] a [element] | | array_flow.rb:1096:9:1096:9 | a [element 0] | semmle.label | a [element 0] | @@ -7064,14 +7006,12 @@ nodes | array_flow.rb:1096:9:1096:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1096:9:1096:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1096:9:1096:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] | semmle.label | call to rotate! [element 0] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] | semmle.label | call to rotate! [element 0] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] | semmle.label | call to rotate! [element 1] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] | semmle.label | call to rotate! [element 1] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] | semmle.label | call to rotate! [element] | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] | semmle.label | call to rotate! [element] | -| array_flow.rb:1097:10:1097:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1097:10:1097:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element 1] | semmle.label | call to rotate! [element 1] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element 1] | semmle.label | call to rotate! [element 1] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element 2] | semmle.label | call to rotate! [element 2] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element 2] | semmle.label | call to rotate! [element 2] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element] | semmle.label | call to rotate! [element] | +| array_flow.rb:1096:9:1096:17 | call to rotate! [element] | semmle.label | call to rotate! [element] | | array_flow.rb:1097:10:1097:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1097:10:1097:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1097:10:1097:13 | ...[...] | semmle.label | ...[...] | @@ -7082,6 +7022,8 @@ nodes | array_flow.rb:1098:10:1098:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1098:10:1098:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1098:10:1098:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1099:10:1099:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1099:10:1099:10 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1099:10:1099:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1099:10:1099:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1099:10:1099:13 | ...[...] | semmle.label | ...[...] | @@ -7090,8 +7032,6 @@ nodes | array_flow.rb:1100:10:1100:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1100:10:1100:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1100:10:1100:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1101:10:1101:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1101:10:1101:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1101:10:1101:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1101:10:1101:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1101:10:1101:13 | ...[...] | semmle.label | ...[...] | @@ -7102,6 +7042,8 @@ nodes | array_flow.rb:1102:10:1102:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1102:10:1102:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1102:10:1102:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1103:10:1103:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1103:10:1103:10 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1103:10:1103:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1103:10:1103:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1103:10:1103:13 | ...[...] | semmle.label | ...[...] | @@ -7124,16 +7066,16 @@ nodes | array_flow.rb:1106:43:1106:55 | call to source | semmle.label | call to source | | array_flow.rb:1107:5:1107:5 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1107:5:1107:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1107:5:1107:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1107:5:1107:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1107:5:1107:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1107:5:1107:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1107:5:1107:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1107:5:1107:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1107:5:1107:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1107:5:1107:5 | b [element] | semmle.label | b [element] | | array_flow.rb:1107:9:1107:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | | array_flow.rb:1107:9:1107:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | -| array_flow.rb:1107:9:1107:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:1107:9:1107:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:1107:9:1107:9 | [post] a [element 3] | semmle.label | [post] a [element 3] | -| array_flow.rb:1107:9:1107:9 | [post] a [element 3] | semmle.label | [post] a [element 3] | +| array_flow.rb:1107:9:1107:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:1107:9:1107:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1107:9:1107:9 | [post] a [element] | semmle.label | [post] a [element] | | array_flow.rb:1107:9:1107:9 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1107:9:1107:9 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1107:9:1107:9 | a [element 2] | semmle.label | a [element 2] | @@ -7142,32 +7084,48 @@ nodes | array_flow.rb:1107:9:1107:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] | semmle.label | call to rotate! [element 0] | | array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] | semmle.label | call to rotate! [element 0] | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] | semmle.label | call to rotate! [element 2] | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] | semmle.label | call to rotate! [element 2] | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] | semmle.label | call to rotate! [element 3] | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] | semmle.label | call to rotate! [element 3] | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 1] | semmle.label | call to rotate! [element 1] | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 1] | semmle.label | call to rotate! [element 1] | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element] | semmle.label | call to rotate! [element] | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element] | semmle.label | call to rotate! [element] | | array_flow.rb:1108:10:1108:10 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1108:10:1108:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1108:10:1108:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1108:10:1108:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1108:10:1108:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1108:10:1108:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1110:10:1110:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1110:10:1110:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1109:10:1109:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1109:10:1109:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1109:10:1109:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1109:10:1109:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1109:10:1109:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1109:10:1109:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1110:10:1110:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1110:10:1110:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1110:10:1110:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1110:10:1110:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1111:10:1111:10 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1111:10:1111:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1111:10:1111:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1111:10:1111:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1111:10:1111:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1111:10:1111:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1112:10:1112:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1112:10:1112:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1112:10:1112:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1112:10:1112:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1112:10:1112:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1112:10:1112:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1114:10:1114:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1114:10:1114:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1113:10:1113:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1113:10:1113:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1113:10:1113:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1113:10:1113:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1113:10:1113:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1113:10:1113:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1114:10:1114:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1114:10:1114:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1114:10:1114:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1114:10:1114:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1115:10:1115:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1115:10:1115:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1115:10:1115:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1115:10:1115:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1115:10:1115:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1115:10:1115:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1117:5:1117:5 | a [element 0] | semmle.label | a [element 0] | @@ -7182,208 +7140,242 @@ nodes | array_flow.rb:1117:28:1117:40 | call to source | semmle.label | call to source | | array_flow.rb:1117:43:1117:55 | call to source | semmle.label | call to source | | array_flow.rb:1117:43:1117:55 | call to source | semmle.label | call to source | -| array_flow.rb:1118:5:1118:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1118:5:1118:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1118:9:1118:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1118:5:1118:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1118:5:1118:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1118:5:1118:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1118:5:1118:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1118:5:1118:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1118:5:1118:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 3] | semmle.label | [post] a [element 3] | +| array_flow.rb:1118:9:1118:9 | [post] a [element 3] | semmle.label | [post] a [element 3] | | array_flow.rb:1118:9:1118:9 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1118:9:1118:9 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1118:9:1118:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1118:9:1118:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1118:9:1118:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1118:9:1118:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] | semmle.label | call to rotate! [element] | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] | semmle.label | call to rotate! [element] | -| array_flow.rb:1119:10:1119:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1119:10:1119:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 0] | semmle.label | call to rotate! [element 0] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 0] | semmle.label | call to rotate! [element 0] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 2] | semmle.label | call to rotate! [element 2] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 2] | semmle.label | call to rotate! [element 2] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 3] | semmle.label | call to rotate! [element 3] | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element 3] | semmle.label | call to rotate! [element 3] | +| array_flow.rb:1119:10:1119:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1119:10:1119:10 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:1119:10:1119:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1119:10:1119:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1120:10:1120:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1120:10:1120:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1120:10:1120:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1120:10:1120:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1121:10:1121:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1121:10:1121:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1121:10:1121:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1121:10:1121:10 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1121:10:1121:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1121:10:1121:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1122:10:1122:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1122:10:1122:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1122:10:1122:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1122:10:1122:10 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1122:10:1122:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1122:10:1122:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1123:10:1123:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1123:10:1123:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1123:10:1123:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1123:10:1123:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1123:10:1123:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1123:10:1123:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1124:10:1124:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1124:10:1124:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1124:10:1124:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1124:10:1124:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1125:10:1125:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1125:10:1125:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1125:10:1125:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1125:10:1125:10 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1125:10:1125:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1125:10:1125:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1126:10:1126:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1126:10:1126:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1126:10:1126:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1126:10:1126:10 | b [element 3] | semmle.label | b [element 3] | | array_flow.rb:1126:10:1126:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1126:10:1126:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1130:5:1130:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1130:5:1130:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1130:19:1130:29 | call to source | semmle.label | call to source | -| array_flow.rb:1130:19:1130:29 | call to source | semmle.label | call to source | -| array_flow.rb:1131:5:1131:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1131:5:1131:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1131:9:1131:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1131:9:1131:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1131:9:1133:7 | call to select [element] | semmle.label | call to select [element] | -| array_flow.rb:1131:9:1133:7 | call to select [element] | semmle.label | call to select [element] | -| array_flow.rb:1131:22:1131:22 | x | semmle.label | x | -| array_flow.rb:1131:22:1131:22 | x | semmle.label | x | -| array_flow.rb:1132:14:1132:14 | x | semmle.label | x | -| array_flow.rb:1132:14:1132:14 | x | semmle.label | x | +| array_flow.rb:1128:5:1128:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1128:5:1128:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1128:5:1128:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1128:5:1128:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1128:5:1128:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1128:5:1128:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1128:10:1128:22 | call to source | semmle.label | call to source | +| array_flow.rb:1128:10:1128:22 | call to source | semmle.label | call to source | +| array_flow.rb:1128:28:1128:40 | call to source | semmle.label | call to source | +| array_flow.rb:1128:28:1128:40 | call to source | semmle.label | call to source | +| array_flow.rb:1128:43:1128:55 | call to source | semmle.label | call to source | +| array_flow.rb:1128:43:1128:55 | call to source | semmle.label | call to source | +| array_flow.rb:1129:5:1129:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1129:5:1129:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1129:9:1129:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1129:9:1129:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1129:9:1129:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1129:9:1129:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1129:9:1129:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1129:9:1129:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1129:9:1129:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1129:9:1129:20 | call to rotate! [element] | semmle.label | call to rotate! [element] | +| array_flow.rb:1129:9:1129:20 | call to rotate! [element] | semmle.label | call to rotate! [element] | +| array_flow.rb:1130:10:1130:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1130:10:1130:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1130:10:1130:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1130:10:1130:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1131:10:1131:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1131:10:1131:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1131:10:1131:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1131:10:1131:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1132:10:1132:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1132:10:1132:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1132:10:1132:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1132:10:1132:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1133:10:1133:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1133:10:1133:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1133:10:1133:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1133:10:1133:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1134:10:1134:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1134:10:1134:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1134:10:1134:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1134:10:1134:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1138:5:1138:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1138:5:1138:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1138:16:1138:26 | call to source | semmle.label | call to source | -| array_flow.rb:1138:16:1138:26 | call to source | semmle.label | call to source | -| array_flow.rb:1139:5:1139:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1139:5:1139:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1139:9:1139:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1139:9:1139:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1139:9:1139:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1139:9:1139:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1139:9:1142:7 | call to select! [element] | semmle.label | call to select! [element] | -| array_flow.rb:1139:9:1142:7 | call to select! [element] | semmle.label | call to select! [element] | -| array_flow.rb:1139:23:1139:23 | x | semmle.label | x | -| array_flow.rb:1139:23:1139:23 | x | semmle.label | x | -| array_flow.rb:1140:14:1140:14 | x | semmle.label | x | -| array_flow.rb:1140:14:1140:14 | x | semmle.label | x | -| array_flow.rb:1143:10:1143:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1143:10:1143:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1143:10:1143:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1143:10:1143:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1144:10:1144:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1144:10:1144:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1144:10:1144:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1144:10:1144:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1148:5:1148:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1148:5:1148:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1148:5:1148:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1148:5:1148:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1148:10:1148:22 | call to source | semmle.label | call to source | -| array_flow.rb:1148:10:1148:22 | call to source | semmle.label | call to source | -| array_flow.rb:1148:28:1148:40 | call to source | semmle.label | call to source | -| array_flow.rb:1148:28:1148:40 | call to source | semmle.label | call to source | -| array_flow.rb:1149:5:1149:5 | b | semmle.label | b | -| array_flow.rb:1149:5:1149:5 | b | semmle.label | b | -| array_flow.rb:1149:9:1149:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | -| array_flow.rb:1149:9:1149:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | -| array_flow.rb:1149:9:1149:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1149:9:1149:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1149:9:1149:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1149:9:1149:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1149:9:1149:15 | call to shift | semmle.label | call to shift | -| array_flow.rb:1149:9:1149:15 | call to shift | semmle.label | call to shift | -| array_flow.rb:1150:10:1150:10 | b | semmle.label | b | -| array_flow.rb:1150:10:1150:10 | b | semmle.label | b | -| array_flow.rb:1152:10:1152:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1152:10:1152:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1152:10:1152:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1152:10:1152:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1155:5:1155:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1155:5:1155:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1155:5:1155:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1155:5:1155:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1155:10:1155:22 | call to source | semmle.label | call to source | -| array_flow.rb:1155:10:1155:22 | call to source | semmle.label | call to source | -| array_flow.rb:1155:28:1155:40 | call to source | semmle.label | call to source | -| array_flow.rb:1155:28:1155:40 | call to source | semmle.label | call to source | -| array_flow.rb:1156:5:1156:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1156:5:1156:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1156:9:1156:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | -| array_flow.rb:1156:9:1156:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | -| array_flow.rb:1156:9:1156:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1156:9:1156:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1156:9:1156:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1156:9:1156:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1156:9:1156:18 | call to shift [element 0] | semmle.label | call to shift [element 0] | -| array_flow.rb:1156:9:1156:18 | call to shift [element 0] | semmle.label | call to shift [element 0] | -| array_flow.rb:1157:10:1157:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1157:10:1157:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1157:10:1157:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1157:10:1157:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1159:10:1159:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1159:10:1159:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1159:10:1159:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1159:10:1159:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1163:5:1163:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1163:5:1163:5 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1163:5:1163:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1163:5:1163:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1163:10:1163:22 | call to source | semmle.label | call to source | -| array_flow.rb:1163:10:1163:22 | call to source | semmle.label | call to source | -| array_flow.rb:1163:28:1163:40 | call to source | semmle.label | call to source | -| array_flow.rb:1163:28:1163:40 | call to source | semmle.label | call to source | -| array_flow.rb:1164:5:1164:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1164:5:1164:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1164:9:1164:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1164:9:1164:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1164:9:1164:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1164:9:1164:9 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1164:9:1164:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1164:9:1164:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1164:9:1164:18 | call to shift [element] | semmle.label | call to shift [element] | -| array_flow.rb:1164:9:1164:18 | call to shift [element] | semmle.label | call to shift [element] | -| array_flow.rb:1165:10:1165:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1165:10:1165:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1165:10:1165:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1165:10:1165:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1166:10:1166:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1166:10:1166:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1166:10:1166:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1166:10:1166:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1167:10:1167:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1167:10:1167:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1167:10:1167:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1167:10:1167:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1167:10:1167:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1167:10:1167:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1168:10:1168:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1168:10:1168:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1135:10:1135:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1135:10:1135:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1135:10:1135:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1135:10:1135:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1136:10:1136:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1136:10:1136:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1136:10:1136:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1136:10:1136:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1137:10:1137:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1137:10:1137:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1137:10:1137:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1137:10:1137:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1141:5:1141:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1141:5:1141:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1141:19:1141:29 | call to source | semmle.label | call to source | +| array_flow.rb:1141:19:1141:29 | call to source | semmle.label | call to source | +| array_flow.rb:1142:5:1142:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1142:5:1142:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1142:9:1142:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1142:9:1142:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1142:9:1144:7 | call to select [element] | semmle.label | call to select [element] | +| array_flow.rb:1142:9:1144:7 | call to select [element] | semmle.label | call to select [element] | +| array_flow.rb:1142:22:1142:22 | x | semmle.label | x | +| array_flow.rb:1142:22:1142:22 | x | semmle.label | x | +| array_flow.rb:1143:14:1143:14 | x | semmle.label | x | +| array_flow.rb:1143:14:1143:14 | x | semmle.label | x | +| array_flow.rb:1145:10:1145:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1145:10:1145:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1145:10:1145:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1145:10:1145:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1149:5:1149:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1149:5:1149:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1149:16:1149:26 | call to source | semmle.label | call to source | +| array_flow.rb:1149:16:1149:26 | call to source | semmle.label | call to source | +| array_flow.rb:1150:5:1150:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1150:5:1150:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1150:9:1150:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1150:9:1150:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1150:9:1150:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1150:9:1150:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1150:9:1153:7 | call to select! [element] | semmle.label | call to select! [element] | +| array_flow.rb:1150:9:1153:7 | call to select! [element] | semmle.label | call to select! [element] | +| array_flow.rb:1150:23:1150:23 | x | semmle.label | x | +| array_flow.rb:1150:23:1150:23 | x | semmle.label | x | +| array_flow.rb:1151:14:1151:14 | x | semmle.label | x | +| array_flow.rb:1151:14:1151:14 | x | semmle.label | x | +| array_flow.rb:1154:10:1154:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1154:10:1154:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1154:10:1154:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1154:10:1154:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1155:10:1155:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1155:10:1155:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1155:10:1155:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1155:10:1155:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1159:5:1159:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1159:5:1159:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1159:5:1159:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1159:5:1159:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1159:10:1159:22 | call to source | semmle.label | call to source | +| array_flow.rb:1159:10:1159:22 | call to source | semmle.label | call to source | +| array_flow.rb:1159:28:1159:40 | call to source | semmle.label | call to source | +| array_flow.rb:1159:28:1159:40 | call to source | semmle.label | call to source | +| array_flow.rb:1160:5:1160:5 | b | semmle.label | b | +| array_flow.rb:1160:5:1160:5 | b | semmle.label | b | +| array_flow.rb:1160:9:1160:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:1160:9:1160:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:1160:9:1160:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1160:9:1160:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1160:9:1160:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1160:9:1160:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1160:9:1160:15 | call to shift | semmle.label | call to shift | +| array_flow.rb:1160:9:1160:15 | call to shift | semmle.label | call to shift | +| array_flow.rb:1161:10:1161:10 | b | semmle.label | b | +| array_flow.rb:1161:10:1161:10 | b | semmle.label | b | +| array_flow.rb:1163:10:1163:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1163:10:1163:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1163:10:1163:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1163:10:1163:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1166:5:1166:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1166:5:1166:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1166:5:1166:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1166:5:1166:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1166:10:1166:22 | call to source | semmle.label | call to source | +| array_flow.rb:1166:10:1166:22 | call to source | semmle.label | call to source | +| array_flow.rb:1166:28:1166:40 | call to source | semmle.label | call to source | +| array_flow.rb:1166:28:1166:40 | call to source | semmle.label | call to source | +| array_flow.rb:1167:5:1167:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1167:5:1167:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1167:9:1167:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | +| array_flow.rb:1167:9:1167:9 | [post] a [element 0] | semmle.label | [post] a [element 0] | +| array_flow.rb:1167:9:1167:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1167:9:1167:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1167:9:1167:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1167:9:1167:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1167:9:1167:18 | call to shift [element 0] | semmle.label | call to shift [element 0] | +| array_flow.rb:1167:9:1167:18 | call to shift [element 0] | semmle.label | call to shift [element 0] | +| array_flow.rb:1168:10:1168:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1168:10:1168:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1168:10:1168:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1168:10:1168:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1169:10:1169:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1169:10:1169:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1169:10:1169:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1169:10:1169:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1169:10:1169:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1169:10:1169:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1173:5:1173:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1173:5:1173:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1173:16:1173:26 | call to source | semmle.label | call to source | -| array_flow.rb:1173:16:1173:26 | call to source | semmle.label | call to source | -| array_flow.rb:1174:5:1174:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1174:5:1174:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1174:9:1174:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1174:9:1174:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] | semmle.label | call to shuffle [element] | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] | semmle.label | call to shuffle [element] | -| array_flow.rb:1177:10:1177:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1177:10:1177:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1170:10:1170:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1170:10:1170:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1170:10:1170:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1170:10:1170:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1174:5:1174:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1174:5:1174:5 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1174:5:1174:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1174:5:1174:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1174:10:1174:22 | call to source | semmle.label | call to source | +| array_flow.rb:1174:10:1174:22 | call to source | semmle.label | call to source | +| array_flow.rb:1174:28:1174:40 | call to source | semmle.label | call to source | +| array_flow.rb:1174:28:1174:40 | call to source | semmle.label | call to source | +| array_flow.rb:1175:5:1175:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1175:5:1175:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1175:9:1175:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1175:9:1175:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1175:9:1175:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1175:9:1175:9 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1175:9:1175:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1175:9:1175:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1175:9:1175:18 | call to shift [element] | semmle.label | call to shift [element] | +| array_flow.rb:1175:9:1175:18 | call to shift [element] | semmle.label | call to shift [element] | +| array_flow.rb:1176:10:1176:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1176:10:1176:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1176:10:1176:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1176:10:1176:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1177:10:1177:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1177:10:1177:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1177:10:1177:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1177:10:1177:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1178:10:1178:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1178:10:1178:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1178:10:1178:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1178:10:1178:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1178:10:1178:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1178:10:1178:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1178:10:1178:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1178:10:1178:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1179:10:1179:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1179:10:1179:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1179:10:1179:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1179:10:1179:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1179:10:1179:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1179:10:1179:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1180:10:1180:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1180:10:1180:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1180:10:1180:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1180:10:1180:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1180:10:1180:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1180:10:1180:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1180:10:1180:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1180:10:1180:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1184:5:1184:5 | a [element 2] | semmle.label | a [element 2] | @@ -7392,24 +7384,12 @@ nodes | array_flow.rb:1184:16:1184:26 | call to source | semmle.label | call to source | | array_flow.rb:1185:5:1185:5 | b [element] | semmle.label | b [element] | | array_flow.rb:1185:5:1185:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1185:9:1185:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1185:9:1185:9 | [post] a [element] | semmle.label | [post] a [element] | | array_flow.rb:1185:9:1185:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1185:9:1185:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] | semmle.label | call to shuffle! [element] | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] | semmle.label | call to shuffle! [element] | -| array_flow.rb:1186:10:1186:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1186:10:1186:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1186:10:1186:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1186:10:1186:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1187:10:1187:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1187:10:1187:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1187:10:1187:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1187:10:1187:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1185:9:1185:17 | call to shuffle [element] | semmle.label | call to shuffle [element] | +| array_flow.rb:1185:9:1185:17 | call to shuffle [element] | semmle.label | call to shuffle [element] | | array_flow.rb:1188:10:1188:10 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1188:10:1188:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1188:10:1188:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1188:10:1188:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1188:10:1188:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1188:10:1188:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1189:10:1189:10 | b [element] | semmle.label | b [element] | @@ -7426,234 +7406,227 @@ nodes | array_flow.rb:1191:10:1191:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1195:5:1195:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1195:5:1195:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1195:5:1195:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1195:16:1195:28 | call to source | semmle.label | call to source | -| array_flow.rb:1195:16:1195:28 | call to source | semmle.label | call to source | -| array_flow.rb:1195:34:1195:46 | call to source | semmle.label | call to source | -| array_flow.rb:1195:34:1195:46 | call to source | semmle.label | call to source | -| array_flow.rb:1197:5:1197:5 | b | semmle.label | b | -| array_flow.rb:1197:5:1197:5 | b | semmle.label | b | -| array_flow.rb:1197:9:1197:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1197:9:1197:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1197:9:1197:17 | call to slice | semmle.label | call to slice | -| array_flow.rb:1197:9:1197:17 | call to slice | semmle.label | call to slice | -| array_flow.rb:1198:10:1198:10 | b | semmle.label | b | -| array_flow.rb:1198:10:1198:10 | b | semmle.label | b | -| array_flow.rb:1200:5:1200:5 | b | semmle.label | b | -| array_flow.rb:1200:5:1200:5 | b | semmle.label | b | -| array_flow.rb:1200:9:1200:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1200:9:1200:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1200:9:1200:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1200:9:1200:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1200:9:1200:19 | call to slice | semmle.label | call to slice | -| array_flow.rb:1200:9:1200:19 | call to slice | semmle.label | call to slice | -| array_flow.rb:1201:10:1201:10 | b | semmle.label | b | -| array_flow.rb:1201:10:1201:10 | b | semmle.label | b | -| array_flow.rb:1203:5:1203:5 | b | semmle.label | b | -| array_flow.rb:1203:5:1203:5 | b | semmle.label | b | -| array_flow.rb:1203:5:1203:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1203:5:1203:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1203:9:1203:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1203:9:1203:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1203:9:1203:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1203:9:1203:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1203:9:1203:17 | call to slice | semmle.label | call to slice | -| array_flow.rb:1203:9:1203:17 | call to slice | semmle.label | call to slice | -| array_flow.rb:1203:9:1203:17 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1203:9:1203:17 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1205:10:1205:10 | b | semmle.label | b | -| array_flow.rb:1205:10:1205:10 | b | semmle.label | b | -| array_flow.rb:1207:10:1207:10 | b | semmle.label | b | -| array_flow.rb:1207:10:1207:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1207:10:1207:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1207:10:1207:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1207:10:1207:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1209:5:1209:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1209:5:1209:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1209:5:1209:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1209:5:1209:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1209:9:1209:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1209:9:1209:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1209:9:1209:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1209:9:1209:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1209:9:1209:21 | call to slice [element 0] | semmle.label | call to slice [element 0] | -| array_flow.rb:1209:9:1209:21 | call to slice [element 0] | semmle.label | call to slice [element 0] | -| array_flow.rb:1209:9:1209:21 | call to slice [element 2] | semmle.label | call to slice [element 2] | -| array_flow.rb:1209:9:1209:21 | call to slice [element 2] | semmle.label | call to slice [element 2] | -| array_flow.rb:1210:10:1210:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1210:10:1210:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1210:10:1210:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1210:10:1210:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1212:10:1212:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1212:10:1212:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1212:10:1212:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1212:10:1212:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1195:16:1195:26 | call to source | semmle.label | call to source | +| array_flow.rb:1195:16:1195:26 | call to source | semmle.label | call to source | +| array_flow.rb:1196:5:1196:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1196:5:1196:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1196:9:1196:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1196:9:1196:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1196:9:1196:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1196:9:1196:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1196:9:1196:18 | call to shuffle! [element] | semmle.label | call to shuffle! [element] | +| array_flow.rb:1196:9:1196:18 | call to shuffle! [element] | semmle.label | call to shuffle! [element] | +| array_flow.rb:1197:10:1197:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1197:10:1197:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1197:10:1197:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1197:10:1197:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1198:10:1198:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1198:10:1198:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1198:10:1198:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1198:10:1198:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1199:10:1199:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1199:10:1199:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1199:10:1199:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1199:10:1199:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1199:10:1199:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1199:10:1199:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1200:10:1200:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1200:10:1200:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1200:10:1200:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1200:10:1200:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1201:10:1201:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1201:10:1201:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1201:10:1201:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1201:10:1201:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1202:10:1202:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1202:10:1202:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1202:10:1202:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1202:10:1202:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1206:5:1206:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1206:16:1206:28 | call to source | semmle.label | call to source | +| array_flow.rb:1206:16:1206:28 | call to source | semmle.label | call to source | +| array_flow.rb:1206:34:1206:46 | call to source | semmle.label | call to source | +| array_flow.rb:1206:34:1206:46 | call to source | semmle.label | call to source | +| array_flow.rb:1208:5:1208:5 | b | semmle.label | b | +| array_flow.rb:1208:5:1208:5 | b | semmle.label | b | +| array_flow.rb:1208:9:1208:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1208:9:1208:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1208:9:1208:17 | call to slice | semmle.label | call to slice | +| array_flow.rb:1208:9:1208:17 | call to slice | semmle.label | call to slice | +| array_flow.rb:1209:10:1209:10 | b | semmle.label | b | +| array_flow.rb:1209:10:1209:10 | b | semmle.label | b | +| array_flow.rb:1211:5:1211:5 | b | semmle.label | b | +| array_flow.rb:1211:5:1211:5 | b | semmle.label | b | +| array_flow.rb:1211:9:1211:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1211:9:1211:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1211:9:1211:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1211:9:1211:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1211:9:1211:19 | call to slice | semmle.label | call to slice | +| array_flow.rb:1211:9:1211:19 | call to slice | semmle.label | call to slice | +| array_flow.rb:1212:10:1212:10 | b | semmle.label | b | +| array_flow.rb:1212:10:1212:10 | b | semmle.label | b | +| array_flow.rb:1214:5:1214:5 | b | semmle.label | b | +| array_flow.rb:1214:5:1214:5 | b | semmle.label | b | | array_flow.rb:1214:5:1214:5 | b [element] | semmle.label | b [element] | | array_flow.rb:1214:5:1214:5 | b [element] | semmle.label | b [element] | | array_flow.rb:1214:9:1214:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1214:9:1214:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1214:9:1214:9 | a [element 4] | semmle.label | a [element 4] | | array_flow.rb:1214:9:1214:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1214:9:1214:21 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1214:9:1214:21 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1215:10:1215:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1215:10:1215:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1215:10:1215:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1215:10:1215:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1216:10:1216:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1216:10:1216:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1216:10:1216:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1216:10:1216:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1218:5:1218:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1218:5:1218:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1218:9:1218:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1218:9:1218:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1218:9:1218:21 | call to slice [element 0] | semmle.label | call to slice [element 0] | -| array_flow.rb:1218:9:1218:21 | call to slice [element 0] | semmle.label | call to slice [element 0] | -| array_flow.rb:1219:10:1219:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1219:10:1219:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1219:10:1219:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1219:10:1219:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1223:5:1223:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1223:5:1223:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1223:9:1223:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1223:9:1223:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1223:9:1223:22 | call to slice [element 0] | semmle.label | call to slice [element 0] | -| array_flow.rb:1223:9:1223:22 | call to slice [element 0] | semmle.label | call to slice [element 0] | -| array_flow.rb:1224:10:1224:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1224:10:1224:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1224:10:1224:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1224:10:1224:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1228:5:1228:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1228:5:1228:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1228:9:1228:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1228:9:1228:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1228:9:1228:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1228:9:1228:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1228:9:1228:21 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1228:9:1228:21 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1229:10:1229:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1229:10:1229:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1229:10:1229:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1229:10:1229:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1230:10:1230:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1230:10:1230:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1214:9:1214:17 | call to slice | semmle.label | call to slice | +| array_flow.rb:1214:9:1214:17 | call to slice | semmle.label | call to slice | +| array_flow.rb:1214:9:1214:17 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1214:9:1214:17 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1216:10:1216:10 | b | semmle.label | b | +| array_flow.rb:1216:10:1216:10 | b | semmle.label | b | +| array_flow.rb:1218:10:1218:10 | b | semmle.label | b | +| array_flow.rb:1218:10:1218:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1218:10:1218:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1218:10:1218:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1218:10:1218:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1220:5:1220:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1220:5:1220:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1220:5:1220:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1220:5:1220:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1220:9:1220:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1220:9:1220:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1220:9:1220:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1220:9:1220:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1220:9:1220:21 | call to slice [element 0] | semmle.label | call to slice [element 0] | +| array_flow.rb:1220:9:1220:21 | call to slice [element 0] | semmle.label | call to slice [element 0] | +| array_flow.rb:1220:9:1220:21 | call to slice [element 2] | semmle.label | call to slice [element 2] | +| array_flow.rb:1220:9:1220:21 | call to slice [element 2] | semmle.label | call to slice [element 2] | +| array_flow.rb:1221:10:1221:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1221:10:1221:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1221:10:1221:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1221:10:1221:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1223:10:1223:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1223:10:1223:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1223:10:1223:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1223:10:1223:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1225:5:1225:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1225:5:1225:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1225:9:1225:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1225:9:1225:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1225:9:1225:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1225:9:1225:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1225:9:1225:21 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1225:9:1225:21 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1226:10:1226:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1226:10:1226:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1226:10:1226:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1226:10:1226:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1227:10:1227:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1227:10:1227:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1227:10:1227:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1227:10:1227:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1229:5:1229:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1229:5:1229:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1229:9:1229:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1229:9:1229:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1229:9:1229:21 | call to slice [element 0] | semmle.label | call to slice [element 0] | +| array_flow.rb:1229:9:1229:21 | call to slice [element 0] | semmle.label | call to slice [element 0] | +| array_flow.rb:1230:10:1230:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1230:10:1230:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1230:10:1230:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1230:10:1230:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1232:5:1232:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1232:5:1232:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1232:9:1232:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1232:9:1232:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1232:9:1232:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1232:9:1232:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1232:9:1232:24 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1232:9:1232:24 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1233:10:1233:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1233:10:1233:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1233:10:1233:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1233:10:1233:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1234:10:1234:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1234:10:1234:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1234:10:1234:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1234:10:1234:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1236:5:1236:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1236:5:1236:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1236:9:1236:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1236:9:1236:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1236:9:1236:20 | call to slice [element 2] | semmle.label | call to slice [element 2] | -| array_flow.rb:1236:9:1236:20 | call to slice [element 2] | semmle.label | call to slice [element 2] | -| array_flow.rb:1239:10:1239:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1239:10:1239:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1239:10:1239:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1239:10:1239:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1241:5:1241:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1241:5:1241:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1241:9:1241:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1241:9:1241:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1241:9:1241:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1241:9:1241:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1241:9:1241:20 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1241:9:1241:20 | call to slice [element] | semmle.label | call to slice [element] | -| array_flow.rb:1242:10:1242:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1242:10:1242:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1242:10:1242:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1242:10:1242:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1243:10:1243:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1243:10:1243:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1243:10:1243:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1243:10:1243:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1234:5:1234:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1234:5:1234:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1234:9:1234:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1234:9:1234:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1234:9:1234:22 | call to slice [element 0] | semmle.label | call to slice [element 0] | +| array_flow.rb:1234:9:1234:22 | call to slice [element 0] | semmle.label | call to slice [element 0] | +| array_flow.rb:1235:10:1235:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1235:10:1235:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1235:10:1235:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1235:10:1235:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1239:5:1239:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1239:5:1239:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1239:9:1239:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1239:9:1239:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1239:9:1239:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1239:9:1239:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1239:9:1239:21 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1239:9:1239:21 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1240:10:1240:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1240:10:1240:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1240:10:1240:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1240:10:1240:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1241:10:1241:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1241:10:1241:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1241:10:1241:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1241:10:1241:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1243:5:1243:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1243:5:1243:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1243:9:1243:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1243:9:1243:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1243:9:1243:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1243:9:1243:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1243:9:1243:24 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1243:9:1243:24 | call to slice [element] | semmle.label | call to slice [element] | | array_flow.rb:1244:10:1244:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1244:10:1244:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1244:10:1244:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1244:10:1244:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1248:5:1248:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1248:5:1248:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1248:5:1248:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1248:5:1248:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1248:16:1248:28 | call to source | semmle.label | call to source | -| array_flow.rb:1248:16:1248:28 | call to source | semmle.label | call to source | -| array_flow.rb:1248:34:1248:46 | call to source | semmle.label | call to source | -| array_flow.rb:1248:34:1248:46 | call to source | semmle.label | call to source | -| array_flow.rb:1249:5:1249:5 | b | semmle.label | b | -| array_flow.rb:1249:5:1249:5 | b | semmle.label | b | -| array_flow.rb:1249:9:1249:9 | [post] a [element 3] | semmle.label | [post] a [element 3] | -| array_flow.rb:1249:9:1249:9 | [post] a [element 3] | semmle.label | [post] a [element 3] | -| array_flow.rb:1249:9:1249:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1249:9:1249:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1249:9:1249:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1249:9:1249:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1249:9:1249:19 | call to slice! | semmle.label | call to slice! | -| array_flow.rb:1249:9:1249:19 | call to slice! | semmle.label | call to slice! | -| array_flow.rb:1250:10:1250:10 | b | semmle.label | b | -| array_flow.rb:1250:10:1250:10 | b | semmle.label | b | -| array_flow.rb:1254:10:1254:10 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1254:10:1254:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1245:10:1245:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1245:10:1245:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1245:10:1245:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1245:10:1245:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1247:5:1247:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1247:5:1247:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1247:9:1247:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1247:9:1247:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1247:9:1247:20 | call to slice [element 2] | semmle.label | call to slice [element 2] | +| array_flow.rb:1247:9:1247:20 | call to slice [element 2] | semmle.label | call to slice [element 2] | +| array_flow.rb:1250:10:1250:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1250:10:1250:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1250:10:1250:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1250:10:1250:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1252:5:1252:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1252:5:1252:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1252:9:1252:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1252:9:1252:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1252:9:1252:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1252:9:1252:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1252:9:1252:20 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1252:9:1252:20 | call to slice [element] | semmle.label | call to slice [element] | +| array_flow.rb:1253:10:1253:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1253:10:1253:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1253:10:1253:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1253:10:1253:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1254:10:1254:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1254:10:1254:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1254:10:1254:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1254:10:1254:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1256:5:1256:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1256:5:1256:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1256:5:1256:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1256:5:1256:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1256:16:1256:28 | call to source | semmle.label | call to source | -| array_flow.rb:1256:16:1256:28 | call to source | semmle.label | call to source | -| array_flow.rb:1256:34:1256:46 | call to source | semmle.label | call to source | -| array_flow.rb:1256:34:1256:46 | call to source | semmle.label | call to source | -| array_flow.rb:1257:5:1257:5 | b | semmle.label | b | -| array_flow.rb:1257:5:1257:5 | b | semmle.label | b | -| array_flow.rb:1257:5:1257:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1257:5:1257:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1257:9:1257:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1257:9:1257:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1257:9:1257:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1257:9:1257:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1257:9:1257:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1257:9:1257:19 | call to slice! | semmle.label | call to slice! | -| array_flow.rb:1257:9:1257:19 | call to slice! | semmle.label | call to slice! | -| array_flow.rb:1257:9:1257:19 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1257:9:1257:19 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1258:10:1258:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1258:10:1258:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1258:10:1258:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1258:10:1258:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1259:10:1259:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1259:10:1259:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1259:10:1259:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1259:10:1259:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1260:10:1260:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1260:10:1260:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1260:10:1260:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1260:10:1260:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1261:10:1261:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1261:10:1261:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1261:10:1261:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1261:10:1261:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1263:10:1263:10 | b | semmle.label | b | -| array_flow.rb:1263:10:1263:10 | b | semmle.label | b | -| array_flow.rb:1265:10:1265:10 | b | semmle.label | b | -| array_flow.rb:1265:10:1265:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1265:10:1265:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1255:10:1255:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1255:10:1255:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1255:10:1255:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1255:10:1255:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1259:5:1259:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1259:5:1259:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1259:5:1259:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1259:5:1259:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1259:16:1259:28 | call to source | semmle.label | call to source | +| array_flow.rb:1259:16:1259:28 | call to source | semmle.label | call to source | +| array_flow.rb:1259:34:1259:46 | call to source | semmle.label | call to source | +| array_flow.rb:1259:34:1259:46 | call to source | semmle.label | call to source | +| array_flow.rb:1260:5:1260:5 | b | semmle.label | b | +| array_flow.rb:1260:5:1260:5 | b | semmle.label | b | +| array_flow.rb:1260:9:1260:9 | [post] a [element 3] | semmle.label | [post] a [element 3] | +| array_flow.rb:1260:9:1260:9 | [post] a [element 3] | semmle.label | [post] a [element 3] | +| array_flow.rb:1260:9:1260:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1260:9:1260:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1260:9:1260:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1260:9:1260:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1260:9:1260:19 | call to slice! | semmle.label | call to slice! | +| array_flow.rb:1260:9:1260:19 | call to slice! | semmle.label | call to slice! | +| array_flow.rb:1261:10:1261:10 | b | semmle.label | b | +| array_flow.rb:1261:10:1261:10 | b | semmle.label | b | +| array_flow.rb:1265:10:1265:10 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1265:10:1265:10 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1265:10:1265:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1265:10:1265:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1267:5:1267:5 | a [element 2] | semmle.label | a [element 2] | @@ -7664,26 +7637,43 @@ nodes | array_flow.rb:1267:16:1267:28 | call to source | semmle.label | call to source | | array_flow.rb:1267:34:1267:46 | call to source | semmle.label | call to source | | array_flow.rb:1267:34:1267:46 | call to source | semmle.label | call to source | -| array_flow.rb:1268:5:1268:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1268:5:1268:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1268:5:1268:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1268:5:1268:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1268:5:1268:5 | b | semmle.label | b | +| array_flow.rb:1268:5:1268:5 | b | semmle.label | b | +| array_flow.rb:1268:5:1268:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1268:5:1268:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1268:9:1268:9 | [post] a [element] | semmle.label | [post] a [element] | | array_flow.rb:1268:9:1268:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1268:9:1268:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1268:9:1268:9 | a [element 4] | semmle.label | a [element 4] | | array_flow.rb:1268:9:1268:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 2] | semmle.label | call to slice! [element 2] | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 2] | semmle.label | call to slice! [element 2] | -| array_flow.rb:1269:10:1269:10 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1269:10:1269:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1268:9:1268:19 | call to slice! | semmle.label | call to slice! | +| array_flow.rb:1268:9:1268:19 | call to slice! | semmle.label | call to slice! | +| array_flow.rb:1268:9:1268:19 | call to slice! [element] | semmle.label | call to slice! [element] | +| array_flow.rb:1268:9:1268:19 | call to slice! [element] | semmle.label | call to slice! [element] | +| array_flow.rb:1269:10:1269:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1269:10:1269:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1269:10:1269:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1269:10:1269:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1271:10:1271:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1271:10:1271:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1270:10:1270:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1270:10:1270:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1270:10:1270:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1270:10:1270:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1271:10:1271:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1271:10:1271:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1271:10:1271:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1271:10:1271:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1272:10:1272:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1272:10:1272:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1272:10:1272:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1272:10:1272:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1274:10:1274:10 | b | semmle.label | b | +| array_flow.rb:1274:10:1274:10 | b | semmle.label | b | +| array_flow.rb:1276:10:1276:10 | b | semmle.label | b | +| array_flow.rb:1276:10:1276:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1276:10:1276:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1276:10:1276:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1276:10:1276:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1278:5:1278:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1278:5:1278:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1278:5:1278:5 | a [element 4] | semmle.label | a [element 4] | @@ -7694,22 +7684,24 @@ nodes | array_flow.rb:1278:34:1278:46 | call to source | semmle.label | call to source | | array_flow.rb:1279:5:1279:5 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1279:5:1279:5 | b [element 0] | semmle.label | b [element 0] | -| array_flow.rb:1279:9:1279:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:1279:9:1279:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:1279:5:1279:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1279:5:1279:5 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1279:9:1279:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1279:9:1279:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1279:9:1279:9 | a [element 4] | semmle.label | a [element 4] | | array_flow.rb:1279:9:1279:9 | a [element 4] | semmle.label | a [element 4] | | array_flow.rb:1279:9:1279:22 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | | array_flow.rb:1279:9:1279:22 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | +| array_flow.rb:1279:9:1279:22 | call to slice! [element 2] | semmle.label | call to slice! [element 2] | +| array_flow.rb:1279:9:1279:22 | call to slice! [element 2] | semmle.label | call to slice! [element 2] | | array_flow.rb:1280:10:1280:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1280:10:1280:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1280:10:1280:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1280:10:1280:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1285:10:1285:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1285:10:1285:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1285:10:1285:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1285:10:1285:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1282:10:1282:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1282:10:1282:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1282:10:1282:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1282:10:1282:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1289:5:1289:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1289:5:1289:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1289:5:1289:5 | a [element 4] | semmle.label | a [element 4] | @@ -7726,8 +7718,8 @@ nodes | array_flow.rb:1290:9:1290:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1290:9:1290:9 | a [element 4] | semmle.label | a [element 4] | | array_flow.rb:1290:9:1290:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1290:9:1290:23 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | -| array_flow.rb:1290:9:1290:23 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | +| array_flow.rb:1290:9:1290:22 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | +| array_flow.rb:1290:9:1290:22 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | | array_flow.rb:1291:10:1291:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1291:10:1291:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1291:10:1291:13 | ...[...] | semmle.label | ...[...] | @@ -7744,314 +7736,304 @@ nodes | array_flow.rb:1300:16:1300:28 | call to source | semmle.label | call to source | | array_flow.rb:1300:34:1300:46 | call to source | semmle.label | call to source | | array_flow.rb:1300:34:1300:46 | call to source | semmle.label | call to source | -| array_flow.rb:1301:5:1301:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1301:5:1301:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1301:9:1301:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1301:9:1301:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1301:5:1301:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1301:5:1301:5 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1301:9:1301:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:1301:9:1301:9 | [post] a [element 2] | semmle.label | [post] a [element 2] | | array_flow.rb:1301:9:1301:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1301:9:1301:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1301:9:1301:9 | a [element 4] | semmle.label | a [element 4] | | array_flow.rb:1301:9:1301:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1302:10:1302:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1302:10:1302:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1301:9:1301:23 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | +| array_flow.rb:1301:9:1301:23 | call to slice! [element 0] | semmle.label | call to slice! [element 0] | +| array_flow.rb:1302:10:1302:10 | b [element 0] | semmle.label | b [element 0] | +| array_flow.rb:1302:10:1302:10 | b [element 0] | semmle.label | b [element 0] | | array_flow.rb:1302:10:1302:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1302:10:1302:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1303:10:1303:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1303:10:1303:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1303:10:1303:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1303:10:1303:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1304:10:1304:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1304:10:1304:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1304:10:1304:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1304:10:1304:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1305:10:1305:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1305:10:1305:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1305:10:1305:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1305:10:1305:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1306:10:1306:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1306:10:1306:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1306:10:1306:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1306:10:1306:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1307:10:1307:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1307:10:1307:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1307:10:1307:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1307:10:1307:10 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1307:10:1307:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1307:10:1307:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1309:5:1309:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1309:5:1309:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1309:5:1309:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1309:5:1309:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1309:16:1309:28 | call to source | semmle.label | call to source | -| array_flow.rb:1309:16:1309:28 | call to source | semmle.label | call to source | -| array_flow.rb:1309:34:1309:46 | call to source | semmle.label | call to source | -| array_flow.rb:1309:34:1309:46 | call to source | semmle.label | call to source | -| array_flow.rb:1310:5:1310:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1310:5:1310:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1310:9:1310:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1310:9:1310:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1310:9:1310:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1310:9:1310:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1310:9:1310:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1310:9:1310:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1311:10:1311:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1311:10:1311:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1311:10:1311:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1311:10:1311:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1312:10:1312:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1312:10:1312:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1312:10:1312:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1312:10:1312:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1311:5:1311:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1311:5:1311:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1311:5:1311:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1311:5:1311:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1311:16:1311:28 | call to source | semmle.label | call to source | +| array_flow.rb:1311:16:1311:28 | call to source | semmle.label | call to source | +| array_flow.rb:1311:34:1311:46 | call to source | semmle.label | call to source | +| array_flow.rb:1311:34:1311:46 | call to source | semmle.label | call to source | +| array_flow.rb:1312:5:1312:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1312:5:1312:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1312:9:1312:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1312:9:1312:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1312:9:1312:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1312:9:1312:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1312:9:1312:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1312:9:1312:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1312:9:1312:22 | call to slice! [element] | semmle.label | call to slice! [element] | +| array_flow.rb:1312:9:1312:22 | call to slice! [element] | semmle.label | call to slice! [element] | | array_flow.rb:1313:10:1313:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1313:10:1313:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1313:10:1313:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1313:10:1313:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1314:10:1314:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1314:10:1314:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1314:10:1314:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1314:10:1314:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1314:10:1314:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1314:10:1314:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1315:10:1315:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1315:10:1315:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1315:10:1315:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1315:10:1315:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1315:10:1315:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1315:10:1315:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1316:10:1316:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1316:10:1316:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1316:10:1316:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1316:10:1316:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1318:5:1318:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1318:5:1318:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1318:5:1318:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1318:5:1318:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1318:16:1318:28 | call to source | semmle.label | call to source | -| array_flow.rb:1318:16:1318:28 | call to source | semmle.label | call to source | -| array_flow.rb:1318:34:1318:46 | call to source | semmle.label | call to source | -| array_flow.rb:1318:34:1318:46 | call to source | semmle.label | call to source | -| array_flow.rb:1319:5:1319:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1319:5:1319:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1319:9:1319:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1319:9:1319:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1319:9:1319:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1319:9:1319:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1319:9:1319:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1319:9:1319:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1320:10:1320:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1320:10:1320:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1320:10:1320:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1320:10:1320:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1321:10:1321:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1321:10:1321:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1321:10:1321:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1321:10:1321:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1317:10:1317:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1317:10:1317:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1317:10:1317:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1317:10:1317:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1318:10:1318:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1318:10:1318:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1318:10:1318:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1318:10:1318:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1320:5:1320:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1320:5:1320:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1320:5:1320:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1320:5:1320:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1320:16:1320:28 | call to source | semmle.label | call to source | +| array_flow.rb:1320:16:1320:28 | call to source | semmle.label | call to source | +| array_flow.rb:1320:34:1320:46 | call to source | semmle.label | call to source | +| array_flow.rb:1320:34:1320:46 | call to source | semmle.label | call to source | +| array_flow.rb:1321:5:1321:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1321:5:1321:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1321:9:1321:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1321:9:1321:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1321:9:1321:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1321:9:1321:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1321:9:1321:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1321:9:1321:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1321:9:1321:22 | call to slice! [element] | semmle.label | call to slice! [element] | +| array_flow.rb:1321:9:1321:22 | call to slice! [element] | semmle.label | call to slice! [element] | | array_flow.rb:1322:10:1322:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1322:10:1322:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1322:10:1322:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1322:10:1322:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1323:10:1323:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1323:10:1323:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1323:10:1323:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1323:10:1323:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1323:10:1323:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1323:10:1323:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1324:10:1324:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1324:10:1324:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1324:10:1324:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1324:10:1324:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1324:10:1324:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1324:10:1324:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1325:10:1325:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1325:10:1325:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1325:10:1325:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1325:10:1325:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1327:5:1327:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1327:5:1327:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1327:5:1327:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1327:5:1327:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1327:16:1327:28 | call to source | semmle.label | call to source | -| array_flow.rb:1327:16:1327:28 | call to source | semmle.label | call to source | -| array_flow.rb:1327:34:1327:46 | call to source | semmle.label | call to source | -| array_flow.rb:1327:34:1327:46 | call to source | semmle.label | call to source | -| array_flow.rb:1328:5:1328:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1328:5:1328:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1328:9:1328:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | -| array_flow.rb:1328:9:1328:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | -| array_flow.rb:1328:9:1328:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1328:9:1328:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1328:9:1328:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1328:9:1328:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1328:9:1328:21 | call to slice! [element 2] | semmle.label | call to slice! [element 2] | -| array_flow.rb:1328:9:1328:21 | call to slice! [element 2] | semmle.label | call to slice! [element 2] | -| array_flow.rb:1331:10:1331:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1331:10:1331:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1326:10:1326:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1326:10:1326:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1326:10:1326:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1326:10:1326:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1327:10:1327:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1327:10:1327:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1327:10:1327:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1327:10:1327:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1329:5:1329:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1329:5:1329:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1329:5:1329:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1329:5:1329:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1329:16:1329:28 | call to source | semmle.label | call to source | +| array_flow.rb:1329:16:1329:28 | call to source | semmle.label | call to source | +| array_flow.rb:1329:34:1329:46 | call to source | semmle.label | call to source | +| array_flow.rb:1329:34:1329:46 | call to source | semmle.label | call to source | +| array_flow.rb:1330:5:1330:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1330:5:1330:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1330:9:1330:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1330:9:1330:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1330:9:1330:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1330:9:1330:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1330:9:1330:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1330:9:1330:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1330:9:1330:25 | call to slice! [element] | semmle.label | call to slice! [element] | +| array_flow.rb:1330:9:1330:25 | call to slice! [element] | semmle.label | call to slice! [element] | +| array_flow.rb:1331:10:1331:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1331:10:1331:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1331:10:1331:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1331:10:1331:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1333:10:1333:10 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1333:10:1333:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1332:10:1332:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1332:10:1332:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1332:10:1332:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1332:10:1332:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1333:10:1333:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1333:10:1333:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1333:10:1333:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1333:10:1333:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1336:5:1336:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1336:5:1336:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1336:5:1336:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1336:5:1336:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1336:16:1336:28 | call to source | semmle.label | call to source | -| array_flow.rb:1336:16:1336:28 | call to source | semmle.label | call to source | -| array_flow.rb:1336:34:1336:46 | call to source | semmle.label | call to source | -| array_flow.rb:1336:34:1336:46 | call to source | semmle.label | call to source | -| array_flow.rb:1337:5:1337:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1337:5:1337:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1337:9:1337:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1337:9:1337:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1337:9:1337:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1337:9:1337:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1337:9:1337:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1337:9:1337:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] | semmle.label | call to slice! [element] | -| array_flow.rb:1338:10:1338:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1338:10:1338:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1338:10:1338:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1338:10:1338:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1339:10:1339:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1339:10:1339:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1339:10:1339:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1339:10:1339:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1340:10:1340:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1340:10:1340:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1340:10:1340:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1340:10:1340:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1341:10:1341:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1341:10:1341:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1341:10:1341:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1341:10:1341:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1342:10:1342:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1342:10:1342:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1334:10:1334:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1334:10:1334:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1334:10:1334:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1334:10:1334:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1335:10:1335:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1335:10:1335:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1335:10:1335:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1335:10:1335:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1336:10:1336:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1336:10:1336:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1336:10:1336:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1336:10:1336:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1338:5:1338:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1338:5:1338:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1338:5:1338:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1338:5:1338:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1338:16:1338:28 | call to source | semmle.label | call to source | +| array_flow.rb:1338:16:1338:28 | call to source | semmle.label | call to source | +| array_flow.rb:1338:34:1338:46 | call to source | semmle.label | call to source | +| array_flow.rb:1338:34:1338:46 | call to source | semmle.label | call to source | +| array_flow.rb:1339:5:1339:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1339:5:1339:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1339:9:1339:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:1339:9:1339:9 | [post] a [element 1] | semmle.label | [post] a [element 1] | +| array_flow.rb:1339:9:1339:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1339:9:1339:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1339:9:1339:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1339:9:1339:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1339:9:1339:21 | call to slice! [element 2] | semmle.label | call to slice! [element 2] | +| array_flow.rb:1339:9:1339:21 | call to slice! [element 2] | semmle.label | call to slice! [element 2] | +| array_flow.rb:1342:10:1342:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1342:10:1342:10 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1342:10:1342:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1342:10:1342:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1343:10:1343:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1343:10:1343:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1343:10:1343:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1343:10:1343:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1344:10:1344:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1344:10:1344:10 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1344:10:1344:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1344:10:1344:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1347:5:1347:5 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1347:5:1347:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1347:16:1347:26 | call to source | semmle.label | call to source | -| array_flow.rb:1347:16:1347:26 | call to source | semmle.label | call to source | +| array_flow.rb:1347:5:1347:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1347:5:1347:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1347:16:1347:28 | call to source | semmle.label | call to source | +| array_flow.rb:1347:16:1347:28 | call to source | semmle.label | call to source | +| array_flow.rb:1347:34:1347:46 | call to source | semmle.label | call to source | +| array_flow.rb:1347:34:1347:46 | call to source | semmle.label | call to source | +| array_flow.rb:1348:5:1348:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1348:5:1348:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1348:9:1348:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1348:9:1348:9 | [post] a [element] | semmle.label | [post] a [element] | | array_flow.rb:1348:9:1348:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1348:9:1348:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1348:27:1348:27 | x | semmle.label | x | -| array_flow.rb:1348:27:1348:27 | x | semmle.label | x | -| array_flow.rb:1349:14:1349:14 | x | semmle.label | x | -| array_flow.rb:1349:14:1349:14 | x | semmle.label | x | -| array_flow.rb:1355:5:1355:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1355:5:1355:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1355:16:1355:26 | call to source | semmle.label | call to source | -| array_flow.rb:1355:16:1355:26 | call to source | semmle.label | call to source | -| array_flow.rb:1356:9:1356:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1356:9:1356:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1356:28:1356:28 | x | semmle.label | x | -| array_flow.rb:1356:28:1356:28 | x | semmle.label | x | -| array_flow.rb:1357:14:1357:14 | x | semmle.label | x | -| array_flow.rb:1357:14:1357:14 | x | semmle.label | x | -| array_flow.rb:1363:5:1363:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1363:5:1363:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1363:16:1363:26 | call to source | semmle.label | call to source | -| array_flow.rb:1363:16:1363:26 | call to source | semmle.label | call to source | -| array_flow.rb:1364:9:1364:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1364:9:1364:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1364:26:1364:26 | x | semmle.label | x | -| array_flow.rb:1364:26:1364:26 | x | semmle.label | x | -| array_flow.rb:1364:29:1364:29 | y | semmle.label | y | -| array_flow.rb:1364:29:1364:29 | y | semmle.label | y | -| array_flow.rb:1365:14:1365:14 | x | semmle.label | x | -| array_flow.rb:1365:14:1365:14 | x | semmle.label | x | -| array_flow.rb:1366:14:1366:14 | y | semmle.label | y | -| array_flow.rb:1366:14:1366:14 | y | semmle.label | y | -| array_flow.rb:1371:5:1371:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1371:5:1371:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1371:16:1371:26 | call to source | semmle.label | call to source | -| array_flow.rb:1371:16:1371:26 | call to source | semmle.label | call to source | -| array_flow.rb:1372:5:1372:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1372:5:1372:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1372:9:1372:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1372:9:1372:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1372:9:1372:14 | call to sort [element] | semmle.label | call to sort [element] | -| array_flow.rb:1372:9:1372:14 | call to sort [element] | semmle.label | call to sort [element] | -| array_flow.rb:1373:10:1373:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1373:10:1373:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1373:10:1373:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1373:10:1373:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1374:10:1374:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1374:10:1374:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1374:10:1374:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1374:10:1374:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1375:5:1375:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:1375:5:1375:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:1348:9:1348:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1348:9:1348:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1348:9:1348:21 | call to slice! [element] | semmle.label | call to slice! [element] | +| array_flow.rb:1348:9:1348:21 | call to slice! [element] | semmle.label | call to slice! [element] | +| array_flow.rb:1349:10:1349:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1349:10:1349:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1349:10:1349:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1349:10:1349:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1350:10:1350:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1350:10:1350:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1350:10:1350:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1350:10:1350:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1351:10:1351:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1351:10:1351:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1351:10:1351:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1351:10:1351:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1352:10:1352:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1352:10:1352:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1352:10:1352:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1352:10:1352:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1353:10:1353:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1353:10:1353:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1353:10:1353:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1353:10:1353:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1354:10:1354:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1354:10:1354:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1354:10:1354:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1354:10:1354:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1358:5:1358:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1358:5:1358:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1358:16:1358:26 | call to source | semmle.label | call to source | +| array_flow.rb:1358:16:1358:26 | call to source | semmle.label | call to source | +| array_flow.rb:1359:9:1359:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1359:9:1359:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1359:27:1359:27 | x | semmle.label | x | +| array_flow.rb:1359:27:1359:27 | x | semmle.label | x | +| array_flow.rb:1360:14:1360:14 | x | semmle.label | x | +| array_flow.rb:1360:14:1360:14 | x | semmle.label | x | +| array_flow.rb:1366:5:1366:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1366:5:1366:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1366:16:1366:26 | call to source | semmle.label | call to source | +| array_flow.rb:1366:16:1366:26 | call to source | semmle.label | call to source | +| array_flow.rb:1367:9:1367:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1367:9:1367:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1367:28:1367:28 | x | semmle.label | x | +| array_flow.rb:1367:28:1367:28 | x | semmle.label | x | +| array_flow.rb:1368:14:1368:14 | x | semmle.label | x | +| array_flow.rb:1368:14:1368:14 | x | semmle.label | x | +| array_flow.rb:1374:5:1374:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1374:5:1374:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1374:16:1374:26 | call to source | semmle.label | call to source | +| array_flow.rb:1374:16:1374:26 | call to source | semmle.label | call to source | | array_flow.rb:1375:9:1375:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1375:9:1375:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1375:9:1379:7 | call to sort [element] | semmle.label | call to sort [element] | -| array_flow.rb:1375:9:1379:7 | call to sort [element] | semmle.label | call to sort [element] | -| array_flow.rb:1375:20:1375:20 | x | semmle.label | x | -| array_flow.rb:1375:20:1375:20 | x | semmle.label | x | -| array_flow.rb:1375:23:1375:23 | y | semmle.label | y | -| array_flow.rb:1375:23:1375:23 | y | semmle.label | y | +| array_flow.rb:1375:26:1375:26 | x | semmle.label | x | +| array_flow.rb:1375:26:1375:26 | x | semmle.label | x | +| array_flow.rb:1375:29:1375:29 | y | semmle.label | y | +| array_flow.rb:1375:29:1375:29 | y | semmle.label | y | | array_flow.rb:1376:14:1376:14 | x | semmle.label | x | | array_flow.rb:1376:14:1376:14 | x | semmle.label | x | | array_flow.rb:1377:14:1377:14 | y | semmle.label | y | | array_flow.rb:1377:14:1377:14 | y | semmle.label | y | -| array_flow.rb:1380:10:1380:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1380:10:1380:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1380:10:1380:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1380:10:1380:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1381:10:1381:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1381:10:1381:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1381:10:1381:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1381:10:1381:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1385:5:1385:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1385:5:1385:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1385:16:1385:26 | call to source | semmle.label | call to source | -| array_flow.rb:1385:16:1385:26 | call to source | semmle.label | call to source | -| array_flow.rb:1386:5:1386:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1386:5:1386:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1386:9:1386:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1386:9:1386:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1382:5:1382:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1382:5:1382:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1382:16:1382:26 | call to source | semmle.label | call to source | +| array_flow.rb:1382:16:1382:26 | call to source | semmle.label | call to source | +| array_flow.rb:1383:5:1383:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1383:5:1383:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1383:9:1383:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1383:9:1383:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1383:9:1383:14 | call to sort [element] | semmle.label | call to sort [element] | +| array_flow.rb:1383:9:1383:14 | call to sort [element] | semmle.label | call to sort [element] | +| array_flow.rb:1384:10:1384:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1384:10:1384:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1384:10:1384:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1384:10:1384:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1385:10:1385:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1385:10:1385:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1385:10:1385:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1385:10:1385:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1386:5:1386:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:1386:5:1386:5 | c [element] | semmle.label | c [element] | | array_flow.rb:1386:9:1386:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1386:9:1386:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1386:9:1386:15 | call to sort! [element] | semmle.label | call to sort! [element] | -| array_flow.rb:1386:9:1386:15 | call to sort! [element] | semmle.label | call to sort! [element] | -| array_flow.rb:1387:10:1387:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1387:10:1387:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1387:10:1387:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1387:10:1387:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1388:10:1388:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1388:10:1388:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1388:10:1388:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1388:10:1388:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1389:10:1389:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1389:10:1389:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1389:10:1389:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1389:10:1389:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1390:10:1390:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1390:10:1390:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1390:10:1390:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1390:10:1390:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1392:5:1392:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1392:5:1392:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1392:16:1392:26 | call to source | semmle.label | call to source | -| array_flow.rb:1392:16:1392:26 | call to source | semmle.label | call to source | -| array_flow.rb:1393:5:1393:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1393:5:1393:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1393:9:1393:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1393:9:1393:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1393:9:1393:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1393:9:1393:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1393:9:1397:7 | call to sort! [element] | semmle.label | call to sort! [element] | -| array_flow.rb:1393:9:1397:7 | call to sort! [element] | semmle.label | call to sort! [element] | -| array_flow.rb:1393:21:1393:21 | x | semmle.label | x | -| array_flow.rb:1393:21:1393:21 | x | semmle.label | x | -| array_flow.rb:1393:24:1393:24 | y | semmle.label | y | -| array_flow.rb:1393:24:1393:24 | y | semmle.label | y | -| array_flow.rb:1394:14:1394:14 | x | semmle.label | x | -| array_flow.rb:1394:14:1394:14 | x | semmle.label | x | -| array_flow.rb:1395:14:1395:14 | y | semmle.label | y | -| array_flow.rb:1395:14:1395:14 | y | semmle.label | y | +| array_flow.rb:1386:9:1390:7 | call to sort [element] | semmle.label | call to sort [element] | +| array_flow.rb:1386:9:1390:7 | call to sort [element] | semmle.label | call to sort [element] | +| array_flow.rb:1386:20:1386:20 | x | semmle.label | x | +| array_flow.rb:1386:20:1386:20 | x | semmle.label | x | +| array_flow.rb:1386:23:1386:23 | y | semmle.label | y | +| array_flow.rb:1386:23:1386:23 | y | semmle.label | y | +| array_flow.rb:1387:14:1387:14 | x | semmle.label | x | +| array_flow.rb:1387:14:1387:14 | x | semmle.label | x | +| array_flow.rb:1388:14:1388:14 | y | semmle.label | y | +| array_flow.rb:1388:14:1388:14 | y | semmle.label | y | +| array_flow.rb:1391:10:1391:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1391:10:1391:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1391:10:1391:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1391:10:1391:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1392:10:1392:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1392:10:1392:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1392:10:1392:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1392:10:1392:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1396:5:1396:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1396:5:1396:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1396:16:1396:26 | call to source | semmle.label | call to source | +| array_flow.rb:1396:16:1396:26 | call to source | semmle.label | call to source | +| array_flow.rb:1397:5:1397:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1397:5:1397:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1397:9:1397:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1397:9:1397:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1397:9:1397:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1397:9:1397:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1397:9:1397:15 | call to sort! [element] | semmle.label | call to sort! [element] | +| array_flow.rb:1397:9:1397:15 | call to sort! [element] | semmle.label | call to sort! [element] | | array_flow.rb:1398:10:1398:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1398:10:1398:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1398:10:1398:13 | ...[...] | semmle.label | ...[...] | @@ -8068,112 +8050,114 @@ nodes | array_flow.rb:1401:10:1401:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1401:10:1401:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1401:10:1401:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1405:5:1405:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1405:5:1405:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1405:16:1405:26 | call to source | semmle.label | call to source | -| array_flow.rb:1405:16:1405:26 | call to source | semmle.label | call to source | -| array_flow.rb:1406:5:1406:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1406:5:1406:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1406:9:1406:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1406:9:1406:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1406:9:1409:7 | call to sort_by [element] | semmle.label | call to sort_by [element] | -| array_flow.rb:1406:9:1409:7 | call to sort_by [element] | semmle.label | call to sort_by [element] | -| array_flow.rb:1406:23:1406:23 | x | semmle.label | x | -| array_flow.rb:1406:23:1406:23 | x | semmle.label | x | -| array_flow.rb:1407:14:1407:14 | x | semmle.label | x | -| array_flow.rb:1407:14:1407:14 | x | semmle.label | x | +| array_flow.rb:1403:5:1403:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1403:5:1403:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1403:16:1403:26 | call to source | semmle.label | call to source | +| array_flow.rb:1403:16:1403:26 | call to source | semmle.label | call to source | +| array_flow.rb:1404:5:1404:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1404:5:1404:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1404:9:1404:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1404:9:1404:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1404:9:1404:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1404:9:1404:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1404:9:1408:7 | call to sort! [element] | semmle.label | call to sort! [element] | +| array_flow.rb:1404:9:1408:7 | call to sort! [element] | semmle.label | call to sort! [element] | +| array_flow.rb:1404:21:1404:21 | x | semmle.label | x | +| array_flow.rb:1404:21:1404:21 | x | semmle.label | x | +| array_flow.rb:1404:24:1404:24 | y | semmle.label | y | +| array_flow.rb:1404:24:1404:24 | y | semmle.label | y | +| array_flow.rb:1405:14:1405:14 | x | semmle.label | x | +| array_flow.rb:1405:14:1405:14 | x | semmle.label | x | +| array_flow.rb:1406:14:1406:14 | y | semmle.label | y | +| array_flow.rb:1406:14:1406:14 | y | semmle.label | y | +| array_flow.rb:1409:10:1409:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1409:10:1409:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1409:10:1409:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1409:10:1409:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1410:10:1410:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1410:10:1410:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1410:10:1410:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1410:10:1410:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1411:10:1411:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1411:10:1411:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1411:10:1411:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1411:10:1411:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1411:10:1411:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1411:10:1411:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1415:5:1415:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1415:5:1415:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1415:16:1415:26 | call to source | semmle.label | call to source | -| array_flow.rb:1415:16:1415:26 | call to source | semmle.label | call to source | -| array_flow.rb:1416:5:1416:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1416:5:1416:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1416:9:1416:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1416:9:1416:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1416:9:1416:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1416:9:1416:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] | semmle.label | call to sort_by! [element] | -| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] | semmle.label | call to sort_by! [element] | -| array_flow.rb:1416:24:1416:24 | x | semmle.label | x | -| array_flow.rb:1416:24:1416:24 | x | semmle.label | x | -| array_flow.rb:1417:14:1417:14 | x | semmle.label | x | -| array_flow.rb:1417:14:1417:14 | x | semmle.label | x | -| array_flow.rb:1420:10:1420:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1420:10:1420:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1420:10:1420:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1420:10:1420:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1421:10:1421:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1421:10:1421:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1412:10:1412:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1412:10:1412:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1412:10:1412:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1412:10:1412:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1416:5:1416:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1416:5:1416:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1416:16:1416:26 | call to source | semmle.label | call to source | +| array_flow.rb:1416:16:1416:26 | call to source | semmle.label | call to source | +| array_flow.rb:1417:5:1417:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1417:5:1417:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1417:9:1417:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1417:9:1417:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1417:9:1420:7 | call to sort_by [element] | semmle.label | call to sort_by [element] | +| array_flow.rb:1417:9:1420:7 | call to sort_by [element] | semmle.label | call to sort_by [element] | +| array_flow.rb:1417:23:1417:23 | x | semmle.label | x | +| array_flow.rb:1417:23:1417:23 | x | semmle.label | x | +| array_flow.rb:1418:14:1418:14 | x | semmle.label | x | +| array_flow.rb:1418:14:1418:14 | x | semmle.label | x | +| array_flow.rb:1421:10:1421:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1421:10:1421:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1421:10:1421:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1421:10:1421:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1422:10:1422:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1422:10:1422:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1422:10:1422:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1422:10:1422:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1423:10:1423:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1423:10:1423:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1423:10:1423:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1423:10:1423:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1427:5:1427:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1427:5:1427:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1427:16:1427:26 | call to source | semmle.label | call to source | -| array_flow.rb:1427:16:1427:26 | call to source | semmle.label | call to source | -| array_flow.rb:1428:9:1428:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1428:9:1428:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1428:19:1428:19 | x | semmle.label | x | -| array_flow.rb:1428:19:1428:19 | x | semmle.label | x | -| array_flow.rb:1429:14:1429:14 | x | semmle.label | x | -| array_flow.rb:1429:14:1429:14 | x | semmle.label | x | -| array_flow.rb:1435:5:1435:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1435:5:1435:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1435:5:1435:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1435:16:1435:28 | call to source | semmle.label | call to source | -| array_flow.rb:1435:16:1435:28 | call to source | semmle.label | call to source | -| array_flow.rb:1435:31:1435:43 | call to source | semmle.label | call to source | -| array_flow.rb:1435:31:1435:43 | call to source | semmle.label | call to source | -| array_flow.rb:1436:5:1436:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1436:5:1436:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1436:5:1436:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1436:5:1436:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1436:9:1436:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1436:9:1436:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1436:9:1436:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1436:9:1436:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1436:9:1436:17 | call to take [element 2] | semmle.label | call to take [element 2] | -| array_flow.rb:1436:9:1436:17 | call to take [element 2] | semmle.label | call to take [element 2] | -| array_flow.rb:1436:9:1436:17 | call to take [element 3] | semmle.label | call to take [element 3] | -| array_flow.rb:1436:9:1436:17 | call to take [element 3] | semmle.label | call to take [element 3] | -| array_flow.rb:1439:10:1439:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1439:10:1439:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1439:10:1439:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1439:10:1439:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1440:10:1440:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1440:10:1440:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1440:10:1440:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1440:10:1440:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1441:5:1441:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1441:5:1441:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1441:9:1441:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1441:9:1441:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1441:9:1441:17 | call to take [element 2] | semmle.label | call to take [element 2] | -| array_flow.rb:1441:9:1441:17 | call to take [element 2] | semmle.label | call to take [element 2] | -| array_flow.rb:1444:10:1444:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1444:10:1444:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1444:10:1444:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1444:10:1444:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1446:10:1446:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1446:10:1446:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1446:10:1446:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1446:10:1446:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1426:5:1426:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1426:5:1426:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1426:16:1426:26 | call to source | semmle.label | call to source | +| array_flow.rb:1426:16:1426:26 | call to source | semmle.label | call to source | +| array_flow.rb:1427:5:1427:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1427:5:1427:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1427:9:1427:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1427:9:1427:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1427:9:1427:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1427:9:1427:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1427:9:1430:7 | call to sort_by! [element] | semmle.label | call to sort_by! [element] | +| array_flow.rb:1427:9:1430:7 | call to sort_by! [element] | semmle.label | call to sort_by! [element] | +| array_flow.rb:1427:24:1427:24 | x | semmle.label | x | +| array_flow.rb:1427:24:1427:24 | x | semmle.label | x | +| array_flow.rb:1428:14:1428:14 | x | semmle.label | x | +| array_flow.rb:1428:14:1428:14 | x | semmle.label | x | +| array_flow.rb:1431:10:1431:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1431:10:1431:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1431:10:1431:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1431:10:1431:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1432:10:1432:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1432:10:1432:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1432:10:1432:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1432:10:1432:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1433:10:1433:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1433:10:1433:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1433:10:1433:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1433:10:1433:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1434:10:1434:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1434:10:1434:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1434:10:1434:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1434:10:1434:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1438:5:1438:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1438:5:1438:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1438:16:1438:26 | call to source | semmle.label | call to source | +| array_flow.rb:1438:16:1438:26 | call to source | semmle.label | call to source | +| array_flow.rb:1439:9:1439:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1439:9:1439:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1439:19:1439:19 | x | semmle.label | x | +| array_flow.rb:1439:19:1439:19 | x | semmle.label | x | +| array_flow.rb:1440:14:1440:14 | x | semmle.label | x | +| array_flow.rb:1440:14:1440:14 | x | semmle.label | x | +| array_flow.rb:1446:5:1446:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1446:5:1446:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1446:5:1446:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1446:16:1446:28 | call to source | semmle.label | call to source | +| array_flow.rb:1446:16:1446:28 | call to source | semmle.label | call to source | +| array_flow.rb:1446:31:1446:43 | call to source | semmle.label | call to source | +| array_flow.rb:1446:31:1446:43 | call to source | semmle.label | call to source | | array_flow.rb:1447:5:1447:5 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1447:5:1447:5 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1447:5:1447:5 | b [element 3] | semmle.label | b [element 3] | @@ -8182,10 +8166,10 @@ nodes | array_flow.rb:1447:9:1447:9 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1447:9:1447:9 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1447:9:1447:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1447:9:1447:19 | call to take [element 2] | semmle.label | call to take [element 2] | -| array_flow.rb:1447:9:1447:19 | call to take [element 2] | semmle.label | call to take [element 2] | -| array_flow.rb:1447:9:1447:19 | call to take [element 3] | semmle.label | call to take [element 3] | -| array_flow.rb:1447:9:1447:19 | call to take [element 3] | semmle.label | call to take [element 3] | +| array_flow.rb:1447:9:1447:17 | call to take [element 2] | semmle.label | call to take [element 2] | +| array_flow.rb:1447:9:1447:17 | call to take [element 2] | semmle.label | call to take [element 2] | +| array_flow.rb:1447:9:1447:17 | call to take [element 3] | semmle.label | call to take [element 3] | +| array_flow.rb:1447:9:1447:17 | call to take [element 3] | semmle.label | call to take [element 3] | | array_flow.rb:1450:10:1450:10 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1450:10:1450:10 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1450:10:1450:13 | ...[...] | semmle.label | ...[...] | @@ -8194,546 +8178,580 @@ nodes | array_flow.rb:1451:10:1451:10 | b [element 3] | semmle.label | b [element 3] | | array_flow.rb:1451:10:1451:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1451:10:1451:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1452:10:1452:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1452:10:1452:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1452:10:1452:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1452:10:1452:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1452:10:1452:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1452:10:1452:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1453:5:1453:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1453:5:1453:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1453:12:1453:24 | call to source | semmle.label | call to source | -| array_flow.rb:1453:12:1453:24 | call to source | semmle.label | call to source | -| array_flow.rb:1454:5:1454:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1454:5:1454:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1454:5:1454:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1454:5:1454:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1454:9:1454:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1454:9:1454:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1454:9:1454:9 | a [element] | semmle.label | a [element] | -| array_flow.rb:1454:9:1454:9 | a [element] | semmle.label | a [element] | -| array_flow.rb:1454:9:1454:17 | call to take [element 2] | semmle.label | call to take [element 2] | -| array_flow.rb:1454:9:1454:17 | call to take [element 2] | semmle.label | call to take [element 2] | -| array_flow.rb:1454:9:1454:17 | call to take [element] | semmle.label | call to take [element] | -| array_flow.rb:1454:9:1454:17 | call to take [element] | semmle.label | call to take [element] | +| array_flow.rb:1452:5:1452:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1452:5:1452:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1452:9:1452:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1452:9:1452:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1452:9:1452:17 | call to take [element 2] | semmle.label | call to take [element 2] | +| array_flow.rb:1452:9:1452:17 | call to take [element 2] | semmle.label | call to take [element 2] | | array_flow.rb:1455:10:1455:10 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1455:10:1455:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1455:10:1455:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1455:10:1455:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1455:10:1455:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1455:10:1455:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1459:5:1459:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1459:5:1459:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1459:16:1459:26 | call to source | semmle.label | call to source | -| array_flow.rb:1459:16:1459:26 | call to source | semmle.label | call to source | -| array_flow.rb:1460:5:1460:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1460:5:1460:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1460:9:1460:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1460:9:1460:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1460:9:1463:7 | call to take_while [element 2] | semmle.label | call to take_while [element 2] | -| array_flow.rb:1460:9:1463:7 | call to take_while [element 2] | semmle.label | call to take_while [element 2] | -| array_flow.rb:1460:26:1460:26 | x | semmle.label | x | -| array_flow.rb:1460:26:1460:26 | x | semmle.label | x | -| array_flow.rb:1461:14:1461:14 | x | semmle.label | x | -| array_flow.rb:1461:14:1461:14 | x | semmle.label | x | +| array_flow.rb:1457:10:1457:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1457:10:1457:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1457:10:1457:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1457:10:1457:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1458:5:1458:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1458:5:1458:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1458:5:1458:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1458:5:1458:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1458:9:1458:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1458:9:1458:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1458:9:1458:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1458:9:1458:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1458:9:1458:19 | call to take [element 2] | semmle.label | call to take [element 2] | +| array_flow.rb:1458:9:1458:19 | call to take [element 2] | semmle.label | call to take [element 2] | +| array_flow.rb:1458:9:1458:19 | call to take [element 3] | semmle.label | call to take [element 3] | +| array_flow.rb:1458:9:1458:19 | call to take [element 3] | semmle.label | call to take [element 3] | +| array_flow.rb:1461:10:1461:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1461:10:1461:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1461:10:1461:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1461:10:1461:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1462:10:1462:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1462:10:1462:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1462:10:1462:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1462:10:1462:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1463:10:1463:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1463:10:1463:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1463:10:1463:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1463:10:1463:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1463:10:1463:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1463:10:1463:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1464:5:1464:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1464:5:1464:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1464:12:1464:24 | call to source | semmle.label | call to source | +| array_flow.rb:1464:12:1464:24 | call to source | semmle.label | call to source | +| array_flow.rb:1465:5:1465:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1465:5:1465:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1465:5:1465:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1465:5:1465:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1465:9:1465:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1465:9:1465:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1465:9:1465:9 | a [element] | semmle.label | a [element] | +| array_flow.rb:1465:9:1465:9 | a [element] | semmle.label | a [element] | +| array_flow.rb:1465:9:1465:17 | call to take [element 2] | semmle.label | call to take [element 2] | +| array_flow.rb:1465:9:1465:17 | call to take [element 2] | semmle.label | call to take [element 2] | +| array_flow.rb:1465:9:1465:17 | call to take [element] | semmle.label | call to take [element] | +| array_flow.rb:1465:9:1465:17 | call to take [element] | semmle.label | call to take [element] | | array_flow.rb:1466:10:1466:10 | b [element 2] | semmle.label | b [element 2] | | array_flow.rb:1466:10:1466:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1466:10:1466:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1466:10:1466:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1466:10:1466:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1466:10:1466:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1472:5:1472:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1472:5:1472:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1472:19:1472:29 | call to source | semmle.label | call to source | -| array_flow.rb:1472:19:1472:29 | call to source | semmle.label | call to source | -| array_flow.rb:1473:5:1473:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1473:5:1473:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1473:9:1473:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1473:9:1473:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1473:9:1473:14 | call to to_a [element 3] | semmle.label | call to to_a [element 3] | -| array_flow.rb:1473:9:1473:14 | call to to_a [element 3] | semmle.label | call to to_a [element 3] | -| array_flow.rb:1474:10:1474:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1474:10:1474:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1474:10:1474:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1474:10:1474:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1478:5:1478:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1478:5:1478:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1478:16:1478:26 | call to source | semmle.label | call to source | -| array_flow.rb:1478:16:1478:26 | call to source | semmle.label | call to source | -| array_flow.rb:1479:5:1479:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1479:5:1479:5 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1479:9:1479:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1479:9:1479:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] | semmle.label | call to to_ary [element 2] | -| array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] | semmle.label | call to to_ary [element 2] | -| array_flow.rb:1482:10:1482:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1482:10:1482:10 | b [element 2] | semmle.label | b [element 2] | -| array_flow.rb:1482:10:1482:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1482:10:1482:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1495:5:1495:5 | a [element 0, element 1] | semmle.label | a [element 0, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 0, element 1] | semmle.label | a [element 0, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 1, element 1] | semmle.label | a [element 1, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 1, element 1] | semmle.label | a [element 1, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:1495:5:1495:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:1495:14:1495:26 | call to source | semmle.label | call to source | -| array_flow.rb:1495:14:1495:26 | call to source | semmle.label | call to source | -| array_flow.rb:1495:34:1495:46 | call to source | semmle.label | call to source | -| array_flow.rb:1495:34:1495:46 | call to source | semmle.label | call to source | -| array_flow.rb:1495:54:1495:66 | call to source | semmle.label | call to source | -| array_flow.rb:1495:54:1495:66 | call to source | semmle.label | call to source | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 0] | semmle.label | b [element 1, element 0] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 0] | semmle.label | b [element 1, element 0] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 1] | semmle.label | b [element 1, element 1] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 1] | semmle.label | b [element 1, element 1] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 2] | semmle.label | b [element 1, element 2] | -| array_flow.rb:1496:5:1496:5 | b [element 1, element 2] | semmle.label | b [element 1, element 2] | -| array_flow.rb:1496:9:1496:9 | a [element 0, element 1] | semmle.label | a [element 0, element 1] | -| array_flow.rb:1496:9:1496:9 | a [element 0, element 1] | semmle.label | a [element 0, element 1] | -| array_flow.rb:1496:9:1496:9 | a [element 1, element 1] | semmle.label | a [element 1, element 1] | -| array_flow.rb:1496:9:1496:9 | a [element 1, element 1] | semmle.label | a [element 1, element 1] | -| array_flow.rb:1496:9:1496:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:1496:9:1496:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] | semmle.label | call to transpose [element 1, element 0] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] | semmle.label | call to transpose [element 1, element 0] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] | semmle.label | call to transpose [element 1, element 1] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] | semmle.label | call to transpose [element 1, element 1] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] | semmle.label | call to transpose [element 1, element 2] | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] | semmle.label | call to transpose [element 1, element 2] | -| array_flow.rb:1500:10:1500:10 | b [element 1, element 0] | semmle.label | b [element 1, element 0] | -| array_flow.rb:1500:10:1500:10 | b [element 1, element 0] | semmle.label | b [element 1, element 0] | -| array_flow.rb:1500:10:1500:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1500:10:1500:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1500:10:1500:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1500:10:1500:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1501:10:1501:10 | b [element 1, element 1] | semmle.label | b [element 1, element 1] | -| array_flow.rb:1501:10:1501:10 | b [element 1, element 1] | semmle.label | b [element 1, element 1] | -| array_flow.rb:1501:10:1501:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:1501:10:1501:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:1501:10:1501:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1501:10:1501:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1502:10:1502:10 | b [element 1, element 2] | semmle.label | b [element 1, element 2] | -| array_flow.rb:1502:10:1502:10 | b [element 1, element 2] | semmle.label | b [element 1, element 2] | -| array_flow.rb:1502:10:1502:13 | ...[...] [element 2] | semmle.label | ...[...] [element 2] | -| array_flow.rb:1502:10:1502:13 | ...[...] [element 2] | semmle.label | ...[...] [element 2] | -| array_flow.rb:1502:10:1502:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1502:10:1502:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1506:5:1506:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1506:5:1506:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1506:16:1506:28 | call to source | semmle.label | call to source | -| array_flow.rb:1506:16:1506:28 | call to source | semmle.label | call to source | -| array_flow.rb:1507:5:1507:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1507:5:1507:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1507:13:1507:25 | call to source | semmle.label | call to source | -| array_flow.rb:1507:13:1507:25 | call to source | semmle.label | call to source | -| array_flow.rb:1508:5:1508:5 | c [element 1] | semmle.label | c [element 1] | -| array_flow.rb:1508:5:1508:5 | c [element 1] | semmle.label | c [element 1] | -| array_flow.rb:1508:13:1508:25 | call to source | semmle.label | call to source | -| array_flow.rb:1508:13:1508:25 | call to source | semmle.label | call to source | -| array_flow.rb:1509:5:1509:5 | d [element] | semmle.label | d [element] | -| array_flow.rb:1509:5:1509:5 | d [element] | semmle.label | d [element] | -| array_flow.rb:1509:9:1509:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1509:9:1509:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1509:9:1509:21 | call to union [element] | semmle.label | call to union [element] | -| array_flow.rb:1509:9:1509:21 | call to union [element] | semmle.label | call to union [element] | -| array_flow.rb:1509:17:1509:17 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1509:17:1509:17 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1509:20:1509:20 | c [element 1] | semmle.label | c [element 1] | -| array_flow.rb:1509:20:1509:20 | c [element 1] | semmle.label | c [element 1] | -| array_flow.rb:1510:10:1510:10 | d [element] | semmle.label | d [element] | -| array_flow.rb:1510:10:1510:10 | d [element] | semmle.label | d [element] | -| array_flow.rb:1510:10:1510:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1510:10:1510:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1511:10:1511:10 | d [element] | semmle.label | d [element] | -| array_flow.rb:1511:10:1511:10 | d [element] | semmle.label | d [element] | -| array_flow.rb:1511:10:1511:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1511:10:1511:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1512:10:1512:10 | d [element] | semmle.label | d [element] | -| array_flow.rb:1512:10:1512:10 | d [element] | semmle.label | d [element] | -| array_flow.rb:1512:10:1512:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1512:10:1512:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1516:5:1516:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1516:5:1516:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1516:5:1516:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1516:5:1516:5 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1516:19:1516:31 | call to source | semmle.label | call to source | -| array_flow.rb:1516:19:1516:31 | call to source | semmle.label | call to source | -| array_flow.rb:1516:34:1516:46 | call to source | semmle.label | call to source | -| array_flow.rb:1516:34:1516:46 | call to source | semmle.label | call to source | -| array_flow.rb:1518:5:1518:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1518:5:1518:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1518:9:1518:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1518:9:1518:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1518:9:1518:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1518:9:1518:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1518:9:1518:14 | call to uniq [element] | semmle.label | call to uniq [element] | -| array_flow.rb:1518:9:1518:14 | call to uniq [element] | semmle.label | call to uniq [element] | -| array_flow.rb:1519:10:1519:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1519:10:1519:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1519:10:1519:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1519:10:1519:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1520:10:1520:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1520:10:1520:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1520:10:1520:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1520:10:1520:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1522:5:1522:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:1522:5:1522:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:1522:9:1522:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1522:9:1522:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1522:9:1522:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1522:9:1522:9 | a [element 4] | semmle.label | a [element 4] | -| array_flow.rb:1522:9:1525:7 | call to uniq [element] | semmle.label | call to uniq [element] | -| array_flow.rb:1522:9:1525:7 | call to uniq [element] | semmle.label | call to uniq [element] | -| array_flow.rb:1522:20:1522:20 | x | semmle.label | x | -| array_flow.rb:1522:20:1522:20 | x | semmle.label | x | -| array_flow.rb:1523:14:1523:14 | x | semmle.label | x | -| array_flow.rb:1523:14:1523:14 | x | semmle.label | x | -| array_flow.rb:1526:10:1526:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1526:10:1526:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1526:10:1526:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1526:10:1526:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1530:5:1530:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1530:5:1530:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1530:5:1530:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1530:5:1530:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1530:16:1530:28 | call to source | semmle.label | call to source | -| array_flow.rb:1530:16:1530:28 | call to source | semmle.label | call to source | -| array_flow.rb:1530:31:1530:43 | call to source | semmle.label | call to source | -| array_flow.rb:1530:31:1530:43 | call to source | semmle.label | call to source | -| array_flow.rb:1531:5:1531:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1531:5:1531:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1531:9:1531:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1531:9:1531:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1531:9:1531:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1531:9:1531:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1531:9:1531:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1531:9:1531:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1531:9:1531:15 | call to uniq! [element] | semmle.label | call to uniq! [element] | -| array_flow.rb:1531:9:1531:15 | call to uniq! [element] | semmle.label | call to uniq! [element] | -| array_flow.rb:1532:10:1532:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1532:10:1532:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1532:10:1532:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1532:10:1532:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1533:10:1533:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1533:10:1533:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1533:10:1533:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1533:10:1533:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1534:10:1534:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1534:10:1534:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1534:10:1534:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1534:10:1534:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1535:10:1535:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1535:10:1535:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1535:10:1535:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1535:10:1535:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1537:5:1537:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1537:5:1537:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1537:5:1537:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1537:5:1537:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1537:16:1537:28 | call to source | semmle.label | call to source | -| array_flow.rb:1537:16:1537:28 | call to source | semmle.label | call to source | -| array_flow.rb:1537:31:1537:43 | call to source | semmle.label | call to source | -| array_flow.rb:1537:31:1537:43 | call to source | semmle.label | call to source | -| array_flow.rb:1538:5:1538:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1538:5:1538:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1538:9:1538:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1538:9:1538:9 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1538:9:1538:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1538:9:1538:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1538:9:1538:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1538:9:1538:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1538:9:1541:7 | call to uniq! [element] | semmle.label | call to uniq! [element] | -| array_flow.rb:1538:9:1541:7 | call to uniq! [element] | semmle.label | call to uniq! [element] | -| array_flow.rb:1538:21:1538:21 | x | semmle.label | x | -| array_flow.rb:1538:21:1538:21 | x | semmle.label | x | -| array_flow.rb:1539:14:1539:14 | x | semmle.label | x | -| array_flow.rb:1539:14:1539:14 | x | semmle.label | x | -| array_flow.rb:1542:10:1542:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1542:10:1542:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1542:10:1542:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1542:10:1542:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1470:5:1470:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1470:5:1470:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1470:16:1470:26 | call to source | semmle.label | call to source | +| array_flow.rb:1470:16:1470:26 | call to source | semmle.label | call to source | +| array_flow.rb:1471:5:1471:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1471:5:1471:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1471:9:1471:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1471:9:1471:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1471:9:1474:7 | call to take_while [element 2] | semmle.label | call to take_while [element 2] | +| array_flow.rb:1471:9:1474:7 | call to take_while [element 2] | semmle.label | call to take_while [element 2] | +| array_flow.rb:1471:26:1471:26 | x | semmle.label | x | +| array_flow.rb:1471:26:1471:26 | x | semmle.label | x | +| array_flow.rb:1472:14:1472:14 | x | semmle.label | x | +| array_flow.rb:1472:14:1472:14 | x | semmle.label | x | +| array_flow.rb:1477:10:1477:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1477:10:1477:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1477:10:1477:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1477:10:1477:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1483:5:1483:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1483:5:1483:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1483:19:1483:29 | call to source | semmle.label | call to source | +| array_flow.rb:1483:19:1483:29 | call to source | semmle.label | call to source | +| array_flow.rb:1484:5:1484:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1484:5:1484:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1484:9:1484:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1484:9:1484:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1484:9:1484:14 | call to to_a [element 3] | semmle.label | call to to_a [element 3] | +| array_flow.rb:1484:9:1484:14 | call to to_a [element 3] | semmle.label | call to to_a [element 3] | +| array_flow.rb:1485:10:1485:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1485:10:1485:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1485:10:1485:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1485:10:1485:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1489:5:1489:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1489:5:1489:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1489:16:1489:26 | call to source | semmle.label | call to source | +| array_flow.rb:1489:16:1489:26 | call to source | semmle.label | call to source | +| array_flow.rb:1490:5:1490:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1490:5:1490:5 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1490:9:1490:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1490:9:1490:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1490:9:1490:16 | call to to_ary [element 2] | semmle.label | call to to_ary [element 2] | +| array_flow.rb:1490:9:1490:16 | call to to_ary [element 2] | semmle.label | call to to_ary [element 2] | +| array_flow.rb:1493:10:1493:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1493:10:1493:10 | b [element 2] | semmle.label | b [element 2] | +| array_flow.rb:1493:10:1493:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1493:10:1493:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1506:5:1506:5 | a [element 0, element 1] | semmle.label | a [element 0, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 0, element 1] | semmle.label | a [element 0, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 1, element 1] | semmle.label | a [element 1, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 1, element 1] | semmle.label | a [element 1, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:1506:5:1506:5 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:1506:14:1506:26 | call to source | semmle.label | call to source | +| array_flow.rb:1506:14:1506:26 | call to source | semmle.label | call to source | +| array_flow.rb:1506:34:1506:46 | call to source | semmle.label | call to source | +| array_flow.rb:1506:34:1506:46 | call to source | semmle.label | call to source | +| array_flow.rb:1506:54:1506:66 | call to source | semmle.label | call to source | +| array_flow.rb:1506:54:1506:66 | call to source | semmle.label | call to source | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 0] | semmle.label | b [element 1, element 0] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 0] | semmle.label | b [element 1, element 0] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 1] | semmle.label | b [element 1, element 1] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 1] | semmle.label | b [element 1, element 1] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 2] | semmle.label | b [element 1, element 2] | +| array_flow.rb:1507:5:1507:5 | b [element 1, element 2] | semmle.label | b [element 1, element 2] | +| array_flow.rb:1507:9:1507:9 | a [element 0, element 1] | semmle.label | a [element 0, element 1] | +| array_flow.rb:1507:9:1507:9 | a [element 0, element 1] | semmle.label | a [element 0, element 1] | +| array_flow.rb:1507:9:1507:9 | a [element 1, element 1] | semmle.label | a [element 1, element 1] | +| array_flow.rb:1507:9:1507:9 | a [element 1, element 1] | semmle.label | a [element 1, element 1] | +| array_flow.rb:1507:9:1507:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:1507:9:1507:9 | a [element 2, element 1] | semmle.label | a [element 2, element 1] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 0] | semmle.label | call to transpose [element 1, element 0] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 0] | semmle.label | call to transpose [element 1, element 0] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 1] | semmle.label | call to transpose [element 1, element 1] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 1] | semmle.label | call to transpose [element 1, element 1] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 2] | semmle.label | call to transpose [element 1, element 2] | +| array_flow.rb:1507:9:1507:19 | call to transpose [element 1, element 2] | semmle.label | call to transpose [element 1, element 2] | +| array_flow.rb:1511:10:1511:10 | b [element 1, element 0] | semmle.label | b [element 1, element 0] | +| array_flow.rb:1511:10:1511:10 | b [element 1, element 0] | semmle.label | b [element 1, element 0] | +| array_flow.rb:1511:10:1511:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1511:10:1511:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1511:10:1511:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1511:10:1511:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1512:10:1512:10 | b [element 1, element 1] | semmle.label | b [element 1, element 1] | +| array_flow.rb:1512:10:1512:10 | b [element 1, element 1] | semmle.label | b [element 1, element 1] | +| array_flow.rb:1512:10:1512:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:1512:10:1512:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:1512:10:1512:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1512:10:1512:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1513:10:1513:10 | b [element 1, element 2] | semmle.label | b [element 1, element 2] | +| array_flow.rb:1513:10:1513:10 | b [element 1, element 2] | semmle.label | b [element 1, element 2] | +| array_flow.rb:1513:10:1513:13 | ...[...] [element 2] | semmle.label | ...[...] [element 2] | +| array_flow.rb:1513:10:1513:13 | ...[...] [element 2] | semmle.label | ...[...] [element 2] | +| array_flow.rb:1513:10:1513:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1513:10:1513:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1517:5:1517:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1517:5:1517:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1517:16:1517:28 | call to source | semmle.label | call to source | +| array_flow.rb:1517:16:1517:28 | call to source | semmle.label | call to source | +| array_flow.rb:1518:5:1518:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1518:5:1518:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1518:13:1518:25 | call to source | semmle.label | call to source | +| array_flow.rb:1518:13:1518:25 | call to source | semmle.label | call to source | +| array_flow.rb:1519:5:1519:5 | c [element 1] | semmle.label | c [element 1] | +| array_flow.rb:1519:5:1519:5 | c [element 1] | semmle.label | c [element 1] | +| array_flow.rb:1519:13:1519:25 | call to source | semmle.label | call to source | +| array_flow.rb:1519:13:1519:25 | call to source | semmle.label | call to source | +| array_flow.rb:1520:5:1520:5 | d [element] | semmle.label | d [element] | +| array_flow.rb:1520:5:1520:5 | d [element] | semmle.label | d [element] | +| array_flow.rb:1520:9:1520:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1520:9:1520:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1520:9:1520:21 | call to union [element] | semmle.label | call to union [element] | +| array_flow.rb:1520:9:1520:21 | call to union [element] | semmle.label | call to union [element] | +| array_flow.rb:1520:17:1520:17 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1520:17:1520:17 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1520:20:1520:20 | c [element 1] | semmle.label | c [element 1] | +| array_flow.rb:1520:20:1520:20 | c [element 1] | semmle.label | c [element 1] | +| array_flow.rb:1521:10:1521:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:1521:10:1521:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:1521:10:1521:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1521:10:1521:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1522:10:1522:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:1522:10:1522:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:1522:10:1522:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1522:10:1522:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1523:10:1523:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:1523:10:1523:10 | d [element] | semmle.label | d [element] | +| array_flow.rb:1523:10:1523:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1523:10:1523:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1527:5:1527:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1527:5:1527:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1527:5:1527:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1527:5:1527:5 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1527:19:1527:31 | call to source | semmle.label | call to source | +| array_flow.rb:1527:19:1527:31 | call to source | semmle.label | call to source | +| array_flow.rb:1527:34:1527:46 | call to source | semmle.label | call to source | +| array_flow.rb:1527:34:1527:46 | call to source | semmle.label | call to source | +| array_flow.rb:1529:5:1529:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1529:5:1529:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1529:9:1529:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1529:9:1529:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1529:9:1529:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1529:9:1529:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1529:9:1529:14 | call to uniq [element] | semmle.label | call to uniq [element] | +| array_flow.rb:1529:9:1529:14 | call to uniq [element] | semmle.label | call to uniq [element] | +| array_flow.rb:1530:10:1530:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1530:10:1530:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1530:10:1530:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1530:10:1530:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1531:10:1531:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1531:10:1531:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1531:10:1531:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1531:10:1531:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1533:5:1533:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:1533:5:1533:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:1533:9:1533:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1533:9:1533:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1533:9:1533:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1533:9:1533:9 | a [element 4] | semmle.label | a [element 4] | +| array_flow.rb:1533:9:1536:7 | call to uniq [element] | semmle.label | call to uniq [element] | +| array_flow.rb:1533:9:1536:7 | call to uniq [element] | semmle.label | call to uniq [element] | +| array_flow.rb:1533:20:1533:20 | x | semmle.label | x | +| array_flow.rb:1533:20:1533:20 | x | semmle.label | x | +| array_flow.rb:1534:14:1534:14 | x | semmle.label | x | +| array_flow.rb:1534:14:1534:14 | x | semmle.label | x | +| array_flow.rb:1537:10:1537:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1537:10:1537:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1537:10:1537:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1537:10:1537:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1541:5:1541:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1541:5:1541:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1541:5:1541:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1541:5:1541:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1541:16:1541:28 | call to source | semmle.label | call to source | +| array_flow.rb:1541:16:1541:28 | call to source | semmle.label | call to source | +| array_flow.rb:1541:31:1541:43 | call to source | semmle.label | call to source | +| array_flow.rb:1541:31:1541:43 | call to source | semmle.label | call to source | +| array_flow.rb:1542:5:1542:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1542:5:1542:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1542:9:1542:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1542:9:1542:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1542:9:1542:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1542:9:1542:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1542:9:1542:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1542:9:1542:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1542:9:1542:15 | call to uniq! [element] | semmle.label | call to uniq! [element] | +| array_flow.rb:1542:9:1542:15 | call to uniq! [element] | semmle.label | call to uniq! [element] | | array_flow.rb:1543:10:1543:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1543:10:1543:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1543:10:1543:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1543:10:1543:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1544:10:1544:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1544:10:1544:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1544:10:1544:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1544:10:1544:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1544:10:1544:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1544:10:1544:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1545:10:1545:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1545:10:1545:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1545:10:1545:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1545:10:1545:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1549:5:1549:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1549:5:1549:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1549:16:1549:28 | call to source | semmle.label | call to source | -| array_flow.rb:1549:16:1549:28 | call to source | semmle.label | call to source | -| array_flow.rb:1550:5:1550:5 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:1550:5:1550:5 | [post] a [element 2] | semmle.label | [post] a [element 2] | -| array_flow.rb:1550:5:1550:5 | [post] a [element 5] | semmle.label | [post] a [element 5] | -| array_flow.rb:1550:5:1550:5 | [post] a [element 5] | semmle.label | [post] a [element 5] | -| array_flow.rb:1550:5:1550:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1550:5:1550:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1550:21:1550:33 | call to source | semmle.label | call to source | -| array_flow.rb:1550:21:1550:33 | call to source | semmle.label | call to source | -| array_flow.rb:1553:10:1553:10 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1553:10:1553:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1546:10:1546:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1546:10:1546:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1546:10:1546:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1546:10:1546:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1548:5:1548:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1548:5:1548:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1548:5:1548:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1548:5:1548:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1548:16:1548:28 | call to source | semmle.label | call to source | +| array_flow.rb:1548:16:1548:28 | call to source | semmle.label | call to source | +| array_flow.rb:1548:31:1548:43 | call to source | semmle.label | call to source | +| array_flow.rb:1548:31:1548:43 | call to source | semmle.label | call to source | +| array_flow.rb:1549:5:1549:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1549:5:1549:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1549:9:1549:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1549:9:1549:9 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1549:9:1549:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1549:9:1549:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1549:9:1549:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1549:9:1549:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1549:9:1552:7 | call to uniq! [element] | semmle.label | call to uniq! [element] | +| array_flow.rb:1549:9:1552:7 | call to uniq! [element] | semmle.label | call to uniq! [element] | +| array_flow.rb:1549:21:1549:21 | x | semmle.label | x | +| array_flow.rb:1549:21:1549:21 | x | semmle.label | x | +| array_flow.rb:1550:14:1550:14 | x | semmle.label | x | +| array_flow.rb:1550:14:1550:14 | x | semmle.label | x | +| array_flow.rb:1553:10:1553:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1553:10:1553:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1553:10:1553:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1553:10:1553:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1556:10:1556:10 | a [element 5] | semmle.label | a [element 5] | -| array_flow.rb:1556:10:1556:10 | a [element 5] | semmle.label | a [element 5] | +| array_flow.rb:1554:10:1554:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1554:10:1554:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1554:10:1554:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1554:10:1554:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1555:10:1555:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1555:10:1555:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1555:10:1555:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1555:10:1555:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1556:10:1556:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1556:10:1556:10 | a [element] | semmle.label | a [element] | | array_flow.rb:1556:10:1556:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1556:10:1556:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1560:5:1560:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1560:5:1560:5 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1560:13:1560:25 | call to source | semmle.label | call to source | -| array_flow.rb:1560:13:1560:25 | call to source | semmle.label | call to source | -| array_flow.rb:1560:31:1560:43 | call to source | semmle.label | call to source | -| array_flow.rb:1560:31:1560:43 | call to source | semmle.label | call to source | -| array_flow.rb:1562:5:1562:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1562:5:1562:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1562:5:1562:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1562:5:1562:5 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1562:9:1562:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1562:9:1562:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 1] | semmle.label | call to values_at [element 1] | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 1] | semmle.label | call to values_at [element 1] | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 3] | semmle.label | call to values_at [element 3] | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 3] | semmle.label | call to values_at [element 3] | -| array_flow.rb:1564:10:1564:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1564:10:1564:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1560:5:1560:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1560:5:1560:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1560:16:1560:28 | call to source | semmle.label | call to source | +| array_flow.rb:1560:16:1560:28 | call to source | semmle.label | call to source | +| array_flow.rb:1561:5:1561:5 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:1561:5:1561:5 | [post] a [element 2] | semmle.label | [post] a [element 2] | +| array_flow.rb:1561:5:1561:5 | [post] a [element 5] | semmle.label | [post] a [element 5] | +| array_flow.rb:1561:5:1561:5 | [post] a [element 5] | semmle.label | [post] a [element 5] | +| array_flow.rb:1561:5:1561:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1561:5:1561:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1561:21:1561:33 | call to source | semmle.label | call to source | +| array_flow.rb:1561:21:1561:33 | call to source | semmle.label | call to source | +| array_flow.rb:1564:10:1564:10 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1564:10:1564:10 | a [element 2] | semmle.label | a [element 2] | | array_flow.rb:1564:10:1564:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1564:10:1564:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1566:10:1566:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1566:10:1566:10 | b [element 3] | semmle.label | b [element 3] | -| array_flow.rb:1566:10:1566:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1566:10:1566:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1568:5:1568:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1568:5:1568:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1568:9:1568:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1568:9:1568:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1568:9:1568:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1568:9:1568:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1568:9:1568:25 | call to values_at [element] | semmle.label | call to values_at [element] | -| array_flow.rb:1568:9:1568:25 | call to values_at [element] | semmle.label | call to values_at [element] | -| array_flow.rb:1569:10:1569:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1569:10:1569:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1569:10:1569:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1569:10:1569:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1570:10:1570:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1570:10:1570:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1570:10:1570:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1570:10:1570:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1572:5:1572:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1572:5:1572:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1572:9:1572:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1572:9:1572:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1572:9:1572:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1572:9:1572:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1572:9:1572:26 | call to values_at [element] | semmle.label | call to values_at [element] | -| array_flow.rb:1572:9:1572:26 | call to values_at [element] | semmle.label | call to values_at [element] | -| array_flow.rb:1573:10:1573:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1573:10:1573:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1573:10:1573:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1573:10:1573:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1574:10:1574:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1574:10:1574:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1574:10:1574:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1574:10:1574:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1576:5:1576:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1576:5:1576:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1576:5:1576:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1576:5:1576:5 | b [element] | semmle.label | b [element] | -| array_flow.rb:1576:9:1576:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1576:9:1576:9 | a [element 1] | semmle.label | a [element 1] | -| array_flow.rb:1576:9:1576:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1576:9:1576:9 | a [element 3] | semmle.label | a [element 3] | -| array_flow.rb:1576:9:1576:28 | call to values_at [element 1] | semmle.label | call to values_at [element 1] | -| array_flow.rb:1576:9:1576:28 | call to values_at [element 1] | semmle.label | call to values_at [element 1] | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] | semmle.label | call to values_at [element] | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] | semmle.label | call to values_at [element] | -| array_flow.rb:1577:10:1577:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1577:10:1577:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1567:10:1567:10 | a [element 5] | semmle.label | a [element 5] | +| array_flow.rb:1567:10:1567:10 | a [element 5] | semmle.label | a [element 5] | +| array_flow.rb:1567:10:1567:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1567:10:1567:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1571:5:1571:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1571:5:1571:5 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1571:13:1571:25 | call to source | semmle.label | call to source | +| array_flow.rb:1571:13:1571:25 | call to source | semmle.label | call to source | +| array_flow.rb:1571:31:1571:43 | call to source | semmle.label | call to source | +| array_flow.rb:1571:31:1571:43 | call to source | semmle.label | call to source | +| array_flow.rb:1573:5:1573:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1573:5:1573:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1573:5:1573:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1573:5:1573:5 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1573:9:1573:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1573:9:1573:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1573:9:1573:31 | call to values_at [element 1] | semmle.label | call to values_at [element 1] | +| array_flow.rb:1573:9:1573:31 | call to values_at [element 1] | semmle.label | call to values_at [element 1] | +| array_flow.rb:1573:9:1573:31 | call to values_at [element 3] | semmle.label | call to values_at [element 3] | +| array_flow.rb:1573:9:1573:31 | call to values_at [element 3] | semmle.label | call to values_at [element 3] | +| array_flow.rb:1575:10:1575:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1575:10:1575:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1575:10:1575:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1575:10:1575:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1577:10:1577:10 | b [element 3] | semmle.label | b [element 3] | +| array_flow.rb:1577:10:1577:10 | b [element 3] | semmle.label | b [element 3] | | array_flow.rb:1577:10:1577:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1577:10:1577:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1578:10:1578:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1578:10:1578:10 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1578:10:1578:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1578:10:1578:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1578:10:1578:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1578:10:1578:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1579:10:1579:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1579:10:1579:10 | b [element] | semmle.label | b [element] | -| array_flow.rb:1579:10:1579:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1579:10:1579:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1579:5:1579:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1579:5:1579:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1579:9:1579:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1579:9:1579:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1579:9:1579:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1579:9:1579:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1579:9:1579:25 | call to values_at [element] | semmle.label | call to values_at [element] | +| array_flow.rb:1579:9:1579:25 | call to values_at [element] | semmle.label | call to values_at [element] | | array_flow.rb:1580:10:1580:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1580:10:1580:10 | b [element] | semmle.label | b [element] | | array_flow.rb:1580:10:1580:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1580:10:1580:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1584:5:1584:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1584:5:1584:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1584:16:1584:28 | call to source | semmle.label | call to source | -| array_flow.rb:1584:16:1584:28 | call to source | semmle.label | call to source | -| array_flow.rb:1585:5:1585:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1585:5:1585:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1585:13:1585:25 | call to source | semmle.label | call to source | -| array_flow.rb:1585:13:1585:25 | call to source | semmle.label | call to source | -| array_flow.rb:1586:5:1586:5 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:1586:5:1586:5 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:1586:10:1586:22 | call to source | semmle.label | call to source | -| array_flow.rb:1586:10:1586:22 | call to source | semmle.label | call to source | -| array_flow.rb:1587:5:1587:5 | d [element 0, element 2] | semmle.label | d [element 0, element 2] | -| array_flow.rb:1587:5:1587:5 | d [element 0, element 2] | semmle.label | d [element 0, element 2] | -| array_flow.rb:1587:5:1587:5 | d [element 1, element 1] | semmle.label | d [element 1, element 1] | -| array_flow.rb:1587:5:1587:5 | d [element 1, element 1] | semmle.label | d [element 1, element 1] | -| array_flow.rb:1587:5:1587:5 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:1587:5:1587:5 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:1587:9:1587:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1587:9:1587:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] | semmle.label | call to zip [element 0, element 2] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] | semmle.label | call to zip [element 0, element 2] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] | semmle.label | call to zip [element 1, element 1] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] | semmle.label | call to zip [element 1, element 1] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] | semmle.label | call to zip [element 2, element 0] | -| array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] | semmle.label | call to zip [element 2, element 0] | -| array_flow.rb:1587:15:1587:15 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1587:15:1587:15 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1587:18:1587:18 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:1587:18:1587:18 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:1589:10:1589:10 | d [element 0, element 2] | semmle.label | d [element 0, element 2] | -| array_flow.rb:1589:10:1589:10 | d [element 0, element 2] | semmle.label | d [element 0, element 2] | -| array_flow.rb:1589:10:1589:13 | ...[...] [element 2] | semmle.label | ...[...] [element 2] | -| array_flow.rb:1589:10:1589:13 | ...[...] [element 2] | semmle.label | ...[...] [element 2] | -| array_flow.rb:1589:10:1589:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1589:10:1589:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1590:10:1590:10 | d [element 1, element 1] | semmle.label | d [element 1, element 1] | -| array_flow.rb:1590:10:1590:10 | d [element 1, element 1] | semmle.label | d [element 1, element 1] | -| array_flow.rb:1590:10:1590:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:1590:10:1590:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | -| array_flow.rb:1590:10:1590:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1590:10:1590:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1591:10:1591:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:1591:10:1591:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | -| array_flow.rb:1591:10:1591:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1591:10:1591:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1591:10:1591:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1591:10:1591:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1592:5:1592:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1592:5:1592:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1592:11:1592:11 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1592:11:1592:11 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1592:14:1592:14 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:1592:14:1592:14 | c [element 0] | semmle.label | c [element 0] | -| array_flow.rb:1592:21:1592:21 | x [element 0] | semmle.label | x [element 0] | -| array_flow.rb:1592:21:1592:21 | x [element 0] | semmle.label | x [element 0] | -| array_flow.rb:1592:21:1592:21 | x [element 1] | semmle.label | x [element 1] | -| array_flow.rb:1592:21:1592:21 | x [element 1] | semmle.label | x [element 1] | -| array_flow.rb:1592:21:1592:21 | x [element 2] | semmle.label | x [element 2] | -| array_flow.rb:1592:21:1592:21 | x [element 2] | semmle.label | x [element 2] | -| array_flow.rb:1593:14:1593:14 | x [element 0] | semmle.label | x [element 0] | -| array_flow.rb:1593:14:1593:14 | x [element 0] | semmle.label | x [element 0] | -| array_flow.rb:1593:14:1593:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1593:14:1593:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1594:14:1594:14 | x [element 1] | semmle.label | x [element 1] | -| array_flow.rb:1594:14:1594:14 | x [element 1] | semmle.label | x [element 1] | -| array_flow.rb:1594:14:1594:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1594:14:1594:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1595:14:1595:14 | x [element 2] | semmle.label | x [element 2] | -| array_flow.rb:1595:14:1595:14 | x [element 2] | semmle.label | x [element 2] | -| array_flow.rb:1595:14:1595:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1595:14:1595:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1600:5:1600:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1600:5:1600:5 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1600:16:1600:28 | call to source | semmle.label | call to source | -| array_flow.rb:1600:16:1600:28 | call to source | semmle.label | call to source | -| array_flow.rb:1601:5:1601:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1601:5:1601:5 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1601:13:1601:25 | call to source | semmle.label | call to source | -| array_flow.rb:1601:13:1601:25 | call to source | semmle.label | call to source | -| array_flow.rb:1602:5:1602:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:1602:5:1602:5 | c [element] | semmle.label | c [element] | -| array_flow.rb:1602:9:1602:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1602:9:1602:9 | a [element 2] | semmle.label | a [element 2] | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] | semmle.label | ... \| ... [element] | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] | semmle.label | ... \| ... [element] | -| array_flow.rb:1602:13:1602:13 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1602:13:1602:13 | b [element 1] | semmle.label | b [element 1] | -| array_flow.rb:1603:10:1603:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1603:10:1603:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1603:10:1603:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1603:10:1603:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1604:10:1604:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1604:10:1604:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1604:10:1604:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1604:10:1604:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1605:10:1605:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1605:10:1605:10 | c [element] | semmle.label | c [element] | -| array_flow.rb:1605:10:1605:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1605:10:1605:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | semmle.label | [post] a [element, element 0] | -| array_flow.rb:1610:5:1610:5 | [post] a [element, element 0] | semmle.label | [post] a [element, element 0] | -| array_flow.rb:1610:5:1610:8 | [post] ...[...] [element 0] | semmle.label | [post] ...[...] [element 0] | -| array_flow.rb:1610:5:1610:8 | [post] ...[...] [element 0] | semmle.label | [post] ...[...] [element 0] | -| array_flow.rb:1610:15:1610:27 | call to source | semmle.label | call to source | -| array_flow.rb:1610:15:1610:27 | call to source | semmle.label | call to source | -| array_flow.rb:1611:10:1611:10 | a [element, element 0] | semmle.label | a [element, element 0] | -| array_flow.rb:1611:10:1611:10 | a [element, element 0] | semmle.label | a [element, element 0] | -| array_flow.rb:1611:10:1611:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1611:10:1611:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1611:10:1611:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1611:10:1611:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1613:5:1613:5 | [post] a [element 1, element 0] | semmle.label | [post] a [element 1, element 0] | -| array_flow.rb:1613:5:1613:5 | [post] a [element 1, element 0] | semmle.label | [post] a [element 1, element 0] | -| array_flow.rb:1613:5:1613:8 | [post] ...[...] [element 0] | semmle.label | [post] ...[...] [element 0] | -| array_flow.rb:1613:5:1613:8 | [post] ...[...] [element 0] | semmle.label | [post] ...[...] [element 0] | -| array_flow.rb:1613:15:1613:27 | call to source | semmle.label | call to source | -| array_flow.rb:1613:15:1613:27 | call to source | semmle.label | call to source | -| array_flow.rb:1614:10:1614:10 | a [element 1, element 0] | semmle.label | a [element 1, element 0] | -| array_flow.rb:1614:10:1614:10 | a [element 1, element 0] | semmle.label | a [element 1, element 0] | -| array_flow.rb:1614:10:1614:10 | a [element, element 0] | semmle.label | a [element, element 0] | -| array_flow.rb:1614:10:1614:10 | a [element, element 0] | semmle.label | a [element, element 0] | -| array_flow.rb:1614:10:1614:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1614:10:1614:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1614:10:1614:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1614:10:1614:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1615:10:1615:10 | a [element, element 0] | semmle.label | a [element, element 0] | -| array_flow.rb:1615:10:1615:10 | a [element, element 0] | semmle.label | a [element, element 0] | -| array_flow.rb:1615:10:1615:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1615:10:1615:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | -| array_flow.rb:1615:10:1615:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1615:10:1615:16 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1620:5:1620:5 | [post] a [element 0] | semmle.label | [post] a [element 0] | -| array_flow.rb:1620:5:1620:5 | [post] a [element 0] | semmle.label | [post] a [element 0] | -| array_flow.rb:1620:12:1620:24 | call to source | semmle.label | call to source | -| array_flow.rb:1620:12:1620:24 | call to source | semmle.label | call to source | -| array_flow.rb:1622:5:1622:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1622:5:1622:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1622:16:1622:28 | call to source | semmle.label | call to source | -| array_flow.rb:1622:16:1622:28 | call to source | semmle.label | call to source | -| array_flow.rb:1624:5:1624:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1624:5:1624:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1624:14:1624:26 | call to source | semmle.label | call to source | -| array_flow.rb:1624:14:1624:26 | call to source | semmle.label | call to source | -| array_flow.rb:1626:5:1626:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1626:5:1626:5 | [post] a [element] | semmle.label | [post] a [element] | -| array_flow.rb:1626:16:1626:28 | call to source | semmle.label | call to source | -| array_flow.rb:1626:16:1626:28 | call to source | semmle.label | call to source | -| array_flow.rb:1627:10:1627:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1627:10:1627:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1627:10:1627:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1627:10:1627:13 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1629:10:1629:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1629:10:1629:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1629:10:1629:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1629:10:1629:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1629:10:1629:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1629:10:1629:17 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1631:10:1631:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1631:10:1631:10 | a [element 0] | semmle.label | a [element 0] | -| array_flow.rb:1631:10:1631:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1631:10:1631:10 | a [element] | semmle.label | a [element] | -| array_flow.rb:1631:10:1631:15 | ...[...] | semmle.label | ...[...] | -| array_flow.rb:1631:10:1631:15 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1581:10:1581:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1581:10:1581:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1581:10:1581:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1581:10:1581:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1583:5:1583:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1583:5:1583:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1583:9:1583:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1583:9:1583:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1583:9:1583:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1583:9:1583:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1583:9:1583:26 | call to values_at [element] | semmle.label | call to values_at [element] | +| array_flow.rb:1583:9:1583:26 | call to values_at [element] | semmle.label | call to values_at [element] | +| array_flow.rb:1584:10:1584:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1584:10:1584:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1584:10:1584:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1584:10:1584:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1585:10:1585:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1585:10:1585:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1585:10:1585:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1585:10:1585:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1587:5:1587:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1587:5:1587:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1587:5:1587:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1587:5:1587:5 | b [element] | semmle.label | b [element] | +| array_flow.rb:1587:9:1587:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1587:9:1587:9 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1587:9:1587:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1587:9:1587:9 | a [element 3] | semmle.label | a [element 3] | +| array_flow.rb:1587:9:1587:28 | call to values_at [element 1] | semmle.label | call to values_at [element 1] | +| array_flow.rb:1587:9:1587:28 | call to values_at [element 1] | semmle.label | call to values_at [element 1] | +| array_flow.rb:1587:9:1587:28 | call to values_at [element] | semmle.label | call to values_at [element] | +| array_flow.rb:1587:9:1587:28 | call to values_at [element] | semmle.label | call to values_at [element] | +| array_flow.rb:1588:10:1588:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1588:10:1588:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1588:10:1588:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1588:10:1588:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1589:10:1589:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1589:10:1589:10 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1589:10:1589:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1589:10:1589:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1589:10:1589:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1589:10:1589:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1590:10:1590:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1590:10:1590:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1590:10:1590:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1590:10:1590:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1591:10:1591:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1591:10:1591:10 | b [element] | semmle.label | b [element] | +| array_flow.rb:1591:10:1591:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1591:10:1591:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1595:5:1595:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1595:5:1595:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1595:16:1595:28 | call to source | semmle.label | call to source | +| array_flow.rb:1595:16:1595:28 | call to source | semmle.label | call to source | +| array_flow.rb:1596:5:1596:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1596:5:1596:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1596:13:1596:25 | call to source | semmle.label | call to source | +| array_flow.rb:1596:13:1596:25 | call to source | semmle.label | call to source | +| array_flow.rb:1597:5:1597:5 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:1597:5:1597:5 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:1597:10:1597:22 | call to source | semmle.label | call to source | +| array_flow.rb:1597:10:1597:22 | call to source | semmle.label | call to source | +| array_flow.rb:1598:5:1598:5 | d [element 0, element 2] | semmle.label | d [element 0, element 2] | +| array_flow.rb:1598:5:1598:5 | d [element 0, element 2] | semmle.label | d [element 0, element 2] | +| array_flow.rb:1598:5:1598:5 | d [element 1, element 1] | semmle.label | d [element 1, element 1] | +| array_flow.rb:1598:5:1598:5 | d [element 1, element 1] | semmle.label | d [element 1, element 1] | +| array_flow.rb:1598:5:1598:5 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:1598:5:1598:5 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:1598:9:1598:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1598:9:1598:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 0, element 2] | semmle.label | call to zip [element 0, element 2] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 0, element 2] | semmle.label | call to zip [element 0, element 2] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 1, element 1] | semmle.label | call to zip [element 1, element 1] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 1, element 1] | semmle.label | call to zip [element 1, element 1] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 2, element 0] | semmle.label | call to zip [element 2, element 0] | +| array_flow.rb:1598:9:1598:19 | call to zip [element 2, element 0] | semmle.label | call to zip [element 2, element 0] | +| array_flow.rb:1598:15:1598:15 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1598:15:1598:15 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1598:18:1598:18 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:1598:18:1598:18 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:1600:10:1600:10 | d [element 0, element 2] | semmle.label | d [element 0, element 2] | +| array_flow.rb:1600:10:1600:10 | d [element 0, element 2] | semmle.label | d [element 0, element 2] | +| array_flow.rb:1600:10:1600:13 | ...[...] [element 2] | semmle.label | ...[...] [element 2] | +| array_flow.rb:1600:10:1600:13 | ...[...] [element 2] | semmle.label | ...[...] [element 2] | +| array_flow.rb:1600:10:1600:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1600:10:1600:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1601:10:1601:10 | d [element 1, element 1] | semmle.label | d [element 1, element 1] | +| array_flow.rb:1601:10:1601:10 | d [element 1, element 1] | semmle.label | d [element 1, element 1] | +| array_flow.rb:1601:10:1601:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:1601:10:1601:13 | ...[...] [element 1] | semmle.label | ...[...] [element 1] | +| array_flow.rb:1601:10:1601:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1601:10:1601:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1602:10:1602:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:1602:10:1602:10 | d [element 2, element 0] | semmle.label | d [element 2, element 0] | +| array_flow.rb:1602:10:1602:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1602:10:1602:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1602:10:1602:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1602:10:1602:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1603:5:1603:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1603:5:1603:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1603:11:1603:11 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1603:11:1603:11 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1603:14:1603:14 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:1603:14:1603:14 | c [element 0] | semmle.label | c [element 0] | +| array_flow.rb:1603:21:1603:21 | x [element 0] | semmle.label | x [element 0] | +| array_flow.rb:1603:21:1603:21 | x [element 0] | semmle.label | x [element 0] | +| array_flow.rb:1603:21:1603:21 | x [element 1] | semmle.label | x [element 1] | +| array_flow.rb:1603:21:1603:21 | x [element 1] | semmle.label | x [element 1] | +| array_flow.rb:1603:21:1603:21 | x [element 2] | semmle.label | x [element 2] | +| array_flow.rb:1603:21:1603:21 | x [element 2] | semmle.label | x [element 2] | +| array_flow.rb:1604:14:1604:14 | x [element 0] | semmle.label | x [element 0] | +| array_flow.rb:1604:14:1604:14 | x [element 0] | semmle.label | x [element 0] | +| array_flow.rb:1604:14:1604:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1604:14:1604:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1605:14:1605:14 | x [element 1] | semmle.label | x [element 1] | +| array_flow.rb:1605:14:1605:14 | x [element 1] | semmle.label | x [element 1] | +| array_flow.rb:1605:14:1605:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1605:14:1605:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1606:14:1606:14 | x [element 2] | semmle.label | x [element 2] | +| array_flow.rb:1606:14:1606:14 | x [element 2] | semmle.label | x [element 2] | +| array_flow.rb:1606:14:1606:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1606:14:1606:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1611:5:1611:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1611:5:1611:5 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1611:16:1611:28 | call to source | semmle.label | call to source | +| array_flow.rb:1611:16:1611:28 | call to source | semmle.label | call to source | +| array_flow.rb:1612:5:1612:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1612:5:1612:5 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1612:13:1612:25 | call to source | semmle.label | call to source | +| array_flow.rb:1612:13:1612:25 | call to source | semmle.label | call to source | +| array_flow.rb:1613:5:1613:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:1613:5:1613:5 | c [element] | semmle.label | c [element] | +| array_flow.rb:1613:9:1613:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1613:9:1613:9 | a [element 2] | semmle.label | a [element 2] | +| array_flow.rb:1613:9:1613:13 | ... \| ... [element] | semmle.label | ... \| ... [element] | +| array_flow.rb:1613:9:1613:13 | ... \| ... [element] | semmle.label | ... \| ... [element] | +| array_flow.rb:1613:13:1613:13 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1613:13:1613:13 | b [element 1] | semmle.label | b [element 1] | +| array_flow.rb:1614:10:1614:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1614:10:1614:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1614:10:1614:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1614:10:1614:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1615:10:1615:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1615:10:1615:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1615:10:1615:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1615:10:1615:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1616:10:1616:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1616:10:1616:10 | c [element] | semmle.label | c [element] | +| array_flow.rb:1616:10:1616:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1616:10:1616:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | semmle.label | [post] a [element, element 0] | +| array_flow.rb:1621:5:1621:5 | [post] a [element, element 0] | semmle.label | [post] a [element, element 0] | +| array_flow.rb:1621:5:1621:8 | [post] ...[...] [element 0] | semmle.label | [post] ...[...] [element 0] | +| array_flow.rb:1621:5:1621:8 | [post] ...[...] [element 0] | semmle.label | [post] ...[...] [element 0] | +| array_flow.rb:1621:15:1621:27 | call to source | semmle.label | call to source | +| array_flow.rb:1621:15:1621:27 | call to source | semmle.label | call to source | +| array_flow.rb:1622:10:1622:10 | a [element, element 0] | semmle.label | a [element, element 0] | +| array_flow.rb:1622:10:1622:10 | a [element, element 0] | semmle.label | a [element, element 0] | +| array_flow.rb:1622:10:1622:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1622:10:1622:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1622:10:1622:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1622:10:1622:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1624:5:1624:5 | [post] a [element 1, element 0] | semmle.label | [post] a [element 1, element 0] | +| array_flow.rb:1624:5:1624:5 | [post] a [element 1, element 0] | semmle.label | [post] a [element 1, element 0] | +| array_flow.rb:1624:5:1624:8 | [post] ...[...] [element 0] | semmle.label | [post] ...[...] [element 0] | +| array_flow.rb:1624:5:1624:8 | [post] ...[...] [element 0] | semmle.label | [post] ...[...] [element 0] | +| array_flow.rb:1624:15:1624:27 | call to source | semmle.label | call to source | +| array_flow.rb:1624:15:1624:27 | call to source | semmle.label | call to source | +| array_flow.rb:1625:10:1625:10 | a [element 1, element 0] | semmle.label | a [element 1, element 0] | +| array_flow.rb:1625:10:1625:10 | a [element 1, element 0] | semmle.label | a [element 1, element 0] | +| array_flow.rb:1625:10:1625:10 | a [element, element 0] | semmle.label | a [element, element 0] | +| array_flow.rb:1625:10:1625:10 | a [element, element 0] | semmle.label | a [element, element 0] | +| array_flow.rb:1625:10:1625:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1625:10:1625:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1625:10:1625:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1625:10:1625:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1626:10:1626:10 | a [element, element 0] | semmle.label | a [element, element 0] | +| array_flow.rb:1626:10:1626:10 | a [element, element 0] | semmle.label | a [element, element 0] | +| array_flow.rb:1626:10:1626:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1626:10:1626:13 | ...[...] [element 0] | semmle.label | ...[...] [element 0] | +| array_flow.rb:1626:10:1626:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1626:10:1626:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1631:5:1631:5 | [post] a [element 0] | semmle.label | [post] a [element 0] | +| array_flow.rb:1631:5:1631:5 | [post] a [element 0] | semmle.label | [post] a [element 0] | +| array_flow.rb:1631:12:1631:24 | call to source | semmle.label | call to source | +| array_flow.rb:1631:12:1631:24 | call to source | semmle.label | call to source | +| array_flow.rb:1633:5:1633:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1633:5:1633:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1633:16:1633:28 | call to source | semmle.label | call to source | +| array_flow.rb:1633:16:1633:28 | call to source | semmle.label | call to source | +| array_flow.rb:1635:5:1635:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1635:5:1635:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1635:14:1635:26 | call to source | semmle.label | call to source | +| array_flow.rb:1635:14:1635:26 | call to source | semmle.label | call to source | +| array_flow.rb:1637:5:1637:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1637:5:1637:5 | [post] a [element] | semmle.label | [post] a [element] | +| array_flow.rb:1637:16:1637:28 | call to source | semmle.label | call to source | +| array_flow.rb:1637:16:1637:28 | call to source | semmle.label | call to source | +| array_flow.rb:1638:10:1638:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1638:10:1638:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1638:10:1638:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1638:10:1638:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1640:10:1640:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1640:10:1640:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1640:10:1640:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1640:10:1640:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1640:10:1640:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1640:10:1640:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1642:10:1642:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1642:10:1642:10 | a [element 0] | semmle.label | a [element 0] | +| array_flow.rb:1642:10:1642:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1642:10:1642:10 | a [element] | semmle.label | a [element] | +| array_flow.rb:1642:10:1642:15 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1642:10:1642:15 | ...[...] | semmle.label | ...[...] | subpaths #select | array_flow.rb:3:10:3:13 | ...[...] | array_flow.rb:2:10:2:20 | call to source | array_flow.rb:3:10:3:13 | ...[...] | $@ | array_flow.rb:2:10:2:20 | call to source | call to source | @@ -8904,531 +8922,532 @@ subpaths | array_flow.rb:500:14:500:14 | x | array_flow.rb:498:19:498:28 | call to source | array_flow.rb:500:14:500:14 | x | $@ | array_flow.rb:498:19:498:28 | call to source | call to source | | array_flow.rb:502:10:502:13 | ...[...] | array_flow.rb:498:19:498:28 | call to source | array_flow.rb:502:10:502:13 | ...[...] | $@ | array_flow.rb:498:19:498:28 | call to source | call to source | | array_flow.rb:508:14:508:14 | x | array_flow.rb:506:19:506:28 | call to source | array_flow.rb:508:14:508:14 | x | $@ | array_flow.rb:506:19:506:28 | call to source | call to source | -| array_flow.rb:510:10:510:13 | ...[...] | array_flow.rb:506:19:506:28 | call to source | array_flow.rb:510:10:510:13 | ...[...] | $@ | array_flow.rb:506:19:506:28 | call to source | call to source | -| array_flow.rb:516:14:516:14 | x | array_flow.rb:514:19:514:28 | call to source | array_flow.rb:516:14:516:14 | x | $@ | array_flow.rb:514:19:514:28 | call to source | call to source | -| array_flow.rb:519:10:519:13 | ...[...] | array_flow.rb:514:19:514:28 | call to source | array_flow.rb:519:10:519:13 | ...[...] | $@ | array_flow.rb:514:19:514:28 | call to source | call to source | -| array_flow.rb:520:10:520:13 | ...[...] | array_flow.rb:514:19:514:28 | call to source | array_flow.rb:520:10:520:13 | ...[...] | $@ | array_flow.rb:514:19:514:28 | call to source | call to source | -| array_flow.rb:526:14:526:14 | x | array_flow.rb:524:19:524:30 | call to source | array_flow.rb:526:14:526:14 | x | $@ | array_flow.rb:524:19:524:30 | call to source | call to source | -| array_flow.rb:528:10:528:10 | b | array_flow.rb:524:19:524:30 | call to source | array_flow.rb:528:10:528:10 | b | $@ | array_flow.rb:524:19:524:30 | call to source | call to source | -| array_flow.rb:528:10:528:10 | b | array_flow.rb:525:21:525:32 | call to source | array_flow.rb:528:10:528:10 | b | $@ | array_flow.rb:525:21:525:32 | call to source | call to source | -| array_flow.rb:534:14:534:14 | x | array_flow.rb:532:19:532:28 | call to source | array_flow.rb:534:14:534:14 | x | $@ | array_flow.rb:532:19:532:28 | call to source | call to source | -| array_flow.rb:536:10:536:13 | ...[...] | array_flow.rb:532:19:532:28 | call to source | array_flow.rb:536:10:536:13 | ...[...] | $@ | array_flow.rb:532:19:532:28 | call to source | call to source | -| array_flow.rb:542:14:542:14 | x | array_flow.rb:540:19:540:28 | call to source | array_flow.rb:542:14:542:14 | x | $@ | array_flow.rb:540:19:540:28 | call to source | call to source | -| array_flow.rb:549:10:549:16 | call to first | array_flow.rb:547:10:547:21 | call to source | array_flow.rb:549:10:549:16 | call to first | $@ | array_flow.rb:547:10:547:21 | call to source | call to source | -| array_flow.rb:549:10:549:16 | call to first | array_flow.rb:548:12:548:23 | call to source | array_flow.rb:549:10:549:16 | call to first | $@ | array_flow.rb:548:12:548:23 | call to source | call to source | -| array_flow.rb:551:10:551:13 | ...[...] | array_flow.rb:547:10:547:21 | call to source | array_flow.rb:551:10:551:13 | ...[...] | $@ | array_flow.rb:547:10:547:21 | call to source | call to source | -| array_flow.rb:551:10:551:13 | ...[...] | array_flow.rb:548:12:548:23 | call to source | array_flow.rb:551:10:551:13 | ...[...] | $@ | array_flow.rb:548:12:548:23 | call to source | call to source | -| array_flow.rb:552:10:552:13 | ...[...] | array_flow.rb:548:12:548:23 | call to source | array_flow.rb:552:10:552:13 | ...[...] | $@ | array_flow.rb:548:12:548:23 | call to source | call to source | -| array_flow.rb:554:10:554:13 | ...[...] | array_flow.rb:547:10:547:21 | call to source | array_flow.rb:554:10:554:13 | ...[...] | $@ | array_flow.rb:547:10:547:21 | call to source | call to source | -| array_flow.rb:554:10:554:13 | ...[...] | array_flow.rb:548:12:548:23 | call to source | array_flow.rb:554:10:554:13 | ...[...] | $@ | array_flow.rb:548:12:548:23 | call to source | call to source | -| array_flow.rb:555:10:555:13 | ...[...] | array_flow.rb:547:30:547:41 | call to source | array_flow.rb:555:10:555:13 | ...[...] | $@ | array_flow.rb:547:30:547:41 | call to source | call to source | -| array_flow.rb:555:10:555:13 | ...[...] | array_flow.rb:548:12:548:23 | call to source | array_flow.rb:555:10:555:13 | ...[...] | $@ | array_flow.rb:548:12:548:23 | call to source | call to source | -| array_flow.rb:561:14:561:14 | x | array_flow.rb:559:16:559:27 | call to source | array_flow.rb:561:14:561:14 | x | $@ | array_flow.rb:559:16:559:27 | call to source | call to source | -| array_flow.rb:564:10:564:13 | ...[...] | array_flow.rb:559:16:559:27 | call to source | array_flow.rb:564:10:564:13 | ...[...] | $@ | array_flow.rb:559:16:559:27 | call to source | call to source | -| array_flow.rb:564:10:564:13 | ...[...] | array_flow.rb:562:13:562:24 | call to source | array_flow.rb:564:10:564:13 | ...[...] | $@ | array_flow.rb:562:13:562:24 | call to source | call to source | -| array_flow.rb:566:14:566:14 | x | array_flow.rb:559:16:559:27 | call to source | array_flow.rb:566:14:566:14 | x | $@ | array_flow.rb:559:16:559:27 | call to source | call to source | -| array_flow.rb:569:10:569:13 | ...[...] | array_flow.rb:567:9:567:20 | call to source | array_flow.rb:569:10:569:13 | ...[...] | $@ | array_flow.rb:567:9:567:20 | call to source | call to source | -| array_flow.rb:575:10:575:13 | ...[...] | array_flow.rb:573:20:573:29 | call to source | array_flow.rb:575:10:575:13 | ...[...] | $@ | array_flow.rb:573:20:573:29 | call to source | call to source | -| array_flow.rb:580:10:580:16 | ...[...] | array_flow.rb:579:20:579:29 | call to source | array_flow.rb:580:10:580:16 | ...[...] | $@ | array_flow.rb:579:20:579:29 | call to source | call to source | -| array_flow.rb:582:10:582:13 | ...[...] | array_flow.rb:579:20:579:29 | call to source | array_flow.rb:582:10:582:13 | ...[...] | $@ | array_flow.rb:579:20:579:29 | call to source | call to source | -| array_flow.rb:583:10:583:16 | ...[...] | array_flow.rb:579:20:579:29 | call to source | array_flow.rb:583:10:583:16 | ...[...] | $@ | array_flow.rb:579:20:579:29 | call to source | call to source | -| array_flow.rb:584:10:584:13 | ...[...] | array_flow.rb:579:20:579:29 | call to source | array_flow.rb:584:10:584:13 | ...[...] | $@ | array_flow.rb:579:20:579:29 | call to source | call to source | -| array_flow.rb:585:10:585:16 | ...[...] | array_flow.rb:579:20:579:29 | call to source | array_flow.rb:585:10:585:16 | ...[...] | $@ | array_flow.rb:579:20:579:29 | call to source | call to source | -| array_flow.rb:591:10:591:13 | ...[...] | array_flow.rb:589:19:589:30 | call to source | array_flow.rb:591:10:591:13 | ...[...] | $@ | array_flow.rb:589:19:589:30 | call to source | call to source | -| array_flow.rb:593:14:593:14 | x | array_flow.rb:589:19:589:30 | call to source | array_flow.rb:593:14:593:14 | x | $@ | array_flow.rb:589:19:589:30 | call to source | call to source | -| array_flow.rb:596:10:596:13 | ...[...] | array_flow.rb:594:9:594:20 | call to source | array_flow.rb:596:10:596:13 | ...[...] | $@ | array_flow.rb:594:9:594:20 | call to source | call to source | +| array_flow.rb:511:10:511:13 | ...[...] | array_flow.rb:506:19:506:28 | call to source | array_flow.rb:511:10:511:13 | ...[...] | $@ | array_flow.rb:506:19:506:28 | call to source | call to source | +| array_flow.rb:521:10:521:13 | ...[...] | array_flow.rb:519:9:519:20 | call to source | array_flow.rb:521:10:521:13 | ...[...] | $@ | array_flow.rb:519:9:519:20 | call to source | call to source | +| array_flow.rb:527:14:527:14 | x | array_flow.rb:525:19:525:28 | call to source | array_flow.rb:527:14:527:14 | x | $@ | array_flow.rb:525:19:525:28 | call to source | call to source | +| array_flow.rb:530:10:530:13 | ...[...] | array_flow.rb:525:19:525:28 | call to source | array_flow.rb:530:10:530:13 | ...[...] | $@ | array_flow.rb:525:19:525:28 | call to source | call to source | +| array_flow.rb:531:10:531:13 | ...[...] | array_flow.rb:525:19:525:28 | call to source | array_flow.rb:531:10:531:13 | ...[...] | $@ | array_flow.rb:525:19:525:28 | call to source | call to source | +| array_flow.rb:537:14:537:14 | x | array_flow.rb:535:19:535:30 | call to source | array_flow.rb:537:14:537:14 | x | $@ | array_flow.rb:535:19:535:30 | call to source | call to source | +| array_flow.rb:539:10:539:10 | b | array_flow.rb:535:19:535:30 | call to source | array_flow.rb:539:10:539:10 | b | $@ | array_flow.rb:535:19:535:30 | call to source | call to source | +| array_flow.rb:539:10:539:10 | b | array_flow.rb:536:21:536:32 | call to source | array_flow.rb:539:10:539:10 | b | $@ | array_flow.rb:536:21:536:32 | call to source | call to source | +| array_flow.rb:545:14:545:14 | x | array_flow.rb:543:19:543:28 | call to source | array_flow.rb:545:14:545:14 | x | $@ | array_flow.rb:543:19:543:28 | call to source | call to source | +| array_flow.rb:547:10:547:13 | ...[...] | array_flow.rb:543:19:543:28 | call to source | array_flow.rb:547:10:547:13 | ...[...] | $@ | array_flow.rb:543:19:543:28 | call to source | call to source | +| array_flow.rb:553:14:553:14 | x | array_flow.rb:551:19:551:28 | call to source | array_flow.rb:553:14:553:14 | x | $@ | array_flow.rb:551:19:551:28 | call to source | call to source | +| array_flow.rb:560:10:560:16 | call to first | array_flow.rb:558:10:558:21 | call to source | array_flow.rb:560:10:560:16 | call to first | $@ | array_flow.rb:558:10:558:21 | call to source | call to source | +| array_flow.rb:560:10:560:16 | call to first | array_flow.rb:559:12:559:23 | call to source | array_flow.rb:560:10:560:16 | call to first | $@ | array_flow.rb:559:12:559:23 | call to source | call to source | +| array_flow.rb:562:10:562:13 | ...[...] | array_flow.rb:558:10:558:21 | call to source | array_flow.rb:562:10:562:13 | ...[...] | $@ | array_flow.rb:558:10:558:21 | call to source | call to source | +| array_flow.rb:562:10:562:13 | ...[...] | array_flow.rb:559:12:559:23 | call to source | array_flow.rb:562:10:562:13 | ...[...] | $@ | array_flow.rb:559:12:559:23 | call to source | call to source | +| array_flow.rb:563:10:563:13 | ...[...] | array_flow.rb:559:12:559:23 | call to source | array_flow.rb:563:10:563:13 | ...[...] | $@ | array_flow.rb:559:12:559:23 | call to source | call to source | +| array_flow.rb:565:10:565:13 | ...[...] | array_flow.rb:558:10:558:21 | call to source | array_flow.rb:565:10:565:13 | ...[...] | $@ | array_flow.rb:558:10:558:21 | call to source | call to source | +| array_flow.rb:565:10:565:13 | ...[...] | array_flow.rb:559:12:559:23 | call to source | array_flow.rb:565:10:565:13 | ...[...] | $@ | array_flow.rb:559:12:559:23 | call to source | call to source | +| array_flow.rb:566:10:566:13 | ...[...] | array_flow.rb:558:30:558:41 | call to source | array_flow.rb:566:10:566:13 | ...[...] | $@ | array_flow.rb:558:30:558:41 | call to source | call to source | +| array_flow.rb:566:10:566:13 | ...[...] | array_flow.rb:559:12:559:23 | call to source | array_flow.rb:566:10:566:13 | ...[...] | $@ | array_flow.rb:559:12:559:23 | call to source | call to source | +| array_flow.rb:572:14:572:14 | x | array_flow.rb:570:16:570:27 | call to source | array_flow.rb:572:14:572:14 | x | $@ | array_flow.rb:570:16:570:27 | call to source | call to source | +| array_flow.rb:575:10:575:13 | ...[...] | array_flow.rb:570:16:570:27 | call to source | array_flow.rb:575:10:575:13 | ...[...] | $@ | array_flow.rb:570:16:570:27 | call to source | call to source | +| array_flow.rb:575:10:575:13 | ...[...] | array_flow.rb:573:13:573:24 | call to source | array_flow.rb:575:10:575:13 | ...[...] | $@ | array_flow.rb:573:13:573:24 | call to source | call to source | +| array_flow.rb:577:14:577:14 | x | array_flow.rb:570:16:570:27 | call to source | array_flow.rb:577:14:577:14 | x | $@ | array_flow.rb:570:16:570:27 | call to source | call to source | +| array_flow.rb:580:10:580:13 | ...[...] | array_flow.rb:578:9:578:20 | call to source | array_flow.rb:580:10:580:13 | ...[...] | $@ | array_flow.rb:578:9:578:20 | call to source | call to source | +| array_flow.rb:586:10:586:13 | ...[...] | array_flow.rb:584:20:584:29 | call to source | array_flow.rb:586:10:586:13 | ...[...] | $@ | array_flow.rb:584:20:584:29 | call to source | call to source | +| array_flow.rb:591:10:591:16 | ...[...] | array_flow.rb:590:20:590:29 | call to source | array_flow.rb:591:10:591:16 | ...[...] | $@ | array_flow.rb:590:20:590:29 | call to source | call to source | +| array_flow.rb:593:10:593:13 | ...[...] | array_flow.rb:590:20:590:29 | call to source | array_flow.rb:593:10:593:13 | ...[...] | $@ | array_flow.rb:590:20:590:29 | call to source | call to source | +| array_flow.rb:594:10:594:16 | ...[...] | array_flow.rb:590:20:590:29 | call to source | array_flow.rb:594:10:594:16 | ...[...] | $@ | array_flow.rb:590:20:590:29 | call to source | call to source | +| array_flow.rb:595:10:595:13 | ...[...] | array_flow.rb:590:20:590:29 | call to source | array_flow.rb:595:10:595:13 | ...[...] | $@ | array_flow.rb:590:20:590:29 | call to source | call to source | +| array_flow.rb:596:10:596:16 | ...[...] | array_flow.rb:590:20:590:29 | call to source | array_flow.rb:596:10:596:16 | ...[...] | $@ | array_flow.rb:590:20:590:29 | call to source | call to source | | array_flow.rb:602:10:602:13 | ...[...] | array_flow.rb:600:19:600:30 | call to source | array_flow.rb:602:10:602:13 | ...[...] | $@ | array_flow.rb:600:19:600:30 | call to source | call to source | | array_flow.rb:604:14:604:14 | x | array_flow.rb:600:19:600:30 | call to source | array_flow.rb:604:14:604:14 | x | $@ | array_flow.rb:600:19:600:30 | call to source | call to source | | array_flow.rb:607:10:607:13 | ...[...] | array_flow.rb:605:9:605:20 | call to source | array_flow.rb:607:10:607:13 | ...[...] | $@ | array_flow.rb:605:9:605:20 | call to source | call to source | -| array_flow.rb:613:14:613:14 | x | array_flow.rb:611:19:611:30 | call to source | array_flow.rb:613:14:613:14 | x | $@ | array_flow.rb:611:19:611:30 | call to source | call to source | -| array_flow.rb:622:14:622:14 | x | array_flow.rb:620:19:620:28 | call to source | array_flow.rb:622:14:622:14 | x | $@ | array_flow.rb:620:19:620:28 | call to source | call to source | -| array_flow.rb:629:14:629:14 | x | array_flow.rb:627:10:627:21 | call to source | array_flow.rb:629:14:629:14 | x | $@ | array_flow.rb:627:10:627:21 | call to source | call to source | -| array_flow.rb:630:14:630:14 | y | array_flow.rb:627:27:627:38 | call to source | array_flow.rb:630:14:630:14 | y | $@ | array_flow.rb:627:27:627:38 | call to source | call to source | -| array_flow.rb:633:10:633:10 | b | array_flow.rb:631:9:631:19 | call to source | array_flow.rb:633:10:633:10 | b | $@ | array_flow.rb:631:9:631:19 | call to source | call to source | -| array_flow.rb:636:14:636:14 | y | array_flow.rb:627:10:627:21 | call to source | array_flow.rb:636:14:636:14 | y | $@ | array_flow.rb:627:10:627:21 | call to source | call to source | -| array_flow.rb:636:14:636:14 | y | array_flow.rb:627:27:627:38 | call to source | array_flow.rb:636:14:636:14 | y | $@ | array_flow.rb:627:27:627:38 | call to source | call to source | -| array_flow.rb:639:10:639:10 | c | array_flow.rb:637:9:637:19 | call to source | array_flow.rb:639:10:639:10 | c | $@ | array_flow.rb:637:9:637:19 | call to source | call to source | -| array_flow.rb:647:10:647:13 | ...[...] | array_flow.rb:645:21:645:32 | call to source | array_flow.rb:647:10:647:13 | ...[...] | $@ | array_flow.rb:645:21:645:32 | call to source | call to source | -| array_flow.rb:648:10:648:13 | ...[...] | array_flow.rb:645:35:645:46 | call to source | array_flow.rb:648:10:648:13 | ...[...] | $@ | array_flow.rb:645:35:645:46 | call to source | call to source | -| array_flow.rb:650:10:650:13 | ...[...] | array_flow.rb:644:16:644:27 | call to source | array_flow.rb:650:10:650:13 | ...[...] | $@ | array_flow.rb:644:16:644:27 | call to source | call to source | -| array_flow.rb:652:10:652:13 | ...[...] | array_flow.rb:645:21:645:32 | call to source | array_flow.rb:652:10:652:13 | ...[...] | $@ | array_flow.rb:645:21:645:32 | call to source | call to source | -| array_flow.rb:653:10:653:13 | ...[...] | array_flow.rb:645:35:645:46 | call to source | array_flow.rb:653:10:653:13 | ...[...] | $@ | array_flow.rb:645:35:645:46 | call to source | call to source | -| array_flow.rb:655:10:655:13 | ...[...] | array_flow.rb:644:16:644:27 | call to source | array_flow.rb:655:10:655:13 | ...[...] | $@ | array_flow.rb:644:16:644:27 | call to source | call to source | -| array_flow.rb:660:10:660:13 | ...[...] | array_flow.rb:658:16:658:27 | call to source | array_flow.rb:660:10:660:13 | ...[...] | $@ | array_flow.rb:658:16:658:27 | call to source | call to source | -| array_flow.rb:660:10:660:13 | ...[...] | array_flow.rb:659:21:659:32 | call to source | array_flow.rb:660:10:660:13 | ...[...] | $@ | array_flow.rb:659:21:659:32 | call to source | call to source | -| array_flow.rb:660:10:660:13 | ...[...] | array_flow.rb:659:35:659:46 | call to source | array_flow.rb:660:10:660:13 | ...[...] | $@ | array_flow.rb:659:35:659:46 | call to source | call to source | -| array_flow.rb:661:10:661:13 | ...[...] | array_flow.rb:658:16:658:27 | call to source | array_flow.rb:661:10:661:13 | ...[...] | $@ | array_flow.rb:658:16:658:27 | call to source | call to source | -| array_flow.rb:661:10:661:13 | ...[...] | array_flow.rb:659:21:659:32 | call to source | array_flow.rb:661:10:661:13 | ...[...] | $@ | array_flow.rb:659:21:659:32 | call to source | call to source | -| array_flow.rb:661:10:661:13 | ...[...] | array_flow.rb:659:35:659:46 | call to source | array_flow.rb:661:10:661:13 | ...[...] | $@ | array_flow.rb:659:35:659:46 | call to source | call to source | -| array_flow.rb:674:10:674:13 | ...[...] | array_flow.rb:672:16:672:27 | call to source | array_flow.rb:674:10:674:13 | ...[...] | $@ | array_flow.rb:672:16:672:27 | call to source | call to source | -| array_flow.rb:674:10:674:13 | ...[...] | array_flow.rb:673:31:673:42 | call to source | array_flow.rb:674:10:674:13 | ...[...] | $@ | array_flow.rb:673:31:673:42 | call to source | call to source | -| array_flow.rb:674:10:674:13 | ...[...] | array_flow.rb:673:47:673:58 | call to source | array_flow.rb:674:10:674:13 | ...[...] | $@ | array_flow.rb:673:47:673:58 | call to source | call to source | -| array_flow.rb:680:14:680:14 | x | array_flow.rb:678:16:678:25 | call to source | array_flow.rb:680:14:680:14 | x | $@ | array_flow.rb:678:16:678:25 | call to source | call to source | -| array_flow.rb:683:10:683:13 | ...[...] | array_flow.rb:678:16:678:25 | call to source | array_flow.rb:683:10:683:13 | ...[...] | $@ | array_flow.rb:678:16:678:25 | call to source | call to source | -| array_flow.rb:684:10:684:13 | ...[...] | array_flow.rb:678:16:678:25 | call to source | array_flow.rb:684:10:684:13 | ...[...] | $@ | array_flow.rb:678:16:678:25 | call to source | call to source | -| array_flow.rb:690:10:690:15 | call to last | array_flow.rb:688:16:688:27 | call to source | array_flow.rb:690:10:690:15 | call to last | $@ | array_flow.rb:688:16:688:27 | call to source | call to source | -| array_flow.rb:690:10:690:15 | call to last | array_flow.rb:689:12:689:23 | call to source | array_flow.rb:690:10:690:15 | call to last | $@ | array_flow.rb:689:12:689:23 | call to source | call to source | -| array_flow.rb:692:10:692:13 | ...[...] | array_flow.rb:688:16:688:27 | call to source | array_flow.rb:692:10:692:13 | ...[...] | $@ | array_flow.rb:688:16:688:27 | call to source | call to source | -| array_flow.rb:692:10:692:13 | ...[...] | array_flow.rb:689:12:689:23 | call to source | array_flow.rb:692:10:692:13 | ...[...] | $@ | array_flow.rb:689:12:689:23 | call to source | call to source | -| array_flow.rb:693:10:693:13 | ...[...] | array_flow.rb:688:16:688:27 | call to source | array_flow.rb:693:10:693:13 | ...[...] | $@ | array_flow.rb:688:16:688:27 | call to source | call to source | -| array_flow.rb:693:10:693:13 | ...[...] | array_flow.rb:689:12:689:23 | call to source | array_flow.rb:693:10:693:13 | ...[...] | $@ | array_flow.rb:689:12:689:23 | call to source | call to source | -| array_flow.rb:699:14:699:14 | x | array_flow.rb:697:16:697:27 | call to source | array_flow.rb:699:14:699:14 | x | $@ | array_flow.rb:697:16:697:27 | call to source | call to source | -| array_flow.rb:702:10:702:13 | ...[...] | array_flow.rb:700:9:700:19 | call to source | array_flow.rb:702:10:702:13 | ...[...] | $@ | array_flow.rb:700:9:700:19 | call to source | call to source | -| array_flow.rb:708:14:708:14 | x | array_flow.rb:706:16:706:27 | call to source | array_flow.rb:708:14:708:14 | x | $@ | array_flow.rb:706:16:706:27 | call to source | call to source | -| array_flow.rb:711:10:711:13 | ...[...] | array_flow.rb:709:9:709:19 | call to source | array_flow.rb:711:10:711:13 | ...[...] | $@ | array_flow.rb:709:9:709:19 | call to source | call to source | -| array_flow.rb:719:10:719:10 | b | array_flow.rb:715:16:715:25 | call to source | array_flow.rb:719:10:719:10 | b | $@ | array_flow.rb:715:16:715:25 | call to source | call to source | -| array_flow.rb:723:10:723:13 | ...[...] | array_flow.rb:715:16:715:25 | call to source | array_flow.rb:723:10:723:13 | ...[...] | $@ | array_flow.rb:715:16:715:25 | call to source | call to source | -| array_flow.rb:727:14:727:14 | x | array_flow.rb:715:16:715:25 | call to source | array_flow.rb:727:14:727:14 | x | $@ | array_flow.rb:715:16:715:25 | call to source | call to source | -| array_flow.rb:728:14:728:14 | y | array_flow.rb:715:16:715:25 | call to source | array_flow.rb:728:14:728:14 | y | $@ | array_flow.rb:715:16:715:25 | call to source | call to source | -| array_flow.rb:731:10:731:10 | d | array_flow.rb:715:16:715:25 | call to source | array_flow.rb:731:10:731:10 | d | $@ | array_flow.rb:715:16:715:25 | call to source | call to source | -| array_flow.rb:735:14:735:14 | x | array_flow.rb:715:16:715:25 | call to source | array_flow.rb:735:14:735:14 | x | $@ | array_flow.rb:715:16:715:25 | call to source | call to source | -| array_flow.rb:736:14:736:14 | y | array_flow.rb:715:16:715:25 | call to source | array_flow.rb:736:14:736:14 | y | $@ | array_flow.rb:715:16:715:25 | call to source | call to source | -| array_flow.rb:739:10:739:13 | ...[...] | array_flow.rb:715:16:715:25 | call to source | array_flow.rb:739:10:739:13 | ...[...] | $@ | array_flow.rb:715:16:715:25 | call to source | call to source | -| array_flow.rb:747:14:747:14 | x | array_flow.rb:743:16:743:25 | call to source | array_flow.rb:747:14:747:14 | x | $@ | array_flow.rb:743:16:743:25 | call to source | call to source | -| array_flow.rb:750:10:750:10 | b | array_flow.rb:743:16:743:25 | call to source | array_flow.rb:750:10:750:10 | b | $@ | array_flow.rb:743:16:743:25 | call to source | call to source | -| array_flow.rb:754:14:754:14 | x | array_flow.rb:743:16:743:25 | call to source | array_flow.rb:754:14:754:14 | x | $@ | array_flow.rb:743:16:743:25 | call to source | call to source | -| array_flow.rb:757:10:757:13 | ...[...] | array_flow.rb:743:16:743:25 | call to source | array_flow.rb:757:10:757:13 | ...[...] | $@ | array_flow.rb:743:16:743:25 | call to source | call to source | -| array_flow.rb:765:10:765:10 | b | array_flow.rb:761:16:761:25 | call to source | array_flow.rb:765:10:765:10 | b | $@ | array_flow.rb:761:16:761:25 | call to source | call to source | -| array_flow.rb:769:10:769:13 | ...[...] | array_flow.rb:761:16:761:25 | call to source | array_flow.rb:769:10:769:13 | ...[...] | $@ | array_flow.rb:761:16:761:25 | call to source | call to source | -| array_flow.rb:773:14:773:14 | x | array_flow.rb:761:16:761:25 | call to source | array_flow.rb:773:14:773:14 | x | $@ | array_flow.rb:761:16:761:25 | call to source | call to source | -| array_flow.rb:774:14:774:14 | y | array_flow.rb:761:16:761:25 | call to source | array_flow.rb:774:14:774:14 | y | $@ | array_flow.rb:761:16:761:25 | call to source | call to source | -| array_flow.rb:777:10:777:10 | d | array_flow.rb:761:16:761:25 | call to source | array_flow.rb:777:10:777:10 | d | $@ | array_flow.rb:761:16:761:25 | call to source | call to source | -| array_flow.rb:781:14:781:14 | x | array_flow.rb:761:16:761:25 | call to source | array_flow.rb:781:14:781:14 | x | $@ | array_flow.rb:761:16:761:25 | call to source | call to source | -| array_flow.rb:782:14:782:14 | y | array_flow.rb:761:16:761:25 | call to source | array_flow.rb:782:14:782:14 | y | $@ | array_flow.rb:761:16:761:25 | call to source | call to source | -| array_flow.rb:785:10:785:13 | ...[...] | array_flow.rb:761:16:761:25 | call to source | array_flow.rb:785:10:785:13 | ...[...] | $@ | array_flow.rb:761:16:761:25 | call to source | call to source | -| array_flow.rb:793:14:793:14 | x | array_flow.rb:789:16:789:25 | call to source | array_flow.rb:793:14:793:14 | x | $@ | array_flow.rb:789:16:789:25 | call to source | call to source | -| array_flow.rb:796:10:796:10 | b | array_flow.rb:789:16:789:25 | call to source | array_flow.rb:796:10:796:10 | b | $@ | array_flow.rb:789:16:789:25 | call to source | call to source | -| array_flow.rb:800:14:800:14 | x | array_flow.rb:789:16:789:25 | call to source | array_flow.rb:800:14:800:14 | x | $@ | array_flow.rb:789:16:789:25 | call to source | call to source | -| array_flow.rb:803:10:803:13 | ...[...] | array_flow.rb:789:16:789:25 | call to source | array_flow.rb:803:10:803:13 | ...[...] | $@ | array_flow.rb:789:16:789:25 | call to source | call to source | -| array_flow.rb:810:10:810:13 | ...[...] | array_flow.rb:807:16:807:25 | call to source | array_flow.rb:810:10:810:13 | ...[...] | $@ | array_flow.rb:807:16:807:25 | call to source | call to source | -| array_flow.rb:811:10:811:13 | ...[...] | array_flow.rb:807:16:807:25 | call to source | array_flow.rb:811:10:811:13 | ...[...] | $@ | array_flow.rb:807:16:807:25 | call to source | call to source | -| array_flow.rb:814:14:814:14 | x | array_flow.rb:807:16:807:25 | call to source | array_flow.rb:814:14:814:14 | x | $@ | array_flow.rb:807:16:807:25 | call to source | call to source | -| array_flow.rb:815:14:815:14 | y | array_flow.rb:807:16:807:25 | call to source | array_flow.rb:815:14:815:14 | y | $@ | array_flow.rb:807:16:807:25 | call to source | call to source | -| array_flow.rb:818:10:818:13 | ...[...] | array_flow.rb:807:16:807:25 | call to source | array_flow.rb:818:10:818:13 | ...[...] | $@ | array_flow.rb:807:16:807:25 | call to source | call to source | -| array_flow.rb:819:10:819:13 | ...[...] | array_flow.rb:807:16:807:25 | call to source | array_flow.rb:819:10:819:13 | ...[...] | $@ | array_flow.rb:807:16:807:25 | call to source | call to source | -| array_flow.rb:825:14:825:14 | x | array_flow.rb:823:16:823:25 | call to source | array_flow.rb:825:14:825:14 | x | $@ | array_flow.rb:823:16:823:25 | call to source | call to source | -| array_flow.rb:828:10:828:13 | ...[...] | array_flow.rb:823:16:823:25 | call to source | array_flow.rb:828:10:828:13 | ...[...] | $@ | array_flow.rb:823:16:823:25 | call to source | call to source | -| array_flow.rb:829:10:829:13 | ...[...] | array_flow.rb:823:16:823:25 | call to source | array_flow.rb:829:10:829:13 | ...[...] | $@ | array_flow.rb:823:16:823:25 | call to source | call to source | -| array_flow.rb:835:14:835:14 | x | array_flow.rb:833:16:833:25 | call to source | array_flow.rb:835:14:835:14 | x | $@ | array_flow.rb:833:16:833:25 | call to source | call to source | -| array_flow.rb:844:14:844:14 | x | array_flow.rb:842:16:842:25 | call to source | array_flow.rb:844:14:844:14 | x | $@ | array_flow.rb:842:16:842:25 | call to source | call to source | -| array_flow.rb:857:14:857:14 | x | array_flow.rb:855:16:855:25 | call to source | array_flow.rb:857:14:857:14 | x | $@ | array_flow.rb:855:16:855:25 | call to source | call to source | -| array_flow.rb:860:10:860:16 | ...[...] | array_flow.rb:855:16:855:25 | call to source | array_flow.rb:860:10:860:16 | ...[...] | $@ | array_flow.rb:855:16:855:25 | call to source | call to source | -| array_flow.rb:861:10:861:16 | ...[...] | array_flow.rb:855:16:855:25 | call to source | array_flow.rb:861:10:861:16 | ...[...] | $@ | array_flow.rb:855:16:855:25 | call to source | call to source | -| array_flow.rb:868:14:868:17 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:868:14:868:17 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:869:14:869:17 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:869:14:869:17 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:870:14:870:17 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:870:14:870:17 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:873:10:873:13 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:873:10:873:13 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:876:14:876:17 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:876:14:876:17 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:877:14:877:17 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:877:14:877:17 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:880:10:880:13 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:880:10:880:13 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:883:14:883:17 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:883:14:883:17 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:884:14:884:17 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:884:14:884:17 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:887:10:887:13 | ...[...] | array_flow.rb:865:16:865:25 | call to source | array_flow.rb:887:10:887:13 | ...[...] | $@ | array_flow.rb:865:16:865:25 | call to source | call to source | -| array_flow.rb:896:10:896:10 | b | array_flow.rb:894:13:894:24 | call to source | array_flow.rb:896:10:896:10 | b | $@ | array_flow.rb:894:13:894:24 | call to source | call to source | -| array_flow.rb:896:10:896:10 | b | array_flow.rb:894:30:894:41 | call to source | array_flow.rb:896:10:896:10 | b | $@ | array_flow.rb:894:30:894:41 | call to source | call to source | -| array_flow.rb:898:10:898:13 | ...[...] | array_flow.rb:894:13:894:24 | call to source | array_flow.rb:898:10:898:13 | ...[...] | $@ | array_flow.rb:894:13:894:24 | call to source | call to source | -| array_flow.rb:900:10:900:13 | ...[...] | array_flow.rb:894:30:894:41 | call to source | array_flow.rb:900:10:900:13 | ...[...] | $@ | array_flow.rb:894:30:894:41 | call to source | call to source | -| array_flow.rb:904:10:904:13 | ...[...] | array_flow.rb:902:13:902:24 | call to source | array_flow.rb:904:10:904:13 | ...[...] | $@ | array_flow.rb:902:13:902:24 | call to source | call to source | -| array_flow.rb:904:10:904:13 | ...[...] | array_flow.rb:902:30:902:41 | call to source | array_flow.rb:904:10:904:13 | ...[...] | $@ | array_flow.rb:902:30:902:41 | call to source | call to source | -| array_flow.rb:905:10:905:13 | ...[...] | array_flow.rb:902:13:902:24 | call to source | array_flow.rb:905:10:905:13 | ...[...] | $@ | array_flow.rb:902:13:902:24 | call to source | call to source | -| array_flow.rb:905:10:905:13 | ...[...] | array_flow.rb:902:30:902:41 | call to source | array_flow.rb:905:10:905:13 | ...[...] | $@ | array_flow.rb:902:30:902:41 | call to source | call to source | -| array_flow.rb:907:10:907:13 | ...[...] | array_flow.rb:902:13:902:24 | call to source | array_flow.rb:907:10:907:13 | ...[...] | $@ | array_flow.rb:902:13:902:24 | call to source | call to source | -| array_flow.rb:909:10:909:13 | ...[...] | array_flow.rb:902:30:902:41 | call to source | array_flow.rb:909:10:909:13 | ...[...] | $@ | array_flow.rb:902:30:902:41 | call to source | call to source | -| array_flow.rb:917:10:917:13 | ...[...] | array_flow.rb:914:21:914:32 | call to source | array_flow.rb:917:10:917:13 | ...[...] | $@ | array_flow.rb:914:21:914:32 | call to source | call to source | -| array_flow.rb:920:10:920:13 | ...[...] | array_flow.rb:913:16:913:27 | call to source | array_flow.rb:920:10:920:13 | ...[...] | $@ | array_flow.rb:913:16:913:27 | call to source | call to source | -| array_flow.rb:928:10:928:16 | ...[...] | array_flow.rb:924:16:924:27 | call to source | array_flow.rb:928:10:928:16 | ...[...] | $@ | array_flow.rb:924:16:924:27 | call to source | call to source | -| array_flow.rb:928:10:928:16 | ...[...] | array_flow.rb:925:13:925:24 | call to source | array_flow.rb:928:10:928:16 | ...[...] | $@ | array_flow.rb:925:13:925:24 | call to source | call to source | -| array_flow.rb:928:10:928:16 | ...[...] | array_flow.rb:926:10:926:21 | call to source | array_flow.rb:928:10:928:16 | ...[...] | $@ | array_flow.rb:926:10:926:21 | call to source | call to source | -| array_flow.rb:929:10:929:16 | ...[...] | array_flow.rb:924:16:924:27 | call to source | array_flow.rb:929:10:929:16 | ...[...] | $@ | array_flow.rb:924:16:924:27 | call to source | call to source | -| array_flow.rb:929:10:929:16 | ...[...] | array_flow.rb:925:13:925:24 | call to source | array_flow.rb:929:10:929:16 | ...[...] | $@ | array_flow.rb:925:13:925:24 | call to source | call to source | -| array_flow.rb:929:10:929:16 | ...[...] | array_flow.rb:926:10:926:21 | call to source | array_flow.rb:929:10:929:16 | ...[...] | $@ | array_flow.rb:926:10:926:21 | call to source | call to source | -| array_flow.rb:935:10:935:13 | ...[...] | array_flow.rb:933:10:933:21 | call to source | array_flow.rb:935:10:935:13 | ...[...] | $@ | array_flow.rb:933:10:933:21 | call to source | call to source | -| array_flow.rb:935:10:935:13 | ...[...] | array_flow.rb:934:18:934:29 | call to source | array_flow.rb:935:10:935:13 | ...[...] | $@ | array_flow.rb:934:18:934:29 | call to source | call to source | -| array_flow.rb:935:10:935:13 | ...[...] | array_flow.rb:934:32:934:43 | call to source | array_flow.rb:935:10:935:13 | ...[...] | $@ | array_flow.rb:934:32:934:43 | call to source | call to source | -| array_flow.rb:936:10:936:13 | ...[...] | array_flow.rb:934:18:934:29 | call to source | array_flow.rb:936:10:936:13 | ...[...] | $@ | array_flow.rb:934:18:934:29 | call to source | call to source | -| array_flow.rb:936:10:936:13 | ...[...] | array_flow.rb:934:32:934:43 | call to source | array_flow.rb:936:10:936:13 | ...[...] | $@ | array_flow.rb:934:32:934:43 | call to source | call to source | -| array_flow.rb:937:10:937:13 | ...[...] | array_flow.rb:933:10:933:21 | call to source | array_flow.rb:937:10:937:13 | ...[...] | $@ | array_flow.rb:933:10:933:21 | call to source | call to source | -| array_flow.rb:937:10:937:13 | ...[...] | array_flow.rb:934:18:934:29 | call to source | array_flow.rb:937:10:937:13 | ...[...] | $@ | array_flow.rb:934:18:934:29 | call to source | call to source | -| array_flow.rb:937:10:937:13 | ...[...] | array_flow.rb:934:32:934:43 | call to source | array_flow.rb:937:10:937:13 | ...[...] | $@ | array_flow.rb:934:32:934:43 | call to source | call to source | -| array_flow.rb:938:10:938:13 | ...[...] | array_flow.rb:934:18:934:29 | call to source | array_flow.rb:938:10:938:13 | ...[...] | $@ | array_flow.rb:934:18:934:29 | call to source | call to source | -| array_flow.rb:938:10:938:13 | ...[...] | array_flow.rb:934:32:934:43 | call to source | array_flow.rb:938:10:938:13 | ...[...] | $@ | array_flow.rb:934:32:934:43 | call to source | call to source | -| array_flow.rb:946:10:946:25 | ...[...] | array_flow.rb:944:10:944:19 | call to source | array_flow.rb:946:10:946:25 | ...[...] | $@ | array_flow.rb:944:10:944:19 | call to source | call to source | -| array_flow.rb:947:10:947:25 | ...[...] | array_flow.rb:944:10:944:19 | call to source | array_flow.rb:947:10:947:25 | ...[...] | $@ | array_flow.rb:944:10:944:19 | call to source | call to source | -| array_flow.rb:953:14:953:14 | x | array_flow.rb:951:10:951:21 | call to source | array_flow.rb:953:14:953:14 | x | $@ | array_flow.rb:951:10:951:21 | call to source | call to source | -| array_flow.rb:954:14:954:14 | y | array_flow.rb:951:27:951:38 | call to source | array_flow.rb:954:14:954:14 | y | $@ | array_flow.rb:951:27:951:38 | call to source | call to source | -| array_flow.rb:959:14:959:14 | y | array_flow.rb:951:10:951:21 | call to source | array_flow.rb:959:14:959:14 | y | $@ | array_flow.rb:951:10:951:21 | call to source | call to source | -| array_flow.rb:959:14:959:14 | y | array_flow.rb:951:27:951:38 | call to source | array_flow.rb:959:14:959:14 | y | $@ | array_flow.rb:951:27:951:38 | call to source | call to source | -| array_flow.rb:967:14:967:14 | x | array_flow.rb:965:16:965:25 | call to source | array_flow.rb:967:14:967:14 | x | $@ | array_flow.rb:965:16:965:25 | call to source | call to source | -| array_flow.rb:970:10:970:13 | ...[...] | array_flow.rb:965:16:965:25 | call to source | array_flow.rb:970:10:970:13 | ...[...] | $@ | array_flow.rb:965:16:965:25 | call to source | call to source | -| array_flow.rb:976:14:976:14 | x | array_flow.rb:974:16:974:25 | call to source | array_flow.rb:976:14:976:14 | x | $@ | array_flow.rb:974:16:974:25 | call to source | call to source | -| array_flow.rb:979:10:979:13 | ...[...] | array_flow.rb:974:16:974:25 | call to source | array_flow.rb:979:10:979:13 | ...[...] | $@ | array_flow.rb:974:16:974:25 | call to source | call to source | -| array_flow.rb:980:10:980:13 | ...[...] | array_flow.rb:974:16:974:25 | call to source | array_flow.rb:980:10:980:13 | ...[...] | $@ | array_flow.rb:974:16:974:25 | call to source | call to source | -| array_flow.rb:986:14:986:17 | ...[...] | array_flow.rb:984:16:984:25 | call to source | array_flow.rb:986:14:986:17 | ...[...] | $@ | array_flow.rb:984:16:984:25 | call to source | call to source | -| array_flow.rb:987:14:987:17 | ...[...] | array_flow.rb:984:16:984:25 | call to source | array_flow.rb:987:14:987:17 | ...[...] | $@ | array_flow.rb:984:16:984:25 | call to source | call to source | -| array_flow.rb:990:10:990:13 | ...[...] | array_flow.rb:984:16:984:25 | call to source | array_flow.rb:990:10:990:13 | ...[...] | $@ | array_flow.rb:984:16:984:25 | call to source | call to source | -| array_flow.rb:996:14:996:17 | ...[...] | array_flow.rb:994:16:994:25 | call to source | array_flow.rb:996:14:996:17 | ...[...] | $@ | array_flow.rb:994:16:994:25 | call to source | call to source | -| array_flow.rb:997:14:997:17 | ...[...] | array_flow.rb:994:16:994:25 | call to source | array_flow.rb:997:14:997:17 | ...[...] | $@ | array_flow.rb:994:16:994:25 | call to source | call to source | -| array_flow.rb:1000:10:1000:13 | ...[...] | array_flow.rb:994:16:994:25 | call to source | array_flow.rb:1000:10:1000:13 | ...[...] | $@ | array_flow.rb:994:16:994:25 | call to source | call to source | -| array_flow.rb:1007:10:1007:13 | ...[...] | array_flow.rb:1006:20:1006:31 | call to source | array_flow.rb:1007:10:1007:13 | ...[...] | $@ | array_flow.rb:1006:20:1006:31 | call to source | call to source | -| array_flow.rb:1008:10:1008:13 | ...[...] | array_flow.rb:1006:20:1006:31 | call to source | array_flow.rb:1008:10:1008:13 | ...[...] | $@ | array_flow.rb:1006:20:1006:31 | call to source | call to source | -| array_flow.rb:1014:10:1014:13 | ...[...] | array_flow.rb:1012:16:1012:28 | call to source | array_flow.rb:1014:10:1014:13 | ...[...] | $@ | array_flow.rb:1012:16:1012:28 | call to source | call to source | -| array_flow.rb:1014:10:1014:13 | ...[...] | array_flow.rb:1012:31:1012:43 | call to source | array_flow.rb:1014:10:1014:13 | ...[...] | $@ | array_flow.rb:1012:31:1012:43 | call to source | call to source | -| array_flow.rb:1015:10:1015:13 | ...[...] | array_flow.rb:1012:16:1012:28 | call to source | array_flow.rb:1015:10:1015:13 | ...[...] | $@ | array_flow.rb:1012:16:1012:28 | call to source | call to source | -| array_flow.rb:1015:10:1015:13 | ...[...] | array_flow.rb:1012:31:1012:43 | call to source | array_flow.rb:1015:10:1015:13 | ...[...] | $@ | array_flow.rb:1012:31:1012:43 | call to source | call to source | -| array_flow.rb:1016:10:1016:13 | ...[...] | array_flow.rb:1012:16:1012:28 | call to source | array_flow.rb:1016:10:1016:13 | ...[...] | $@ | array_flow.rb:1012:16:1012:28 | call to source | call to source | -| array_flow.rb:1016:10:1016:13 | ...[...] | array_flow.rb:1012:31:1012:43 | call to source | array_flow.rb:1016:10:1016:13 | ...[...] | $@ | array_flow.rb:1012:31:1012:43 | call to source | call to source | -| array_flow.rb:1018:10:1018:13 | ...[...] | array_flow.rb:1012:16:1012:28 | call to source | array_flow.rb:1018:10:1018:13 | ...[...] | $@ | array_flow.rb:1012:16:1012:28 | call to source | call to source | -| array_flow.rb:1019:10:1019:13 | ...[...] | array_flow.rb:1012:31:1012:43 | call to source | array_flow.rb:1019:10:1019:13 | ...[...] | $@ | array_flow.rb:1012:31:1012:43 | call to source | call to source | +| array_flow.rb:613:10:613:13 | ...[...] | array_flow.rb:611:19:611:30 | call to source | array_flow.rb:613:10:613:13 | ...[...] | $@ | array_flow.rb:611:19:611:30 | call to source | call to source | +| array_flow.rb:615:14:615:14 | x | array_flow.rb:611:19:611:30 | call to source | array_flow.rb:615:14:615:14 | x | $@ | array_flow.rb:611:19:611:30 | call to source | call to source | +| array_flow.rb:618:10:618:13 | ...[...] | array_flow.rb:616:9:616:20 | call to source | array_flow.rb:618:10:618:13 | ...[...] | $@ | array_flow.rb:616:9:616:20 | call to source | call to source | +| array_flow.rb:624:14:624:14 | x | array_flow.rb:622:19:622:30 | call to source | array_flow.rb:624:14:624:14 | x | $@ | array_flow.rb:622:19:622:30 | call to source | call to source | +| array_flow.rb:633:14:633:14 | x | array_flow.rb:631:19:631:28 | call to source | array_flow.rb:633:14:633:14 | x | $@ | array_flow.rb:631:19:631:28 | call to source | call to source | +| array_flow.rb:640:14:640:14 | x | array_flow.rb:638:10:638:21 | call to source | array_flow.rb:640:14:640:14 | x | $@ | array_flow.rb:638:10:638:21 | call to source | call to source | +| array_flow.rb:641:14:641:14 | y | array_flow.rb:638:27:638:38 | call to source | array_flow.rb:641:14:641:14 | y | $@ | array_flow.rb:638:27:638:38 | call to source | call to source | +| array_flow.rb:644:10:644:10 | b | array_flow.rb:642:9:642:19 | call to source | array_flow.rb:644:10:644:10 | b | $@ | array_flow.rb:642:9:642:19 | call to source | call to source | +| array_flow.rb:647:14:647:14 | y | array_flow.rb:638:10:638:21 | call to source | array_flow.rb:647:14:647:14 | y | $@ | array_flow.rb:638:10:638:21 | call to source | call to source | +| array_flow.rb:647:14:647:14 | y | array_flow.rb:638:27:638:38 | call to source | array_flow.rb:647:14:647:14 | y | $@ | array_flow.rb:638:27:638:38 | call to source | call to source | +| array_flow.rb:650:10:650:10 | c | array_flow.rb:648:9:648:19 | call to source | array_flow.rb:650:10:650:10 | c | $@ | array_flow.rb:648:9:648:19 | call to source | call to source | +| array_flow.rb:658:10:658:13 | ...[...] | array_flow.rb:656:21:656:32 | call to source | array_flow.rb:658:10:658:13 | ...[...] | $@ | array_flow.rb:656:21:656:32 | call to source | call to source | +| array_flow.rb:659:10:659:13 | ...[...] | array_flow.rb:656:35:656:46 | call to source | array_flow.rb:659:10:659:13 | ...[...] | $@ | array_flow.rb:656:35:656:46 | call to source | call to source | +| array_flow.rb:661:10:661:13 | ...[...] | array_flow.rb:655:16:655:27 | call to source | array_flow.rb:661:10:661:13 | ...[...] | $@ | array_flow.rb:655:16:655:27 | call to source | call to source | +| array_flow.rb:663:10:663:13 | ...[...] | array_flow.rb:656:21:656:32 | call to source | array_flow.rb:663:10:663:13 | ...[...] | $@ | array_flow.rb:656:21:656:32 | call to source | call to source | +| array_flow.rb:664:10:664:13 | ...[...] | array_flow.rb:656:35:656:46 | call to source | array_flow.rb:664:10:664:13 | ...[...] | $@ | array_flow.rb:656:35:656:46 | call to source | call to source | +| array_flow.rb:666:10:666:13 | ...[...] | array_flow.rb:655:16:655:27 | call to source | array_flow.rb:666:10:666:13 | ...[...] | $@ | array_flow.rb:655:16:655:27 | call to source | call to source | +| array_flow.rb:671:10:671:13 | ...[...] | array_flow.rb:669:16:669:27 | call to source | array_flow.rb:671:10:671:13 | ...[...] | $@ | array_flow.rb:669:16:669:27 | call to source | call to source | +| array_flow.rb:671:10:671:13 | ...[...] | array_flow.rb:670:21:670:32 | call to source | array_flow.rb:671:10:671:13 | ...[...] | $@ | array_flow.rb:670:21:670:32 | call to source | call to source | +| array_flow.rb:671:10:671:13 | ...[...] | array_flow.rb:670:35:670:46 | call to source | array_flow.rb:671:10:671:13 | ...[...] | $@ | array_flow.rb:670:35:670:46 | call to source | call to source | +| array_flow.rb:672:10:672:13 | ...[...] | array_flow.rb:669:16:669:27 | call to source | array_flow.rb:672:10:672:13 | ...[...] | $@ | array_flow.rb:669:16:669:27 | call to source | call to source | +| array_flow.rb:672:10:672:13 | ...[...] | array_flow.rb:670:21:670:32 | call to source | array_flow.rb:672:10:672:13 | ...[...] | $@ | array_flow.rb:670:21:670:32 | call to source | call to source | +| array_flow.rb:672:10:672:13 | ...[...] | array_flow.rb:670:35:670:46 | call to source | array_flow.rb:672:10:672:13 | ...[...] | $@ | array_flow.rb:670:35:670:46 | call to source | call to source | +| array_flow.rb:685:10:685:13 | ...[...] | array_flow.rb:683:16:683:27 | call to source | array_flow.rb:685:10:685:13 | ...[...] | $@ | array_flow.rb:683:16:683:27 | call to source | call to source | +| array_flow.rb:685:10:685:13 | ...[...] | array_flow.rb:684:31:684:42 | call to source | array_flow.rb:685:10:685:13 | ...[...] | $@ | array_flow.rb:684:31:684:42 | call to source | call to source | +| array_flow.rb:685:10:685:13 | ...[...] | array_flow.rb:684:47:684:58 | call to source | array_flow.rb:685:10:685:13 | ...[...] | $@ | array_flow.rb:684:47:684:58 | call to source | call to source | +| array_flow.rb:691:14:691:14 | x | array_flow.rb:689:16:689:25 | call to source | array_flow.rb:691:14:691:14 | x | $@ | array_flow.rb:689:16:689:25 | call to source | call to source | +| array_flow.rb:694:10:694:13 | ...[...] | array_flow.rb:689:16:689:25 | call to source | array_flow.rb:694:10:694:13 | ...[...] | $@ | array_flow.rb:689:16:689:25 | call to source | call to source | +| array_flow.rb:695:10:695:13 | ...[...] | array_flow.rb:689:16:689:25 | call to source | array_flow.rb:695:10:695:13 | ...[...] | $@ | array_flow.rb:689:16:689:25 | call to source | call to source | +| array_flow.rb:701:10:701:15 | call to last | array_flow.rb:699:16:699:27 | call to source | array_flow.rb:701:10:701:15 | call to last | $@ | array_flow.rb:699:16:699:27 | call to source | call to source | +| array_flow.rb:701:10:701:15 | call to last | array_flow.rb:700:12:700:23 | call to source | array_flow.rb:701:10:701:15 | call to last | $@ | array_flow.rb:700:12:700:23 | call to source | call to source | +| array_flow.rb:703:10:703:13 | ...[...] | array_flow.rb:699:16:699:27 | call to source | array_flow.rb:703:10:703:13 | ...[...] | $@ | array_flow.rb:699:16:699:27 | call to source | call to source | +| array_flow.rb:703:10:703:13 | ...[...] | array_flow.rb:700:12:700:23 | call to source | array_flow.rb:703:10:703:13 | ...[...] | $@ | array_flow.rb:700:12:700:23 | call to source | call to source | +| array_flow.rb:704:10:704:13 | ...[...] | array_flow.rb:699:16:699:27 | call to source | array_flow.rb:704:10:704:13 | ...[...] | $@ | array_flow.rb:699:16:699:27 | call to source | call to source | +| array_flow.rb:704:10:704:13 | ...[...] | array_flow.rb:700:12:700:23 | call to source | array_flow.rb:704:10:704:13 | ...[...] | $@ | array_flow.rb:700:12:700:23 | call to source | call to source | +| array_flow.rb:710:14:710:14 | x | array_flow.rb:708:16:708:27 | call to source | array_flow.rb:710:14:710:14 | x | $@ | array_flow.rb:708:16:708:27 | call to source | call to source | +| array_flow.rb:713:10:713:13 | ...[...] | array_flow.rb:711:9:711:19 | call to source | array_flow.rb:713:10:713:13 | ...[...] | $@ | array_flow.rb:711:9:711:19 | call to source | call to source | +| array_flow.rb:719:14:719:14 | x | array_flow.rb:717:16:717:27 | call to source | array_flow.rb:719:14:719:14 | x | $@ | array_flow.rb:717:16:717:27 | call to source | call to source | +| array_flow.rb:722:10:722:13 | ...[...] | array_flow.rb:720:9:720:19 | call to source | array_flow.rb:722:10:722:13 | ...[...] | $@ | array_flow.rb:720:9:720:19 | call to source | call to source | +| array_flow.rb:730:10:730:10 | b | array_flow.rb:726:16:726:25 | call to source | array_flow.rb:730:10:730:10 | b | $@ | array_flow.rb:726:16:726:25 | call to source | call to source | +| array_flow.rb:734:10:734:13 | ...[...] | array_flow.rb:726:16:726:25 | call to source | array_flow.rb:734:10:734:13 | ...[...] | $@ | array_flow.rb:726:16:726:25 | call to source | call to source | +| array_flow.rb:738:14:738:14 | x | array_flow.rb:726:16:726:25 | call to source | array_flow.rb:738:14:738:14 | x | $@ | array_flow.rb:726:16:726:25 | call to source | call to source | +| array_flow.rb:739:14:739:14 | y | array_flow.rb:726:16:726:25 | call to source | array_flow.rb:739:14:739:14 | y | $@ | array_flow.rb:726:16:726:25 | call to source | call to source | +| array_flow.rb:742:10:742:10 | d | array_flow.rb:726:16:726:25 | call to source | array_flow.rb:742:10:742:10 | d | $@ | array_flow.rb:726:16:726:25 | call to source | call to source | +| array_flow.rb:746:14:746:14 | x | array_flow.rb:726:16:726:25 | call to source | array_flow.rb:746:14:746:14 | x | $@ | array_flow.rb:726:16:726:25 | call to source | call to source | +| array_flow.rb:747:14:747:14 | y | array_flow.rb:726:16:726:25 | call to source | array_flow.rb:747:14:747:14 | y | $@ | array_flow.rb:726:16:726:25 | call to source | call to source | +| array_flow.rb:750:10:750:13 | ...[...] | array_flow.rb:726:16:726:25 | call to source | array_flow.rb:750:10:750:13 | ...[...] | $@ | array_flow.rb:726:16:726:25 | call to source | call to source | +| array_flow.rb:758:14:758:14 | x | array_flow.rb:754:16:754:25 | call to source | array_flow.rb:758:14:758:14 | x | $@ | array_flow.rb:754:16:754:25 | call to source | call to source | +| array_flow.rb:761:10:761:10 | b | array_flow.rb:754:16:754:25 | call to source | array_flow.rb:761:10:761:10 | b | $@ | array_flow.rb:754:16:754:25 | call to source | call to source | +| array_flow.rb:765:14:765:14 | x | array_flow.rb:754:16:754:25 | call to source | array_flow.rb:765:14:765:14 | x | $@ | array_flow.rb:754:16:754:25 | call to source | call to source | +| array_flow.rb:768:10:768:13 | ...[...] | array_flow.rb:754:16:754:25 | call to source | array_flow.rb:768:10:768:13 | ...[...] | $@ | array_flow.rb:754:16:754:25 | call to source | call to source | +| array_flow.rb:776:10:776:10 | b | array_flow.rb:772:16:772:25 | call to source | array_flow.rb:776:10:776:10 | b | $@ | array_flow.rb:772:16:772:25 | call to source | call to source | +| array_flow.rb:780:10:780:13 | ...[...] | array_flow.rb:772:16:772:25 | call to source | array_flow.rb:780:10:780:13 | ...[...] | $@ | array_flow.rb:772:16:772:25 | call to source | call to source | +| array_flow.rb:784:14:784:14 | x | array_flow.rb:772:16:772:25 | call to source | array_flow.rb:784:14:784:14 | x | $@ | array_flow.rb:772:16:772:25 | call to source | call to source | +| array_flow.rb:785:14:785:14 | y | array_flow.rb:772:16:772:25 | call to source | array_flow.rb:785:14:785:14 | y | $@ | array_flow.rb:772:16:772:25 | call to source | call to source | +| array_flow.rb:788:10:788:10 | d | array_flow.rb:772:16:772:25 | call to source | array_flow.rb:788:10:788:10 | d | $@ | array_flow.rb:772:16:772:25 | call to source | call to source | +| array_flow.rb:792:14:792:14 | x | array_flow.rb:772:16:772:25 | call to source | array_flow.rb:792:14:792:14 | x | $@ | array_flow.rb:772:16:772:25 | call to source | call to source | +| array_flow.rb:793:14:793:14 | y | array_flow.rb:772:16:772:25 | call to source | array_flow.rb:793:14:793:14 | y | $@ | array_flow.rb:772:16:772:25 | call to source | call to source | +| array_flow.rb:796:10:796:13 | ...[...] | array_flow.rb:772:16:772:25 | call to source | array_flow.rb:796:10:796:13 | ...[...] | $@ | array_flow.rb:772:16:772:25 | call to source | call to source | +| array_flow.rb:804:14:804:14 | x | array_flow.rb:800:16:800:25 | call to source | array_flow.rb:804:14:804:14 | x | $@ | array_flow.rb:800:16:800:25 | call to source | call to source | +| array_flow.rb:807:10:807:10 | b | array_flow.rb:800:16:800:25 | call to source | array_flow.rb:807:10:807:10 | b | $@ | array_flow.rb:800:16:800:25 | call to source | call to source | +| array_flow.rb:811:14:811:14 | x | array_flow.rb:800:16:800:25 | call to source | array_flow.rb:811:14:811:14 | x | $@ | array_flow.rb:800:16:800:25 | call to source | call to source | +| array_flow.rb:814:10:814:13 | ...[...] | array_flow.rb:800:16:800:25 | call to source | array_flow.rb:814:10:814:13 | ...[...] | $@ | array_flow.rb:800:16:800:25 | call to source | call to source | +| array_flow.rb:821:10:821:13 | ...[...] | array_flow.rb:818:16:818:25 | call to source | array_flow.rb:821:10:821:13 | ...[...] | $@ | array_flow.rb:818:16:818:25 | call to source | call to source | +| array_flow.rb:822:10:822:13 | ...[...] | array_flow.rb:818:16:818:25 | call to source | array_flow.rb:822:10:822:13 | ...[...] | $@ | array_flow.rb:818:16:818:25 | call to source | call to source | +| array_flow.rb:825:14:825:14 | x | array_flow.rb:818:16:818:25 | call to source | array_flow.rb:825:14:825:14 | x | $@ | array_flow.rb:818:16:818:25 | call to source | call to source | +| array_flow.rb:826:14:826:14 | y | array_flow.rb:818:16:818:25 | call to source | array_flow.rb:826:14:826:14 | y | $@ | array_flow.rb:818:16:818:25 | call to source | call to source | +| array_flow.rb:829:10:829:13 | ...[...] | array_flow.rb:818:16:818:25 | call to source | array_flow.rb:829:10:829:13 | ...[...] | $@ | array_flow.rb:818:16:818:25 | call to source | call to source | +| array_flow.rb:830:10:830:13 | ...[...] | array_flow.rb:818:16:818:25 | call to source | array_flow.rb:830:10:830:13 | ...[...] | $@ | array_flow.rb:818:16:818:25 | call to source | call to source | +| array_flow.rb:836:14:836:14 | x | array_flow.rb:834:16:834:25 | call to source | array_flow.rb:836:14:836:14 | x | $@ | array_flow.rb:834:16:834:25 | call to source | call to source | +| array_flow.rb:839:10:839:13 | ...[...] | array_flow.rb:834:16:834:25 | call to source | array_flow.rb:839:10:839:13 | ...[...] | $@ | array_flow.rb:834:16:834:25 | call to source | call to source | +| array_flow.rb:840:10:840:13 | ...[...] | array_flow.rb:834:16:834:25 | call to source | array_flow.rb:840:10:840:13 | ...[...] | $@ | array_flow.rb:834:16:834:25 | call to source | call to source | +| array_flow.rb:846:14:846:14 | x | array_flow.rb:844:16:844:25 | call to source | array_flow.rb:846:14:846:14 | x | $@ | array_flow.rb:844:16:844:25 | call to source | call to source | +| array_flow.rb:855:14:855:14 | x | array_flow.rb:853:16:853:25 | call to source | array_flow.rb:855:14:855:14 | x | $@ | array_flow.rb:853:16:853:25 | call to source | call to source | +| array_flow.rb:868:14:868:14 | x | array_flow.rb:866:16:866:25 | call to source | array_flow.rb:868:14:868:14 | x | $@ | array_flow.rb:866:16:866:25 | call to source | call to source | +| array_flow.rb:871:10:871:16 | ...[...] | array_flow.rb:866:16:866:25 | call to source | array_flow.rb:871:10:871:16 | ...[...] | $@ | array_flow.rb:866:16:866:25 | call to source | call to source | +| array_flow.rb:872:10:872:16 | ...[...] | array_flow.rb:866:16:866:25 | call to source | array_flow.rb:872:10:872:16 | ...[...] | $@ | array_flow.rb:866:16:866:25 | call to source | call to source | +| array_flow.rb:879:14:879:17 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:879:14:879:17 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:880:14:880:17 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:880:14:880:17 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:881:14:881:17 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:881:14:881:17 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:884:10:884:13 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:884:10:884:13 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:887:14:887:17 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:887:14:887:17 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:888:14:888:17 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:888:14:888:17 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:891:10:891:13 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:891:10:891:13 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:894:14:894:17 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:894:14:894:17 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:895:14:895:17 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:895:14:895:17 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:898:10:898:13 | ...[...] | array_flow.rb:876:16:876:25 | call to source | array_flow.rb:898:10:898:13 | ...[...] | $@ | array_flow.rb:876:16:876:25 | call to source | call to source | +| array_flow.rb:907:10:907:10 | b | array_flow.rb:905:13:905:24 | call to source | array_flow.rb:907:10:907:10 | b | $@ | array_flow.rb:905:13:905:24 | call to source | call to source | +| array_flow.rb:907:10:907:10 | b | array_flow.rb:905:30:905:41 | call to source | array_flow.rb:907:10:907:10 | b | $@ | array_flow.rb:905:30:905:41 | call to source | call to source | +| array_flow.rb:909:10:909:13 | ...[...] | array_flow.rb:905:13:905:24 | call to source | array_flow.rb:909:10:909:13 | ...[...] | $@ | array_flow.rb:905:13:905:24 | call to source | call to source | +| array_flow.rb:911:10:911:13 | ...[...] | array_flow.rb:905:30:905:41 | call to source | array_flow.rb:911:10:911:13 | ...[...] | $@ | array_flow.rb:905:30:905:41 | call to source | call to source | +| array_flow.rb:915:10:915:13 | ...[...] | array_flow.rb:913:13:913:24 | call to source | array_flow.rb:915:10:915:13 | ...[...] | $@ | array_flow.rb:913:13:913:24 | call to source | call to source | +| array_flow.rb:915:10:915:13 | ...[...] | array_flow.rb:913:30:913:41 | call to source | array_flow.rb:915:10:915:13 | ...[...] | $@ | array_flow.rb:913:30:913:41 | call to source | call to source | +| array_flow.rb:916:10:916:13 | ...[...] | array_flow.rb:913:13:913:24 | call to source | array_flow.rb:916:10:916:13 | ...[...] | $@ | array_flow.rb:913:13:913:24 | call to source | call to source | +| array_flow.rb:916:10:916:13 | ...[...] | array_flow.rb:913:30:913:41 | call to source | array_flow.rb:916:10:916:13 | ...[...] | $@ | array_flow.rb:913:30:913:41 | call to source | call to source | +| array_flow.rb:918:10:918:13 | ...[...] | array_flow.rb:913:13:913:24 | call to source | array_flow.rb:918:10:918:13 | ...[...] | $@ | array_flow.rb:913:13:913:24 | call to source | call to source | +| array_flow.rb:920:10:920:13 | ...[...] | array_flow.rb:913:30:913:41 | call to source | array_flow.rb:920:10:920:13 | ...[...] | $@ | array_flow.rb:913:30:913:41 | call to source | call to source | +| array_flow.rb:928:10:928:13 | ...[...] | array_flow.rb:925:21:925:32 | call to source | array_flow.rb:928:10:928:13 | ...[...] | $@ | array_flow.rb:925:21:925:32 | call to source | call to source | +| array_flow.rb:931:10:931:13 | ...[...] | array_flow.rb:924:16:924:27 | call to source | array_flow.rb:931:10:931:13 | ...[...] | $@ | array_flow.rb:924:16:924:27 | call to source | call to source | +| array_flow.rb:939:10:939:16 | ...[...] | array_flow.rb:935:16:935:27 | call to source | array_flow.rb:939:10:939:16 | ...[...] | $@ | array_flow.rb:935:16:935:27 | call to source | call to source | +| array_flow.rb:939:10:939:16 | ...[...] | array_flow.rb:936:13:936:24 | call to source | array_flow.rb:939:10:939:16 | ...[...] | $@ | array_flow.rb:936:13:936:24 | call to source | call to source | +| array_flow.rb:939:10:939:16 | ...[...] | array_flow.rb:937:10:937:21 | call to source | array_flow.rb:939:10:939:16 | ...[...] | $@ | array_flow.rb:937:10:937:21 | call to source | call to source | +| array_flow.rb:940:10:940:16 | ...[...] | array_flow.rb:935:16:935:27 | call to source | array_flow.rb:940:10:940:16 | ...[...] | $@ | array_flow.rb:935:16:935:27 | call to source | call to source | +| array_flow.rb:940:10:940:16 | ...[...] | array_flow.rb:936:13:936:24 | call to source | array_flow.rb:940:10:940:16 | ...[...] | $@ | array_flow.rb:936:13:936:24 | call to source | call to source | +| array_flow.rb:940:10:940:16 | ...[...] | array_flow.rb:937:10:937:21 | call to source | array_flow.rb:940:10:940:16 | ...[...] | $@ | array_flow.rb:937:10:937:21 | call to source | call to source | +| array_flow.rb:946:10:946:13 | ...[...] | array_flow.rb:944:10:944:21 | call to source | array_flow.rb:946:10:946:13 | ...[...] | $@ | array_flow.rb:944:10:944:21 | call to source | call to source | +| array_flow.rb:946:10:946:13 | ...[...] | array_flow.rb:945:18:945:29 | call to source | array_flow.rb:946:10:946:13 | ...[...] | $@ | array_flow.rb:945:18:945:29 | call to source | call to source | +| array_flow.rb:946:10:946:13 | ...[...] | array_flow.rb:945:32:945:43 | call to source | array_flow.rb:946:10:946:13 | ...[...] | $@ | array_flow.rb:945:32:945:43 | call to source | call to source | +| array_flow.rb:947:10:947:13 | ...[...] | array_flow.rb:945:18:945:29 | call to source | array_flow.rb:947:10:947:13 | ...[...] | $@ | array_flow.rb:945:18:945:29 | call to source | call to source | +| array_flow.rb:947:10:947:13 | ...[...] | array_flow.rb:945:32:945:43 | call to source | array_flow.rb:947:10:947:13 | ...[...] | $@ | array_flow.rb:945:32:945:43 | call to source | call to source | +| array_flow.rb:948:10:948:13 | ...[...] | array_flow.rb:944:10:944:21 | call to source | array_flow.rb:948:10:948:13 | ...[...] | $@ | array_flow.rb:944:10:944:21 | call to source | call to source | +| array_flow.rb:948:10:948:13 | ...[...] | array_flow.rb:945:18:945:29 | call to source | array_flow.rb:948:10:948:13 | ...[...] | $@ | array_flow.rb:945:18:945:29 | call to source | call to source | +| array_flow.rb:948:10:948:13 | ...[...] | array_flow.rb:945:32:945:43 | call to source | array_flow.rb:948:10:948:13 | ...[...] | $@ | array_flow.rb:945:32:945:43 | call to source | call to source | +| array_flow.rb:949:10:949:13 | ...[...] | array_flow.rb:945:18:945:29 | call to source | array_flow.rb:949:10:949:13 | ...[...] | $@ | array_flow.rb:945:18:945:29 | call to source | call to source | +| array_flow.rb:949:10:949:13 | ...[...] | array_flow.rb:945:32:945:43 | call to source | array_flow.rb:949:10:949:13 | ...[...] | $@ | array_flow.rb:945:32:945:43 | call to source | call to source | +| array_flow.rb:957:10:957:25 | ...[...] | array_flow.rb:955:10:955:19 | call to source | array_flow.rb:957:10:957:25 | ...[...] | $@ | array_flow.rb:955:10:955:19 | call to source | call to source | +| array_flow.rb:958:10:958:25 | ...[...] | array_flow.rb:955:10:955:19 | call to source | array_flow.rb:958:10:958:25 | ...[...] | $@ | array_flow.rb:955:10:955:19 | call to source | call to source | +| array_flow.rb:964:14:964:14 | x | array_flow.rb:962:10:962:21 | call to source | array_flow.rb:964:14:964:14 | x | $@ | array_flow.rb:962:10:962:21 | call to source | call to source | +| array_flow.rb:965:14:965:14 | y | array_flow.rb:962:27:962:38 | call to source | array_flow.rb:965:14:965:14 | y | $@ | array_flow.rb:962:27:962:38 | call to source | call to source | +| array_flow.rb:970:14:970:14 | y | array_flow.rb:962:10:962:21 | call to source | array_flow.rb:970:14:970:14 | y | $@ | array_flow.rb:962:10:962:21 | call to source | call to source | +| array_flow.rb:970:14:970:14 | y | array_flow.rb:962:27:962:38 | call to source | array_flow.rb:970:14:970:14 | y | $@ | array_flow.rb:962:27:962:38 | call to source | call to source | +| array_flow.rb:978:14:978:14 | x | array_flow.rb:976:16:976:25 | call to source | array_flow.rb:978:14:978:14 | x | $@ | array_flow.rb:976:16:976:25 | call to source | call to source | +| array_flow.rb:981:10:981:13 | ...[...] | array_flow.rb:976:16:976:25 | call to source | array_flow.rb:981:10:981:13 | ...[...] | $@ | array_flow.rb:976:16:976:25 | call to source | call to source | +| array_flow.rb:987:14:987:14 | x | array_flow.rb:985:16:985:25 | call to source | array_flow.rb:987:14:987:14 | x | $@ | array_flow.rb:985:16:985:25 | call to source | call to source | +| array_flow.rb:990:10:990:13 | ...[...] | array_flow.rb:985:16:985:25 | call to source | array_flow.rb:990:10:990:13 | ...[...] | $@ | array_flow.rb:985:16:985:25 | call to source | call to source | +| array_flow.rb:991:10:991:13 | ...[...] | array_flow.rb:985:16:985:25 | call to source | array_flow.rb:991:10:991:13 | ...[...] | $@ | array_flow.rb:985:16:985:25 | call to source | call to source | +| array_flow.rb:997:14:997:17 | ...[...] | array_flow.rb:995:16:995:25 | call to source | array_flow.rb:997:14:997:17 | ...[...] | $@ | array_flow.rb:995:16:995:25 | call to source | call to source | +| array_flow.rb:998:14:998:17 | ...[...] | array_flow.rb:995:16:995:25 | call to source | array_flow.rb:998:14:998:17 | ...[...] | $@ | array_flow.rb:995:16:995:25 | call to source | call to source | +| array_flow.rb:1001:10:1001:13 | ...[...] | array_flow.rb:995:16:995:25 | call to source | array_flow.rb:1001:10:1001:13 | ...[...] | $@ | array_flow.rb:995:16:995:25 | call to source | call to source | +| array_flow.rb:1007:14:1007:17 | ...[...] | array_flow.rb:1005:16:1005:25 | call to source | array_flow.rb:1007:14:1007:17 | ...[...] | $@ | array_flow.rb:1005:16:1005:25 | call to source | call to source | +| array_flow.rb:1008:14:1008:17 | ...[...] | array_flow.rb:1005:16:1005:25 | call to source | array_flow.rb:1008:14:1008:17 | ...[...] | $@ | array_flow.rb:1005:16:1005:25 | call to source | call to source | +| array_flow.rb:1011:10:1011:13 | ...[...] | array_flow.rb:1005:16:1005:25 | call to source | array_flow.rb:1011:10:1011:13 | ...[...] | $@ | array_flow.rb:1005:16:1005:25 | call to source | call to source | +| array_flow.rb:1018:10:1018:13 | ...[...] | array_flow.rb:1017:20:1017:31 | call to source | array_flow.rb:1018:10:1018:13 | ...[...] | $@ | array_flow.rb:1017:20:1017:31 | call to source | call to source | +| array_flow.rb:1019:10:1019:13 | ...[...] | array_flow.rb:1017:20:1017:31 | call to source | array_flow.rb:1019:10:1019:13 | ...[...] | $@ | array_flow.rb:1017:20:1017:31 | call to source | call to source | | array_flow.rb:1025:10:1025:13 | ...[...] | array_flow.rb:1023:16:1023:28 | call to source | array_flow.rb:1025:10:1025:13 | ...[...] | $@ | array_flow.rb:1023:16:1023:28 | call to source | call to source | | array_flow.rb:1025:10:1025:13 | ...[...] | array_flow.rb:1023:31:1023:43 | call to source | array_flow.rb:1025:10:1025:13 | ...[...] | $@ | array_flow.rb:1023:31:1023:43 | call to source | call to source | | array_flow.rb:1026:10:1026:13 | ...[...] | array_flow.rb:1023:16:1023:28 | call to source | array_flow.rb:1026:10:1026:13 | ...[...] | $@ | array_flow.rb:1023:16:1023:28 | call to source | call to source | | array_flow.rb:1026:10:1026:13 | ...[...] | array_flow.rb:1023:31:1023:43 | call to source | array_flow.rb:1026:10:1026:13 | ...[...] | $@ | array_flow.rb:1023:31:1023:43 | call to source | call to source | | array_flow.rb:1027:10:1027:13 | ...[...] | array_flow.rb:1023:16:1023:28 | call to source | array_flow.rb:1027:10:1027:13 | ...[...] | $@ | array_flow.rb:1023:16:1023:28 | call to source | call to source | | array_flow.rb:1027:10:1027:13 | ...[...] | array_flow.rb:1023:31:1023:43 | call to source | array_flow.rb:1027:10:1027:13 | ...[...] | $@ | array_flow.rb:1023:31:1023:43 | call to source | call to source | -| array_flow.rb:1028:10:1028:13 | ...[...] | array_flow.rb:1023:16:1023:28 | call to source | array_flow.rb:1028:10:1028:13 | ...[...] | $@ | array_flow.rb:1023:16:1023:28 | call to source | call to source | -| array_flow.rb:1028:10:1028:13 | ...[...] | array_flow.rb:1023:31:1023:43 | call to source | array_flow.rb:1028:10:1028:13 | ...[...] | $@ | array_flow.rb:1023:31:1023:43 | call to source | call to source | | array_flow.rb:1029:10:1029:13 | ...[...] | array_flow.rb:1023:16:1023:28 | call to source | array_flow.rb:1029:10:1029:13 | ...[...] | $@ | array_flow.rb:1023:16:1023:28 | call to source | call to source | -| array_flow.rb:1029:10:1029:13 | ...[...] | array_flow.rb:1023:31:1023:43 | call to source | array_flow.rb:1029:10:1029:13 | ...[...] | $@ | array_flow.rb:1023:31:1023:43 | call to source | call to source | -| array_flow.rb:1030:10:1030:13 | ...[...] | array_flow.rb:1023:16:1023:28 | call to source | array_flow.rb:1030:10:1030:13 | ...[...] | $@ | array_flow.rb:1023:16:1023:28 | call to source | call to source | | array_flow.rb:1030:10:1030:13 | ...[...] | array_flow.rb:1023:31:1023:43 | call to source | array_flow.rb:1030:10:1030:13 | ...[...] | $@ | array_flow.rb:1023:31:1023:43 | call to source | call to source | -| array_flow.rb:1036:14:1036:14 | x | array_flow.rb:1034:16:1034:26 | call to source | array_flow.rb:1036:14:1036:14 | x | $@ | array_flow.rb:1034:16:1034:26 | call to source | call to source | -| array_flow.rb:1038:10:1038:13 | ...[...] | array_flow.rb:1034:16:1034:26 | call to source | array_flow.rb:1038:10:1038:13 | ...[...] | $@ | array_flow.rb:1034:16:1034:26 | call to source | call to source | -| array_flow.rb:1044:14:1044:14 | x | array_flow.rb:1042:16:1042:26 | call to source | array_flow.rb:1044:14:1044:14 | x | $@ | array_flow.rb:1042:16:1042:26 | call to source | call to source | -| array_flow.rb:1055:10:1055:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1055:10:1055:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1056:10:1056:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1056:10:1056:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1056:10:1056:13 | ...[...] | array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1056:10:1056:13 | ...[...] | $@ | array_flow.rb:1052:28:1052:40 | call to source | call to source | -| array_flow.rb:1057:10:1057:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1057:10:1057:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1057:10:1057:13 | ...[...] | array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1057:10:1057:13 | ...[...] | $@ | array_flow.rb:1052:43:1052:55 | call to source | call to source | -| array_flow.rb:1058:10:1058:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1058:10:1058:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1061:10:1061:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1061:10:1061:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1061:10:1061:13 | ...[...] | array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1061:10:1061:13 | ...[...] | $@ | array_flow.rb:1052:28:1052:40 | call to source | call to source | -| array_flow.rb:1062:10:1062:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1062:10:1062:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1062:10:1062:13 | ...[...] | array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1062:10:1062:13 | ...[...] | $@ | array_flow.rb:1052:43:1052:55 | call to source | call to source | -| array_flow.rb:1063:10:1063:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1063:10:1063:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1064:10:1064:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1064:10:1064:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1067:10:1067:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1067:10:1067:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1069:10:1069:13 | ...[...] | array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1069:10:1069:13 | ...[...] | $@ | array_flow.rb:1052:28:1052:40 | call to source | call to source | -| array_flow.rb:1070:10:1070:13 | ...[...] | array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1070:10:1070:13 | ...[...] | $@ | array_flow.rb:1052:43:1052:55 | call to source | call to source | -| array_flow.rb:1073:10:1073:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1073:10:1073:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1073:10:1073:13 | ...[...] | array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1073:10:1073:13 | ...[...] | $@ | array_flow.rb:1052:28:1052:40 | call to source | call to source | -| array_flow.rb:1073:10:1073:13 | ...[...] | array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1073:10:1073:13 | ...[...] | $@ | array_flow.rb:1052:43:1052:55 | call to source | call to source | -| array_flow.rb:1074:10:1074:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1074:10:1074:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1074:10:1074:13 | ...[...] | array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1074:10:1074:13 | ...[...] | $@ | array_flow.rb:1052:28:1052:40 | call to source | call to source | -| array_flow.rb:1074:10:1074:13 | ...[...] | array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1074:10:1074:13 | ...[...] | $@ | array_flow.rb:1052:43:1052:55 | call to source | call to source | -| array_flow.rb:1075:10:1075:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1075:10:1075:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1075:10:1075:13 | ...[...] | array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1075:10:1075:13 | ...[...] | $@ | array_flow.rb:1052:28:1052:40 | call to source | call to source | -| array_flow.rb:1075:10:1075:13 | ...[...] | array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1075:10:1075:13 | ...[...] | $@ | array_flow.rb:1052:43:1052:55 | call to source | call to source | -| array_flow.rb:1076:10:1076:13 | ...[...] | array_flow.rb:1052:10:1052:22 | call to source | array_flow.rb:1076:10:1076:13 | ...[...] | $@ | array_flow.rb:1052:10:1052:22 | call to source | call to source | -| array_flow.rb:1076:10:1076:13 | ...[...] | array_flow.rb:1052:28:1052:40 | call to source | array_flow.rb:1076:10:1076:13 | ...[...] | $@ | array_flow.rb:1052:28:1052:40 | call to source | call to source | -| array_flow.rb:1076:10:1076:13 | ...[...] | array_flow.rb:1052:43:1052:55 | call to source | array_flow.rb:1076:10:1076:13 | ...[...] | $@ | array_flow.rb:1052:43:1052:55 | call to source | call to source | -| array_flow.rb:1086:10:1086:13 | ...[...] | array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1086:10:1086:13 | ...[...] | $@ | array_flow.rb:1084:10:1084:22 | call to source | call to source | -| array_flow.rb:1087:10:1087:13 | ...[...] | array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1087:10:1087:13 | ...[...] | $@ | array_flow.rb:1084:10:1084:22 | call to source | call to source | -| array_flow.rb:1087:10:1087:13 | ...[...] | array_flow.rb:1084:28:1084:40 | call to source | array_flow.rb:1087:10:1087:13 | ...[...] | $@ | array_flow.rb:1084:28:1084:40 | call to source | call to source | -| array_flow.rb:1088:10:1088:13 | ...[...] | array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1088:10:1088:13 | ...[...] | $@ | array_flow.rb:1084:10:1084:22 | call to source | call to source | -| array_flow.rb:1088:10:1088:13 | ...[...] | array_flow.rb:1084:43:1084:55 | call to source | array_flow.rb:1088:10:1088:13 | ...[...] | $@ | array_flow.rb:1084:43:1084:55 | call to source | call to source | -| array_flow.rb:1089:10:1089:13 | ...[...] | array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1089:10:1089:13 | ...[...] | $@ | array_flow.rb:1084:10:1084:22 | call to source | call to source | -| array_flow.rb:1090:10:1090:13 | ...[...] | array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1090:10:1090:13 | ...[...] | $@ | array_flow.rb:1084:10:1084:22 | call to source | call to source | -| array_flow.rb:1091:10:1091:13 | ...[...] | array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1091:10:1091:13 | ...[...] | $@ | array_flow.rb:1084:10:1084:22 | call to source | call to source | -| array_flow.rb:1091:10:1091:13 | ...[...] | array_flow.rb:1084:28:1084:40 | call to source | array_flow.rb:1091:10:1091:13 | ...[...] | $@ | array_flow.rb:1084:28:1084:40 | call to source | call to source | -| array_flow.rb:1092:10:1092:13 | ...[...] | array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1092:10:1092:13 | ...[...] | $@ | array_flow.rb:1084:10:1084:22 | call to source | call to source | -| array_flow.rb:1092:10:1092:13 | ...[...] | array_flow.rb:1084:43:1084:55 | call to source | array_flow.rb:1092:10:1092:13 | ...[...] | $@ | array_flow.rb:1084:43:1084:55 | call to source | call to source | -| array_flow.rb:1093:10:1093:13 | ...[...] | array_flow.rb:1084:10:1084:22 | call to source | array_flow.rb:1093:10:1093:13 | ...[...] | $@ | array_flow.rb:1084:10:1084:22 | call to source | call to source | +| array_flow.rb:1036:10:1036:13 | ...[...] | array_flow.rb:1034:16:1034:28 | call to source | array_flow.rb:1036:10:1036:13 | ...[...] | $@ | array_flow.rb:1034:16:1034:28 | call to source | call to source | +| array_flow.rb:1036:10:1036:13 | ...[...] | array_flow.rb:1034:31:1034:43 | call to source | array_flow.rb:1036:10:1036:13 | ...[...] | $@ | array_flow.rb:1034:31:1034:43 | call to source | call to source | +| array_flow.rb:1037:10:1037:13 | ...[...] | array_flow.rb:1034:16:1034:28 | call to source | array_flow.rb:1037:10:1037:13 | ...[...] | $@ | array_flow.rb:1034:16:1034:28 | call to source | call to source | +| array_flow.rb:1037:10:1037:13 | ...[...] | array_flow.rb:1034:31:1034:43 | call to source | array_flow.rb:1037:10:1037:13 | ...[...] | $@ | array_flow.rb:1034:31:1034:43 | call to source | call to source | +| array_flow.rb:1038:10:1038:13 | ...[...] | array_flow.rb:1034:16:1034:28 | call to source | array_flow.rb:1038:10:1038:13 | ...[...] | $@ | array_flow.rb:1034:16:1034:28 | call to source | call to source | +| array_flow.rb:1038:10:1038:13 | ...[...] | array_flow.rb:1034:31:1034:43 | call to source | array_flow.rb:1038:10:1038:13 | ...[...] | $@ | array_flow.rb:1034:31:1034:43 | call to source | call to source | +| array_flow.rb:1039:10:1039:13 | ...[...] | array_flow.rb:1034:16:1034:28 | call to source | array_flow.rb:1039:10:1039:13 | ...[...] | $@ | array_flow.rb:1034:16:1034:28 | call to source | call to source | +| array_flow.rb:1039:10:1039:13 | ...[...] | array_flow.rb:1034:31:1034:43 | call to source | array_flow.rb:1039:10:1039:13 | ...[...] | $@ | array_flow.rb:1034:31:1034:43 | call to source | call to source | +| array_flow.rb:1040:10:1040:13 | ...[...] | array_flow.rb:1034:16:1034:28 | call to source | array_flow.rb:1040:10:1040:13 | ...[...] | $@ | array_flow.rb:1034:16:1034:28 | call to source | call to source | +| array_flow.rb:1040:10:1040:13 | ...[...] | array_flow.rb:1034:31:1034:43 | call to source | array_flow.rb:1040:10:1040:13 | ...[...] | $@ | array_flow.rb:1034:31:1034:43 | call to source | call to source | +| array_flow.rb:1041:10:1041:13 | ...[...] | array_flow.rb:1034:16:1034:28 | call to source | array_flow.rb:1041:10:1041:13 | ...[...] | $@ | array_flow.rb:1034:16:1034:28 | call to source | call to source | +| array_flow.rb:1041:10:1041:13 | ...[...] | array_flow.rb:1034:31:1034:43 | call to source | array_flow.rb:1041:10:1041:13 | ...[...] | $@ | array_flow.rb:1034:31:1034:43 | call to source | call to source | +| array_flow.rb:1047:14:1047:14 | x | array_flow.rb:1045:16:1045:26 | call to source | array_flow.rb:1047:14:1047:14 | x | $@ | array_flow.rb:1045:16:1045:26 | call to source | call to source | +| array_flow.rb:1049:10:1049:13 | ...[...] | array_flow.rb:1045:16:1045:26 | call to source | array_flow.rb:1049:10:1049:13 | ...[...] | $@ | array_flow.rb:1045:16:1045:26 | call to source | call to source | +| array_flow.rb:1055:14:1055:14 | x | array_flow.rb:1053:16:1053:26 | call to source | array_flow.rb:1055:14:1055:14 | x | $@ | array_flow.rb:1053:16:1053:26 | call to source | call to source | +| array_flow.rb:1066:10:1066:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1066:10:1066:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1067:10:1067:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1067:10:1067:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1067:10:1067:13 | ...[...] | array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1067:10:1067:13 | ...[...] | $@ | array_flow.rb:1063:28:1063:40 | call to source | call to source | +| array_flow.rb:1068:10:1068:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1068:10:1068:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1068:10:1068:13 | ...[...] | array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1068:10:1068:13 | ...[...] | $@ | array_flow.rb:1063:43:1063:55 | call to source | call to source | +| array_flow.rb:1069:10:1069:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1069:10:1069:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1072:10:1072:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1072:10:1072:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1072:10:1072:13 | ...[...] | array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1072:10:1072:13 | ...[...] | $@ | array_flow.rb:1063:28:1063:40 | call to source | call to source | +| array_flow.rb:1073:10:1073:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1073:10:1073:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1073:10:1073:13 | ...[...] | array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1073:10:1073:13 | ...[...] | $@ | array_flow.rb:1063:43:1063:55 | call to source | call to source | +| array_flow.rb:1074:10:1074:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1074:10:1074:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1075:10:1075:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1075:10:1075:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1078:10:1078:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1078:10:1078:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1080:10:1080:13 | ...[...] | array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1080:10:1080:13 | ...[...] | $@ | array_flow.rb:1063:28:1063:40 | call to source | call to source | +| array_flow.rb:1081:10:1081:13 | ...[...] | array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1081:10:1081:13 | ...[...] | $@ | array_flow.rb:1063:43:1063:55 | call to source | call to source | +| array_flow.rb:1084:10:1084:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1084:10:1084:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1084:10:1084:13 | ...[...] | array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1084:10:1084:13 | ...[...] | $@ | array_flow.rb:1063:28:1063:40 | call to source | call to source | +| array_flow.rb:1084:10:1084:13 | ...[...] | array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1084:10:1084:13 | ...[...] | $@ | array_flow.rb:1063:43:1063:55 | call to source | call to source | +| array_flow.rb:1085:10:1085:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1085:10:1085:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1085:10:1085:13 | ...[...] | array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1085:10:1085:13 | ...[...] | $@ | array_flow.rb:1063:28:1063:40 | call to source | call to source | +| array_flow.rb:1085:10:1085:13 | ...[...] | array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1085:10:1085:13 | ...[...] | $@ | array_flow.rb:1063:43:1063:55 | call to source | call to source | +| array_flow.rb:1086:10:1086:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1086:10:1086:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1086:10:1086:13 | ...[...] | array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1086:10:1086:13 | ...[...] | $@ | array_flow.rb:1063:28:1063:40 | call to source | call to source | +| array_flow.rb:1086:10:1086:13 | ...[...] | array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1086:10:1086:13 | ...[...] | $@ | array_flow.rb:1063:43:1063:55 | call to source | call to source | +| array_flow.rb:1087:10:1087:13 | ...[...] | array_flow.rb:1063:10:1063:22 | call to source | array_flow.rb:1087:10:1087:13 | ...[...] | $@ | array_flow.rb:1063:10:1063:22 | call to source | call to source | +| array_flow.rb:1087:10:1087:13 | ...[...] | array_flow.rb:1063:28:1063:40 | call to source | array_flow.rb:1087:10:1087:13 | ...[...] | $@ | array_flow.rb:1063:28:1063:40 | call to source | call to source | +| array_flow.rb:1087:10:1087:13 | ...[...] | array_flow.rb:1063:43:1063:55 | call to source | array_flow.rb:1087:10:1087:13 | ...[...] | $@ | array_flow.rb:1063:43:1063:55 | call to source | call to source | | array_flow.rb:1097:10:1097:13 | ...[...] | array_flow.rb:1095:10:1095:22 | call to source | array_flow.rb:1097:10:1097:13 | ...[...] | $@ | array_flow.rb:1095:10:1095:22 | call to source | call to source | -| array_flow.rb:1097:10:1097:13 | ...[...] | array_flow.rb:1095:28:1095:40 | call to source | array_flow.rb:1097:10:1097:13 | ...[...] | $@ | array_flow.rb:1095:28:1095:40 | call to source | call to source | | array_flow.rb:1098:10:1098:13 | ...[...] | array_flow.rb:1095:10:1095:22 | call to source | array_flow.rb:1098:10:1098:13 | ...[...] | $@ | array_flow.rb:1095:10:1095:22 | call to source | call to source | -| array_flow.rb:1098:10:1098:13 | ...[...] | array_flow.rb:1095:43:1095:55 | call to source | array_flow.rb:1098:10:1098:13 | ...[...] | $@ | array_flow.rb:1095:43:1095:55 | call to source | call to source | +| array_flow.rb:1098:10:1098:13 | ...[...] | array_flow.rb:1095:28:1095:40 | call to source | array_flow.rb:1098:10:1098:13 | ...[...] | $@ | array_flow.rb:1095:28:1095:40 | call to source | call to source | | array_flow.rb:1099:10:1099:13 | ...[...] | array_flow.rb:1095:10:1095:22 | call to source | array_flow.rb:1099:10:1099:13 | ...[...] | $@ | array_flow.rb:1095:10:1095:22 | call to source | call to source | +| array_flow.rb:1099:10:1099:13 | ...[...] | array_flow.rb:1095:43:1095:55 | call to source | array_flow.rb:1099:10:1099:13 | ...[...] | $@ | array_flow.rb:1095:43:1095:55 | call to source | call to source | | array_flow.rb:1100:10:1100:13 | ...[...] | array_flow.rb:1095:10:1095:22 | call to source | array_flow.rb:1100:10:1100:13 | ...[...] | $@ | array_flow.rb:1095:10:1095:22 | call to source | call to source | | array_flow.rb:1101:10:1101:13 | ...[...] | array_flow.rb:1095:10:1095:22 | call to source | array_flow.rb:1101:10:1101:13 | ...[...] | $@ | array_flow.rb:1095:10:1095:22 | call to source | call to source | -| array_flow.rb:1101:10:1101:13 | ...[...] | array_flow.rb:1095:28:1095:40 | call to source | array_flow.rb:1101:10:1101:13 | ...[...] | $@ | array_flow.rb:1095:28:1095:40 | call to source | call to source | | array_flow.rb:1102:10:1102:13 | ...[...] | array_flow.rb:1095:10:1095:22 | call to source | array_flow.rb:1102:10:1102:13 | ...[...] | $@ | array_flow.rb:1095:10:1095:22 | call to source | call to source | -| array_flow.rb:1102:10:1102:13 | ...[...] | array_flow.rb:1095:43:1095:55 | call to source | array_flow.rb:1102:10:1102:13 | ...[...] | $@ | array_flow.rb:1095:43:1095:55 | call to source | call to source | +| array_flow.rb:1102:10:1102:13 | ...[...] | array_flow.rb:1095:28:1095:40 | call to source | array_flow.rb:1102:10:1102:13 | ...[...] | $@ | array_flow.rb:1095:28:1095:40 | call to source | call to source | | array_flow.rb:1103:10:1103:13 | ...[...] | array_flow.rb:1095:10:1095:22 | call to source | array_flow.rb:1103:10:1103:13 | ...[...] | $@ | array_flow.rb:1095:10:1095:22 | call to source | call to source | +| array_flow.rb:1103:10:1103:13 | ...[...] | array_flow.rb:1095:43:1095:55 | call to source | array_flow.rb:1103:10:1103:13 | ...[...] | $@ | array_flow.rb:1095:43:1095:55 | call to source | call to source | | array_flow.rb:1104:10:1104:13 | ...[...] | array_flow.rb:1095:10:1095:22 | call to source | array_flow.rb:1104:10:1104:13 | ...[...] | $@ | array_flow.rb:1095:10:1095:22 | call to source | call to source | | array_flow.rb:1108:10:1108:13 | ...[...] | array_flow.rb:1106:10:1106:22 | call to source | array_flow.rb:1108:10:1108:13 | ...[...] | $@ | array_flow.rb:1106:10:1106:22 | call to source | call to source | -| array_flow.rb:1110:10:1110:13 | ...[...] | array_flow.rb:1106:28:1106:40 | call to source | array_flow.rb:1110:10:1110:13 | ...[...] | $@ | array_flow.rb:1106:28:1106:40 | call to source | call to source | -| array_flow.rb:1111:10:1111:13 | ...[...] | array_flow.rb:1106:43:1106:55 | call to source | array_flow.rb:1111:10:1111:13 | ...[...] | $@ | array_flow.rb:1106:43:1106:55 | call to source | call to source | +| array_flow.rb:1108:10:1108:13 | ...[...] | array_flow.rb:1106:28:1106:40 | call to source | array_flow.rb:1108:10:1108:13 | ...[...] | $@ | array_flow.rb:1106:28:1106:40 | call to source | call to source | +| array_flow.rb:1109:10:1109:13 | ...[...] | array_flow.rb:1106:10:1106:22 | call to source | array_flow.rb:1109:10:1109:13 | ...[...] | $@ | array_flow.rb:1106:10:1106:22 | call to source | call to source | +| array_flow.rb:1109:10:1109:13 | ...[...] | array_flow.rb:1106:43:1106:55 | call to source | array_flow.rb:1109:10:1109:13 | ...[...] | $@ | array_flow.rb:1106:43:1106:55 | call to source | call to source | +| array_flow.rb:1110:10:1110:13 | ...[...] | array_flow.rb:1106:10:1106:22 | call to source | array_flow.rb:1110:10:1110:13 | ...[...] | $@ | array_flow.rb:1106:10:1106:22 | call to source | call to source | +| array_flow.rb:1111:10:1111:13 | ...[...] | array_flow.rb:1106:10:1106:22 | call to source | array_flow.rb:1111:10:1111:13 | ...[...] | $@ | array_flow.rb:1106:10:1106:22 | call to source | call to source | | array_flow.rb:1112:10:1112:13 | ...[...] | array_flow.rb:1106:10:1106:22 | call to source | array_flow.rb:1112:10:1112:13 | ...[...] | $@ | array_flow.rb:1106:10:1106:22 | call to source | call to source | -| array_flow.rb:1114:10:1114:13 | ...[...] | array_flow.rb:1106:28:1106:40 | call to source | array_flow.rb:1114:10:1114:13 | ...[...] | $@ | array_flow.rb:1106:28:1106:40 | call to source | call to source | -| array_flow.rb:1115:10:1115:13 | ...[...] | array_flow.rb:1106:43:1106:55 | call to source | array_flow.rb:1115:10:1115:13 | ...[...] | $@ | array_flow.rb:1106:43:1106:55 | call to source | call to source | +| array_flow.rb:1112:10:1112:13 | ...[...] | array_flow.rb:1106:28:1106:40 | call to source | array_flow.rb:1112:10:1112:13 | ...[...] | $@ | array_flow.rb:1106:28:1106:40 | call to source | call to source | +| array_flow.rb:1113:10:1113:13 | ...[...] | array_flow.rb:1106:10:1106:22 | call to source | array_flow.rb:1113:10:1113:13 | ...[...] | $@ | array_flow.rb:1106:10:1106:22 | call to source | call to source | +| array_flow.rb:1113:10:1113:13 | ...[...] | array_flow.rb:1106:43:1106:55 | call to source | array_flow.rb:1113:10:1113:13 | ...[...] | $@ | array_flow.rb:1106:43:1106:55 | call to source | call to source | +| array_flow.rb:1114:10:1114:13 | ...[...] | array_flow.rb:1106:10:1106:22 | call to source | array_flow.rb:1114:10:1114:13 | ...[...] | $@ | array_flow.rb:1106:10:1106:22 | call to source | call to source | +| array_flow.rb:1115:10:1115:13 | ...[...] | array_flow.rb:1106:10:1106:22 | call to source | array_flow.rb:1115:10:1115:13 | ...[...] | $@ | array_flow.rb:1106:10:1106:22 | call to source | call to source | | array_flow.rb:1119:10:1119:13 | ...[...] | array_flow.rb:1117:10:1117:22 | call to source | array_flow.rb:1119:10:1119:13 | ...[...] | $@ | array_flow.rb:1117:10:1117:22 | call to source | call to source | -| array_flow.rb:1119:10:1119:13 | ...[...] | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1119:10:1119:13 | ...[...] | $@ | array_flow.rb:1117:28:1117:40 | call to source | call to source | -| array_flow.rb:1119:10:1119:13 | ...[...] | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1119:10:1119:13 | ...[...] | $@ | array_flow.rb:1117:43:1117:55 | call to source | call to source | -| array_flow.rb:1120:10:1120:13 | ...[...] | array_flow.rb:1117:10:1117:22 | call to source | array_flow.rb:1120:10:1120:13 | ...[...] | $@ | array_flow.rb:1117:10:1117:22 | call to source | call to source | -| array_flow.rb:1120:10:1120:13 | ...[...] | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1120:10:1120:13 | ...[...] | $@ | array_flow.rb:1117:28:1117:40 | call to source | call to source | -| array_flow.rb:1120:10:1120:13 | ...[...] | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1120:10:1120:13 | ...[...] | $@ | array_flow.rb:1117:43:1117:55 | call to source | call to source | -| array_flow.rb:1121:10:1121:13 | ...[...] | array_flow.rb:1117:10:1117:22 | call to source | array_flow.rb:1121:10:1121:13 | ...[...] | $@ | array_flow.rb:1117:10:1117:22 | call to source | call to source | | array_flow.rb:1121:10:1121:13 | ...[...] | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1121:10:1121:13 | ...[...] | $@ | array_flow.rb:1117:28:1117:40 | call to source | call to source | -| array_flow.rb:1121:10:1121:13 | ...[...] | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1121:10:1121:13 | ...[...] | $@ | array_flow.rb:1117:43:1117:55 | call to source | call to source | -| array_flow.rb:1122:10:1122:13 | ...[...] | array_flow.rb:1117:10:1117:22 | call to source | array_flow.rb:1122:10:1122:13 | ...[...] | $@ | array_flow.rb:1117:10:1117:22 | call to source | call to source | -| array_flow.rb:1122:10:1122:13 | ...[...] | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1122:10:1122:13 | ...[...] | $@ | array_flow.rb:1117:28:1117:40 | call to source | call to source | | array_flow.rb:1122:10:1122:13 | ...[...] | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1122:10:1122:13 | ...[...] | $@ | array_flow.rb:1117:43:1117:55 | call to source | call to source | | array_flow.rb:1123:10:1123:13 | ...[...] | array_flow.rb:1117:10:1117:22 | call to source | array_flow.rb:1123:10:1123:13 | ...[...] | $@ | array_flow.rb:1117:10:1117:22 | call to source | call to source | -| array_flow.rb:1123:10:1123:13 | ...[...] | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1123:10:1123:13 | ...[...] | $@ | array_flow.rb:1117:28:1117:40 | call to source | call to source | -| array_flow.rb:1123:10:1123:13 | ...[...] | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1123:10:1123:13 | ...[...] | $@ | array_flow.rb:1117:43:1117:55 | call to source | call to source | -| array_flow.rb:1124:10:1124:13 | ...[...] | array_flow.rb:1117:10:1117:22 | call to source | array_flow.rb:1124:10:1124:13 | ...[...] | $@ | array_flow.rb:1117:10:1117:22 | call to source | call to source | -| array_flow.rb:1124:10:1124:13 | ...[...] | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1124:10:1124:13 | ...[...] | $@ | array_flow.rb:1117:28:1117:40 | call to source | call to source | -| array_flow.rb:1124:10:1124:13 | ...[...] | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1124:10:1124:13 | ...[...] | $@ | array_flow.rb:1117:43:1117:55 | call to source | call to source | -| array_flow.rb:1125:10:1125:13 | ...[...] | array_flow.rb:1117:10:1117:22 | call to source | array_flow.rb:1125:10:1125:13 | ...[...] | $@ | array_flow.rb:1117:10:1117:22 | call to source | call to source | | array_flow.rb:1125:10:1125:13 | ...[...] | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1125:10:1125:13 | ...[...] | $@ | array_flow.rb:1117:28:1117:40 | call to source | call to source | -| array_flow.rb:1125:10:1125:13 | ...[...] | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1125:10:1125:13 | ...[...] | $@ | array_flow.rb:1117:43:1117:55 | call to source | call to source | -| array_flow.rb:1126:10:1126:13 | ...[...] | array_flow.rb:1117:10:1117:22 | call to source | array_flow.rb:1126:10:1126:13 | ...[...] | $@ | array_flow.rb:1117:10:1117:22 | call to source | call to source | -| array_flow.rb:1126:10:1126:13 | ...[...] | array_flow.rb:1117:28:1117:40 | call to source | array_flow.rb:1126:10:1126:13 | ...[...] | $@ | array_flow.rb:1117:28:1117:40 | call to source | call to source | | array_flow.rb:1126:10:1126:13 | ...[...] | array_flow.rb:1117:43:1117:55 | call to source | array_flow.rb:1126:10:1126:13 | ...[...] | $@ | array_flow.rb:1117:43:1117:55 | call to source | call to source | -| array_flow.rb:1132:14:1132:14 | x | array_flow.rb:1130:19:1130:29 | call to source | array_flow.rb:1132:14:1132:14 | x | $@ | array_flow.rb:1130:19:1130:29 | call to source | call to source | -| array_flow.rb:1134:10:1134:13 | ...[...] | array_flow.rb:1130:19:1130:29 | call to source | array_flow.rb:1134:10:1134:13 | ...[...] | $@ | array_flow.rb:1130:19:1130:29 | call to source | call to source | -| array_flow.rb:1140:14:1140:14 | x | array_flow.rb:1138:16:1138:26 | call to source | array_flow.rb:1140:14:1140:14 | x | $@ | array_flow.rb:1138:16:1138:26 | call to source | call to source | -| array_flow.rb:1143:10:1143:13 | ...[...] | array_flow.rb:1138:16:1138:26 | call to source | array_flow.rb:1143:10:1143:13 | ...[...] | $@ | array_flow.rb:1138:16:1138:26 | call to source | call to source | -| array_flow.rb:1144:10:1144:13 | ...[...] | array_flow.rb:1138:16:1138:26 | call to source | array_flow.rb:1144:10:1144:13 | ...[...] | $@ | array_flow.rb:1138:16:1138:26 | call to source | call to source | -| array_flow.rb:1150:10:1150:10 | b | array_flow.rb:1148:10:1148:22 | call to source | array_flow.rb:1150:10:1150:10 | b | $@ | array_flow.rb:1148:10:1148:22 | call to source | call to source | -| array_flow.rb:1152:10:1152:13 | ...[...] | array_flow.rb:1148:28:1148:40 | call to source | array_flow.rb:1152:10:1152:13 | ...[...] | $@ | array_flow.rb:1148:28:1148:40 | call to source | call to source | -| array_flow.rb:1157:10:1157:13 | ...[...] | array_flow.rb:1155:10:1155:22 | call to source | array_flow.rb:1157:10:1157:13 | ...[...] | $@ | array_flow.rb:1155:10:1155:22 | call to source | call to source | -| array_flow.rb:1159:10:1159:13 | ...[...] | array_flow.rb:1155:28:1155:40 | call to source | array_flow.rb:1159:10:1159:13 | ...[...] | $@ | array_flow.rb:1155:28:1155:40 | call to source | call to source | -| array_flow.rb:1165:10:1165:13 | ...[...] | array_flow.rb:1163:10:1163:22 | call to source | array_flow.rb:1165:10:1165:13 | ...[...] | $@ | array_flow.rb:1163:10:1163:22 | call to source | call to source | -| array_flow.rb:1165:10:1165:13 | ...[...] | array_flow.rb:1163:28:1163:40 | call to source | array_flow.rb:1165:10:1165:13 | ...[...] | $@ | array_flow.rb:1163:28:1163:40 | call to source | call to source | -| array_flow.rb:1166:10:1166:13 | ...[...] | array_flow.rb:1163:10:1163:22 | call to source | array_flow.rb:1166:10:1166:13 | ...[...] | $@ | array_flow.rb:1163:10:1163:22 | call to source | call to source | -| array_flow.rb:1166:10:1166:13 | ...[...] | array_flow.rb:1163:28:1163:40 | call to source | array_flow.rb:1166:10:1166:13 | ...[...] | $@ | array_flow.rb:1163:28:1163:40 | call to source | call to source | -| array_flow.rb:1167:10:1167:13 | ...[...] | array_flow.rb:1163:10:1163:22 | call to source | array_flow.rb:1167:10:1167:13 | ...[...] | $@ | array_flow.rb:1163:10:1163:22 | call to source | call to source | -| array_flow.rb:1167:10:1167:13 | ...[...] | array_flow.rb:1163:28:1163:40 | call to source | array_flow.rb:1167:10:1167:13 | ...[...] | $@ | array_flow.rb:1163:28:1163:40 | call to source | call to source | -| array_flow.rb:1168:10:1168:13 | ...[...] | array_flow.rb:1163:10:1163:22 | call to source | array_flow.rb:1168:10:1168:13 | ...[...] | $@ | array_flow.rb:1163:10:1163:22 | call to source | call to source | -| array_flow.rb:1168:10:1168:13 | ...[...] | array_flow.rb:1163:28:1163:40 | call to source | array_flow.rb:1168:10:1168:13 | ...[...] | $@ | array_flow.rb:1163:28:1163:40 | call to source | call to source | -| array_flow.rb:1169:10:1169:13 | ...[...] | array_flow.rb:1163:10:1163:22 | call to source | array_flow.rb:1169:10:1169:13 | ...[...] | $@ | array_flow.rb:1163:10:1163:22 | call to source | call to source | -| array_flow.rb:1169:10:1169:13 | ...[...] | array_flow.rb:1163:28:1163:40 | call to source | array_flow.rb:1169:10:1169:13 | ...[...] | $@ | array_flow.rb:1163:28:1163:40 | call to source | call to source | -| array_flow.rb:1177:10:1177:13 | ...[...] | array_flow.rb:1173:16:1173:26 | call to source | array_flow.rb:1177:10:1177:13 | ...[...] | $@ | array_flow.rb:1173:16:1173:26 | call to source | call to source | -| array_flow.rb:1178:10:1178:13 | ...[...] | array_flow.rb:1173:16:1173:26 | call to source | array_flow.rb:1178:10:1178:13 | ...[...] | $@ | array_flow.rb:1173:16:1173:26 | call to source | call to source | -| array_flow.rb:1179:10:1179:13 | ...[...] | array_flow.rb:1173:16:1173:26 | call to source | array_flow.rb:1179:10:1179:13 | ...[...] | $@ | array_flow.rb:1173:16:1173:26 | call to source | call to source | -| array_flow.rb:1180:10:1180:13 | ...[...] | array_flow.rb:1173:16:1173:26 | call to source | array_flow.rb:1180:10:1180:13 | ...[...] | $@ | array_flow.rb:1173:16:1173:26 | call to source | call to source | -| array_flow.rb:1186:10:1186:13 | ...[...] | array_flow.rb:1184:16:1184:26 | call to source | array_flow.rb:1186:10:1186:13 | ...[...] | $@ | array_flow.rb:1184:16:1184:26 | call to source | call to source | -| array_flow.rb:1187:10:1187:13 | ...[...] | array_flow.rb:1184:16:1184:26 | call to source | array_flow.rb:1187:10:1187:13 | ...[...] | $@ | array_flow.rb:1184:16:1184:26 | call to source | call to source | +| array_flow.rb:1130:10:1130:13 | ...[...] | array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1130:10:1130:13 | ...[...] | $@ | array_flow.rb:1128:10:1128:22 | call to source | call to source | +| array_flow.rb:1130:10:1130:13 | ...[...] | array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1130:10:1130:13 | ...[...] | $@ | array_flow.rb:1128:28:1128:40 | call to source | call to source | +| array_flow.rb:1130:10:1130:13 | ...[...] | array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1130:10:1130:13 | ...[...] | $@ | array_flow.rb:1128:43:1128:55 | call to source | call to source | +| array_flow.rb:1131:10:1131:13 | ...[...] | array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1131:10:1131:13 | ...[...] | $@ | array_flow.rb:1128:10:1128:22 | call to source | call to source | +| array_flow.rb:1131:10:1131:13 | ...[...] | array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1131:10:1131:13 | ...[...] | $@ | array_flow.rb:1128:28:1128:40 | call to source | call to source | +| array_flow.rb:1131:10:1131:13 | ...[...] | array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1131:10:1131:13 | ...[...] | $@ | array_flow.rb:1128:43:1128:55 | call to source | call to source | +| array_flow.rb:1132:10:1132:13 | ...[...] | array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1132:10:1132:13 | ...[...] | $@ | array_flow.rb:1128:10:1128:22 | call to source | call to source | +| array_flow.rb:1132:10:1132:13 | ...[...] | array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1132:10:1132:13 | ...[...] | $@ | array_flow.rb:1128:28:1128:40 | call to source | call to source | +| array_flow.rb:1132:10:1132:13 | ...[...] | array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1132:10:1132:13 | ...[...] | $@ | array_flow.rb:1128:43:1128:55 | call to source | call to source | +| array_flow.rb:1133:10:1133:13 | ...[...] | array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1133:10:1133:13 | ...[...] | $@ | array_flow.rb:1128:10:1128:22 | call to source | call to source | +| array_flow.rb:1133:10:1133:13 | ...[...] | array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1133:10:1133:13 | ...[...] | $@ | array_flow.rb:1128:28:1128:40 | call to source | call to source | +| array_flow.rb:1133:10:1133:13 | ...[...] | array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1133:10:1133:13 | ...[...] | $@ | array_flow.rb:1128:43:1128:55 | call to source | call to source | +| array_flow.rb:1134:10:1134:13 | ...[...] | array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1134:10:1134:13 | ...[...] | $@ | array_flow.rb:1128:10:1128:22 | call to source | call to source | +| array_flow.rb:1134:10:1134:13 | ...[...] | array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1134:10:1134:13 | ...[...] | $@ | array_flow.rb:1128:28:1128:40 | call to source | call to source | +| array_flow.rb:1134:10:1134:13 | ...[...] | array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1134:10:1134:13 | ...[...] | $@ | array_flow.rb:1128:43:1128:55 | call to source | call to source | +| array_flow.rb:1135:10:1135:13 | ...[...] | array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1135:10:1135:13 | ...[...] | $@ | array_flow.rb:1128:10:1128:22 | call to source | call to source | +| array_flow.rb:1135:10:1135:13 | ...[...] | array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1135:10:1135:13 | ...[...] | $@ | array_flow.rb:1128:28:1128:40 | call to source | call to source | +| array_flow.rb:1135:10:1135:13 | ...[...] | array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1135:10:1135:13 | ...[...] | $@ | array_flow.rb:1128:43:1128:55 | call to source | call to source | +| array_flow.rb:1136:10:1136:13 | ...[...] | array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1136:10:1136:13 | ...[...] | $@ | array_flow.rb:1128:10:1128:22 | call to source | call to source | +| array_flow.rb:1136:10:1136:13 | ...[...] | array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1136:10:1136:13 | ...[...] | $@ | array_flow.rb:1128:28:1128:40 | call to source | call to source | +| array_flow.rb:1136:10:1136:13 | ...[...] | array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1136:10:1136:13 | ...[...] | $@ | array_flow.rb:1128:43:1128:55 | call to source | call to source | +| array_flow.rb:1137:10:1137:13 | ...[...] | array_flow.rb:1128:10:1128:22 | call to source | array_flow.rb:1137:10:1137:13 | ...[...] | $@ | array_flow.rb:1128:10:1128:22 | call to source | call to source | +| array_flow.rb:1137:10:1137:13 | ...[...] | array_flow.rb:1128:28:1128:40 | call to source | array_flow.rb:1137:10:1137:13 | ...[...] | $@ | array_flow.rb:1128:28:1128:40 | call to source | call to source | +| array_flow.rb:1137:10:1137:13 | ...[...] | array_flow.rb:1128:43:1128:55 | call to source | array_flow.rb:1137:10:1137:13 | ...[...] | $@ | array_flow.rb:1128:43:1128:55 | call to source | call to source | +| array_flow.rb:1143:14:1143:14 | x | array_flow.rb:1141:19:1141:29 | call to source | array_flow.rb:1143:14:1143:14 | x | $@ | array_flow.rb:1141:19:1141:29 | call to source | call to source | +| array_flow.rb:1145:10:1145:13 | ...[...] | array_flow.rb:1141:19:1141:29 | call to source | array_flow.rb:1145:10:1145:13 | ...[...] | $@ | array_flow.rb:1141:19:1141:29 | call to source | call to source | +| array_flow.rb:1151:14:1151:14 | x | array_flow.rb:1149:16:1149:26 | call to source | array_flow.rb:1151:14:1151:14 | x | $@ | array_flow.rb:1149:16:1149:26 | call to source | call to source | +| array_flow.rb:1154:10:1154:13 | ...[...] | array_flow.rb:1149:16:1149:26 | call to source | array_flow.rb:1154:10:1154:13 | ...[...] | $@ | array_flow.rb:1149:16:1149:26 | call to source | call to source | +| array_flow.rb:1155:10:1155:13 | ...[...] | array_flow.rb:1149:16:1149:26 | call to source | array_flow.rb:1155:10:1155:13 | ...[...] | $@ | array_flow.rb:1149:16:1149:26 | call to source | call to source | +| array_flow.rb:1161:10:1161:10 | b | array_flow.rb:1159:10:1159:22 | call to source | array_flow.rb:1161:10:1161:10 | b | $@ | array_flow.rb:1159:10:1159:22 | call to source | call to source | +| array_flow.rb:1163:10:1163:13 | ...[...] | array_flow.rb:1159:28:1159:40 | call to source | array_flow.rb:1163:10:1163:13 | ...[...] | $@ | array_flow.rb:1159:28:1159:40 | call to source | call to source | +| array_flow.rb:1168:10:1168:13 | ...[...] | array_flow.rb:1166:10:1166:22 | call to source | array_flow.rb:1168:10:1168:13 | ...[...] | $@ | array_flow.rb:1166:10:1166:22 | call to source | call to source | +| array_flow.rb:1170:10:1170:13 | ...[...] | array_flow.rb:1166:28:1166:40 | call to source | array_flow.rb:1170:10:1170:13 | ...[...] | $@ | array_flow.rb:1166:28:1166:40 | call to source | call to source | +| array_flow.rb:1176:10:1176:13 | ...[...] | array_flow.rb:1174:10:1174:22 | call to source | array_flow.rb:1176:10:1176:13 | ...[...] | $@ | array_flow.rb:1174:10:1174:22 | call to source | call to source | +| array_flow.rb:1176:10:1176:13 | ...[...] | array_flow.rb:1174:28:1174:40 | call to source | array_flow.rb:1176:10:1176:13 | ...[...] | $@ | array_flow.rb:1174:28:1174:40 | call to source | call to source | +| array_flow.rb:1177:10:1177:13 | ...[...] | array_flow.rb:1174:10:1174:22 | call to source | array_flow.rb:1177:10:1177:13 | ...[...] | $@ | array_flow.rb:1174:10:1174:22 | call to source | call to source | +| array_flow.rb:1177:10:1177:13 | ...[...] | array_flow.rb:1174:28:1174:40 | call to source | array_flow.rb:1177:10:1177:13 | ...[...] | $@ | array_flow.rb:1174:28:1174:40 | call to source | call to source | +| array_flow.rb:1178:10:1178:13 | ...[...] | array_flow.rb:1174:10:1174:22 | call to source | array_flow.rb:1178:10:1178:13 | ...[...] | $@ | array_flow.rb:1174:10:1174:22 | call to source | call to source | +| array_flow.rb:1178:10:1178:13 | ...[...] | array_flow.rb:1174:28:1174:40 | call to source | array_flow.rb:1178:10:1178:13 | ...[...] | $@ | array_flow.rb:1174:28:1174:40 | call to source | call to source | +| array_flow.rb:1179:10:1179:13 | ...[...] | array_flow.rb:1174:10:1174:22 | call to source | array_flow.rb:1179:10:1179:13 | ...[...] | $@ | array_flow.rb:1174:10:1174:22 | call to source | call to source | +| array_flow.rb:1179:10:1179:13 | ...[...] | array_flow.rb:1174:28:1174:40 | call to source | array_flow.rb:1179:10:1179:13 | ...[...] | $@ | array_flow.rb:1174:28:1174:40 | call to source | call to source | +| array_flow.rb:1180:10:1180:13 | ...[...] | array_flow.rb:1174:10:1174:22 | call to source | array_flow.rb:1180:10:1180:13 | ...[...] | $@ | array_flow.rb:1174:10:1174:22 | call to source | call to source | +| array_flow.rb:1180:10:1180:13 | ...[...] | array_flow.rb:1174:28:1174:40 | call to source | array_flow.rb:1180:10:1180:13 | ...[...] | $@ | array_flow.rb:1174:28:1174:40 | call to source | call to source | | array_flow.rb:1188:10:1188:13 | ...[...] | array_flow.rb:1184:16:1184:26 | call to source | array_flow.rb:1188:10:1188:13 | ...[...] | $@ | array_flow.rb:1184:16:1184:26 | call to source | call to source | | array_flow.rb:1189:10:1189:13 | ...[...] | array_flow.rb:1184:16:1184:26 | call to source | array_flow.rb:1189:10:1189:13 | ...[...] | $@ | array_flow.rb:1184:16:1184:26 | call to source | call to source | | array_flow.rb:1190:10:1190:13 | ...[...] | array_flow.rb:1184:16:1184:26 | call to source | array_flow.rb:1190:10:1190:13 | ...[...] | $@ | array_flow.rb:1184:16:1184:26 | call to source | call to source | | array_flow.rb:1191:10:1191:13 | ...[...] | array_flow.rb:1184:16:1184:26 | call to source | array_flow.rb:1191:10:1191:13 | ...[...] | $@ | array_flow.rb:1184:16:1184:26 | call to source | call to source | -| array_flow.rb:1198:10:1198:10 | b | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1198:10:1198:10 | b | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1201:10:1201:10 | b | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1201:10:1201:10 | b | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1201:10:1201:10 | b | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1201:10:1201:10 | b | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1205:10:1205:10 | b | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1205:10:1205:10 | b | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1205:10:1205:10 | b | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1205:10:1205:10 | b | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1207:10:1207:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1207:10:1207:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1207:10:1207:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1207:10:1207:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1210:10:1210:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1210:10:1210:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1212:10:1212:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1212:10:1212:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1215:10:1215:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1215:10:1215:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1215:10:1215:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1215:10:1215:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1216:10:1216:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1216:10:1216:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1216:10:1216:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1216:10:1216:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1219:10:1219:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1219:10:1219:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1224:10:1224:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1224:10:1224:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1229:10:1229:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1229:10:1229:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1229:10:1229:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1229:10:1229:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1230:10:1230:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1230:10:1230:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1230:10:1230:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1230:10:1230:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1233:10:1233:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1233:10:1233:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1233:10:1233:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1233:10:1233:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1234:10:1234:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1234:10:1234:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1234:10:1234:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1234:10:1234:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1239:10:1239:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1239:10:1239:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1242:10:1242:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1242:10:1242:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1242:10:1242:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1242:10:1242:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1243:10:1243:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1243:10:1243:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1243:10:1243:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1243:10:1243:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1244:10:1244:13 | ...[...] | array_flow.rb:1195:16:1195:28 | call to source | array_flow.rb:1244:10:1244:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:28 | call to source | call to source | -| array_flow.rb:1244:10:1244:13 | ...[...] | array_flow.rb:1195:34:1195:46 | call to source | array_flow.rb:1244:10:1244:13 | ...[...] | $@ | array_flow.rb:1195:34:1195:46 | call to source | call to source | -| array_flow.rb:1250:10:1250:10 | b | array_flow.rb:1248:16:1248:28 | call to source | array_flow.rb:1250:10:1250:10 | b | $@ | array_flow.rb:1248:16:1248:28 | call to source | call to source | -| array_flow.rb:1254:10:1254:13 | ...[...] | array_flow.rb:1248:34:1248:46 | call to source | array_flow.rb:1254:10:1254:13 | ...[...] | $@ | array_flow.rb:1248:34:1248:46 | call to source | call to source | -| array_flow.rb:1258:10:1258:13 | ...[...] | array_flow.rb:1256:16:1256:28 | call to source | array_flow.rb:1258:10:1258:13 | ...[...] | $@ | array_flow.rb:1256:16:1256:28 | call to source | call to source | -| array_flow.rb:1258:10:1258:13 | ...[...] | array_flow.rb:1256:34:1256:46 | call to source | array_flow.rb:1258:10:1258:13 | ...[...] | $@ | array_flow.rb:1256:34:1256:46 | call to source | call to source | -| array_flow.rb:1259:10:1259:13 | ...[...] | array_flow.rb:1256:16:1256:28 | call to source | array_flow.rb:1259:10:1259:13 | ...[...] | $@ | array_flow.rb:1256:16:1256:28 | call to source | call to source | -| array_flow.rb:1259:10:1259:13 | ...[...] | array_flow.rb:1256:34:1256:46 | call to source | array_flow.rb:1259:10:1259:13 | ...[...] | $@ | array_flow.rb:1256:34:1256:46 | call to source | call to source | -| array_flow.rb:1260:10:1260:13 | ...[...] | array_flow.rb:1256:16:1256:28 | call to source | array_flow.rb:1260:10:1260:13 | ...[...] | $@ | array_flow.rb:1256:16:1256:28 | call to source | call to source | -| array_flow.rb:1260:10:1260:13 | ...[...] | array_flow.rb:1256:34:1256:46 | call to source | array_flow.rb:1260:10:1260:13 | ...[...] | $@ | array_flow.rb:1256:34:1256:46 | call to source | call to source | -| array_flow.rb:1261:10:1261:13 | ...[...] | array_flow.rb:1256:16:1256:28 | call to source | array_flow.rb:1261:10:1261:13 | ...[...] | $@ | array_flow.rb:1256:16:1256:28 | call to source | call to source | -| array_flow.rb:1261:10:1261:13 | ...[...] | array_flow.rb:1256:34:1256:46 | call to source | array_flow.rb:1261:10:1261:13 | ...[...] | $@ | array_flow.rb:1256:34:1256:46 | call to source | call to source | -| array_flow.rb:1263:10:1263:10 | b | array_flow.rb:1256:16:1256:28 | call to source | array_flow.rb:1263:10:1263:10 | b | $@ | array_flow.rb:1256:16:1256:28 | call to source | call to source | -| array_flow.rb:1263:10:1263:10 | b | array_flow.rb:1256:34:1256:46 | call to source | array_flow.rb:1263:10:1263:10 | b | $@ | array_flow.rb:1256:34:1256:46 | call to source | call to source | -| array_flow.rb:1265:10:1265:13 | ...[...] | array_flow.rb:1256:16:1256:28 | call to source | array_flow.rb:1265:10:1265:13 | ...[...] | $@ | array_flow.rb:1256:16:1256:28 | call to source | call to source | -| array_flow.rb:1265:10:1265:13 | ...[...] | array_flow.rb:1256:34:1256:46 | call to source | array_flow.rb:1265:10:1265:13 | ...[...] | $@ | array_flow.rb:1256:34:1256:46 | call to source | call to source | +| array_flow.rb:1197:10:1197:13 | ...[...] | array_flow.rb:1195:16:1195:26 | call to source | array_flow.rb:1197:10:1197:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:26 | call to source | call to source | +| array_flow.rb:1198:10:1198:13 | ...[...] | array_flow.rb:1195:16:1195:26 | call to source | array_flow.rb:1198:10:1198:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:26 | call to source | call to source | +| array_flow.rb:1199:10:1199:13 | ...[...] | array_flow.rb:1195:16:1195:26 | call to source | array_flow.rb:1199:10:1199:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:26 | call to source | call to source | +| array_flow.rb:1200:10:1200:13 | ...[...] | array_flow.rb:1195:16:1195:26 | call to source | array_flow.rb:1200:10:1200:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:26 | call to source | call to source | +| array_flow.rb:1201:10:1201:13 | ...[...] | array_flow.rb:1195:16:1195:26 | call to source | array_flow.rb:1201:10:1201:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:26 | call to source | call to source | +| array_flow.rb:1202:10:1202:13 | ...[...] | array_flow.rb:1195:16:1195:26 | call to source | array_flow.rb:1202:10:1202:13 | ...[...] | $@ | array_flow.rb:1195:16:1195:26 | call to source | call to source | +| array_flow.rb:1209:10:1209:10 | b | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1209:10:1209:10 | b | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1212:10:1212:10 | b | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1212:10:1212:10 | b | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1212:10:1212:10 | b | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1212:10:1212:10 | b | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1216:10:1216:10 | b | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1216:10:1216:10 | b | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1216:10:1216:10 | b | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1216:10:1216:10 | b | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1218:10:1218:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1218:10:1218:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1218:10:1218:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1218:10:1218:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1221:10:1221:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1221:10:1221:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1223:10:1223:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1223:10:1223:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1226:10:1226:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1226:10:1226:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1226:10:1226:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1226:10:1226:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1227:10:1227:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1227:10:1227:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1227:10:1227:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1227:10:1227:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1230:10:1230:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1230:10:1230:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1235:10:1235:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1235:10:1235:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1240:10:1240:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1240:10:1240:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1240:10:1240:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1240:10:1240:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1241:10:1241:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1241:10:1241:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1241:10:1241:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1241:10:1241:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1244:10:1244:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1244:10:1244:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1244:10:1244:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1244:10:1244:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1245:10:1245:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1245:10:1245:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1245:10:1245:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1245:10:1245:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1250:10:1250:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1250:10:1250:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1253:10:1253:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1253:10:1253:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1253:10:1253:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1253:10:1253:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1254:10:1254:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1254:10:1254:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1254:10:1254:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1254:10:1254:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1255:10:1255:13 | ...[...] | array_flow.rb:1206:16:1206:28 | call to source | array_flow.rb:1255:10:1255:13 | ...[...] | $@ | array_flow.rb:1206:16:1206:28 | call to source | call to source | +| array_flow.rb:1255:10:1255:13 | ...[...] | array_flow.rb:1206:34:1206:46 | call to source | array_flow.rb:1255:10:1255:13 | ...[...] | $@ | array_flow.rb:1206:34:1206:46 | call to source | call to source | +| array_flow.rb:1261:10:1261:10 | b | array_flow.rb:1259:16:1259:28 | call to source | array_flow.rb:1261:10:1261:10 | b | $@ | array_flow.rb:1259:16:1259:28 | call to source | call to source | +| array_flow.rb:1265:10:1265:13 | ...[...] | array_flow.rb:1259:34:1259:46 | call to source | array_flow.rb:1265:10:1265:13 | ...[...] | $@ | array_flow.rb:1259:34:1259:46 | call to source | call to source | | array_flow.rb:1269:10:1269:13 | ...[...] | array_flow.rb:1267:16:1267:28 | call to source | array_flow.rb:1269:10:1269:13 | ...[...] | $@ | array_flow.rb:1267:16:1267:28 | call to source | call to source | +| array_flow.rb:1269:10:1269:13 | ...[...] | array_flow.rb:1267:34:1267:46 | call to source | array_flow.rb:1269:10:1269:13 | ...[...] | $@ | array_flow.rb:1267:34:1267:46 | call to source | call to source | +| array_flow.rb:1270:10:1270:13 | ...[...] | array_flow.rb:1267:16:1267:28 | call to source | array_flow.rb:1270:10:1270:13 | ...[...] | $@ | array_flow.rb:1267:16:1267:28 | call to source | call to source | +| array_flow.rb:1270:10:1270:13 | ...[...] | array_flow.rb:1267:34:1267:46 | call to source | array_flow.rb:1270:10:1270:13 | ...[...] | $@ | array_flow.rb:1267:34:1267:46 | call to source | call to source | +| array_flow.rb:1271:10:1271:13 | ...[...] | array_flow.rb:1267:16:1267:28 | call to source | array_flow.rb:1271:10:1271:13 | ...[...] | $@ | array_flow.rb:1267:16:1267:28 | call to source | call to source | | array_flow.rb:1271:10:1271:13 | ...[...] | array_flow.rb:1267:34:1267:46 | call to source | array_flow.rb:1271:10:1271:13 | ...[...] | $@ | array_flow.rb:1267:34:1267:46 | call to source | call to source | +| array_flow.rb:1272:10:1272:13 | ...[...] | array_flow.rb:1267:16:1267:28 | call to source | array_flow.rb:1272:10:1272:13 | ...[...] | $@ | array_flow.rb:1267:16:1267:28 | call to source | call to source | +| array_flow.rb:1272:10:1272:13 | ...[...] | array_flow.rb:1267:34:1267:46 | call to source | array_flow.rb:1272:10:1272:13 | ...[...] | $@ | array_flow.rb:1267:34:1267:46 | call to source | call to source | +| array_flow.rb:1274:10:1274:10 | b | array_flow.rb:1267:16:1267:28 | call to source | array_flow.rb:1274:10:1274:10 | b | $@ | array_flow.rb:1267:16:1267:28 | call to source | call to source | +| array_flow.rb:1274:10:1274:10 | b | array_flow.rb:1267:34:1267:46 | call to source | array_flow.rb:1274:10:1274:10 | b | $@ | array_flow.rb:1267:34:1267:46 | call to source | call to source | +| array_flow.rb:1276:10:1276:13 | ...[...] | array_flow.rb:1267:16:1267:28 | call to source | array_flow.rb:1276:10:1276:13 | ...[...] | $@ | array_flow.rb:1267:16:1267:28 | call to source | call to source | +| array_flow.rb:1276:10:1276:13 | ...[...] | array_flow.rb:1267:34:1267:46 | call to source | array_flow.rb:1276:10:1276:13 | ...[...] | $@ | array_flow.rb:1267:34:1267:46 | call to source | call to source | | array_flow.rb:1280:10:1280:13 | ...[...] | array_flow.rb:1278:16:1278:28 | call to source | array_flow.rb:1280:10:1280:13 | ...[...] | $@ | array_flow.rb:1278:16:1278:28 | call to source | call to source | -| array_flow.rb:1285:10:1285:13 | ...[...] | array_flow.rb:1278:34:1278:46 | call to source | array_flow.rb:1285:10:1285:13 | ...[...] | $@ | array_flow.rb:1278:34:1278:46 | call to source | call to source | +| array_flow.rb:1282:10:1282:13 | ...[...] | array_flow.rb:1278:34:1278:46 | call to source | array_flow.rb:1282:10:1282:13 | ...[...] | $@ | array_flow.rb:1278:34:1278:46 | call to source | call to source | | array_flow.rb:1291:10:1291:13 | ...[...] | array_flow.rb:1289:16:1289:28 | call to source | array_flow.rb:1291:10:1291:13 | ...[...] | $@ | array_flow.rb:1289:16:1289:28 | call to source | call to source | | array_flow.rb:1296:10:1296:13 | ...[...] | array_flow.rb:1289:34:1289:46 | call to source | array_flow.rb:1296:10:1296:13 | ...[...] | $@ | array_flow.rb:1289:34:1289:46 | call to source | call to source | | array_flow.rb:1302:10:1302:13 | ...[...] | array_flow.rb:1300:16:1300:28 | call to source | array_flow.rb:1302:10:1302:13 | ...[...] | $@ | array_flow.rb:1300:16:1300:28 | call to source | call to source | -| array_flow.rb:1302:10:1302:13 | ...[...] | array_flow.rb:1300:34:1300:46 | call to source | array_flow.rb:1302:10:1302:13 | ...[...] | $@ | array_flow.rb:1300:34:1300:46 | call to source | call to source | -| array_flow.rb:1303:10:1303:13 | ...[...] | array_flow.rb:1300:16:1300:28 | call to source | array_flow.rb:1303:10:1303:13 | ...[...] | $@ | array_flow.rb:1300:16:1300:28 | call to source | call to source | -| array_flow.rb:1303:10:1303:13 | ...[...] | array_flow.rb:1300:34:1300:46 | call to source | array_flow.rb:1303:10:1303:13 | ...[...] | $@ | array_flow.rb:1300:34:1300:46 | call to source | call to source | -| array_flow.rb:1304:10:1304:13 | ...[...] | array_flow.rb:1300:16:1300:28 | call to source | array_flow.rb:1304:10:1304:13 | ...[...] | $@ | array_flow.rb:1300:16:1300:28 | call to source | call to source | -| array_flow.rb:1304:10:1304:13 | ...[...] | array_flow.rb:1300:34:1300:46 | call to source | array_flow.rb:1304:10:1304:13 | ...[...] | $@ | array_flow.rb:1300:34:1300:46 | call to source | call to source | -| array_flow.rb:1305:10:1305:13 | ...[...] | array_flow.rb:1300:16:1300:28 | call to source | array_flow.rb:1305:10:1305:13 | ...[...] | $@ | array_flow.rb:1300:16:1300:28 | call to source | call to source | -| array_flow.rb:1305:10:1305:13 | ...[...] | array_flow.rb:1300:34:1300:46 | call to source | array_flow.rb:1305:10:1305:13 | ...[...] | $@ | array_flow.rb:1300:34:1300:46 | call to source | call to source | -| array_flow.rb:1306:10:1306:13 | ...[...] | array_flow.rb:1300:16:1300:28 | call to source | array_flow.rb:1306:10:1306:13 | ...[...] | $@ | array_flow.rb:1300:16:1300:28 | call to source | call to source | -| array_flow.rb:1306:10:1306:13 | ...[...] | array_flow.rb:1300:34:1300:46 | call to source | array_flow.rb:1306:10:1306:13 | ...[...] | $@ | array_flow.rb:1300:34:1300:46 | call to source | call to source | -| array_flow.rb:1307:10:1307:13 | ...[...] | array_flow.rb:1300:16:1300:28 | call to source | array_flow.rb:1307:10:1307:13 | ...[...] | $@ | array_flow.rb:1300:16:1300:28 | call to source | call to source | | array_flow.rb:1307:10:1307:13 | ...[...] | array_flow.rb:1300:34:1300:46 | call to source | array_flow.rb:1307:10:1307:13 | ...[...] | $@ | array_flow.rb:1300:34:1300:46 | call to source | call to source | -| array_flow.rb:1311:10:1311:13 | ...[...] | array_flow.rb:1309:16:1309:28 | call to source | array_flow.rb:1311:10:1311:13 | ...[...] | $@ | array_flow.rb:1309:16:1309:28 | call to source | call to source | -| array_flow.rb:1311:10:1311:13 | ...[...] | array_flow.rb:1309:34:1309:46 | call to source | array_flow.rb:1311:10:1311:13 | ...[...] | $@ | array_flow.rb:1309:34:1309:46 | call to source | call to source | -| array_flow.rb:1312:10:1312:13 | ...[...] | array_flow.rb:1309:16:1309:28 | call to source | array_flow.rb:1312:10:1312:13 | ...[...] | $@ | array_flow.rb:1309:16:1309:28 | call to source | call to source | -| array_flow.rb:1312:10:1312:13 | ...[...] | array_flow.rb:1309:34:1309:46 | call to source | array_flow.rb:1312:10:1312:13 | ...[...] | $@ | array_flow.rb:1309:34:1309:46 | call to source | call to source | -| array_flow.rb:1313:10:1313:13 | ...[...] | array_flow.rb:1309:16:1309:28 | call to source | array_flow.rb:1313:10:1313:13 | ...[...] | $@ | array_flow.rb:1309:16:1309:28 | call to source | call to source | -| array_flow.rb:1313:10:1313:13 | ...[...] | array_flow.rb:1309:34:1309:46 | call to source | array_flow.rb:1313:10:1313:13 | ...[...] | $@ | array_flow.rb:1309:34:1309:46 | call to source | call to source | -| array_flow.rb:1314:10:1314:13 | ...[...] | array_flow.rb:1309:16:1309:28 | call to source | array_flow.rb:1314:10:1314:13 | ...[...] | $@ | array_flow.rb:1309:16:1309:28 | call to source | call to source | -| array_flow.rb:1314:10:1314:13 | ...[...] | array_flow.rb:1309:34:1309:46 | call to source | array_flow.rb:1314:10:1314:13 | ...[...] | $@ | array_flow.rb:1309:34:1309:46 | call to source | call to source | -| array_flow.rb:1315:10:1315:13 | ...[...] | array_flow.rb:1309:16:1309:28 | call to source | array_flow.rb:1315:10:1315:13 | ...[...] | $@ | array_flow.rb:1309:16:1309:28 | call to source | call to source | -| array_flow.rb:1315:10:1315:13 | ...[...] | array_flow.rb:1309:34:1309:46 | call to source | array_flow.rb:1315:10:1315:13 | ...[...] | $@ | array_flow.rb:1309:34:1309:46 | call to source | call to source | -| array_flow.rb:1316:10:1316:13 | ...[...] | array_flow.rb:1309:16:1309:28 | call to source | array_flow.rb:1316:10:1316:13 | ...[...] | $@ | array_flow.rb:1309:16:1309:28 | call to source | call to source | -| array_flow.rb:1316:10:1316:13 | ...[...] | array_flow.rb:1309:34:1309:46 | call to source | array_flow.rb:1316:10:1316:13 | ...[...] | $@ | array_flow.rb:1309:34:1309:46 | call to source | call to source | -| array_flow.rb:1320:10:1320:13 | ...[...] | array_flow.rb:1318:16:1318:28 | call to source | array_flow.rb:1320:10:1320:13 | ...[...] | $@ | array_flow.rb:1318:16:1318:28 | call to source | call to source | -| array_flow.rb:1320:10:1320:13 | ...[...] | array_flow.rb:1318:34:1318:46 | call to source | array_flow.rb:1320:10:1320:13 | ...[...] | $@ | array_flow.rb:1318:34:1318:46 | call to source | call to source | -| array_flow.rb:1321:10:1321:13 | ...[...] | array_flow.rb:1318:16:1318:28 | call to source | array_flow.rb:1321:10:1321:13 | ...[...] | $@ | array_flow.rb:1318:16:1318:28 | call to source | call to source | -| array_flow.rb:1321:10:1321:13 | ...[...] | array_flow.rb:1318:34:1318:46 | call to source | array_flow.rb:1321:10:1321:13 | ...[...] | $@ | array_flow.rb:1318:34:1318:46 | call to source | call to source | -| array_flow.rb:1322:10:1322:13 | ...[...] | array_flow.rb:1318:16:1318:28 | call to source | array_flow.rb:1322:10:1322:13 | ...[...] | $@ | array_flow.rb:1318:16:1318:28 | call to source | call to source | -| array_flow.rb:1322:10:1322:13 | ...[...] | array_flow.rb:1318:34:1318:46 | call to source | array_flow.rb:1322:10:1322:13 | ...[...] | $@ | array_flow.rb:1318:34:1318:46 | call to source | call to source | -| array_flow.rb:1323:10:1323:13 | ...[...] | array_flow.rb:1318:16:1318:28 | call to source | array_flow.rb:1323:10:1323:13 | ...[...] | $@ | array_flow.rb:1318:16:1318:28 | call to source | call to source | -| array_flow.rb:1323:10:1323:13 | ...[...] | array_flow.rb:1318:34:1318:46 | call to source | array_flow.rb:1323:10:1323:13 | ...[...] | $@ | array_flow.rb:1318:34:1318:46 | call to source | call to source | -| array_flow.rb:1324:10:1324:13 | ...[...] | array_flow.rb:1318:16:1318:28 | call to source | array_flow.rb:1324:10:1324:13 | ...[...] | $@ | array_flow.rb:1318:16:1318:28 | call to source | call to source | -| array_flow.rb:1324:10:1324:13 | ...[...] | array_flow.rb:1318:34:1318:46 | call to source | array_flow.rb:1324:10:1324:13 | ...[...] | $@ | array_flow.rb:1318:34:1318:46 | call to source | call to source | -| array_flow.rb:1325:10:1325:13 | ...[...] | array_flow.rb:1318:16:1318:28 | call to source | array_flow.rb:1325:10:1325:13 | ...[...] | $@ | array_flow.rb:1318:16:1318:28 | call to source | call to source | -| array_flow.rb:1325:10:1325:13 | ...[...] | array_flow.rb:1318:34:1318:46 | call to source | array_flow.rb:1325:10:1325:13 | ...[...] | $@ | array_flow.rb:1318:34:1318:46 | call to source | call to source | -| array_flow.rb:1331:10:1331:13 | ...[...] | array_flow.rb:1327:16:1327:28 | call to source | array_flow.rb:1331:10:1331:13 | ...[...] | $@ | array_flow.rb:1327:16:1327:28 | call to source | call to source | -| array_flow.rb:1333:10:1333:13 | ...[...] | array_flow.rb:1327:34:1327:46 | call to source | array_flow.rb:1333:10:1333:13 | ...[...] | $@ | array_flow.rb:1327:34:1327:46 | call to source | call to source | -| array_flow.rb:1338:10:1338:13 | ...[...] | array_flow.rb:1336:16:1336:28 | call to source | array_flow.rb:1338:10:1338:13 | ...[...] | $@ | array_flow.rb:1336:16:1336:28 | call to source | call to source | -| array_flow.rb:1338:10:1338:13 | ...[...] | array_flow.rb:1336:34:1336:46 | call to source | array_flow.rb:1338:10:1338:13 | ...[...] | $@ | array_flow.rb:1336:34:1336:46 | call to source | call to source | -| array_flow.rb:1339:10:1339:13 | ...[...] | array_flow.rb:1336:16:1336:28 | call to source | array_flow.rb:1339:10:1339:13 | ...[...] | $@ | array_flow.rb:1336:16:1336:28 | call to source | call to source | -| array_flow.rb:1339:10:1339:13 | ...[...] | array_flow.rb:1336:34:1336:46 | call to source | array_flow.rb:1339:10:1339:13 | ...[...] | $@ | array_flow.rb:1336:34:1336:46 | call to source | call to source | -| array_flow.rb:1340:10:1340:13 | ...[...] | array_flow.rb:1336:16:1336:28 | call to source | array_flow.rb:1340:10:1340:13 | ...[...] | $@ | array_flow.rb:1336:16:1336:28 | call to source | call to source | -| array_flow.rb:1340:10:1340:13 | ...[...] | array_flow.rb:1336:34:1336:46 | call to source | array_flow.rb:1340:10:1340:13 | ...[...] | $@ | array_flow.rb:1336:34:1336:46 | call to source | call to source | -| array_flow.rb:1341:10:1341:13 | ...[...] | array_flow.rb:1336:16:1336:28 | call to source | array_flow.rb:1341:10:1341:13 | ...[...] | $@ | array_flow.rb:1336:16:1336:28 | call to source | call to source | -| array_flow.rb:1341:10:1341:13 | ...[...] | array_flow.rb:1336:34:1336:46 | call to source | array_flow.rb:1341:10:1341:13 | ...[...] | $@ | array_flow.rb:1336:34:1336:46 | call to source | call to source | -| array_flow.rb:1342:10:1342:13 | ...[...] | array_flow.rb:1336:16:1336:28 | call to source | array_flow.rb:1342:10:1342:13 | ...[...] | $@ | array_flow.rb:1336:16:1336:28 | call to source | call to source | -| array_flow.rb:1342:10:1342:13 | ...[...] | array_flow.rb:1336:34:1336:46 | call to source | array_flow.rb:1342:10:1342:13 | ...[...] | $@ | array_flow.rb:1336:34:1336:46 | call to source | call to source | -| array_flow.rb:1343:10:1343:13 | ...[...] | array_flow.rb:1336:16:1336:28 | call to source | array_flow.rb:1343:10:1343:13 | ...[...] | $@ | array_flow.rb:1336:16:1336:28 | call to source | call to source | -| array_flow.rb:1343:10:1343:13 | ...[...] | array_flow.rb:1336:34:1336:46 | call to source | array_flow.rb:1343:10:1343:13 | ...[...] | $@ | array_flow.rb:1336:34:1336:46 | call to source | call to source | -| array_flow.rb:1349:14:1349:14 | x | array_flow.rb:1347:16:1347:26 | call to source | array_flow.rb:1349:14:1349:14 | x | $@ | array_flow.rb:1347:16:1347:26 | call to source | call to source | -| array_flow.rb:1357:14:1357:14 | x | array_flow.rb:1355:16:1355:26 | call to source | array_flow.rb:1357:14:1357:14 | x | $@ | array_flow.rb:1355:16:1355:26 | call to source | call to source | -| array_flow.rb:1365:14:1365:14 | x | array_flow.rb:1363:16:1363:26 | call to source | array_flow.rb:1365:14:1365:14 | x | $@ | array_flow.rb:1363:16:1363:26 | call to source | call to source | -| array_flow.rb:1366:14:1366:14 | y | array_flow.rb:1363:16:1363:26 | call to source | array_flow.rb:1366:14:1366:14 | y | $@ | array_flow.rb:1363:16:1363:26 | call to source | call to source | -| array_flow.rb:1373:10:1373:13 | ...[...] | array_flow.rb:1371:16:1371:26 | call to source | array_flow.rb:1373:10:1373:13 | ...[...] | $@ | array_flow.rb:1371:16:1371:26 | call to source | call to source | -| array_flow.rb:1374:10:1374:13 | ...[...] | array_flow.rb:1371:16:1371:26 | call to source | array_flow.rb:1374:10:1374:13 | ...[...] | $@ | array_flow.rb:1371:16:1371:26 | call to source | call to source | -| array_flow.rb:1376:14:1376:14 | x | array_flow.rb:1371:16:1371:26 | call to source | array_flow.rb:1376:14:1376:14 | x | $@ | array_flow.rb:1371:16:1371:26 | call to source | call to source | -| array_flow.rb:1377:14:1377:14 | y | array_flow.rb:1371:16:1371:26 | call to source | array_flow.rb:1377:14:1377:14 | y | $@ | array_flow.rb:1371:16:1371:26 | call to source | call to source | -| array_flow.rb:1380:10:1380:13 | ...[...] | array_flow.rb:1371:16:1371:26 | call to source | array_flow.rb:1380:10:1380:13 | ...[...] | $@ | array_flow.rb:1371:16:1371:26 | call to source | call to source | -| array_flow.rb:1381:10:1381:13 | ...[...] | array_flow.rb:1371:16:1371:26 | call to source | array_flow.rb:1381:10:1381:13 | ...[...] | $@ | array_flow.rb:1371:16:1371:26 | call to source | call to source | -| array_flow.rb:1387:10:1387:13 | ...[...] | array_flow.rb:1385:16:1385:26 | call to source | array_flow.rb:1387:10:1387:13 | ...[...] | $@ | array_flow.rb:1385:16:1385:26 | call to source | call to source | -| array_flow.rb:1388:10:1388:13 | ...[...] | array_flow.rb:1385:16:1385:26 | call to source | array_flow.rb:1388:10:1388:13 | ...[...] | $@ | array_flow.rb:1385:16:1385:26 | call to source | call to source | -| array_flow.rb:1389:10:1389:13 | ...[...] | array_flow.rb:1385:16:1385:26 | call to source | array_flow.rb:1389:10:1389:13 | ...[...] | $@ | array_flow.rb:1385:16:1385:26 | call to source | call to source | -| array_flow.rb:1390:10:1390:13 | ...[...] | array_flow.rb:1385:16:1385:26 | call to source | array_flow.rb:1390:10:1390:13 | ...[...] | $@ | array_flow.rb:1385:16:1385:26 | call to source | call to source | -| array_flow.rb:1394:14:1394:14 | x | array_flow.rb:1392:16:1392:26 | call to source | array_flow.rb:1394:14:1394:14 | x | $@ | array_flow.rb:1392:16:1392:26 | call to source | call to source | -| array_flow.rb:1395:14:1395:14 | y | array_flow.rb:1392:16:1392:26 | call to source | array_flow.rb:1395:14:1395:14 | y | $@ | array_flow.rb:1392:16:1392:26 | call to source | call to source | -| array_flow.rb:1398:10:1398:13 | ...[...] | array_flow.rb:1392:16:1392:26 | call to source | array_flow.rb:1398:10:1398:13 | ...[...] | $@ | array_flow.rb:1392:16:1392:26 | call to source | call to source | -| array_flow.rb:1399:10:1399:13 | ...[...] | array_flow.rb:1392:16:1392:26 | call to source | array_flow.rb:1399:10:1399:13 | ...[...] | $@ | array_flow.rb:1392:16:1392:26 | call to source | call to source | -| array_flow.rb:1400:10:1400:13 | ...[...] | array_flow.rb:1392:16:1392:26 | call to source | array_flow.rb:1400:10:1400:13 | ...[...] | $@ | array_flow.rb:1392:16:1392:26 | call to source | call to source | -| array_flow.rb:1401:10:1401:13 | ...[...] | array_flow.rb:1392:16:1392:26 | call to source | array_flow.rb:1401:10:1401:13 | ...[...] | $@ | array_flow.rb:1392:16:1392:26 | call to source | call to source | -| array_flow.rb:1407:14:1407:14 | x | array_flow.rb:1405:16:1405:26 | call to source | array_flow.rb:1407:14:1407:14 | x | $@ | array_flow.rb:1405:16:1405:26 | call to source | call to source | -| array_flow.rb:1410:10:1410:13 | ...[...] | array_flow.rb:1405:16:1405:26 | call to source | array_flow.rb:1410:10:1410:13 | ...[...] | $@ | array_flow.rb:1405:16:1405:26 | call to source | call to source | -| array_flow.rb:1411:10:1411:13 | ...[...] | array_flow.rb:1405:16:1405:26 | call to source | array_flow.rb:1411:10:1411:13 | ...[...] | $@ | array_flow.rb:1405:16:1405:26 | call to source | call to source | -| array_flow.rb:1417:14:1417:14 | x | array_flow.rb:1415:16:1415:26 | call to source | array_flow.rb:1417:14:1417:14 | x | $@ | array_flow.rb:1415:16:1415:26 | call to source | call to source | -| array_flow.rb:1420:10:1420:13 | ...[...] | array_flow.rb:1415:16:1415:26 | call to source | array_flow.rb:1420:10:1420:13 | ...[...] | $@ | array_flow.rb:1415:16:1415:26 | call to source | call to source | -| array_flow.rb:1421:10:1421:13 | ...[...] | array_flow.rb:1415:16:1415:26 | call to source | array_flow.rb:1421:10:1421:13 | ...[...] | $@ | array_flow.rb:1415:16:1415:26 | call to source | call to source | -| array_flow.rb:1422:10:1422:13 | ...[...] | array_flow.rb:1415:16:1415:26 | call to source | array_flow.rb:1422:10:1422:13 | ...[...] | $@ | array_flow.rb:1415:16:1415:26 | call to source | call to source | -| array_flow.rb:1423:10:1423:13 | ...[...] | array_flow.rb:1415:16:1415:26 | call to source | array_flow.rb:1423:10:1423:13 | ...[...] | $@ | array_flow.rb:1415:16:1415:26 | call to source | call to source | -| array_flow.rb:1429:14:1429:14 | x | array_flow.rb:1427:16:1427:26 | call to source | array_flow.rb:1429:14:1429:14 | x | $@ | array_flow.rb:1427:16:1427:26 | call to source | call to source | -| array_flow.rb:1439:10:1439:13 | ...[...] | array_flow.rb:1435:16:1435:28 | call to source | array_flow.rb:1439:10:1439:13 | ...[...] | $@ | array_flow.rb:1435:16:1435:28 | call to source | call to source | -| array_flow.rb:1440:10:1440:13 | ...[...] | array_flow.rb:1435:31:1435:43 | call to source | array_flow.rb:1440:10:1440:13 | ...[...] | $@ | array_flow.rb:1435:31:1435:43 | call to source | call to source | -| array_flow.rb:1444:10:1444:13 | ...[...] | array_flow.rb:1435:16:1435:28 | call to source | array_flow.rb:1444:10:1444:13 | ...[...] | $@ | array_flow.rb:1435:16:1435:28 | call to source | call to source | -| array_flow.rb:1446:10:1446:13 | ...[...] | array_flow.rb:1435:16:1435:28 | call to source | array_flow.rb:1446:10:1446:13 | ...[...] | $@ | array_flow.rb:1435:16:1435:28 | call to source | call to source | -| array_flow.rb:1450:10:1450:13 | ...[...] | array_flow.rb:1435:16:1435:28 | call to source | array_flow.rb:1450:10:1450:13 | ...[...] | $@ | array_flow.rb:1435:16:1435:28 | call to source | call to source | -| array_flow.rb:1451:10:1451:13 | ...[...] | array_flow.rb:1435:31:1435:43 | call to source | array_flow.rb:1451:10:1451:13 | ...[...] | $@ | array_flow.rb:1435:31:1435:43 | call to source | call to source | -| array_flow.rb:1452:10:1452:13 | ...[...] | array_flow.rb:1435:16:1435:28 | call to source | array_flow.rb:1452:10:1452:13 | ...[...] | $@ | array_flow.rb:1435:16:1435:28 | call to source | call to source | -| array_flow.rb:1452:10:1452:13 | ...[...] | array_flow.rb:1435:31:1435:43 | call to source | array_flow.rb:1452:10:1452:13 | ...[...] | $@ | array_flow.rb:1435:31:1435:43 | call to source | call to source | -| array_flow.rb:1455:10:1455:13 | ...[...] | array_flow.rb:1435:16:1435:28 | call to source | array_flow.rb:1455:10:1455:13 | ...[...] | $@ | array_flow.rb:1435:16:1435:28 | call to source | call to source | -| array_flow.rb:1455:10:1455:13 | ...[...] | array_flow.rb:1453:12:1453:24 | call to source | array_flow.rb:1455:10:1455:13 | ...[...] | $@ | array_flow.rb:1453:12:1453:24 | call to source | call to source | -| array_flow.rb:1461:14:1461:14 | x | array_flow.rb:1459:16:1459:26 | call to source | array_flow.rb:1461:14:1461:14 | x | $@ | array_flow.rb:1459:16:1459:26 | call to source | call to source | -| array_flow.rb:1466:10:1466:13 | ...[...] | array_flow.rb:1459:16:1459:26 | call to source | array_flow.rb:1466:10:1466:13 | ...[...] | $@ | array_flow.rb:1459:16:1459:26 | call to source | call to source | -| array_flow.rb:1474:10:1474:13 | ...[...] | array_flow.rb:1472:19:1472:29 | call to source | array_flow.rb:1474:10:1474:13 | ...[...] | $@ | array_flow.rb:1472:19:1472:29 | call to source | call to source | -| array_flow.rb:1482:10:1482:13 | ...[...] | array_flow.rb:1478:16:1478:26 | call to source | array_flow.rb:1482:10:1482:13 | ...[...] | $@ | array_flow.rb:1478:16:1478:26 | call to source | call to source | -| array_flow.rb:1500:10:1500:16 | ...[...] | array_flow.rb:1495:14:1495:26 | call to source | array_flow.rb:1500:10:1500:16 | ...[...] | $@ | array_flow.rb:1495:14:1495:26 | call to source | call to source | -| array_flow.rb:1501:10:1501:16 | ...[...] | array_flow.rb:1495:34:1495:46 | call to source | array_flow.rb:1501:10:1501:16 | ...[...] | $@ | array_flow.rb:1495:34:1495:46 | call to source | call to source | -| array_flow.rb:1502:10:1502:16 | ...[...] | array_flow.rb:1495:54:1495:66 | call to source | array_flow.rb:1502:10:1502:16 | ...[...] | $@ | array_flow.rb:1495:54:1495:66 | call to source | call to source | -| array_flow.rb:1510:10:1510:13 | ...[...] | array_flow.rb:1506:16:1506:28 | call to source | array_flow.rb:1510:10:1510:13 | ...[...] | $@ | array_flow.rb:1506:16:1506:28 | call to source | call to source | -| array_flow.rb:1510:10:1510:13 | ...[...] | array_flow.rb:1507:13:1507:25 | call to source | array_flow.rb:1510:10:1510:13 | ...[...] | $@ | array_flow.rb:1507:13:1507:25 | call to source | call to source | -| array_flow.rb:1510:10:1510:13 | ...[...] | array_flow.rb:1508:13:1508:25 | call to source | array_flow.rb:1510:10:1510:13 | ...[...] | $@ | array_flow.rb:1508:13:1508:25 | call to source | call to source | -| array_flow.rb:1511:10:1511:13 | ...[...] | array_flow.rb:1506:16:1506:28 | call to source | array_flow.rb:1511:10:1511:13 | ...[...] | $@ | array_flow.rb:1506:16:1506:28 | call to source | call to source | -| array_flow.rb:1511:10:1511:13 | ...[...] | array_flow.rb:1507:13:1507:25 | call to source | array_flow.rb:1511:10:1511:13 | ...[...] | $@ | array_flow.rb:1507:13:1507:25 | call to source | call to source | -| array_flow.rb:1511:10:1511:13 | ...[...] | array_flow.rb:1508:13:1508:25 | call to source | array_flow.rb:1511:10:1511:13 | ...[...] | $@ | array_flow.rb:1508:13:1508:25 | call to source | call to source | -| array_flow.rb:1512:10:1512:13 | ...[...] | array_flow.rb:1506:16:1506:28 | call to source | array_flow.rb:1512:10:1512:13 | ...[...] | $@ | array_flow.rb:1506:16:1506:28 | call to source | call to source | -| array_flow.rb:1512:10:1512:13 | ...[...] | array_flow.rb:1507:13:1507:25 | call to source | array_flow.rb:1512:10:1512:13 | ...[...] | $@ | array_flow.rb:1507:13:1507:25 | call to source | call to source | -| array_flow.rb:1512:10:1512:13 | ...[...] | array_flow.rb:1508:13:1508:25 | call to source | array_flow.rb:1512:10:1512:13 | ...[...] | $@ | array_flow.rb:1508:13:1508:25 | call to source | call to source | -| array_flow.rb:1519:10:1519:13 | ...[...] | array_flow.rb:1516:19:1516:31 | call to source | array_flow.rb:1519:10:1519:13 | ...[...] | $@ | array_flow.rb:1516:19:1516:31 | call to source | call to source | -| array_flow.rb:1519:10:1519:13 | ...[...] | array_flow.rb:1516:34:1516:46 | call to source | array_flow.rb:1519:10:1519:13 | ...[...] | $@ | array_flow.rb:1516:34:1516:46 | call to source | call to source | -| array_flow.rb:1520:10:1520:13 | ...[...] | array_flow.rb:1516:19:1516:31 | call to source | array_flow.rb:1520:10:1520:13 | ...[...] | $@ | array_flow.rb:1516:19:1516:31 | call to source | call to source | -| array_flow.rb:1520:10:1520:13 | ...[...] | array_flow.rb:1516:34:1516:46 | call to source | array_flow.rb:1520:10:1520:13 | ...[...] | $@ | array_flow.rb:1516:34:1516:46 | call to source | call to source | -| array_flow.rb:1523:14:1523:14 | x | array_flow.rb:1516:19:1516:31 | call to source | array_flow.rb:1523:14:1523:14 | x | $@ | array_flow.rb:1516:19:1516:31 | call to source | call to source | -| array_flow.rb:1523:14:1523:14 | x | array_flow.rb:1516:34:1516:46 | call to source | array_flow.rb:1523:14:1523:14 | x | $@ | array_flow.rb:1516:34:1516:46 | call to source | call to source | -| array_flow.rb:1526:10:1526:13 | ...[...] | array_flow.rb:1516:19:1516:31 | call to source | array_flow.rb:1526:10:1526:13 | ...[...] | $@ | array_flow.rb:1516:19:1516:31 | call to source | call to source | -| array_flow.rb:1526:10:1526:13 | ...[...] | array_flow.rb:1516:34:1516:46 | call to source | array_flow.rb:1526:10:1526:13 | ...[...] | $@ | array_flow.rb:1516:34:1516:46 | call to source | call to source | -| array_flow.rb:1532:10:1532:13 | ...[...] | array_flow.rb:1530:16:1530:28 | call to source | array_flow.rb:1532:10:1532:13 | ...[...] | $@ | array_flow.rb:1530:16:1530:28 | call to source | call to source | -| array_flow.rb:1532:10:1532:13 | ...[...] | array_flow.rb:1530:31:1530:43 | call to source | array_flow.rb:1532:10:1532:13 | ...[...] | $@ | array_flow.rb:1530:31:1530:43 | call to source | call to source | -| array_flow.rb:1533:10:1533:13 | ...[...] | array_flow.rb:1530:16:1530:28 | call to source | array_flow.rb:1533:10:1533:13 | ...[...] | $@ | array_flow.rb:1530:16:1530:28 | call to source | call to source | -| array_flow.rb:1533:10:1533:13 | ...[...] | array_flow.rb:1530:31:1530:43 | call to source | array_flow.rb:1533:10:1533:13 | ...[...] | $@ | array_flow.rb:1530:31:1530:43 | call to source | call to source | -| array_flow.rb:1534:10:1534:13 | ...[...] | array_flow.rb:1530:16:1530:28 | call to source | array_flow.rb:1534:10:1534:13 | ...[...] | $@ | array_flow.rb:1530:16:1530:28 | call to source | call to source | -| array_flow.rb:1534:10:1534:13 | ...[...] | array_flow.rb:1530:31:1530:43 | call to source | array_flow.rb:1534:10:1534:13 | ...[...] | $@ | array_flow.rb:1530:31:1530:43 | call to source | call to source | -| array_flow.rb:1535:10:1535:13 | ...[...] | array_flow.rb:1530:16:1530:28 | call to source | array_flow.rb:1535:10:1535:13 | ...[...] | $@ | array_flow.rb:1530:16:1530:28 | call to source | call to source | -| array_flow.rb:1535:10:1535:13 | ...[...] | array_flow.rb:1530:31:1530:43 | call to source | array_flow.rb:1535:10:1535:13 | ...[...] | $@ | array_flow.rb:1530:31:1530:43 | call to source | call to source | -| array_flow.rb:1539:14:1539:14 | x | array_flow.rb:1537:16:1537:28 | call to source | array_flow.rb:1539:14:1539:14 | x | $@ | array_flow.rb:1537:16:1537:28 | call to source | call to source | -| array_flow.rb:1539:14:1539:14 | x | array_flow.rb:1537:31:1537:43 | call to source | array_flow.rb:1539:14:1539:14 | x | $@ | array_flow.rb:1537:31:1537:43 | call to source | call to source | -| array_flow.rb:1542:10:1542:13 | ...[...] | array_flow.rb:1537:16:1537:28 | call to source | array_flow.rb:1542:10:1542:13 | ...[...] | $@ | array_flow.rb:1537:16:1537:28 | call to source | call to source | -| array_flow.rb:1542:10:1542:13 | ...[...] | array_flow.rb:1537:31:1537:43 | call to source | array_flow.rb:1542:10:1542:13 | ...[...] | $@ | array_flow.rb:1537:31:1537:43 | call to source | call to source | -| array_flow.rb:1543:10:1543:13 | ...[...] | array_flow.rb:1537:16:1537:28 | call to source | array_flow.rb:1543:10:1543:13 | ...[...] | $@ | array_flow.rb:1537:16:1537:28 | call to source | call to source | -| array_flow.rb:1543:10:1543:13 | ...[...] | array_flow.rb:1537:31:1537:43 | call to source | array_flow.rb:1543:10:1543:13 | ...[...] | $@ | array_flow.rb:1537:31:1537:43 | call to source | call to source | -| array_flow.rb:1544:10:1544:13 | ...[...] | array_flow.rb:1537:16:1537:28 | call to source | array_flow.rb:1544:10:1544:13 | ...[...] | $@ | array_flow.rb:1537:16:1537:28 | call to source | call to source | -| array_flow.rb:1544:10:1544:13 | ...[...] | array_flow.rb:1537:31:1537:43 | call to source | array_flow.rb:1544:10:1544:13 | ...[...] | $@ | array_flow.rb:1537:31:1537:43 | call to source | call to source | -| array_flow.rb:1545:10:1545:13 | ...[...] | array_flow.rb:1537:16:1537:28 | call to source | array_flow.rb:1545:10:1545:13 | ...[...] | $@ | array_flow.rb:1537:16:1537:28 | call to source | call to source | -| array_flow.rb:1545:10:1545:13 | ...[...] | array_flow.rb:1537:31:1537:43 | call to source | array_flow.rb:1545:10:1545:13 | ...[...] | $@ | array_flow.rb:1537:31:1537:43 | call to source | call to source | -| array_flow.rb:1553:10:1553:13 | ...[...] | array_flow.rb:1550:21:1550:33 | call to source | array_flow.rb:1553:10:1553:13 | ...[...] | $@ | array_flow.rb:1550:21:1550:33 | call to source | call to source | -| array_flow.rb:1556:10:1556:13 | ...[...] | array_flow.rb:1549:16:1549:28 | call to source | array_flow.rb:1556:10:1556:13 | ...[...] | $@ | array_flow.rb:1549:16:1549:28 | call to source | call to source | -| array_flow.rb:1564:10:1564:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1564:10:1564:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1566:10:1566:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1566:10:1566:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1569:10:1569:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1569:10:1569:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1569:10:1569:13 | ...[...] | array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1569:10:1569:13 | ...[...] | $@ | array_flow.rb:1560:31:1560:43 | call to source | call to source | -| array_flow.rb:1570:10:1570:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1570:10:1570:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1570:10:1570:13 | ...[...] | array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1570:10:1570:13 | ...[...] | $@ | array_flow.rb:1560:31:1560:43 | call to source | call to source | -| array_flow.rb:1573:10:1573:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1573:10:1573:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1573:10:1573:13 | ...[...] | array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1573:10:1573:13 | ...[...] | $@ | array_flow.rb:1560:31:1560:43 | call to source | call to source | -| array_flow.rb:1574:10:1574:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1574:10:1574:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1574:10:1574:13 | ...[...] | array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1574:10:1574:13 | ...[...] | $@ | array_flow.rb:1560:31:1560:43 | call to source | call to source | -| array_flow.rb:1577:10:1577:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1577:10:1577:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1577:10:1577:13 | ...[...] | array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1577:10:1577:13 | ...[...] | $@ | array_flow.rb:1560:31:1560:43 | call to source | call to source | -| array_flow.rb:1578:10:1578:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1578:10:1578:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1578:10:1578:13 | ...[...] | array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1578:10:1578:13 | ...[...] | $@ | array_flow.rb:1560:31:1560:43 | call to source | call to source | -| array_flow.rb:1579:10:1579:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1579:10:1579:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1579:10:1579:13 | ...[...] | array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1579:10:1579:13 | ...[...] | $@ | array_flow.rb:1560:31:1560:43 | call to source | call to source | -| array_flow.rb:1580:10:1580:13 | ...[...] | array_flow.rb:1560:13:1560:25 | call to source | array_flow.rb:1580:10:1580:13 | ...[...] | $@ | array_flow.rb:1560:13:1560:25 | call to source | call to source | -| array_flow.rb:1580:10:1580:13 | ...[...] | array_flow.rb:1560:31:1560:43 | call to source | array_flow.rb:1580:10:1580:13 | ...[...] | $@ | array_flow.rb:1560:31:1560:43 | call to source | call to source | -| array_flow.rb:1589:10:1589:16 | ...[...] | array_flow.rb:1586:10:1586:22 | call to source | array_flow.rb:1589:10:1589:16 | ...[...] | $@ | array_flow.rb:1586:10:1586:22 | call to source | call to source | -| array_flow.rb:1590:10:1590:16 | ...[...] | array_flow.rb:1585:13:1585:25 | call to source | array_flow.rb:1590:10:1590:16 | ...[...] | $@ | array_flow.rb:1585:13:1585:25 | call to source | call to source | -| array_flow.rb:1591:10:1591:16 | ...[...] | array_flow.rb:1584:16:1584:28 | call to source | array_flow.rb:1591:10:1591:16 | ...[...] | $@ | array_flow.rb:1584:16:1584:28 | call to source | call to source | -| array_flow.rb:1593:14:1593:17 | ...[...] | array_flow.rb:1584:16:1584:28 | call to source | array_flow.rb:1593:14:1593:17 | ...[...] | $@ | array_flow.rb:1584:16:1584:28 | call to source | call to source | -| array_flow.rb:1594:14:1594:17 | ...[...] | array_flow.rb:1585:13:1585:25 | call to source | array_flow.rb:1594:14:1594:17 | ...[...] | $@ | array_flow.rb:1585:13:1585:25 | call to source | call to source | -| array_flow.rb:1595:14:1595:17 | ...[...] | array_flow.rb:1586:10:1586:22 | call to source | array_flow.rb:1595:14:1595:17 | ...[...] | $@ | array_flow.rb:1586:10:1586:22 | call to source | call to source | -| array_flow.rb:1603:10:1603:13 | ...[...] | array_flow.rb:1600:16:1600:28 | call to source | array_flow.rb:1603:10:1603:13 | ...[...] | $@ | array_flow.rb:1600:16:1600:28 | call to source | call to source | -| array_flow.rb:1603:10:1603:13 | ...[...] | array_flow.rb:1601:13:1601:25 | call to source | array_flow.rb:1603:10:1603:13 | ...[...] | $@ | array_flow.rb:1601:13:1601:25 | call to source | call to source | -| array_flow.rb:1604:10:1604:13 | ...[...] | array_flow.rb:1600:16:1600:28 | call to source | array_flow.rb:1604:10:1604:13 | ...[...] | $@ | array_flow.rb:1600:16:1600:28 | call to source | call to source | -| array_flow.rb:1604:10:1604:13 | ...[...] | array_flow.rb:1601:13:1601:25 | call to source | array_flow.rb:1604:10:1604:13 | ...[...] | $@ | array_flow.rb:1601:13:1601:25 | call to source | call to source | -| array_flow.rb:1605:10:1605:13 | ...[...] | array_flow.rb:1600:16:1600:28 | call to source | array_flow.rb:1605:10:1605:13 | ...[...] | $@ | array_flow.rb:1600:16:1600:28 | call to source | call to source | -| array_flow.rb:1605:10:1605:13 | ...[...] | array_flow.rb:1601:13:1601:25 | call to source | array_flow.rb:1605:10:1605:13 | ...[...] | $@ | array_flow.rb:1601:13:1601:25 | call to source | call to source | -| array_flow.rb:1611:10:1611:16 | ...[...] | array_flow.rb:1610:15:1610:27 | call to source | array_flow.rb:1611:10:1611:16 | ...[...] | $@ | array_flow.rb:1610:15:1610:27 | call to source | call to source | -| array_flow.rb:1614:10:1614:16 | ...[...] | array_flow.rb:1610:15:1610:27 | call to source | array_flow.rb:1614:10:1614:16 | ...[...] | $@ | array_flow.rb:1610:15:1610:27 | call to source | call to source | -| array_flow.rb:1614:10:1614:16 | ...[...] | array_flow.rb:1613:15:1613:27 | call to source | array_flow.rb:1614:10:1614:16 | ...[...] | $@ | array_flow.rb:1613:15:1613:27 | call to source | call to source | -| array_flow.rb:1615:10:1615:16 | ...[...] | array_flow.rb:1610:15:1610:27 | call to source | array_flow.rb:1615:10:1615:16 | ...[...] | $@ | array_flow.rb:1610:15:1610:27 | call to source | call to source | -| array_flow.rb:1627:10:1627:13 | ...[...] | array_flow.rb:1622:16:1622:28 | call to source | array_flow.rb:1627:10:1627:13 | ...[...] | $@ | array_flow.rb:1622:16:1622:28 | call to source | call to source | -| array_flow.rb:1627:10:1627:13 | ...[...] | array_flow.rb:1624:14:1624:26 | call to source | array_flow.rb:1627:10:1627:13 | ...[...] | $@ | array_flow.rb:1624:14:1624:26 | call to source | call to source | -| array_flow.rb:1627:10:1627:13 | ...[...] | array_flow.rb:1626:16:1626:28 | call to source | array_flow.rb:1627:10:1627:13 | ...[...] | $@ | array_flow.rb:1626:16:1626:28 | call to source | call to source | -| array_flow.rb:1629:10:1629:17 | ...[...] | array_flow.rb:1620:12:1620:24 | call to source | array_flow.rb:1629:10:1629:17 | ...[...] | $@ | array_flow.rb:1620:12:1620:24 | call to source | call to source | -| array_flow.rb:1629:10:1629:17 | ...[...] | array_flow.rb:1622:16:1622:28 | call to source | array_flow.rb:1629:10:1629:17 | ...[...] | $@ | array_flow.rb:1622:16:1622:28 | call to source | call to source | -| array_flow.rb:1629:10:1629:17 | ...[...] | array_flow.rb:1624:14:1624:26 | call to source | array_flow.rb:1629:10:1629:17 | ...[...] | $@ | array_flow.rb:1624:14:1624:26 | call to source | call to source | -| array_flow.rb:1629:10:1629:17 | ...[...] | array_flow.rb:1626:16:1626:28 | call to source | array_flow.rb:1629:10:1629:17 | ...[...] | $@ | array_flow.rb:1626:16:1626:28 | call to source | call to source | -| array_flow.rb:1631:10:1631:15 | ...[...] | array_flow.rb:1620:12:1620:24 | call to source | array_flow.rb:1631:10:1631:15 | ...[...] | $@ | array_flow.rb:1620:12:1620:24 | call to source | call to source | -| array_flow.rb:1631:10:1631:15 | ...[...] | array_flow.rb:1622:16:1622:28 | call to source | array_flow.rb:1631:10:1631:15 | ...[...] | $@ | array_flow.rb:1622:16:1622:28 | call to source | call to source | -| array_flow.rb:1631:10:1631:15 | ...[...] | array_flow.rb:1624:14:1624:26 | call to source | array_flow.rb:1631:10:1631:15 | ...[...] | $@ | array_flow.rb:1624:14:1624:26 | call to source | call to source | -| array_flow.rb:1631:10:1631:15 | ...[...] | array_flow.rb:1626:16:1626:28 | call to source | array_flow.rb:1631:10:1631:15 | ...[...] | $@ | array_flow.rb:1626:16:1626:28 | call to source | call to source | +| array_flow.rb:1313:10:1313:13 | ...[...] | array_flow.rb:1311:16:1311:28 | call to source | array_flow.rb:1313:10:1313:13 | ...[...] | $@ | array_flow.rb:1311:16:1311:28 | call to source | call to source | +| array_flow.rb:1313:10:1313:13 | ...[...] | array_flow.rb:1311:34:1311:46 | call to source | array_flow.rb:1313:10:1313:13 | ...[...] | $@ | array_flow.rb:1311:34:1311:46 | call to source | call to source | +| array_flow.rb:1314:10:1314:13 | ...[...] | array_flow.rb:1311:16:1311:28 | call to source | array_flow.rb:1314:10:1314:13 | ...[...] | $@ | array_flow.rb:1311:16:1311:28 | call to source | call to source | +| array_flow.rb:1314:10:1314:13 | ...[...] | array_flow.rb:1311:34:1311:46 | call to source | array_flow.rb:1314:10:1314:13 | ...[...] | $@ | array_flow.rb:1311:34:1311:46 | call to source | call to source | +| array_flow.rb:1315:10:1315:13 | ...[...] | array_flow.rb:1311:16:1311:28 | call to source | array_flow.rb:1315:10:1315:13 | ...[...] | $@ | array_flow.rb:1311:16:1311:28 | call to source | call to source | +| array_flow.rb:1315:10:1315:13 | ...[...] | array_flow.rb:1311:34:1311:46 | call to source | array_flow.rb:1315:10:1315:13 | ...[...] | $@ | array_flow.rb:1311:34:1311:46 | call to source | call to source | +| array_flow.rb:1316:10:1316:13 | ...[...] | array_flow.rb:1311:16:1311:28 | call to source | array_flow.rb:1316:10:1316:13 | ...[...] | $@ | array_flow.rb:1311:16:1311:28 | call to source | call to source | +| array_flow.rb:1316:10:1316:13 | ...[...] | array_flow.rb:1311:34:1311:46 | call to source | array_flow.rb:1316:10:1316:13 | ...[...] | $@ | array_flow.rb:1311:34:1311:46 | call to source | call to source | +| array_flow.rb:1317:10:1317:13 | ...[...] | array_flow.rb:1311:16:1311:28 | call to source | array_flow.rb:1317:10:1317:13 | ...[...] | $@ | array_flow.rb:1311:16:1311:28 | call to source | call to source | +| array_flow.rb:1317:10:1317:13 | ...[...] | array_flow.rb:1311:34:1311:46 | call to source | array_flow.rb:1317:10:1317:13 | ...[...] | $@ | array_flow.rb:1311:34:1311:46 | call to source | call to source | +| array_flow.rb:1318:10:1318:13 | ...[...] | array_flow.rb:1311:16:1311:28 | call to source | array_flow.rb:1318:10:1318:13 | ...[...] | $@ | array_flow.rb:1311:16:1311:28 | call to source | call to source | +| array_flow.rb:1318:10:1318:13 | ...[...] | array_flow.rb:1311:34:1311:46 | call to source | array_flow.rb:1318:10:1318:13 | ...[...] | $@ | array_flow.rb:1311:34:1311:46 | call to source | call to source | +| array_flow.rb:1322:10:1322:13 | ...[...] | array_flow.rb:1320:16:1320:28 | call to source | array_flow.rb:1322:10:1322:13 | ...[...] | $@ | array_flow.rb:1320:16:1320:28 | call to source | call to source | +| array_flow.rb:1322:10:1322:13 | ...[...] | array_flow.rb:1320:34:1320:46 | call to source | array_flow.rb:1322:10:1322:13 | ...[...] | $@ | array_flow.rb:1320:34:1320:46 | call to source | call to source | +| array_flow.rb:1323:10:1323:13 | ...[...] | array_flow.rb:1320:16:1320:28 | call to source | array_flow.rb:1323:10:1323:13 | ...[...] | $@ | array_flow.rb:1320:16:1320:28 | call to source | call to source | +| array_flow.rb:1323:10:1323:13 | ...[...] | array_flow.rb:1320:34:1320:46 | call to source | array_flow.rb:1323:10:1323:13 | ...[...] | $@ | array_flow.rb:1320:34:1320:46 | call to source | call to source | +| array_flow.rb:1324:10:1324:13 | ...[...] | array_flow.rb:1320:16:1320:28 | call to source | array_flow.rb:1324:10:1324:13 | ...[...] | $@ | array_flow.rb:1320:16:1320:28 | call to source | call to source | +| array_flow.rb:1324:10:1324:13 | ...[...] | array_flow.rb:1320:34:1320:46 | call to source | array_flow.rb:1324:10:1324:13 | ...[...] | $@ | array_flow.rb:1320:34:1320:46 | call to source | call to source | +| array_flow.rb:1325:10:1325:13 | ...[...] | array_flow.rb:1320:16:1320:28 | call to source | array_flow.rb:1325:10:1325:13 | ...[...] | $@ | array_flow.rb:1320:16:1320:28 | call to source | call to source | +| array_flow.rb:1325:10:1325:13 | ...[...] | array_flow.rb:1320:34:1320:46 | call to source | array_flow.rb:1325:10:1325:13 | ...[...] | $@ | array_flow.rb:1320:34:1320:46 | call to source | call to source | +| array_flow.rb:1326:10:1326:13 | ...[...] | array_flow.rb:1320:16:1320:28 | call to source | array_flow.rb:1326:10:1326:13 | ...[...] | $@ | array_flow.rb:1320:16:1320:28 | call to source | call to source | +| array_flow.rb:1326:10:1326:13 | ...[...] | array_flow.rb:1320:34:1320:46 | call to source | array_flow.rb:1326:10:1326:13 | ...[...] | $@ | array_flow.rb:1320:34:1320:46 | call to source | call to source | +| array_flow.rb:1327:10:1327:13 | ...[...] | array_flow.rb:1320:16:1320:28 | call to source | array_flow.rb:1327:10:1327:13 | ...[...] | $@ | array_flow.rb:1320:16:1320:28 | call to source | call to source | +| array_flow.rb:1327:10:1327:13 | ...[...] | array_flow.rb:1320:34:1320:46 | call to source | array_flow.rb:1327:10:1327:13 | ...[...] | $@ | array_flow.rb:1320:34:1320:46 | call to source | call to source | +| array_flow.rb:1331:10:1331:13 | ...[...] | array_flow.rb:1329:16:1329:28 | call to source | array_flow.rb:1331:10:1331:13 | ...[...] | $@ | array_flow.rb:1329:16:1329:28 | call to source | call to source | +| array_flow.rb:1331:10:1331:13 | ...[...] | array_flow.rb:1329:34:1329:46 | call to source | array_flow.rb:1331:10:1331:13 | ...[...] | $@ | array_flow.rb:1329:34:1329:46 | call to source | call to source | +| array_flow.rb:1332:10:1332:13 | ...[...] | array_flow.rb:1329:16:1329:28 | call to source | array_flow.rb:1332:10:1332:13 | ...[...] | $@ | array_flow.rb:1329:16:1329:28 | call to source | call to source | +| array_flow.rb:1332:10:1332:13 | ...[...] | array_flow.rb:1329:34:1329:46 | call to source | array_flow.rb:1332:10:1332:13 | ...[...] | $@ | array_flow.rb:1329:34:1329:46 | call to source | call to source | +| array_flow.rb:1333:10:1333:13 | ...[...] | array_flow.rb:1329:16:1329:28 | call to source | array_flow.rb:1333:10:1333:13 | ...[...] | $@ | array_flow.rb:1329:16:1329:28 | call to source | call to source | +| array_flow.rb:1333:10:1333:13 | ...[...] | array_flow.rb:1329:34:1329:46 | call to source | array_flow.rb:1333:10:1333:13 | ...[...] | $@ | array_flow.rb:1329:34:1329:46 | call to source | call to source | +| array_flow.rb:1334:10:1334:13 | ...[...] | array_flow.rb:1329:16:1329:28 | call to source | array_flow.rb:1334:10:1334:13 | ...[...] | $@ | array_flow.rb:1329:16:1329:28 | call to source | call to source | +| array_flow.rb:1334:10:1334:13 | ...[...] | array_flow.rb:1329:34:1329:46 | call to source | array_flow.rb:1334:10:1334:13 | ...[...] | $@ | array_flow.rb:1329:34:1329:46 | call to source | call to source | +| array_flow.rb:1335:10:1335:13 | ...[...] | array_flow.rb:1329:16:1329:28 | call to source | array_flow.rb:1335:10:1335:13 | ...[...] | $@ | array_flow.rb:1329:16:1329:28 | call to source | call to source | +| array_flow.rb:1335:10:1335:13 | ...[...] | array_flow.rb:1329:34:1329:46 | call to source | array_flow.rb:1335:10:1335:13 | ...[...] | $@ | array_flow.rb:1329:34:1329:46 | call to source | call to source | +| array_flow.rb:1336:10:1336:13 | ...[...] | array_flow.rb:1329:16:1329:28 | call to source | array_flow.rb:1336:10:1336:13 | ...[...] | $@ | array_flow.rb:1329:16:1329:28 | call to source | call to source | +| array_flow.rb:1336:10:1336:13 | ...[...] | array_flow.rb:1329:34:1329:46 | call to source | array_flow.rb:1336:10:1336:13 | ...[...] | $@ | array_flow.rb:1329:34:1329:46 | call to source | call to source | +| array_flow.rb:1342:10:1342:13 | ...[...] | array_flow.rb:1338:16:1338:28 | call to source | array_flow.rb:1342:10:1342:13 | ...[...] | $@ | array_flow.rb:1338:16:1338:28 | call to source | call to source | +| array_flow.rb:1344:10:1344:13 | ...[...] | array_flow.rb:1338:34:1338:46 | call to source | array_flow.rb:1344:10:1344:13 | ...[...] | $@ | array_flow.rb:1338:34:1338:46 | call to source | call to source | +| array_flow.rb:1349:10:1349:13 | ...[...] | array_flow.rb:1347:16:1347:28 | call to source | array_flow.rb:1349:10:1349:13 | ...[...] | $@ | array_flow.rb:1347:16:1347:28 | call to source | call to source | +| array_flow.rb:1349:10:1349:13 | ...[...] | array_flow.rb:1347:34:1347:46 | call to source | array_flow.rb:1349:10:1349:13 | ...[...] | $@ | array_flow.rb:1347:34:1347:46 | call to source | call to source | +| array_flow.rb:1350:10:1350:13 | ...[...] | array_flow.rb:1347:16:1347:28 | call to source | array_flow.rb:1350:10:1350:13 | ...[...] | $@ | array_flow.rb:1347:16:1347:28 | call to source | call to source | +| array_flow.rb:1350:10:1350:13 | ...[...] | array_flow.rb:1347:34:1347:46 | call to source | array_flow.rb:1350:10:1350:13 | ...[...] | $@ | array_flow.rb:1347:34:1347:46 | call to source | call to source | +| array_flow.rb:1351:10:1351:13 | ...[...] | array_flow.rb:1347:16:1347:28 | call to source | array_flow.rb:1351:10:1351:13 | ...[...] | $@ | array_flow.rb:1347:16:1347:28 | call to source | call to source | +| array_flow.rb:1351:10:1351:13 | ...[...] | array_flow.rb:1347:34:1347:46 | call to source | array_flow.rb:1351:10:1351:13 | ...[...] | $@ | array_flow.rb:1347:34:1347:46 | call to source | call to source | +| array_flow.rb:1352:10:1352:13 | ...[...] | array_flow.rb:1347:16:1347:28 | call to source | array_flow.rb:1352:10:1352:13 | ...[...] | $@ | array_flow.rb:1347:16:1347:28 | call to source | call to source | +| array_flow.rb:1352:10:1352:13 | ...[...] | array_flow.rb:1347:34:1347:46 | call to source | array_flow.rb:1352:10:1352:13 | ...[...] | $@ | array_flow.rb:1347:34:1347:46 | call to source | call to source | +| array_flow.rb:1353:10:1353:13 | ...[...] | array_flow.rb:1347:16:1347:28 | call to source | array_flow.rb:1353:10:1353:13 | ...[...] | $@ | array_flow.rb:1347:16:1347:28 | call to source | call to source | +| array_flow.rb:1353:10:1353:13 | ...[...] | array_flow.rb:1347:34:1347:46 | call to source | array_flow.rb:1353:10:1353:13 | ...[...] | $@ | array_flow.rb:1347:34:1347:46 | call to source | call to source | +| array_flow.rb:1354:10:1354:13 | ...[...] | array_flow.rb:1347:16:1347:28 | call to source | array_flow.rb:1354:10:1354:13 | ...[...] | $@ | array_flow.rb:1347:16:1347:28 | call to source | call to source | +| array_flow.rb:1354:10:1354:13 | ...[...] | array_flow.rb:1347:34:1347:46 | call to source | array_flow.rb:1354:10:1354:13 | ...[...] | $@ | array_flow.rb:1347:34:1347:46 | call to source | call to source | +| array_flow.rb:1360:14:1360:14 | x | array_flow.rb:1358:16:1358:26 | call to source | array_flow.rb:1360:14:1360:14 | x | $@ | array_flow.rb:1358:16:1358:26 | call to source | call to source | +| array_flow.rb:1368:14:1368:14 | x | array_flow.rb:1366:16:1366:26 | call to source | array_flow.rb:1368:14:1368:14 | x | $@ | array_flow.rb:1366:16:1366:26 | call to source | call to source | +| array_flow.rb:1376:14:1376:14 | x | array_flow.rb:1374:16:1374:26 | call to source | array_flow.rb:1376:14:1376:14 | x | $@ | array_flow.rb:1374:16:1374:26 | call to source | call to source | +| array_flow.rb:1377:14:1377:14 | y | array_flow.rb:1374:16:1374:26 | call to source | array_flow.rb:1377:14:1377:14 | y | $@ | array_flow.rb:1374:16:1374:26 | call to source | call to source | +| array_flow.rb:1384:10:1384:13 | ...[...] | array_flow.rb:1382:16:1382:26 | call to source | array_flow.rb:1384:10:1384:13 | ...[...] | $@ | array_flow.rb:1382:16:1382:26 | call to source | call to source | +| array_flow.rb:1385:10:1385:13 | ...[...] | array_flow.rb:1382:16:1382:26 | call to source | array_flow.rb:1385:10:1385:13 | ...[...] | $@ | array_flow.rb:1382:16:1382:26 | call to source | call to source | +| array_flow.rb:1387:14:1387:14 | x | array_flow.rb:1382:16:1382:26 | call to source | array_flow.rb:1387:14:1387:14 | x | $@ | array_flow.rb:1382:16:1382:26 | call to source | call to source | +| array_flow.rb:1388:14:1388:14 | y | array_flow.rb:1382:16:1382:26 | call to source | array_flow.rb:1388:14:1388:14 | y | $@ | array_flow.rb:1382:16:1382:26 | call to source | call to source | +| array_flow.rb:1391:10:1391:13 | ...[...] | array_flow.rb:1382:16:1382:26 | call to source | array_flow.rb:1391:10:1391:13 | ...[...] | $@ | array_flow.rb:1382:16:1382:26 | call to source | call to source | +| array_flow.rb:1392:10:1392:13 | ...[...] | array_flow.rb:1382:16:1382:26 | call to source | array_flow.rb:1392:10:1392:13 | ...[...] | $@ | array_flow.rb:1382:16:1382:26 | call to source | call to source | +| array_flow.rb:1398:10:1398:13 | ...[...] | array_flow.rb:1396:16:1396:26 | call to source | array_flow.rb:1398:10:1398:13 | ...[...] | $@ | array_flow.rb:1396:16:1396:26 | call to source | call to source | +| array_flow.rb:1399:10:1399:13 | ...[...] | array_flow.rb:1396:16:1396:26 | call to source | array_flow.rb:1399:10:1399:13 | ...[...] | $@ | array_flow.rb:1396:16:1396:26 | call to source | call to source | +| array_flow.rb:1400:10:1400:13 | ...[...] | array_flow.rb:1396:16:1396:26 | call to source | array_flow.rb:1400:10:1400:13 | ...[...] | $@ | array_flow.rb:1396:16:1396:26 | call to source | call to source | +| array_flow.rb:1401:10:1401:13 | ...[...] | array_flow.rb:1396:16:1396:26 | call to source | array_flow.rb:1401:10:1401:13 | ...[...] | $@ | array_flow.rb:1396:16:1396:26 | call to source | call to source | +| array_flow.rb:1405:14:1405:14 | x | array_flow.rb:1403:16:1403:26 | call to source | array_flow.rb:1405:14:1405:14 | x | $@ | array_flow.rb:1403:16:1403:26 | call to source | call to source | +| array_flow.rb:1406:14:1406:14 | y | array_flow.rb:1403:16:1403:26 | call to source | array_flow.rb:1406:14:1406:14 | y | $@ | array_flow.rb:1403:16:1403:26 | call to source | call to source | +| array_flow.rb:1409:10:1409:13 | ...[...] | array_flow.rb:1403:16:1403:26 | call to source | array_flow.rb:1409:10:1409:13 | ...[...] | $@ | array_flow.rb:1403:16:1403:26 | call to source | call to source | +| array_flow.rb:1410:10:1410:13 | ...[...] | array_flow.rb:1403:16:1403:26 | call to source | array_flow.rb:1410:10:1410:13 | ...[...] | $@ | array_flow.rb:1403:16:1403:26 | call to source | call to source | +| array_flow.rb:1411:10:1411:13 | ...[...] | array_flow.rb:1403:16:1403:26 | call to source | array_flow.rb:1411:10:1411:13 | ...[...] | $@ | array_flow.rb:1403:16:1403:26 | call to source | call to source | +| array_flow.rb:1412:10:1412:13 | ...[...] | array_flow.rb:1403:16:1403:26 | call to source | array_flow.rb:1412:10:1412:13 | ...[...] | $@ | array_flow.rb:1403:16:1403:26 | call to source | call to source | +| array_flow.rb:1418:14:1418:14 | x | array_flow.rb:1416:16:1416:26 | call to source | array_flow.rb:1418:14:1418:14 | x | $@ | array_flow.rb:1416:16:1416:26 | call to source | call to source | +| array_flow.rb:1421:10:1421:13 | ...[...] | array_flow.rb:1416:16:1416:26 | call to source | array_flow.rb:1421:10:1421:13 | ...[...] | $@ | array_flow.rb:1416:16:1416:26 | call to source | call to source | +| array_flow.rb:1422:10:1422:13 | ...[...] | array_flow.rb:1416:16:1416:26 | call to source | array_flow.rb:1422:10:1422:13 | ...[...] | $@ | array_flow.rb:1416:16:1416:26 | call to source | call to source | +| array_flow.rb:1428:14:1428:14 | x | array_flow.rb:1426:16:1426:26 | call to source | array_flow.rb:1428:14:1428:14 | x | $@ | array_flow.rb:1426:16:1426:26 | call to source | call to source | +| array_flow.rb:1431:10:1431:13 | ...[...] | array_flow.rb:1426:16:1426:26 | call to source | array_flow.rb:1431:10:1431:13 | ...[...] | $@ | array_flow.rb:1426:16:1426:26 | call to source | call to source | +| array_flow.rb:1432:10:1432:13 | ...[...] | array_flow.rb:1426:16:1426:26 | call to source | array_flow.rb:1432:10:1432:13 | ...[...] | $@ | array_flow.rb:1426:16:1426:26 | call to source | call to source | +| array_flow.rb:1433:10:1433:13 | ...[...] | array_flow.rb:1426:16:1426:26 | call to source | array_flow.rb:1433:10:1433:13 | ...[...] | $@ | array_flow.rb:1426:16:1426:26 | call to source | call to source | +| array_flow.rb:1434:10:1434:13 | ...[...] | array_flow.rb:1426:16:1426:26 | call to source | array_flow.rb:1434:10:1434:13 | ...[...] | $@ | array_flow.rb:1426:16:1426:26 | call to source | call to source | +| array_flow.rb:1440:14:1440:14 | x | array_flow.rb:1438:16:1438:26 | call to source | array_flow.rb:1440:14:1440:14 | x | $@ | array_flow.rb:1438:16:1438:26 | call to source | call to source | +| array_flow.rb:1450:10:1450:13 | ...[...] | array_flow.rb:1446:16:1446:28 | call to source | array_flow.rb:1450:10:1450:13 | ...[...] | $@ | array_flow.rb:1446:16:1446:28 | call to source | call to source | +| array_flow.rb:1451:10:1451:13 | ...[...] | array_flow.rb:1446:31:1446:43 | call to source | array_flow.rb:1451:10:1451:13 | ...[...] | $@ | array_flow.rb:1446:31:1446:43 | call to source | call to source | +| array_flow.rb:1455:10:1455:13 | ...[...] | array_flow.rb:1446:16:1446:28 | call to source | array_flow.rb:1455:10:1455:13 | ...[...] | $@ | array_flow.rb:1446:16:1446:28 | call to source | call to source | +| array_flow.rb:1457:10:1457:13 | ...[...] | array_flow.rb:1446:16:1446:28 | call to source | array_flow.rb:1457:10:1457:13 | ...[...] | $@ | array_flow.rb:1446:16:1446:28 | call to source | call to source | +| array_flow.rb:1461:10:1461:13 | ...[...] | array_flow.rb:1446:16:1446:28 | call to source | array_flow.rb:1461:10:1461:13 | ...[...] | $@ | array_flow.rb:1446:16:1446:28 | call to source | call to source | +| array_flow.rb:1462:10:1462:13 | ...[...] | array_flow.rb:1446:31:1446:43 | call to source | array_flow.rb:1462:10:1462:13 | ...[...] | $@ | array_flow.rb:1446:31:1446:43 | call to source | call to source | +| array_flow.rb:1463:10:1463:13 | ...[...] | array_flow.rb:1446:16:1446:28 | call to source | array_flow.rb:1463:10:1463:13 | ...[...] | $@ | array_flow.rb:1446:16:1446:28 | call to source | call to source | +| array_flow.rb:1463:10:1463:13 | ...[...] | array_flow.rb:1446:31:1446:43 | call to source | array_flow.rb:1463:10:1463:13 | ...[...] | $@ | array_flow.rb:1446:31:1446:43 | call to source | call to source | +| array_flow.rb:1466:10:1466:13 | ...[...] | array_flow.rb:1446:16:1446:28 | call to source | array_flow.rb:1466:10:1466:13 | ...[...] | $@ | array_flow.rb:1446:16:1446:28 | call to source | call to source | +| array_flow.rb:1466:10:1466:13 | ...[...] | array_flow.rb:1464:12:1464:24 | call to source | array_flow.rb:1466:10:1466:13 | ...[...] | $@ | array_flow.rb:1464:12:1464:24 | call to source | call to source | +| array_flow.rb:1472:14:1472:14 | x | array_flow.rb:1470:16:1470:26 | call to source | array_flow.rb:1472:14:1472:14 | x | $@ | array_flow.rb:1470:16:1470:26 | call to source | call to source | +| array_flow.rb:1477:10:1477:13 | ...[...] | array_flow.rb:1470:16:1470:26 | call to source | array_flow.rb:1477:10:1477:13 | ...[...] | $@ | array_flow.rb:1470:16:1470:26 | call to source | call to source | +| array_flow.rb:1485:10:1485:13 | ...[...] | array_flow.rb:1483:19:1483:29 | call to source | array_flow.rb:1485:10:1485:13 | ...[...] | $@ | array_flow.rb:1483:19:1483:29 | call to source | call to source | +| array_flow.rb:1493:10:1493:13 | ...[...] | array_flow.rb:1489:16:1489:26 | call to source | array_flow.rb:1493:10:1493:13 | ...[...] | $@ | array_flow.rb:1489:16:1489:26 | call to source | call to source | +| array_flow.rb:1511:10:1511:16 | ...[...] | array_flow.rb:1506:14:1506:26 | call to source | array_flow.rb:1511:10:1511:16 | ...[...] | $@ | array_flow.rb:1506:14:1506:26 | call to source | call to source | +| array_flow.rb:1512:10:1512:16 | ...[...] | array_flow.rb:1506:34:1506:46 | call to source | array_flow.rb:1512:10:1512:16 | ...[...] | $@ | array_flow.rb:1506:34:1506:46 | call to source | call to source | +| array_flow.rb:1513:10:1513:16 | ...[...] | array_flow.rb:1506:54:1506:66 | call to source | array_flow.rb:1513:10:1513:16 | ...[...] | $@ | array_flow.rb:1506:54:1506:66 | call to source | call to source | +| array_flow.rb:1521:10:1521:13 | ...[...] | array_flow.rb:1517:16:1517:28 | call to source | array_flow.rb:1521:10:1521:13 | ...[...] | $@ | array_flow.rb:1517:16:1517:28 | call to source | call to source | +| array_flow.rb:1521:10:1521:13 | ...[...] | array_flow.rb:1518:13:1518:25 | call to source | array_flow.rb:1521:10:1521:13 | ...[...] | $@ | array_flow.rb:1518:13:1518:25 | call to source | call to source | +| array_flow.rb:1521:10:1521:13 | ...[...] | array_flow.rb:1519:13:1519:25 | call to source | array_flow.rb:1521:10:1521:13 | ...[...] | $@ | array_flow.rb:1519:13:1519:25 | call to source | call to source | +| array_flow.rb:1522:10:1522:13 | ...[...] | array_flow.rb:1517:16:1517:28 | call to source | array_flow.rb:1522:10:1522:13 | ...[...] | $@ | array_flow.rb:1517:16:1517:28 | call to source | call to source | +| array_flow.rb:1522:10:1522:13 | ...[...] | array_flow.rb:1518:13:1518:25 | call to source | array_flow.rb:1522:10:1522:13 | ...[...] | $@ | array_flow.rb:1518:13:1518:25 | call to source | call to source | +| array_flow.rb:1522:10:1522:13 | ...[...] | array_flow.rb:1519:13:1519:25 | call to source | array_flow.rb:1522:10:1522:13 | ...[...] | $@ | array_flow.rb:1519:13:1519:25 | call to source | call to source | +| array_flow.rb:1523:10:1523:13 | ...[...] | array_flow.rb:1517:16:1517:28 | call to source | array_flow.rb:1523:10:1523:13 | ...[...] | $@ | array_flow.rb:1517:16:1517:28 | call to source | call to source | +| array_flow.rb:1523:10:1523:13 | ...[...] | array_flow.rb:1518:13:1518:25 | call to source | array_flow.rb:1523:10:1523:13 | ...[...] | $@ | array_flow.rb:1518:13:1518:25 | call to source | call to source | +| array_flow.rb:1523:10:1523:13 | ...[...] | array_flow.rb:1519:13:1519:25 | call to source | array_flow.rb:1523:10:1523:13 | ...[...] | $@ | array_flow.rb:1519:13:1519:25 | call to source | call to source | +| array_flow.rb:1530:10:1530:13 | ...[...] | array_flow.rb:1527:19:1527:31 | call to source | array_flow.rb:1530:10:1530:13 | ...[...] | $@ | array_flow.rb:1527:19:1527:31 | call to source | call to source | +| array_flow.rb:1530:10:1530:13 | ...[...] | array_flow.rb:1527:34:1527:46 | call to source | array_flow.rb:1530:10:1530:13 | ...[...] | $@ | array_flow.rb:1527:34:1527:46 | call to source | call to source | +| array_flow.rb:1531:10:1531:13 | ...[...] | array_flow.rb:1527:19:1527:31 | call to source | array_flow.rb:1531:10:1531:13 | ...[...] | $@ | array_flow.rb:1527:19:1527:31 | call to source | call to source | +| array_flow.rb:1531:10:1531:13 | ...[...] | array_flow.rb:1527:34:1527:46 | call to source | array_flow.rb:1531:10:1531:13 | ...[...] | $@ | array_flow.rb:1527:34:1527:46 | call to source | call to source | +| array_flow.rb:1534:14:1534:14 | x | array_flow.rb:1527:19:1527:31 | call to source | array_flow.rb:1534:14:1534:14 | x | $@ | array_flow.rb:1527:19:1527:31 | call to source | call to source | +| array_flow.rb:1534:14:1534:14 | x | array_flow.rb:1527:34:1527:46 | call to source | array_flow.rb:1534:14:1534:14 | x | $@ | array_flow.rb:1527:34:1527:46 | call to source | call to source | +| array_flow.rb:1537:10:1537:13 | ...[...] | array_flow.rb:1527:19:1527:31 | call to source | array_flow.rb:1537:10:1537:13 | ...[...] | $@ | array_flow.rb:1527:19:1527:31 | call to source | call to source | +| array_flow.rb:1537:10:1537:13 | ...[...] | array_flow.rb:1527:34:1527:46 | call to source | array_flow.rb:1537:10:1537:13 | ...[...] | $@ | array_flow.rb:1527:34:1527:46 | call to source | call to source | +| array_flow.rb:1543:10:1543:13 | ...[...] | array_flow.rb:1541:16:1541:28 | call to source | array_flow.rb:1543:10:1543:13 | ...[...] | $@ | array_flow.rb:1541:16:1541:28 | call to source | call to source | +| array_flow.rb:1543:10:1543:13 | ...[...] | array_flow.rb:1541:31:1541:43 | call to source | array_flow.rb:1543:10:1543:13 | ...[...] | $@ | array_flow.rb:1541:31:1541:43 | call to source | call to source | +| array_flow.rb:1544:10:1544:13 | ...[...] | array_flow.rb:1541:16:1541:28 | call to source | array_flow.rb:1544:10:1544:13 | ...[...] | $@ | array_flow.rb:1541:16:1541:28 | call to source | call to source | +| array_flow.rb:1544:10:1544:13 | ...[...] | array_flow.rb:1541:31:1541:43 | call to source | array_flow.rb:1544:10:1544:13 | ...[...] | $@ | array_flow.rb:1541:31:1541:43 | call to source | call to source | +| array_flow.rb:1545:10:1545:13 | ...[...] | array_flow.rb:1541:16:1541:28 | call to source | array_flow.rb:1545:10:1545:13 | ...[...] | $@ | array_flow.rb:1541:16:1541:28 | call to source | call to source | +| array_flow.rb:1545:10:1545:13 | ...[...] | array_flow.rb:1541:31:1541:43 | call to source | array_flow.rb:1545:10:1545:13 | ...[...] | $@ | array_flow.rb:1541:31:1541:43 | call to source | call to source | +| array_flow.rb:1546:10:1546:13 | ...[...] | array_flow.rb:1541:16:1541:28 | call to source | array_flow.rb:1546:10:1546:13 | ...[...] | $@ | array_flow.rb:1541:16:1541:28 | call to source | call to source | +| array_flow.rb:1546:10:1546:13 | ...[...] | array_flow.rb:1541:31:1541:43 | call to source | array_flow.rb:1546:10:1546:13 | ...[...] | $@ | array_flow.rb:1541:31:1541:43 | call to source | call to source | +| array_flow.rb:1550:14:1550:14 | x | array_flow.rb:1548:16:1548:28 | call to source | array_flow.rb:1550:14:1550:14 | x | $@ | array_flow.rb:1548:16:1548:28 | call to source | call to source | +| array_flow.rb:1550:14:1550:14 | x | array_flow.rb:1548:31:1548:43 | call to source | array_flow.rb:1550:14:1550:14 | x | $@ | array_flow.rb:1548:31:1548:43 | call to source | call to source | +| array_flow.rb:1553:10:1553:13 | ...[...] | array_flow.rb:1548:16:1548:28 | call to source | array_flow.rb:1553:10:1553:13 | ...[...] | $@ | array_flow.rb:1548:16:1548:28 | call to source | call to source | +| array_flow.rb:1553:10:1553:13 | ...[...] | array_flow.rb:1548:31:1548:43 | call to source | array_flow.rb:1553:10:1553:13 | ...[...] | $@ | array_flow.rb:1548:31:1548:43 | call to source | call to source | +| array_flow.rb:1554:10:1554:13 | ...[...] | array_flow.rb:1548:16:1548:28 | call to source | array_flow.rb:1554:10:1554:13 | ...[...] | $@ | array_flow.rb:1548:16:1548:28 | call to source | call to source | +| array_flow.rb:1554:10:1554:13 | ...[...] | array_flow.rb:1548:31:1548:43 | call to source | array_flow.rb:1554:10:1554:13 | ...[...] | $@ | array_flow.rb:1548:31:1548:43 | call to source | call to source | +| array_flow.rb:1555:10:1555:13 | ...[...] | array_flow.rb:1548:16:1548:28 | call to source | array_flow.rb:1555:10:1555:13 | ...[...] | $@ | array_flow.rb:1548:16:1548:28 | call to source | call to source | +| array_flow.rb:1555:10:1555:13 | ...[...] | array_flow.rb:1548:31:1548:43 | call to source | array_flow.rb:1555:10:1555:13 | ...[...] | $@ | array_flow.rb:1548:31:1548:43 | call to source | call to source | +| array_flow.rb:1556:10:1556:13 | ...[...] | array_flow.rb:1548:16:1548:28 | call to source | array_flow.rb:1556:10:1556:13 | ...[...] | $@ | array_flow.rb:1548:16:1548:28 | call to source | call to source | +| array_flow.rb:1556:10:1556:13 | ...[...] | array_flow.rb:1548:31:1548:43 | call to source | array_flow.rb:1556:10:1556:13 | ...[...] | $@ | array_flow.rb:1548:31:1548:43 | call to source | call to source | +| array_flow.rb:1564:10:1564:13 | ...[...] | array_flow.rb:1561:21:1561:33 | call to source | array_flow.rb:1564:10:1564:13 | ...[...] | $@ | array_flow.rb:1561:21:1561:33 | call to source | call to source | +| array_flow.rb:1567:10:1567:13 | ...[...] | array_flow.rb:1560:16:1560:28 | call to source | array_flow.rb:1567:10:1567:13 | ...[...] | $@ | array_flow.rb:1560:16:1560:28 | call to source | call to source | +| array_flow.rb:1575:10:1575:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1575:10:1575:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1577:10:1577:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1577:10:1577:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1580:10:1580:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1580:10:1580:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1580:10:1580:13 | ...[...] | array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1580:10:1580:13 | ...[...] | $@ | array_flow.rb:1571:31:1571:43 | call to source | call to source | +| array_flow.rb:1581:10:1581:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1581:10:1581:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1581:10:1581:13 | ...[...] | array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1581:10:1581:13 | ...[...] | $@ | array_flow.rb:1571:31:1571:43 | call to source | call to source | +| array_flow.rb:1584:10:1584:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1584:10:1584:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1584:10:1584:13 | ...[...] | array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1584:10:1584:13 | ...[...] | $@ | array_flow.rb:1571:31:1571:43 | call to source | call to source | +| array_flow.rb:1585:10:1585:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1585:10:1585:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1585:10:1585:13 | ...[...] | array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1585:10:1585:13 | ...[...] | $@ | array_flow.rb:1571:31:1571:43 | call to source | call to source | +| array_flow.rb:1588:10:1588:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1588:10:1588:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1588:10:1588:13 | ...[...] | array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1588:10:1588:13 | ...[...] | $@ | array_flow.rb:1571:31:1571:43 | call to source | call to source | +| array_flow.rb:1589:10:1589:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1589:10:1589:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1589:10:1589:13 | ...[...] | array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1589:10:1589:13 | ...[...] | $@ | array_flow.rb:1571:31:1571:43 | call to source | call to source | +| array_flow.rb:1590:10:1590:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1590:10:1590:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1590:10:1590:13 | ...[...] | array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1590:10:1590:13 | ...[...] | $@ | array_flow.rb:1571:31:1571:43 | call to source | call to source | +| array_flow.rb:1591:10:1591:13 | ...[...] | array_flow.rb:1571:13:1571:25 | call to source | array_flow.rb:1591:10:1591:13 | ...[...] | $@ | array_flow.rb:1571:13:1571:25 | call to source | call to source | +| array_flow.rb:1591:10:1591:13 | ...[...] | array_flow.rb:1571:31:1571:43 | call to source | array_flow.rb:1591:10:1591:13 | ...[...] | $@ | array_flow.rb:1571:31:1571:43 | call to source | call to source | +| array_flow.rb:1600:10:1600:16 | ...[...] | array_flow.rb:1597:10:1597:22 | call to source | array_flow.rb:1600:10:1600:16 | ...[...] | $@ | array_flow.rb:1597:10:1597:22 | call to source | call to source | +| array_flow.rb:1601:10:1601:16 | ...[...] | array_flow.rb:1596:13:1596:25 | call to source | array_flow.rb:1601:10:1601:16 | ...[...] | $@ | array_flow.rb:1596:13:1596:25 | call to source | call to source | +| array_flow.rb:1602:10:1602:16 | ...[...] | array_flow.rb:1595:16:1595:28 | call to source | array_flow.rb:1602:10:1602:16 | ...[...] | $@ | array_flow.rb:1595:16:1595:28 | call to source | call to source | +| array_flow.rb:1604:14:1604:17 | ...[...] | array_flow.rb:1595:16:1595:28 | call to source | array_flow.rb:1604:14:1604:17 | ...[...] | $@ | array_flow.rb:1595:16:1595:28 | call to source | call to source | +| array_flow.rb:1605:14:1605:17 | ...[...] | array_flow.rb:1596:13:1596:25 | call to source | array_flow.rb:1605:14:1605:17 | ...[...] | $@ | array_flow.rb:1596:13:1596:25 | call to source | call to source | +| array_flow.rb:1606:14:1606:17 | ...[...] | array_flow.rb:1597:10:1597:22 | call to source | array_flow.rb:1606:14:1606:17 | ...[...] | $@ | array_flow.rb:1597:10:1597:22 | call to source | call to source | +| array_flow.rb:1614:10:1614:13 | ...[...] | array_flow.rb:1611:16:1611:28 | call to source | array_flow.rb:1614:10:1614:13 | ...[...] | $@ | array_flow.rb:1611:16:1611:28 | call to source | call to source | +| array_flow.rb:1614:10:1614:13 | ...[...] | array_flow.rb:1612:13:1612:25 | call to source | array_flow.rb:1614:10:1614:13 | ...[...] | $@ | array_flow.rb:1612:13:1612:25 | call to source | call to source | +| array_flow.rb:1615:10:1615:13 | ...[...] | array_flow.rb:1611:16:1611:28 | call to source | array_flow.rb:1615:10:1615:13 | ...[...] | $@ | array_flow.rb:1611:16:1611:28 | call to source | call to source | +| array_flow.rb:1615:10:1615:13 | ...[...] | array_flow.rb:1612:13:1612:25 | call to source | array_flow.rb:1615:10:1615:13 | ...[...] | $@ | array_flow.rb:1612:13:1612:25 | call to source | call to source | +| array_flow.rb:1616:10:1616:13 | ...[...] | array_flow.rb:1611:16:1611:28 | call to source | array_flow.rb:1616:10:1616:13 | ...[...] | $@ | array_flow.rb:1611:16:1611:28 | call to source | call to source | +| array_flow.rb:1616:10:1616:13 | ...[...] | array_flow.rb:1612:13:1612:25 | call to source | array_flow.rb:1616:10:1616:13 | ...[...] | $@ | array_flow.rb:1612:13:1612:25 | call to source | call to source | +| array_flow.rb:1622:10:1622:16 | ...[...] | array_flow.rb:1621:15:1621:27 | call to source | array_flow.rb:1622:10:1622:16 | ...[...] | $@ | array_flow.rb:1621:15:1621:27 | call to source | call to source | +| array_flow.rb:1625:10:1625:16 | ...[...] | array_flow.rb:1621:15:1621:27 | call to source | array_flow.rb:1625:10:1625:16 | ...[...] | $@ | array_flow.rb:1621:15:1621:27 | call to source | call to source | +| array_flow.rb:1625:10:1625:16 | ...[...] | array_flow.rb:1624:15:1624:27 | call to source | array_flow.rb:1625:10:1625:16 | ...[...] | $@ | array_flow.rb:1624:15:1624:27 | call to source | call to source | +| array_flow.rb:1626:10:1626:16 | ...[...] | array_flow.rb:1621:15:1621:27 | call to source | array_flow.rb:1626:10:1626:16 | ...[...] | $@ | array_flow.rb:1621:15:1621:27 | call to source | call to source | +| array_flow.rb:1638:10:1638:13 | ...[...] | array_flow.rb:1633:16:1633:28 | call to source | array_flow.rb:1638:10:1638:13 | ...[...] | $@ | array_flow.rb:1633:16:1633:28 | call to source | call to source | +| array_flow.rb:1638:10:1638:13 | ...[...] | array_flow.rb:1635:14:1635:26 | call to source | array_flow.rb:1638:10:1638:13 | ...[...] | $@ | array_flow.rb:1635:14:1635:26 | call to source | call to source | +| array_flow.rb:1638:10:1638:13 | ...[...] | array_flow.rb:1637:16:1637:28 | call to source | array_flow.rb:1638:10:1638:13 | ...[...] | $@ | array_flow.rb:1637:16:1637:28 | call to source | call to source | +| array_flow.rb:1640:10:1640:17 | ...[...] | array_flow.rb:1631:12:1631:24 | call to source | array_flow.rb:1640:10:1640:17 | ...[...] | $@ | array_flow.rb:1631:12:1631:24 | call to source | call to source | +| array_flow.rb:1640:10:1640:17 | ...[...] | array_flow.rb:1633:16:1633:28 | call to source | array_flow.rb:1640:10:1640:17 | ...[...] | $@ | array_flow.rb:1633:16:1633:28 | call to source | call to source | +| array_flow.rb:1640:10:1640:17 | ...[...] | array_flow.rb:1635:14:1635:26 | call to source | array_flow.rb:1640:10:1640:17 | ...[...] | $@ | array_flow.rb:1635:14:1635:26 | call to source | call to source | +| array_flow.rb:1640:10:1640:17 | ...[...] | array_flow.rb:1637:16:1637:28 | call to source | array_flow.rb:1640:10:1640:17 | ...[...] | $@ | array_flow.rb:1637:16:1637:28 | call to source | call to source | +| array_flow.rb:1642:10:1642:15 | ...[...] | array_flow.rb:1631:12:1631:24 | call to source | array_flow.rb:1642:10:1642:15 | ...[...] | $@ | array_flow.rb:1631:12:1631:24 | call to source | call to source | +| array_flow.rb:1642:10:1642:15 | ...[...] | array_flow.rb:1633:16:1633:28 | call to source | array_flow.rb:1642:10:1642:15 | ...[...] | $@ | array_flow.rb:1633:16:1633:28 | call to source | call to source | +| array_flow.rb:1642:10:1642:15 | ...[...] | array_flow.rb:1635:14:1635:26 | call to source | array_flow.rb:1642:10:1642:15 | ...[...] | $@ | array_flow.rb:1635:14:1635:26 | call to source | call to source | +| array_flow.rb:1642:10:1642:15 | ...[...] | array_flow.rb:1637:16:1637:28 | call to source | array_flow.rb:1642:10:1642:15 | ...[...] | $@ | array_flow.rb:1637:16:1637:28 | call to source | call to source | diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb b/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb index 9600b64eaa3..6c617945c2e 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb +++ b/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb @@ -506,8 +506,19 @@ def m56 a = [0, 1, 2, source(56)] b = a.filter_map do |x| sink(x) # $ hasValueFlow=56 + x end - sink(b[0]) # $ hasValueFlow=56 + sink(b[3]) # $ hasValueFlow=56 + + c = a.filter_map do |x| + "safe" + end + sink(c[0]) # safe + + d = ["safe"].filter_map do |x| + source(56.1) + end + sink(d[0]) # $ hasValueFlow=56.1 end def m57 @@ -1629,4 +1640,4 @@ def m137 sink(a[10001]) # $ hasValueFlow=137.1 $ hasValueFlow=137.2 $ hasValueFlow=137.3 $ hasValueFlow=137.4 # unknown read sink(a[1.0]) # $ hasValueFlow=137.1 $ hasValueFlow=137.2 $ hasValueFlow=137.3 $ hasValueFlow=137.4 -end \ No newline at end of file +end From d47477bd3bdf843edf62355176849bd63f20d341 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 9 Jun 2023 14:52:21 +0200 Subject: [PATCH 471/739] Ruby: update line numbers in expectation file --- .../type-tracking-array-flow.expected | 236 +++++++++--------- 1 file changed, 118 insertions(+), 118 deletions(-) diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected index d92fb3132b1..83e81729d98 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected @@ -25,138 +25,138 @@ | array_flow.rb:490:10:490:13 | ...[...] | Unexpected result: hasValueFlow=54.5 | | array_flow.rb:494:10:494:13 | ...[...] | Unexpected result: hasValueFlow=54.2 | | array_flow.rb:494:10:494:13 | ...[...] | Unexpected result: hasValueFlow=54.3 | -| array_flow.rb:575:16:575:34 | # $ hasValueFlow=63 | Missing result:hasValueFlow=63 | -| array_flow.rb:580:19:580:37 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 | -| array_flow.rb:582:16:582:34 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 | -| array_flow.rb:583:19:583:47 | # $ SPURIOUS: hasValueFlow=64 | Fixed spurious result:hasValueFlow=64 | -| array_flow.rb:584:16:584:34 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 | -| array_flow.rb:585:19:585:47 | # $ SPURIOUS: hasValueFlow=64 | Fixed spurious result:hasValueFlow=64 | -| array_flow.rb:646:10:646:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | -| array_flow.rb:646:10:646:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | -| array_flow.rb:646:10:646:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | -| array_flow.rb:647:10:647:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | -| array_flow.rb:647:10:647:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | -| array_flow.rb:648:10:648:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | -| array_flow.rb:648:10:648:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | -| array_flow.rb:649:10:649:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | -| array_flow.rb:649:10:649:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | -| array_flow.rb:649:10:649:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | -| array_flow.rb:650:10:650:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | -| array_flow.rb:650:10:650:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | -| array_flow.rb:651:10:651:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | -| array_flow.rb:651:10:651:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | -| array_flow.rb:651:10:651:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | -| array_flow.rb:652:10:652:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | -| array_flow.rb:652:10:652:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | -| array_flow.rb:653:10:653:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | -| array_flow.rb:653:10:653:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | -| array_flow.rb:654:10:654:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | -| array_flow.rb:654:10:654:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | -| array_flow.rb:654:10:654:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | -| array_flow.rb:655:10:655:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | -| array_flow.rb:655:10:655:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | -| array_flow.rb:708:14:708:14 | x | Unexpected result: hasValueFlow=76.2 | -| array_flow.rb:860:18:860:36 | # $ hasValueFlow=87 | Missing result:hasValueFlow=87 | -| array_flow.rb:861:18:861:36 | # $ hasValueFlow=87 | Missing result:hasValueFlow=87 | -| array_flow.rb:915:10:915:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | -| array_flow.rb:915:10:915:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | -| array_flow.rb:916:10:916:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | -| array_flow.rb:916:10:916:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | -| array_flow.rb:917:10:917:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | -| array_flow.rb:918:10:918:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | -| array_flow.rb:918:10:918:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | -| array_flow.rb:919:10:919:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | -| array_flow.rb:919:10:919:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | -| array_flow.rb:920:10:920:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | -| array_flow.rb:928:18:928:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.1 | -| array_flow.rb:928:18:928:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.2 | -| array_flow.rb:928:18:928:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.3 | -| array_flow.rb:929:18:929:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.1 | -| array_flow.rb:929:18:929:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.2 | -| array_flow.rb:929:18:929:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.3 | -| array_flow.rb:946:28:946:46 | # $ hasValueFlow=93 | Missing result:hasValueFlow=93 | -| array_flow.rb:947:28:947:46 | # $ hasValueFlow=93 | Missing result:hasValueFlow=93 | -| array_flow.rb:1007:16:1007:36 | # $ hasValueFlow=99.2 | Missing result:hasValueFlow=99.2 | -| array_flow.rb:1086:10:1086:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | -| array_flow.rb:1086:10:1086:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | -| array_flow.rb:1087:10:1087:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | -| array_flow.rb:1088:10:1088:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | -| array_flow.rb:1089:10:1089:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | -| array_flow.rb:1089:10:1089:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | -| array_flow.rb:1090:10:1090:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | -| array_flow.rb:1090:10:1090:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | -| array_flow.rb:1091:10:1091:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | -| array_flow.rb:1092:10:1092:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | -| array_flow.rb:1093:10:1093:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | -| array_flow.rb:1093:10:1093:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | +| array_flow.rb:586:16:586:34 | # $ hasValueFlow=63 | Missing result:hasValueFlow=63 | +| array_flow.rb:591:19:591:37 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 | +| array_flow.rb:593:16:593:34 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 | +| array_flow.rb:594:19:594:47 | # $ SPURIOUS: hasValueFlow=64 | Fixed spurious result:hasValueFlow=64 | +| array_flow.rb:595:16:595:34 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 | +| array_flow.rb:596:19:596:47 | # $ SPURIOUS: hasValueFlow=64 | Fixed spurious result:hasValueFlow=64 | +| array_flow.rb:657:10:657:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | +| array_flow.rb:657:10:657:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | +| array_flow.rb:657:10:657:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | +| array_flow.rb:658:10:658:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | +| array_flow.rb:658:10:658:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | +| array_flow.rb:659:10:659:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | +| array_flow.rb:659:10:659:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | +| array_flow.rb:660:10:660:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | +| array_flow.rb:660:10:660:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | +| array_flow.rb:660:10:660:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | +| array_flow.rb:661:10:661:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | +| array_flow.rb:661:10:661:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | +| array_flow.rb:662:10:662:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | +| array_flow.rb:662:10:662:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | +| array_flow.rb:662:10:662:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | +| array_flow.rb:663:10:663:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | +| array_flow.rb:663:10:663:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | +| array_flow.rb:664:10:664:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | +| array_flow.rb:664:10:664:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | +| array_flow.rb:665:10:665:13 | ...[...] | Unexpected result: hasValueFlow=70.1 | +| array_flow.rb:665:10:665:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | +| array_flow.rb:665:10:665:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | +| array_flow.rb:666:10:666:13 | ...[...] | Unexpected result: hasValueFlow=70.2 | +| array_flow.rb:666:10:666:13 | ...[...] | Unexpected result: hasValueFlow=70.3 | +| array_flow.rb:719:14:719:14 | x | Unexpected result: hasValueFlow=76.2 | +| array_flow.rb:871:18:871:36 | # $ hasValueFlow=87 | Missing result:hasValueFlow=87 | +| array_flow.rb:872:18:872:36 | # $ hasValueFlow=87 | Missing result:hasValueFlow=87 | +| array_flow.rb:926:10:926:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | +| array_flow.rb:926:10:926:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | +| array_flow.rb:927:10:927:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | +| array_flow.rb:927:10:927:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | +| array_flow.rb:928:10:928:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | +| array_flow.rb:929:10:929:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | +| array_flow.rb:929:10:929:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | +| array_flow.rb:930:10:930:13 | ...[...] | Unexpected result: hasValueFlow=90.1 | +| array_flow.rb:930:10:930:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | +| array_flow.rb:931:10:931:13 | ...[...] | Unexpected result: hasValueFlow=90.2 | +| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.1 | +| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.2 | +| array_flow.rb:939:18:939:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.3 | +| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.1 | +| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.2 | +| array_flow.rb:940:18:940:78 | # $ hasValueFlow=91.1 $ hasValueFlow=91.2 $ hasValueFlow=91.3 | Missing result:hasValueFlow=91.3 | +| array_flow.rb:957:28:957:46 | # $ hasValueFlow=93 | Missing result:hasValueFlow=93 | +| array_flow.rb:958:28:958:46 | # $ hasValueFlow=93 | Missing result:hasValueFlow=93 | +| array_flow.rb:1018:16:1018:36 | # $ hasValueFlow=99.2 | Missing result:hasValueFlow=99.2 | +| array_flow.rb:1097:10:1097:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | | array_flow.rb:1097:10:1097:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | -| array_flow.rb:1098:10:1098:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | +| array_flow.rb:1098:10:1098:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | | array_flow.rb:1099:10:1099:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | -| array_flow.rb:1099:10:1099:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | | array_flow.rb:1100:10:1100:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | | array_flow.rb:1100:10:1100:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | +| array_flow.rb:1101:10:1101:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | | array_flow.rb:1101:10:1101:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | -| array_flow.rb:1102:10:1102:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | +| array_flow.rb:1102:10:1102:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | | array_flow.rb:1103:10:1103:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | -| array_flow.rb:1103:10:1103:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | | array_flow.rb:1104:10:1104:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | | array_flow.rb:1104:10:1104:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | -| array_flow.rb:1150:10:1150:10 | b | Unexpected result: hasValueFlow=108.2 | -| array_flow.rb:1151:10:1151:13 | ...[...] | Unexpected result: hasValueFlow=108.1 | -| array_flow.rb:1151:10:1151:13 | ...[...] | Unexpected result: hasValueFlow=108.2 | -| array_flow.rb:1153:10:1153:13 | ...[...] | Unexpected result: hasValueFlow=108.2 | -| array_flow.rb:1157:10:1157:13 | ...[...] | Unexpected result: hasValueFlow=108.2 | -| array_flow.rb:1159:10:1159:13 | ...[...] | Unexpected result: hasValueFlow=108.1 | -| array_flow.rb:1161:10:1161:13 | ...[...] | Unexpected result: hasValueFlow=108.2 | -| array_flow.rb:1212:10:1212:13 | ...[...] | Unexpected result: hasValueFlow=111.1 | -| array_flow.rb:1221:10:1221:13 | ...[...] | Unexpected result: hasValueFlow=111.1 | -| array_flow.rb:1226:10:1226:13 | ...[...] | Unexpected result: hasValueFlow=111.1 | -| array_flow.rb:1250:10:1250:10 | b | Unexpected result: hasValueFlow=112.2 | -| array_flow.rb:1253:10:1253:13 | ...[...] | Unexpected result: hasValueFlow=112.1 | -| array_flow.rb:1253:10:1253:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | -| array_flow.rb:1274:10:1274:13 | ...[...] | Unexpected result: hasValueFlow=112.1 | -| array_flow.rb:1276:10:1276:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | -| array_flow.rb:1280:10:1280:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | +| array_flow.rb:1108:10:1108:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | +| array_flow.rb:1109:10:1109:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | +| array_flow.rb:1110:10:1110:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | +| array_flow.rb:1110:10:1110:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | +| array_flow.rb:1111:10:1111:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | +| array_flow.rb:1111:10:1111:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | +| array_flow.rb:1112:10:1112:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | +| array_flow.rb:1113:10:1113:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | +| array_flow.rb:1114:10:1114:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | +| array_flow.rb:1114:10:1114:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | +| array_flow.rb:1115:10:1115:13 | ...[...] | Unexpected result: hasValueFlow=105.2 | +| array_flow.rb:1115:10:1115:13 | ...[...] | Unexpected result: hasValueFlow=105.3 | +| array_flow.rb:1161:10:1161:10 | b | Unexpected result: hasValueFlow=108.2 | +| array_flow.rb:1162:10:1162:13 | ...[...] | Unexpected result: hasValueFlow=108.1 | +| array_flow.rb:1162:10:1162:13 | ...[...] | Unexpected result: hasValueFlow=108.2 | +| array_flow.rb:1164:10:1164:13 | ...[...] | Unexpected result: hasValueFlow=108.2 | +| array_flow.rb:1168:10:1168:13 | ...[...] | Unexpected result: hasValueFlow=108.2 | +| array_flow.rb:1170:10:1170:13 | ...[...] | Unexpected result: hasValueFlow=108.1 | +| array_flow.rb:1172:10:1172:13 | ...[...] | Unexpected result: hasValueFlow=108.2 | +| array_flow.rb:1223:10:1223:13 | ...[...] | Unexpected result: hasValueFlow=111.1 | +| array_flow.rb:1232:10:1232:13 | ...[...] | Unexpected result: hasValueFlow=111.1 | +| array_flow.rb:1237:10:1237:13 | ...[...] | Unexpected result: hasValueFlow=111.1 | +| array_flow.rb:1261:10:1261:10 | b | Unexpected result: hasValueFlow=112.2 | +| array_flow.rb:1264:10:1264:13 | ...[...] | Unexpected result: hasValueFlow=112.1 | +| array_flow.rb:1264:10:1264:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | | array_flow.rb:1285:10:1285:13 | ...[...] | Unexpected result: hasValueFlow=112.1 | | array_flow.rb:1287:10:1287:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | | array_flow.rb:1291:10:1291:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | | array_flow.rb:1296:10:1296:13 | ...[...] | Unexpected result: hasValueFlow=112.1 | | array_flow.rb:1298:10:1298:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | -| array_flow.rb:1330:10:1330:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | -| array_flow.rb:1334:10:1334:13 | ...[...] | Unexpected result: hasValueFlow=112.1 | -| array_flow.rb:1437:10:1437:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1438:10:1438:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1439:10:1439:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1440:10:1440:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1442:10:1442:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1443:10:1443:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1444:10:1444:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1445:10:1445:13 | ...[...] | Unexpected result: hasValueFlow=121.2 | -| array_flow.rb:1445:10:1445:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1446:10:1446:13 | ...[...] | Unexpected result: hasValueFlow=121.2 | -| array_flow.rb:1446:10:1446:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1302:10:1302:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | +| array_flow.rb:1307:10:1307:13 | ...[...] | Unexpected result: hasValueFlow=112.1 | +| array_flow.rb:1309:10:1309:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | +| array_flow.rb:1341:10:1341:13 | ...[...] | Unexpected result: hasValueFlow=112.2 | +| array_flow.rb:1345:10:1345:13 | ...[...] | Unexpected result: hasValueFlow=112.1 | | array_flow.rb:1448:10:1448:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | | array_flow.rb:1449:10:1449:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | | array_flow.rb:1450:10:1450:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | | array_flow.rb:1451:10:1451:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1452:10:1452:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | -| array_flow.rb:1500:18:1500:39 | # $ hasValueFlow=128.1 | Missing result:hasValueFlow=128.1 | -| array_flow.rb:1501:18:1501:39 | # $ hasValueFlow=128.2 | Missing result:hasValueFlow=128.2 | -| array_flow.rb:1502:18:1502:39 | # $ hasValueFlow=128.3 | Missing result:hasValueFlow=128.3 | -| array_flow.rb:1551:10:1551:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | -| array_flow.rb:1551:10:1551:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | -| array_flow.rb:1552:10:1552:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | -| array_flow.rb:1552:10:1552:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | -| array_flow.rb:1553:10:1553:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | -| array_flow.rb:1554:10:1554:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | -| array_flow.rb:1554:10:1554:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | -| array_flow.rb:1555:10:1555:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | -| array_flow.rb:1555:10:1555:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | -| array_flow.rb:1556:10:1556:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | -| array_flow.rb:1589:18:1589:39 | # $ hasValueFlow=134.3 | Missing result:hasValueFlow=134.3 | -| array_flow.rb:1590:18:1590:39 | # $ hasValueFlow=134.2 | Missing result:hasValueFlow=134.2 | -| array_flow.rb:1591:18:1591:39 | # $ hasValueFlow=134.1 | Missing result:hasValueFlow=134.1 | -| array_flow.rb:1611:19:1611:40 | # $ hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 | -| array_flow.rb:1614:19:1614:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 | -| array_flow.rb:1614:19:1614:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.2 | -| array_flow.rb:1615:19:1615:40 | # $ hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 | +| array_flow.rb:1453:10:1453:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1454:10:1454:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1455:10:1455:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1456:10:1456:13 | ...[...] | Unexpected result: hasValueFlow=121.2 | +| array_flow.rb:1456:10:1456:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1457:10:1457:13 | ...[...] | Unexpected result: hasValueFlow=121.2 | +| array_flow.rb:1457:10:1457:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1459:10:1459:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1460:10:1460:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1461:10:1461:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1462:10:1462:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1463:10:1463:13 | ...[...] | Unexpected result: hasValueFlow=121.3 | +| array_flow.rb:1511:18:1511:39 | # $ hasValueFlow=128.1 | Missing result:hasValueFlow=128.1 | +| array_flow.rb:1512:18:1512:39 | # $ hasValueFlow=128.2 | Missing result:hasValueFlow=128.2 | +| array_flow.rb:1513:18:1513:39 | # $ hasValueFlow=128.3 | Missing result:hasValueFlow=128.3 | +| array_flow.rb:1562:10:1562:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | +| array_flow.rb:1562:10:1562:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | +| array_flow.rb:1563:10:1563:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | +| array_flow.rb:1563:10:1563:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | +| array_flow.rb:1564:10:1564:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | +| array_flow.rb:1565:10:1565:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | +| array_flow.rb:1565:10:1565:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | +| array_flow.rb:1566:10:1566:13 | ...[...] | Unexpected result: hasValueFlow=132.1 | +| array_flow.rb:1566:10:1566:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | +| array_flow.rb:1567:10:1567:13 | ...[...] | Unexpected result: hasValueFlow=132.2 | +| array_flow.rb:1600:18:1600:39 | # $ hasValueFlow=134.3 | Missing result:hasValueFlow=134.3 | +| array_flow.rb:1601:18:1601:39 | # $ hasValueFlow=134.2 | Missing result:hasValueFlow=134.2 | +| array_flow.rb:1602:18:1602:39 | # $ hasValueFlow=134.1 | Missing result:hasValueFlow=134.1 | +| array_flow.rb:1622:19:1622:40 | # $ hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 | +| array_flow.rb:1625:19:1625:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 | +| array_flow.rb:1625:19:1625:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.2 | +| array_flow.rb:1626:19:1626:40 | # $ hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 | From b38bc52019ec2b7b4f442e768785afc9693a7998 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer <kaeluka@github.com> Date: Fri, 9 Jun 2023 14:57:56 +0200 Subject: [PATCH 472/739] Java: fix bug in ExcludedFromModeling Characteristic --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 8556d659611..86aff731ba2 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -294,8 +294,7 @@ private class ExcludedFromModeling extends CharacteristicsImpl::UninterestingToM ExcludedFromModeling() { this = "excluded from modeling" } override predicate appliesToEndpoint(Endpoint e) { - ModelExclusions::isUninterestingForModels(ApplicationModeGetCallable::getCallable(e)) or - ModelExclusions::isUninterestingForModels(e.getEnclosingCallable()) + ModelExclusions::isUninterestingForModels(ApplicationModeGetCallable::getCallable(e)) } } From 6dfeb2536bd274a3068e17c63d50f872150dd56e Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 1 Jun 2023 09:44:30 +0200 Subject: [PATCH 473/739] delete old deprecations --- python/ql/lib/semmle/python/Files.qll | 6 - .../python/dataflow/old/TaintTracking.qll | 8 - .../lib/semmle/python/frameworks/Django.qll | 33 ----- .../lib/semmle/python/frameworks/FastApi.qll | 3 - .../python/frameworks/RestFramework.qll | 3 - .../semmle/python/frameworks/SqlAlchemy.qll | 3 - .../lib/semmle/python/frameworks/Stdlib.qll | 39 ----- .../lib/semmle/python/frameworks/Tornado.qll | 3 - .../lib/semmle/python/pointsto/PointsTo.qll | 48 ------ .../lib/semmle/python/security/ClearText.qll | 54 ------- .../ql/lib/semmle/python/security/Crypto.qll | 139 ------------------ .../semmle/python/security/SensitiveData.qll | 118 --------------- .../security/dataflow/ChainedConfigs12.qll | 95 ------------ .../security/dataflow/CleartextLogging.qll | 14 -- .../security/dataflow/CleartextStorage.qll | 14 -- .../security/dataflow/CodeInjection.qll | 13 -- .../security/dataflow/CommandInjection.qll | 13 -- .../security/dataflow/LdapInjection.qll | 12 -- .../python/security/dataflow/LogInjection.qll | 10 -- .../security/dataflow/PathInjection.qll | 133 ----------------- .../security/dataflow/PolynomialReDoS.qll | 10 -- .../python/security/dataflow/ReflectedXSS.qll | 16 -- .../dataflow/ReflectedXSSCustomizations.qll | 3 - .../security/dataflow/RegexInjection.qll | 10 -- .../dataflow/ServerSideRequestForgery.qll | 25 ---- .../python/security/dataflow/SqlInjection.qll | 16 -- .../security/dataflow/StackTraceExposure.qll | 13 -- .../dataflow/UnsafeDeserialization.qll | 13 -- .../python/security/dataflow/UrlRedirect.qll | 13 -- .../dataflow/WeakSensitiveDataHashing.qll | 19 --- .../security/dataflow/XpathInjection.qll | 10 -- .../semmle/python/security/flow/AnyCall.qll | 9 -- .../security/injection/Deserialization.qll | 8 - .../semmle/python/security/injection/Exec.qll | 29 ---- .../python/security/injection/Marshal.qll | 33 ----- .../semmle/python/security/injection/Path.qll | 81 ---------- .../python/security/injection/Pickle.qll | 36 ----- .../security/injection/RegexInjection.qll | 6 - .../RegexInjectionCustomizations.qll | 6 - .../semmle/python/security/injection/Xml.qll | 70 --------- .../semmle/python/security/injection/Yaml.qll | 28 ---- .../ql/lib/semmle/python/types/Extensions.qll | 25 ---- .../CWE-020-ExternalAPIs/ExternalAPIs.qll | 15 -- .../experimental/semmle/python/Concepts.qll | 48 ------ .../python/security/LDAPInsecureAuth.qll | 24 --- .../security/injection/NoSQLInjection.qll | 3 - .../security/sensitive/Sources.expected | 6 - .../security/sensitive/Sources.ql | 5 - .../library-tests/security/sensitive/test.py | 21 --- .../web/bottle/HttpResponseSinks.expected | 5 - .../web/bottle/HttpResponseSinks.ql | 7 - .../web/bottle/HttpSources.expected | 9 -- .../library-tests/web/bottle/HttpSources.ql | 7 - .../library-tests/web/bottle/Routing.expected | 8 - .../test/library-tests/web/bottle/Routing.ql | 5 - .../library-tests/web/bottle/Taint.expected | 23 --- .../ql/test/library-tests/web/bottle/Taint.ql | 7 - .../ql/test/library-tests/web/bottle/options | 1 - .../ql/test/library-tests/web/bottle/test.py | 36 ----- .../web/cherrypy/HttpResponseSinks.expected | 4 - .../web/cherrypy/HttpResponseSinks.ql | 7 - .../web/cherrypy/HttpSources.expected | 4 - .../library-tests/web/cherrypy/HttpSources.ql | 7 - .../test/library-tests/web/cherrypy/options | 1 - .../ql/test/library-tests/web/cherrypy/red.py | 11 -- .../test/library-tests/web/cherrypy/test.py | 23 --- .../requests/ClientHttpRequests.expected | 3 - .../web/client/requests/ClientHttpRequests.ql | 7 - .../library-tests/web/client/requests/options | 1 - .../library-tests/web/client/requests/test.py | 4 - .../client/six/ClientHttpRequests.expected | 11 -- .../web/client/six/ClientHttpRequests.ql | 7 - .../test/library-tests/web/client/six/options | 2 - .../test/library-tests/web/client/six/test.py | 37 ----- .../client/stdlib/ClientHttpRequests.expected | 11 -- .../web/client/stdlib/ClientHttpRequests.ql | 7 - .../library-tests/web/client/stdlib/options | 1 - .../library-tests/web/client/stdlib/test.py | 44 ------ .../web/django/HttpRedirectSinks.expected | 5 - .../web/django/HttpRedirectSinks.ql | 7 - .../web/django/HttpResponseSinks.expected | 32 ---- .../web/django/HttpResponseSinks.ql | 7 - .../web/django/HttpSources.expected | 53 ------- .../library-tests/web/django/HttpSources.ql | 7 - .../web/django/SqlInjectionSinks.expected | 9 -- .../web/django/SqlInjectionSinks.ql | 8 - .../ql/test/library-tests/web/django/options | 1 - .../ql/test/library-tests/web/django/sql.py | 53 ------- .../test/library-tests/web/django/test_1x.py | 19 --- .../library-tests/web/django/test_2x_3x.py | 19 --- .../test/library-tests/web/django/views_1x.py | 107 -------------- .../library-tests/web/django/views_2x_3x.py | 128 ---------------- .../web/falcon/HttpResponseSinks.expected | 1 - .../web/falcon/HttpResponseSinks.ql | 8 - .../web/falcon/HttpSources.expected | 4 - .../library-tests/web/falcon/HttpSources.ql | 7 - .../library-tests/web/falcon/Routing.expected | 4 - .../test/library-tests/web/falcon/Routing.ql | 5 - .../library-tests/web/falcon/Sinks.expected | 0 .../ql/test/library-tests/web/falcon/Sinks.ql | 8 - .../library-tests/web/falcon/Taint.expected | 20 --- .../ql/test/library-tests/web/falcon/Taint.ql | 8 - .../ql/test/library-tests/web/falcon/options | 1 - .../ql/test/library-tests/web/falcon/test.py | 28 ---- .../web/flask/HttpResponseSinks.expected | 17 --- .../web/flask/HttpResponseSinks.ql | 7 - .../web/flask/HttpSources.expected | 10 -- .../library-tests/web/flask/HttpSources.ql | 7 - .../library-tests/web/flask/Routing.expected | 11 -- .../test/library-tests/web/flask/Routing.ql | 6 - .../library-tests/web/flask/Taint.expected | 33 ----- .../ql/test/library-tests/web/flask/Taint.ql | 8 - .../ql/test/library-tests/web/flask/options | 1 - .../ql/test/library-tests/web/flask/test.py | 67 --------- .../web/pyramid/HttpResponseSinks.expected | 4 - .../web/pyramid/HttpResponseSinks.ql | 7 - .../web/pyramid/HttpSources.expected | 4 - .../library-tests/web/pyramid/HttpSources.ql | 7 - .../web/pyramid/Routing.expected | 4 - .../test/library-tests/web/pyramid/Routing.ql | 6 - .../library-tests/web/pyramid/Taint.expected | 11 -- .../test/library-tests/web/pyramid/Taint.ql | 8 - .../ql/test/library-tests/web/pyramid/options | 1 - .../ql/test/library-tests/web/pyramid/test.py | 25 ---- .../web/stdlib/HttpResponseSinks.expected | 3 - .../web/stdlib/HttpResponseSinks.ql | 7 - .../web/stdlib/HttpSources.expected | 35 ----- .../library-tests/web/stdlib/HttpSources.ql | 9 -- .../web/stdlib/TestTaint.expected | 32 ---- .../library-tests/web/stdlib/TestTaint.ql | 32 ---- .../ql/test/library-tests/web/stdlib/test.py | 108 -------------- .../web/tornado/Classes.expected | 5 - .../test/library-tests/web/tornado/Classes.ql | 7 - .../web/tornado/HttpRedirectSinks.expected | 2 - .../web/tornado/HttpRedirectSinks.ql | 7 - .../web/tornado/HttpResponseSinks.expected | 4 - .../web/tornado/HttpResponseSinks.ql | 7 - .../web/tornado/HttpSources.expected | 5 - .../library-tests/web/tornado/HttpSources.ql | 7 - .../library-tests/web/tornado/Taint.expected | 12 -- .../test/library-tests/web/tornado/Taint.ql | 10 -- .../ql/test/library-tests/web/tornado/options | 1 - .../ql/test/library-tests/web/tornado/test.py | 26 ---- .../web/turbogears/Controller.expected | 6 - .../web/turbogears/Controller.ql | 5 - .../web/turbogears/HttpResponseSinks.expected | 6 - .../web/turbogears/HttpResponseSinks.ql | 7 - .../web/turbogears/HttpSources.expected | 4 - .../web/turbogears/HttpSources.ql | 7 - .../web/turbogears/Taint.expected | 12 -- .../library-tests/web/turbogears/Taint.ql | 7 - .../test/library-tests/web/turbogears/options | 1 - .../test/library-tests/web/turbogears/test.py | 27 ---- .../web/twisted/Classes.expected | 6 - .../test/library-tests/web/twisted/Classes.ql | 7 - .../web/twisted/HttpResponseSinks.expected | 11 -- .../web/twisted/HttpResponseSinks.ql | 7 - .../web/twisted/HttpSources.expected | 9 -- .../library-tests/web/twisted/HttpSources.ql | 7 - .../web/twisted/Methods.expected | 9 -- .../test/library-tests/web/twisted/Methods.ql | 7 - .../library-tests/web/twisted/Taint.expected | 41 ------ .../test/library-tests/web/twisted/Taint.ql | 8 - .../ql/test/library-tests/web/twisted/options | 1 - .../ql/test/library-tests/web/twisted/test.py | 51 ------- .../ql/lib/BytecodeExpr.qll | 33 ----- .../ql/lib/RecordedCalls.qll | 15 -- 167 files changed, 3068 deletions(-) delete mode 100644 python/ql/lib/semmle/python/security/ClearText.qll delete mode 100644 python/ql/lib/semmle/python/security/Crypto.qll delete mode 100644 python/ql/lib/semmle/python/security/SensitiveData.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/CleartextLogging.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/CleartextStorage.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/CodeInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/CommandInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/LdapInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/LogInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/PathInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/PolynomialReDoS.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/ReflectedXSS.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/RegexInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgery.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/SqlInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/StackTraceExposure.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/UnsafeDeserialization.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/UrlRedirect.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashing.qll delete mode 100644 python/ql/lib/semmle/python/security/dataflow/XpathInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/flow/AnyCall.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Deserialization.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Exec.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Marshal.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Path.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Pickle.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/RegexInjection.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/RegexInjectionCustomizations.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Xml.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Yaml.qll delete mode 100644 python/ql/test/library-tests/security/sensitive/Sources.expected delete mode 100644 python/ql/test/library-tests/security/sensitive/Sources.ql delete mode 100644 python/ql/test/library-tests/security/sensitive/test.py delete mode 100644 python/ql/test/library-tests/web/bottle/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/bottle/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/bottle/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/bottle/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/bottle/Routing.expected delete mode 100644 python/ql/test/library-tests/web/bottle/Routing.ql delete mode 100644 python/ql/test/library-tests/web/bottle/Taint.expected delete mode 100644 python/ql/test/library-tests/web/bottle/Taint.ql delete mode 100644 python/ql/test/library-tests/web/bottle/options delete mode 100644 python/ql/test/library-tests/web/bottle/test.py delete mode 100644 python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/cherrypy/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/cherrypy/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/cherrypy/options delete mode 100644 python/ql/test/library-tests/web/cherrypy/red.py delete mode 100644 python/ql/test/library-tests/web/cherrypy/test.py delete mode 100644 python/ql/test/library-tests/web/client/requests/ClientHttpRequests.expected delete mode 100644 python/ql/test/library-tests/web/client/requests/ClientHttpRequests.ql delete mode 100644 python/ql/test/library-tests/web/client/requests/options delete mode 100644 python/ql/test/library-tests/web/client/requests/test.py delete mode 100644 python/ql/test/library-tests/web/client/six/ClientHttpRequests.expected delete mode 100644 python/ql/test/library-tests/web/client/six/ClientHttpRequests.ql delete mode 100644 python/ql/test/library-tests/web/client/six/options delete mode 100644 python/ql/test/library-tests/web/client/six/test.py delete mode 100644 python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.expected delete mode 100644 python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.ql delete mode 100644 python/ql/test/library-tests/web/client/stdlib/options delete mode 100644 python/ql/test/library-tests/web/client/stdlib/test.py delete mode 100644 python/ql/test/library-tests/web/django/HttpRedirectSinks.expected delete mode 100644 python/ql/test/library-tests/web/django/HttpRedirectSinks.ql delete mode 100644 python/ql/test/library-tests/web/django/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/django/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/django/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/django/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/django/SqlInjectionSinks.expected delete mode 100644 python/ql/test/library-tests/web/django/SqlInjectionSinks.ql delete mode 100644 python/ql/test/library-tests/web/django/options delete mode 100644 python/ql/test/library-tests/web/django/sql.py delete mode 100644 python/ql/test/library-tests/web/django/test_1x.py delete mode 100644 python/ql/test/library-tests/web/django/test_2x_3x.py delete mode 100644 python/ql/test/library-tests/web/django/views_1x.py delete mode 100644 python/ql/test/library-tests/web/django/views_2x_3x.py delete mode 100644 python/ql/test/library-tests/web/falcon/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/falcon/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/falcon/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/falcon/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/falcon/Routing.expected delete mode 100644 python/ql/test/library-tests/web/falcon/Routing.ql delete mode 100644 python/ql/test/library-tests/web/falcon/Sinks.expected delete mode 100644 python/ql/test/library-tests/web/falcon/Sinks.ql delete mode 100644 python/ql/test/library-tests/web/falcon/Taint.expected delete mode 100644 python/ql/test/library-tests/web/falcon/Taint.ql delete mode 100644 python/ql/test/library-tests/web/falcon/options delete mode 100644 python/ql/test/library-tests/web/falcon/test.py delete mode 100644 python/ql/test/library-tests/web/flask/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/flask/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/flask/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/flask/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/flask/Routing.expected delete mode 100644 python/ql/test/library-tests/web/flask/Routing.ql delete mode 100644 python/ql/test/library-tests/web/flask/Taint.expected delete mode 100644 python/ql/test/library-tests/web/flask/Taint.ql delete mode 100644 python/ql/test/library-tests/web/flask/options delete mode 100644 python/ql/test/library-tests/web/flask/test.py delete mode 100644 python/ql/test/library-tests/web/pyramid/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/pyramid/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/pyramid/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/pyramid/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/pyramid/Routing.expected delete mode 100644 python/ql/test/library-tests/web/pyramid/Routing.ql delete mode 100644 python/ql/test/library-tests/web/pyramid/Taint.expected delete mode 100644 python/ql/test/library-tests/web/pyramid/Taint.ql delete mode 100644 python/ql/test/library-tests/web/pyramid/options delete mode 100644 python/ql/test/library-tests/web/pyramid/test.py delete mode 100644 python/ql/test/library-tests/web/stdlib/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/stdlib/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/stdlib/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/stdlib/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/stdlib/TestTaint.expected delete mode 100644 python/ql/test/library-tests/web/stdlib/TestTaint.ql delete mode 100644 python/ql/test/library-tests/web/stdlib/test.py delete mode 100644 python/ql/test/library-tests/web/tornado/Classes.expected delete mode 100644 python/ql/test/library-tests/web/tornado/Classes.ql delete mode 100644 python/ql/test/library-tests/web/tornado/HttpRedirectSinks.expected delete mode 100644 python/ql/test/library-tests/web/tornado/HttpRedirectSinks.ql delete mode 100644 python/ql/test/library-tests/web/tornado/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/tornado/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/tornado/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/tornado/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/tornado/Taint.expected delete mode 100644 python/ql/test/library-tests/web/tornado/Taint.ql delete mode 100644 python/ql/test/library-tests/web/tornado/options delete mode 100644 python/ql/test/library-tests/web/tornado/test.py delete mode 100644 python/ql/test/library-tests/web/turbogears/Controller.expected delete mode 100644 python/ql/test/library-tests/web/turbogears/Controller.ql delete mode 100644 python/ql/test/library-tests/web/turbogears/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/turbogears/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/turbogears/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/turbogears/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/turbogears/Taint.expected delete mode 100644 python/ql/test/library-tests/web/turbogears/Taint.ql delete mode 100644 python/ql/test/library-tests/web/turbogears/options delete mode 100644 python/ql/test/library-tests/web/turbogears/test.py delete mode 100644 python/ql/test/library-tests/web/twisted/Classes.expected delete mode 100644 python/ql/test/library-tests/web/twisted/Classes.ql delete mode 100644 python/ql/test/library-tests/web/twisted/HttpResponseSinks.expected delete mode 100644 python/ql/test/library-tests/web/twisted/HttpResponseSinks.ql delete mode 100644 python/ql/test/library-tests/web/twisted/HttpSources.expected delete mode 100644 python/ql/test/library-tests/web/twisted/HttpSources.ql delete mode 100644 python/ql/test/library-tests/web/twisted/Methods.expected delete mode 100644 python/ql/test/library-tests/web/twisted/Methods.ql delete mode 100644 python/ql/test/library-tests/web/twisted/Taint.expected delete mode 100644 python/ql/test/library-tests/web/twisted/Taint.ql delete mode 100644 python/ql/test/library-tests/web/twisted/options delete mode 100644 python/ql/test/library-tests/web/twisted/test.py diff --git a/python/ql/lib/semmle/python/Files.qll b/python/ql/lib/semmle/python/Files.qll index 4d331a26308..059a0d72b28 100644 --- a/python/ql/lib/semmle/python/Files.qll +++ b/python/ql/lib/semmle/python/Files.qll @@ -154,12 +154,6 @@ abstract class Container extends @container { */ string toString() { result = this.getAbsolutePath() } - /** - * Gets the name of this container. - * DEPRECATED: Use `getAbsolutePath` instead. - */ - deprecated string getName() { result = this.getAbsolutePath() } - /** * Gets the relative path of this file or folder from the root folder of the * analyzed source location. The relative path of the root folder itself is diff --git a/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll index d0293522404..0ce4bc27790 100644 --- a/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll +++ b/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll @@ -664,14 +664,6 @@ module DataFlow { } } -deprecated private class DataFlowType extends TaintKind { - // this only exists to avoid an empty recursion error in the type checker - DataFlowType() { - this = "Data flow" and - 1 = 2 - } -} - pragma[noinline] private predicate dict_construct(ControlFlowNode itemnode, ControlFlowNode dictnode) { dictnode.(DictNode).getAValue() = itemnode diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll index 2240894a3f4..7fcc64f181e 100644 --- a/python/ql/lib/semmle/python/frameworks/Django.qll +++ b/python/ql/lib/semmle/python/frameworks/Django.qll @@ -534,9 +534,6 @@ module PrivateDjango { /** Gets a reference to the `django` module. */ API::Node django() { result = API::moduleImport("django") } - /** DEPRECATED: Alias for `DjangoImpl` */ - deprecated module django = DjangoImpl; - /** Provides models for the `django` module. */ module DjangoImpl { // ------------------------------------------------------------------------- @@ -552,9 +549,6 @@ module PrivateDjango { DjangoDb() { this = API::moduleImport("django").getMember("db") } } - /** DEPRECATED: Alias for `DB` */ - deprecated module db = DB; - /** Provides models for the `django.db` module. */ module DB { /** Gets a reference to the `django.db.connection` object. */ @@ -571,9 +565,6 @@ module PrivateDjango { /** Gets a reference to the `django.db.models` module. */ API::Node models() { result = db().getMember("models") } - /** DEPRECATED: Alias for `Models` */ - deprecated module models = Models; - /** Provides models for the `django.db.models` module. */ module Models { /** @@ -819,9 +810,6 @@ module PrivateDjango { /** Gets a reference to the `django.db.models.expressions` module. */ API::Node expressions() { result = models().getMember("expressions") } - /** DEPRECATED: Alias for `Expressions` */ - deprecated module expressions = Expressions; - /** Provides models for the `django.db.models.expressions` module. */ module Expressions { /** Provides models for the `django.db.models.expressions.RawSql` class. */ @@ -858,9 +846,6 @@ module PrivateDjango { instance(DataFlow::TypeTracker::end(), sql).flowsTo(result) } } - - /** DEPRECATED: Alias for RawSql */ - deprecated module RawSQL = RawSql; } /** This internal module provides data-flow modeling of Django ORM. */ @@ -1099,9 +1084,6 @@ module PrivateDjango { /** Gets a reference to the `django.urls` module. */ API::Node urls() { result = django().getMember("urls") } - /** DEPRECATED: Alias for `Urls` */ - deprecated module urls = Urls; - /** Provides models for the `django.urls` module */ module Urls { /** @@ -1123,14 +1105,8 @@ module PrivateDjango { /** Gets a reference to the `django.conf` module. */ API::Node conf() { result = django().getMember("conf") } - /** DEPRECATED: Alias for `Conf` */ - deprecated module conf = Conf; - /** Provides models for the `django.conf` module */ module Conf { - /** DEPRECATED: Alias for `ConfUrls` */ - deprecated module conf_urls = ConfUrls; - /** Provides models for the `django.conf.urls` module */ module ConfUrls { // ------------------------------------------------------------------------- @@ -1166,9 +1142,6 @@ module PrivateDjango { /** Gets a reference to the `django.http.request` module. */ API::Node request() { result = http().getMember("request") } - /** DEPRECATED: Alias for `Request` */ - deprecated module request = Request; - /** Provides models for the `django.http.request` module. */ module Request { /** @@ -1331,9 +1304,6 @@ module PrivateDjango { /** Gets a reference to the `django.http.response` module. */ API::Node response() { result = http().getMember("response") } - /** DEPRECATED: Alias for `Response` */ - deprecated module response = Response; - /** Provides models for the `django.http.response` module */ module Response { /** @@ -2189,9 +2159,6 @@ module PrivateDjango { /** Gets a reference to the `django.shortcuts` module. */ API::Node shortcuts() { result = django().getMember("shortcuts") } - /** DEPRECATED: Alias for `Shortcuts` */ - deprecated module shortcuts = Shortcuts; - /** Provides models for the `django.shortcuts` module */ module Shortcuts { /** diff --git a/python/ql/lib/semmle/python/frameworks/FastApi.qll b/python/ql/lib/semmle/python/frameworks/FastApi.qll index d6f5bba6d9f..07dbd982653 100644 --- a/python/ql/lib/semmle/python/frameworks/FastApi.qll +++ b/python/ql/lib/semmle/python/frameworks/FastApi.qll @@ -37,9 +37,6 @@ private module FastApi { } } - /** DEPRECATED: Alias for ApiRouter */ - deprecated module APIRouter = ApiRouter; - // --------------------------------------------------------------------------- // routing modeling // --------------------------------------------------------------------------- diff --git a/python/ql/lib/semmle/python/frameworks/RestFramework.qll b/python/ql/lib/semmle/python/frameworks/RestFramework.qll index dcbd247a1c5..23b32946e31 100644 --- a/python/ql/lib/semmle/python/frameworks/RestFramework.qll +++ b/python/ql/lib/semmle/python/frameworks/RestFramework.qll @@ -359,7 +359,4 @@ private module RestFramework { override string getMimetypeDefault() { none() } } } - - /** DEPRECATED: Alias for ApiException */ - deprecated module APIException = ApiException; } diff --git a/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll b/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll index c1712e7e7eb..0bb0125cf5c 100644 --- a/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll +++ b/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll @@ -169,9 +169,6 @@ module SqlAlchemy { DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } } - /** DEPRECATED: Alias for DBApiConnection */ - deprecated module DBAPIConnection = DBApiConnection; - /** * Provides models for the `sqlalchemy.orm.Session` class * diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index cd5ec31945e..8af918f4bb4 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -130,9 +130,6 @@ module Stdlib { } } - /** DEPRECATED: Alias for HttpMessage */ - deprecated module HTTPMessage = HttpMessage; - /** * Provides models for the `http.cookies.Morsel` class * @@ -1821,9 +1818,6 @@ private module StdlibPrivate { /** Gets a reference to the `BaseHttpServer` module. */ API::Node baseHttpServer() { result = API::moduleImport("BaseHTTPServer") } - /** DEPRECATED: Alias for baseHttpServer */ - deprecated API::Node baseHTTPServer() { result = baseHttpServer() } - /** Provides models for the `BaseHttpServer` module. */ module BaseHttpServer { /** @@ -1833,23 +1827,14 @@ private module StdlibPrivate { /** Gets a reference to the `BaseHttpServer.BaseHttpRequestHandler` class. */ API::Node classRef() { result = baseHttpServer().getMember("BaseHTTPRequestHandler") } } - - /** DEPRECATED: Alias for BaseHttpRequestHandler */ - deprecated module BaseHTTPRequestHandler = BaseHttpRequestHandler; } - /** DEPRECATED: Alias for BaseHttpServer */ - deprecated module BaseHTTPServer = BaseHttpServer; - // --------------------------------------------------------------------------- // SimpleHTTPServer (Python 2 only) // --------------------------------------------------------------------------- /** Gets a reference to the `SimpleHttpServer` module. */ API::Node simpleHttpServer() { result = API::moduleImport("SimpleHTTPServer") } - /** DEPRECATED: Alias for simpleHttpServer */ - deprecated API::Node simpleHTTPServer() { result = simpleHttpServer() } - /** Provides models for the `SimpleHttpServer` module. */ module SimpleHttpServer { /** @@ -1859,23 +1844,14 @@ private module StdlibPrivate { /** Gets a reference to the `SimpleHttpServer.SimpleHttpRequestHandler` class. */ API::Node classRef() { result = simpleHttpServer().getMember("SimpleHTTPRequestHandler") } } - - /** DEPRECATED: Alias for SimpleHttpRequestHandler */ - deprecated module SimpleHTTPRequestHandler = SimpleHttpRequestHandler; } - /** DEPRECATED: Alias for SimpleHttpServer */ - deprecated module SimpleHTTPServer = SimpleHttpServer; - // --------------------------------------------------------------------------- // CGIHTTPServer (Python 2 only) // --------------------------------------------------------------------------- /** Gets a reference to the `CGIHTTPServer` module. */ API::Node cgiHttpServer() { result = API::moduleImport("CGIHTTPServer") } - /** DEPRECATED: Alias for cgiHttpServer */ - deprecated API::Node cgiHTTPServer() { result = cgiHttpServer() } - /** Provides models for the `CGIHTTPServer` module. */ module CgiHttpServer { /** @@ -1919,9 +1895,6 @@ private module StdlibPrivate { API::Node classRef() { result = server().getMember("BaseHTTPRequestHandler") } } - /** DEPRECATED: Alias for BaseHttpRequestHandler */ - deprecated module BaseHTTPRequestHandler = BaseHttpRequestHandler; - /** * Provides models for the `http.server.SimpleHTTPRequestHandler` class (Python 3 only). * @@ -1932,9 +1905,6 @@ private module StdlibPrivate { API::Node classRef() { result = server().getMember("SimpleHTTPRequestHandler") } } - /** DEPRECATED: Alias for SimpleHttpRequestHandler */ - deprecated module SimpleHTTPRequestHandler = SimpleHttpRequestHandler; - /** * Provides models for the `http.server.CGIHTTPRequestHandler` class (Python 3 only). * @@ -1978,9 +1948,6 @@ private module StdlibPrivate { HttpRequestHandlerClassDef() { this.getParent() = subclassRef().asSource().asExpr() } } - /** DEPRECATED: Alias for HttpRequestHandlerClassDef */ - deprecated class HTTPRequestHandlerClassDef = HttpRequestHandlerClassDef; - /** * A source of instances of the `BaseHTTPRequestHandler` class or any subclass, extend this class to model new instances. * @@ -2352,9 +2319,6 @@ private module StdlibPrivate { } } - /** DEPRECATED: Alias for HttpConnection */ - deprecated module HTTPConnection = HttpConnection; - /** * Provides models for the `http.client.HTTPResponse` class * @@ -2424,9 +2388,6 @@ private module StdlibPrivate { } } - /** DEPRECATED: Alias for HttpResponse */ - deprecated module HTTPResponse = HttpResponse; - // --------------------------------------------------------------------------- // sqlite3 // --------------------------------------------------------------------------- diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll index 12a69908f80..73c016ed927 100644 --- a/python/ql/lib/semmle/python/frameworks/Tornado.qll +++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll @@ -64,9 +64,6 @@ module Tornado { } } - /** DEPRECATED: Alias for HttpHeaders */ - deprecated module HTTPHeaders = HttpHeaders; - // --------------------------------------------------------------------------- // tornado // --------------------------------------------------------------------------- diff --git a/python/ql/lib/semmle/python/pointsto/PointsTo.qll b/python/ql/lib/semmle/python/pointsto/PointsTo.qll index 1369d6d6ce7..fb05e9b49ff 100644 --- a/python/ql/lib/semmle/python/pointsto/PointsTo.qll +++ b/python/ql/lib/semmle/python/pointsto/PointsTo.qll @@ -1445,14 +1445,6 @@ module Expressions { ) } - deprecated predicate subscriptPointsTo( - SubscriptNode subscr, PointsToContext context, ObjectInternal value, ControlFlowNode origin, - ControlFlowNode obj, ObjectInternal objvalue - ) { - subscriptPointsTo(subscr, context, value, obj, objvalue) and - origin = subscr - } - pragma[noinline] private predicate subscriptPointsTo( SubscriptNode subscr, PointsToContext context, ObjectInternal value, ControlFlowNode obj, @@ -1489,14 +1481,6 @@ module Expressions { index = subscr.getIndex() } - deprecated predicate binaryPointsTo( - BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode origin, - ControlFlowNode operand, ObjectInternal opvalue - ) { - binaryPointsTo(b, context, value, operand, opvalue) and - origin = b - } - /** * Tracking too many binary expressions is likely to kill performance, so just say anything other than addition or bitwise or is 'unknown'. */ @@ -1521,14 +1505,6 @@ module Expressions { ) } - deprecated predicate addPointsTo( - BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode origin, - ControlFlowNode operand, ObjectInternal opvalue - ) { - addPointsTo(b, context, value, operand, opvalue) and - origin = b - } - pragma[noinline] private predicate addPointsTo( BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode operand, @@ -1545,14 +1521,6 @@ module Expressions { ) } - deprecated predicate bitOrPointsTo( - BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode origin, - ControlFlowNode operand, ObjectInternal opvalue - ) { - bitOrPointsTo(b, context, value, operand, opvalue) and - origin = b - } - pragma[noinline] private predicate bitOrPointsTo( BinaryExprNode b, PointsToContext context, ObjectInternal value, ControlFlowNode operand, @@ -1577,14 +1545,6 @@ module Expressions { value = obj.intValue() } - deprecated predicate unaryPointsTo( - UnaryExprNode u, PointsToContext context, ObjectInternal value, ControlFlowNode origin, - ControlFlowNode operand, ObjectInternal opvalue - ) { - unaryPointsTo(u, context, value, operand, opvalue) and - origin = u - } - pragma[noinline] private predicate unaryPointsTo( UnaryExprNode u, PointsToContext context, ObjectInternal value, ControlFlowNode operand, @@ -1603,14 +1563,6 @@ module Expressions { ) } - deprecated predicate builtinCallPointsTo( - CallNode call, PointsToContext context, ObjectInternal value, ControlFlowNode origin, - ControlFlowNode arg, ObjectInternal argvalue - ) { - builtinCallPointsTo(call, context, value, arg, argvalue) and - origin = call - } - pragma[noinline] private predicate builtinCallPointsTo( CallNode call, PointsToContext context, ObjectInternal value, ControlFlowNode arg, diff --git a/python/ql/lib/semmle/python/security/ClearText.qll b/python/ql/lib/semmle/python/security/ClearText.qll deleted file mode 100644 index c466be17ae6..00000000000 --- a/python/ql/lib/semmle/python/security/ClearText.qll +++ /dev/null @@ -1,54 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.SensitiveData -import semmle.python.dataflow.Files -import semmle.python.web.Http - -deprecated module ClearTextStorage { - abstract class Sink extends TaintSink { - override predicate sinks(TaintKind kind) { kind instanceof SensitiveData } - } - - class CookieStorageSink extends Sink { - CookieStorageSink() { any(CookieSet cookie).getValue() = this } - } - - class FileStorageSink extends Sink { - FileStorageSink() { - exists(CallNode call, AttrNode meth, string name | - any(OpenFile fd).taints(meth.getObject(name)) and - call.getFunction() = meth and - call.getAnArg() = this - | - name = "write" - ) - } - } -} - -deprecated module ClearTextLogging { - abstract class Sink extends TaintSink { - override predicate sinks(TaintKind kind) { kind instanceof SensitiveData } - } - - class PrintSink extends Sink { - PrintSink() { - exists(CallNode call | - call.getAnArg() = this and - call = Value::named("print").getACall() - ) - } - } - - class LoggingSink extends Sink { - LoggingSink() { - exists(CallNode call, AttrNode meth, string name | - call.getFunction() = meth and - meth.getObject(name).(NameNode).getId().matches("logg%") and - call.getAnArg() = this - | - name = ["error", "warn", "warning", "debug", "info"] - ) - } - } -} diff --git a/python/ql/lib/semmle/python/security/Crypto.qll b/python/ql/lib/semmle/python/security/Crypto.qll deleted file mode 100644 index dbf53f8a0fa..00000000000 --- a/python/ql/lib/semmle/python/security/Crypto.qll +++ /dev/null @@ -1,139 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -private import semmle.python.security.SensitiveData -private import semmle.crypto.Crypto as CryptoLib - -abstract deprecated class WeakCryptoSink extends TaintSink { - override predicate sinks(TaintKind taint) { taint instanceof SensitiveData } -} - -/** Modeling the 'pycrypto' package https://github.com/dlitz/pycrypto (latest release 2013) */ -deprecated module Pycrypto { - ModuleValue cipher(string name) { result = Module::named("Crypto.Cipher").attr(name) } - - class CipherInstance extends TaintKind { - string name; - - CipherInstance() { - this = "Crypto.Cipher." + name and - exists(cipher(name)) - } - - string getName() { result = name } - - CryptoLib::CryptographicAlgorithm getAlgorithm() { result.getName() = name } - - predicate isWeak() { this.getAlgorithm().isWeak() } - } - - class CipherInstanceSource extends TaintSource { - CipherInstance instance; - - CipherInstanceSource() { - exists(AttrNode attr | - this.(CallNode).getFunction() = attr and - attr.getObject("new").pointsTo(cipher(instance.getName())) - ) - } - - override string toString() { result = "Source of " + instance } - - override predicate isSourceOf(TaintKind kind) { kind = instance } - } - - class PycryptoWeakCryptoSink extends WeakCryptoSink { - string name; - - PycryptoWeakCryptoSink() { - exists(CallNode call, AttrNode method, CipherInstance cipher | - call.getAnArg() = this and - call.getFunction() = method and - cipher.taints(method.getObject("encrypt")) and - cipher.isWeak() and - cipher.getName() = name - ) - } - - override string toString() { result = "Use of weak crypto algorithm " + name } - } -} - -deprecated module Cryptography { - ModuleValue ciphers() { - result = Module::named("cryptography.hazmat.primitives.ciphers") and - result.isPackage() - } - - class CipherClass extends ClassValue { - CipherClass() { ciphers().attr("Cipher") = this } - } - - class AlgorithmClass extends ClassValue { - AlgorithmClass() { ciphers().attr("algorithms").attr(_) = this } - - string getAlgorithmName() { result = this.declaredAttribute("name").(StringValue).getText() } - - predicate isWeak() { - exists(CryptoLib::CryptographicAlgorithm algo | - algo.getName() = this.getAlgorithmName() and - algo.isWeak() - ) - } - } - - class CipherInstance extends TaintKind { - AlgorithmClass cls; - - CipherInstance() { this = "cryptography.Cipher." + cls.getAlgorithmName() } - - AlgorithmClass getAlgorithm() { result = cls } - - predicate isWeak() { cls.isWeak() } - - override TaintKind getTaintOfMethodResult(string name) { - name = "encryptor" and - result.(Encryptor).getAlgorithm() = this.getAlgorithm() - } - } - - class CipherSource extends TaintSource { - CipherSource() { this.(CallNode).getFunction().pointsTo(any(CipherClass cls)) } - - override predicate isSourceOf(TaintKind kind) { - this.(CallNode).getArg(0).pointsTo().getClass() = kind.(CipherInstance).getAlgorithm() - } - - override string toString() { result = "cryptography.Cipher.source" } - } - - class Encryptor extends TaintKind { - AlgorithmClass cls; - - Encryptor() { this = "cryptography.encryptor." + cls.getAlgorithmName() } - - AlgorithmClass getAlgorithm() { result = cls } - } - - class CryptographyWeakCryptoSink extends WeakCryptoSink { - CryptographyWeakCryptoSink() { - exists(CallNode call, AttrNode method, Encryptor encryptor | - call.getAnArg() = this and - call.getFunction() = method and - encryptor.taints(method.getObject("update")) and - encryptor.getAlgorithm().isWeak() - ) - } - - override string toString() { result = "Use of weak crypto algorithm" } - } -} - -deprecated private class CipherConfig extends TaintTracking::Configuration { - CipherConfig() { this = "Crypto cipher config" } - - override predicate isSource(TaintTracking::Source source) { - source instanceof Pycrypto::CipherInstanceSource - or - source instanceof Cryptography::CipherSource - } -} diff --git a/python/ql/lib/semmle/python/security/SensitiveData.qll b/python/ql/lib/semmle/python/security/SensitiveData.qll deleted file mode 100644 index 7a955c0fd5a..00000000000 --- a/python/ql/lib/semmle/python/security/SensitiveData.qll +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Provides classes and predicates for identifying sensitive data and methods for security. - * - * 'Sensitive' data in general is anything that should not be sent around in unencrypted form. This - * library tries to guess where sensitive data may either be stored in a variable or produced by a - * method. - * - * In addition, there are methods that ought not to be executed or not in a fashion that the user - * can control. This includes authorization methods such as logins, and sending of data, etc. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.HttpRequest -import semmle.python.security.internal.SensitiveDataHeuristics -private import HeuristicNames - -abstract deprecated class SensitiveData extends TaintKind { - bindingset[this] - SensitiveData() { this = this } - - /** Gets the classification of this sensitive data taint kind. */ - abstract SensitiveDataClassification getClassification(); -} - -deprecated module SensitiveData { - class Secret extends SensitiveData { - Secret() { this = "sensitive.data.secret" } - - override string repr() { result = "a secret" } - - override SensitiveDataClassification getClassification() { - result = SensitiveDataClassification::secret() - } - } - - class Id extends SensitiveData { - Id() { this = "sensitive.data.id" } - - override string repr() { result = "an ID" } - - override SensitiveDataClassification getClassification() { - result = SensitiveDataClassification::id() - } - } - - class Password extends SensitiveData { - Password() { this = "sensitive.data.password" } - - override string repr() { result = "a password" } - - override SensitiveDataClassification getClassification() { - result = SensitiveDataClassification::password() - } - } - - class Certificate extends SensitiveData { - Certificate() { this = "sensitive.data.certificate" } - - override string repr() { result = "a certificate or key" } - - override SensitiveDataClassification getClassification() { - result = SensitiveDataClassification::certificate() - } - } - - private SensitiveData fromFunction(Value func) { - nameIndicatesSensitiveData(func.getName(), result.getClassification()) - } - - abstract class Source extends TaintSource { - abstract string repr(); - } - - private class SensitiveCallSource extends Source { - SensitiveData data; - - SensitiveCallSource() { - exists(Value callee | callee.getACall() = this | data = fromFunction(callee)) - } - - override predicate isSourceOf(TaintKind kind) { kind = data } - - override string repr() { result = "a call returning " + data.repr() } - } - - /** An access to a variable or property that might contain sensitive data. */ - private class SensitiveVariableAccess extends SensitiveData::Source { - SensitiveData data; - - SensitiveVariableAccess() { - nameIndicatesSensitiveData(this.(AttrNode).getName(), data.getClassification()) - } - - override predicate isSourceOf(TaintKind kind) { kind = data } - - override string repr() { result = "an attribute or property containing " + data.repr() } - } - - private class SensitiveRequestParameter extends SensitiveData::Source { - SensitiveData data; - - SensitiveRequestParameter() { - this.(CallNode).getFunction().(AttrNode).getName() = "get" and - exists(StringValue sensitive | - this.(CallNode).getAnArg().pointsTo(sensitive) and - nameIndicatesSensitiveData(sensitive.getText(), data.getClassification()) - ) - } - - override predicate isSourceOf(TaintKind kind) { kind = data } - - override string repr() { result = "a request parameter containing " + data.repr() } - } -} - -//Backwards compatibility -deprecated class SensitiveDataSource = SensitiveData::Source; diff --git a/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll b/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll deleted file mode 100644 index 7eee413131b..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll +++ /dev/null @@ -1,95 +0,0 @@ -/** - * DEPRECATED -- use flow state instead - * - * This defines a `PathGraph` where sinks from `TaintTracking::Configuration`s are identified with - * sources from `TaintTracking2::Configuration`s if they represent the same `ControlFlowNode`. - * - * Paths are then connected appropriately. - */ - -import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.DataFlow2 -import semmle.python.dataflow.new.TaintTracking -import semmle.python.dataflow.new.TaintTracking2 - -/** - * A `DataFlow::Node` that appears as a sink in Config1 and a source in Config2. - */ -private predicate crossoverNode(DataFlow::Node n) { - any(TaintTracking::Configuration t1).isSink(n) and - any(TaintTracking2::Configuration t2).isSource(n) -} - -/** - * A new type which represents the union of the two sets of nodes. - */ -private newtype TCustomPathNode = - Config1Node(DataFlow::PathNode node1) { not crossoverNode(node1.getNode()) } or - Config2Node(DataFlow2::PathNode node2) { not crossoverNode(node2.getNode()) } or - CrossoverNode(DataFlow::Node node) { crossoverNode(node) } - -/** - * DEPRECATED: Use flow state instead - * - * A class representing the set of all the path nodes in either config. - */ -deprecated class CustomPathNode extends TCustomPathNode { - /** Gets the PathNode if it is in Config1. */ - DataFlow::PathNode asNode1() { - this = Config1Node(result) or this = CrossoverNode(result.getNode()) - } - - /** Gets the PathNode if it is in Config2. */ - DataFlow2::PathNode asNode2() { - this = Config2Node(result) or this = CrossoverNode(result.getNode()) - } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.asNode1().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - or - this.asNode2().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets a textual representation of this element. */ - string toString() { - result = this.asNode1().toString() - or - result = this.asNode2().toString() - } -} - -/** - * DEPRECATED: Use flow state instead - * - * Holds if `(a,b)` is an edge in the graph of data flow path explanations. - */ -deprecated query predicate edges(CustomPathNode a, CustomPathNode b) { - // Edge is in Config1 graph - DataFlow::PathGraph::edges(a.asNode1(), b.asNode1()) - or - // Edge is in Config2 graph - DataFlow2::PathGraph::edges(a.asNode2(), b.asNode2()) -} - -/** - * DEPRECATED: Use flow state instead - * - * Holds if `n` is a node in the graph of data flow path explanations. - */ -deprecated query predicate nodes(CustomPathNode n, string key, string val) { - // Node is in Config1 graph - DataFlow::PathGraph::nodes(n.asNode1(), key, val) - or - // Node is in Config2 graph - DataFlow2::PathGraph::nodes(n.asNode2(), key, val) -} diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextLogging.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextLogging.qll deleted file mode 100644 index 4471c9f4c34..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextLogging.qll +++ /dev/null @@ -1,14 +0,0 @@ -/** DEPRECATED. Import `CleartextLoggingQuery` instead. */ - -private import python -private import semmle.python.dataflow.new.DataFlow -private import semmle.python.dataflow.new.TaintTracking -private import semmle.python.Concepts -private import semmle.python.dataflow.new.RemoteFlowSources -private import semmle.python.dataflow.new.BarrierGuards -private import semmle.python.dataflow.new.SensitiveDataSources - -/** DEPRECATED. Import `CleartextLoggingQuery` instead. */ -deprecated module CleartextLogging { - import CleartextLoggingQuery // ignore-query-import -} diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorage.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorage.qll deleted file mode 100644 index 105510aaeb5..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorage.qll +++ /dev/null @@ -1,14 +0,0 @@ -/** DEPRECATED. Import `CleartextStorageQuery` instead. */ - -private import python -private import semmle.python.dataflow.new.DataFlow -private import semmle.python.dataflow.new.TaintTracking -private import semmle.python.Concepts -private import semmle.python.dataflow.new.RemoteFlowSources -private import semmle.python.dataflow.new.BarrierGuards -private import semmle.python.dataflow.new.SensitiveDataSources - -/** DEPRECATED. Import `CleartextStorageQuery` instead. */ -deprecated module CleartextStorage { - import CleartextStorageQuery // ignore-query-import -} diff --git a/python/ql/lib/semmle/python/security/dataflow/CodeInjection.qll b/python/ql/lib/semmle/python/security/dataflow/CodeInjection.qll deleted file mode 100644 index 35f6d96b753..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/CodeInjection.qll +++ /dev/null @@ -1,13 +0,0 @@ -/** DEPRECATED. Import `CodeInjectionQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `CodeInjectionQuery` instead. */ -deprecated module CodeInjection { - import CodeInjectionQuery // ignore-query-import -} - -/** DEPRECATED. Import `CodeInjectionQuery` instead. */ -deprecated class CodeInjectionConfiguration = CodeInjection::Configuration; diff --git a/python/ql/lib/semmle/python/security/dataflow/CommandInjection.qll b/python/ql/lib/semmle/python/security/dataflow/CommandInjection.qll deleted file mode 100644 index c72be4985fc..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/CommandInjection.qll +++ /dev/null @@ -1,13 +0,0 @@ -/** DEPRECATED. Import `CommandInjectionQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `CommandInjectionQuery` instead. */ -deprecated module CommandInjection { - import CommandInjectionQuery // ignore-query-import -} - -/** DEPRECATED. Import `CommandInjectionQuery` instead. */ -deprecated class CommandInjectionConfiguration = CommandInjection::Configuration; diff --git a/python/ql/lib/semmle/python/security/dataflow/LdapInjection.qll b/python/ql/lib/semmle/python/security/dataflow/LdapInjection.qll deleted file mode 100644 index df9e89dbf82..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/LdapInjection.qll +++ /dev/null @@ -1,12 +0,0 @@ -/** DEPRECATED. Import `LdapInjectionQuery` instead. */ - -import python -import semmle.python.Concepts -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking -import semmle.python.dataflow.new.RemoteFlowSources - -/** DEPRECATED. Import `LdapInjectionQuery` instead. */ -deprecated module LdapInjection { - import LdapInjectionQuery // ignore-query-import -} diff --git a/python/ql/lib/semmle/python/security/dataflow/LogInjection.qll b/python/ql/lib/semmle/python/security/dataflow/LogInjection.qll deleted file mode 100644 index 0a00e695483..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/LogInjection.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** DEPRECATED. Import `LogInjectionQuery` instead. */ - -import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `LogInjectionQuery` instead. */ -deprecated module LogInjection { - import LogInjectionQuery // ignore-query-import -} diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjection.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjection.qll deleted file mode 100644 index 79e61abb0ce..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/PathInjection.qll +++ /dev/null @@ -1,133 +0,0 @@ -/** DEPRECATED. Import `PathInjectionQuery` instead. */ - -private import python -private import semmle.python.Concepts -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `PathInjectionQuery` instead. */ -deprecated module PathInjection { - import PathInjectionQuery // ignore-query-import -} - -// --------------------------------------------------------------------------- -// Old, deprecated code -// --------------------------------------------------------------------------- -private import semmle.python.dataflow.new.DataFlow2 -private import semmle.python.dataflow.new.TaintTracking2 -private import ChainedConfigs12 -import PathInjectionCustomizations::PathInjection - -// --------------------------------------------------------------------------- -// Case 1. The path is never normalized. -// --------------------------------------------------------------------------- -/** - * DEPRECATED: Import `PathInjectionQuery` instead. - * - * Configuration to find paths from sources to sinks that contain no normalization. - */ -deprecated class PathNotNormalizedConfiguration extends TaintTracking::Configuration { - PathNotNormalizedConfiguration() { this = "PathNotNormalizedConfiguration" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Sanitizer - or - node instanceof Path::PathNormalization - } - - override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { - guard instanceof SanitizerGuard - } -} - -/** - * DEPRECATED: Import `PathInjectionQuery` instead. - * - * Holds if there is a path injection from source to sink, where the (python) path is - * not normalized. - */ -deprecated predicate pathNotNormalized(CustomPathNode source, CustomPathNode sink) { - any(PathNotNormalizedConfiguration config).hasFlowPath(source.asNode1(), sink.asNode1()) -} - -// --------------------------------------------------------------------------- -// Case 2. The path is normalized at least once, but never checked afterwards. -// --------------------------------------------------------------------------- -/** - * DEPRECATED: Import `PathInjectionQuery` instead. - * - * Configuration to find paths from sources to normalizations that contain no prior normalizations. - */ -deprecated class FirstNormalizationConfiguration extends TaintTracking::Configuration { - FirstNormalizationConfiguration() { this = "FirstNormalizationConfiguration" } - - override predicate isSource(DataFlow::Node source) { source instanceof Source } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Path::PathNormalization } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - override predicate isSanitizerOut(DataFlow::Node node) { node instanceof Path::PathNormalization } - - override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { - guard instanceof SanitizerGuard - } -} - -/** - * DEPRECATED: Import `PathInjectionQuery` instead. - * - * Configuration to find paths from normalizations to sinks that do not go through a check. - */ -deprecated class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuration { - NormalizedPathNotCheckedConfiguration() { this = "NormalizedPathNotCheckedConfiguration" } - - override predicate isSource(DataFlow::Node source) { source instanceof Path::PathNormalization } - - override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof Path::SafeAccessCheck - or - node instanceof Sanitizer - } - - override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { - guard instanceof SanitizerGuard - } -} - -/** - * DEPRECATED: Import `PathInjectionQuery` instead. - * - * Holds if there is a path injection from source to sink, where the (python) path is - * normalized at least once, but never checked afterwards. - */ -deprecated predicate pathNotCheckedAfterNormalization(CustomPathNode source, CustomPathNode sink) { - exists( - FirstNormalizationConfiguration config, DataFlow::PathNode mid1, DataFlow2::PathNode mid2, - NormalizedPathNotCheckedConfiguration config2 - | - config.hasFlowPath(source.asNode1(), mid1) and - config2.hasFlowPath(mid2, sink.asNode2()) and - mid1.getNode().asCfgNode() = mid2.getNode().asCfgNode() - ) -} - -// --------------------------------------------------------------------------- -// Query: Either case 1 or case 2. -// --------------------------------------------------------------------------- -/** - * DEPRECATED: Import `PathInjectionQuery` instead. - * - * Holds if there is a path injection from source to sink - */ -deprecated predicate pathInjection(CustomPathNode source, CustomPathNode sink) { - pathNotNormalized(source, sink) - or - pathNotCheckedAfterNormalization(source, sink) -} diff --git a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoS.qll b/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoS.qll deleted file mode 100644 index 5454b889f03..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/PolynomialReDoS.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** DEPRECATED. Import `PolynomialReDoSQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `PolynomialReDoSQuery` instead. */ -deprecated module PolynomialReDoS { - import PolynomialReDoSQuery // ignore-query-import -} diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSS.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSS.qll deleted file mode 100644 index 2e481d25cf7..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSS.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** DEPRECATED. Import `ReflectedXSSQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `ReflectedXSSQuery` instead. */ -deprecated module ReflectedXss { - import ReflectedXssQuery // ignore-query-import -} - -/** DEPRECATED. Import `ReflectedXSSQuery` instead. */ -deprecated module ReflectedXSS = ReflectedXss; - -/** DEPRECATED. Import `ReflectedXSSQuery` instead. */ -deprecated class ReflectedXssConfiguration = ReflectedXss::Configuration; diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll index ea826c3b0c5..2229d0c758c 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll @@ -76,6 +76,3 @@ module ReflectedXss { */ class StringConstCompareAsSanitizerGuard extends Sanitizer, StringConstCompareBarrier { } } - -/** DEPRECATED: Alias for ReflectedXss */ -deprecated module ReflectedXSS = ReflectedXss; diff --git a/python/ql/lib/semmle/python/security/dataflow/RegexInjection.qll b/python/ql/lib/semmle/python/security/dataflow/RegexInjection.qll deleted file mode 100644 index decc9b00946..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/RegexInjection.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** DEPRECATED. Import `RegexInjectionQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `RegexInjectionQuery` instead. */ -deprecated module RegexInjection { - import RegexInjectionQuery // ignore-query-import -} diff --git a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgery.qll b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgery.qll deleted file mode 100644 index dd04ccf4cf5..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgery.qll +++ /dev/null @@ -1,25 +0,0 @@ -/** DEPRECATED. Import `ServerSideRequestForgeryQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking -import semmle.python.Concepts -import ServerSideRequestForgeryQuery as ServerSideRequestForgeryQuery // ignore-query-import - -/** DEPRECATED. Import `ServerSideRequestForgeryQuery` instead. */ -deprecated module FullServerSideRequestForgery { - import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery - - class Configuration = ServerSideRequestForgeryQuery::FullServerSideRequestForgeryConfiguration; -} - -/** DEPRECATED. Import `ServerSideRequestForgeryQuery` instead. */ -deprecated predicate fullyControlledRequest = - ServerSideRequestForgeryQuery::fullyControlledRequest/1; - -/** DEPRECATED. Import `ServerSideRequestForgeryQuery` instead. */ -deprecated module PartialServerSideRequestForgery { - import ServerSideRequestForgeryCustomizations::ServerSideRequestForgery - - class Configuration = ServerSideRequestForgeryQuery::PartialServerSideRequestForgeryConfiguration; -} diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjection.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjection.qll deleted file mode 100644 index eebe6251c22..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/SqlInjection.qll +++ /dev/null @@ -1,16 +0,0 @@ -/** DEPRECATED. Import `SqlInjectionQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `SqlInjectionQuery` instead. */ -deprecated module SqlInjection { - import SqlInjectionQuery // ignore-query-import -} - -/** DEPRECATED. Import `SqlInjectionQuery` instead. */ -deprecated class SqlInjectionConfiguration = SqlInjection::Configuration; - -/** DEPRECATED. Import `SqlInjectionQuery` instead. */ -deprecated class SQLInjectionConfiguration = SqlInjectionConfiguration; diff --git a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposure.qll b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposure.qll deleted file mode 100644 index 64e59756dff..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposure.qll +++ /dev/null @@ -1,13 +0,0 @@ -/** DEPRECATED. Import `StackTraceExposureQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `StackTraceExposureQuery` instead. */ -deprecated module StackTraceExposure { - import StackTraceExposureQuery // ignore-query-import -} - -/** DEPRECATED. Import `StackTraceExposureQuery` instead. */ -deprecated class StackTraceExposureConfiguration = StackTraceExposure::Configuration; diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserialization.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserialization.qll deleted file mode 100644 index 3bdd569128d..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeDeserialization.qll +++ /dev/null @@ -1,13 +0,0 @@ -/** DEPRECATED. Import `UnsafeDeserializationQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `UnsafeDeserializationQuery` instead. */ -deprecated module UnsafeDeserialization { - import UnsafeDeserializationQuery // ignore-query-import -} - -/** DEPRECATED. Import `UnsafeDeserializationQuery` instead. */ -deprecated class UnsafeDeserializationConfiguration = UnsafeDeserialization::Configuration; diff --git a/python/ql/lib/semmle/python/security/dataflow/UrlRedirect.qll b/python/ql/lib/semmle/python/security/dataflow/UrlRedirect.qll deleted file mode 100644 index 4cb354eabf8..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/UrlRedirect.qll +++ /dev/null @@ -1,13 +0,0 @@ -/** DEPRECATED. Import `UrlRedirectQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `UrlRedirectQuery` instead. */ -deprecated module UrlRedirect { - import UrlRedirectQuery // ignore-query-import -} - -/** DEPRECATED. Import `UrlRedirectQuery` instead. */ -deprecated class UrlRedirectConfiguration = UrlRedirect::Configuration; diff --git a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashing.qll b/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashing.qll deleted file mode 100644 index 867b3bedd0b..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/WeakSensitiveDataHashing.qll +++ /dev/null @@ -1,19 +0,0 @@ -/** DEPRECATED. Import `WeakSensitiveDataHashingQuery` instead. */ - -private import python -private import semmle.python.dataflow.new.DataFlow -private import semmle.python.dataflow.new.TaintTracking -private import semmle.python.Concepts -private import semmle.python.dataflow.new.RemoteFlowSources -private import semmle.python.dataflow.new.BarrierGuards -private import semmle.python.dataflow.new.SensitiveDataSources - -/** DEPRECATED. Import `WeakSensitiveDataHashingQuery` instead. */ -deprecated module NormalHashFunction { - import WeakSensitiveDataHashingQuery::NormalHashFunction // ignore-query-import -} - -/** DEPRECATED. Import `WeakSensitiveDataHashingQuery` instead. */ -deprecated module ComputationallyExpensiveHashFunction { - import WeakSensitiveDataHashingQuery::ComputationallyExpensiveHashFunction // ignore-query-import -} diff --git a/python/ql/lib/semmle/python/security/dataflow/XpathInjection.qll b/python/ql/lib/semmle/python/security/dataflow/XpathInjection.qll deleted file mode 100644 index 2ed69d035f9..00000000000 --- a/python/ql/lib/semmle/python/security/dataflow/XpathInjection.qll +++ /dev/null @@ -1,10 +0,0 @@ -/** DEPRECATED. Import `XpathInjectionQuery` instead. */ - -private import python -import semmle.python.dataflow.new.DataFlow -import semmle.python.dataflow.new.TaintTracking - -/** DEPRECATED. Import `XpathInjectionQuery` instead. */ -deprecated module XpathInjection { - import XpathInjectionQuery // ignore-query-import -} diff --git a/python/ql/lib/semmle/python/security/flow/AnyCall.qll b/python/ql/lib/semmle/python/security/flow/AnyCall.qll deleted file mode 100644 index 6c93f3841b2..00000000000 --- a/python/ql/lib/semmle/python/security/flow/AnyCall.qll +++ /dev/null @@ -1,9 +0,0 @@ -import python -import semmle.python.security.strings.Basic - -/** Assume that taint flows from argument to result for *any* call */ -deprecated class AnyCallStringFlow extends DataFlowExtension::DataFlowNode { - AnyCallStringFlow() { any(CallNode call).getAnArg() = this } - - override ControlFlowNode getASuccessorNode() { result.(CallNode).getAnArg() = this } -} diff --git a/python/ql/lib/semmle/python/security/injection/Deserialization.qll b/python/ql/lib/semmle/python/security/injection/Deserialization.qll deleted file mode 100644 index b516a2d6b2f..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Deserialization.qll +++ /dev/null @@ -1,8 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking - -/** `pickle.loads(untrusted)` vulnerability. */ -abstract deprecated class DeserializationSink extends TaintSink { - bindingset[this] - DeserializationSink() { this = this } -} diff --git a/python/ql/lib/semmle/python/security/injection/Exec.qll b/python/ql/lib/semmle/python/security/injection/Exec.qll deleted file mode 100644 index 3ff84915ae0..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Exec.qll +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious Python code. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -/** - * A taint sink that represents an argument to exec or eval that is vulnerable to malicious input. - * The `vuln` in `exec(vuln)` or similar. - */ -deprecated class StringEvaluationNode extends TaintSink { - override string toString() { result = "exec or eval" } - - StringEvaluationNode() { - exists(Exec exec | exec.getASubExpression().getAFlowNode() = this) - or - Value::named("exec").getACall().getAnArg() = this - or - Value::named("eval").getACall().getAnArg() = this - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/lib/semmle/python/security/injection/Marshal.qll b/python/ql/lib/semmle/python/security/injection/Marshal.qll deleted file mode 100644 index 815890903bd..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Marshal.qll +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious marshals. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.security.injection.Deserialization - -deprecated private FunctionObject marshalLoads() { - result = ModuleObject::named("marshal").attr("loads") -} - -/** - * A taint sink that is potentially vulnerable to malicious marshaled objects. - * The `vuln` in `marshal.loads(vuln)`. - */ -deprecated class UnmarshalingNode extends DeserializationSink { - override string toString() { result = "unmarshaling vulnerability" } - - UnmarshalingNode() { - exists(CallNode call | - marshalLoads().getACall() = call and - call.getAnArg() = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/lib/semmle/python/security/injection/Path.qll b/python/ql/lib/semmle/python/security/injection/Path.qll deleted file mode 100644 index 73d76104493..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Path.qll +++ /dev/null @@ -1,81 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -/** - * Prevents taint flowing through ntpath.normpath() - * NormalizedPath below handles that case. - */ -deprecated class PathSanitizer extends Sanitizer { - PathSanitizer() { this = "path.sanitizer" } - - override predicate sanitizingNode(TaintKind taint, ControlFlowNode node) { - taint instanceof ExternalStringKind and - abspath_call(node, _) - } -} - -deprecated private FunctionObject abspath() { - exists(ModuleObject os_path | ModuleObject::named("os").attr("path") = os_path | - os_path.attr("abspath") = result - or - os_path.attr("normpath") = result - ) -} - -/** A path that has been normalized, but not verified to be safe */ -deprecated class NormalizedPath extends TaintKind { - NormalizedPath() { this = "normalized.path.injection" } - - override string repr() { result = "normalized path" } -} - -deprecated private predicate abspath_call(CallNode call, ControlFlowNode arg) { - call.getFunction().refersTo(abspath()) and - arg = call.getArg(0) -} - -deprecated class AbsPath extends DataFlowExtension::DataFlowNode { - AbsPath() { abspath_call(_, this) } - - override ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) { - abspath_call(result, this) and - tokind instanceof NormalizedPath and - fromkind instanceof ExternalStringKind - } -} - -deprecated class NormalizedPathSanitizer extends Sanitizer { - NormalizedPathSanitizer() { this = "normalized.path.sanitizer" } - - override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { - taint instanceof NormalizedPath and - test.getTest().(CallNode).getFunction().(AttrNode).getName() = "startswith" and - test.getSense() = true - } -} - -/** - * A taint sink that is vulnerable to malicious paths. - * The `vuln` in `open(vuln)` and similar. - */ -deprecated class OpenNode extends TaintSink { - override string toString() { result = "argument to open()" } - - OpenNode() { - exists(CallNode call | - call = Value::named("open").getACall() and - ( - call.getArg(0) = this - or - call.getArgByName("file") = this - ) - ) - } - - override predicate sinks(TaintKind kind) { - kind instanceof ExternalStringKind - or - kind instanceof NormalizedPath - } -} diff --git a/python/ql/lib/semmle/python/security/injection/Pickle.qll b/python/ql/lib/semmle/python/security/injection/Pickle.qll deleted file mode 100644 index 621eccbd6ce..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Pickle.qll +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious pickles. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.security.injection.Deserialization - -deprecated private ModuleObject pickleModule() { - result.getName() = "pickle" - or - result.getName() = "cPickle" - or - result.getName() = "dill" -} - -deprecated private FunctionObject pickleLoads() { result = pickleModule().attr("loads") } - -/** `pickle.loads(untrusted)` vulnerability. */ -deprecated class UnpicklingNode extends DeserializationSink { - override string toString() { result = "unpickling untrusted data" } - - UnpicklingNode() { - exists(CallNode call | - pickleLoads().getACall() = call and - call.getAnArg() = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/lib/semmle/python/security/injection/RegexInjection.qll b/python/ql/lib/semmle/python/security/injection/RegexInjection.qll deleted file mode 100644 index c0c0f42dbd6..00000000000 --- a/python/ql/lib/semmle/python/security/injection/RegexInjection.qll +++ /dev/null @@ -1,6 +0,0 @@ -/** DEPRECATED: use semmle.python.security.dataflow.RegexInjection instead. */ - -private import semmle.python.security.dataflow.RegexInjection as New - -/** DEPRECATED: use semmle.python.security.dataflow.RegexInjection instead. */ -deprecated module RegexInjection = New::RegexInjection; diff --git a/python/ql/lib/semmle/python/security/injection/RegexInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/injection/RegexInjectionCustomizations.qll deleted file mode 100644 index 0738f2b58b6..00000000000 --- a/python/ql/lib/semmle/python/security/injection/RegexInjectionCustomizations.qll +++ /dev/null @@ -1,6 +0,0 @@ -/** DEPRECATED: use semmle.python.security.dataflow.RegexInjectionCustomizations instead. */ - -private import semmle.python.security.dataflow.RegexInjectionCustomizations as New - -/** DEPRECATED: use semmle.python.security.dataflow.RegexInjectionCustomizations instead. */ -deprecated module RegexInjection = New::RegexInjection; diff --git a/python/ql/lib/semmle/python/security/injection/Xml.qll b/python/ql/lib/semmle/python/security/injection/Xml.qll deleted file mode 100644 index 6f61e0a5ef5..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Xml.qll +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious XML objects. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.security.injection.Deserialization - -deprecated private ModuleObject xmlElementTreeModule() { - result.getName() = "xml.etree.ElementTree" -} - -deprecated private ModuleObject xmlMiniDomModule() { result.getName() = "xml.dom.minidom" } - -deprecated private ModuleObject xmlPullDomModule() { result.getName() = "xml.dom.pulldom" } - -deprecated private ModuleObject xmlSaxModule() { result.getName() = "xml.sax" } - -deprecated private class ExpatParser extends TaintKind { - ExpatParser() { this = "expat.parser" } -} - -deprecated private FunctionObject expatCreateParseFunction() { - result = ModuleObject::named("xml.parsers.expat").attr("ParserCreate") -} - -deprecated private class ExpatCreateParser extends TaintSource { - ExpatCreateParser() { expatCreateParseFunction().getACall() = this } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExpatParser } - - override string toString() { result = "expat.create.parser" } -} - -deprecated private FunctionObject xmlFromString() { - result = xmlElementTreeModule().attr("fromstring") - or - result = xmlMiniDomModule().attr("parseString") - or - result = xmlPullDomModule().attr("parseString") - or - result = xmlSaxModule().attr("parseString") -} - -/** A (potentially) malicious XML string. */ -deprecated class ExternalXmlString extends ExternalStringKind { - ExternalXmlString() { this = "external xml encoded object" } -} - -/** - * A call to an XML library function that is potentially vulnerable to a - * specially crafted XML string. - */ -deprecated class XmlLoadNode extends DeserializationSink { - override string toString() { result = "xml.load vulnerability" } - - XmlLoadNode() { - exists(CallNode call | call.getAnArg() = this | - xmlFromString().getACall() = call or - any(ExpatParser parser).taints(call.getFunction().(AttrNode).getObject("Parse")) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalXmlString } -} diff --git a/python/ql/lib/semmle/python/security/injection/Yaml.qll b/python/ql/lib/semmle/python/security/injection/Yaml.qll deleted file mode 100644 index 585552442f7..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Yaml.qll +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious yaml-encoded objects. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.security.injection.Deserialization - -deprecated private FunctionObject yamlLoad() { result = ModuleObject::named("yaml").attr("load") } - -/** `yaml.load(untrusted)` vulnerability. */ -deprecated class YamlLoadNode extends DeserializationSink { - override string toString() { result = "yaml.load vulnerability" } - - YamlLoadNode() { - exists(CallNode call | - yamlLoad().getACall() = call and - call.getAnArg() = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/lib/semmle/python/types/Extensions.qll b/python/ql/lib/semmle/python/types/Extensions.qll index 8b5b357723f..f6c824f9ab2 100644 --- a/python/ql/lib/semmle/python/types/Extensions.qll +++ b/python/ql/lib/semmle/python/types/Extensions.qll @@ -14,7 +14,6 @@ import python private import semmle.python.pointsto.PointsTo private import semmle.python.pointsto.PointsToContext private import semmle.python.objects.TObject -private import semmle.python.web.HttpConstants /* Make ObjectInternal visible to save extra imports in user code */ import semmle.python.objects.ObjectInternal @@ -52,30 +51,6 @@ class RangeIterationVariableFact extends PointsToExtension { } } -/* bottle module route constants */ -deprecated class BottleRoutePointToExtension extends PointsToExtension { - string name; - - BottleRoutePointToExtension() { - exists(DefinitionNode defn | - defn.getScope().(Module).getName() = "bottle" and - this = defn.getValue() and - name = defn.(NameNode).getId() - | - name = "route" or - name = httpVerbLower() - ) - } - - override predicate pointsTo(Context context, ObjectInternal value, ControlFlowNode origin) { - context.isImport() and - exists(CfgOrigin orig | - Module::named("bottle").attr("Bottle").(ClassObjectInternal).attribute(name, value, orig) and - origin = orig.asCfgNodeOrHere(this) - ) - } -} - /* Python 3.6+ regex module constants */ string short_flag(string flag) { flag in ["ASCII", "IGNORECASE", "LOCALE", "UNICODE", "MULTILINE", "TEMPLATE"] and diff --git a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll index bdf55bfc4f2..766cf6845af 100644 --- a/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll +++ b/python/ql/src/Security/CWE-020-ExternalAPIs/ExternalAPIs.qll @@ -33,9 +33,6 @@ class SafeExternalApi extends Unit { DataFlowPrivate::DataFlowCallable getSafeCallable() { none() } } -/** DEPRECATED: Alias for SafeExternalApi */ -deprecated class SafeExternalAPI = SafeExternalApi; - /** The default set of "safe" external APIs. */ private class DefaultSafeExternalApi extends SafeExternalApi { override DataFlow::CallCfgNode getSafeCall() { @@ -170,9 +167,6 @@ class ExternalApiDataNode extends DataFlow::Node { } } -/** DEPRECATED: Alias for ExternalApiDataNode */ -deprecated class ExternalAPIDataNode = ExternalApiDataNode; - /** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */ class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" } @@ -182,9 +176,6 @@ class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } -/** DEPRECATED: Alias for UntrustedDataToExternalApiConfig */ -deprecated class UntrustedDataToExternalAPIConfig = UntrustedDataToExternalApiConfig; - /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { UntrustedExternalApiDataNode() { any(UntrustedDataToExternalApiConfig c).hasFlow(_, this) } @@ -195,9 +186,6 @@ class UntrustedExternalApiDataNode extends ExternalApiDataNode { } } -/** DEPRECATED: Alias for UntrustedExternalApiDataNode */ -deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode; - /** An external API which is used with untrusted data. */ private newtype TExternalApi = MkExternalApi(string repr, DataFlowPrivate::ArgumentPosition apos) { @@ -230,6 +218,3 @@ class ExternalApiUsedWithUntrustedData extends MkExternalApi { /** Gets a textual representation of this element. */ string toString() { result = repr + " [" + apos + "]" } } - -/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */ -deprecated class ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData; diff --git a/python/ql/src/experimental/semmle/python/Concepts.qll b/python/ql/src/experimental/semmle/python/Concepts.qll index 65f1e0d8e01..3331e1117e0 100644 --- a/python/ql/src/experimental/semmle/python/Concepts.qll +++ b/python/ql/src/experimental/semmle/python/Concepts.qll @@ -90,9 +90,6 @@ module LdapQuery { } } -/** DEPRECATED: Alias for LdapQuery */ -deprecated module LDAPQuery = LdapQuery; - /** * A data-flow node that collect methods executing a LDAP query. * @@ -106,9 +103,6 @@ class LdapQuery extends DataFlow::Node instanceof LdapQuery::Range { DataFlow::Node getQuery() { result = super.getQuery() } } -/** DEPRECATED: Alias for LdapQuery */ -deprecated class LDAPQuery = LdapQuery; - /** Provides classes for modeling LDAP components escape-related APIs. */ module LdapEscape { /** @@ -125,9 +119,6 @@ module LdapEscape { } } -/** DEPRECATED: Alias for LdapEscape */ -deprecated module LDAPEscape = LdapEscape; - /** * A data-flow node that collects functions escaping LDAP components. * @@ -141,9 +132,6 @@ class LdapEscape extends DataFlow::Node instanceof LdapEscape::Range { DataFlow::Node getAnInput() { result = super.getAnInput() } } -/** DEPRECATED: Alias for LdapEscape */ -deprecated class LDAPEscape = LdapEscape; - /** Provides classes for modeling LDAP bind-related APIs. */ module LdapBind { /** @@ -173,9 +161,6 @@ module LdapBind { } } -/** DEPRECATED: Alias for LdapBind */ -deprecated module LDAPBind = LdapBind; - /** * A data-flow node that collects methods binding a LDAP connection. * @@ -202,9 +187,6 @@ class LdapBind extends DataFlow::Node instanceof LdapBind::Range { deprecated predicate useSSL() { this.useSsl() } } -/** DEPRECATED: Alias for LdapBind */ -deprecated class LDAPBind = LdapBind; - /** Provides classes for modeling SQL sanitization libraries. */ module SqlEscape { /** @@ -221,9 +203,6 @@ module SqlEscape { } } -/** DEPRECATED: Alias for SqlEscape */ -deprecated module SQLEscape = SqlEscape; - /** * A data-flow node that collects functions escaping SQL statements. * @@ -237,9 +216,6 @@ class SqlEscape extends DataFlow::Node instanceof SqlEscape::Range { DataFlow::Node getAnInput() { result = super.getAnInput() } } -/** DEPRECATED: Alias for SqlEscape */ -deprecated class SQLEscape = SqlEscape; - /** Provides a class for modeling NoSql execution APIs. */ module NoSqlQuery { /** @@ -254,9 +230,6 @@ module NoSqlQuery { } } -/** DEPRECATED: Alias for NoSqlQuery */ -deprecated module NoSQLQuery = NoSqlQuery; - /** * A data-flow node that executes NoSQL queries. * @@ -268,9 +241,6 @@ class NoSqlQuery extends DataFlow::Node instanceof NoSqlQuery::Range { DataFlow::Node getQuery() { result = super.getQuery() } } -/** DEPRECATED: Alias for NoSqlQuery */ -deprecated class NoSQLQuery = NoSqlQuery; - /** Provides classes for modeling NoSql sanitization-related APIs. */ module NoSqlSanitizer { /** @@ -285,9 +255,6 @@ module NoSqlSanitizer { } } -/** DEPRECATED: Alias for NoSqlSanitizer */ -deprecated module NoSQLSanitizer = NoSqlSanitizer; - /** * A data-flow node that collects functions sanitizing NoSQL queries. * @@ -299,9 +266,6 @@ class NoSqlSanitizer extends DataFlow::Node instanceof NoSqlSanitizer::Range { DataFlow::Node getAnInput() { result = super.getAnInput() } } -/** DEPRECATED: Alias for NoSqlSanitizer */ -deprecated class NoSQLSanitizer = NoSqlSanitizer; - /** Provides classes for modeling HTTP Header APIs. */ module HeaderDeclaration { /** @@ -450,9 +414,6 @@ module JwtEncoding { } } -/** DEPRECATED: Alias for JwtEncoding */ -deprecated module JWTEncoding = JwtEncoding; - /** * A data-flow node that collects methods encoding a JWT token. * @@ -481,9 +442,6 @@ class JwtEncoding extends DataFlow::Node instanceof JwtEncoding::Range { string getAlgorithmString() { result = super.getAlgorithmString() } } -/** DEPRECATED: Alias for JwtEncoding */ -deprecated class JWTEncoding = JwtEncoding; - /** Provides classes for modeling JWT decoding-related APIs. */ module JwtDecoding { /** @@ -525,9 +483,6 @@ module JwtDecoding { } } -/** DEPRECATED: Alias for JwtDecoding */ -deprecated module JWTDecoding = JwtDecoding; - /** * A data-flow node that collects methods encoding a JWT token. * @@ -566,9 +521,6 @@ class JwtDecoding extends DataFlow::Node instanceof JwtDecoding::Range { predicate verifiesSignature() { super.verifiesSignature() } } -/** DEPRECATED: Alias for JwtDecoding */ -deprecated class JWTDecoding = JwtDecoding; - /** Provides classes for modeling Email APIs. */ module EmailSender { /** diff --git a/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll b/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll index dbe1cbe4117..56fffe3a2a0 100644 --- a/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll +++ b/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll @@ -29,23 +29,14 @@ class LdapFullHost extends StrConst { } } -/** DEPRECATED: Alias for LdapFullHost */ -deprecated class LDAPFullHost = LdapFullHost; - class LdapSchema extends StrConst { LdapSchema() { this.getText().regexpMatch(getSchemaRegex()) } } -/** DEPRECATED: Alias for LdapSchema */ -deprecated class LDAPSchema = LdapSchema; - class LdapPrivateHost extends StrConst { LdapPrivateHost() { this.getText().regexpMatch(getPrivateHostRegex()) } } -/** DEPRECATED: Alias for LdapPrivateHost */ -deprecated class LDAPPrivateHost = LdapPrivateHost; - predicate concatAndCompareAgainstFullHostRegex(LdapSchema schema, StrConst host) { not host instanceof LdapPrivateHost and (schema.getText() + host.getText()).regexpMatch(getFullHostRegex()) @@ -56,9 +47,6 @@ class LdapBothStrings extends BinaryExpr { LdapBothStrings() { concatAndCompareAgainstFullHostRegex(this.getLeft(), this.getRight()) } } -/** DEPRECATED: Alias for LdapBothStrings */ -deprecated class LDAPBothStrings = LdapBothStrings; - // schema + host class LdapBothVar extends BinaryExpr { LdapBothVar() { @@ -73,9 +61,6 @@ class LdapBothVar extends BinaryExpr { } } -/** DEPRECATED: Alias for LdapBothVar */ -deprecated class LDAPBothVar = LdapBothVar; - // schema + "somethingon.theinternet.com" class LdapVarString extends BinaryExpr { LdapVarString() { @@ -89,9 +74,6 @@ class LdapVarString extends BinaryExpr { } } -/** DEPRECATED: Alias for LdapVarString */ -deprecated class LDAPVarString = LdapVarString; - // "ldap://" + host class LdapStringVar extends BinaryExpr { LdapStringVar() { @@ -103,9 +85,6 @@ class LdapStringVar extends BinaryExpr { } } -/** DEPRECATED: Alias for LdapStringVar */ -deprecated class LDAPStringVar = LdapStringVar; - /** * A taint-tracking configuration for detecting LDAP insecure authentications. */ @@ -125,6 +104,3 @@ class LdapInsecureAuthConfig extends TaintTracking::Configuration { exists(LdapBind ldapBind | not ldapBind.useSsl() and sink = ldapBind.getHost()) } } - -/** DEPRECATED: Alias for LdapInsecureAuthConfig */ -deprecated class LDAPInsecureAuthConfig = LdapInsecureAuthConfig; diff --git a/python/ql/src/experimental/semmle/python/security/injection/NoSQLInjection.qll b/python/ql/src/experimental/semmle/python/security/injection/NoSQLInjection.qll index e6f3832e4ff..f7a40fb3ee6 100644 --- a/python/ql/src/experimental/semmle/python/security/injection/NoSQLInjection.qll +++ b/python/ql/src/experimental/semmle/python/security/injection/NoSQLInjection.qll @@ -52,6 +52,3 @@ module NoSqlInjection { ConvertedToDict() { this = "ConvertedToDict" } } } - -/** DEPRECATED: Alias for NoSqlInjection */ -deprecated module NoSQLInjection = NoSqlInjection; diff --git a/python/ql/test/library-tests/security/sensitive/Sources.expected b/python/ql/test/library-tests/security/sensitive/Sources.expected deleted file mode 100644 index 4500a2c23a5..00000000000 --- a/python/ql/test/library-tests/security/sensitive/Sources.expected +++ /dev/null @@ -1,6 +0,0 @@ -WARNING: Module SensitiveData has been deprecated and may be removed in future (Sources.ql:4,6-19) -| test.py:16:1:16:14 | test.py:16 | a call returning a password | -| test.py:17:1:17:12 | test.py:17 | a call returning a password | -| test.py:18:1:18:12 | test.py:18 | a call returning a secret | -| test.py:19:1:19:19 | test.py:19 | a call returning a certificate or key | -| test.py:20:1:20:12 | test.py:20 | a call returning an ID | diff --git a/python/ql/test/library-tests/security/sensitive/Sources.ql b/python/ql/test/library-tests/security/sensitive/Sources.ql deleted file mode 100644 index b5328a9f105..00000000000 --- a/python/ql/test/library-tests/security/sensitive/Sources.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import semmle.python.security.SensitiveData - -from SensitiveData::Source src -select src.getLocation(), src.repr() diff --git a/python/ql/test/library-tests/security/sensitive/test.py b/python/ql/test/library-tests/security/sensitive/test.py deleted file mode 100644 index bd5aaf238d8..00000000000 --- a/python/ql/test/library-tests/security/sensitive/test.py +++ /dev/null @@ -1,21 +0,0 @@ - -from not_found import get_passwd, account_id - -def get_password(): - pass - -def get_secret(): - pass - -def fetch_certificate(): - pass - -def encrypt_password(pwd): - pass - -get_password() -get_passwd() -get_secret() -fetch_certificate() -account_id() -safe_to_store = encrypt_password(pwd) diff --git a/python/ql/test/library-tests/web/bottle/HttpResponseSinks.expected b/python/ql/test/library-tests/web/bottle/HttpResponseSinks.expected deleted file mode 100644 index 196468fd4c1..00000000000 --- a/python/ql/test/library-tests/web/bottle/HttpResponseSinks.expected +++ /dev/null @@ -1,5 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| test.py:9:12:9:26 | bottle handler function result | externally controlled string | -| test.py:13:12:13:24 | bottle handler function result | externally controlled string | -| test.py:19:12:19:33 | bottle handler function result | externally controlled string | -| test.py:36:21:36:51 | Taint sink | externally controlled string | diff --git a/python/ql/test/library-tests/web/bottle/HttpResponseSinks.ql b/python/ql/test/library-tests/web/bottle/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/bottle/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/bottle/HttpSources.expected b/python/ql/test/library-tests/web/bottle/HttpSources.expected deleted file mode 100644 index 63d149e955a..00000000000 --- a/python/ql/test/library-tests/web/bottle/HttpSources.expected +++ /dev/null @@ -1,9 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| ../../../query-tests/Security/lib/bottle.py:64:11:64:24 | LocalRequest() | bottle.request | -| test.py:3:35:3:41 | ImportMember | bottle.request | -| test.py:8:11:8:14 | name | externally controlled string | -| test.py:12:9:12:12 | name | externally controlled string | -| test.py:18:12:18:18 | request | bottle.request | -| test.py:27:12:27:16 | where | externally controlled string | -| test.py:32:14:32:20 | request | bottle.request | -| test.py:36:34:36:40 | request | bottle.request | diff --git a/python/ql/test/library-tests/web/bottle/HttpSources.ql b/python/ql/test/library-tests/web/bottle/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/bottle/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/bottle/Routing.expected b/python/ql/test/library-tests/web/bottle/Routing.expected deleted file mode 100644 index d07889879a3..00000000000 --- a/python/ql/test/library-tests/web/bottle/Routing.expected +++ /dev/null @@ -1,8 +0,0 @@ -WARNING: Type BottleRoute has been deprecated and may be removed in future (Routing.ql:4,6-17) -| /args | test.py:31:1:31:14 | Function unsafe2 | -| /bye/<name> | test.py:12:1:12:25 | Function bye | -| /hello/<name> | test.py:8:1:8:27 | Function hello | -| /other | test.py:17:1:17:12 | Function other | -| /wrong/<where> | test.py:27:1:27:31 | Function unsafe | -| /wrong/url | test.py:23:1:23:11 | Function safe | -| /xss | test.py:35:1:35:16 | Function maybe_xss | diff --git a/python/ql/test/library-tests/web/bottle/Routing.ql b/python/ql/test/library-tests/web/bottle/Routing.ql deleted file mode 100644 index 988b8398f04..00000000000 --- a/python/ql/test/library-tests/web/bottle/Routing.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import semmle.python.web.bottle.General - -from BottleRoute route -select route.getUrl(), route.getFunction() diff --git a/python/ql/test/library-tests/web/bottle/Taint.expected b/python/ql/test/library-tests/web/bottle/Taint.expected deleted file mode 100644 index 451b1ee3e00..00000000000 --- a/python/ql/test/library-tests/web/bottle/Taint.expected +++ /dev/null @@ -1,23 +0,0 @@ -| ../../../query-tests/Security/lib/bottle.py:64 | LocalRequest() | bottle.request | -| ../../../query-tests/Security/lib/bottle.py:68 | url | externally controlled string | -| test.py:3 | ImportMember | bottle.request | -| test.py:8 | name | externally controlled string | -| test.py:9 | BinaryExpr | externally controlled string | -| test.py:9 | name | externally controlled string | -| test.py:12 | name | externally controlled string | -| test.py:13 | BinaryExpr | externally controlled string | -| test.py:13 | name | externally controlled string | -| test.py:18 | Attribute | bottle.FormsDict | -| test.py:18 | Attribute | externally controlled string | -| test.py:18 | request | bottle.request | -| test.py:19 | BinaryExpr | externally controlled string | -| test.py:19 | name | externally controlled string | -| test.py:27 | where | externally controlled string | -| test.py:28 | where | externally controlled string | -| test.py:32 | Attribute | bottle.FormsDict | -| test.py:32 | Attribute | externally controlled string | -| test.py:32 | request | bottle.request | -| test.py:36 | Attribute | bottle.FormsDict | -| test.py:36 | Attribute | externally controlled string | -| test.py:36 | BinaryExpr | externally controlled string | -| test.py:36 | request | bottle.request | diff --git a/python/ql/test/library-tests/web/bottle/Taint.ql b/python/ql/test/library-tests/web/bottle/Taint.ql deleted file mode 100644 index 09972af5f98..00000000000 --- a/python/ql/test/library-tests/web/bottle/Taint.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from TaintedNode node -select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind() diff --git a/python/ql/test/library-tests/web/bottle/options b/python/ql/test/library-tests/web/bottle/options deleted file mode 100644 index 7fb713d5924..00000000000 --- a/python/ql/test/library-tests/web/bottle/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/bottle/test.py b/python/ql/test/library-tests/web/bottle/test.py deleted file mode 100644 index 8975de72ea4..00000000000 --- a/python/ql/test/library-tests/web/bottle/test.py +++ /dev/null @@ -1,36 +0,0 @@ - - -from bottle import Bottle, route, request, redirect, response - -app = Bottle() - -@app.route('/hello/<name>') -def hello(name = "World!"): - return "Hello " + name - -@route('/bye/<name>') -def bye(name = "World!"): - return "Bye " + name - - -@route('/other') -def other(): - name = request.cookies.username - return "User name is " + name - - -@route('/wrong/url') -def safe(): - redirect("/right/url") - -@route('/wrong/<where>') -def unsafe(where="/right/url"): - redirect(where) - -@route('/args') -def unsafe2(): - redirect(request.query.where, code) - -@route('/xss') -def maybe_xss(): - response.body = "name is " + request.query.name diff --git a/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.expected b/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.expected deleted file mode 100644 index d45cfd65989..00000000000 --- a/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| red.py:8:16:8:20 | cherrypy handler function result | externally controlled string | -| test.py:11:16:11:29 | cherrypy handler function result | externally controlled string | -| test.py:17:16:17:27 | cherrypy handler function result | externally controlled string | diff --git a/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.ql b/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/cherrypy/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/cherrypy/HttpSources.expected b/python/ql/test/library-tests/web/cherrypy/HttpSources.expected deleted file mode 100644 index e0d1d7c4e59..00000000000 --- a/python/ql/test/library-tests/web/cherrypy/HttpSources.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| ../../../query-tests/Security/lib/cherrypy/__init__.py:10:11:10:38 | _ThreadLocalProxy() | cherrypy.request | -| test.py:10:17:10:19 | arg | externally controlled string | -| test.py:16:17:16:19 | arg | externally controlled string | diff --git a/python/ql/test/library-tests/web/cherrypy/HttpSources.ql b/python/ql/test/library-tests/web/cherrypy/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/cherrypy/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/cherrypy/options b/python/ql/test/library-tests/web/cherrypy/options deleted file mode 100644 index 7fb713d5924..00000000000 --- a/python/ql/test/library-tests/web/cherrypy/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/cherrypy/red.py b/python/ql/test/library-tests/web/cherrypy/red.py deleted file mode 100644 index 5fa25b5aa0f..00000000000 --- a/python/ql/test/library-tests/web/cherrypy/red.py +++ /dev/null @@ -1,11 +0,0 @@ - -import cherrypy - -class MultiPath(object): - - @cherrypy.expose(['color', 'colour']) - def red(self): - return "RED" - -if __name__ == '__main__': - cherrypy.quickstart(MultiPath()) diff --git a/python/ql/test/library-tests/web/cherrypy/test.py b/python/ql/test/library-tests/web/cherrypy/test.py deleted file mode 100644 index 5d44b54077b..00000000000 --- a/python/ql/test/library-tests/web/cherrypy/test.py +++ /dev/null @@ -1,23 +0,0 @@ - -import random -import string - -import cherrypy - -class A(object): - - @cherrypy.expose - def a(self, arg): - return "hello " + arg - -class B(object): - - @cherrypy.expose - def b(self, arg): - return "bye " + arg - -cherrypy.tree.mount(A(), '/a', a_conf) -cherrypy.tree.mount(B(), '/b', b_conf) - -cherrypy.engine.start() -cherrypy.engine.block() \ No newline at end of file diff --git a/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.expected b/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.expected deleted file mode 100644 index fa93ffe7e88..00000000000 --- a/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.expected +++ /dev/null @@ -1,3 +0,0 @@ -WARNING: Module Client has been deprecated and may be removed in future (ClientHttpRequests.ql:5,6-12) -| test.py:3:1:3:27 | ControlFlowNode for Attribute() | test.py:3:14:3:26 | ControlFlowNode for Str | GET | -| test.py:4:1:4:28 | ControlFlowNode for Attribute() | test.py:4:15:4:27 | ControlFlowNode for Str | POST | diff --git a/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.ql b/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.ql deleted file mode 100644 index 52fd7ff218e..00000000000 --- a/python/ql/test/library-tests/web/client/requests/ClientHttpRequests.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.Http -import semmle.python.web.ClientHttpRequest - -from Client::HttpRequest req, string method -where if exists(req.getMethodUpper()) then method = req.getMethodUpper() else method = "<NO METHOD>" -select req, req.getAUrlPart(), method diff --git a/python/ql/test/library-tests/web/client/requests/options b/python/ql/test/library-tests/web/client/requests/options deleted file mode 100644 index f1858a6caf9..00000000000 --- a/python/ql/test/library-tests/web/client/requests/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: -p ../../../../query-tests/Security/lib/ --max-import-depth=1 diff --git a/python/ql/test/library-tests/web/client/requests/test.py b/python/ql/test/library-tests/web/client/requests/test.py deleted file mode 100644 index 1cb5e47e166..00000000000 --- a/python/ql/test/library-tests/web/client/requests/test.py +++ /dev/null @@ -1,4 +0,0 @@ -import requests - -requests.get('example.com') -requests.post('example.com') diff --git a/python/ql/test/library-tests/web/client/six/ClientHttpRequests.expected b/python/ql/test/library-tests/web/client/six/ClientHttpRequests.expected deleted file mode 100644 index 40400cce819..00000000000 --- a/python/ql/test/library-tests/web/client/six/ClientHttpRequests.expected +++ /dev/null @@ -1,11 +0,0 @@ -WARNING: Module Client has been deprecated and may be removed in future (ClientHttpRequests.ql:5,6-12) -| test.py:6:5:6:32 | ControlFlowNode for Attribute() | test.py:5:27:5:39 | ControlFlowNode for Str | GET | -| test.py:6:5:6:32 | ControlFlowNode for Attribute() | test.py:6:25:6:31 | ControlFlowNode for Str | GET | -| test.py:15:5:15:33 | ControlFlowNode for Attribute() | test.py:10:28:10:40 | ControlFlowNode for Str | POST | -| test.py:15:5:15:33 | ControlFlowNode for Attribute() | test.py:15:26:15:32 | ControlFlowNode for Str | POST | -| test.py:20:5:20:33 | ControlFlowNode for Attribute() | test.py:19:27:19:39 | ControlFlowNode for Str | <NO METHOD> | -| test.py:20:5:20:33 | ControlFlowNode for Attribute() | test.py:20:26:20:32 | ControlFlowNode for Str | <NO METHOD> | -| test.py:30:5:30:32 | ControlFlowNode for Attribute() | test.py:28:27:28:30 | ControlFlowNode for fake | GET | -| test.py:30:5:30:32 | ControlFlowNode for Attribute() | test.py:30:25:30:31 | ControlFlowNode for Str | GET | -| test.py:37:5:37:29 | ControlFlowNode for req_meth() | test.py:35:27:35:39 | ControlFlowNode for Str | HEAD | -| test.py:37:5:37:29 | ControlFlowNode for req_meth() | test.py:37:22:37:28 | ControlFlowNode for Str | HEAD | diff --git a/python/ql/test/library-tests/web/client/six/ClientHttpRequests.ql b/python/ql/test/library-tests/web/client/six/ClientHttpRequests.ql deleted file mode 100644 index 52fd7ff218e..00000000000 --- a/python/ql/test/library-tests/web/client/six/ClientHttpRequests.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.Http -import semmle.python.web.ClientHttpRequest - -from Client::HttpRequest req, string method -where if exists(req.getMethodUpper()) then method = req.getMethodUpper() else method = "<NO METHOD>" -select req, req.getAUrlPart(), method diff --git a/python/ql/test/library-tests/web/client/six/options b/python/ql/test/library-tests/web/client/six/options deleted file mode 100644 index 1f95e64d742..00000000000 --- a/python/ql/test/library-tests/web/client/six/options +++ /dev/null @@ -1,2 +0,0 @@ -semmle-extractor-options: --max-import-depth=2 -optimize: true diff --git a/python/ql/test/library-tests/web/client/six/test.py b/python/ql/test/library-tests/web/client/six/test.py deleted file mode 100644 index cdd79021d87..00000000000 --- a/python/ql/test/library-tests/web/client/six/test.py +++ /dev/null @@ -1,37 +0,0 @@ -from six.moves.http_client import HTTPConnection, HTTPSConnection - - -def basic(): - conn = HTTPConnection('example.com') - conn.request('GET', '/path') - - -def indirect_caller(): - conn = HTTPSConnection('example.com') - indirect_callee(conn) - - -def indirect_callee(conn): - conn.request('POST', '/path') - - -def method_not_known(method): - conn = HTTPConnection('example.com') - conn.request(method, '/path') - - -def sneaky_setting_host(): - # We don't handle that the host is overwritten directly. - # A contrived example; you're not supposed to do this, but you certainly can. - fake = 'fakehost.com' - real = 'realhost.com' - conn = HTTPConnection(fake) - conn.host = real - conn.request('GET', '/path') - - -def tricky_not_attribute_node(): - # A contrived example; you're not supposed to do this, but you certainly can. - conn = HTTPConnection('example.com') - req_meth = conn.request - req_meth('HEAD', '/path') diff --git a/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.expected b/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.expected deleted file mode 100644 index 73540db65e6..00000000000 --- a/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.expected +++ /dev/null @@ -1,11 +0,0 @@ -WARNING: Module Client has been deprecated and may be removed in future (ClientHttpRequests.ql:5,6-12) -| test.py:13:5:13:32 | ControlFlowNode for Attribute() | test.py:12:27:12:39 | ControlFlowNode for Str | GET | -| test.py:13:5:13:32 | ControlFlowNode for Attribute() | test.py:13:25:13:31 | ControlFlowNode for Str | GET | -| test.py:22:5:22:33 | ControlFlowNode for Attribute() | test.py:17:28:17:40 | ControlFlowNode for Str | POST | -| test.py:22:5:22:33 | ControlFlowNode for Attribute() | test.py:22:26:22:32 | ControlFlowNode for Str | POST | -| test.py:27:5:27:33 | ControlFlowNode for Attribute() | test.py:26:27:26:39 | ControlFlowNode for Str | <NO METHOD> | -| test.py:27:5:27:33 | ControlFlowNode for Attribute() | test.py:27:26:27:32 | ControlFlowNode for Str | <NO METHOD> | -| test.py:37:5:37:32 | ControlFlowNode for Attribute() | test.py:35:27:35:30 | ControlFlowNode for fake | GET | -| test.py:37:5:37:32 | ControlFlowNode for Attribute() | test.py:37:25:37:31 | ControlFlowNode for Str | GET | -| test.py:44:5:44:29 | ControlFlowNode for req_meth() | test.py:42:27:42:39 | ControlFlowNode for Str | HEAD | -| test.py:44:5:44:29 | ControlFlowNode for req_meth() | test.py:44:22:44:28 | ControlFlowNode for Str | HEAD | diff --git a/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.ql b/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.ql deleted file mode 100644 index 52fd7ff218e..00000000000 --- a/python/ql/test/library-tests/web/client/stdlib/ClientHttpRequests.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.Http -import semmle.python.web.ClientHttpRequest - -from Client::HttpRequest req, string method -where if exists(req.getMethodUpper()) then method = req.getMethodUpper() else method = "<NO METHOD>" -select req, req.getAUrlPart(), method diff --git a/python/ql/test/library-tests/web/client/stdlib/options b/python/ql/test/library-tests/web/client/stdlib/options deleted file mode 100644 index eb214fc2931..00000000000 --- a/python/ql/test/library-tests/web/client/stdlib/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=1 diff --git a/python/ql/test/library-tests/web/client/stdlib/test.py b/python/ql/test/library-tests/web/client/stdlib/test.py deleted file mode 100644 index 179f9b30858..00000000000 --- a/python/ql/test/library-tests/web/client/stdlib/test.py +++ /dev/null @@ -1,44 +0,0 @@ -import sys -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 - -if PY2: - from httplib import HTTPConnection, HTTPSConnection -if PY3: - from http.client import HTTPConnection, HTTPSConnection - - -def basic(): - conn = HTTPConnection('example.com') - conn.request('GET', '/path') - - -def indirect_caller(): - conn = HTTPSConnection('example.com') - indirect_callee(conn) - - -def indirect_callee(conn): - conn.request('POST', '/path') - - -def method_not_known(method): - conn = HTTPConnection('example.com') - conn.request(method, '/path') - - -def sneaky_setting_host(): - # We don't handle that the host is overwritten directly. - # A contrived example; you're not supposed to do this, but you certainly can. - fake = 'fakehost.com' - real = 'realhost.com' - conn = HTTPConnection(fake) - conn.host = real - conn.request('GET', '/path') - - -def tricky_not_attribute_node(): - # A contrived example; you're not supposed to do this, but you certainly can. - conn = HTTPConnection('example.com') - req_meth = conn.request - req_meth('HEAD', '/path') diff --git a/python/ql/test/library-tests/web/django/HttpRedirectSinks.expected b/python/ql/test/library-tests/web/django/HttpRedirectSinks.expected deleted file mode 100644 index 6753f22d31f..00000000000 --- a/python/ql/test/library-tests/web/django/HttpRedirectSinks.expected +++ /dev/null @@ -1,5 +0,0 @@ -WARNING: Type HttpRedirectTaintSink has been deprecated and may be removed in future (HttpRedirectSinks.ql:5,6-27) -| test_1x.py:13:21:13:24 | DjangoShortcutsRedirectSink | externally controlled string | -| test_2x_3x.py:13:21:13:24 | DjangoShortcutsRedirectSink | externally controlled string | -| views_1x.py:99:33:99:55 | DjangoRedirectResponseSink | externally controlled string | -| views_2x_3x.py:120:33:120:55 | DjangoRedirectResponseSink | externally controlled string | diff --git a/python/ql/test/library-tests/web/django/HttpRedirectSinks.ql b/python/ql/test/library-tests/web/django/HttpRedirectSinks.ql deleted file mode 100644 index 157ef2d4430..00000000000 --- a/python/ql/test/library-tests/web/django/HttpRedirectSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRedirect -import semmle.python.security.strings.Untrusted - -from HttpRedirectTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/django/HttpResponseSinks.expected b/python/ql/test/library-tests/web/django/HttpResponseSinks.expected deleted file mode 100644 index 2f620ac508f..00000000000 --- a/python/ql/test/library-tests/web/django/HttpResponseSinks.expected +++ /dev/null @@ -1,32 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| views_1x.py:8:25:8:63 | django.Response(...) | externally controlled string | -| views_1x.py:12:25:12:52 | django.Response(...) | externally controlled string | -| views_1x.py:16:25:16:53 | django.Response(...) | externally controlled string | -| views_1x.py:21:15:21:42 | django.Response.write(...) | externally controlled string | -| views_1x.py:30:29:30:60 | django.Response(...) | externally controlled string | -| views_1x.py:36:29:36:65 | django.Response(...) | externally controlled string | -| views_1x.py:41:25:41:63 | django.Response(...) | externally controlled string | -| views_1x.py:45:25:45:70 | django.Response(...) | externally controlled string | -| views_1x.py:66:25:66:55 | django.Response(...) | externally controlled string | -| views_1x.py:75:25:75:33 | django.Response(...) | externally controlled string | -| views_1x.py:90:25:90:33 | django.Response(...) | externally controlled string | -| views_1x.py:94:25:94:58 | django.Response(...) | externally controlled string | -| views_1x.py:103:33:103:55 | django.Response(...) | externally controlled string | -| views_1x.py:107:25:107:47 | django.Response(...) | externally controlled string | -| views_2x_3x.py:8:25:8:63 | django.Response(...) | externally controlled string | -| views_2x_3x.py:12:25:12:52 | django.Response(...) | externally controlled string | -| views_2x_3x.py:16:25:16:53 | django.Response(...) | externally controlled string | -| views_2x_3x.py:21:15:21:42 | django.Response.write(...) | externally controlled string | -| views_2x_3x.py:30:29:30:60 | django.Response(...) | externally controlled string | -| views_2x_3x.py:36:29:36:65 | django.Response(...) | externally controlled string | -| views_2x_3x.py:41:25:41:63 | django.Response(...) | externally controlled string | -| views_2x_3x.py:45:25:45:70 | django.Response(...) | externally controlled string | -| views_2x_3x.py:66:25:66:40 | django.Response(...) | externally controlled string | -| views_2x_3x.py:79:25:79:61 | django.Response(...) | externally controlled string | -| views_2x_3x.py:82:25:82:69 | django.Response(...) | externally controlled string | -| views_2x_3x.py:85:25:85:64 | django.Response(...) | externally controlled string | -| views_2x_3x.py:88:25:88:32 | django.Response(...) | externally controlled string | -| views_2x_3x.py:111:25:111:33 | django.Response(...) | externally controlled string | -| views_2x_3x.py:115:25:115:58 | django.Response(...) | externally controlled string | -| views_2x_3x.py:124:33:124:55 | django.Response(...) | externally controlled string | -| views_2x_3x.py:128:25:128:47 | django.Response(...) | externally controlled string | diff --git a/python/ql/test/library-tests/web/django/HttpResponseSinks.ql b/python/ql/test/library-tests/web/django/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/django/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/django/HttpSources.expected b/python/ql/test/library-tests/web/django/HttpSources.expected deleted file mode 100644 index 2aa9c979334..00000000000 --- a/python/ql/test/library-tests/web/django/HttpSources.expected +++ /dev/null @@ -1,53 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| test_1x.py:6:19:6:25 | request | django.request.HttpRequest | -| test_1x.py:6:28:6:31 | path | externally controlled string | -| test_1x.py:12:19:12:25 | request | django.request.HttpRequest | -| test_1x.py:12:28:12:31 | path | externally controlled string | -| test_2x_3x.py:6:19:6:25 | request | django.request.HttpRequest | -| test_2x_3x.py:6:28:6:31 | path | externally controlled string | -| test_2x_3x.py:12:19:12:25 | request | django.request.HttpRequest | -| test_2x_3x.py:12:28:12:31 | path | externally controlled string | -| views_1x.py:7:19:7:25 | request | django.request.HttpRequest | -| views_1x.py:7:28:7:30 | foo | externally controlled string | -| views_1x.py:7:33:7:35 | bar | externally controlled string | -| views_1x.py:11:20:11:26 | request | django.request.HttpRequest | -| views_1x.py:15:21:15:27 | request | django.request.HttpRequest | -| views_1x.py:19:21:19:27 | request | django.request.HttpRequest | -| views_1x.py:29:20:29:26 | request | django.request.HttpRequest | -| views_1x.py:29:29:29:37 | untrusted | externally controlled string | -| views_1x.py:35:19:35:25 | request | django.request.HttpRequest | -| views_1x.py:35:28:35:36 | untrusted | externally controlled string | -| views_1x.py:39:19:39:25 | request | django.request.HttpRequest | -| views_1x.py:39:28:39:38 | page_number | externally controlled string | -| views_1x.py:44:24:44:30 | request | django.request.HttpRequest | -| views_1x.py:44:33:44:36 | arg0 | externally controlled string | -| views_1x.py:44:39:44:42 | arg1 | externally controlled string | -| views_1x.py:65:15:65:21 | request | django.request.HttpRequest | -| views_1x.py:65:24:65:31 | username | externally controlled string | -| views_1x.py:74:13:74:19 | request | django.request.HttpRequest | -| views_2x_3x.py:7:19:7:25 | request | django.request.HttpRequest | -| views_2x_3x.py:7:28:7:30 | foo | externally controlled string | -| views_2x_3x.py:7:33:7:35 | bar | externally controlled string | -| views_2x_3x.py:11:20:11:26 | request | django.request.HttpRequest | -| views_2x_3x.py:15:21:15:27 | request | django.request.HttpRequest | -| views_2x_3x.py:19:21:19:27 | request | django.request.HttpRequest | -| views_2x_3x.py:29:20:29:26 | request | django.request.HttpRequest | -| views_2x_3x.py:29:29:29:37 | untrusted | externally controlled string | -| views_2x_3x.py:35:19:35:25 | request | django.request.HttpRequest | -| views_2x_3x.py:35:28:35:36 | untrusted | externally controlled string | -| views_2x_3x.py:39:19:39:25 | request | django.request.HttpRequest | -| views_2x_3x.py:39:28:39:38 | page_number | externally controlled string | -| views_2x_3x.py:44:24:44:30 | request | django.request.HttpRequest | -| views_2x_3x.py:44:33:44:36 | arg0 | externally controlled string | -| views_2x_3x.py:44:39:44:42 | arg1 | externally controlled string | -| views_2x_3x.py:65:20:65:26 | request | django.request.HttpRequest | -| views_2x_3x.py:78:17:78:23 | request | django.request.HttpRequest | -| views_2x_3x.py:78:26:78:36 | page_number | externally controlled string | -| views_2x_3x.py:81:17:81:23 | request | django.request.HttpRequest | -| views_2x_3x.py:81:26:81:28 | foo | externally controlled string | -| views_2x_3x.py:81:31:81:33 | bar | externally controlled string | -| views_2x_3x.py:81:36:81:38 | baz | externally controlled string | -| views_2x_3x.py:84:17:84:23 | request | django.request.HttpRequest | -| views_2x_3x.py:84:26:84:28 | foo | externally controlled string | -| views_2x_3x.py:84:31:84:33 | bar | externally controlled string | -| views_2x_3x.py:87:26:87:32 | request | django.request.HttpRequest | diff --git a/python/ql/test/library-tests/web/django/HttpSources.ql b/python/ql/test/library-tests/web/django/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/django/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/django/SqlInjectionSinks.expected b/python/ql/test/library-tests/web/django/SqlInjectionSinks.expected deleted file mode 100644 index d9850f2f7c6..00000000000 --- a/python/ql/test/library-tests/web/django/SqlInjectionSinks.expected +++ /dev/null @@ -1,9 +0,0 @@ -| sql.py:13:24:13:64 | db.connection.execute | externally controlled string | -| sql.py:14:26:14:66 | django.models.QuerySet.raw(sink,...) | externally controlled string | -| sql.py:17:24:17:77 | db.connection.execute | externally controlled string | -| sql.py:20:38:20:95 | django.db.models.expressions.RawSQL(sink,...) | externally controlled string | -| sql.py:21:26:21:83 | django.models.QuerySet.raw(sink,...) | externally controlled string | -| sql.py:22:28:22:85 | django.models.QuerySet.extra(sink,...) | externally controlled string | -| sql.py:36:26:36:68 | django.models.QuerySet.raw(sink,...) | externally controlled string | -| sql.py:42:11:42:52 | django.models.QuerySet.raw(sink,...) | externally controlled string | -| sql.py:47:13:47:54 | django.models.QuerySet.extra(sink,...) | externally controlled string | diff --git a/python/ql/test/library-tests/web/django/SqlInjectionSinks.ql b/python/ql/test/library-tests/web/django/SqlInjectionSinks.ql deleted file mode 100644 index b12dd8ea041..00000000000 --- a/python/ql/test/library-tests/web/django/SqlInjectionSinks.ql +++ /dev/null @@ -1,8 +0,0 @@ -import python -import semmle.python.security.injection.Sql -import semmle.python.web.django.Db -import semmle.python.web.django.Model - -from SqlInjectionSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/django/options b/python/ql/test/library-tests/web/django/options deleted file mode 100644 index a87f995c396..00000000000 --- a/python/ql/test/library-tests/web/django/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --lang=3 --max-import-depth=3 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/django/sql.py b/python/ql/test/library-tests/web/django/sql.py deleted file mode 100644 index 7809c24edc1..00000000000 --- a/python/ql/test/library-tests/web/django/sql.py +++ /dev/null @@ -1,53 +0,0 @@ -from django.db import connection, models -from django.db.models.expressions import RawSQL - - -class User(models.Model): - username = models.CharField(max_length=100) - description = models.TextField(blank=True) - - -def show_user(username): - with connection.cursor() as cursor: - # GOOD -- Using parameters - cursor.execute("SELECT * FROM users WHERE username = %s", username) - User.objects.raw("SELECT * FROM users WHERE username = %s", (username,)) - - # BAD -- Using string formatting - cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) - - # BAD -- other ways of executing raw SQL code with string interpolation - User.objects.annotate(RawSQL("insert into names_file ('name') values ('%s')" % username)) - User.objects.raw("insert into names_file ('name') values ('%s')" % username) - User.objects.extra("insert into names_file ('name') values ('%s')" % username) - - # BAD (but currently no custom query to find this) - # - # It is exposed to SQL injection (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#extra) - # For example, using name = "; DROP ALL TABLES -- " - # will result in SQL: SELECT * FROM name WHERE name = ''; DROP ALL TABLES -- '' - # - # This shouldn't be very widespread, since using a normal string will result in invalid SQL - # Using name = "example", will result in SQL: SELECT * FROM name WHERE name = ''example'' - # which in MySQL will give a syntax error - # - # When testing this out locally, none of the queries worked against SQLite3, but I could use - # the SQL injection against MySQL. - User.objects.raw("SELECT * FROM users WHERE username = '%s'", (username,)) - - -def raw3(arg): - m = User.objects.filter('foo') - m = m.filter('bar') - m.raw("select foo from bar where baz = %s" % arg) - - -def raw4(arg): - m = User.objects.filter('foo') - m.extra("select foo from bar where baz = %s" % arg) - - -def update_user(key, description1): - # Neither of these are exposed to sql-injections - user = User.objects.get(pk=key) - item.description = description diff --git a/python/ql/test/library-tests/web/django/test_1x.py b/python/ql/test/library-tests/web/django/test_1x.py deleted file mode 100644 index ce15a5e71bf..00000000000 --- a/python/ql/test/library-tests/web/django/test_1x.py +++ /dev/null @@ -1,19 +0,0 @@ -"""tests for Django 1.x""" -from django.conf.urls import url -from django.shortcuts import redirect, render - - -def with_template(request, path='default'): - env = {'path': path} - # We would need to understand django templates to know if this is safe or not - return render(request, 'possibly-vulnerable-template.html', env) - - -def vuln_redirect(request, path): - return redirect(path) - - -urlpatterns = [ - url(r'^(?P<path>.*)$', with_template), - url(r'^redirect/(?P<path>.*)$', vuln_redirect), -] diff --git a/python/ql/test/library-tests/web/django/test_2x_3x.py b/python/ql/test/library-tests/web/django/test_2x_3x.py deleted file mode 100644 index da08a80c27c..00000000000 --- a/python/ql/test/library-tests/web/django/test_2x_3x.py +++ /dev/null @@ -1,19 +0,0 @@ -"""tests for Django 2.x and 3.x""" -from django.urls import path -from django.shortcuts import redirect, render - - -def with_template(request, path='default'): - env = {'path': path} - # We would need to understand django templates to know if this is safe or not - return render(request, 'possibly-vulnerable-template.html', env) - - -def vuln_redirect(request, path): - return redirect(path) - - -urlpatterns = [ - path('/<path>', with_template), - path('/redirect/<path>', vuln_redirect), -] diff --git a/python/ql/test/library-tests/web/django/views_1x.py b/python/ql/test/library-tests/web/django/views_1x.py deleted file mode 100644 index f5476a13cef..00000000000 --- a/python/ql/test/library-tests/web/django/views_1x.py +++ /dev/null @@ -1,107 +0,0 @@ -"""test of views for Django 1.x""" -from django.conf.urls import patterns, url -from django.http.response import HttpResponse, HttpResponseRedirect, JsonResponse, HttpResponseNotFound -from django.views.generic import View - - -def url_match_xss(request, foo, bar, no_taint=None): - return HttpResponse('url_match_xss: {} {}'.format(foo, bar)) - - -def get_params_xss(request): - return HttpResponse(request.GET.get("untrusted")) - - -def post_params_xss(request): - return HttpResponse(request.POST.get("untrusted")) - - -def http_resp_write(request): - rsp = HttpResponse() - rsp.write(request.GET.get("untrusted")) - return rsp - - -class Foo(object): - # Note: since Foo is used as the super type in a class view, it will be able to handle requests. - - - def post(self, request, untrusted): - return HttpResponse('Foo post: {}'.format(untrusted)) - - -class ClassView(View, Foo): - - def get(self, request, untrusted): - return HttpResponse('ClassView get: {}'.format(untrusted)) - - -def show_articles(request, page_number=1): - page_number = int(page_number) - return HttpResponse('articles page: {}'.format(page_number)) - - -def xxs_positional_arg(request, arg0, arg1, no_taint=None): - return HttpResponse('xxs_positional_arg: {} {}'.format(arg0, arg1)) - - -urlpatterns = [ - url(r'^url_match/(?P<foo>[^/]+)/(?P<bar>[^/]+)$', url_match_xss), - url(r'^get_params$', get_params_xss), - url(r'^post_params$', post_params_xss), - url(r'^http_resp_write$', http_resp_write), - url(r'^class_view/(?P<untrusted>.+)$', ClassView.as_view()), - - # one pattern to support `articles/page-<n>` and ensuring that articles/ goes to page-1 - url(r'articles/^(?:page-(?P<page_number>\d+)/)?$', show_articles), - # passing as positional argument is not the recommended way of doing things, but it is certainly - # possible - url(r'^([^/]+)/(?:foo|bar)/([^/]+)$', xxs_positional_arg, name='xxs_positional_arg'), -] - -################################################################################ -# Using patterns() for routing - -def show_user(request, username): - return HttpResponse('show_user {}'.format(username)) - - -urlpatterns = patterns(url(r'^users/(?P<username>[^/]+)$', show_user)) - -################################################################################ -# Show we understand the keyword arguments to django.conf.urls.url - -def kw_args(request): - return HttpResponse('kw_args') - -urlpatterns = [ - url(view=kw_args, regex=r'^kw_args$') -] - -# Not an XSS sink, since the Content-Type is not "text/html" -# FP reported in https://github.com/github/codeql-python-team/issues/38 -def fp_json_response(request): - # implicitly sets Content-Type to "application/json" - return JsonResponse({"foo": request.GET.get("foo")}) - -# Not an XSS sink, since the Content-Type is not "text/html" -def fp_manual_json_response(request): - json_data = '{"json": "{}"}'.format(request.GET.get("foo")) - return HttpResponse(json_data, content_type="application/json") - -# Not an XSS sink, since the Content-Type is not "text/html" -def fp_manual_content_type(reuqest): - return HttpResponse('<img src="0" onerror="alert(1)">', content_type="text/plain") - -# XSS FP reported in https://github.com/github/codeql/issues/3466 -# Note: This should be a open-redirect sink, but not a XSS sink. -def fp_redirect(request): - return HttpResponseRedirect(request.GET.get("next")) - -# Ensure that simple subclasses are still vuln to XSS -def tp_not_found(request): - return HttpResponseNotFound(request.GET.get("name")) - -# Ensure we still have a XSS sink when manually setting the content_type to HTML -def tp_manual_response_type(request): - return HttpResponse(request.GET.get("name"), content_type="text/html; charset=utf-8") diff --git a/python/ql/test/library-tests/web/django/views_2x_3x.py b/python/ql/test/library-tests/web/django/views_2x_3x.py deleted file mode 100644 index d61792004e9..00000000000 --- a/python/ql/test/library-tests/web/django/views_2x_3x.py +++ /dev/null @@ -1,128 +0,0 @@ -"""testing views for Django 2.x and 3.x""" -from django.urls import path, re_path -from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, HttpResponseNotFound -from django.views import View - - -def url_match_xss(request, foo, bar, no_taint=None): - return HttpResponse('url_match_xss: {} {}'.format(foo, bar)) - - -def get_params_xss(request): - return HttpResponse(request.GET.get("untrusted")) - - -def post_params_xss(request): - return HttpResponse(request.POST.get("untrusted")) - - -def http_resp_write(request): - rsp = HttpResponse() - rsp.write(request.GET.get("untrusted")) - return rsp - - -class Foo(object): - # Note: since Foo is used as the super type in a class view, it will be able to handle requests. - - - def post(self, request, untrusted): - return HttpResponse('Foo post: {}'.format(untrusted)) - - -class ClassView(View, Foo): - - def get(self, request, untrusted): - return HttpResponse('ClassView get: {}'.format(untrusted)) - - -def show_articles(request, page_number=1): - page_number = int(page_number) - return HttpResponse('articles page: {}'.format(page_number)) - - -def xxs_positional_arg(request, arg0, arg1, no_taint=None): - return HttpResponse('xxs_positional_arg: {} {}'.format(arg0, arg1)) - - -urlpatterns = [ - re_path(r'^url_match/(?P<foo>[^/]+)/(?P<bar>[^/]+)$', url_match_xss), - re_path(r'^get_params$', get_params_xss), - re_path(r'^post_params$', post_params_xss), - re_path(r'^http_resp_write$', http_resp_write), - re_path(r'^class_view/(?P<untrusted>.+)$', ClassView.as_view()), - - # one pattern to support `articles/page-<n>` and ensuring that articles/ goes to page-1 - re_path(r'articles/^(?:page-(?P<page_number>\d+)/)?$', show_articles), - # passing as positional argument is not the recommended way of doing things, but it is certainly - # possible - re_path(r'^([^/]+)/(?:foo|bar)/([^/]+)$', xxs_positional_arg, name='xxs_positional_arg'), -] - - -# Show we understand the keyword arguments to from django.urls.re_path - -def re_path_kwargs(request): - return HttpResponse('re_path_kwargs') - - -urlpatterns = [ - re_path(view=re_path_kwargs, route=r'^specifying-as-kwargs-is-not-a-problem$') -] - -################################################################################ -# Using path -################################################################################ - -# saying page_number is an externally controlled *string* is a bit strange, when we have an int converter :O -def page_number(request, page_number=1): - return HttpResponse('page_number: {}'.format(page_number)) - -def foo_bar_baz(request, foo, bar, baz): - return HttpResponse('foo_bar_baz: {} {} {}'.format(foo, bar, baz)) - -def path_kwargs(request, foo, bar): - return HttpResponse('path_kwargs: {} {} {}'.format(foo, bar)) - -def not_valid_identifier(request): - return HttpResponse('<foo!>') - -urlpatterns = [ - path('articles/', page_number), - path('articles/page-<int:page_number>', page_number), - path('<int:foo>/<str:bar>/<baz>', foo_bar_baz, name='foo-bar-baz'), - - path(view=path_kwargs, route='<foo>/<bar>'), - - # We should not report there is a request parameter called `not_valid!` - path('not_valid/<not_valid!>', not_valid_identifier), -] - - -# Not an XSS sink, since the Content-Type is not "text/html" -# FP reported in https://github.com/github/codeql-python-team/issues/38 -def fp_json_response(request): - # implicitly sets Content-Type to "application/json" - return JsonResponse({"foo": request.GET.get("foo")}) - -# Not an XSS sink, since the Content-Type is not "text/html" -def fp_manual_json_response(request): - json_data = '{"json": "{}"}'.format(request.GET.get("foo")) - return HttpResponse(json_data, content_type="application/json") - -# Not an XSS sink, since the Content-Type is not "text/html" -def fp_manual_content_type(reuqest): - return HttpResponse('<img src="0" onerror="alert(1)">', content_type="text/plain") - -# XSS FP reported in https://github.com/github/codeql/issues/3466 -# Note: This should be a open-redirect sink, but not a XSS sink. -def fp_redirect(request): - return HttpResponseRedirect(request.GET.get("next")) - -# Ensure that simple subclasses are still vuln to XSS -def tp_not_found(request): - return HttpResponseNotFound(request.GET.get("name")) - -# Ensure we still have a XSS sink when manually setting the content_type to HTML -def tp_manual_response_type(request): - return HttpResponse(request.GET.get("name"), content_type="text/html; charset=utf-8") diff --git a/python/ql/test/library-tests/web/falcon/HttpResponseSinks.expected b/python/ql/test/library-tests/web/falcon/HttpResponseSinks.expected deleted file mode 100644 index 76fe8773866..00000000000 --- a/python/ql/test/library-tests/web/falcon/HttpResponseSinks.expected +++ /dev/null @@ -1 +0,0 @@ -| FIXME: temporarily disabled since it's not working | diff --git a/python/ql/test/library-tests/web/falcon/HttpResponseSinks.ql b/python/ql/test/library-tests/web/falcon/HttpResponseSinks.ql deleted file mode 100644 index eec9b1ef3cf..00000000000 --- a/python/ql/test/library-tests/web/falcon/HttpResponseSinks.ql +++ /dev/null @@ -1,8 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -// from HttpResponseTaintSink sink, TaintKind kind -// where sink.sinks(kind) -// select sink, kind -select "FIXME: temporarily disabled since it's not working" diff --git a/python/ql/test/library-tests/web/falcon/HttpSources.expected b/python/ql/test/library-tests/web/falcon/HttpSources.expected deleted file mode 100644 index 3cc29f418ab..00000000000 --- a/python/ql/test/library-tests/web/falcon/HttpSources.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| test.py:9:22:9:24 | req | falcon.request | -| test.py:19:23:19:25 | req | falcon.request | -| test.py:22:25:22:27 | req | falcon.request | diff --git a/python/ql/test/library-tests/web/falcon/HttpSources.ql b/python/ql/test/library-tests/web/falcon/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/falcon/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/falcon/Routing.expected b/python/ql/test/library-tests/web/falcon/Routing.expected deleted file mode 100644 index 47bcb473273..00000000000 --- a/python/ql/test/library-tests/web/falcon/Routing.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type FalconRoute has been deprecated and may be removed in future (Routing.ql:4,6-17) -| /hello | delete | test.py:22:5:22:35 | Function on_delete | -| /hello | get | test.py:9:5:9:32 | Function on_get | -| /hello | post | test.py:19:5:19:33 | Function on_post | diff --git a/python/ql/test/library-tests/web/falcon/Routing.ql b/python/ql/test/library-tests/web/falcon/Routing.ql deleted file mode 100644 index fde6c933b65..00000000000 --- a/python/ql/test/library-tests/web/falcon/Routing.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import semmle.python.web.falcon.General - -from FalconRoute route, string method -select route.getUrl(), method, route.getHandlerFunction(method) diff --git a/python/ql/test/library-tests/web/falcon/Sinks.expected b/python/ql/test/library-tests/web/falcon/Sinks.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/python/ql/test/library-tests/web/falcon/Sinks.ql b/python/ql/test/library-tests/web/falcon/Sinks.ql deleted file mode 100644 index efaafe17f02..00000000000 --- a/python/ql/test/library-tests/web/falcon/Sinks.ql +++ /dev/null @@ -1,8 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from TaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink.getLocation().toString(), sink.(ControlFlowNode).getNode().toString(), kind diff --git a/python/ql/test/library-tests/web/falcon/Taint.expected b/python/ql/test/library-tests/web/falcon/Taint.expected deleted file mode 100644 index f1e7abb4f0d..00000000000 --- a/python/ql/test/library-tests/web/falcon/Taint.expected +++ /dev/null @@ -1,20 +0,0 @@ -| test.py:9 | req | falcon.request | -| test.py:9 | resp | falcon.response | -| test.py:10 | Attribute | file[externally controlled string] | -| test.py:10 | Attribute() | externally controlled string | -| test.py:10 | req | falcon.request | -| test.py:11 | Attribute() | json[externally controlled string] | -| test.py:11 | raw_json | externally controlled string | -| test.py:12 | resp | falcon.response | -| test.py:13 | Dict | {json[externally controlled string]} | -| test.py:15 | result | json[externally controlled string] | -| test.py:17 | result | {json[externally controlled string]} | -| test.py:19 | req | falcon.request | -| test.py:19 | resp | falcon.response | -| test.py:22 | req | falcon.request | -| test.py:22 | resp | falcon.response | -| test.py:23 | Attribute | wsgi.environment | -| test.py:23 | req | falcon.request | -| test.py:24 | Subscript | externally controlled string | -| test.py:24 | env | wsgi.environment | -| test.py:25 | qs | externally controlled string | diff --git a/python/ql/test/library-tests/web/falcon/Taint.ql b/python/ql/test/library-tests/web/falcon/Taint.ql deleted file mode 100644 index d68b12079b8..00000000000 --- a/python/ql/test/library-tests/web/falcon/Taint.ql +++ /dev/null @@ -1,8 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from TaintedNode node -where node.getLocation().getFile().getShortName() = "test.py" -select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind() diff --git a/python/ql/test/library-tests/web/falcon/options b/python/ql/test/library-tests/web/falcon/options deleted file mode 100644 index 7fb713d5924..00000000000 --- a/python/ql/test/library-tests/web/falcon/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/falcon/test.py b/python/ql/test/library-tests/web/falcon/test.py deleted file mode 100644 index 72853c94ad0..00000000000 --- a/python/ql/test/library-tests/web/falcon/test.py +++ /dev/null @@ -1,28 +0,0 @@ -import json - -from falcon import API - -app = API() - -class Handler(object): - - def on_get(self, req, resp): - raw_json = req.stream.read() - result = json.loads(raw_json) - resp.status = 200 - result = { - 'status': 'success', - 'data': result - } - resp.body = json.dumps(result) - - def on_post(self, req, resp): - pass - - def on_delete(self, req, resp): - env = req.env - qs = env["QUERY_STRING"] - return qs - -app.add_route('/hello', Handler()) - diff --git a/python/ql/test/library-tests/web/flask/HttpResponseSinks.expected b/python/ql/test/library-tests/web/flask/HttpResponseSinks.expected deleted file mode 100644 index e860c6f2f87..00000000000 --- a/python/ql/test/library-tests/web/flask/HttpResponseSinks.expected +++ /dev/null @@ -1,17 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| test.py:8:12:8:25 | flask.routed.response | externally controlled string | -| test.py:29:12:29:38 | flask.routed.response | externally controlled string | -| test.py:35:16:35:37 | flask.routed.response | externally controlled string | -| test.py:36:12:36:15 | flask.routed.response | externally controlled string | -| test.py:41:12:41:54 | flask.routed.response | externally controlled string | -| test.py:41:26:41:53 | flask.response.argument | externally controlled string | -| test.py:46:12:46:62 | flask.routed.response | externally controlled string | -| test.py:46:26:46:61 | flask.response.argument | externally controlled string | -| test.py:50:12:50:48 | flask.routed.response | externally controlled string | -| test.py:50:26:50:47 | flask.response.argument | externally controlled string | -| test.py:54:12:54:53 | flask.routed.response | externally controlled string | -| test.py:54:26:54:52 | flask.response.argument | externally controlled string | -| test.py:60:12:60:62 | flask.routed.response | externally controlled string | -| test.py:60:26:60:61 | flask.response.argument | externally controlled string | -| test.py:64:12:64:58 | flask.routed.response | externally controlled string | -| test.py:64:26:64:57 | flask.response.argument | externally controlled string | diff --git a/python/ql/test/library-tests/web/flask/HttpResponseSinks.ql b/python/ql/test/library-tests/web/flask/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/flask/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/flask/HttpSources.expected b/python/ql/test/library-tests/web/flask/HttpSources.expected deleted file mode 100644 index e313f9bf1c2..00000000000 --- a/python/ql/test/library-tests/web/flask/HttpSources.expected +++ /dev/null @@ -1,10 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| test.py:29:12:29:23 | Attribute | {externally controlled string} | -| test.py:33:9:33:20 | Attribute | {externally controlled string} | -| test.py:35:16:35:27 | Attribute | {externally controlled string} | -| test.py:40:18:40:29 | Attribute | {externally controlled string} | -| test.py:45:18:45:29 | Attribute | {externally controlled string} | -| test.py:49:11:49:14 | name | externally controlled string | -| test.py:53:9:53:15 | subpath | externally controlled string | -| test.py:59:24:59:26 | bar | externally controlled string | -| test.py:63:13:63:21 | lang_code | externally controlled string | diff --git a/python/ql/test/library-tests/web/flask/HttpSources.ql b/python/ql/test/library-tests/web/flask/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/flask/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/flask/Routing.expected b/python/ql/test/library-tests/web/flask/Routing.expected deleted file mode 100644 index 90e70bcee8a..00000000000 --- a/python/ql/test/library-tests/web/flask/Routing.expected +++ /dev/null @@ -1,11 +0,0 @@ -WARNING: Predicate flask_routing has been deprecated and may be removed in future (Routing.ql:5,7-20) -| / | Function hello_world | -| /complex/<string(length=2):lang_code> | Function complex | -| /dangerous | Function dangerous | -| /dangerous-with-cfg-split | Function dangerous2 | -| /foo/<path:subpath> | Function foo | -| /hello/<name> | Function hello | -| /multiple/bar/<bar> | Function multiple | -| /safe | Function safe | -| /the/ | Function get | -| /unsafe | Function unsafe | diff --git a/python/ql/test/library-tests/web/flask/Routing.ql b/python/ql/test/library-tests/web/flask/Routing.ql deleted file mode 100644 index 92ae6740f0d..00000000000 --- a/python/ql/test/library-tests/web/flask/Routing.ql +++ /dev/null @@ -1,6 +0,0 @@ -import python -import semmle.python.web.flask.General - -from ControlFlowNode regex, Function func -where flask_routing(regex, func) -select regex.getNode().(StrConst).getText(), func.toString() diff --git a/python/ql/test/library-tests/web/flask/Taint.expected b/python/ql/test/library-tests/web/flask/Taint.expected deleted file mode 100644 index 48562648096..00000000000 --- a/python/ql/test/library-tests/web/flask/Taint.expected +++ /dev/null @@ -1,33 +0,0 @@ -| test.py:22 | Attribute() | flask/MyView.as.view | -| test.py:25 | the_view | flask/MyView.as.view | -| test.py:29 | Attribute | {externally controlled string} | -| test.py:29 | Attribute() | externally controlled string | -| test.py:33 | Attribute | {externally controlled string} | -| test.py:33 | Subscript | externally controlled string | -| test.py:35 | Attribute | {externally controlled string} | -| test.py:35 | Subscript | externally controlled string | -| test.py:40 | Attribute | {externally controlled string} | -| test.py:40 | Attribute() | externally controlled string | -| test.py:41 | BinaryExpr | externally controlled string | -| test.py:41 | first_name | externally controlled string | -| test.py:41 | make_response() | flask.Response | -| test.py:45 | Attribute | {externally controlled string} | -| test.py:45 | Attribute() | externally controlled string | -| test.py:46 | first_name | externally controlled string | -| test.py:46 | make_response() | flask.Response | -| test.py:49 | name | externally controlled string | -| test.py:50 | BinaryExpr | externally controlled string | -| test.py:50 | make_response() | flask.Response | -| test.py:50 | name | externally controlled string | -| test.py:53 | subpath | externally controlled string | -| test.py:54 | BinaryExpr | externally controlled string | -| test.py:54 | make_response() | flask.Response | -| test.py:54 | subpath | externally controlled string | -| test.py:59 | bar | externally controlled string | -| test.py:60 | Attribute() | externally controlled string | -| test.py:60 | bar | externally controlled string | -| test.py:60 | make_response() | flask.Response | -| test.py:63 | lang_code | externally controlled string | -| test.py:64 | Attribute() | externally controlled string | -| test.py:64 | lang_code | externally controlled string | -| test.py:64 | make_response() | flask.Response | diff --git a/python/ql/test/library-tests/web/flask/Taint.ql b/python/ql/test/library-tests/web/flask/Taint.ql deleted file mode 100644 index d68b12079b8..00000000000 --- a/python/ql/test/library-tests/web/flask/Taint.ql +++ /dev/null @@ -1,8 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from TaintedNode node -where node.getLocation().getFile().getShortName() = "test.py" -select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind() diff --git a/python/ql/test/library-tests/web/flask/options b/python/ql/test/library-tests/web/flask/options deleted file mode 100644 index 7fb713d5924..00000000000 --- a/python/ql/test/library-tests/web/flask/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/flask/test.py b/python/ql/test/library-tests/web/flask/test.py deleted file mode 100644 index bedeaa56423..00000000000 --- a/python/ql/test/library-tests/web/flask/test.py +++ /dev/null @@ -1,67 +0,0 @@ -import flask - -from flask import Flask, request, make_response -app = Flask(__name__) - -@app.route("/") -def hello_world(): - return "Hello World!" - -from flask.views import MethodView - -class MyView(MethodView): - - def get(self, user_id): - if user_id is None: - # return a list of users - pass - else: - # expose a single user - pass - -the_view = MyView.as_view('my_view') - -app.add_url_rule('/the/', defaults={'user_id': None}, - view_func=the_view, methods=['GET',]) - -@app.route("/dangerous") -def dangerous(): - return request.args.get('payload') - -@app.route("/dangerous-with-cfg-split") -def dangerous2(): - x = request.form['param0'] - if request.method == "POST": - return request.form['param1'] - return None - -@app.route('/unsafe') -def unsafe(): - first_name = request.args.get('name', '') - return make_response("Your name is " + first_name) - -@app.route('/safe') -def safe(): - first_name = request.args.get('name', '') - return make_response("Your name is " + escape(first_name)) - -@app.route('/hello/<name>') -def hello(name): - return make_response("Your name is " + name) - -@app.route('/foo/<path:subpath>') -def foo(subpath): - return make_response("The subpath is " + subpath) - -@app.route('/multiple/') # TODO: not recognized as route -@app.route('/multiple/foo/<foo>') # TODO: not recognized as route -@app.route('/multiple/bar/<bar>') -def multiple(foo=None, bar=None): - return make_response("foo={!r} bar={!r}".format(foo, bar)) - -@app.route('/complex/<string(length=2):lang_code>') -def complex(lang_code): - return make_response("lang_code {}".format(lang_code)) - -if __name__ == "__main__": - app.run(debug=True) diff --git a/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.expected b/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.expected deleted file mode 100644 index 959217e0acd..00000000000 --- a/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| test.py:8:12:8:31 | pyramid.routed.response | externally controlled string | -| test.py:17:12:17:41 | pyramid.routed.response | externally controlled string | -| test.py:25:12:25:43 | pyramid.routed.response | externally controlled string | diff --git a/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.ql b/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/pyramid/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/pyramid/HttpSources.expected b/python/ql/test/library-tests/web/pyramid/HttpSources.expected deleted file mode 100644 index 23f8ab8e3ab..00000000000 --- a/python/ql/test/library-tests/web/pyramid/HttpSources.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| test.py:7:10:7:16 | request | pyramid.request | -| test.py:15:11:15:17 | request | pyramid.request | -| test.py:24:11:24:17 | request | pyramid.request | diff --git a/python/ql/test/library-tests/web/pyramid/HttpSources.ql b/python/ql/test/library-tests/web/pyramid/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/pyramid/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/pyramid/Routing.expected b/python/ql/test/library-tests/web/pyramid/Routing.expected deleted file mode 100644 index 41e66136a68..00000000000 --- a/python/ql/test/library-tests/web/pyramid/Routing.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Predicate is_pyramid_view_function has been deprecated and may be removed in future (Routing.ql:5,7-31) -| test.py:7 | Function home | -| test.py:15 | Function greet | -| test.py:24 | Function stuff | diff --git a/python/ql/test/library-tests/web/pyramid/Routing.ql b/python/ql/test/library-tests/web/pyramid/Routing.ql deleted file mode 100644 index 4a442c1115e..00000000000 --- a/python/ql/test/library-tests/web/pyramid/Routing.ql +++ /dev/null @@ -1,6 +0,0 @@ -import python -import semmle.python.web.pyramid.View - -from Function func -where is_pyramid_view_function(func) -select func.getLocation().toString(), func.toString() diff --git a/python/ql/test/library-tests/web/pyramid/Taint.expected b/python/ql/test/library-tests/web/pyramid/Taint.expected deleted file mode 100644 index 94b8f844efb..00000000000 --- a/python/ql/test/library-tests/web/pyramid/Taint.expected +++ /dev/null @@ -1,11 +0,0 @@ -| test.py:7 | request | pyramid.request | -| test.py:15 | request | pyramid.request | -| test.py:16 | Attribute | {externally controlled string} | -| test.py:16 | Subscript | externally controlled string | -| test.py:16 | request | pyramid.request | -| test.py:17 | BinaryExpr | externally controlled string | -| test.py:17 | name | externally controlled string | -| test.py:24 | request | pyramid.request | -| test.py:25 | Attribute | externally controlled string | -| test.py:25 | Dict | {externally controlled string} | -| test.py:25 | request | pyramid.request | diff --git a/python/ql/test/library-tests/web/pyramid/Taint.ql b/python/ql/test/library-tests/web/pyramid/Taint.ql deleted file mode 100644 index d68b12079b8..00000000000 --- a/python/ql/test/library-tests/web/pyramid/Taint.ql +++ /dev/null @@ -1,8 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from TaintedNode node -where node.getLocation().getFile().getShortName() = "test.py" -select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind() diff --git a/python/ql/test/library-tests/web/pyramid/options b/python/ql/test/library-tests/web/pyramid/options deleted file mode 100644 index 1d132442a3b..00000000000 --- a/python/ql/test/library-tests/web/pyramid/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/pyramid/test.py b/python/ql/test/library-tests/web/pyramid/test.py deleted file mode 100644 index 9fad8a7ba00..00000000000 --- a/python/ql/test/library-tests/web/pyramid/test.py +++ /dev/null @@ -1,25 +0,0 @@ -from pyramid.view import view_config -from pyramid.response import Response - -@view_config( - route_name='home' -) -def home(request): - return Response('Welcome!') - - -@view_config( - route_name='greet', - request_method='POST' -) -def greet(request): - name = request.POST['arg'] - return Response('Welcome %s!' % name) - - -@view_config( - route_name='stuff', - renderer='json' -) -def stuff(request): - return {"err": 0, "body": request.body} diff --git a/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.expected b/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.expected deleted file mode 100644 index c4344d158b7..00000000000 --- a/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.expected +++ /dev/null @@ -1,3 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| test.py:72:26:72:58 | Taint sink | externally controlled string | -| test.py:73:31:73:54 | Taint sink | [externally controlled string] | diff --git a/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.ql b/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/stdlib/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/stdlib/HttpSources.expected b/python/ql/test/library-tests/web/stdlib/HttpSources.expected deleted file mode 100644 index e979c63fd84..00000000000 --- a/python/ql/test/library-tests/web/stdlib/HttpSources.expected +++ /dev/null @@ -1,35 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| test.py:18:13:18:16 | self | BaseHTTPRequestHandlerKind | -| test.py:20:13:20:16 | self | BaseHTTPRequestHandlerKind | -| test.py:22:13:22:16 | self | BaseHTTPRequestHandlerKind | -| test.py:24:13:24:16 | self | BaseHTTPRequestHandlerKind | -| test.py:25:13:25:16 | self | BaseHTTPRequestHandlerKind | -| test.py:26:13:26:16 | self | BaseHTTPRequestHandlerKind | -| test.py:27:13:27:16 | self | BaseHTTPRequestHandlerKind | -| test.py:28:13:28:16 | self | BaseHTTPRequestHandlerKind | -| test.py:29:13:29:16 | self | BaseHTTPRequestHandlerKind | -| test.py:30:13:30:16 | self | BaseHTTPRequestHandlerKind | -| test.py:31:13:31:16 | self | BaseHTTPRequestHandlerKind | -| test.py:32:13:32:16 | self | BaseHTTPRequestHandlerKind | -| test.py:33:17:33:20 | self | BaseHTTPRequestHandlerKind | -| test.py:34:19:34:22 | self | BaseHTTPRequestHandlerKind | -| test.py:36:13:36:16 | self | BaseHTTPRequestHandlerKind | -| test.py:37:13:37:16 | self | BaseHTTPRequestHandlerKind | -| test.py:40:16:44:9 | Attribute() | CgiFieldStorageFormKind | -| test.py:41:13:41:16 | self | BaseHTTPRequestHandlerKind | -| test.py:42:13:42:16 | self | BaseHTTPRequestHandlerKind | -| test.py:43:64:43:67 | self | BaseHTTPRequestHandlerKind | -| test.py:69:9:69:12 | self | BaseHTTPRequestHandlerKind | -| test.py:70:9:70:12 | self | BaseHTTPRequestHandlerKind | -| test.py:71:9:71:12 | self | BaseHTTPRequestHandlerKind | -| test.py:72:9:72:12 | self | BaseHTTPRequestHandlerKind | -| test.py:73:9:73:12 | self | BaseHTTPRequestHandlerKind | -| test.py:74:15:74:18 | self | BaseHTTPRequestHandlerKind | -| test.py:78:16:82:9 | Attribute() | CgiFieldStorageFormKind | -| test.py:79:13:79:16 | self | BaseHTTPRequestHandlerKind | -| test.py:80:13:80:16 | self | BaseHTTPRequestHandlerKind | -| test.py:81:64:81:67 | self | BaseHTTPRequestHandlerKind | -| test.py:85:13:85:16 | self | BaseHTTPRequestHandlerKind | -| test.py:86:13:86:16 | self | BaseHTTPRequestHandlerKind | -| test.py:96:9:96:12 | self | BaseHTTPRequestHandlerKind | -| test.py:97:9:97:12 | self | BaseHTTPRequestHandlerKind | diff --git a/python/ql/test/library-tests/web/stdlib/HttpSources.ql b/python/ql/test/library-tests/web/stdlib/HttpSources.ql deleted file mode 100644 index f4e9a1b48d3..00000000000 --- a/python/ql/test/library-tests/web/stdlib/HttpSources.ql +++ /dev/null @@ -1,9 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where - source.isSourceOf(kind) and - source.getLocation().getFile().getShortName() != "cgi.py" -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/stdlib/TestTaint.expected b/python/ql/test/library-tests/web/stdlib/TestTaint.expected deleted file mode 100644 index eba1bff195a..00000000000 --- a/python/ql/test/library-tests/web/stdlib/TestTaint.expected +++ /dev/null @@ -1,32 +0,0 @@ -| test.py:18 | ok | taint_sources | self | BaseHTTPRequestHandlerKind | -| test.py:20 | ok | taint_sources | Attribute | externally controlled string | -| test.py:22 | ok | taint_sources | Attribute | externally controlled string | -| test.py:24 | ok | taint_sources | Attribute | {externally controlled string} | -| test.py:25 | ok | taint_sources | Subscript | externally controlled string | -| test.py:26 | ok | taint_sources | Attribute() | externally controlled string | -| test.py:27 | ok | taint_sources | Attribute() | [externally controlled string] | -| test.py:28 | fail | taint_sources | Attribute() | <NO TAINT> | -| test.py:29 | ok | taint_sources | Attribute() | [externally controlled string] | -| test.py:30 | fail | taint_sources | Attribute() | <NO TAINT> | -| test.py:31 | ok | taint_sources | Attribute() | externally controlled string | -| test.py:32 | ok | taint_sources | Attribute() | externally controlled string | -| test.py:33 | ok | taint_sources | str() | externally controlled string | -| test.py:34 | ok | taint_sources | bytes() | externally controlled string | -| test.py:36 | ok | taint_sources | Attribute | file[externally controlled string] | -| test.py:37 | ok | taint_sources | Attribute() | externally controlled string | -| test.py:47 | ok | taint_sources | form | CgiFieldStorageFormKind | -| test.py:49 | ok | taint_sources | Subscript | CgiFieldStorageFieldKind | -| test.py:49 | ok | taint_sources | Subscript | [CgiFieldStorageFieldKind] | -| test.py:50 | ok | taint_sources | Attribute | externally controlled string | -| test.py:51 | ok | taint_sources | Attribute | file[externally controlled string] | -| test.py:52 | ok | taint_sources | Attribute | externally controlled string | -| test.py:53 | ok | taint_sources | Subscript | CgiFieldStorageFieldKind | -| test.py:54 | ok | taint_sources | Attribute | externally controlled string | -| test.py:55 | ok | taint_sources | Attribute | file[externally controlled string] | -| test.py:56 | ok | taint_sources | Attribute | externally controlled string | -| test.py:58 | ok | taint_sources | Attribute() | [externally controlled string] | -| test.py:58 | ok | taint_sources | Attribute() | externally controlled string | -| test.py:59 | ok | taint_sources | Subscript | externally controlled string | -| test.py:61 | ok | taint_sources | Attribute() | externally controlled string | -| test.py:63 | ok | taint_sources | Attribute() | [externally controlled string] | -| test.py:64 | ok | taint_sources | Subscript | externally controlled string | diff --git a/python/ql/test/library-tests/web/stdlib/TestTaint.ql b/python/ql/test/library-tests/web/stdlib/TestTaint.ql deleted file mode 100644 index cd2b08ef235..00000000000 --- a/python/ql/test/library-tests/web/stdlib/TestTaint.ql +++ /dev/null @@ -1,32 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from - Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res, - string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - ( - call.getFunc().(Name).getId() = "ensure_tainted" and - expected_taint = true - or - call.getFunc().(Name).getId() = "ensure_not_tainted" and - expected_taint = false - ) and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "<NO TAINT>" and - has_taint = false - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) and - has_taint = true - ) and - if expected_taint = has_taint then test_res = "ok " else test_res = "fail" -// if expected_taint = has_taint then test_res = "✓" else test_res = "✕" -select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(), - taint_string diff --git a/python/ql/test/library-tests/web/stdlib/test.py b/python/ql/test/library-tests/web/stdlib/test.py deleted file mode 100644 index 1c239f776bb..00000000000 --- a/python/ql/test/library-tests/web/stdlib/test.py +++ /dev/null @@ -1,108 +0,0 @@ -import sys -import os -import cgi - -if sys.version_info[0] == 2: - from BaseHTTPServer import BaseHTTPRequestHandler - from BaseHTTPServer import HTTPServer - -if sys.version_info[0] == 3: - from http.server import HTTPServer, BaseHTTPRequestHandler - - -class MyHandler(BaseHTTPRequestHandler): - - def taint_sources(self): - - ensure_tainted( - self, - - self.requestline, - - self.path, - - self.headers, - self.headers['Foo'], - self.headers.get('Foo'), - self.headers.get_all('Foo'), - self.headers.keys(), - self.headers.values(), - self.headers.items(), - self.headers.as_bytes(), - self.headers.as_string(), - str(self.headers), - bytes(self.headers), - - self.rfile, - self.rfile.read(), - ) - - form = cgi.FieldStorage( - self.rfile, - self.headers, - environ={'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': self.headers.get('content-type')}, - ) - - ensure_tainted( - form, - - form['key'], - form['key'].value, - form['key'].file, - form['key'].filename, - form['key'][0], # will be a list, if multiple fields named "key" are provided - form['key'][0].value, - form['key'][0].file, - form['key'][0].filename, - - form.getvalue('key'), - form.getvalue('key')[0], # will be a list, if multiple fields named "key" are provided - - form.getfirst('key'), - - form.getlist('key'), - form.getlist('key')[0], - ) - - def do_GET(self): - # send_response will log a line to stderr - self.send_response(200) - self.send_header("Content-type", "text/plain; charset=utf-8") - self.end_headers() - self.wfile.write(b"Hello BaseHTTPRequestHandler\n") - self.wfile.writelines([b"1\n", b"2\n", b"3\n"]) - print(self.headers) - - - def do_POST(self): - form = cgi.FieldStorage( - self.rfile, - self.headers, - environ={'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': self.headers.get('content-type')}, - ) - - if 'myfile' not in form: - self.send_response(422) - self.end_headers() - return - - field = form['myfile'] - - field.file.seek(0, os.SEEK_END) - filesize = field.file.tell() - - print("Uploaded {!r} with {} bytes".format(field.filename, filesize)) - - self.send_response(200) - self.end_headers() - - -if __name__ == "__main__": - server = HTTPServer(("127.0.0.1", 8080), MyHandler) - server.serve_forever() - - # Headers works case insensitvely, so self.headers['foo'] == self.headers['FOO'] - # curl localhost:8080 --header "Foo: 1" --header "foo: 2" - - # To test file submission through forms, use - # curl -F myfile=@<yourfile> localhost:8080 diff --git a/python/ql/test/library-tests/web/tornado/Classes.expected b/python/ql/test/library-tests/web/tornado/Classes.expected deleted file mode 100644 index 693976a2480..00000000000 --- a/python/ql/test/library-tests/web/tornado/Classes.expected +++ /dev/null @@ -1,5 +0,0 @@ -WARNING: Predicate aTornadoRequestHandlerClass has been deprecated and may be removed in future (Classes.ql:6,13-40) -| test.py:4 | class Handler1 | -| test.py:8 | class Handler2 | -| test.py:14 | class Handler3 | -| test.py:23 | class DeepInheritance | diff --git a/python/ql/test/library-tests/web/tornado/Classes.ql b/python/ql/test/library-tests/web/tornado/Classes.ql deleted file mode 100644 index fda9b6eb00a..00000000000 --- a/python/ql/test/library-tests/web/tornado/Classes.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.TestUtils -import semmle.python.web.tornado.Tornado - -from ClassValue cls -where cls = aTornadoRequestHandlerClass() -select remove_library_prefix(cls.getScope().getLocation()), cls.toString() diff --git a/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.expected b/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.expected deleted file mode 100644 index aced656734c..00000000000 --- a/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.expected +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: Type HttpRedirectTaintSink has been deprecated and may be removed in future (HttpRedirectSinks.ql:5,6-27) -| test.py:20:23:20:25 | tornado.HttpRequestHandler.redirect | externally controlled string | diff --git a/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.ql b/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.ql deleted file mode 100644 index 157ef2d4430..00000000000 --- a/python/ql/test/library-tests/web/tornado/HttpRedirectSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRedirect -import semmle.python.security.strings.Untrusted - -from HttpRedirectTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/tornado/HttpResponseSinks.expected b/python/ql/test/library-tests/web/tornado/HttpResponseSinks.expected deleted file mode 100644 index 0681e121664..00000000000 --- a/python/ql/test/library-tests/web/tornado/HttpResponseSinks.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| test.py:6:20:6:43 | tornado.HttpRequestHandler.write | externally controlled string | -| test.py:12:20:12:23 | tornado.HttpRequestHandler.write | externally controlled string | -| test.py:26:20:26:48 | tornado.HttpRequestHandler.write | externally controlled string | diff --git a/python/ql/test/library-tests/web/tornado/HttpResponseSinks.ql b/python/ql/test/library-tests/web/tornado/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/tornado/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/tornado/HttpSources.expected b/python/ql/test/library-tests/web/tornado/HttpSources.expected deleted file mode 100644 index 7e882de7791..00000000000 --- a/python/ql/test/library-tests/web/tornado/HttpSources.expected +++ /dev/null @@ -1,5 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| test.py:6:20:6:43 | Attribute() | externally controlled string | -| test.py:10:16:10:40 | Attribute() | [externally controlled string] | -| test.py:17:15:17:26 | Attribute | tornado.request.HttpRequest | -| test.py:26:20:26:48 | Attribute() | externally controlled string | diff --git a/python/ql/test/library-tests/web/tornado/HttpSources.ql b/python/ql/test/library-tests/web/tornado/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/tornado/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/tornado/Taint.expected b/python/ql/test/library-tests/web/tornado/Taint.expected deleted file mode 100644 index 6028c194b94..00000000000 --- a/python/ql/test/library-tests/web/tornado/Taint.expected +++ /dev/null @@ -1,12 +0,0 @@ -| test.py:6 | Attribute() | externally controlled string | -| test.py:10 | Attribute() | [externally controlled string] | -| test.py:11 | Subscript | externally controlled string | -| test.py:11 | args | [externally controlled string] | -| test.py:12 | name | externally controlled string | -| test.py:17 | Attribute | tornado.request.HttpRequest | -| test.py:18 | Attribute | {externally controlled string} | -| test.py:18 | req | tornado.request.HttpRequest | -| test.py:19 | Subscript | externally controlled string | -| test.py:19 | h | {externally controlled string} | -| test.py:20 | url | externally controlled string | -| test.py:26 | Attribute() | externally controlled string | diff --git a/python/ql/test/library-tests/web/tornado/Taint.ql b/python/ql/test/library-tests/web/tornado/Taint.ql deleted file mode 100644 index d4fc34b643c..00000000000 --- a/python/ql/test/library-tests/web/tornado/Taint.ql +++ /dev/null @@ -1,10 +0,0 @@ -import python -import semmle.python.TestUtils -import semmle.python.web.HttpRequest -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from TaintedNode node -// Add this restriction to keep Python2 and 3 results the same. -where not exists(node.getContext().getCaller()) -select remove_library_prefix(node.getLocation()), node.getAstNode().toString(), node.getTaintKind() diff --git a/python/ql/test/library-tests/web/tornado/options b/python/ql/test/library-tests/web/tornado/options deleted file mode 100644 index 1d132442a3b..00000000000 --- a/python/ql/test/library-tests/web/tornado/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/tornado/test.py b/python/ql/test/library-tests/web/tornado/test.py deleted file mode 100644 index a5a467a81ab..00000000000 --- a/python/ql/test/library-tests/web/tornado/test.py +++ /dev/null @@ -1,26 +0,0 @@ - -import tornado.web - -class Handler1(tornado.web.RequestHandler): - def get(self): - self.write(self.get_argument("xss")) - -class Handler2(tornado.web.RequestHandler): - def get(self): - args = self.get_body_arguments() - name = args[0] - self.write(name) - -class Handler3(tornado.web.RequestHandler): - - def get(self): - req = self.request - h = req.headers - url = h["url"] - self.redirect(url) - - -class DeepInheritance(Handler3): - - def get(self): - self.write(self.get_argument("also_xss")) diff --git a/python/ql/test/library-tests/web/turbogears/Controller.expected b/python/ql/test/library-tests/web/turbogears/Controller.expected deleted file mode 100644 index 1f47639b5a5..00000000000 --- a/python/ql/test/library-tests/web/turbogears/Controller.expected +++ /dev/null @@ -1,6 +0,0 @@ -WARNING: Type TurboGearsControllerMethod has been deprecated and may be removed in future (Controller.ql:4,6-32) -| test.py:7:5:7:32 | Function onerror | -| test.py:13:5:13:50 | Function ok_validated | -| test.py:18:5:18:57 | Function partially_validated | -| test.py:22:5:22:51 | Function not_validated | -| test.py:26:5:26:28 | Function with_template | diff --git a/python/ql/test/library-tests/web/turbogears/Controller.ql b/python/ql/test/library-tests/web/turbogears/Controller.ql deleted file mode 100644 index 850e56ef453..00000000000 --- a/python/ql/test/library-tests/web/turbogears/Controller.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import semmle.python.web.turbogears.TurboGears - -from TurboGearsControllerMethod m -select m diff --git a/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.expected b/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.expected deleted file mode 100644 index f2c1d0ee324..00000000000 --- a/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.expected +++ /dev/null @@ -1,6 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| test.py:8:16:8:69 | TurboGears ControllerMethodReturnValue | externally controlled string | -| test.py:14:16:14:50 | TurboGears ControllerMethodReturnValue | externally controlled string | -| test.py:19:16:19:50 | TurboGears ControllerMethodReturnValue | externally controlled string | -| test.py:23:16:23:50 | TurboGears ControllerMethodReturnValue | externally controlled string | -| test.py:27:16:27:38 | TurboGears ControllerMethodTemplatedReturnValue | {externally controlled string} | diff --git a/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.ql b/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/turbogears/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/turbogears/HttpSources.expected b/python/ql/test/library-tests/web/turbogears/HttpSources.expected deleted file mode 100644 index 0d0dc0f72fe..00000000000 --- a/python/ql/test/library-tests/web/turbogears/HttpSources.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| test.py:18:43:18:43 | b | externally controlled string | -| test.py:22:29:22:29 | a | externally controlled string | -| test.py:22:37:22:37 | b | externally controlled string | diff --git a/python/ql/test/library-tests/web/turbogears/HttpSources.ql b/python/ql/test/library-tests/web/turbogears/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/turbogears/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/turbogears/Taint.expected b/python/ql/test/library-tests/web/turbogears/Taint.expected deleted file mode 100644 index 45b84df72c2..00000000000 --- a/python/ql/test/library-tests/web/turbogears/Taint.expected +++ /dev/null @@ -1,12 +0,0 @@ -| test.py:18 | b | externally controlled string | -| test.py:19 | BinaryExpr | [externally controlled string] | -| test.py:19 | BinaryExpr | externally controlled string | -| test.py:19 | Tuple | [externally controlled string] | -| test.py:19 | b | externally controlled string | -| test.py:22 | a | externally controlled string | -| test.py:22 | b | externally controlled string | -| test.py:23 | BinaryExpr | [externally controlled string] | -| test.py:23 | BinaryExpr | externally controlled string | -| test.py:23 | Tuple | [externally controlled string] | -| test.py:23 | a | externally controlled string | -| test.py:23 | b | externally controlled string | diff --git a/python/ql/test/library-tests/web/turbogears/Taint.ql b/python/ql/test/library-tests/web/turbogears/Taint.ql deleted file mode 100644 index 09972af5f98..00000000000 --- a/python/ql/test/library-tests/web/turbogears/Taint.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from TaintedNode node -select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind() diff --git a/python/ql/test/library-tests/web/turbogears/options b/python/ql/test/library-tests/web/turbogears/options deleted file mode 100644 index 7fb713d5924..00000000000 --- a/python/ql/test/library-tests/web/turbogears/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=3 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/turbogears/test.py b/python/ql/test/library-tests/web/turbogears/test.py deleted file mode 100644 index bae3a460f43..00000000000 --- a/python/ql/test/library-tests/web/turbogears/test.py +++ /dev/null @@ -1,27 +0,0 @@ - -from tg import request, validate, expose, TGController -from formencode import validators - -class RootController(TGController): - @expose() - def onerror(self, **kwargs): - return 'An error occurred: %s' % request.validation['errors'] - - @expose() - @validate({"a": validators.Int(not_empty=True), "b": validators.Email}, - error_handler=onerror) - def ok_validated(self, a=None, b=None, *args): - return 'Values: %s, %s, %s' % (a, b, args) - - @expose() - @validate({"a": validators.Int(not_empty=True)}) - def partially_validated(self, a=None, b=None, *args): - return 'Values: %s, %s, %s' % (a, b, args) - - @expose() - def not_validated(self, a=None, b=None, *args): - return 'Values: %s, %s, %s' % (a, b, args) - - @expose("<template_path>") - def with_template(self): - return {'template_var': 'foo'} diff --git a/python/ql/test/library-tests/web/twisted/Classes.expected b/python/ql/test/library-tests/web/twisted/Classes.expected deleted file mode 100644 index b818907e98f..00000000000 --- a/python/ql/test/library-tests/web/twisted/Classes.expected +++ /dev/null @@ -1,6 +0,0 @@ -WARNING: Predicate aTwistedRequestHandlerClass has been deprecated and may be removed in future (Classes.ql:6,13-40) -| class MyRequestHandler1 | test.py:3 | -| class MyRequestHandler2 | test.py:23 | -| class MyRequestHandler3 | test.py:27 | -| class MyRequestHandler4 | test.py:38 | -| class MyRequestHandler5 | test.py:42 | diff --git a/python/ql/test/library-tests/web/twisted/Classes.ql b/python/ql/test/library-tests/web/twisted/Classes.ql deleted file mode 100644 index ccc3618b61e..00000000000 --- a/python/ql/test/library-tests/web/twisted/Classes.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.TestUtils -import semmle.python.web.twisted.Twisted - -from ClassValue cls -where cls = aTwistedRequestHandlerClass() -select cls.toString(), remove_library_prefix(cls.getScope().getLocation()) diff --git a/python/ql/test/library-tests/web/twisted/HttpResponseSinks.expected b/python/ql/test/library-tests/web/twisted/HttpResponseSinks.expected deleted file mode 100644 index 763655ffe37..00000000000 --- a/python/ql/test/library-tests/web/twisted/HttpResponseSinks.expected +++ /dev/null @@ -1,11 +0,0 @@ -WARNING: Type HttpResponseTaintSink has been deprecated and may be removed in future (HttpResponseSinks.ql:5,6-27) -| test.py:7:16:7:23 | Twisted response | externally controlled string | -| test.py:14:16:14:23 | Twisted response | externally controlled string | -| test.py:21:16:21:23 | Twisted response | externally controlled string | -| test.py:36:16:36:37 | Twisted response | externally controlled string | -| test.py:40:23:40:30 | Twisted request setter | externally controlled string | -| test.py:44:27:44:31 | Twisted request setter | externally controlled string | -| test.py:44:34:44:38 | Twisted request setter | externally controlled string | -| test.py:45:27:45:31 | Twisted request setter | externally controlled string | -| test.py:45:34:45:40 | Twisted request setter | externally controlled string | -| test.py:46:16:46:37 | Twisted response | externally controlled string | diff --git a/python/ql/test/library-tests/web/twisted/HttpResponseSinks.ql b/python/ql/test/library-tests/web/twisted/HttpResponseSinks.ql deleted file mode 100644 index e62ec486da6..00000000000 --- a/python/ql/test/library-tests/web/twisted/HttpResponseSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from HttpResponseTaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/web/twisted/HttpSources.expected b/python/ql/test/library-tests/web/twisted/HttpSources.expected deleted file mode 100644 index 4e7cb4c7abb..00000000000 --- a/python/ql/test/library-tests/web/twisted/HttpSources.expected +++ /dev/null @@ -1,9 +0,0 @@ -WARNING: Type HttpRequestTaintSource has been deprecated and may be removed in future (HttpSources.ql:5,6-28) -| test.py:4:22:4:28 | request | twisted.request.http.Request | -| test.py:9:26:9:32 | request | twisted.request.http.Request | -| test.py:16:27:16:33 | request | twisted.request.http.Request | -| test.py:24:24:24:30 | request | twisted.request.http.Request | -| test.py:28:22:28:30 | myrequest | twisted.request.http.Request | -| test.py:31:27:31:37 | postrequest | twisted.request.http.Request | -| test.py:39:22:39:28 | request | twisted.request.http.Request | -| test.py:43:22:43:28 | request | twisted.request.http.Request | diff --git a/python/ql/test/library-tests/web/twisted/HttpSources.ql b/python/ql/test/library-tests/web/twisted/HttpSources.ql deleted file mode 100644 index 6fa1a7d2a6b..00000000000 --- a/python/ql/test/library-tests/web/twisted/HttpSources.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted - -from HttpRequestTaintSource source, TaintKind kind -where source.isSourceOf(kind) -select source.(ControlFlowNode).getNode(), kind diff --git a/python/ql/test/library-tests/web/twisted/Methods.expected b/python/ql/test/library-tests/web/twisted/Methods.expected deleted file mode 100644 index 6578ef88da9..00000000000 --- a/python/ql/test/library-tests/web/twisted/Methods.expected +++ /dev/null @@ -1,9 +0,0 @@ -WARNING: Predicate getTwistedRequestHandlerMethod has been deprecated and may be removed in future (Methods.ql:6,14-44) -| myrender | Function MyRequestHandler2.myrender | test.py:24 | -| render | Function MyRequestHandler1.render | test.py:4 | -| render | Function MyRequestHandler3.render | test.py:28 | -| render | Function MyRequestHandler4.render | test.py:39 | -| render | Function MyRequestHandler5.render | test.py:43 | -| render_GET | Function MyRequestHandler1.render_GET | test.py:9 | -| render_POST | Function MyRequestHandler1.render_POST | test.py:16 | -| render_POST | Function MyRequestHandler3.render_POST | test.py:31 | diff --git a/python/ql/test/library-tests/web/twisted/Methods.ql b/python/ql/test/library-tests/web/twisted/Methods.ql deleted file mode 100644 index f997b7deef3..00000000000 --- a/python/ql/test/library-tests/web/twisted/Methods.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.TestUtils -import semmle.python.web.twisted.Twisted - -from FunctionValue func, string name -where func = getTwistedRequestHandlerMethod(name) -select name, func.toString(), remove_library_prefix(func.getScope().getLocation()) diff --git a/python/ql/test/library-tests/web/twisted/Taint.expected b/python/ql/test/library-tests/web/twisted/Taint.expected deleted file mode 100644 index 1c793c973bd..00000000000 --- a/python/ql/test/library-tests/web/twisted/Taint.expected +++ /dev/null @@ -1,41 +0,0 @@ -| test.py:4 | request | twisted.request.http.Request | -| test.py:5 | Attribute | externally controlled string | -| test.py:5 | request | twisted.request.http.Request | -| test.py:6 | request | twisted.request.http.Request | -| test.py:9 | request | twisted.request.http.Request | -| test.py:10 | request | twisted.request.http.Request | -| test.py:11 | Attribute | externally controlled string | -| test.py:11 | x | twisted.request.http.Request | -| test.py:12 | request | twisted.request.http.Request | -| test.py:13 | request | twisted.request.http.Request | -| test.py:16 | request | twisted.request.http.Request | -| test.py:17 | Attribute | {[externally controlled string]} | -| test.py:17 | request | twisted.request.http.Request | -| test.py:18 | Attribute | {[externally controlled string]} | -| test.py:18 | Attribute() | [externally controlled string] | -| test.py:18 | request | twisted.request.http.Request | -| test.py:19 | Subscript | externally controlled string | -| test.py:19 | foo | [externally controlled string] | -| test.py:20 | quux | externally controlled string | -| test.py:24 | request | twisted.request.http.Request | -| test.py:25 | request | twisted.request.http.Request | -| test.py:28 | myrequest | twisted.request.http.Request | -| test.py:29 | myrequest | twisted.request.http.Request | -| test.py:31 | postrequest | twisted.request.http.Request | -| test.py:32 | Attribute() | externally controlled string | -| test.py:32 | postrequest | twisted.request.http.Request | -| test.py:33 | Attribute() | externally controlled string | -| test.py:33 | postrequest | twisted.request.http.Request | -| test.py:34 | Attribute() | externally controlled string | -| test.py:34 | postrequest | twisted.request.http.Request | -| test.py:35 | Attribute() | externally controlled string | -| test.py:35 | postrequest | twisted.request.http.Request | -| test.py:36 | w | externally controlled string | -| test.py:36 | x | externally controlled string | -| test.py:36 | y | externally controlled string | -| test.py:36 | z | externally controlled string | -| test.py:39 | request | twisted.request.http.Request | -| test.py:40 | request | twisted.request.http.Request | -| test.py:43 | request | twisted.request.http.Request | -| test.py:44 | request | twisted.request.http.Request | -| test.py:45 | request | twisted.request.http.Request | diff --git a/python/ql/test/library-tests/web/twisted/Taint.ql b/python/ql/test/library-tests/web/twisted/Taint.ql deleted file mode 100644 index e92616b6b29..00000000000 --- a/python/ql/test/library-tests/web/twisted/Taint.ql +++ /dev/null @@ -1,8 +0,0 @@ -import python -import semmle.python.TestUtils -import semmle.python.web.HttpRequest -import semmle.python.web.HttpResponse -import semmle.python.security.strings.Untrusted - -from TaintedNode node -select remove_library_prefix(node.getLocation()), node.getAstNode().toString(), node.getTaintKind() diff --git a/python/ql/test/library-tests/web/twisted/options b/python/ql/test/library-tests/web/twisted/options deleted file mode 100644 index 4084b102b55..00000000000 --- a/python/ql/test/library-tests/web/twisted/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=1 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/web/twisted/test.py b/python/ql/test/library-tests/web/twisted/test.py deleted file mode 100644 index f6691b84d95..00000000000 --- a/python/ql/test/library-tests/web/twisted/test.py +++ /dev/null @@ -1,51 +0,0 @@ -from twisted.web import resource - -class MyRequestHandler1(resource.Resource): - def render(self, request): - foo(request.uri) - response = do_stuff_with(request) - return response - - def render_GET(self, request): - x = request - bar(x.uri) - do_stuff_with(request) - response = do_stuff_with(request) - return response - - def render_POST(self, request): - baz(request.args) - foo = request.args.get("baz") - quux = foo[5] - response = do_stuff_with(quux) - return response - -class MyRequestHandler2(resource.Resource): - def myrender(self, request): - do_stuff_with(request) - -class MyRequestHandler3(resource.Resource): - def render(self, myrequest): - do_stuff_with(myrequest) - - def render_POST(self, postrequest): - x = postrequest.getHeader("someheader") - y = postrequest.getCookie("somecookie") - z = postrequest.getUser() - w = postrequest.getPassword() - return do_stuff_with(x,y,z,w) - -class MyRequestHandler4(resource.Resource): - def render(self, request): - request.write("Foobar") - -class MyRequestHandler5(resource.Resource): - def render(self, request): - request.setHeader("foo", "bar") - request.addCookie("key", "value") - return "This is my response." - -class NotATwistedRequestHandler(object): - def render(self, request): - return do_stuff_with(request) - diff --git a/python/tools/recorded-call-graph-metrics/ql/lib/BytecodeExpr.qll b/python/tools/recorded-call-graph-metrics/ql/lib/BytecodeExpr.qll index 4d1bfeb3859..c8d1acff57a 100644 --- a/python/tools/recorded-call-graph-metrics/ql/lib/BytecodeExpr.qll +++ b/python/tools/recorded-call-graph-metrics/ql/lib/BytecodeExpr.qll @@ -2,27 +2,18 @@ import python abstract class XmlBytecodeExpr extends XmlElement { } -/** DEPRECATED: Alias for XmlBytecodeExpr */ -deprecated class XMLBytecodeExpr = XmlBytecodeExpr; - class XmlBytecodeConst extends XmlBytecodeExpr { XmlBytecodeConst() { this.hasName("BytecodeConst") } string get_value_data_raw() { result = this.getAChild("value").getTextValue() } } -/** DEPRECATED: Alias for XmlBytecodeConst */ -deprecated class XMLBytecodeConst = XmlBytecodeConst; - class XmlBytecodeVariableName extends XmlBytecodeExpr { XmlBytecodeVariableName() { this.hasName("BytecodeVariableName") } string get_name_data() { result = this.getAChild("name").getTextValue() } } -/** DEPRECATED: Alias for XmlBytecodeVariableName */ -deprecated class XMLBytecodeVariableName = XmlBytecodeVariableName; - class XmlBytecodeAttribute extends XmlBytecodeExpr { XmlBytecodeAttribute() { this.hasName("BytecodeAttribute") } @@ -31,9 +22,6 @@ class XmlBytecodeAttribute extends XmlBytecodeExpr { XmlBytecodeExpr get_object_data() { result.getParent() = this.getAChild("object") } } -/** DEPRECATED: Alias for XmlBytecodeAttribute */ -deprecated class XMLBytecodeAttribute = XmlBytecodeAttribute; - class XmlBytecodeSubscript extends XmlBytecodeExpr { XmlBytecodeSubscript() { this.hasName("BytecodeSubscript") } @@ -42,9 +30,6 @@ class XmlBytecodeSubscript extends XmlBytecodeExpr { XmlBytecodeExpr get_object_data() { result.getParent() = this.getAChild("object") } } -/** DEPRECATED: Alias for XmlBytecodeSubscript */ -deprecated class XMLBytecodeSubscript = XmlBytecodeSubscript; - class XmlBytecodeTuple extends XmlBytecodeExpr { XmlBytecodeTuple() { this.hasName("BytecodeTuple") } @@ -53,9 +38,6 @@ class XmlBytecodeTuple extends XmlBytecodeExpr { } } -/** DEPRECATED: Alias for XmlBytecodeTuple */ -deprecated class XMLBytecodeTuple = XmlBytecodeTuple; - class XmlBytecodeList extends XmlBytecodeExpr { XmlBytecodeList() { this.hasName("BytecodeList") } @@ -64,27 +46,18 @@ class XmlBytecodeList extends XmlBytecodeExpr { } } -/** DEPRECATED: Alias for XmlBytecodeList */ -deprecated class XMLBytecodeList = XmlBytecodeList; - class XmlBytecodeCall extends XmlBytecodeExpr { XmlBytecodeCall() { this.hasName("BytecodeCall") } XmlBytecodeExpr get_function_data() { result.getParent() = this.getAChild("function") } } -/** DEPRECATED: Alias for XmlBytecodeCall */ -deprecated class XMLBytecodeCall = XmlBytecodeCall; - class XmlBytecodeUnknown extends XmlBytecodeExpr { XmlBytecodeUnknown() { this.hasName("BytecodeUnknown") } string get_opname_data() { result = this.getAChild("opname").getTextValue() } } -/** DEPRECATED: Alias for XmlBytecodeUnknown */ -deprecated class XMLBytecodeUnknown = XmlBytecodeUnknown; - class XmlBytecodeMakeFunction extends XmlBytecodeExpr { XmlBytecodeMakeFunction() { this.hasName("BytecodeMakeFunction") } @@ -93,14 +66,8 @@ class XmlBytecodeMakeFunction extends XmlBytecodeExpr { } } -/** DEPRECATED: Alias for XmlBytecodeMakeFunction */ -deprecated class XMLBytecodeMakeFunction = XmlBytecodeMakeFunction; - class XmlSomethingInvolvingScaryBytecodeJump extends XmlBytecodeExpr { XmlSomethingInvolvingScaryBytecodeJump() { this.hasName("SomethingInvolvingScaryBytecodeJump") } string get_opname_data() { result = this.getAChild("opname").getTextValue() } } - -/** DEPRECATED: Alias for XmlSomethingInvolvingScaryBytecodeJump */ -deprecated class XMLSomethingInvolvingScaryBytecodeJump = XmlSomethingInvolvingScaryBytecodeJump; diff --git a/python/tools/recorded-call-graph-metrics/ql/lib/RecordedCalls.qll b/python/tools/recorded-call-graph-metrics/ql/lib/RecordedCalls.qll index d6ad84ae3a1..4d0c11fa3fd 100644 --- a/python/tools/recorded-call-graph-metrics/ql/lib/RecordedCalls.qll +++ b/python/tools/recorded-call-graph-metrics/ql/lib/RecordedCalls.qll @@ -57,9 +57,6 @@ class XmlRecordedCall extends XmlElement { } } -/** DEPRECATED: Alias for XmlRecordedCall */ -deprecated class XMLRecordedCall = XmlRecordedCall; - /** The XML data for the call part a recorded call. */ class XmlCall extends XmlElement { XmlCall() { this.hasName("Call") } @@ -110,15 +107,9 @@ class XmlCall extends XmlElement { } } -/** DEPRECATED: Alias for XmlCall */ -deprecated class XMLCall = XmlCall; - /** The XML data for the callee part a recorded call. */ abstract class XmlCallee extends XmlElement { } -/** DEPRECATED: Alias for XmlCallee */ -deprecated class XMLCallee = XmlCallee; - /** The XML data for the callee part a recorded call, when the callee is a Python function. */ class XmlPythonCallee extends XmlCallee { XmlPythonCallee() { this.hasName("PythonCallee") } @@ -140,9 +131,6 @@ class XmlPythonCallee extends XmlCallee { } } -/** DEPRECATED: Alias for XmlPythonCallee */ -deprecated class XMLPythonCallee = XmlPythonCallee; - /** The XML data for the callee part a recorded call, when the callee is a C function or builtin. */ class XmlExternalCallee extends XmlCallee { XmlExternalCallee() { this.hasName("ExternalCallee") } @@ -161,9 +149,6 @@ class XmlExternalCallee extends XmlCallee { } } -/** DEPRECATED: Alias for XmlExternalCallee */ -deprecated class XMLExternalCallee = XmlExternalCallee; - /** * Helper predicate. If parent = `builtins` and qualname = `list.append`, it will * return the result of `builtins.list.append`.class From 42d67d0137d806a63c48eec662a0df3fe3d20f7a Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Fri, 9 Jun 2023 15:24:12 +0200 Subject: [PATCH 474/739] add change-note --- python/ql/lib/change-notes/2023-06-09-delete-deps.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 python/ql/lib/change-notes/2023-06-09-delete-deps.md diff --git a/python/ql/lib/change-notes/2023-06-09-delete-deps.md b/python/ql/lib/change-notes/2023-06-09-delete-deps.md new file mode 100644 index 00000000000..75753ea93b7 --- /dev/null +++ b/python/ql/lib/change-notes/2023-06-09-delete-deps.md @@ -0,0 +1,9 @@ +--- +category: minorAnalysis +--- +* Deleted many deprecated predicates and classes with uppercase `API`, `HTTP`, `XSS`, `SQL`, etc. in their names. Use the PascalCased versions instead. +* Deleted the deprecated `getName()` predicate from the `Container` class, use `getAbsolutePath()` instead. +* Deleted many deprecated module names that started with a lowercase letter, use the versions that start with an uppercase letter instead. +* Deleted many deprecated predicates in `PointsTo.qll`. +* Deleted many deprecated files from the `semmle.python.security` package. +* Deleted the deprecated `BottleRoutePointToExtension` class from `Extensions.qll`. \ No newline at end of file From 59636c43cae983871edd318aa62708cbadec037d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 23 May 2023 14:39:01 +0200 Subject: [PATCH 475/739] Dataflow: Rename two private predicates. --- .../java/dataflow/internal/FlowSummaryImpl.qll | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..fb2dc49bae3 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -872,7 +872,7 @@ module Private { } pragma[nomagic] - private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + private ParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) @@ -911,18 +911,18 @@ module Private { predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { exists(ParamNode p, ParameterPosition ppos, Node ret | paramReachesLocal(p, ret, true) and - p = summaryArgParam0(_, arg, sc) and + p = summaryArgParam(_, arg, sc) and p.isParameterOf(_, pragma[only_bind_into](ppos)) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) ) } bindingset[ret] - private ParamNode summaryArgParam( + private ParamNode summaryArgParamRetOut( ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc ) { exists(DataFlowCall call, ReturnKindExt rk | - result = summaryArgParam0(call, arg, sc) and + result = summaryArgParam(call, arg, sc) and ret.getKind() = pragma[only_bind_into](rk) and out = pragma[only_bind_into](rk).getAnOutNode(call) ) @@ -937,7 +937,7 @@ module Private { */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and + summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and ret.getKind() = pragma[only_bind_into](rk) and out = getAnOutNode(call, pragma[only_bind_into](rk)) ) @@ -951,7 +951,7 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false)) + exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false)) } /** @@ -963,7 +963,7 @@ module Private { */ predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { exists(Node mid, ReturnNodeExt ret | - summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and + summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and summaryLocalStep(mid, ret, _) ) } @@ -977,7 +977,7 @@ module Private { */ predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { exists(Node mid, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and summaryStoreStep(mid, c, ret) ) } From 254d60c8260ab976f32911001550bd95eab7db84 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 23 May 2023 10:48:11 +0200 Subject: [PATCH 476/739] Dataflow: Refactor FlowSummaryImpl to synthesize nodes independently from DataFlow::Node. --- .../semmle/code/java/dataflow/FlowSummary.qll | 5 +- .../java/dataflow/internal/DataFlowNodes.qll | 80 ++++---- .../dataflow/internal/DataFlowPrivate.qll | 28 +-- .../java/dataflow/internal/DataFlowUtil.qll | 3 +- .../dataflow/internal/FlowSummaryImpl.qll | 173 ++++++++++++------ .../internal/FlowSummaryImplSpecific.qll | 5 +- .../dataflow/internal/TaintTrackingUtil.qll | 4 +- 7 files changed, 178 insertions(+), 120 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll index 6d6af4f82b4..e45ba0be27e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll @@ -149,8 +149,9 @@ class SummarizedCallableBase extends TSummarizedCallableBase { or result = this.asSyntheticCallable().getParameterType(pos) or - exists(SyntheticCallable sc | sc = this.asSyntheticCallable() | - Impl::Private::summaryParameterNodeRange(this, pos) and + exists(SyntheticCallable sc, Impl::Private::SummaryNode p | sc = this.asSyntheticCallable() | + Impl::Private::summaryParameterNode(p, pos) and + this = p.getSummarizedCallable() and not exists(sc.getParameterType(pos)) and result instanceof TypeObject ) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll index 22d79d7da15..8758d0e7c24 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll @@ -54,12 +54,7 @@ private module Cached { fa.getField() instanceof InstanceField and ia.isImplicitFieldQualifier(fa) ) } or - TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { - FlowSummaryImpl::Private::summaryNodeRange(c, state) - } or - TSummaryParameterNode(SummarizedCallable c, int pos) { - FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos) - } or + TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or TFieldValueNode(Field f) cached @@ -378,8 +373,7 @@ module Private { result.asCallable() = n.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or result.asCallable() = n.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or result = nodeGetEnclosingCallable(n.(ImplicitPostUpdateNode).getPreUpdateNode()) or - n = TSummaryInternalNode(result.asSummarizedCallable(), _) or - n = TSummaryParameterNode(result.asSummarizedCallable(), _) or + result.asSummarizedCallable() = n.(FlowSummaryNode).getSummarizedCallable() or result.asFieldScope() = n.(FieldValueNode).getField() } @@ -407,7 +401,7 @@ module Private { or this = getInstanceArgument(_) or - this.(SummaryNode).isArgumentOf(_, _) + this.(FlowSummaryNode).isArgumentOf(_, _) } /** @@ -424,7 +418,7 @@ module Private { or pos = -1 and this = getInstanceArgument(call.asCall()) or - this.(SummaryNode).isArgumentOf(call, pos) + this.(FlowSummaryNode).isArgumentOf(call, pos) } /** Gets the call in which this node is an argument. */ @@ -435,7 +429,7 @@ module Private { class ReturnNode extends Node { ReturnNode() { exists(ReturnStmt ret | this.asExpr() = ret.getResult()) or - this.(SummaryNode).isReturn() + this.(FlowSummaryNode).isReturn() } /** Gets the kind of this returned value. */ @@ -447,61 +441,61 @@ module Private { OutNode() { this.asExpr() instanceof MethodAccess or - this.(SummaryNode).isOut(_) + this.(FlowSummaryNode).isOut(_) } /** Gets the underlying call. */ DataFlowCall getCall() { result.asCall() = this.asExpr() or - this.(SummaryNode).isOut(result) + this.(FlowSummaryNode).isOut(result) } } /** * A data-flow node used to model flow summaries. */ - class SummaryNode extends Node, TSummaryInternalNode { - private SummarizedCallable c; - private FlowSummaryImpl::Private::SummaryNodeState state; + class FlowSummaryNode extends Node, TFlowSummaryNode { + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) } - SummaryNode() { this = TSummaryInternalNode(c, state) } + SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() + } - override Location getLocation() { result = c.getLocation() } + override Location getLocation() { result = this.getSummarizedCallable().getLocation() } - override string toString() { result = "[summary] " + state + " in " + c } + override string toString() { result = this.getSummaryNode().toString() } /** Holds if this summary node is the `i`th argument of `call`. */ predicate isArgumentOf(DataFlowCall call, int i) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this, i) + FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), i) } /** Holds if this summary node is a return node. */ - predicate isReturn() { FlowSummaryImpl::Private::summaryReturnNode(this, _) } + predicate isReturn() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), _) } /** Holds if this summary node is an out node for `call`. */ - predicate isOut(DataFlowCall call) { FlowSummaryImpl::Private::summaryOutNode(call, this, _) } + predicate isOut(DataFlowCall call) { + FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), _) + } } - SummaryNode getSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { - result = TSummaryInternalNode(c, state) - } - - class SummaryParameterNode extends ParameterNode, TSummaryParameterNode { - private SummarizedCallable sc; - private int pos_; - - SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) } - - override Location getLocation() { result = sc.getLocation() } - - override string toString() { result = "[summary param] " + pos_ + " in " + sc } - - override predicate isParameterOf(DataFlowCallable c, int pos) { - c.asSummarizedCallable() = sc and pos = pos_ + class SummaryParameterNode extends ParameterNode, FlowSummaryNode { + SummaryParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) } - Type getTypeImpl() { result = sc.getParameterType(pos_) } + private int getPosition() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + } + + override predicate isParameterOf(DataFlowCallable c, int pos) { + c.asSummarizedCallable() = this.getSummarizedCallable() and pos = this.getPosition() + } + + Type getTypeImpl() { + result = this.getSummarizedCallable().getParameterType(this.getPosition()) + } } } @@ -523,10 +517,12 @@ private class MallocNode extends Node, TMallocNode { ClassInstanceExpr getClassInstanceExpr() { result = cie } } -private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNode { - private Node pre; +private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode { + private FlowSummaryNode pre; - SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) } + SummaryPostUpdateNode() { + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode()) + } override Node getPreUpdateNode() { result = pre } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 01bf90cb7ba..ea393dad0bf 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -85,7 +85,8 @@ predicate jumpStep(Node node1, Node node2) { any(AdditionalValueStep a).step(node1, node2) and node1.getEnclosingCallable() != node2.getEnclosingCallable() or - FlowSummaryImpl::Private::Steps::summaryJumpStep(node1, node2) + FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(), + node2.(FlowSummaryNode).getSummaryNode()) } /** @@ -114,7 +115,8 @@ predicate storeStep(Node node1, Content f, Node node2) { or f instanceof ArrayContent and arrayStoreStep(node1, node2) or - FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, f, node2) + FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), f, + node2.(FlowSummaryNode).getSummaryNode()) } /** @@ -145,7 +147,8 @@ predicate readStep(Node node1, Content f, Node node2) { or f instanceof CollectionContent and collectionReadStep(node1, node2) or - FlowSummaryImpl::Private::Steps::summaryReadStep(node1, f, node2) + FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), f, + node2.(FlowSummaryNode).getSummaryNode()) } /** @@ -160,7 +163,7 @@ predicate clearsContent(Node n, Content c) { c.(FieldContent).getField() = fa.getField() ) or - FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) } /** @@ -168,7 +171,7 @@ predicate clearsContent(Node n, Content c) { * at node `n`. */ predicate expectsContent(Node n, ContentSet c) { - FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) } /** @@ -200,7 +203,7 @@ pragma[noinline] DataFlowType getNodeType(Node n) { result = getErasedRepr(n.getTypeBound()) or - result = FlowSummaryImpl::Private::summaryNodeType(n) + result = FlowSummaryImpl::Private::summaryNodeType(n.(FlowSummaryNode).getSummaryNode()) } /** Gets a string representation of a type returned by `getErasedRepr`. */ @@ -268,7 +271,7 @@ class DataFlowExpr = Expr; private newtype TDataFlowCall = TCall(Call c) or - TSummaryCall(SummarizedCallable c, Node receiver) { + TSummaryCall(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver) { FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) } @@ -318,12 +321,12 @@ class SrcCall extends DataFlowCall, TCall { /** A synthesized call inside a `SummarizedCallable`. */ class SummaryCall extends DataFlowCall, TSummaryCall { private SummarizedCallable c; - private Node receiver; + private FlowSummaryImpl::Private::SummaryNode receiver; SummaryCall() { this = TSummaryCall(c, receiver) } /** Gets the data flow node that this call targets. */ - Node getReceiver() { result = receiver } + FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } override DataFlowCallable getEnclosingCallable() { result.asSummarizedCallable() = c } @@ -383,10 +386,7 @@ predicate forceHighPrecision(Content c) { } /** Holds if `n` should be hidden from path explanations. */ -predicate nodeIsHidden(Node n) { - n instanceof SummaryNode or - n instanceof SummaryParameterNode -} +predicate nodeIsHidden(Node n) { n instanceof FlowSummaryNode } class LambdaCallKind = Method; // the "apply" method in the functional interface @@ -404,7 +404,7 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) /** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { - receiver = call.(SummaryCall).getReceiver() and + receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() and getNodeDataFlowType(receiver) .getSourceDeclaration() .(FunctionalInterface) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index ff064cc8405..29758d4b972 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -183,7 +183,8 @@ private predicate simpleLocalFlowStep0(Node node1, Node node2) { node1.(ArgumentNode).argumentOf(any(DataFlowCall c | c.asCall() = ma), argNo) ) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(), + node2.(FlowSummaryNode).getSummaryNode(), true) } /** diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index fb2dc49bae3..fa803e6cc92 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -530,7 +530,7 @@ module Private { * this state represents that the components in `s` _remain to be written_ to * the output. */ - class SummaryNodeState extends TSummaryNodeState { + private class SummaryNodeState extends TSummaryNodeState { /** Holds if this state is a valid input state for `c`. */ pragma[nomagic] predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { @@ -559,6 +559,42 @@ module Private { } } + private newtype TSummaryNode = + TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) { + summaryNodeRange(c, state) + } or + TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) { + summaryParameterNodeRange(c, pos) + } + + class SummaryNode extends TSummaryNode { + abstract string toString(); + + abstract SummarizedCallable getSummarizedCallable(); + } + + private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode { + private SummarizedCallable c; + private SummaryNodeState state; + + SummaryInternalNode() { this = TSummaryInternalNode(c, state) } + + override string toString() { result = "[summary] " + state + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + + private class SummaryParamNode extends SummaryNode, TSummaryParameterNode { + private SummarizedCallable c; + private ParameterPosition pos; + + SummaryParamNode() { this = TSummaryParameterNode(c, pos) } + + override string toString() { result = "[summary param] " + pos + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + /** * Holds if `state` represents having read from a parameter at position * `pos` in `c`. In this case we are not synthesizing a data-flow node, @@ -574,7 +610,7 @@ module Private { * Holds if a synthesized summary node is needed for the state `state` in summarized * callable `c`. */ - predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { + private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { state.isInputState(c, _) and not parameterReadState(c, state, _) or @@ -582,22 +618,22 @@ module Private { } pragma[noinline] - private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isInputState(c, s) | - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) or exists(ParameterPosition pos | parameterReadState(c, state, pos) and - result.(ParamNode).isParameterOf(inject(c), pos) + result = TSummaryParameterNode(c, pos) ) ) } pragma[noinline] - private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isOutputState(c, s) and - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) ) } @@ -605,12 +641,14 @@ module Private { * Holds if a write targets `post`, which is a post-update node for a * parameter at position `pos` in `c`. */ - private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) { + private predicate isParameterPostUpdate( + SummaryNode post, SummarizedCallable c, ParameterPosition pos + ) { post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos)) } /** Holds if a parameter node at position `pos` is required for `c`. */ - predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { + private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context @@ -618,7 +656,7 @@ module Private { } private predicate callbackOutput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk ) { any(SummaryNodeState state).isInputState(c, s) and s.head() = TReturnSummaryComponent(rk) and @@ -626,7 +664,7 @@ module Private { } private predicate callbackInput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(pos) and @@ -634,7 +672,7 @@ module Private { } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ - predicate summaryCallbackRange(SummarizedCallable c, Node receiver) { + predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) { callbackOutput(c, _, receiver, _) or callbackInput(c, _, receiver, _) @@ -647,10 +685,10 @@ module Private { * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and * `getCallbackReturnType()`. */ - DataFlowType summaryNodeType(Node n) { - exists(Node pre | + DataFlowType summaryNodeType(SummaryNode n) { + exists(SummaryNode pre | summaryPostUpdateNode(n, pre) and - result = getNodeType(pre) + result = summaryNodeType(pre) ) or exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | @@ -662,12 +700,12 @@ module Private { ) or head = TWithoutContentSummaryComponent(_) and - result = getNodeType(summaryNodeInputState(c, s.tail())) + result = summaryNodeType(summaryNodeInputState(c, s.tail())) or exists(ReturnKind rk | head = TReturnSummaryComponent(rk) and result = - getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), rk) ) or @@ -691,7 +729,7 @@ module Private { or exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | result = - getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), pos) ) or @@ -703,9 +741,14 @@ module Private { ) } + /** Holds if summary node `p` is a parameter with position `pos`. */ + predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) { + p = TSummaryParameterNode(_, pos) + } + /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ - predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackOutput(callable, s, receiver, rk) and out = summaryNodeInputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -713,8 +756,8 @@ module Private { } /** Holds if summary node `arg` is at position `pos` in the call `c`. */ - predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackInput(callable, s, receiver, pos) and arg = summaryNodeOutputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -722,10 +765,10 @@ module Private { } /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ - predicate summaryPostUpdateNode(Node post, Node pre) { + predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) { exists(SummarizedCallable c, ParameterPosition pos | isParameterPostUpdate(post, c, pos) and - pre.(ParamNode).isParameterOf(inject(c), pos) + pre = TSummaryParameterNode(c, pos) ) or exists(SummarizedCallable callable, SummaryComponentStack s | @@ -736,7 +779,7 @@ module Private { } /** Holds if summary node `ret` is a return node of kind `rk`. */ - predicate summaryReturnNode(Node ret, ReturnKind rk) { + predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) { exists(SummaryComponentStack s | ret = summaryNodeOutputState(_, s) and s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) @@ -748,7 +791,9 @@ module Private { * node, and back out to `p`. */ predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) | + exists(SummarizedCallable c, ParameterPosition ppos | + p.isParameterOf(inject(c), pragma[only_bind_into](ppos)) + | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | summary(c, inputContents, outputContents, _) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and @@ -763,7 +808,7 @@ module Private { * Holds if there is a local step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) { + predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) { exists( SummarizedCallable c, SummaryComponentStack inputContents, SummaryComponentStack outputContents @@ -789,7 +834,7 @@ module Private { * Holds if there is a read step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryReadStep(Node pred, ContentSet c, Node succ) { + predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeInputState(sc, s.tail()) and succ = summaryNodeInputState(sc, s) and @@ -801,7 +846,7 @@ module Private { * Holds if there is a store step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { + predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeOutputState(sc, s) and succ = summaryNodeOutputState(sc, s.tail()) and @@ -813,7 +858,7 @@ module Private { * Holds if there is a jump step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryJumpStep(Node pred, Node succ) { + predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) { exists(SummaryComponentStack s | s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and pred = summaryNodeOutputState(_, s) and @@ -840,9 +885,9 @@ module Private { * `a` on line 2 to the post-update node for `a` on that line (via an intermediate * node where field `b` is cleared). */ - predicate summaryClearsContent(Node n, ContentSet c) { + predicate summaryClearsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withoutContent(c) ) @@ -852,9 +897,9 @@ module Private { * Holds if the value that is being tracked is expected to be stored inside * content `c` at `n`. */ - predicate summaryExpectsContent(Node n, ContentSet c) { + predicate summaryExpectsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withContent(c) ) @@ -862,17 +907,17 @@ module Private { pragma[noinline] private predicate viableParam( - DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p + DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p ) { exists(DataFlowCallable c | c = inject(sc) and - p.isParameterOf(c, ppos) and + p = TSummaryParameterNode(sc, ppos) and c = viableCallable(call) ) } pragma[nomagic] - private ParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) @@ -884,12 +929,12 @@ module Private { * local steps. `clearsOrExpects` records whether any node on the path from `p` to * `n` either clears or expects contents. */ - private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) { + private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) { viableParam(_, _, _, p) and n = p and clearsOrExpects = false or - exists(Node mid, boolean clearsOrExpectsMid | + exists(SummaryNode mid, boolean clearsOrExpectsMid | paramReachesLocal(p, mid, clearsOrExpectsMid) and summaryLocalStep(mid, n, true) and if @@ -909,21 +954,33 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, ParameterPosition ppos, Node ret | + exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret | paramReachesLocal(p, ret, true) and p = summaryArgParam(_, arg, sc) and - p.isParameterOf(_, pragma[only_bind_into](ppos)) and + p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) ) } + pragma[nomagic] + private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) { + summaryReturnNode(ret, rk.(ValueReturnKind).getKind()) + or + exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos | + paramReachesLocal(p, pre, _) and + summaryPostUpdateNode(ret, pre) and + p = TSummaryParameterNode(_, pos) and + rk.(ParamUpdateReturnKind).getPosition() = pos + ) + } + bindingset[ret] - private ParamNode summaryArgParamRetOut( - ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc + private SummaryParamNode summaryArgParamRetOut( + ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc ) { exists(DataFlowCall call, ReturnKindExt rk | result = summaryArgParam(call, arg, sc) and - ret.getKind() = pragma[only_bind_into](rk) and + summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and out = pragma[only_bind_into](rk).getAnOutNode(call) ) } @@ -936,9 +993,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | + exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and - ret.getKind() = pragma[only_bind_into](rk) and + summaryReturnNode(ret, pragma[only_bind_into](rk)) and out = getAnOutNode(call, pragma[only_bind_into](rk)) ) } @@ -951,7 +1008,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false)) + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false) + ) } /** @@ -962,7 +1021,7 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | + exists(SummaryNode mid, SummaryNode ret | summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and summaryLocalStep(mid, ret, _) ) @@ -976,7 +1035,7 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | + exists(SummaryNode mid, SummaryNode ret | summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and summaryStoreStep(mid, c, ret) ) @@ -1344,11 +1403,11 @@ module Private { } private newtype TNodeOrCall = - MkNode(Node n) { + MkNode(SummaryNode n) { exists(RelevantSummarizedCallable c | - n = summaryNode(c, _) + n = TSummaryInternalNode(c, _) or - n.(ParamNode).isParameterOf(inject(c), _) + n = TSummaryParameterNode(c, _) ) } or MkCall(DataFlowCall call) { @@ -1357,7 +1416,7 @@ module Private { } private class NodeOrCall extends TNodeOrCall { - Node asNode() { this = MkNode(result) } + SummaryNode asNode() { this = MkNode(result) } DataFlowCall asCall() { this = MkCall(result) } @@ -1377,9 +1436,11 @@ module Private { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - or - this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + filepath = "" and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index 1a0e06553d4..0d948b7dada 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -26,11 +26,8 @@ DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = /** Gets the parameter position of the instance parameter. */ ArgumentPosition callbackSelfParameterPosition() { result = -1 } -/** Gets the synthesized summary data-flow node for the given values. */ -Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSummaryNode(c, state) } - /** Gets the synthesized data-flow call for `receiver`. */ -SummaryCall summaryDataFlowCall(Node receiver) { result.getReceiver() = receiver } +SummaryCall summaryDataFlowCall(SummaryNode receiver) { result.getReceiver() = receiver } /** Gets the type of content `c`. */ DataFlowType getContentType(Content c) { result = c.getType() } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index af8f2273cbe..a43aa5be4f1 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -86,6 +86,7 @@ module LocalTaintFlow<nodeSig/1 source, nodeSig/1 sink> { cached private module Cached { private import DataFlowImplCommon as DataFlowImplCommon + private import DataFlowPrivate as DataFlowPrivate cached predicate forceCachingInSameStage() { DataFlowImplCommon::forceCachingInSameStage() } @@ -136,7 +137,8 @@ private module Cached { ) ) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(src.(DataFlowPrivate::FlowSummaryNode) + .getSummaryNode(), sink.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false) } /** From 2cc5bde925af216fb1b3b7c9f39502c4bb279ceb Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 23 May 2023 14:45:53 +0200 Subject: [PATCH 477/739] Dataflow: Sync. --- .../dataflow/internal/FlowSummaryImpl.qll | 183 ++++++++++++------ .../go/dataflow/internal/FlowSummaryImpl.qll | 183 ++++++++++++------ .../dataflow/new/internal/FlowSummaryImpl.qll | 183 ++++++++++++------ .../dataflow/internal/FlowSummaryImpl.qll | 183 ++++++++++++------ .../dataflow/internal/FlowSummaryImpl.qll | 183 ++++++++++++------ 5 files changed, 610 insertions(+), 305 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..fa803e6cc92 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -530,7 +530,7 @@ module Private { * this state represents that the components in `s` _remain to be written_ to * the output. */ - class SummaryNodeState extends TSummaryNodeState { + private class SummaryNodeState extends TSummaryNodeState { /** Holds if this state is a valid input state for `c`. */ pragma[nomagic] predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { @@ -559,6 +559,42 @@ module Private { } } + private newtype TSummaryNode = + TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) { + summaryNodeRange(c, state) + } or + TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) { + summaryParameterNodeRange(c, pos) + } + + class SummaryNode extends TSummaryNode { + abstract string toString(); + + abstract SummarizedCallable getSummarizedCallable(); + } + + private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode { + private SummarizedCallable c; + private SummaryNodeState state; + + SummaryInternalNode() { this = TSummaryInternalNode(c, state) } + + override string toString() { result = "[summary] " + state + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + + private class SummaryParamNode extends SummaryNode, TSummaryParameterNode { + private SummarizedCallable c; + private ParameterPosition pos; + + SummaryParamNode() { this = TSummaryParameterNode(c, pos) } + + override string toString() { result = "[summary param] " + pos + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + /** * Holds if `state` represents having read from a parameter at position * `pos` in `c`. In this case we are not synthesizing a data-flow node, @@ -574,7 +610,7 @@ module Private { * Holds if a synthesized summary node is needed for the state `state` in summarized * callable `c`. */ - predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { + private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { state.isInputState(c, _) and not parameterReadState(c, state, _) or @@ -582,22 +618,22 @@ module Private { } pragma[noinline] - private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isInputState(c, s) | - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) or exists(ParameterPosition pos | parameterReadState(c, state, pos) and - result.(ParamNode).isParameterOf(inject(c), pos) + result = TSummaryParameterNode(c, pos) ) ) } pragma[noinline] - private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isOutputState(c, s) and - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) ) } @@ -605,12 +641,14 @@ module Private { * Holds if a write targets `post`, which is a post-update node for a * parameter at position `pos` in `c`. */ - private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) { + private predicate isParameterPostUpdate( + SummaryNode post, SummarizedCallable c, ParameterPosition pos + ) { post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos)) } /** Holds if a parameter node at position `pos` is required for `c`. */ - predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { + private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context @@ -618,7 +656,7 @@ module Private { } private predicate callbackOutput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk ) { any(SummaryNodeState state).isInputState(c, s) and s.head() = TReturnSummaryComponent(rk) and @@ -626,7 +664,7 @@ module Private { } private predicate callbackInput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(pos) and @@ -634,7 +672,7 @@ module Private { } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ - predicate summaryCallbackRange(SummarizedCallable c, Node receiver) { + predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) { callbackOutput(c, _, receiver, _) or callbackInput(c, _, receiver, _) @@ -647,10 +685,10 @@ module Private { * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and * `getCallbackReturnType()`. */ - DataFlowType summaryNodeType(Node n) { - exists(Node pre | + DataFlowType summaryNodeType(SummaryNode n) { + exists(SummaryNode pre | summaryPostUpdateNode(n, pre) and - result = getNodeType(pre) + result = summaryNodeType(pre) ) or exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | @@ -662,12 +700,12 @@ module Private { ) or head = TWithoutContentSummaryComponent(_) and - result = getNodeType(summaryNodeInputState(c, s.tail())) + result = summaryNodeType(summaryNodeInputState(c, s.tail())) or exists(ReturnKind rk | head = TReturnSummaryComponent(rk) and result = - getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), rk) ) or @@ -691,7 +729,7 @@ module Private { or exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | result = - getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), pos) ) or @@ -703,9 +741,14 @@ module Private { ) } + /** Holds if summary node `p` is a parameter with position `pos`. */ + predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) { + p = TSummaryParameterNode(_, pos) + } + /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ - predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackOutput(callable, s, receiver, rk) and out = summaryNodeInputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -713,8 +756,8 @@ module Private { } /** Holds if summary node `arg` is at position `pos` in the call `c`. */ - predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackInput(callable, s, receiver, pos) and arg = summaryNodeOutputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -722,10 +765,10 @@ module Private { } /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ - predicate summaryPostUpdateNode(Node post, Node pre) { + predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) { exists(SummarizedCallable c, ParameterPosition pos | isParameterPostUpdate(post, c, pos) and - pre.(ParamNode).isParameterOf(inject(c), pos) + pre = TSummaryParameterNode(c, pos) ) or exists(SummarizedCallable callable, SummaryComponentStack s | @@ -736,7 +779,7 @@ module Private { } /** Holds if summary node `ret` is a return node of kind `rk`. */ - predicate summaryReturnNode(Node ret, ReturnKind rk) { + predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) { exists(SummaryComponentStack s | ret = summaryNodeOutputState(_, s) and s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) @@ -748,7 +791,9 @@ module Private { * node, and back out to `p`. */ predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) | + exists(SummarizedCallable c, ParameterPosition ppos | + p.isParameterOf(inject(c), pragma[only_bind_into](ppos)) + | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | summary(c, inputContents, outputContents, _) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and @@ -763,7 +808,7 @@ module Private { * Holds if there is a local step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) { + predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) { exists( SummarizedCallable c, SummaryComponentStack inputContents, SummaryComponentStack outputContents @@ -789,7 +834,7 @@ module Private { * Holds if there is a read step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryReadStep(Node pred, ContentSet c, Node succ) { + predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeInputState(sc, s.tail()) and succ = summaryNodeInputState(sc, s) and @@ -801,7 +846,7 @@ module Private { * Holds if there is a store step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { + predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeOutputState(sc, s) and succ = summaryNodeOutputState(sc, s.tail()) and @@ -813,7 +858,7 @@ module Private { * Holds if there is a jump step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryJumpStep(Node pred, Node succ) { + predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) { exists(SummaryComponentStack s | s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and pred = summaryNodeOutputState(_, s) and @@ -840,9 +885,9 @@ module Private { * `a` on line 2 to the post-update node for `a` on that line (via an intermediate * node where field `b` is cleared). */ - predicate summaryClearsContent(Node n, ContentSet c) { + predicate summaryClearsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withoutContent(c) ) @@ -852,9 +897,9 @@ module Private { * Holds if the value that is being tracked is expected to be stored inside * content `c` at `n`. */ - predicate summaryExpectsContent(Node n, ContentSet c) { + predicate summaryExpectsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withContent(c) ) @@ -862,17 +907,17 @@ module Private { pragma[noinline] private predicate viableParam( - DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p + DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p ) { exists(DataFlowCallable c | c = inject(sc) and - p.isParameterOf(c, ppos) and + p = TSummaryParameterNode(sc, ppos) and c = viableCallable(call) ) } pragma[nomagic] - private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) @@ -884,12 +929,12 @@ module Private { * local steps. `clearsOrExpects` records whether any node on the path from `p` to * `n` either clears or expects contents. */ - private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) { + private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) { viableParam(_, _, _, p) and n = p and clearsOrExpects = false or - exists(Node mid, boolean clearsOrExpectsMid | + exists(SummaryNode mid, boolean clearsOrExpectsMid | paramReachesLocal(p, mid, clearsOrExpectsMid) and summaryLocalStep(mid, n, true) and if @@ -909,21 +954,33 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, ParameterPosition ppos, Node ret | + exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret | paramReachesLocal(p, ret, true) and - p = summaryArgParam0(_, arg, sc) and - p.isParameterOf(_, pragma[only_bind_into](ppos)) and + p = summaryArgParam(_, arg, sc) and + p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) ) } + pragma[nomagic] + private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) { + summaryReturnNode(ret, rk.(ValueReturnKind).getKind()) + or + exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos | + paramReachesLocal(p, pre, _) and + summaryPostUpdateNode(ret, pre) and + p = TSummaryParameterNode(_, pos) and + rk.(ParamUpdateReturnKind).getPosition() = pos + ) + } + bindingset[ret] - private ParamNode summaryArgParam( - ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc + private SummaryParamNode summaryArgParamRetOut( + ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc ) { exists(DataFlowCall call, ReturnKindExt rk | - result = summaryArgParam0(call, arg, sc) and - ret.getKind() = pragma[only_bind_into](rk) and + result = summaryArgParam(call, arg, sc) and + summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and out = pragma[only_bind_into](rk).getAnOutNode(call) ) } @@ -936,9 +993,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and - ret.getKind() = pragma[only_bind_into](rk) and + exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | + summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and + summaryReturnNode(ret, pragma[only_bind_into](rk)) and out = getAnOutNode(call, pragma[only_bind_into](rk)) ) } @@ -951,7 +1008,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false)) + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false) + ) } /** @@ -962,8 +1021,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and + exists(SummaryNode mid, SummaryNode ret | + summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and summaryLocalStep(mid, ret, _) ) } @@ -976,8 +1035,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and + exists(SummaryNode mid, SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and summaryStoreStep(mid, c, ret) ) } @@ -1344,11 +1403,11 @@ module Private { } private newtype TNodeOrCall = - MkNode(Node n) { + MkNode(SummaryNode n) { exists(RelevantSummarizedCallable c | - n = summaryNode(c, _) + n = TSummaryInternalNode(c, _) or - n.(ParamNode).isParameterOf(inject(c), _) + n = TSummaryParameterNode(c, _) ) } or MkCall(DataFlowCall call) { @@ -1357,7 +1416,7 @@ module Private { } private class NodeOrCall extends TNodeOrCall { - Node asNode() { this = MkNode(result) } + SummaryNode asNode() { this = MkNode(result) } DataFlowCall asCall() { this = MkCall(result) } @@ -1377,9 +1436,11 @@ module Private { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - or - this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + filepath = "" and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 } } diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..fa803e6cc92 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -530,7 +530,7 @@ module Private { * this state represents that the components in `s` _remain to be written_ to * the output. */ - class SummaryNodeState extends TSummaryNodeState { + private class SummaryNodeState extends TSummaryNodeState { /** Holds if this state is a valid input state for `c`. */ pragma[nomagic] predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { @@ -559,6 +559,42 @@ module Private { } } + private newtype TSummaryNode = + TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) { + summaryNodeRange(c, state) + } or + TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) { + summaryParameterNodeRange(c, pos) + } + + class SummaryNode extends TSummaryNode { + abstract string toString(); + + abstract SummarizedCallable getSummarizedCallable(); + } + + private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode { + private SummarizedCallable c; + private SummaryNodeState state; + + SummaryInternalNode() { this = TSummaryInternalNode(c, state) } + + override string toString() { result = "[summary] " + state + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + + private class SummaryParamNode extends SummaryNode, TSummaryParameterNode { + private SummarizedCallable c; + private ParameterPosition pos; + + SummaryParamNode() { this = TSummaryParameterNode(c, pos) } + + override string toString() { result = "[summary param] " + pos + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + /** * Holds if `state` represents having read from a parameter at position * `pos` in `c`. In this case we are not synthesizing a data-flow node, @@ -574,7 +610,7 @@ module Private { * Holds if a synthesized summary node is needed for the state `state` in summarized * callable `c`. */ - predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { + private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { state.isInputState(c, _) and not parameterReadState(c, state, _) or @@ -582,22 +618,22 @@ module Private { } pragma[noinline] - private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isInputState(c, s) | - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) or exists(ParameterPosition pos | parameterReadState(c, state, pos) and - result.(ParamNode).isParameterOf(inject(c), pos) + result = TSummaryParameterNode(c, pos) ) ) } pragma[noinline] - private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isOutputState(c, s) and - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) ) } @@ -605,12 +641,14 @@ module Private { * Holds if a write targets `post`, which is a post-update node for a * parameter at position `pos` in `c`. */ - private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) { + private predicate isParameterPostUpdate( + SummaryNode post, SummarizedCallable c, ParameterPosition pos + ) { post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos)) } /** Holds if a parameter node at position `pos` is required for `c`. */ - predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { + private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context @@ -618,7 +656,7 @@ module Private { } private predicate callbackOutput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk ) { any(SummaryNodeState state).isInputState(c, s) and s.head() = TReturnSummaryComponent(rk) and @@ -626,7 +664,7 @@ module Private { } private predicate callbackInput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(pos) and @@ -634,7 +672,7 @@ module Private { } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ - predicate summaryCallbackRange(SummarizedCallable c, Node receiver) { + predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) { callbackOutput(c, _, receiver, _) or callbackInput(c, _, receiver, _) @@ -647,10 +685,10 @@ module Private { * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and * `getCallbackReturnType()`. */ - DataFlowType summaryNodeType(Node n) { - exists(Node pre | + DataFlowType summaryNodeType(SummaryNode n) { + exists(SummaryNode pre | summaryPostUpdateNode(n, pre) and - result = getNodeType(pre) + result = summaryNodeType(pre) ) or exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | @@ -662,12 +700,12 @@ module Private { ) or head = TWithoutContentSummaryComponent(_) and - result = getNodeType(summaryNodeInputState(c, s.tail())) + result = summaryNodeType(summaryNodeInputState(c, s.tail())) or exists(ReturnKind rk | head = TReturnSummaryComponent(rk) and result = - getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), rk) ) or @@ -691,7 +729,7 @@ module Private { or exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | result = - getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), pos) ) or @@ -703,9 +741,14 @@ module Private { ) } + /** Holds if summary node `p` is a parameter with position `pos`. */ + predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) { + p = TSummaryParameterNode(_, pos) + } + /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ - predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackOutput(callable, s, receiver, rk) and out = summaryNodeInputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -713,8 +756,8 @@ module Private { } /** Holds if summary node `arg` is at position `pos` in the call `c`. */ - predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackInput(callable, s, receiver, pos) and arg = summaryNodeOutputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -722,10 +765,10 @@ module Private { } /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ - predicate summaryPostUpdateNode(Node post, Node pre) { + predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) { exists(SummarizedCallable c, ParameterPosition pos | isParameterPostUpdate(post, c, pos) and - pre.(ParamNode).isParameterOf(inject(c), pos) + pre = TSummaryParameterNode(c, pos) ) or exists(SummarizedCallable callable, SummaryComponentStack s | @@ -736,7 +779,7 @@ module Private { } /** Holds if summary node `ret` is a return node of kind `rk`. */ - predicate summaryReturnNode(Node ret, ReturnKind rk) { + predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) { exists(SummaryComponentStack s | ret = summaryNodeOutputState(_, s) and s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) @@ -748,7 +791,9 @@ module Private { * node, and back out to `p`. */ predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) | + exists(SummarizedCallable c, ParameterPosition ppos | + p.isParameterOf(inject(c), pragma[only_bind_into](ppos)) + | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | summary(c, inputContents, outputContents, _) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and @@ -763,7 +808,7 @@ module Private { * Holds if there is a local step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) { + predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) { exists( SummarizedCallable c, SummaryComponentStack inputContents, SummaryComponentStack outputContents @@ -789,7 +834,7 @@ module Private { * Holds if there is a read step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryReadStep(Node pred, ContentSet c, Node succ) { + predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeInputState(sc, s.tail()) and succ = summaryNodeInputState(sc, s) and @@ -801,7 +846,7 @@ module Private { * Holds if there is a store step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { + predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeOutputState(sc, s) and succ = summaryNodeOutputState(sc, s.tail()) and @@ -813,7 +858,7 @@ module Private { * Holds if there is a jump step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryJumpStep(Node pred, Node succ) { + predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) { exists(SummaryComponentStack s | s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and pred = summaryNodeOutputState(_, s) and @@ -840,9 +885,9 @@ module Private { * `a` on line 2 to the post-update node for `a` on that line (via an intermediate * node where field `b` is cleared). */ - predicate summaryClearsContent(Node n, ContentSet c) { + predicate summaryClearsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withoutContent(c) ) @@ -852,9 +897,9 @@ module Private { * Holds if the value that is being tracked is expected to be stored inside * content `c` at `n`. */ - predicate summaryExpectsContent(Node n, ContentSet c) { + predicate summaryExpectsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withContent(c) ) @@ -862,17 +907,17 @@ module Private { pragma[noinline] private predicate viableParam( - DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p + DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p ) { exists(DataFlowCallable c | c = inject(sc) and - p.isParameterOf(c, ppos) and + p = TSummaryParameterNode(sc, ppos) and c = viableCallable(call) ) } pragma[nomagic] - private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) @@ -884,12 +929,12 @@ module Private { * local steps. `clearsOrExpects` records whether any node on the path from `p` to * `n` either clears or expects contents. */ - private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) { + private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) { viableParam(_, _, _, p) and n = p and clearsOrExpects = false or - exists(Node mid, boolean clearsOrExpectsMid | + exists(SummaryNode mid, boolean clearsOrExpectsMid | paramReachesLocal(p, mid, clearsOrExpectsMid) and summaryLocalStep(mid, n, true) and if @@ -909,21 +954,33 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, ParameterPosition ppos, Node ret | + exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret | paramReachesLocal(p, ret, true) and - p = summaryArgParam0(_, arg, sc) and - p.isParameterOf(_, pragma[only_bind_into](ppos)) and + p = summaryArgParam(_, arg, sc) and + p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) ) } + pragma[nomagic] + private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) { + summaryReturnNode(ret, rk.(ValueReturnKind).getKind()) + or + exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos | + paramReachesLocal(p, pre, _) and + summaryPostUpdateNode(ret, pre) and + p = TSummaryParameterNode(_, pos) and + rk.(ParamUpdateReturnKind).getPosition() = pos + ) + } + bindingset[ret] - private ParamNode summaryArgParam( - ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc + private SummaryParamNode summaryArgParamRetOut( + ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc ) { exists(DataFlowCall call, ReturnKindExt rk | - result = summaryArgParam0(call, arg, sc) and - ret.getKind() = pragma[only_bind_into](rk) and + result = summaryArgParam(call, arg, sc) and + summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and out = pragma[only_bind_into](rk).getAnOutNode(call) ) } @@ -936,9 +993,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and - ret.getKind() = pragma[only_bind_into](rk) and + exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | + summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and + summaryReturnNode(ret, pragma[only_bind_into](rk)) and out = getAnOutNode(call, pragma[only_bind_into](rk)) ) } @@ -951,7 +1008,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false)) + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false) + ) } /** @@ -962,8 +1021,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and + exists(SummaryNode mid, SummaryNode ret | + summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and summaryLocalStep(mid, ret, _) ) } @@ -976,8 +1035,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and + exists(SummaryNode mid, SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and summaryStoreStep(mid, c, ret) ) } @@ -1344,11 +1403,11 @@ module Private { } private newtype TNodeOrCall = - MkNode(Node n) { + MkNode(SummaryNode n) { exists(RelevantSummarizedCallable c | - n = summaryNode(c, _) + n = TSummaryInternalNode(c, _) or - n.(ParamNode).isParameterOf(inject(c), _) + n = TSummaryParameterNode(c, _) ) } or MkCall(DataFlowCall call) { @@ -1357,7 +1416,7 @@ module Private { } private class NodeOrCall extends TNodeOrCall { - Node asNode() { this = MkNode(result) } + SummaryNode asNode() { this = MkNode(result) } DataFlowCall asCall() { this = MkCall(result) } @@ -1377,9 +1436,11 @@ module Private { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - or - this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + filepath = "" and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 } } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index e6379f6a170..fa803e6cc92 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -530,7 +530,7 @@ module Private { * this state represents that the components in `s` _remain to be written_ to * the output. */ - class SummaryNodeState extends TSummaryNodeState { + private class SummaryNodeState extends TSummaryNodeState { /** Holds if this state is a valid input state for `c`. */ pragma[nomagic] predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { @@ -559,6 +559,42 @@ module Private { } } + private newtype TSummaryNode = + TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) { + summaryNodeRange(c, state) + } or + TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) { + summaryParameterNodeRange(c, pos) + } + + class SummaryNode extends TSummaryNode { + abstract string toString(); + + abstract SummarizedCallable getSummarizedCallable(); + } + + private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode { + private SummarizedCallable c; + private SummaryNodeState state; + + SummaryInternalNode() { this = TSummaryInternalNode(c, state) } + + override string toString() { result = "[summary] " + state + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + + private class SummaryParamNode extends SummaryNode, TSummaryParameterNode { + private SummarizedCallable c; + private ParameterPosition pos; + + SummaryParamNode() { this = TSummaryParameterNode(c, pos) } + + override string toString() { result = "[summary param] " + pos + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + /** * Holds if `state` represents having read from a parameter at position * `pos` in `c`. In this case we are not synthesizing a data-flow node, @@ -574,7 +610,7 @@ module Private { * Holds if a synthesized summary node is needed for the state `state` in summarized * callable `c`. */ - predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { + private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { state.isInputState(c, _) and not parameterReadState(c, state, _) or @@ -582,22 +618,22 @@ module Private { } pragma[noinline] - private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isInputState(c, s) | - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) or exists(ParameterPosition pos | parameterReadState(c, state, pos) and - result.(ParamNode).isParameterOf(inject(c), pos) + result = TSummaryParameterNode(c, pos) ) ) } pragma[noinline] - private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isOutputState(c, s) and - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) ) } @@ -605,12 +641,14 @@ module Private { * Holds if a write targets `post`, which is a post-update node for a * parameter at position `pos` in `c`. */ - private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) { + private predicate isParameterPostUpdate( + SummaryNode post, SummarizedCallable c, ParameterPosition pos + ) { post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos)) } /** Holds if a parameter node at position `pos` is required for `c`. */ - predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { + private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context @@ -618,7 +656,7 @@ module Private { } private predicate callbackOutput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk ) { any(SummaryNodeState state).isInputState(c, s) and s.head() = TReturnSummaryComponent(rk) and @@ -626,7 +664,7 @@ module Private { } private predicate callbackInput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(pos) and @@ -634,7 +672,7 @@ module Private { } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ - predicate summaryCallbackRange(SummarizedCallable c, Node receiver) { + predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) { callbackOutput(c, _, receiver, _) or callbackInput(c, _, receiver, _) @@ -647,10 +685,10 @@ module Private { * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and * `getCallbackReturnType()`. */ - DataFlowType summaryNodeType(Node n) { - exists(Node pre | + DataFlowType summaryNodeType(SummaryNode n) { + exists(SummaryNode pre | summaryPostUpdateNode(n, pre) and - result = getNodeType(pre) + result = summaryNodeType(pre) ) or exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | @@ -662,12 +700,12 @@ module Private { ) or head = TWithoutContentSummaryComponent(_) and - result = getNodeType(summaryNodeInputState(c, s.tail())) + result = summaryNodeType(summaryNodeInputState(c, s.tail())) or exists(ReturnKind rk | head = TReturnSummaryComponent(rk) and result = - getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), rk) ) or @@ -691,7 +729,7 @@ module Private { or exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | result = - getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), pos) ) or @@ -703,9 +741,14 @@ module Private { ) } + /** Holds if summary node `p` is a parameter with position `pos`. */ + predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) { + p = TSummaryParameterNode(_, pos) + } + /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ - predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackOutput(callable, s, receiver, rk) and out = summaryNodeInputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -713,8 +756,8 @@ module Private { } /** Holds if summary node `arg` is at position `pos` in the call `c`. */ - predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackInput(callable, s, receiver, pos) and arg = summaryNodeOutputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -722,10 +765,10 @@ module Private { } /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ - predicate summaryPostUpdateNode(Node post, Node pre) { + predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) { exists(SummarizedCallable c, ParameterPosition pos | isParameterPostUpdate(post, c, pos) and - pre.(ParamNode).isParameterOf(inject(c), pos) + pre = TSummaryParameterNode(c, pos) ) or exists(SummarizedCallable callable, SummaryComponentStack s | @@ -736,7 +779,7 @@ module Private { } /** Holds if summary node `ret` is a return node of kind `rk`. */ - predicate summaryReturnNode(Node ret, ReturnKind rk) { + predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) { exists(SummaryComponentStack s | ret = summaryNodeOutputState(_, s) and s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) @@ -748,7 +791,9 @@ module Private { * node, and back out to `p`. */ predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) | + exists(SummarizedCallable c, ParameterPosition ppos | + p.isParameterOf(inject(c), pragma[only_bind_into](ppos)) + | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | summary(c, inputContents, outputContents, _) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and @@ -763,7 +808,7 @@ module Private { * Holds if there is a local step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) { + predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) { exists( SummarizedCallable c, SummaryComponentStack inputContents, SummaryComponentStack outputContents @@ -789,7 +834,7 @@ module Private { * Holds if there is a read step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryReadStep(Node pred, ContentSet c, Node succ) { + predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeInputState(sc, s.tail()) and succ = summaryNodeInputState(sc, s) and @@ -801,7 +846,7 @@ module Private { * Holds if there is a store step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { + predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeOutputState(sc, s) and succ = summaryNodeOutputState(sc, s.tail()) and @@ -813,7 +858,7 @@ module Private { * Holds if there is a jump step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryJumpStep(Node pred, Node succ) { + predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) { exists(SummaryComponentStack s | s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and pred = summaryNodeOutputState(_, s) and @@ -840,9 +885,9 @@ module Private { * `a` on line 2 to the post-update node for `a` on that line (via an intermediate * node where field `b` is cleared). */ - predicate summaryClearsContent(Node n, ContentSet c) { + predicate summaryClearsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withoutContent(c) ) @@ -852,9 +897,9 @@ module Private { * Holds if the value that is being tracked is expected to be stored inside * content `c` at `n`. */ - predicate summaryExpectsContent(Node n, ContentSet c) { + predicate summaryExpectsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withContent(c) ) @@ -862,17 +907,17 @@ module Private { pragma[noinline] private predicate viableParam( - DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p + DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p ) { exists(DataFlowCallable c | c = inject(sc) and - p.isParameterOf(c, ppos) and + p = TSummaryParameterNode(sc, ppos) and c = viableCallable(call) ) } pragma[nomagic] - private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) @@ -884,12 +929,12 @@ module Private { * local steps. `clearsOrExpects` records whether any node on the path from `p` to * `n` either clears or expects contents. */ - private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) { + private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) { viableParam(_, _, _, p) and n = p and clearsOrExpects = false or - exists(Node mid, boolean clearsOrExpectsMid | + exists(SummaryNode mid, boolean clearsOrExpectsMid | paramReachesLocal(p, mid, clearsOrExpectsMid) and summaryLocalStep(mid, n, true) and if @@ -909,21 +954,33 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, ParameterPosition ppos, Node ret | + exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret | paramReachesLocal(p, ret, true) and - p = summaryArgParam0(_, arg, sc) and - p.isParameterOf(_, pragma[only_bind_into](ppos)) and + p = summaryArgParam(_, arg, sc) and + p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) ) } + pragma[nomagic] + private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) { + summaryReturnNode(ret, rk.(ValueReturnKind).getKind()) + or + exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos | + paramReachesLocal(p, pre, _) and + summaryPostUpdateNode(ret, pre) and + p = TSummaryParameterNode(_, pos) and + rk.(ParamUpdateReturnKind).getPosition() = pos + ) + } + bindingset[ret] - private ParamNode summaryArgParam( - ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc + private SummaryParamNode summaryArgParamRetOut( + ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc ) { exists(DataFlowCall call, ReturnKindExt rk | - result = summaryArgParam0(call, arg, sc) and - ret.getKind() = pragma[only_bind_into](rk) and + result = summaryArgParam(call, arg, sc) and + summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and out = pragma[only_bind_into](rk).getAnOutNode(call) ) } @@ -936,9 +993,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and - ret.getKind() = pragma[only_bind_into](rk) and + exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | + summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and + summaryReturnNode(ret, pragma[only_bind_into](rk)) and out = getAnOutNode(call, pragma[only_bind_into](rk)) ) } @@ -951,7 +1008,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false)) + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false) + ) } /** @@ -962,8 +1021,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and + exists(SummaryNode mid, SummaryNode ret | + summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and summaryLocalStep(mid, ret, _) ) } @@ -976,8 +1035,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and + exists(SummaryNode mid, SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and summaryStoreStep(mid, c, ret) ) } @@ -1344,11 +1403,11 @@ module Private { } private newtype TNodeOrCall = - MkNode(Node n) { + MkNode(SummaryNode n) { exists(RelevantSummarizedCallable c | - n = summaryNode(c, _) + n = TSummaryInternalNode(c, _) or - n.(ParamNode).isParameterOf(inject(c), _) + n = TSummaryParameterNode(c, _) ) } or MkCall(DataFlowCall call) { @@ -1357,7 +1416,7 @@ module Private { } private class NodeOrCall extends TNodeOrCall { - Node asNode() { this = MkNode(result) } + SummaryNode asNode() { this = MkNode(result) } DataFlowCall asCall() { this = MkCall(result) } @@ -1377,9 +1436,11 @@ module Private { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - or - this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + filepath = "" and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..fa803e6cc92 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -530,7 +530,7 @@ module Private { * this state represents that the components in `s` _remain to be written_ to * the output. */ - class SummaryNodeState extends TSummaryNodeState { + private class SummaryNodeState extends TSummaryNodeState { /** Holds if this state is a valid input state for `c`. */ pragma[nomagic] predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { @@ -559,6 +559,42 @@ module Private { } } + private newtype TSummaryNode = + TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) { + summaryNodeRange(c, state) + } or + TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) { + summaryParameterNodeRange(c, pos) + } + + class SummaryNode extends TSummaryNode { + abstract string toString(); + + abstract SummarizedCallable getSummarizedCallable(); + } + + private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode { + private SummarizedCallable c; + private SummaryNodeState state; + + SummaryInternalNode() { this = TSummaryInternalNode(c, state) } + + override string toString() { result = "[summary] " + state + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + + private class SummaryParamNode extends SummaryNode, TSummaryParameterNode { + private SummarizedCallable c; + private ParameterPosition pos; + + SummaryParamNode() { this = TSummaryParameterNode(c, pos) } + + override string toString() { result = "[summary param] " + pos + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + /** * Holds if `state` represents having read from a parameter at position * `pos` in `c`. In this case we are not synthesizing a data-flow node, @@ -574,7 +610,7 @@ module Private { * Holds if a synthesized summary node is needed for the state `state` in summarized * callable `c`. */ - predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { + private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { state.isInputState(c, _) and not parameterReadState(c, state, _) or @@ -582,22 +618,22 @@ module Private { } pragma[noinline] - private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isInputState(c, s) | - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) or exists(ParameterPosition pos | parameterReadState(c, state, pos) and - result.(ParamNode).isParameterOf(inject(c), pos) + result = TSummaryParameterNode(c, pos) ) ) } pragma[noinline] - private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isOutputState(c, s) and - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) ) } @@ -605,12 +641,14 @@ module Private { * Holds if a write targets `post`, which is a post-update node for a * parameter at position `pos` in `c`. */ - private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) { + private predicate isParameterPostUpdate( + SummaryNode post, SummarizedCallable c, ParameterPosition pos + ) { post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos)) } /** Holds if a parameter node at position `pos` is required for `c`. */ - predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { + private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context @@ -618,7 +656,7 @@ module Private { } private predicate callbackOutput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk ) { any(SummaryNodeState state).isInputState(c, s) and s.head() = TReturnSummaryComponent(rk) and @@ -626,7 +664,7 @@ module Private { } private predicate callbackInput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(pos) and @@ -634,7 +672,7 @@ module Private { } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ - predicate summaryCallbackRange(SummarizedCallable c, Node receiver) { + predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) { callbackOutput(c, _, receiver, _) or callbackInput(c, _, receiver, _) @@ -647,10 +685,10 @@ module Private { * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and * `getCallbackReturnType()`. */ - DataFlowType summaryNodeType(Node n) { - exists(Node pre | + DataFlowType summaryNodeType(SummaryNode n) { + exists(SummaryNode pre | summaryPostUpdateNode(n, pre) and - result = getNodeType(pre) + result = summaryNodeType(pre) ) or exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | @@ -662,12 +700,12 @@ module Private { ) or head = TWithoutContentSummaryComponent(_) and - result = getNodeType(summaryNodeInputState(c, s.tail())) + result = summaryNodeType(summaryNodeInputState(c, s.tail())) or exists(ReturnKind rk | head = TReturnSummaryComponent(rk) and result = - getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), rk) ) or @@ -691,7 +729,7 @@ module Private { or exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | result = - getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), pos) ) or @@ -703,9 +741,14 @@ module Private { ) } + /** Holds if summary node `p` is a parameter with position `pos`. */ + predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) { + p = TSummaryParameterNode(_, pos) + } + /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ - predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackOutput(callable, s, receiver, rk) and out = summaryNodeInputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -713,8 +756,8 @@ module Private { } /** Holds if summary node `arg` is at position `pos` in the call `c`. */ - predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackInput(callable, s, receiver, pos) and arg = summaryNodeOutputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -722,10 +765,10 @@ module Private { } /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ - predicate summaryPostUpdateNode(Node post, Node pre) { + predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) { exists(SummarizedCallable c, ParameterPosition pos | isParameterPostUpdate(post, c, pos) and - pre.(ParamNode).isParameterOf(inject(c), pos) + pre = TSummaryParameterNode(c, pos) ) or exists(SummarizedCallable callable, SummaryComponentStack s | @@ -736,7 +779,7 @@ module Private { } /** Holds if summary node `ret` is a return node of kind `rk`. */ - predicate summaryReturnNode(Node ret, ReturnKind rk) { + predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) { exists(SummaryComponentStack s | ret = summaryNodeOutputState(_, s) and s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) @@ -748,7 +791,9 @@ module Private { * node, and back out to `p`. */ predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) | + exists(SummarizedCallable c, ParameterPosition ppos | + p.isParameterOf(inject(c), pragma[only_bind_into](ppos)) + | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | summary(c, inputContents, outputContents, _) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and @@ -763,7 +808,7 @@ module Private { * Holds if there is a local step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) { + predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) { exists( SummarizedCallable c, SummaryComponentStack inputContents, SummaryComponentStack outputContents @@ -789,7 +834,7 @@ module Private { * Holds if there is a read step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryReadStep(Node pred, ContentSet c, Node succ) { + predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeInputState(sc, s.tail()) and succ = summaryNodeInputState(sc, s) and @@ -801,7 +846,7 @@ module Private { * Holds if there is a store step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { + predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeOutputState(sc, s) and succ = summaryNodeOutputState(sc, s.tail()) and @@ -813,7 +858,7 @@ module Private { * Holds if there is a jump step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryJumpStep(Node pred, Node succ) { + predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) { exists(SummaryComponentStack s | s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and pred = summaryNodeOutputState(_, s) and @@ -840,9 +885,9 @@ module Private { * `a` on line 2 to the post-update node for `a` on that line (via an intermediate * node where field `b` is cleared). */ - predicate summaryClearsContent(Node n, ContentSet c) { + predicate summaryClearsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withoutContent(c) ) @@ -852,9 +897,9 @@ module Private { * Holds if the value that is being tracked is expected to be stored inside * content `c` at `n`. */ - predicate summaryExpectsContent(Node n, ContentSet c) { + predicate summaryExpectsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withContent(c) ) @@ -862,17 +907,17 @@ module Private { pragma[noinline] private predicate viableParam( - DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p + DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p ) { exists(DataFlowCallable c | c = inject(sc) and - p.isParameterOf(c, ppos) and + p = TSummaryParameterNode(sc, ppos) and c = viableCallable(call) ) } pragma[nomagic] - private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) @@ -884,12 +929,12 @@ module Private { * local steps. `clearsOrExpects` records whether any node on the path from `p` to * `n` either clears or expects contents. */ - private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) { + private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) { viableParam(_, _, _, p) and n = p and clearsOrExpects = false or - exists(Node mid, boolean clearsOrExpectsMid | + exists(SummaryNode mid, boolean clearsOrExpectsMid | paramReachesLocal(p, mid, clearsOrExpectsMid) and summaryLocalStep(mid, n, true) and if @@ -909,21 +954,33 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, ParameterPosition ppos, Node ret | + exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret | paramReachesLocal(p, ret, true) and - p = summaryArgParam0(_, arg, sc) and - p.isParameterOf(_, pragma[only_bind_into](ppos)) and + p = summaryArgParam(_, arg, sc) and + p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) ) } + pragma[nomagic] + private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) { + summaryReturnNode(ret, rk.(ValueReturnKind).getKind()) + or + exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos | + paramReachesLocal(p, pre, _) and + summaryPostUpdateNode(ret, pre) and + p = TSummaryParameterNode(_, pos) and + rk.(ParamUpdateReturnKind).getPosition() = pos + ) + } + bindingset[ret] - private ParamNode summaryArgParam( - ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc + private SummaryParamNode summaryArgParamRetOut( + ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc ) { exists(DataFlowCall call, ReturnKindExt rk | - result = summaryArgParam0(call, arg, sc) and - ret.getKind() = pragma[only_bind_into](rk) and + result = summaryArgParam(call, arg, sc) and + summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and out = pragma[only_bind_into](rk).getAnOutNode(call) ) } @@ -936,9 +993,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and - ret.getKind() = pragma[only_bind_into](rk) and + exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | + summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and + summaryReturnNode(ret, pragma[only_bind_into](rk)) and out = getAnOutNode(call, pragma[only_bind_into](rk)) ) } @@ -951,7 +1008,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false)) + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false) + ) } /** @@ -962,8 +1021,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and + exists(SummaryNode mid, SummaryNode ret | + summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and summaryLocalStep(mid, ret, _) ) } @@ -976,8 +1035,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and + exists(SummaryNode mid, SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and summaryStoreStep(mid, c, ret) ) } @@ -1344,11 +1403,11 @@ module Private { } private newtype TNodeOrCall = - MkNode(Node n) { + MkNode(SummaryNode n) { exists(RelevantSummarizedCallable c | - n = summaryNode(c, _) + n = TSummaryInternalNode(c, _) or - n.(ParamNode).isParameterOf(inject(c), _) + n = TSummaryParameterNode(c, _) ) } or MkCall(DataFlowCall call) { @@ -1357,7 +1416,7 @@ module Private { } private class NodeOrCall extends TNodeOrCall { - Node asNode() { this = MkNode(result) } + SummaryNode asNode() { this = MkNode(result) } DataFlowCall asCall() { this = MkCall(result) } @@ -1377,9 +1436,11 @@ module Private { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - or - this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + filepath = "" and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index e6379f6a170..fa803e6cc92 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -530,7 +530,7 @@ module Private { * this state represents that the components in `s` _remain to be written_ to * the output. */ - class SummaryNodeState extends TSummaryNodeState { + private class SummaryNodeState extends TSummaryNodeState { /** Holds if this state is a valid input state for `c`. */ pragma[nomagic] predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { @@ -559,6 +559,42 @@ module Private { } } + private newtype TSummaryNode = + TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) { + summaryNodeRange(c, state) + } or + TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) { + summaryParameterNodeRange(c, pos) + } + + class SummaryNode extends TSummaryNode { + abstract string toString(); + + abstract SummarizedCallable getSummarizedCallable(); + } + + private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode { + private SummarizedCallable c; + private SummaryNodeState state; + + SummaryInternalNode() { this = TSummaryInternalNode(c, state) } + + override string toString() { result = "[summary] " + state + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + + private class SummaryParamNode extends SummaryNode, TSummaryParameterNode { + private SummarizedCallable c; + private ParameterPosition pos; + + SummaryParamNode() { this = TSummaryParameterNode(c, pos) } + + override string toString() { result = "[summary param] " + pos + " in " + c } + + override SummarizedCallable getSummarizedCallable() { result = c } + } + /** * Holds if `state` represents having read from a parameter at position * `pos` in `c`. In this case we are not synthesizing a data-flow node, @@ -574,7 +610,7 @@ module Private { * Holds if a synthesized summary node is needed for the state `state` in summarized * callable `c`. */ - predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { + private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { state.isInputState(c, _) and not parameterReadState(c, state, _) or @@ -582,22 +618,22 @@ module Private { } pragma[noinline] - private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isInputState(c, s) | - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) or exists(ParameterPosition pos | parameterReadState(c, state, pos) and - result.(ParamNode).isParameterOf(inject(c), pos) + result = TSummaryParameterNode(c, pos) ) ) } pragma[noinline] - private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { + private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { exists(SummaryNodeState state | state.isOutputState(c, s) and - result = summaryNode(c, state) + result = TSummaryInternalNode(c, state) ) } @@ -605,12 +641,14 @@ module Private { * Holds if a write targets `post`, which is a post-update node for a * parameter at position `pos` in `c`. */ - private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) { + private predicate isParameterPostUpdate( + SummaryNode post, SummarizedCallable c, ParameterPosition pos + ) { post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos)) } /** Holds if a parameter node at position `pos` is required for `c`. */ - predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { + private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) { parameterReadState(c, _, pos) or // Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context @@ -618,7 +656,7 @@ module Private { } private predicate callbackOutput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk ) { any(SummaryNodeState state).isInputState(c, s) and s.head() = TReturnSummaryComponent(rk) and @@ -626,7 +664,7 @@ module Private { } private predicate callbackInput( - SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos + SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(pos) and @@ -634,7 +672,7 @@ module Private { } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ - predicate summaryCallbackRange(SummarizedCallable c, Node receiver) { + predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) { callbackOutput(c, _, receiver, _) or callbackInput(c, _, receiver, _) @@ -647,10 +685,10 @@ module Private { * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and * `getCallbackReturnType()`. */ - DataFlowType summaryNodeType(Node n) { - exists(Node pre | + DataFlowType summaryNodeType(SummaryNode n) { + exists(SummaryNode pre | summaryPostUpdateNode(n, pre) and - result = getNodeType(pre) + result = summaryNodeType(pre) ) or exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | @@ -662,12 +700,12 @@ module Private { ) or head = TWithoutContentSummaryComponent(_) and - result = getNodeType(summaryNodeInputState(c, s.tail())) + result = summaryNodeType(summaryNodeInputState(c, s.tail())) or exists(ReturnKind rk | head = TReturnSummaryComponent(rk) and result = - getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), rk) ) or @@ -691,7 +729,7 @@ module Private { or exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | result = - getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), + getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.tail())), pos) ) or @@ -703,9 +741,14 @@ module Private { ) } + /** Holds if summary node `p` is a parameter with position `pos`. */ + predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) { + p = TSummaryParameterNode(_, pos) + } + /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ - predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackOutput(callable, s, receiver, rk) and out = summaryNodeInputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -713,8 +756,8 @@ module Private { } /** Holds if summary node `arg` is at position `pos` in the call `c`. */ - predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) { - exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) { + exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver | callbackInput(callable, s, receiver, pos) and arg = summaryNodeOutputState(callable, s) and c = summaryDataFlowCall(receiver) @@ -722,10 +765,10 @@ module Private { } /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ - predicate summaryPostUpdateNode(Node post, Node pre) { + predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) { exists(SummarizedCallable c, ParameterPosition pos | isParameterPostUpdate(post, c, pos) and - pre.(ParamNode).isParameterOf(inject(c), pos) + pre = TSummaryParameterNode(c, pos) ) or exists(SummarizedCallable callable, SummaryComponentStack s | @@ -736,7 +779,7 @@ module Private { } /** Holds if summary node `ret` is a return node of kind `rk`. */ - predicate summaryReturnNode(Node ret, ReturnKind rk) { + predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) { exists(SummaryComponentStack s | ret = summaryNodeOutputState(_, s) and s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) @@ -748,7 +791,9 @@ module Private { * node, and back out to `p`. */ predicate summaryAllowParameterReturnInSelf(ParamNode p) { - exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) | + exists(SummarizedCallable c, ParameterPosition ppos | + p.isParameterOf(inject(c), pragma[only_bind_into](ppos)) + | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | summary(c, inputContents, outputContents, _) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and @@ -763,7 +808,7 @@ module Private { * Holds if there is a local step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) { + predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) { exists( SummarizedCallable c, SummaryComponentStack inputContents, SummaryComponentStack outputContents @@ -789,7 +834,7 @@ module Private { * Holds if there is a read step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryReadStep(Node pred, ContentSet c, Node succ) { + predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeInputState(sc, s.tail()) and succ = summaryNodeInputState(sc, s) and @@ -801,7 +846,7 @@ module Private { * Holds if there is a store step of content `c` from `pred` to `succ`, which * is synthesized from a flow summary. */ - predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { + predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) { exists(SummarizedCallable sc, SummaryComponentStack s | pred = summaryNodeOutputState(sc, s) and succ = summaryNodeOutputState(sc, s.tail()) and @@ -813,7 +858,7 @@ module Private { * Holds if there is a jump step from `pred` to `succ`, which is synthesized * from a flow summary. */ - predicate summaryJumpStep(Node pred, Node succ) { + predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) { exists(SummaryComponentStack s | s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and pred = summaryNodeOutputState(_, s) and @@ -840,9 +885,9 @@ module Private { * `a` on line 2 to the post-update node for `a` on that line (via an intermediate * node where field `b` is cleared). */ - predicate summaryClearsContent(Node n, ContentSet c) { + predicate summaryClearsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withoutContent(c) ) @@ -852,9 +897,9 @@ module Private { * Holds if the value that is being tracked is expected to be stored inside * content `c` at `n`. */ - predicate summaryExpectsContent(Node n, ContentSet c) { + predicate summaryExpectsContent(SummaryNode n, ContentSet c) { exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack | - n = summaryNode(sc, state) and + n = TSummaryInternalNode(sc, state) and state.isInputState(sc, stack) and stack.head() = SummaryComponent::withContent(c) ) @@ -862,17 +907,17 @@ module Private { pragma[noinline] private predicate viableParam( - DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p + DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p ) { exists(DataFlowCallable c | c = inject(sc) and - p.isParameterOf(c, ppos) and + p = TSummaryParameterNode(sc, ppos) and c = viableCallable(call) ) } pragma[nomagic] - private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { + private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) { exists(ParameterPosition ppos | argumentPositionMatch(call, arg, ppos) and viableParam(call, sc, ppos, result) @@ -884,12 +929,12 @@ module Private { * local steps. `clearsOrExpects` records whether any node on the path from `p` to * `n` either clears or expects contents. */ - private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) { + private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) { viableParam(_, _, _, p) and n = p and clearsOrExpects = false or - exists(Node mid, boolean clearsOrExpectsMid | + exists(SummaryNode mid, boolean clearsOrExpectsMid | paramReachesLocal(p, mid, clearsOrExpectsMid) and summaryLocalStep(mid, n, true) and if @@ -909,21 +954,33 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, ParameterPosition ppos, Node ret | + exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret | paramReachesLocal(p, ret, true) and - p = summaryArgParam0(_, arg, sc) and - p.isParameterOf(_, pragma[only_bind_into](ppos)) and + p = summaryArgParam(_, arg, sc) and + p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) ) } + pragma[nomagic] + private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) { + summaryReturnNode(ret, rk.(ValueReturnKind).getKind()) + or + exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos | + paramReachesLocal(p, pre, _) and + summaryPostUpdateNode(ret, pre) and + p = TSummaryParameterNode(_, pos) and + rk.(ParamUpdateReturnKind).getPosition() = pos + ) + } + bindingset[ret] - private ParamNode summaryArgParam( - ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc + private SummaryParamNode summaryArgParamRetOut( + ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc ) { exists(DataFlowCall call, ReturnKindExt rk | - result = summaryArgParam0(call, arg, sc) and - ret.getKind() = pragma[only_bind_into](rk) and + result = summaryArgParam(call, arg, sc) and + summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and out = pragma[only_bind_into](rk).getAnOutNode(call) ) } @@ -936,9 +993,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnKind rk, ReturnNode ret, DataFlowCall call | - summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and - ret.getKind() = pragma[only_bind_into](rk) and + exists(ReturnKind rk, SummaryNode ret, DataFlowCall call | + summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and + summaryReturnNode(ret, pragma[only_bind_into](rk)) and out = getAnOutNode(call, pragma[only_bind_into](rk)) ) } @@ -951,7 +1008,9 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) { - exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false)) + exists(SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false) + ) } /** @@ -962,8 +1021,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and + exists(SummaryNode mid, SummaryNode ret | + summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and summaryLocalStep(mid, ret, _) ) } @@ -976,8 +1035,8 @@ module Private { * be useful to include in the exposed local data-flow/taint-tracking relations. */ predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) { - exists(Node mid, ReturnNodeExt ret | - summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and + exists(SummaryNode mid, SummaryNode ret | + summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and summaryStoreStep(mid, c, ret) ) } @@ -1344,11 +1403,11 @@ module Private { } private newtype TNodeOrCall = - MkNode(Node n) { + MkNode(SummaryNode n) { exists(RelevantSummarizedCallable c | - n = summaryNode(c, _) + n = TSummaryInternalNode(c, _) or - n.(ParamNode).isParameterOf(inject(c), _) + n = TSummaryParameterNode(c, _) ) } or MkCall(DataFlowCall call) { @@ -1357,7 +1416,7 @@ module Private { } private class NodeOrCall extends TNodeOrCall { - Node asNode() { this = MkNode(result) } + SummaryNode asNode() { this = MkNode(result) } DataFlowCall asCall() { this = MkCall(result) } @@ -1377,9 +1436,11 @@ module Private { predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn ) { - this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - or - this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + filepath = "" and + startline = 0 and + startcolumn = 0 and + endline = 0 and + endcolumn = 0 } } From 5e6031724ac192e4500f077328f8d3b01c2c1af2 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Wed, 24 May 2023 11:10:24 +0200 Subject: [PATCH 478/739] C#: Adjust to FlowSummaryImpl changes. --- .../dataflow/internal/DataFlowDispatch.qll | 8 +- .../dataflow/internal/DataFlowPrivate.qll | 120 +++++++++--------- .../internal/FlowSummaryImplSpecific.qll | 5 +- .../internal/TaintTrackingPrivate.qll | 3 +- 4 files changed, 68 insertions(+), 68 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index c3a54ba8ff3..4e37d14805b 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -128,7 +128,9 @@ private module Cached { // No need to include calls that are compiled from source not call.getImplementation().getMethod().compiledFromSource() } or - TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, Node receiver) { + TSummaryCall( + FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver + ) { FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) } @@ -472,12 +474,12 @@ class CilDataFlowCall extends DataFlowCall, TCilCall { */ class SummaryCall extends DelegateDataFlowCall, TSummaryCall { private FlowSummaryImpl::Public::SummarizedCallable c; - private Node receiver; + private FlowSummaryImpl::Private::SummaryNode receiver; SummaryCall() { this = TSummaryCall(c, receiver) } /** Gets the data flow node that this call targets. */ - Node getReceiver() { result = receiver } + FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } override DataFlowCallable getARuntimeTarget() { none() // handled by the shared library diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 578c8fb8ed5..b142f1615e9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -500,7 +500,7 @@ module LocalFlow { * inter-procedurality or field-sensitivity. */ predicate excludeFromExposedRelations(Node n) { - n instanceof SummaryNode or + n instanceof FlowSummaryNode or n instanceof ImplicitCapturedArgumentNode } @@ -559,7 +559,8 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { or LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), true) or nodeTo.(ObjectCreationNode).getPreUpdateNode() = nodeFrom.(ObjectInitializerNode) } @@ -805,7 +806,8 @@ private module Cached { // Add artificial dependencies to enforce all cached predicates are evaluated // in the "DataFlowImplCommon stage" - private predicate forceCaching() { + cached + predicate forceCaching() { TaintTrackingPrivate::forceCachingInSameStage() or exists(any(NodeImpl n).getTypeImpl()) or exists(any(NodeImpl n).getControlFlowNodeImpl()) or @@ -815,10 +817,7 @@ private module Cached { cached newtype TNode = - TExprNode(ControlFlow::Nodes::ElementNode cfn) { - forceCaching() and - cfn.getElement() instanceof Expr - } or + TExprNode(ControlFlow::Nodes::ElementNode cfn) { cfn.getElement() instanceof Expr } or TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or TCilSsaDefinitionExtNode(CilSsaImpl::DefinitionExt def) or TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) { @@ -867,12 +866,7 @@ private module Cached { ) ) } or - TSummaryNode(DataFlowSummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { - FlowSummaryImpl::Private::summaryNodeRange(c, state) - } or - TSummaryParameterNode(DataFlowSummarizedCallable c, ParameterPosition pos) { - FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos) - } or + TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or TParamsArgumentNode(ControlFlow::Node callCfn) { callCfn = any(Call c | isParamsArg(c, _, _)).getAControlFlowNode() } @@ -977,9 +971,7 @@ predicate nodeIsHidden(Node n) { or n instanceof MallocNode or - n instanceof SummaryNode - or - n instanceof SummaryParameterNode + n instanceof FlowSummaryNode or n instanceof ParamsArgumentNode or @@ -1132,29 +1124,28 @@ private module ParameterNodes { } /** A parameter for a library callable with a flow summary. */ - class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode { - private FlowSummaryImpl::Public::SummarizedCallable sc; - private ParameterPosition pos_; + class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode { + SummaryParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) + } - SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) } + private ParameterPosition getPosition() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + } override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { - sc = c.asSummarizedCallable() and pos = pos_ + this.getSummarizedCallable() = c.asSummarizedCallable() and pos = this.getPosition() } - override DataFlowCallable getEnclosingCallableImpl() { result.asSummarizedCallable() = sc } - override Type getTypeImpl() { - exists(int i | pos_.getPosition() = i and result = sc.getParameter(i).getType()) + exists(int i | + this.getPosition().getPosition() = i and + result = this.getSummarizedCallable().getParameter(i).getType() + ) or - pos_.isThisParameter() and result = sc.getDeclaringType() + this.getPosition().isThisParameter() and + result = this.getSummarizedCallable().getDeclaringType() } - - override ControlFlow::Node getControlFlowNodeImpl() { none() } - - override EmptyLocation getLocationImpl() { any() } - - override string toStringImpl() { result = "parameter " + pos_ + " of " + sc } } } @@ -1323,11 +1314,13 @@ private module ArgumentNodes { override string toStringImpl() { result = "[implicit array creation] " + callCfn } } - private class SummaryArgumentNode extends SummaryNode, ArgumentNodeImpl { - SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) } + private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNodeImpl { + SummaryArgumentNode() { + FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _) + } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos) + FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos) } } } @@ -1469,11 +1462,11 @@ private module ReturnNodes { } } - private class SummaryReturnNode extends SummaryNode, ReturnNode { + private class SummaryReturnNode extends FlowSummaryNode, ReturnNode { private ReturnKind rk; SummaryReturnNode() { - FlowSummaryImpl::Private::summaryReturnNode(this, rk) and + FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) and not rk instanceof JumpReturnKind or exists(Parameter p, int pos | @@ -1494,9 +1487,9 @@ private module ReturnNodes { * Holds if summary node `n` is a post-update node for `out`/`ref` parameter `p`. * In this case we adjust it to instead be a return node. */ -private predicate summaryPostUpdateNodeIsOutOrRef(SummaryNode n, Parameter p) { - exists(ParameterNodeImpl pn, DataFlowCallable c, ParameterPosition pos | - FlowSummaryImpl::Private::summaryPostUpdateNode(n, pn) and +private predicate summaryPostUpdateNodeIsOutOrRef(FlowSummaryNode n, Parameter p) { + exists(SummaryParameterNode pn, DataFlowCallable c, ParameterPosition pos | + FlowSummaryImpl::Private::summaryPostUpdateNode(n.getSummaryNode(), pn.getSummaryNode()) and pn.isParameterOf(c, pos) and p = c.asSummarizedCallable().getParameter(pos.getPosition()) and p.isOutOrRef() @@ -1609,11 +1602,11 @@ private module OutNodes { } } - private class SummaryOutNode extends SummaryNode, OutNode { - SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) } + private class SummaryOutNode extends FlowSummaryNode, OutNode { + SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) } override DataFlowCall getCall(ReturnKind kind) { - FlowSummaryImpl::Private::summaryOutNode(result, this, kind) + FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind) } } } @@ -1621,25 +1614,28 @@ private module OutNodes { import OutNodes /** A data-flow node used to model flow summaries. */ -class SummaryNode extends NodeImpl, TSummaryNode { - private FlowSummaryImpl::Public::SummarizedCallable c; - private FlowSummaryImpl::Private::SummaryNodeState state; +class FlowSummaryNode extends NodeImpl, TFlowSummaryNode { + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) } - SummaryNode() { this = TSummaryNode(c, state) } + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() + } - override DataFlowCallable getEnclosingCallableImpl() { result.asSummarizedCallable() = c } + override DataFlowCallable getEnclosingCallableImpl() { + result.asSummarizedCallable() = this.getSummarizedCallable() + } override DataFlowType getDataFlowType() { - result = FlowSummaryImpl::Private::summaryNodeType(this) + result = FlowSummaryImpl::Private::summaryNodeType(this.getSummaryNode()) } override DotNet::Type getTypeImpl() { none() } override ControlFlow::Node getControlFlowNodeImpl() { none() } - override Location getLocationImpl() { result = c.getLocation() } + override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() } - override string toStringImpl() { result = "[summary] " + state + " in " + c } + override string toStringImpl() { result = this.getSummaryNode().toString() } } /** A field or a property. */ @@ -1719,12 +1715,13 @@ predicate jumpStep(Node pred, Node succ) { ) or exists(JumpReturnKind jrk, NonDelegateDataFlowCall call | - FlowSummaryImpl::Private::summaryReturnNode(pred, jrk) and + FlowSummaryImpl::Private::summaryReturnNode(pred.(FlowSummaryNode).getSummaryNode(), jrk) and jrk.getTarget() = call.getATarget(_) and succ = getAnOutNode(call, jrk.getTargetReturnKind()) ) or - FlowSummaryImpl::Private::Steps::summaryJumpStep(pred, succ) + FlowSummaryImpl::Private::Steps::summaryJumpStep(pred.(FlowSummaryNode).getSummaryNode(), + succ.(FlowSummaryNode).getSummaryNode()) } private class StoreStepConfiguration extends ControlFlowReachabilityConfiguration { @@ -1784,7 +1781,8 @@ predicate storeStep(Node node1, Content c, Node node2) { c = getResultContent() ) or - FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) + FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) } private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration { @@ -1907,7 +1905,8 @@ predicate readStep(Node node1, Content c, Node node2) { ) ) or - FlowSummaryImpl::Private::Steps::summaryReadStep(node1, c, node2) + FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) } /** @@ -1920,7 +1919,7 @@ predicate clearsContent(Node n, Content c) { or fieldOrPropertyStore(_, c, _, n.(ObjectInitializerNode).getInitializer(), false) or - FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) or exists(WithExpr we, ObjectInitializer oi, FieldOrProperty f | oi = we.getInitializer() and @@ -1935,7 +1934,7 @@ predicate clearsContent(Node n, Content c) { * at node `n`. */ predicate expectsContent(Node n, ContentSet c) { - FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) } /** @@ -2130,14 +2129,15 @@ private module PostUpdateNodes { override string toStringImpl() { result = "[post] " + cfn.toString() } } - private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNode { + private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode { SummaryPostUpdateNode() { - FlowSummaryImpl::Private::summaryPostUpdateNode(this, _) and + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), _) and not summaryPostUpdateNodeIsOutOrRef(this, _) } override Node getPreUpdateNode() { - FlowSummaryImpl::Private::summaryPostUpdateNode(this, result) + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), + result.(FlowSummaryNode).getSummaryNode()) } } } @@ -2233,7 +2233,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { call.getControlFlowNode()) ) or - receiver = call.(SummaryCall).getReceiver() + receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() ) and exists(kind) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index 97a27c65ef0..b479bb4387e 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -24,11 +24,8 @@ DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = /** Gets the parameter position of the instance parameter. */ ArgumentPosition callbackSelfParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks -/** Gets the synthesized summary data-flow node for the given values. */ -Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) } - /** Gets the synthesized data-flow call for `receiver`. */ -SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() } +SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() } /** Gets the type of content `c`. */ DataFlowType getContentType(Content c) { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll index 7a6ca4891a7..53b61ed5974 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll @@ -156,7 +156,8 @@ private module Cached { // tracking configurations where the source is a collection readStep(nodeFrom, TElementContent(), nodeTo) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), false) or nodeTo = nodeFrom.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false) } From e6e4cef35e10a17d59fe6d0d41150a50e1cc7cc6 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Wed, 24 May 2023 11:42:15 +0200 Subject: [PATCH 479/739] Go: Adjust to FlowSummaryImpl changes. --- .../go/dataflow/internal/DataFlowNodes.qll | 77 +++++++++---------- .../go/dataflow/internal/DataFlowPrivate.qll | 13 ++-- .../go/dataflow/internal/DataFlowUtil.qll | 3 +- .../internal/FlowSummaryImplSpecific.qll | 6 +- .../dataflow/internal/TaintTrackingUtil.qll | 4 +- 5 files changed, 50 insertions(+), 53 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index e78404ca626..84ed6d5f61c 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -11,12 +11,7 @@ private newtype TNode = MkSsaNode(SsaDefinition ssa) or MkGlobalFunctionNode(Function f) or MkImplicitVarargsSlice(CallExpr c) { c.hasImplicitVarargs() } or - MkSummarizedParameterNode(SummarizedCallable c, int i) { - FlowSummaryImpl::Private::summaryParameterNodeRange(c, i) - } or - MkSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { - FlowSummaryImpl::Private::summaryNodeRange(c, state) - } + MkFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) /** Nodes intended for only use inside the data-flow libraries. */ module Private { @@ -30,9 +25,7 @@ module Private { not exists(n.getEnclosingCallable()) and result.asFileScope() = n.getFile() or - n = MkSummarizedParameterNode(result.asSummarizedCallable(), _) - or - n = MkSummaryInternalNode(result.asSummarizedCallable(), _) + result.asSummarizedCallable() = n.(FlowSummaryNode).getSummarizedCallable() } /** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */ @@ -52,7 +45,7 @@ module Private { ReturnNode() { this.(Public::ResultNode).getIndex() = kind.getIndex() or - this.(SummaryNode).isReturn(kind) + this.(FlowSummaryNode).isReturn(kind) } /** Gets the kind of this returned value. */ @@ -72,33 +65,33 @@ module Private { /** * A data-flow node used to model flow summaries. */ - class SummaryNode extends Node, MkSummaryInternalNode { - private SummarizedCallable c; - private FlowSummaryImpl::Private::SummaryNodeState state; + class FlowSummaryNode extends Node, MkFlowSummaryNode { + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = MkFlowSummaryNode(result) } - SummaryNode() { this = MkSummaryInternalNode(c, state) } - - override predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) { - c.hasLocationInfo(fp, sl, sc, el, ec) + SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() } - override string toString() { result = "[summary] " + state + " in " + c } + override predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) { + this.getSummarizedCallable().hasLocationInfo(fp, sl, sc, el, ec) + } + + override string toString() { result = this.getSummaryNode().toString() } /** Holds if this summary node is the `i`th argument of `call`. */ predicate isArgumentOf(DataFlowCall call, int i) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this, i) + FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), i) } /** Holds if this summary node is a return node. */ - predicate isReturn(ReturnKind kind) { FlowSummaryImpl::Private::summaryReturnNode(this, kind) } + predicate isReturn(ReturnKind kind) { + FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), kind) + } /** Holds if this summary node is an out node for `call`. */ - predicate isOut(DataFlowCall call) { FlowSummaryImpl::Private::summaryOutNode(call, this, _) } - } - - /** Gets the summary node corresponding to the callable `c` and state `state`. */ - SummaryNode getSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { - result = MkSummaryInternalNode(c, state) + predicate isOut(DataFlowCall call) { + FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), _) + } } } @@ -661,11 +654,14 @@ module Public { * A summary node which represents a parameter in a function which doesn't * already have a parameter nodes. */ - class SummarizedParameterNode extends ParameterNode, MkSummarizedParameterNode { - SummarizedCallable c; - int i; + class SummarizedParameterNode extends ParameterNode, FlowSummaryNode { + SummarizedParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) + } - SummarizedParameterNode() { this = MkSummarizedParameterNode(c, i) } + private int getPos() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + } // There are no AST representations of summarized parameter nodes override ControlFlow::Root getRoot() { none() } @@ -673,19 +669,14 @@ module Public { override string getNodeKind() { result = "external parameter node" } override Type getType() { - result = c.getType().getParameterType(i) + result = this.getSummarizedCallable().getType().getParameterType(this.getPos()) or - i = -1 and result = c.asFunction().(Method).getReceiverType() + this.getPos() = -1 and + result = this.getSummarizedCallable().asFunction().(Method).getReceiverType() } override predicate isParameterOf(DataFlowCallable call, int idx) { - c = call.asSummarizedCallable() and i = idx - } - - override string toString() { result = "parameter " + i + " of " + c.toString() } - - override predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) { - c.hasLocationInfo(fp, sl, sc, el, ec) + this.getSummarizedCallable() = call.asSummarizedCallable() and this.getPos() = idx } } @@ -1237,10 +1228,12 @@ module Public { private import Private private import Public -class SummaryPostUpdateNode extends SummaryNode, PostUpdateNode { - private Node pre; +class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode { + private FlowSummaryNode pre; - SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) } + SummaryPostUpdateNode() { + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode()) + } override Node getPreUpdateNode() { result = pre } } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index e0adc9f5790..ee146fc2aba 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -129,7 +129,8 @@ predicate jumpStep(Node n1, Node n2) { n2 = recvRead ) or - FlowSummaryImpl::Private::Steps::summaryJumpStep(n1, n2) + FlowSummaryImpl::Private::Steps::summaryJumpStep(n1.(FlowSummaryNode).getSummaryNode(), + n2.(FlowSummaryNode).getSummaryNode()) } /** @@ -153,7 +154,8 @@ predicate storeStep(Node node1, Content c, Node node2) { node1 = node2.(AddressOperationNode).getOperand() and c = any(DataFlow::PointerContent pc | pc.getPointerType() = node2.getType()) or - FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) + FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) or containerStoreStep(node1, node2, c) } @@ -173,7 +175,8 @@ predicate readStep(Node node1, Content c, Node node2) { c = any(DataFlow::FieldContent fc | fc.getField() = read.getField()) ) or - FlowSummaryImpl::Private::Steps::summaryReadStep(node1, c, node2) + FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) or containerReadStep(node1, node2, c) } @@ -197,7 +200,7 @@ predicate clearsContent(Node n, Content c) { * at node `n`. */ predicate expectsContent(Node n, ContentSet c) { - FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) } predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() } @@ -380,7 +383,7 @@ Node getArgument(CallNode c, int i) { } /** Holds if `n` should be hidden from path explanations. */ -predicate nodeIsHidden(Node n) { n instanceof SummaryNode or n instanceof SummarizedParameterNode } +predicate nodeIsHidden(Node n) { n instanceof FlowSummaryNode } class LambdaCallKind = Unit; diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll index 40ec012cc27..ba0728ff02e 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -124,7 +124,8 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { // step through function model any(FunctionModel m).flowStep(nodeFrom, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), true) } /** diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 7afdb314929..46b4a44bab1 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -17,7 +17,7 @@ private module FlowSummaries { class SummarizedCallableBase = Callable; -DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c } +DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c or none() } /** Gets the parameter position of the instance parameter. */ ArgumentPosition callbackSelfParameterPosition() { result = -1 } @@ -28,10 +28,8 @@ string getParameterPosition(ParameterPosition pos) { result = pos.toString() } /** Gets the textual representation of an argument position in the format used for flow summaries. */ string getArgumentPosition(ArgumentPosition pos) { result = pos.toString() } -Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSummaryNode(c, state) } - /** Gets the synthesized data-flow call for `receiver`. */ -DataFlowCall summaryDataFlowCall(Node receiver) { +DataFlowCall summaryDataFlowCall(SummaryNode receiver) { // We do not currently have support for callback-based library models. none() } diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 38e03f62b44..b17b701f84b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -5,6 +5,7 @@ private import go private import FlowSummaryImpl as FlowSummaryImpl private import codeql.util.Unit +private import DataFlowPrivate as DataFlowPrivate /** * Holds if taint can flow from `src` to `sink` in zero or more @@ -95,7 +96,8 @@ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { sliceStep(pred, succ) or any(FunctionModel fm).taintStep(pred, succ) or any(AdditionalTaintStep a).step(pred, succ) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(pred, succ, false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), + succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false) } /** From 1e3b960c1b7038bcc322bed6620ad4c58df9c688 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Wed, 24 May 2023 12:49:54 +0200 Subject: [PATCH 480/739] Python: Adjust to FlowSummaryImpl changes. --- .../new/internal/DataFlowDispatch.qll | 77 +++++++++---------- .../dataflow/new/internal/DataFlowPrivate.qll | 23 +++--- .../dataflow/new/internal/DataFlowPublic.qll | 9 +-- .../new/internal/FlowSummaryImplSpecific.qll | 5 +- 4 files changed, 52 insertions(+), 62 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 895ef74b41e..3084983a605 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1316,7 +1316,9 @@ newtype TDataFlowCall = TNormalCall(CallNode call, Function target, CallType type) { resolveCall(call, target, type) } or TPotentialLibraryCall(CallNode call) or /** A synthesized call inside a summarized callable */ - TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, Node receiver) { + TSummaryCall( + FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver + ) { FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) } @@ -1448,12 +1450,12 @@ class PotentialLibraryCall extends ExtractedDataFlowCall, TPotentialLibraryCall */ class SummaryCall extends DataFlowCall, TSummaryCall { private FlowSummaryImpl::Public::SummarizedCallable c; - private Node receiver; + private FlowSummaryImpl::Private::SummaryNode receiver; SummaryCall() { this = TSummaryCall(c, receiver) } /** Gets the data flow node that this call targets. */ - Node getReceiver() { result = receiver } + FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c } @@ -1486,44 +1488,35 @@ abstract class ParameterNodeImpl extends Node { } /** A parameter for a library callable with a flow summary. */ -class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode { - private FlowSummaryImpl::Public::SummarizedCallable sc; - private ParameterPosition pos; +class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode { + SummaryParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) + } - SummaryParameterNode() { this = TSummaryParameterNode(sc, pos) } + private ParameterPosition getPosition() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + } override Parameter getParameter() { none() } override predicate isParameterOf(DataFlowCallable c, ParameterPosition ppos) { - sc = c.asLibraryCallable() and ppos = pos - } - - override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = sc } - - override string toString() { result = "parameter " + pos + " of " + sc } - - // Hack to return "empty location" - override predicate hasLocationInfo( - string file, int startline, int startcolumn, int endline, int endcolumn - ) { - file = "" and - startline = 0 and - startcolumn = 0 and - endline = 0 and - endcolumn = 0 + this.getSummarizedCallable() = c.asLibraryCallable() and ppos = this.getPosition() } } /** A data-flow node used to model flow summaries. */ -class SummaryNode extends Node, TSummaryNode { - private FlowSummaryImpl::Public::SummarizedCallable c; - private FlowSummaryImpl::Private::SummaryNodeState state; +class FlowSummaryNode extends Node, TFlowSummaryNode { + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) } - SummaryNode() { this = TSummaryNode(c, state) } + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() + } - override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c } + override DataFlowCallable getEnclosingCallable() { + result.asLibraryCallable() = this.getSummarizedCallable() + } - override string toString() { result = "[summary] " + state + " in " + c } + override string toString() { result = this.getSummaryNode().toString() } // Hack to return "empty location" override predicate hasLocationInfo( @@ -1537,26 +1530,30 @@ class SummaryNode extends Node, TSummaryNode { } } -private class SummaryReturnNode extends SummaryNode, ReturnNode { +private class SummaryReturnNode extends FlowSummaryNode, ReturnNode { private ReturnKind rk; - SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this, rk) } + SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) } override ReturnKind getKind() { result = rk } } -private class SummaryArgumentNode extends SummaryNode, ArgumentNode { - SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) } +private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode { + SummaryArgumentNode() { + FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _) + } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos) + FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos) } } -private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNodeImpl { - private Node pre; +private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl { + private FlowSummaryNode pre; - SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) } + SummaryPostUpdateNode() { + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode()) + } override Node getPreUpdateNode() { result = pre } } @@ -1625,11 +1622,11 @@ private module OutNodes { } } - private class SummaryOutNode extends SummaryNode, OutNode { - SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) } + private class SummaryOutNode extends FlowSummaryNode, OutNode { + SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) } override DataFlowCall getCall(ReturnKind kind) { - FlowSummaryImpl::Private::summaryOutNode(result, this, kind) + FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind) } } } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index de493e5bb53..a6dfefb5a77 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -441,14 +441,16 @@ predicate importTimeSummaryFlowStep(Node nodeFrom, Node nodeTo) { // This will miss statements inside functions called from the top level. isTopLevel(nodeFrom) and isTopLevel(nodeTo) and - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), true) } predicate runtimeSummaryFlowStep(Node nodeFrom, Node nodeTo) { // Anything not at the top level can be executed at runtime. not isTopLevel(nodeFrom) and not isTopLevel(nodeTo) and - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), true) } /** `ModuleVariable`s are accessed via jump steps at runtime. */ @@ -529,7 +531,8 @@ predicate jumpStep(Node nodeFrom, Node nodeTo) { or jumpStepNotSharedWithTypeTracker(nodeFrom, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryJumpStep(nodeFrom, nodeTo) + FlowSummaryImpl::Private::Steps::summaryJumpStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode()) } /** @@ -602,7 +605,8 @@ predicate storeStep(Node nodeFrom, Content c, Node nodeTo) { or any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom, c, nodeTo) + FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c, + nodeTo.(FlowSummaryNode).getSummaryNode()) or synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo) or @@ -806,7 +810,8 @@ predicate readStep(Node nodeFrom, Content c, Node nodeTo) { or attributeReadStep(nodeFrom, c, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom, c, nodeTo) + FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c, + nodeTo.(FlowSummaryNode).getSummaryNode()) or synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo) } @@ -921,7 +926,7 @@ predicate clearsContent(Node n, Content c) { or dictClearStep(n, c) or - FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) or dictSplatParameterNodeClearStep(n, c) } @@ -978,9 +983,7 @@ predicate forceHighPrecision(Content c) { none() } predicate nodeIsHidden(Node n) { n instanceof ModuleVariableNode or - n instanceof SummaryNode - or - n instanceof SummaryParameterNode + n instanceof FlowSummaryNode or n instanceof SynthStarArgsElementParameterNode or @@ -1007,7 +1010,7 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) /** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { - receiver = call.(SummaryCall).getReceiver() and + receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() and exists(kind) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 683b17d6db7..49cf972ab04 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -105,14 +105,7 @@ newtype TNode = // So for now we live with having these synthetic ORM nodes for _all_ classes, which // is a bit wasteful, but we don't think it will hurt too much. TSyntheticOrmModelNode(Class cls) or - TSummaryNode( - FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state - ) { - FlowSummaryImpl::Private::summaryNodeRange(c, state) - } or - TSummaryParameterNode(FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition pos) { - FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos) - } or + TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or /** A synthetic node to capture positional arguments that are passed to a `*args` parameter. */ TSynthStarArgsElementParameterNode(DataFlowCallable callable) { exists(ParameterPosition ppos | ppos.isStarArgs(_) | exists(callable.getParameter(ppos))) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll index 67a047d8843..d938de5200a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll @@ -47,11 +47,8 @@ DataFlowCallable inject(SummarizedCallable c) { result.asLibraryCallable() = c } /** Gets the parameter position of the instance parameter. */ ArgumentPosition callbackSelfParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks -/** Gets the synthesized summary data-flow node for the given values. */ -Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) } - /** Gets the synthesized data-flow call for `receiver`. */ -SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() } +SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() } /** Gets the type of content `c`. */ DataFlowType getContentType(Content c) { any() } From 7e87a7c1f726d3033016d45de6edbc642ace5c04 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Fri, 9 Jun 2023 15:29:13 +0200 Subject: [PATCH 481/739] python: rewrite `argumentPositionMatch` to not use the call graph. --- .../python/dataflow/new/internal/TypeTrackerSpecific.qll | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index f3f9b1b52b9..11e49f5f510 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -170,13 +170,12 @@ private import semmle.python.dataflow.new.internal.DataFlowDispatch as DataFlowD pragma[noinline] private predicate argumentPositionMatch( - DataFlowPublic::CallCfgNode call, DataFlowPublic::ArgumentNode arg, + DataFlowPublic::CallCfgNode call, DataFlowPublic::Node arg, DataFlowDispatch::ParameterPosition ppos ) { - exists(DataFlowDispatch::ArgumentPosition apos, DataFlowPrivate::DataFlowCall c | - c.getNode() = call.asCfgNode() and - arg.argumentOf(c, apos) and - DataFlowDispatch::parameterMatch(ppos, apos) + exists(DataFlowDispatch::ArgumentPosition apos | + DataFlowDispatch::parameterMatch(ppos, apos) and + DataFlowDispatch::normalCallArg(call.getNode(), arg, apos) ) } From 4e531af71b70c4a1299840929cf76b1a8fa21904 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Wed, 24 May 2023 13:23:57 +0200 Subject: [PATCH 482/739] Ruby: Adjust to FlowSummaryImpl changes. --- .../dataflow/internal/DataFlowDispatch.qll | 8 +- .../dataflow/internal/DataFlowPrivate.qll | 106 +++++++++--------- .../ruby/dataflow/internal/DataFlowPublic.qll | 2 +- .../internal/FlowSummaryImplSpecific.qll | 5 +- .../internal/TaintTrackingPrivate.qll | 3 +- 5 files changed, 60 insertions(+), 64 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index 625cc226b96..7408412aa91 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -153,12 +153,12 @@ class DataFlowCall extends TDataFlowCall { */ class SummaryCall extends DataFlowCall, TSummaryCall { private FlowSummaryImpl::Public::SummarizedCallable c; - private DataFlow::Node receiver; + private FlowSummaryImpl::Private::SummaryNode receiver; SummaryCall() { this = TSummaryCall(c, receiver) } /** Gets the data flow node that this call targets. */ - DataFlow::Node getReceiver() { result = receiver } + FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c } @@ -377,7 +377,9 @@ private module Cached { cached newtype TDataFlowCall = TNormalCall(CfgNodes::ExprNodes::CallCfgNode c) or - TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, DataFlow::Node receiver) { + TSummaryCall( + FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver + ) { FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 7708eff235a..ecb9393f127 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -309,24 +309,16 @@ private module Cached { n = any(CfgNodes::ExprNodes::InstanceVariableAccessCfgNode v).getReceiver() ) } or - TSummaryNode( - FlowSummaryImpl::Public::SummarizedCallable c, - FlowSummaryImpl::Private::SummaryNodeState state - ) { - FlowSummaryImpl::Private::summaryNodeRange(c, state) - } or - TSummaryParameterNode(FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition pos) { - FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos) - } or + TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or TSynthHashSplatArgumentNode(CfgNodes::ExprNodes::CallCfgNode c) { exists(Argument arg | arg.isArgumentOf(c, any(ArgumentPosition pos | pos.isKeyword(_)))) or c.getAnArgument() instanceof CfgNodes::ExprNodes::PairCfgNode } - class TParameterNode = + class TSourceParameterNode = TNormalParameterNode or TBlockParameterNode or TSelfParameterNode or - TSynthHashSplatParameterNode or TSummaryParameterNode; + TSynthHashSplatParameterNode; cached Location getLocation(NodeImpl n) { result = n.getLocationImpl() } @@ -355,7 +347,8 @@ private module Cached { exprFrom = nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr() ) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), true) } /** This is the local flow predicate that is exposed. */ @@ -412,7 +405,9 @@ private module Cached { cached predicate isLocalSourceNode(Node n) { - n instanceof TParameterNode + n instanceof TSourceParameterNode + or + n instanceof SummaryParameterNode or // Expressions that can't be reached from another entry definition or expression n instanceof ExprNode and @@ -514,9 +509,7 @@ predicate nodeIsHidden(Node n) { or isDesugarNode(n.(ExprNode).getExprNode().getExpr()) or - n instanceof SummaryNode - or - n instanceof SummaryParameterNode + n instanceof FlowSummaryNode or n instanceof SynthHashSplatParameterNode or @@ -757,47 +750,43 @@ private module ParameterNodes { } /** A parameter for a library callable with a flow summary. */ - class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode { - private FlowSummaryImpl::Public::SummarizedCallable sc; - private ParameterPosition pos_; + class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode { + SummaryParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) + } - SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) } + private ParameterPosition getPosition() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + } override Parameter getParameter() { none() } override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { - sc = c.asLibraryCallable() and pos = pos_ + this.getSummarizedCallable() = c.asLibraryCallable() and pos = this.getPosition() } - - override CfgScope getCfgScope() { none() } - - override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = sc } - - override EmptyLocation getLocationImpl() { any() } - - override string toStringImpl() { result = "parameter " + pos_ + " of " + sc } } } import ParameterNodes /** A data-flow node used to model flow summaries. */ -class SummaryNode extends NodeImpl, TSummaryNode { - FlowSummaryImpl::Public::SummarizedCallable c; - FlowSummaryImpl::Private::SummaryNodeState state; - - SummaryNode() { this = TSummaryNode(c, state) } +class FlowSummaryNode extends NodeImpl, TFlowSummaryNode { + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) } /** Gets the summarized callable that this node belongs to. */ - FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { result = c } + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() + } override CfgScope getCfgScope() { none() } - override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c } + override DataFlowCallable getEnclosingCallable() { + result.asLibraryCallable() = this.getSummarizedCallable() + } override EmptyLocation getLocationImpl() { any() } - override string toStringImpl() { result = "[summary] " + state + " in " + c } + override string toStringImpl() { result = this.getSummaryNode().toString() } } /** A data-flow node that represents a call argument. */ @@ -857,15 +846,17 @@ private module ArgumentNodes { } } - private class SummaryArgumentNode extends SummaryNode, ArgumentNode { - SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) } + private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode { + SummaryArgumentNode() { + FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _) + } override predicate sourceArgumentOf(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos) { none() } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos) + FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos) } } @@ -1029,16 +1020,16 @@ private module ReturnNodes { override ReturnKind getKind() { result instanceof NewReturnKind } } - private class SummaryReturnNode extends SummaryNode, ReturnNode { + private class SummaryReturnNode extends FlowSummaryNode, ReturnNode { private ReturnKind rk; - SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this, rk) } + SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) } override ReturnKind getKind() { result = rk or exists(NewCall new | - TLibraryCallable(c) = viableLibraryCallable(new) and + TLibraryCallable(this.getSummarizedCallable()) = viableLibraryCallable(new) and result instanceof NewReturnKind ) } @@ -1071,11 +1062,11 @@ private module OutNodes { } } - private class SummaryOutNode extends SummaryNode, OutNode { - SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) } + private class SummaryOutNode extends FlowSummaryNode, OutNode { + SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) } override DataFlowCall getCall(ReturnKind kind) { - FlowSummaryImpl::Private::summaryOutNode(result, this, kind) + FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind) } } } @@ -1091,7 +1082,8 @@ predicate jumpStep(Node pred, Node succ) { or succ.asExpr().getExpr().(ConstantReadAccess).getValue() = pred.asExpr().getExpr() or - FlowSummaryImpl::Private::Steps::summaryJumpStep(pred, succ) + FlowSummaryImpl::Private::Steps::summaryJumpStep(pred.(FlowSummaryNode).getSummaryNode(), + succ.(FlowSummaryNode).getSummaryNode()) or any(AdditionalJumpStep s).step(pred, succ) } @@ -1156,7 +1148,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { )) ).getReceiver() or - FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) + FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) or storeStepCommon(node1, c, node2) } @@ -1190,7 +1183,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) { or node2 = node1.(SynthHashSplatParameterNode).getAKeywordParameter(c) or - FlowSummaryImpl::Private::Steps::summaryReadStep(node1, c, node2) + FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) } /** @@ -1199,7 +1193,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { * in `x.f = newValue`. */ predicate clearsContent(Node n, ContentSet c) { - FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) or // Filter out keyword arguments that are part of the method signature from // the hash-splat parameter @@ -1220,7 +1214,7 @@ predicate clearsContent(Node n, ContentSet c) { * at node `n`. */ predicate expectsContent(Node n, ContentSet c) { - FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) } private newtype TDataFlowType = @@ -1277,10 +1271,12 @@ private module PostUpdateNodes { override string toStringImpl() { result = "[post] " + e.toString() } } - private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNodeImpl { - private Node pre; + private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl { + private FlowSummaryNode pre; - SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) } + SummaryPostUpdateNode() { + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode()) + } override Node getPreUpdateNode() { result = pre } } @@ -1355,7 +1351,7 @@ predicate lambdaSourceCall(CfgNodes::ExprNodes::CallCfgNode call, LambdaCallKind predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { lambdaSourceCall(call.asCall(), kind, receiver) or - receiver = call.(SummaryCall).getReceiver() and + receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() and if receiver.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pos | pos.isBlock())) then kind = TYieldCallKind() else kind = TLambdaCallKind() diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index 501cf70593e..c6adcbcbe3a 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -191,7 +191,7 @@ class ExprNode extends Node, TExprNode { * The value of a parameter at function entry, viewed as a node in a data * flow graph. */ -class ParameterNode extends LocalSourceNode, TParameterNode instanceof ParameterNodeImpl { +class ParameterNode extends LocalSourceNode instanceof ParameterNodeImpl { /** Gets the parameter corresponding to this node, if any. */ final Parameter getParameter() { result = super.getParameter() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll index d0d9f4b1b5f..f2b0aa01341 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll @@ -18,11 +18,8 @@ DataFlowCallable inject(SummarizedCallable c) { result.asLibraryCallable() = c } /** Gets the parameter position representing a callback itself, if any. */ ArgumentPosition callbackSelfParameterPosition() { none() } // disables implicit summary flow to `self` for callbacks -/** Gets the synthesized summary data-flow node for the given values. */ -Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) } - /** Gets the synthesized data-flow call for `receiver`. */ -SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() } +SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() } /** Gets the type of content `c`. */ DataFlowType getContentType(ContentSet c) { any() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll index 3381187985a..060f1d33bda 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll @@ -96,7 +96,8 @@ private module Cached { ) ) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), false) or any(FlowSteps::AdditionalTaintStep s).step(nodeFrom, nodeTo) or From 1c3b8e2b96698789109f3d42e828c086ea4d9992 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Wed, 24 May 2023 13:39:32 +0200 Subject: [PATCH 483/739] Swift: Adjust to FlowSummaryImpl changes. --- .../dataflow/internal/DataFlowDispatch.qll | 8 +- .../dataflow/internal/DataFlowPrivate.qll | 85 ++++++++++--------- .../internal/FlowSummaryImplSpecific.qll | 5 +- .../internal/TaintTrackingPrivate.qll | 4 +- 4 files changed, 53 insertions(+), 49 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll index 4fc1b70b9a0..94f297e0e2b 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowDispatch.qll @@ -75,7 +75,9 @@ newtype TDataFlowCall = TPropertySetterCall(PropertySetterCfgNode setter) or TPropertyObserverCall(PropertyObserverCfgNode observer) or TKeyPathCall(KeyPathApplicationExprCfgNode keyPathApplication) or - TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, Node receiver) { + TSummaryCall( + FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver + ) { FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) } @@ -232,12 +234,12 @@ class PropertyObserverCall extends DataFlowCall, TPropertyObserverCall { class SummaryCall extends DataFlowCall, TSummaryCall { private FlowSummaryImpl::Public::SummarizedCallable c; - private Node receiver; + private FlowSummaryImpl::Private::SummaryNode receiver; SummaryCall() { this = TSummaryCall(c, receiver) } /** Gets the data flow node that this call targets. */ - Node getReceiver() { result = receiver } + FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } override DataFlowCallable getEnclosingCallable() { result = TSummarizedCallable(c) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index ab2bbc050a4..02ae10b83af 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -90,16 +90,11 @@ private module Cached { TPatternNode(CfgNode n, Pattern p) { hasPatternNode(n, p) } or TSsaDefinitionNode(Ssa::Definition def) or TInoutReturnNode(ParamDecl param) { modifiableParam(param) } or - TSummaryNode(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { - FlowSummaryImpl::Private::summaryNodeRange(c, state) - } or + TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or TSourceParameterNode(ParamDecl param) or TKeyPathParameterNode(EntryNode entry) { entry.getScope() instanceof KeyPathExpr } or TKeyPathReturnNode(ExitNode exit) { exit.getScope() instanceof KeyPathExpr } or TKeyPathComponentNode(KeyPathComponent component) or - TSummaryParameterNode(FlowSummary::SummarizedCallable c, ParameterPosition pos) { - FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos) - } or TExprPostUpdateNode(CfgNode n) { // Obviously, the base of setters needs a post-update node n = any(PropertySetterCfgNode setter).getBase() @@ -223,7 +218,8 @@ private module Cached { nodeFrom.(KeyPathParameterNode).getComponent(0) or // flow through a flow summary (extension of `SummaryModelCsv`) - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), true) } /** @@ -318,22 +314,19 @@ private module ParameterNodes { override ParamDecl getParameter() { result = param } } - class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode { - FlowSummary::SummarizedCallable sc; - ParameterPosition pos; - - SummaryParameterNode() { this = TSummaryParameterNode(sc, pos) } - - override predicate isParameterOf(DataFlowCallable c, ParameterPosition p) { - c.getUnderlyingCallable() = sc and - p = pos + class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode { + SummaryParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) } - override Location getLocationImpl() { result = sc.getLocation() } + private ParameterPosition getPosition() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + } - override string toStringImpl() { result = "[summary param] " + pos + " in " + sc } - - override DataFlowCallable getEnclosingCallable() { this.isParameterOf(result, _) } + override predicate isParameterOf(DataFlowCallable c, ParameterPosition p) { + c.getUnderlyingCallable() = this.getSummarizedCallable() and + p = this.getPosition() + } } class KeyPathParameterNode extends ParameterNodeImpl, TKeyPathParameterNode { @@ -362,17 +355,20 @@ private module ParameterNodes { import ParameterNodes /** A data-flow node used to model flow summaries. */ -class SummaryNode extends NodeImpl, TSummaryNode { - private FlowSummaryImpl::Public::SummarizedCallable c; - private FlowSummaryImpl::Private::SummaryNodeState state; +class FlowSummaryNode extends NodeImpl, TFlowSummaryNode { + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) } - SummaryNode() { this = TSummaryNode(c, state) } + FlowSummary::SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() + } - override DataFlowCallable getEnclosingCallable() { result.asSummarizedCallable() = c } + override DataFlowCallable getEnclosingCallable() { + result.asSummarizedCallable() = this.getSummarizedCallable() + } - override UnknownLocation getLocationImpl() { any() } + override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() } - override string toStringImpl() { result = "[summary] " + state + " in " + c } + override string toStringImpl() { result = this.getSummaryNode().toString() } } /** A data-flow node that represents a call argument. */ @@ -448,11 +444,13 @@ private module ArgumentNodes { } } - class SummaryArgumentNode extends SummaryNode, ArgumentNode { - SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) } + class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode { + SummaryArgumentNode() { + FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _) + } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos) + FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos) } } @@ -521,10 +519,10 @@ private module ReturnNodes { override string toStringImpl() { result = param.toString() + "[return]" } } - private class SummaryReturnNode extends SummaryNode, ReturnNode { + private class SummaryReturnNode extends FlowSummaryNode, ReturnNode { private ReturnKind rk; - SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this, rk) } + SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) } override ReturnKind getKind() { result = rk } } @@ -577,11 +575,11 @@ private module OutNodes { } } - class SummaryOutNode extends OutNode, SummaryNode { - SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) } + class SummaryOutNode extends OutNode, FlowSummaryNode { + SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) } override DataFlowCall getCall(ReturnKind kind) { - FlowSummaryImpl::Private::summaryOutNode(result, this, kind) + FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind) } } @@ -642,7 +640,8 @@ private module OutNodes { import OutNodes predicate jumpStep(Node pred, Node succ) { - FlowSummaryImpl::Private::Steps::summaryJumpStep(pred, succ) + FlowSummaryImpl::Private::Steps::summaryJumpStep(pred.(FlowSummaryNode).getSummaryNode(), + succ.(FlowSummaryNode).getSummaryNode()) } predicate storeStep(Node node1, ContentSet c, Node node2) { @@ -692,7 +691,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { init.isFailable() ) or - FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) + FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) } predicate isLValue(Expr e) { any(AssignExpr assign).getDest() = e } @@ -830,11 +830,14 @@ private module PostUpdateNodes { override DataFlowCallable getEnclosingCallable() { result = TDataFlowFunc(n.getScope()) } } - class SummaryPostUpdateNode extends SummaryNode, PostUpdateNodeImpl { - SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, _) } + class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl { + SummaryPostUpdateNode() { + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), _) + } override Node getPreUpdateNode() { - FlowSummaryImpl::Private::summaryPostUpdateNode(this, result) + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), + result.(FlowSummaryNode).getSummaryNode()) } } } @@ -883,7 +886,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { receiver.asExpr() = call.asCall().getExpr().(ApplyExpr).getFunction() or kind = TLambdaCallKind() and - receiver = call.(SummaryCall).getReceiver() + receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() or kind = TLambdaCallKind() and receiver.asExpr() = call.asKeyPath().getExpr().(KeyPathApplicationExpr).getKeyPath() diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll index d5306461784..f21fe17cd2c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll @@ -20,11 +20,8 @@ DataFlowCallable inject(SummarizedCallable c) { result.getUnderlyingCallable() = /** Gets the parameter position of the instance parameter. */ ArgumentPosition callbackSelfParameterPosition() { result instanceof ThisArgumentPosition } -/** Gets the synthesized summary data-flow node for the given values. */ -Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) } - /** Gets the synthesized data-flow call for `receiver`. */ -SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() } +SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() } /** Gets the type of content `c`. */ DataFlowType getContentType(ContentSet c) { any() } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll index 00e9d4ca9de..7425dd50465 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll @@ -68,7 +68,9 @@ private module Cached { ) or // flow through a flow summary (extension of `SummaryModelCsv`) - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom + .(DataFlowPrivate::FlowSummaryNode) + .getSummaryNode(), nodeTo.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false) or any(AdditionalTaintStep a).step(nodeFrom, nodeTo) } From 6020e4d0e32442426c8814c5835bfff6d2b10a18 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 25 May 2023 13:18:01 +0200 Subject: [PATCH 484/739] C#/Go/Python/Ruby/Swift: Fix some more references. --- csharp/ql/consistency-queries/DataFlowConsistency.ql | 4 ++-- go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll | 4 ++-- .../python/dataflow/new/internal/TaintTrackingPrivate.qll | 4 +++- ruby/ql/consistency-queries/DataFlowConsistency.ql | 4 ++-- .../codeql/swift/dataflow/internal/TaintTrackingPrivate.qll | 5 ++--- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/csharp/ql/consistency-queries/DataFlowConsistency.ql b/csharp/ql/consistency-queries/DataFlowConsistency.ql index d2c83cd82cc..f4c86ae3815 100644 --- a/csharp/ql/consistency-queries/DataFlowConsistency.ql +++ b/csharp/ql/consistency-queries/DataFlowConsistency.ql @@ -37,13 +37,13 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { } override predicate postWithInFlowExclude(Node n) { - n instanceof SummaryNode + n instanceof FlowSummaryNode or n.asExpr().(ObjectCreation).hasInitializer() } override predicate argHasPostUpdateExclude(ArgumentNode n) { - n instanceof SummaryNode + n instanceof FlowSummaryNode or not exists(LocalFlow::getAPostUpdateNodeForArg(n.getControlFlowNode())) or diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index b17b701f84b..21d3f482f6c 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -96,8 +96,8 @@ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { sliceStep(pred, succ) or any(FunctionModel fm).taintStep(pred, succ) or any(AdditionalTaintStep a).step(pred, succ) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), - succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(DataFlowPrivate::FlowSummaryNode) + .getSummaryNode(), succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false) } /** diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 3b32d95ae0b..456fc172169 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -57,7 +57,9 @@ private module Cached { or asyncWithStep(nodeFrom, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom + .(DataFlowPrivate::FlowSummaryNode) + .getSummaryNode(), nodeTo.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false) } } diff --git a/ruby/ql/consistency-queries/DataFlowConsistency.ql b/ruby/ql/consistency-queries/DataFlowConsistency.ql index 67f30db5261..fbfccce4bcb 100644 --- a/ruby/ql/consistency-queries/DataFlowConsistency.ql +++ b/ruby/ql/consistency-queries/DataFlowConsistency.ql @@ -5,12 +5,12 @@ import codeql.ruby.dataflow.internal.DataFlowPrivate import codeql.ruby.dataflow.internal.DataFlowImplConsistency::Consistency private class MyConsistencyConfiguration extends ConsistencyConfiguration { - override predicate postWithInFlowExclude(Node n) { n instanceof SummaryNode } + override predicate postWithInFlowExclude(Node n) { n instanceof FlowSummaryNode } override predicate argHasPostUpdateExclude(ArgumentNode n) { n instanceof BlockArgumentNode or - n instanceof SummaryNode + n instanceof FlowSummaryNode or n instanceof SynthHashSplatArgumentNode or diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll index 7425dd50465..68cdbe0cb46 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll @@ -68,9 +68,8 @@ private module Cached { ) or // flow through a flow summary (extension of `SummaryModelCsv`) - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom - .(DataFlowPrivate::FlowSummaryNode) - .getSummaryNode(), nodeTo.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), false) or any(AdditionalTaintStep a).step(nodeFrom, nodeTo) } From 0c62901a677d6860f02a5b033a035fa93259fdd8 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 25 May 2023 14:12:01 +0200 Subject: [PATCH 485/739] Ruby: Fix tests. --- .../library-tests/dataflow/local/Nodes.ql | 2 +- .../dataflow/local/TaintStep.expected | 72 +++++++++---------- .../frameworks/pathname/Pathname.expected | 44 ++++++------ 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/ruby/ql/test/library-tests/dataflow/local/Nodes.ql b/ruby/ql/test/library-tests/dataflow/local/Nodes.ql index 88ee1c5b208..ee501f9638c 100644 --- a/ruby/ql/test/library-tests/dataflow/local/Nodes.ql +++ b/ruby/ql/test/library-tests/dataflow/local/Nodes.ql @@ -6,5 +6,5 @@ query predicate ret(SourceReturnNode node) { any() } query predicate arg(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { n.argumentOf(call, pos) and - not n instanceof SummaryNode + not n instanceof FlowSummaryNode } diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index e75c17e818e..c1d861ecced 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -2797,43 +2797,43 @@ | UseUseExplosion.rb:21:3686:21:3696 | else ... | UseUseExplosion.rb:21:9:21:3700 | if ... | | UseUseExplosion.rb:21:3691:21:3696 | call to use | UseUseExplosion.rb:21:3686:21:3696 | else ... | | UseUseExplosion.rb:24:5:25:7 | use | UseUseExplosion.rb:1:1:26:3 | C | +| file://:0:0:0:0 | [summary param] position 0 in & | file://:0:0:0:0 | [summary] read: argument position 0.any element in & | +| file://:0:0:0:0 | [summary param] position 0 in + | file://:0:0:0:0 | [summary] read: argument position 0.any element in + | +| file://:0:0:0:0 | [summary param] position 0 in ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge | +| file://:0:0:0:0 | [summary param] position 0 in ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! | +| file://:0:0:0:0 | [summary param] position 0 in ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! | +| file://:0:0:0:0 | [summary param] position 0 in Arel.sql | file://:0:0:0:0 | [summary] to write: return (return) in Arel.sql | +| file://:0:0:0:0 | [summary param] position 0 in Base64.decode64() | file://:0:0:0:0 | [summary] to write: return (return) in Base64.decode64() | +| file://:0:0:0:0 | [summary param] position 0 in ERB.new | file://:0:0:0:0 | [summary] to write: return (return) in ERB.new | +| file://:0:0:0:0 | [summary param] position 0 in File.absolute_path | file://:0:0:0:0 | [summary] to write: return (return) in File.absolute_path | +| file://:0:0:0:0 | [summary param] position 0 in File.dirname | file://:0:0:0:0 | [summary] to write: return (return) in File.dirname | +| file://:0:0:0:0 | [summary param] position 0 in File.expand_path | file://:0:0:0:0 | [summary] to write: return (return) in File.expand_path | +| file://:0:0:0:0 | [summary param] position 0 in File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join | +| file://:0:0:0:0 | [summary param] position 0 in File.path | file://:0:0:0:0 | [summary] to write: return (return) in File.path | +| file://:0:0:0:0 | [summary param] position 0 in File.realdirpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realdirpath | +| file://:0:0:0:0 | [summary param] position 0 in File.realpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realpath | +| file://:0:0:0:0 | [summary param] position 0 in Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] | +| file://:0:0:0:0 | [summary param] position 0 in Mysql2::Client.escape() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.escape() | +| file://:0:0:0:0 | [summary param] position 0 in Mysql2::Client.new() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.new() | +| file://:0:0:0:0 | [summary param] position 0 in PG.new() | file://:0:0:0:0 | [summary] to write: return (return) in PG.new() | +| file://:0:0:0:0 | [summary param] position 0 in SQLite3::Database.quote() | file://:0:0:0:0 | [summary] to write: return (return) in SQLite3::Database.quote() | +| file://:0:0:0:0 | [summary param] position 0 in Sequel.connect | file://:0:0:0:0 | [summary] to write: return (return) in Sequel.connect | +| file://:0:0:0:0 | [summary param] position 0 in String.try_convert | file://:0:0:0:0 | [summary] to write: return (return) in String.try_convert | +| file://:0:0:0:0 | [summary param] position 0 in \| | file://:0:0:0:0 | [summary] read: argument position 0.any element in \| | +| file://:0:0:0:0 | [summary param] position 1.. in File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join | +| file://:0:0:0:0 | [summary param] self in & | file://:0:0:0:0 | [summary] read: argument self.any element in & | +| file://:0:0:0:0 | [summary param] self in * | file://:0:0:0:0 | [summary] read: argument self.any element in * | +| file://:0:0:0:0 | [summary param] self in - | file://:0:0:0:0 | [summary] read: argument self.any element in - | +| file://:0:0:0:0 | [summary param] self in ActionController::Parameters#<various> | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#<various> | +| file://:0:0:0:0 | [summary param] self in ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge | +| file://:0:0:0:0 | [summary param] self in ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! | +| file://:0:0:0:0 | [summary param] self in ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! | +| file://:0:0:0:0 | [summary param] self in ActiveSupportStringTransform | file://:0:0:0:0 | [summary] to write: return (return) in ActiveSupportStringTransform | +| file://:0:0:0:0 | [summary param] self in [] | file://:0:0:0:0 | [summary] to write: return (return) in [] | +| file://:0:0:0:0 | [summary param] self in \| | file://:0:0:0:0 | [summary] read: argument self.any element in \| | +| file://:0:0:0:0 | [summary param] self in assoc-unknown-arg | file://:0:0:0:0 | [summary] read: argument self.any element in assoc-unknown-arg | +| file://:0:0:0:0 | [summary param] self in each(0) | file://:0:0:0:0 | [summary] read: argument self.any element in each(0) | | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element.element 1 or unknown in Hash[] | -| file://:0:0:0:0 | parameter position 0 of & | file://:0:0:0:0 | [summary] read: argument position 0.any element in & | -| file://:0:0:0:0 | parameter position 0 of + | file://:0:0:0:0 | [summary] read: argument position 0.any element in + | -| file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge | -| file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! | -| file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! | -| file://:0:0:0:0 | parameter position 0 of Arel.sql | file://:0:0:0:0 | [summary] to write: return (return) in Arel.sql | -| file://:0:0:0:0 | parameter position 0 of Base64.decode64() | file://:0:0:0:0 | [summary] to write: return (return) in Base64.decode64() | -| file://:0:0:0:0 | parameter position 0 of ERB.new | file://:0:0:0:0 | [summary] to write: return (return) in ERB.new | -| file://:0:0:0:0 | parameter position 0 of File.absolute_path | file://:0:0:0:0 | [summary] to write: return (return) in File.absolute_path | -| file://:0:0:0:0 | parameter position 0 of File.dirname | file://:0:0:0:0 | [summary] to write: return (return) in File.dirname | -| file://:0:0:0:0 | parameter position 0 of File.expand_path | file://:0:0:0:0 | [summary] to write: return (return) in File.expand_path | -| file://:0:0:0:0 | parameter position 0 of File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join | -| file://:0:0:0:0 | parameter position 0 of File.path | file://:0:0:0:0 | [summary] to write: return (return) in File.path | -| file://:0:0:0:0 | parameter position 0 of File.realdirpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realdirpath | -| file://:0:0:0:0 | parameter position 0 of File.realpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realpath | -| file://:0:0:0:0 | parameter position 0 of Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] | -| file://:0:0:0:0 | parameter position 0 of Mysql2::Client.escape() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.escape() | -| file://:0:0:0:0 | parameter position 0 of Mysql2::Client.new() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.new() | -| file://:0:0:0:0 | parameter position 0 of PG.new() | file://:0:0:0:0 | [summary] to write: return (return) in PG.new() | -| file://:0:0:0:0 | parameter position 0 of SQLite3::Database.quote() | file://:0:0:0:0 | [summary] to write: return (return) in SQLite3::Database.quote() | -| file://:0:0:0:0 | parameter position 0 of Sequel.connect | file://:0:0:0:0 | [summary] to write: return (return) in Sequel.connect | -| file://:0:0:0:0 | parameter position 0 of String.try_convert | file://:0:0:0:0 | [summary] to write: return (return) in String.try_convert | -| file://:0:0:0:0 | parameter position 0 of \| | file://:0:0:0:0 | [summary] read: argument position 0.any element in \| | -| file://:0:0:0:0 | parameter position 1.. of File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join | -| file://:0:0:0:0 | parameter self of & | file://:0:0:0:0 | [summary] read: argument self.any element in & | -| file://:0:0:0:0 | parameter self of * | file://:0:0:0:0 | [summary] read: argument self.any element in * | -| file://:0:0:0:0 | parameter self of - | file://:0:0:0:0 | [summary] read: argument self.any element in - | -| file://:0:0:0:0 | parameter self of ActionController::Parameters#<various> | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#<various> | -| file://:0:0:0:0 | parameter self of ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge | -| file://:0:0:0:0 | parameter self of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! | -| file://:0:0:0:0 | parameter self of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! | -| file://:0:0:0:0 | parameter self of ActiveSupportStringTransform | file://:0:0:0:0 | [summary] to write: return (return) in ActiveSupportStringTransform | -| file://:0:0:0:0 | parameter self of [] | file://:0:0:0:0 | [summary] to write: return (return) in [] | -| file://:0:0:0:0 | parameter self of \| | file://:0:0:0:0 | [summary] read: argument self.any element in \| | -| file://:0:0:0:0 | parameter self of assoc-unknown-arg | file://:0:0:0:0 | [summary] read: argument self.any element in assoc-unknown-arg | -| file://:0:0:0:0 | parameter self of each(0) | file://:0:0:0:0 | [summary] read: argument self.any element in each(0) | | local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self | | local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) | | local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self | diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected index d082076be69..c5639c0245c 100644 --- a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected @@ -57,17 +57,17 @@ pathnameInstances | Pathname.rb:39:12:39:19 | foo_path | | Pathname.rb:41:1:41:3 | p08 | | Pathname.rb:42:1:42:3 | p01 | -| file://:0:0:0:0 | parameter position 0 of + | -| file://:0:0:0:0 | parameter self of + | -| file://:0:0:0:0 | parameter self of Pathname;Method[cleanpath] | -| file://:0:0:0:0 | parameter self of Pathname;Method[expand_path] | -| file://:0:0:0:0 | parameter self of Pathname;Method[realpath] | -| file://:0:0:0:0 | parameter self of Pathname;Method[relative_path_from] | -| file://:0:0:0:0 | parameter self of Pathname;Method[sub_ext] | -| file://:0:0:0:0 | parameter self of Pathname;Method[to_path] | -| file://:0:0:0:0 | parameter self of join | -| file://:0:0:0:0 | parameter self of sub | -| file://:0:0:0:0 | parameter self of to_s | +| file://:0:0:0:0 | [summary param] position 0 in + | +| file://:0:0:0:0 | [summary param] self in + | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[cleanpath] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[expand_path] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[realpath] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[relative_path_from] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[sub_ext] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[to_path] | +| file://:0:0:0:0 | [summary param] self in join | +| file://:0:0:0:0 | [summary param] self in sub | +| file://:0:0:0:0 | [summary param] self in to_s | fileSystemAccesses | Pathname.rb:26:12:26:24 | call to open | Pathname.rb:26:12:26:19 | foo_path | | Pathname.rb:28:11:28:22 | call to opendir | Pathname.rb:28:11:28:14 | pwd1 | @@ -134,17 +134,17 @@ fileNameSources | Pathname.rb:39:12:39:19 | foo_path | | Pathname.rb:41:1:41:3 | p08 | | Pathname.rb:42:1:42:3 | p01 | -| file://:0:0:0:0 | parameter position 0 of + | -| file://:0:0:0:0 | parameter self of + | -| file://:0:0:0:0 | parameter self of Pathname;Method[cleanpath] | -| file://:0:0:0:0 | parameter self of Pathname;Method[expand_path] | -| file://:0:0:0:0 | parameter self of Pathname;Method[realpath] | -| file://:0:0:0:0 | parameter self of Pathname;Method[relative_path_from] | -| file://:0:0:0:0 | parameter self of Pathname;Method[sub_ext] | -| file://:0:0:0:0 | parameter self of Pathname;Method[to_path] | -| file://:0:0:0:0 | parameter self of join | -| file://:0:0:0:0 | parameter self of sub | -| file://:0:0:0:0 | parameter self of to_s | +| file://:0:0:0:0 | [summary param] position 0 in + | +| file://:0:0:0:0 | [summary param] self in + | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[cleanpath] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[expand_path] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[realpath] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[relative_path_from] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[sub_ext] | +| file://:0:0:0:0 | [summary param] self in Pathname;Method[to_path] | +| file://:0:0:0:0 | [summary param] self in join | +| file://:0:0:0:0 | [summary param] self in sub | +| file://:0:0:0:0 | [summary param] self in to_s | fileSystemReadAccesses | Pathname.rb:32:12:32:24 | call to read | Pathname.rb:32:12:32:24 | call to read | fileSystemWriteAccesses From 5eb278095ca1fd2abdfdacf1c688d17cc9c0bb55 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 25 May 2023 14:15:28 +0200 Subject: [PATCH 486/739] Go: Fix tests. --- .../example-tests/snippets/typeinfo.expected | 8 +- .../FlowSteps/LocalTaintStep.expected | 566 +++--- .../frameworks/TaintSteps/TaintStep.expected | 1710 ++++++++--------- 3 files changed, 1142 insertions(+), 1142 deletions(-) diff --git a/go/ql/test/example-tests/snippets/typeinfo.expected b/go/ql/test/example-tests/snippets/typeinfo.expected index c3b63b1b25b..728a1dfc6f7 100644 --- a/go/ql/test/example-tests/snippets/typeinfo.expected +++ b/go/ql/test/example-tests/snippets/typeinfo.expected @@ -1,7 +1,7 @@ -| file://:0:0:0:0 | parameter -1 of AddCookie | -| file://:0:0:0:0 | parameter -1 of Clone | -| file://:0:0:0:0 | parameter -1 of Write | -| file://:0:0:0:0 | parameter -1 of WriteProxy | +| file://:0:0:0:0 | [summary param] -1 in AddCookie | +| file://:0:0:0:0 | [summary param] -1 in Clone | +| file://:0:0:0:0 | [summary param] -1 in Write | +| file://:0:0:0:0 | [summary param] -1 in WriteProxy | | main.go:18:12:18:14 | argument corresponding to req | | main.go:18:12:18:14 | definition of req | | main.go:20:5:20:7 | req | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected index 54091adf7d1..d875c24c49a 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected @@ -1,286 +1,286 @@ -| file://:0:0:0:0 | parameter 0 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | -| file://:0:0:0:0 | parameter 0 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | -| file://:0:0:0:0 | parameter 0 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | -| file://:0:0:0:0 | parameter 0 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | -| file://:0:0:0:0 | parameter 0 of As | file://:0:0:0:0 | [summary] to write: argument 1 in As | -| file://:0:0:0:0 | parameter 0 of Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | -| file://:0:0:0:0 | parameter 0 of BytePtrFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in BytePtrFromString | -| file://:0:0:0:0 | parameter 0 of ByteSliceFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ByteSliceFromString | -| file://:0:0:0:0 | parameter 0 of Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | -| file://:0:0:0:0 | parameter 0 of Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | -| file://:0:0:0:0 | parameter 0 of Expand | file://:0:0:0:0 | [summary] to write: return (return[0]) in Expand | -| file://:0:0:0:0 | parameter 0 of ExpandEnv | file://:0:0:0:0 | [summary] to write: return (return[0]) in ExpandEnv | -| file://:0:0:0:0 | parameter 0 of Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | -| file://:0:0:0:0 | parameter 0 of Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | -| file://:0:0:0:0 | parameter 0 of FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | -| file://:0:0:0:0 | parameter 0 of FileInfoToDirEntry | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileInfoToDirEntry | -| file://:0:0:0:0 | parameter 0 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | -| file://:0:0:0:0 | parameter 0 of Indirect | file://:0:0:0:0 | [summary] to write: return (return[0]) in Indirect | -| file://:0:0:0:0 | parameter 0 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | -| file://:0:0:0:0 | parameter 0 of LimitReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in LimitReader | -| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | -| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | -| file://:0:0:0:0 | parameter 0 of LoadPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadPointer | -| file://:0:0:0:0 | parameter 0 of LoadUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadUintptr | -| file://:0:0:0:0 | parameter 0 of New | file://:0:0:0:0 | [summary] to write: return (return[0]) in New | -| file://:0:0:0:0 | parameter 0 of NewFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewFile | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewSectionReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewSectionReader | -| file://:0:0:0:0 | parameter 0 of NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | -| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | -| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | -| file://:0:0:0:0 | parameter 0 of ParseQuery | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseQuery | -| file://:0:0:0:0 | parameter 0 of ParseRequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseRequestURI | -| file://:0:0:0:0 | parameter 0 of PathEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathEscape | -| file://:0:0:0:0 | parameter 0 of PathUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathUnescape | -| file://:0:0:0:0 | parameter 0 of Put | file://:0:0:0:0 | [summary] to write: argument -1 in Put | -| file://:0:0:0:0 | parameter 0 of QueryEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryEscape | -| file://:0:0:0:0 | parameter 0 of QueryUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryUnescape | -| file://:0:0:0:0 | parameter 0 of Quote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Quote | -| file://:0:0:0:0 | parameter 0 of QuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToASCII | -| file://:0:0:0:0 | parameter 0 of QuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToGraphic | -| file://:0:0:0:0 | parameter 0 of QuotedPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuotedPrefix | -| file://:0:0:0:0 | parameter 0 of ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | -| file://:0:0:0:0 | parameter 0 of ReadAtLeast | file://:0:0:0:0 | [summary] to write: argument 1 in ReadAtLeast | -| file://:0:0:0:0 | parameter 0 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | -| file://:0:0:0:0 | parameter 0 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFull | file://:0:0:0:0 | [summary] to write: argument 1 in ReadFull | -| file://:0:0:0:0 | parameter 0 of Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | -| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | -| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | -| file://:0:0:0:0 | parameter 0 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | -| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | -| file://:0:0:0:0 | parameter 0 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | -| file://:0:0:0:0 | parameter 0 of Reverse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Reverse | -| file://:0:0:0:0 | parameter 0 of Send | file://:0:0:0:0 | [summary] to write: argument -1 in Send | -| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | -| file://:0:0:0:0 | parameter 0 of SetBytes | file://:0:0:0:0 | [summary] to write: argument -1 in SetBytes | -| file://:0:0:0:0 | parameter 0 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | -| file://:0:0:0:0 | parameter 0 of SetPointer | file://:0:0:0:0 | [summary] to write: argument -1 in SetPointer | -| file://:0:0:0:0 | parameter 0 of SetString | file://:0:0:0:0 | [summary] to write: argument -1 in SetString | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | -| file://:0:0:0:0 | parameter 0 of SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | -| file://:0:0:0:0 | parameter 0 of SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | -| file://:0:0:0:0 | parameter 0 of SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | -| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 0 of StringBytePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringBytePtr | -| file://:0:0:0:0 | parameter 0 of StringByteSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringByteSlice | -| file://:0:0:0:0 | parameter 0 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | -| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 0 of SwapPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapPointer | -| file://:0:0:0:0 | parameter 0 of SwapUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapUintptr | -| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: argument 1 in TeeReader | -| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in TeeReader | -| file://:0:0:0:0 | parameter 0 of Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | -| file://:0:0:0:0 | parameter 0 of ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | -| file://:0:0:0:0 | parameter 0 of ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | -| file://:0:0:0:0 | parameter 0 of ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | -| file://:0:0:0:0 | parameter 0 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | -| file://:0:0:0:0 | parameter 0 of Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | -| file://:0:0:0:0 | parameter 0 of TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | -| file://:0:0:0:0 | parameter 0 of TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | -| file://:0:0:0:0 | parameter 0 of TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | -| file://:0:0:0:0 | parameter 0 of TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | -| file://:0:0:0:0 | parameter 0 of TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | -| file://:0:0:0:0 | parameter 0 of TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | -| file://:0:0:0:0 | parameter 0 of TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | -| file://:0:0:0:0 | parameter 0 of TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | -| file://:0:0:0:0 | parameter 0 of TrySend | file://:0:0:0:0 | [summary] to write: argument -1 in TrySend | -| file://:0:0:0:0 | parameter 0 of Unquote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unquote | -| file://:0:0:0:0 | parameter 0 of UnquoteChar | file://:0:0:0:0 | [summary] to write: return (return[2]) in UnquoteChar | -| file://:0:0:0:0 | parameter 0 of Unwrap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unwrap | -| file://:0:0:0:0 | parameter 0 of User | file://:0:0:0:0 | [summary] to write: return (return[0]) in User | -| file://:0:0:0:0 | parameter 0 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | -| file://:0:0:0:0 | parameter 0 of ValueOf | file://:0:0:0:0 | [summary] to write: return (return[0]) in ValueOf | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | -| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | -| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in AddUintptr | -| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in AddUintptr | -| file://:0:0:0:0 | parameter 1 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | -| file://:0:0:0:0 | parameter 1 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | -| file://:0:0:0:0 | parameter 1 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | -| file://:0:0:0:0 | parameter 1 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | -| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | -| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | -| file://:0:0:0:0 | parameter 1 of CopyBuffer | file://:0:0:0:0 | [summary] to write: argument 0 in CopyBuffer | -| file://:0:0:0:0 | parameter 1 of CopyN | file://:0:0:0:0 | [summary] to write: argument 0 in CopyN | -| file://:0:0:0:0 | parameter 1 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | -| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | -| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | -| file://:0:0:0:0 | parameter 1 of Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | -| file://:0:0:0:0 | parameter 1 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | -| file://:0:0:0:0 | parameter 1 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 1 of StorePointer | file://:0:0:0:0 | [summary] to write: argument 0 in StorePointer | -| file://:0:0:0:0 | parameter 1 of StoreUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in StoreUintptr | -| file://:0:0:0:0 | parameter 1 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 1 of SwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in SwapPointer | -| file://:0:0:0:0 | parameter 1 of SwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in SwapUintptr | -| file://:0:0:0:0 | parameter 1 of ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | -| file://:0:0:0:0 | parameter 1 of ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | -| file://:0:0:0:0 | parameter 1 of ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | -| file://:0:0:0:0 | parameter 1 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | -| file://:0:0:0:0 | parameter 1 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | -| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | -| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | -| file://:0:0:0:0 | parameter 2 of CompareAndSwap | file://:0:0:0:0 | [summary] to write: argument -1 in CompareAndSwap | -| file://:0:0:0:0 | parameter 2 of CompareAndSwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapPointer | -| file://:0:0:0:0 | parameter 2 of CompareAndSwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapUintptr | -| file://:0:0:0:0 | parameter 2 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | -| file://:0:0:0:0 | parameter 2 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | -| file://:0:0:0:0 | parameter -1 of Addr | file://:0:0:0:0 | [summary] to write: return (return[0]) in Addr | -| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | -| file://:0:0:0:0 | parameter -1 of Convert | file://:0:0:0:0 | [summary] to write: return (return[0]) in Convert | -| file://:0:0:0:0 | parameter -1 of Elem | file://:0:0:0:0 | [summary] to write: return (return[0]) in Elem | -| file://:0:0:0:0 | parameter -1 of Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | -| file://:0:0:0:0 | parameter -1 of EscapedPath | file://:0:0:0:0 | [summary] to write: return (return[0]) in EscapedPath | -| file://:0:0:0:0 | parameter -1 of Fd | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fd | -| file://:0:0:0:0 | parameter -1 of Field | file://:0:0:0:0 | [summary] to write: return (return[0]) in Field | -| file://:0:0:0:0 | parameter -1 of FieldByIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByIndex | -| file://:0:0:0:0 | parameter -1 of FieldByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByName | -| file://:0:0:0:0 | parameter -1 of FieldByNameFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByNameFunc | -| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | -| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | -| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | -| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | -| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of Hostname | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hostname | -| file://:0:0:0:0 | parameter -1 of Index | file://:0:0:0:0 | [summary] to write: return (return[0]) in Index | -| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | -| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | -| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | -| file://:0:0:0:0 | parameter -1 of Interface | file://:0:0:0:0 | [summary] to write: return (return[0]) in Interface | -| file://:0:0:0:0 | parameter -1 of InterfaceData | file://:0:0:0:0 | [summary] to write: return (return[0]) in InterfaceData | -| file://:0:0:0:0 | parameter -1 of Key | file://:0:0:0:0 | [summary] to write: return (return[0]) in Key | -| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | -| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | -| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | -| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | -| file://:0:0:0:0 | parameter -1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | -| file://:0:0:0:0 | parameter -1 of Lookup | file://:0:0:0:0 | [summary] to write: return (return[0]) in Lookup | -| file://:0:0:0:0 | parameter -1 of MapIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapIndex | -| file://:0:0:0:0 | parameter -1 of MapKeys | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapKeys | -| file://:0:0:0:0 | parameter -1 of MapRange | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapRange | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of Method | file://:0:0:0:0 | [summary] to write: return (return[0]) in Method | -| file://:0:0:0:0 | parameter -1 of MethodByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in MethodByName | -| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | -| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | -| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | -| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter -1 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | -| file://:0:0:0:0 | parameter -1 of Password | file://:0:0:0:0 | [summary] to write: return (return[0]) in Password | -| file://:0:0:0:0 | parameter -1 of Pointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Pointer | -| file://:0:0:0:0 | parameter -1 of Port | file://:0:0:0:0 | [summary] to write: return (return[0]) in Port | -| file://:0:0:0:0 | parameter -1 of Query | file://:0:0:0:0 | [summary] to write: return (return[0]) in Query | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | -| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | -| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | -| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | -| file://:0:0:0:0 | parameter -1 of Recv | file://:0:0:0:0 | [summary] to write: return (return[0]) in Recv | -| file://:0:0:0:0 | parameter -1 of RequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in RequestURI | -| file://:0:0:0:0 | parameter -1 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | -| file://:0:0:0:0 | parameter -1 of Slice | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice | -| file://:0:0:0:0 | parameter -1 of Slice3 | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice3 | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | -| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | -| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | -| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | -| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | -| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | -| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | -| file://:0:0:0:0 | parameter -1 of TryRecv | file://:0:0:0:0 | [summary] to write: return (return[0]) in TryRecv | -| file://:0:0:0:0 | parameter -1 of UnsafeAddr | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnsafeAddr | -| file://:0:0:0:0 | parameter -1 of Username | file://:0:0:0:0 | [summary] to write: return (return[0]) in Username | -| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] 0 in AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | +| file://:0:0:0:0 | [summary param] 0 in AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | +| file://:0:0:0:0 | [summary param] 0 in AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | +| file://:0:0:0:0 | [summary param] 0 in AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | +| file://:0:0:0:0 | [summary param] 0 in As | file://:0:0:0:0 | [summary] to write: argument 1 in As | +| file://:0:0:0:0 | [summary param] 0 in Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | +| file://:0:0:0:0 | [summary param] 0 in BytePtrFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in BytePtrFromString | +| file://:0:0:0:0 | [summary param] 0 in ByteSliceFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ByteSliceFromString | +| file://:0:0:0:0 | [summary param] 0 in Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | +| file://:0:0:0:0 | [summary param] 0 in Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | +| file://:0:0:0:0 | [summary param] 0 in Expand | file://:0:0:0:0 | [summary] to write: return (return[0]) in Expand | +| file://:0:0:0:0 | [summary param] 0 in ExpandEnv | file://:0:0:0:0 | [summary] to write: return (return[0]) in ExpandEnv | +| file://:0:0:0:0 | [summary param] 0 in Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | +| file://:0:0:0:0 | [summary param] 0 in Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | +| file://:0:0:0:0 | [summary param] 0 in FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | +| file://:0:0:0:0 | [summary param] 0 in FileInfoToDirEntry | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileInfoToDirEntry | +| file://:0:0:0:0 | [summary param] 0 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | [summary param] 0 in Indirect | file://:0:0:0:0 | [summary] to write: return (return[0]) in Indirect | +| file://:0:0:0:0 | [summary param] 0 in Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | [summary param] 0 in LimitReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in LimitReader | +| file://:0:0:0:0 | [summary param] 0 in LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | +| file://:0:0:0:0 | [summary param] 0 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | [summary param] 0 in LoadPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadPointer | +| file://:0:0:0:0 | [summary param] 0 in LoadUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadUintptr | +| file://:0:0:0:0 | [summary param] 0 in New | file://:0:0:0:0 | [summary] to write: return (return[0]) in New | +| file://:0:0:0:0 | [summary param] 0 in NewFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewFile | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewSectionReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewSectionReader | +| file://:0:0:0:0 | [summary param] 0 in NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | +| file://:0:0:0:0 | [summary param] 0 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | [summary param] 0 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | [summary param] 0 in ParseQuery | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseQuery | +| file://:0:0:0:0 | [summary param] 0 in ParseRequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseRequestURI | +| file://:0:0:0:0 | [summary param] 0 in PathEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathEscape | +| file://:0:0:0:0 | [summary param] 0 in PathUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathUnescape | +| file://:0:0:0:0 | [summary param] 0 in Put | file://:0:0:0:0 | [summary] to write: argument -1 in Put | +| file://:0:0:0:0 | [summary param] 0 in QueryEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryEscape | +| file://:0:0:0:0 | [summary param] 0 in QueryUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryUnescape | +| file://:0:0:0:0 | [summary param] 0 in Quote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Quote | +| file://:0:0:0:0 | [summary param] 0 in QuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToASCII | +| file://:0:0:0:0 | [summary param] 0 in QuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToGraphic | +| file://:0:0:0:0 | [summary param] 0 in QuotedPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuotedPrefix | +| file://:0:0:0:0 | [summary param] 0 in ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | +| file://:0:0:0:0 | [summary param] 0 in ReadAtLeast | file://:0:0:0:0 | [summary] to write: argument 1 in ReadAtLeast | +| file://:0:0:0:0 | [summary param] 0 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | [summary param] 0 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFull | file://:0:0:0:0 | [summary] to write: argument 1 in ReadFull | +| file://:0:0:0:0 | [summary param] 0 in Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | +| file://:0:0:0:0 | [summary param] 0 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | [summary param] 0 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | [summary param] 0 in ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | [summary param] 0 in Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | [summary param] 0 in ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | +| file://:0:0:0:0 | [summary param] 0 in Reverse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Reverse | +| file://:0:0:0:0 | [summary param] 0 in Send | file://:0:0:0:0 | [summary] to write: argument -1 in Send | +| file://:0:0:0:0 | [summary param] 0 in Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | [summary param] 0 in SetBytes | file://:0:0:0:0 | [summary] to write: argument -1 in SetBytes | +| file://:0:0:0:0 | [summary param] 0 in SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | +| file://:0:0:0:0 | [summary param] 0 in SetPointer | file://:0:0:0:0 | [summary] to write: argument -1 in SetPointer | +| file://:0:0:0:0 | [summary param] 0 in SetString | file://:0:0:0:0 | [summary] to write: argument -1 in SetString | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | +| file://:0:0:0:0 | [summary param] 0 in SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | +| file://:0:0:0:0 | [summary param] 0 in SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | +| file://:0:0:0:0 | [summary param] 0 in SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | +| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 0 in StringBytePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringBytePtr | +| file://:0:0:0:0 | [summary param] 0 in StringByteSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringByteSlice | +| file://:0:0:0:0 | [summary param] 0 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 0 in SwapPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapPointer | +| file://:0:0:0:0 | [summary param] 0 in SwapUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapUintptr | +| file://:0:0:0:0 | [summary param] 0 in TeeReader | file://:0:0:0:0 | [summary] to write: argument 1 in TeeReader | +| file://:0:0:0:0 | [summary param] 0 in TeeReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in TeeReader | +| file://:0:0:0:0 | [summary param] 0 in Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | +| file://:0:0:0:0 | [summary param] 0 in ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | +| file://:0:0:0:0 | [summary param] 0 in ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | +| file://:0:0:0:0 | [summary param] 0 in ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | +| file://:0:0:0:0 | [summary param] 0 in ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | [summary param] 0 in Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | +| file://:0:0:0:0 | [summary param] 0 in TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | +| file://:0:0:0:0 | [summary param] 0 in TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | +| file://:0:0:0:0 | [summary param] 0 in TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | +| file://:0:0:0:0 | [summary param] 0 in TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | +| file://:0:0:0:0 | [summary param] 0 in TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | +| file://:0:0:0:0 | [summary param] 0 in TrySend | file://:0:0:0:0 | [summary] to write: argument -1 in TrySend | +| file://:0:0:0:0 | [summary param] 0 in Unquote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unquote | +| file://:0:0:0:0 | [summary param] 0 in UnquoteChar | file://:0:0:0:0 | [summary] to write: return (return[2]) in UnquoteChar | +| file://:0:0:0:0 | [summary param] 0 in Unwrap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unwrap | +| file://:0:0:0:0 | [summary param] 0 in User | file://:0:0:0:0 | [summary] to write: return (return[0]) in User | +| file://:0:0:0:0 | [summary param] 0 in UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | +| file://:0:0:0:0 | [summary param] 0 in ValueOf | file://:0:0:0:0 | [summary] to write: return (return[0]) in ValueOf | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 1 in AddUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in AddUintptr | +| file://:0:0:0:0 | [summary param] 1 in AddUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in AddUintptr | +| file://:0:0:0:0 | [summary param] 1 in AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | +| file://:0:0:0:0 | [summary param] 1 in AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | +| file://:0:0:0:0 | [summary param] 1 in AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | +| file://:0:0:0:0 | [summary param] 1 in AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | +| file://:0:0:0:0 | [summary param] 1 in Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | +| file://:0:0:0:0 | [summary param] 1 in Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | +| file://:0:0:0:0 | [summary param] 1 in CopyBuffer | file://:0:0:0:0 | [summary] to write: argument 0 in CopyBuffer | +| file://:0:0:0:0 | [summary param] 1 in CopyN | file://:0:0:0:0 | [summary] to write: argument 0 in CopyN | +| file://:0:0:0:0 | [summary param] 1 in Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | [summary param] 1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | +| file://:0:0:0:0 | [summary param] 1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | [summary param] 1 in Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | +| file://:0:0:0:0 | [summary param] 1 in SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | +| file://:0:0:0:0 | [summary param] 1 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 1 in StorePointer | file://:0:0:0:0 | [summary] to write: argument 0 in StorePointer | +| file://:0:0:0:0 | [summary param] 1 in StoreUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in StoreUintptr | +| file://:0:0:0:0 | [summary param] 1 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 1 in SwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in SwapPointer | +| file://:0:0:0:0 | [summary param] 1 in SwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in SwapUintptr | +| file://:0:0:0:0 | [summary param] 1 in ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | [summary param] 1 in UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | +| file://:0:0:0:0 | [summary param] 1 in WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | +| file://:0:0:0:0 | [summary param] 1 in WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | +| file://:0:0:0:0 | [summary param] 2 in CompareAndSwap | file://:0:0:0:0 | [summary] to write: argument -1 in CompareAndSwap | +| file://:0:0:0:0 | [summary param] 2 in CompareAndSwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapPointer | +| file://:0:0:0:0 | [summary param] 2 in CompareAndSwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapUintptr | +| file://:0:0:0:0 | [summary param] 2 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | [summary param] 2 in ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | [summary param] -1 in Addr | file://:0:0:0:0 | [summary] to write: return (return[0]) in Addr | +| file://:0:0:0:0 | [summary param] -1 in Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | +| file://:0:0:0:0 | [summary param] -1 in Convert | file://:0:0:0:0 | [summary] to write: return (return[0]) in Convert | +| file://:0:0:0:0 | [summary param] -1 in Elem | file://:0:0:0:0 | [summary] to write: return (return[0]) in Elem | +| file://:0:0:0:0 | [summary param] -1 in Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | +| file://:0:0:0:0 | [summary param] -1 in EscapedPath | file://:0:0:0:0 | [summary] to write: return (return[0]) in EscapedPath | +| file://:0:0:0:0 | [summary param] -1 in Fd | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fd | +| file://:0:0:0:0 | [summary param] -1 in Field | file://:0:0:0:0 | [summary] to write: return (return[0]) in Field | +| file://:0:0:0:0 | [summary param] -1 in FieldByIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByIndex | +| file://:0:0:0:0 | [summary param] -1 in FieldByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByName | +| file://:0:0:0:0 | [summary param] -1 in FieldByNameFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByNameFunc | +| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | [summary param] -1 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | [summary param] -1 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in Hostname | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hostname | +| file://:0:0:0:0 | [summary param] -1 in Index | file://:0:0:0:0 | [summary] to write: return (return[0]) in Index | +| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | [summary param] -1 in Interface | file://:0:0:0:0 | [summary] to write: return (return[0]) in Interface | +| file://:0:0:0:0 | [summary param] -1 in InterfaceData | file://:0:0:0:0 | [summary] to write: return (return[0]) in InterfaceData | +| file://:0:0:0:0 | [summary param] -1 in Key | file://:0:0:0:0 | [summary] to write: return (return[0]) in Key | +| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | [summary param] -1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | [summary param] -1 in Lookup | file://:0:0:0:0 | [summary] to write: return (return[0]) in Lookup | +| file://:0:0:0:0 | [summary param] -1 in MapIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapIndex | +| file://:0:0:0:0 | [summary param] -1 in MapKeys | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapKeys | +| file://:0:0:0:0 | [summary param] -1 in MapRange | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapRange | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in Method | file://:0:0:0:0 | [summary] to write: return (return[0]) in Method | +| file://:0:0:0:0 | [summary param] -1 in MethodByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in MethodByName | +| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] -1 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | [summary param] -1 in Password | file://:0:0:0:0 | [summary] to write: return (return[0]) in Password | +| file://:0:0:0:0 | [summary param] -1 in Pointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Pointer | +| file://:0:0:0:0 | [summary param] -1 in Port | file://:0:0:0:0 | [summary] to write: return (return[0]) in Port | +| file://:0:0:0:0 | [summary param] -1 in Query | file://:0:0:0:0 | [summary] to write: return (return[0]) in Query | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | [summary param] -1 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | [summary param] -1 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | [summary param] -1 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | [summary param] -1 in Recv | file://:0:0:0:0 | [summary] to write: return (return[0]) in Recv | +| file://:0:0:0:0 | [summary param] -1 in RequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in RequestURI | +| file://:0:0:0:0 | [summary param] -1 in ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | +| file://:0:0:0:0 | [summary param] -1 in Slice | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice | +| file://:0:0:0:0 | [summary param] -1 in Slice3 | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice3 | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | [summary param] -1 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | [summary param] -1 in Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | [summary param] -1 in TryRecv | file://:0:0:0:0 | [summary] to write: return (return[0]) in TryRecv | +| file://:0:0:0:0 | [summary param] -1 in UnsafeAddr | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnsafeAddr | +| file://:0:0:0:0 | [summary param] -1 in Username | file://:0:0:0:0 | [summary] to write: return (return[0]) in Username | +| file://:0:0:0:0 | [summary param] -1 in Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | | main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[0] | | main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[1] | | main.go:38:13:38:13 | 1 | main.go:38:7:38:20 | slice literal | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected b/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected index 325c5c60a36..da82753fd19 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/TaintStep.expected @@ -5,861 +5,861 @@ | crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | ... := ...[0] | | crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | ... := ...[1] | | crypto.go:11:42:11:51 | ciphertext | crypto.go:11:2:11:57 | ... := ...[0] | -| file://:0:0:0:0 | parameter 0 of Abs | file://:0:0:0:0 | [summary] to write: return (return[0]) in Abs | -| file://:0:0:0:0 | parameter 0 of Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | -| file://:0:0:0:0 | parameter 0 of Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | -| file://:0:0:0:0 | parameter 0 of AddCookie | file://:0:0:0:0 | [summary] to write: argument -1 in AddCookie | -| file://:0:0:0:0 | parameter 0 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | -| file://:0:0:0:0 | parameter 0 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | -| file://:0:0:0:0 | parameter 0 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | -| file://:0:0:0:0 | parameter 0 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | -| file://:0:0:0:0 | parameter 0 of As | file://:0:0:0:0 | [summary] to write: argument 1 in As | -| file://:0:0:0:0 | parameter 0 of Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | -| file://:0:0:0:0 | parameter 0 of Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | -| file://:0:0:0:0 | parameter 0 of BytePtrFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in BytePtrFromString | -| file://:0:0:0:0 | parameter 0 of ByteSliceFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ByteSliceFromString | -| file://:0:0:0:0 | parameter 0 of CanonicalHeaderKey | file://:0:0:0:0 | [summary] to write: return (return[0]) in CanonicalHeaderKey | -| file://:0:0:0:0 | parameter 0 of CanonicalMIMEHeaderKey | file://:0:0:0:0 | [summary] to write: return (return[0]) in CanonicalMIMEHeaderKey | -| file://:0:0:0:0 | parameter 0 of Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | -| file://:0:0:0:0 | parameter 0 of Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | -| file://:0:0:0:0 | parameter 0 of Client | file://:0:0:0:0 | [summary] to write: return (return[0]) in Client | -| file://:0:0:0:0 | parameter 0 of Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | -| file://:0:0:0:0 | parameter 0 of Cut | file://:0:0:0:0 | [summary] to write: return (return[0]) in Cut | -| file://:0:0:0:0 | parameter 0 of Cut | file://:0:0:0:0 | [summary] to write: return (return[1]) in Cut | -| file://:0:0:0:0 | parameter 0 of CutPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in CutPrefix | -| file://:0:0:0:0 | parameter 0 of CutSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in CutSuffix | -| file://:0:0:0:0 | parameter 0 of Decode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decode | -| file://:0:0:0:0 | parameter 0 of Decode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decode | -| file://:0:0:0:0 | parameter 0 of Decode | file://:0:0:0:0 | [summary] to write: return (return[1]) in Decode | -| file://:0:0:0:0 | parameter 0 of DecodeHeader | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeHeader | -| file://:0:0:0:0 | parameter 0 of DecodeString | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeString | -| file://:0:0:0:0 | parameter 0 of DecodeString | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeString | -| file://:0:0:0:0 | parameter 0 of DecryptPEMBlock | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptPEMBlock | -| file://:0:0:0:0 | parameter 0 of Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | -| file://:0:0:0:0 | parameter 0 of Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | -| file://:0:0:0:0 | parameter 0 of Encode | file://:0:0:0:0 | [summary] to write: argument -1 in Encode | -| file://:0:0:0:0 | parameter 0 of EncodeToMemory | file://:0:0:0:0 | [summary] to write: return (return[0]) in EncodeToMemory | -| file://:0:0:0:0 | parameter 0 of EvalSymlinks | file://:0:0:0:0 | [summary] to write: return (return[0]) in EvalSymlinks | -| file://:0:0:0:0 | parameter 0 of Expand | file://:0:0:0:0 | [summary] to write: return (return[0]) in Expand | -| file://:0:0:0:0 | parameter 0 of ExpandEnv | file://:0:0:0:0 | [summary] to write: return (return[0]) in ExpandEnv | -| file://:0:0:0:0 | parameter 0 of Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | -| file://:0:0:0:0 | parameter 0 of Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | -| file://:0:0:0:0 | parameter 0 of Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | -| file://:0:0:0:0 | parameter 0 of Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | -| file://:0:0:0:0 | parameter 0 of FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | -| file://:0:0:0:0 | parameter 0 of FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | -| file://:0:0:0:0 | parameter 0 of FileConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileConn | -| file://:0:0:0:0 | parameter 0 of FileInfoToDirEntry | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileInfoToDirEntry | -| file://:0:0:0:0 | parameter 0 of FilePacketConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in FilePacketConn | -| file://:0:0:0:0 | parameter 0 of FormatMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormatMediaType | -| file://:0:0:0:0 | parameter 0 of FromSlash | file://:0:0:0:0 | [summary] to write: return (return[0]) in FromSlash | -| file://:0:0:0:0 | parameter 0 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | -| file://:0:0:0:0 | parameter 0 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | -| file://:0:0:0:0 | parameter 0 of Indirect | file://:0:0:0:0 | [summary] to write: return (return[0]) in Indirect | -| file://:0:0:0:0 | parameter 0 of InsertAfter | file://:0:0:0:0 | [summary] to write: argument -1 in InsertAfter | -| file://:0:0:0:0 | parameter 0 of InsertAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in InsertAfter | -| file://:0:0:0:0 | parameter 0 of InsertBefore | file://:0:0:0:0 | [summary] to write: argument -1 in InsertBefore | -| file://:0:0:0:0 | parameter 0 of InsertBefore | file://:0:0:0:0 | [summary] to write: return (return[0]) in InsertBefore | -| file://:0:0:0:0 | parameter 0 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | -| file://:0:0:0:0 | parameter 0 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | -| file://:0:0:0:0 | parameter 0 of JoinHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in JoinHostPort | -| file://:0:0:0:0 | parameter 0 of LimitReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in LimitReader | -| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | -| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | -| file://:0:0:0:0 | parameter 0 of LoadPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadPointer | -| file://:0:0:0:0 | parameter 0 of LoadUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadUintptr | -| file://:0:0:0:0 | parameter 0 of Marshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Marshal | -| file://:0:0:0:0 | parameter 0 of Marshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Marshal | -| file://:0:0:0:0 | parameter 0 of MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | -| file://:0:0:0:0 | parameter 0 of MarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalWithParams | -| file://:0:0:0:0 | parameter 0 of MoveAfter | file://:0:0:0:0 | [summary] to write: argument -1 in MoveAfter | -| file://:0:0:0:0 | parameter 0 of MoveBefore | file://:0:0:0:0 | [summary] to write: argument -1 in MoveBefore | -| file://:0:0:0:0 | parameter 0 of MoveToBack | file://:0:0:0:0 | [summary] to write: argument -1 in MoveToBack | -| file://:0:0:0:0 | parameter 0 of MoveToFront | file://:0:0:0:0 | [summary] to write: argument -1 in MoveToFront | -| file://:0:0:0:0 | parameter 0 of New | file://:0:0:0:0 | [summary] to write: return (return[0]) in New | -| file://:0:0:0:0 | parameter 0 of NewBuffer | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewBuffer | -| file://:0:0:0:0 | parameter 0 of NewBufferString | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewBufferString | -| file://:0:0:0:0 | parameter 0 of NewConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewConn | -| file://:0:0:0:0 | parameter 0 of NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | -| file://:0:0:0:0 | parameter 0 of NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | -| file://:0:0:0:0 | parameter 0 of NewFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewFile | -| file://:0:0:0:0 | parameter 0 of NewListener | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewListener | -| file://:0:0:0:0 | parameter 0 of NewReadWriter | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReadWriter | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | -| file://:0:0:0:0 | parameter 0 of NewReaderDict | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReaderDict | -| file://:0:0:0:0 | parameter 0 of NewReaderSize | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReaderSize | -| file://:0:0:0:0 | parameter 0 of NewScanner | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewScanner | -| file://:0:0:0:0 | parameter 0 of NewSectionReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewSectionReader | -| file://:0:0:0:0 | parameter 0 of NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | -| file://:0:0:0:0 | parameter 0 of NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | -| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | -| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | -| file://:0:0:0:0 | parameter 0 of ParseMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseMediaType | -| file://:0:0:0:0 | parameter 0 of ParseMediaType | file://:0:0:0:0 | [summary] to write: return (return[1]) in ParseMediaType | -| file://:0:0:0:0 | parameter 0 of ParseQuery | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseQuery | -| file://:0:0:0:0 | parameter 0 of ParseRequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseRequestURI | -| file://:0:0:0:0 | parameter 0 of PathEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathEscape | -| file://:0:0:0:0 | parameter 0 of PathUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathUnescape | -| file://:0:0:0:0 | parameter 0 of PushBack | file://:0:0:0:0 | [summary] to write: argument -1 in PushBack | -| file://:0:0:0:0 | parameter 0 of PushBack | file://:0:0:0:0 | [summary] to write: return (return[0]) in PushBack | -| file://:0:0:0:0 | parameter 0 of PushBackList | file://:0:0:0:0 | [summary] to write: argument -1 in PushBackList | -| file://:0:0:0:0 | parameter 0 of PushFront | file://:0:0:0:0 | [summary] to write: argument -1 in PushFront | -| file://:0:0:0:0 | parameter 0 of PushFront | file://:0:0:0:0 | [summary] to write: return (return[0]) in PushFront | -| file://:0:0:0:0 | parameter 0 of PushFrontList | file://:0:0:0:0 | [summary] to write: argument -1 in PushFrontList | -| file://:0:0:0:0 | parameter 0 of Put | file://:0:0:0:0 | [summary] to write: argument -1 in Put | -| file://:0:0:0:0 | parameter 0 of QueryEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryEscape | -| file://:0:0:0:0 | parameter 0 of QueryUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryUnescape | -| file://:0:0:0:0 | parameter 0 of Quote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Quote | -| file://:0:0:0:0 | parameter 0 of QuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToASCII | -| file://:0:0:0:0 | parameter 0 of QuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToGraphic | -| file://:0:0:0:0 | parameter 0 of QuotedPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuotedPrefix | -| file://:0:0:0:0 | parameter 0 of Read | file://:0:0:0:0 | [summary] to write: argument 2 in Read | -| file://:0:0:0:0 | parameter 0 of ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | -| file://:0:0:0:0 | parameter 0 of ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | -| file://:0:0:0:0 | parameter 0 of ReadAtLeast | file://:0:0:0:0 | [summary] to write: argument 1 in ReadAtLeast | -| file://:0:0:0:0 | parameter 0 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | -| file://:0:0:0:0 | parameter 0 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | -| file://:0:0:0:0 | parameter 0 of ReadFull | file://:0:0:0:0 | [summary] to write: argument 1 in ReadFull | -| file://:0:0:0:0 | parameter 0 of ReadRequest | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadRequest | -| file://:0:0:0:0 | parameter 0 of ReadResponse | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadResponse | -| file://:0:0:0:0 | parameter 0 of Rel | file://:0:0:0:0 | [summary] to write: return (return[0]) in Rel | -| file://:0:0:0:0 | parameter 0 of Remove | file://:0:0:0:0 | [summary] to write: return (return[0]) in Remove | -| file://:0:0:0:0 | parameter 0 of Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | -| file://:0:0:0:0 | parameter 0 of Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | -| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | -| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | -| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | -| file://:0:0:0:0 | parameter 0 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | -| file://:0:0:0:0 | parameter 0 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | -| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | -| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | -| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | -| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | -| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | -| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | -| file://:0:0:0:0 | parameter 0 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | -| file://:0:0:0:0 | parameter 0 of Reverse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Reverse | -| file://:0:0:0:0 | parameter 0 of Runes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Runes | -| file://:0:0:0:0 | parameter 0 of ScanBytes | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanBytes | -| file://:0:0:0:0 | parameter 0 of ScanLines | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanLines | -| file://:0:0:0:0 | parameter 0 of ScanRunes | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanRunes | -| file://:0:0:0:0 | parameter 0 of ScanWords | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanWords | -| file://:0:0:0:0 | parameter 0 of Send | file://:0:0:0:0 | [summary] to write: argument -1 in Send | -| file://:0:0:0:0 | parameter 0 of Server | file://:0:0:0:0 | [summary] to write: return (return[0]) in Server | -| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | -| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | -| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | -| file://:0:0:0:0 | parameter 0 of SetBytes | file://:0:0:0:0 | [summary] to write: argument -1 in SetBytes | -| file://:0:0:0:0 | parameter 0 of SetIndent | file://:0:0:0:0 | [summary] to write: argument -1 in SetIndent | -| file://:0:0:0:0 | parameter 0 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | -| file://:0:0:0:0 | parameter 0 of SetPointer | file://:0:0:0:0 | [summary] to write: argument -1 in SetPointer | -| file://:0:0:0:0 | parameter 0 of SetPrefix | file://:0:0:0:0 | [summary] to write: argument -1 in SetPrefix | -| file://:0:0:0:0 | parameter 0 of SetString | file://:0:0:0:0 | [summary] to write: argument -1 in SetString | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | -| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | -| file://:0:0:0:0 | parameter 0 of SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | -| file://:0:0:0:0 | parameter 0 of SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | -| file://:0:0:0:0 | parameter 0 of SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | -| file://:0:0:0:0 | parameter 0 of SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | -| file://:0:0:0:0 | parameter 0 of SplitHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitHostPort | -| file://:0:0:0:0 | parameter 0 of SplitHostPort | file://:0:0:0:0 | [summary] to write: return (return[1]) in SplitHostPort | -| file://:0:0:0:0 | parameter 0 of SplitList | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitList | -| file://:0:0:0:0 | parameter 0 of SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | -| file://:0:0:0:0 | parameter 0 of SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | -| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 0 of StringBytePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringBytePtr | -| file://:0:0:0:0 | parameter 0 of StringByteSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringByteSlice | -| file://:0:0:0:0 | parameter 0 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | -| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 0 of SwapPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapPointer | -| file://:0:0:0:0 | parameter 0 of SwapUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapUintptr | -| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: argument 1 in TeeReader | -| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in TeeReader | -| file://:0:0:0:0 | parameter 0 of Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | -| file://:0:0:0:0 | parameter 0 of Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | -| file://:0:0:0:0 | parameter 0 of ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | -| file://:0:0:0:0 | parameter 0 of ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | -| file://:0:0:0:0 | parameter 0 of ToSlash | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToSlash | -| file://:0:0:0:0 | parameter 0 of ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | -| file://:0:0:0:0 | parameter 0 of ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | -| file://:0:0:0:0 | parameter 0 of ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | -| file://:0:0:0:0 | parameter 0 of ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | -| file://:0:0:0:0 | parameter 0 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | -| file://:0:0:0:0 | parameter 0 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | -| file://:0:0:0:0 | parameter 0 of Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | -| file://:0:0:0:0 | parameter 0 of Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | -| file://:0:0:0:0 | parameter 0 of TrimBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimBytes | -| file://:0:0:0:0 | parameter 0 of TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | -| file://:0:0:0:0 | parameter 0 of TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | -| file://:0:0:0:0 | parameter 0 of TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | -| file://:0:0:0:0 | parameter 0 of TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | -| file://:0:0:0:0 | parameter 0 of TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | -| file://:0:0:0:0 | parameter 0 of TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | -| file://:0:0:0:0 | parameter 0 of TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | -| file://:0:0:0:0 | parameter 0 of TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | -| file://:0:0:0:0 | parameter 0 of TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | -| file://:0:0:0:0 | parameter 0 of TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | -| file://:0:0:0:0 | parameter 0 of TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | -| file://:0:0:0:0 | parameter 0 of TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | -| file://:0:0:0:0 | parameter 0 of TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | -| file://:0:0:0:0 | parameter 0 of TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | -| file://:0:0:0:0 | parameter 0 of TrimString | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimString | -| file://:0:0:0:0 | parameter 0 of TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | -| file://:0:0:0:0 | parameter 0 of TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | -| file://:0:0:0:0 | parameter 0 of TrySend | file://:0:0:0:0 | [summary] to write: argument -1 in TrySend | -| file://:0:0:0:0 | parameter 0 of Unmarshal | file://:0:0:0:0 | [summary] to write: argument 1 in Unmarshal | -| file://:0:0:0:0 | parameter 0 of Unmarshal | file://:0:0:0:0 | [summary] to write: argument 1 in Unmarshal | -| file://:0:0:0:0 | parameter 0 of Unmarshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unmarshal | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | -| file://:0:0:0:0 | parameter 0 of UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | -| file://:0:0:0:0 | parameter 0 of UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | -| file://:0:0:0:0 | parameter 0 of UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | -| file://:0:0:0:0 | parameter 0 of UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | -| file://:0:0:0:0 | parameter 0 of UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: argument 1 in UnmarshalWithParams | -| file://:0:0:0:0 | parameter 0 of UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnmarshalWithParams | -| file://:0:0:0:0 | parameter 0 of Unquote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unquote | -| file://:0:0:0:0 | parameter 0 of UnquoteChar | file://:0:0:0:0 | [summary] to write: return (return[2]) in UnquoteChar | -| file://:0:0:0:0 | parameter 0 of Unwrap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unwrap | -| file://:0:0:0:0 | parameter 0 of User | file://:0:0:0:0 | [summary] to write: return (return[0]) in User | -| file://:0:0:0:0 | parameter 0 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | -| file://:0:0:0:0 | parameter 0 of ValueOf | file://:0:0:0:0 | [summary] to write: return (return[0]) in ValueOf | -| file://:0:0:0:0 | parameter 0 of VolumeName | file://:0:0:0:0 | [summary] to write: return (return[0]) in VolumeName | -| file://:0:0:0:0 | parameter 0 of WithCancel | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithCancel | -| file://:0:0:0:0 | parameter 0 of WithDeadline | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithDeadline | -| file://:0:0:0:0 | parameter 0 of WithTimeout | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithTimeout | -| file://:0:0:0:0 | parameter 0 of WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | -| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | -| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | -| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | -| file://:0:0:0:0 | parameter 0 of WriteField | file://:0:0:0:0 | [summary] to write: argument -1 in WriteField | -| file://:0:0:0:0 | parameter 0 of WriteMsgIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgIP | -| file://:0:0:0:0 | parameter 0 of WriteMsgUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUDP | -| file://:0:0:0:0 | parameter 0 of WriteMsgUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUnix | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | -| file://:0:0:0:0 | parameter 0 of WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | -| file://:0:0:0:0 | parameter 0 of WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | -| file://:0:0:0:0 | parameter 0 of WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | -| file://:0:0:0:0 | parameter 0 of WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | -| file://:0:0:0:0 | parameter 0 of WriteToIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToIP | -| file://:0:0:0:0 | parameter 0 of WriteToUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToUDP | -| file://:0:0:0:0 | parameter 0 of WriteToUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToUnix | -| file://:0:0:0:0 | parameter 1 of Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | -| file://:0:0:0:0 | parameter 1 of Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | -| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in AddUintptr | -| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in AddUintptr | -| file://:0:0:0:0 | parameter 1 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | -| file://:0:0:0:0 | parameter 1 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | -| file://:0:0:0:0 | parameter 1 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | -| file://:0:0:0:0 | parameter 1 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | -| file://:0:0:0:0 | parameter 1 of Compact | file://:0:0:0:0 | [summary] to write: argument 0 in Compact | -| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | -| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | -| file://:0:0:0:0 | parameter 1 of CopyBuffer | file://:0:0:0:0 | [summary] to write: argument 0 in CopyBuffer | -| file://:0:0:0:0 | parameter 1 of CopyN | file://:0:0:0:0 | [summary] to write: argument 0 in CopyN | -| file://:0:0:0:0 | parameter 1 of Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | -| file://:0:0:0:0 | parameter 1 of Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | -| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | -| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | -| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | -| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | -| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | -| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decrypt | -| file://:0:0:0:0 | parameter 1 of Decrypt | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decrypt | -| file://:0:0:0:0 | parameter 1 of Encode | file://:0:0:0:0 | [summary] to write: argument 0 in Encode | -| file://:0:0:0:0 | parameter 1 of Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | -| file://:0:0:0:0 | parameter 1 of Error | file://:0:0:0:0 | [summary] to write: argument 0 in Error | -| file://:0:0:0:0 | parameter 1 of FormatMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormatMediaType | -| file://:0:0:0:0 | parameter 1 of HTMLEscape | file://:0:0:0:0 | [summary] to write: argument 0 in HTMLEscape | -| file://:0:0:0:0 | parameter 1 of Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | -| file://:0:0:0:0 | parameter 1 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | -| file://:0:0:0:0 | parameter 1 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | -| file://:0:0:0:0 | parameter 1 of JoinHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in JoinHostPort | -| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | -| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | -| file://:0:0:0:0 | parameter 1 of Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | -| file://:0:0:0:0 | parameter 1 of Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | -| file://:0:0:0:0 | parameter 1 of MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | -| file://:0:0:0:0 | parameter 1 of MarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalWithParams | -| file://:0:0:0:0 | parameter 1 of MaxBytesReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in MaxBytesReader | -| file://:0:0:0:0 | parameter 1 of NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | -| file://:0:0:0:0 | parameter 1 of NewRequest | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewRequest | -| file://:0:0:0:0 | parameter 1 of Rel | file://:0:0:0:0 | [summary] to write: return (return[0]) in Rel | -| file://:0:0:0:0 | parameter 1 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | -| file://:0:0:0:0 | parameter 1 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | -| file://:0:0:0:0 | parameter 1 of SetCookie | file://:0:0:0:0 | [summary] to write: argument 0 in SetCookie | -| file://:0:0:0:0 | parameter 1 of SetIndent | file://:0:0:0:0 | [summary] to write: argument -1 in SetIndent | -| file://:0:0:0:0 | parameter 1 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | -| file://:0:0:0:0 | parameter 1 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | -| file://:0:0:0:0 | parameter 1 of StorePointer | file://:0:0:0:0 | [summary] to write: argument 0 in StorePointer | -| file://:0:0:0:0 | parameter 1 of StoreUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in StoreUintptr | -| file://:0:0:0:0 | parameter 1 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | -| file://:0:0:0:0 | parameter 1 of SwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in SwapPointer | -| file://:0:0:0:0 | parameter 1 of SwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in SwapUintptr | -| file://:0:0:0:0 | parameter 1 of ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | -| file://:0:0:0:0 | parameter 1 of ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | -| file://:0:0:0:0 | parameter 1 of ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | -| file://:0:0:0:0 | parameter 1 of ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | -| file://:0:0:0:0 | parameter 1 of ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | -| file://:0:0:0:0 | parameter 1 of ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | -| file://:0:0:0:0 | parameter 1 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | -| file://:0:0:0:0 | parameter 1 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | -| file://:0:0:0:0 | parameter 1 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | -| file://:0:0:0:0 | parameter 1 of WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | -| file://:0:0:0:0 | parameter 1 of WriteField | file://:0:0:0:0 | [summary] to write: argument -1 in WriteField | -| file://:0:0:0:0 | parameter 1 of WriteMsgIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgIP | -| file://:0:0:0:0 | parameter 1 of WriteMsgUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUDP | -| file://:0:0:0:0 | parameter 1 of WriteMsgUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUnix | -| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | -| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | -| file://:0:0:0:0 | parameter 2 of CompareAndSwap | file://:0:0:0:0 | [summary] to write: argument -1 in CompareAndSwap | -| file://:0:0:0:0 | parameter 2 of CompareAndSwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapPointer | -| file://:0:0:0:0 | parameter 2 of CompareAndSwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapUintptr | -| file://:0:0:0:0 | parameter 2 of DecryptPKCS1v15 | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptPKCS1v15 | -| file://:0:0:0:0 | parameter 2 of Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | -| file://:0:0:0:0 | parameter 2 of MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | -| file://:0:0:0:0 | parameter 2 of NewRequestWithContext | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewRequestWithContext | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter 2 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter 2 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | -| file://:0:0:0:0 | parameter 2 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | -| file://:0:0:0:0 | parameter 2 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | -| file://:0:0:0:0 | parameter 2 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | -| file://:0:0:0:0 | parameter 2 of UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: argument 1 in UnmarshalWithParams | -| file://:0:0:0:0 | parameter 2 of UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnmarshalWithParams | -| file://:0:0:0:0 | parameter 2 of WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | -| file://:0:0:0:0 | parameter 2 of Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | -| file://:0:0:0:0 | parameter 3 of DecryptOAEP | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptOAEP | -| file://:0:0:0:0 | parameter 3 of Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | -| file://:0:0:0:0 | parameter -1 of Addr | file://:0:0:0:0 | [summary] to write: return (return[0]) in Addr | -| file://:0:0:0:0 | parameter -1 of Back | file://:0:0:0:0 | [summary] to write: return (return[0]) in Back | -| file://:0:0:0:0 | parameter -1 of Buffered | file://:0:0:0:0 | [summary] to write: return (return[0]) in Buffered | -| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | -| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | -| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | -| file://:0:0:0:0 | parameter -1 of Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | -| file://:0:0:0:0 | parameter -1 of Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | -| file://:0:0:0:0 | parameter -1 of Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | -| file://:0:0:0:0 | parameter -1 of Convert | file://:0:0:0:0 | [summary] to write: return (return[0]) in Convert | -| file://:0:0:0:0 | parameter -1 of Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | -| file://:0:0:0:0 | parameter -1 of DotReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in DotReader | -| file://:0:0:0:0 | parameter -1 of Elem | file://:0:0:0:0 | [summary] to write: return (return[0]) in Elem | -| file://:0:0:0:0 | parameter -1 of Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | -| file://:0:0:0:0 | parameter -1 of EscapedPath | file://:0:0:0:0 | [summary] to write: return (return[0]) in EscapedPath | -| file://:0:0:0:0 | parameter -1 of Fd | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fd | -| file://:0:0:0:0 | parameter -1 of Field | file://:0:0:0:0 | [summary] to write: return (return[0]) in Field | -| file://:0:0:0:0 | parameter -1 of FieldByIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByIndex | -| file://:0:0:0:0 | parameter -1 of FieldByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByName | -| file://:0:0:0:0 | parameter -1 of FieldByNameFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByNameFunc | -| file://:0:0:0:0 | parameter -1 of File | file://:0:0:0:0 | [summary] to write: return (return[0]) in File | -| file://:0:0:0:0 | parameter -1 of File | file://:0:0:0:0 | [summary] to write: return (return[0]) in File | -| file://:0:0:0:0 | parameter -1 of FileName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileName | -| file://:0:0:0:0 | parameter -1 of FormName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormName | -| file://:0:0:0:0 | parameter -1 of Front | file://:0:0:0:0 | [summary] to write: return (return[0]) in Front | -| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | -| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | -| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | -| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | -| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | -| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | -| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | -| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | -| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | -| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | -| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | -| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | -| file://:0:0:0:0 | parameter -1 of Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | -| file://:0:0:0:0 | parameter -1 of Hostname | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hostname | -| file://:0:0:0:0 | parameter -1 of Index | file://:0:0:0:0 | [summary] to write: return (return[0]) in Index | -| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | -| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | -| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | -| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | -| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | -| file://:0:0:0:0 | parameter -1 of Init | file://:0:0:0:0 | [summary] to write: return (return[0]) in Init | -| file://:0:0:0:0 | parameter -1 of Interface | file://:0:0:0:0 | [summary] to write: return (return[0]) in Interface | -| file://:0:0:0:0 | parameter -1 of InterfaceData | file://:0:0:0:0 | [summary] to write: return (return[0]) in InterfaceData | -| file://:0:0:0:0 | parameter -1 of Key | file://:0:0:0:0 | [summary] to write: return (return[0]) in Key | -| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | -| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | -| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | -| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | -| file://:0:0:0:0 | parameter -1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | -| file://:0:0:0:0 | parameter -1 of Lookup | file://:0:0:0:0 | [summary] to write: return (return[0]) in Lookup | -| file://:0:0:0:0 | parameter -1 of MapIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapIndex | -| file://:0:0:0:0 | parameter -1 of MapKeys | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapKeys | -| file://:0:0:0:0 | parameter -1 of MapRange | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapRange | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | -| file://:0:0:0:0 | parameter -1 of MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | -| file://:0:0:0:0 | parameter -1 of MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | -| file://:0:0:0:0 | parameter -1 of MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | -| file://:0:0:0:0 | parameter -1 of MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | -| file://:0:0:0:0 | parameter -1 of Method | file://:0:0:0:0 | [summary] to write: return (return[0]) in Method | -| file://:0:0:0:0 | parameter -1 of MethodByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in MethodByName | -| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | -| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | -| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | -| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | -| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | -| file://:0:0:0:0 | parameter -1 of Next | file://:0:0:0:0 | [summary] to write: return (return[0]) in Next | -| file://:0:0:0:0 | parameter -1 of Next | file://:0:0:0:0 | [summary] to write: return (return[0]) in Next | -| file://:0:0:0:0 | parameter -1 of NextPart | file://:0:0:0:0 | [summary] to write: return (return[0]) in NextPart | -| file://:0:0:0:0 | parameter -1 of NextRawPart | file://:0:0:0:0 | [summary] to write: return (return[0]) in NextRawPart | -| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | -| file://:0:0:0:0 | parameter -1 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | -| file://:0:0:0:0 | parameter -1 of Password | file://:0:0:0:0 | [summary] to write: return (return[0]) in Password | -| file://:0:0:0:0 | parameter -1 of Peek | file://:0:0:0:0 | [summary] to write: return (return[0]) in Peek | -| file://:0:0:0:0 | parameter -1 of Pointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Pointer | -| file://:0:0:0:0 | parameter -1 of Port | file://:0:0:0:0 | [summary] to write: return (return[0]) in Port | -| file://:0:0:0:0 | parameter -1 of Prev | file://:0:0:0:0 | [summary] to write: return (return[0]) in Prev | -| file://:0:0:0:0 | parameter -1 of Query | file://:0:0:0:0 | [summary] to write: return (return[0]) in Query | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | -| file://:0:0:0:0 | parameter -1 of ReadBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadBytes | -| file://:0:0:0:0 | parameter -1 of ReadBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadBytes | -| file://:0:0:0:0 | parameter -1 of ReadCodeLine | file://:0:0:0:0 | [summary] to write: return (return[1]) in ReadCodeLine | -| file://:0:0:0:0 | parameter -1 of ReadContinuedLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadContinuedLine | -| file://:0:0:0:0 | parameter -1 of ReadContinuedLineBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadContinuedLineBytes | -| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | -| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | -| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | -| file://:0:0:0:0 | parameter -1 of ReadDotBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDotBytes | -| file://:0:0:0:0 | parameter -1 of ReadDotLines | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDotLines | -| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | -| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | -| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | -| file://:0:0:0:0 | parameter -1 of ReadForm | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadForm | -| file://:0:0:0:0 | parameter -1 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | -| file://:0:0:0:0 | parameter -1 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | -| file://:0:0:0:0 | parameter -1 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | -| file://:0:0:0:0 | parameter -1 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | -| file://:0:0:0:0 | parameter -1 of ReadFromIP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromIP | -| file://:0:0:0:0 | parameter -1 of ReadFromUDP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromUDP | -| file://:0:0:0:0 | parameter -1 of ReadFromUnix | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromUnix | -| file://:0:0:0:0 | parameter -1 of ReadLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLine | -| file://:0:0:0:0 | parameter -1 of ReadLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLine | -| file://:0:0:0:0 | parameter -1 of ReadLineBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLineBytes | -| file://:0:0:0:0 | parameter -1 of ReadMIMEHeader | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadMIMEHeader | -| file://:0:0:0:0 | parameter -1 of ReadMsgIP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgIP | -| file://:0:0:0:0 | parameter -1 of ReadMsgIP | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgIP | -| file://:0:0:0:0 | parameter -1 of ReadMsgUDP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgUDP | -| file://:0:0:0:0 | parameter -1 of ReadMsgUDP | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgUDP | -| file://:0:0:0:0 | parameter -1 of ReadMsgUnix | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgUnix | -| file://:0:0:0:0 | parameter -1 of ReadMsgUnix | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgUnix | -| file://:0:0:0:0 | parameter -1 of ReadResponse | file://:0:0:0:0 | [summary] to write: return (return[1]) in ReadResponse | -| file://:0:0:0:0 | parameter -1 of ReadSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadSlice | -| file://:0:0:0:0 | parameter -1 of ReadString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadString | -| file://:0:0:0:0 | parameter -1 of ReadString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadString | -| file://:0:0:0:0 | parameter -1 of Recv | file://:0:0:0:0 | [summary] to write: return (return[0]) in Recv | -| file://:0:0:0:0 | parameter -1 of RequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in RequestURI | -| file://:0:0:0:0 | parameter -1 of Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | -| file://:0:0:0:0 | parameter -1 of Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | -| file://:0:0:0:0 | parameter -1 of Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | -| file://:0:0:0:0 | parameter -1 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | -| file://:0:0:0:0 | parameter -1 of SetOutput | file://:0:0:0:0 | [summary] to write: argument 0 in SetOutput | -| file://:0:0:0:0 | parameter -1 of Slice | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice | -| file://:0:0:0:0 | parameter -1 of Slice3 | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice3 | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | -| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | -| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | -| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | -| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | -| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | -| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | -| file://:0:0:0:0 | parameter -1 of Text | file://:0:0:0:0 | [summary] to write: return (return[0]) in Text | -| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | -| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | -| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | -| file://:0:0:0:0 | parameter -1 of TryRecv | file://:0:0:0:0 | [summary] to write: return (return[0]) in TryRecv | -| file://:0:0:0:0 | parameter -1 of UnsafeAddr | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnsafeAddr | -| file://:0:0:0:0 | parameter -1 of Username | file://:0:0:0:0 | [summary] to write: return (return[0]) in Username | -| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | -| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | -| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | -| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | -| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | -| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | -| file://:0:0:0:0 | parameter -1 of Values | file://:0:0:0:0 | [summary] to write: return (return[0]) in Values | -| file://:0:0:0:0 | parameter -1 of Values | file://:0:0:0:0 | [summary] to write: return (return[0]) in Values | -| file://:0:0:0:0 | parameter -1 of Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | -| file://:0:0:0:0 | parameter -1 of Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | -| file://:0:0:0:0 | parameter -1 of Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | -| file://:0:0:0:0 | parameter -1 of WriteProxy | file://:0:0:0:0 | [summary] to write: argument 0 in WriteProxy | -| file://:0:0:0:0 | parameter -1 of WriteSubset | file://:0:0:0:0 | [summary] to write: argument 0 in WriteSubset | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | -| file://:0:0:0:0 | parameter -1 of Writer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Writer | +| file://:0:0:0:0 | [summary param] 0 in Abs | file://:0:0:0:0 | [summary] to write: return (return[0]) in Abs | +| file://:0:0:0:0 | [summary param] 0 in Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | +| file://:0:0:0:0 | [summary param] 0 in Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | +| file://:0:0:0:0 | [summary param] 0 in AddCookie | file://:0:0:0:0 | [summary] to write: argument -1 in AddCookie | +| file://:0:0:0:0 | [summary param] 0 in AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | +| file://:0:0:0:0 | [summary param] 0 in AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | +| file://:0:0:0:0 | [summary param] 0 in AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | +| file://:0:0:0:0 | [summary param] 0 in AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | +| file://:0:0:0:0 | [summary param] 0 in As | file://:0:0:0:0 | [summary] to write: argument 1 in As | +| file://:0:0:0:0 | [summary param] 0 in Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | +| file://:0:0:0:0 | [summary param] 0 in Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base | +| file://:0:0:0:0 | [summary param] 0 in BytePtrFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in BytePtrFromString | +| file://:0:0:0:0 | [summary param] 0 in ByteSliceFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ByteSliceFromString | +| file://:0:0:0:0 | [summary param] 0 in CanonicalHeaderKey | file://:0:0:0:0 | [summary] to write: return (return[0]) in CanonicalHeaderKey | +| file://:0:0:0:0 | [summary param] 0 in CanonicalMIMEHeaderKey | file://:0:0:0:0 | [summary] to write: return (return[0]) in CanonicalMIMEHeaderKey | +| file://:0:0:0:0 | [summary param] 0 in Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | +| file://:0:0:0:0 | [summary param] 0 in Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean | +| file://:0:0:0:0 | [summary param] 0 in Client | file://:0:0:0:0 | [summary] to write: return (return[0]) in Client | +| file://:0:0:0:0 | [summary param] 0 in Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | +| file://:0:0:0:0 | [summary param] 0 in Cut | file://:0:0:0:0 | [summary] to write: return (return[0]) in Cut | +| file://:0:0:0:0 | [summary param] 0 in Cut | file://:0:0:0:0 | [summary] to write: return (return[1]) in Cut | +| file://:0:0:0:0 | [summary param] 0 in CutPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in CutPrefix | +| file://:0:0:0:0 | [summary param] 0 in CutSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in CutSuffix | +| file://:0:0:0:0 | [summary param] 0 in Decode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decode | +| file://:0:0:0:0 | [summary param] 0 in Decode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decode | +| file://:0:0:0:0 | [summary param] 0 in Decode | file://:0:0:0:0 | [summary] to write: return (return[1]) in Decode | +| file://:0:0:0:0 | [summary param] 0 in DecodeHeader | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeHeader | +| file://:0:0:0:0 | [summary param] 0 in DecodeString | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeString | +| file://:0:0:0:0 | [summary param] 0 in DecodeString | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecodeString | +| file://:0:0:0:0 | [summary param] 0 in DecryptPEMBlock | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptPEMBlock | +| file://:0:0:0:0 | [summary param] 0 in Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | +| file://:0:0:0:0 | [summary param] 0 in Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir | +| file://:0:0:0:0 | [summary param] 0 in Encode | file://:0:0:0:0 | [summary] to write: argument -1 in Encode | +| file://:0:0:0:0 | [summary param] 0 in EncodeToMemory | file://:0:0:0:0 | [summary] to write: return (return[0]) in EncodeToMemory | +| file://:0:0:0:0 | [summary param] 0 in EvalSymlinks | file://:0:0:0:0 | [summary] to write: return (return[0]) in EvalSymlinks | +| file://:0:0:0:0 | [summary param] 0 in Expand | file://:0:0:0:0 | [summary] to write: return (return[0]) in Expand | +| file://:0:0:0:0 | [summary param] 0 in ExpandEnv | file://:0:0:0:0 | [summary] to write: return (return[0]) in ExpandEnv | +| file://:0:0:0:0 | [summary param] 0 in Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | +| file://:0:0:0:0 | [summary param] 0 in Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext | +| file://:0:0:0:0 | [summary param] 0 in Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | +| file://:0:0:0:0 | [summary param] 0 in Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields | +| file://:0:0:0:0 | [summary param] 0 in FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | +| file://:0:0:0:0 | [summary param] 0 in FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc | +| file://:0:0:0:0 | [summary param] 0 in FileConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileConn | +| file://:0:0:0:0 | [summary param] 0 in FileInfoToDirEntry | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileInfoToDirEntry | +| file://:0:0:0:0 | [summary param] 0 in FilePacketConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in FilePacketConn | +| file://:0:0:0:0 | [summary param] 0 in FormatMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormatMediaType | +| file://:0:0:0:0 | [summary param] 0 in FromSlash | file://:0:0:0:0 | [summary] to write: return (return[0]) in FromSlash | +| file://:0:0:0:0 | [summary param] 0 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | [summary param] 0 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | [summary param] 0 in Indirect | file://:0:0:0:0 | [summary] to write: return (return[0]) in Indirect | +| file://:0:0:0:0 | [summary param] 0 in InsertAfter | file://:0:0:0:0 | [summary] to write: argument -1 in InsertAfter | +| file://:0:0:0:0 | [summary param] 0 in InsertAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in InsertAfter | +| file://:0:0:0:0 | [summary param] 0 in InsertBefore | file://:0:0:0:0 | [summary] to write: argument -1 in InsertBefore | +| file://:0:0:0:0 | [summary param] 0 in InsertBefore | file://:0:0:0:0 | [summary] to write: return (return[0]) in InsertBefore | +| file://:0:0:0:0 | [summary param] 0 in Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | [summary param] 0 in Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | [summary param] 0 in JoinHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in JoinHostPort | +| file://:0:0:0:0 | [summary param] 0 in LimitReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in LimitReader | +| file://:0:0:0:0 | [summary param] 0 in LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | +| file://:0:0:0:0 | [summary param] 0 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | [summary param] 0 in LoadPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadPointer | +| file://:0:0:0:0 | [summary param] 0 in LoadUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadUintptr | +| file://:0:0:0:0 | [summary param] 0 in Marshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Marshal | +| file://:0:0:0:0 | [summary param] 0 in Marshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Marshal | +| file://:0:0:0:0 | [summary param] 0 in MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | +| file://:0:0:0:0 | [summary param] 0 in MarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalWithParams | +| file://:0:0:0:0 | [summary param] 0 in MoveAfter | file://:0:0:0:0 | [summary] to write: argument -1 in MoveAfter | +| file://:0:0:0:0 | [summary param] 0 in MoveBefore | file://:0:0:0:0 | [summary] to write: argument -1 in MoveBefore | +| file://:0:0:0:0 | [summary param] 0 in MoveToBack | file://:0:0:0:0 | [summary] to write: argument -1 in MoveToBack | +| file://:0:0:0:0 | [summary param] 0 in MoveToFront | file://:0:0:0:0 | [summary] to write: argument -1 in MoveToFront | +| file://:0:0:0:0 | [summary param] 0 in New | file://:0:0:0:0 | [summary] to write: return (return[0]) in New | +| file://:0:0:0:0 | [summary param] 0 in NewBuffer | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewBuffer | +| file://:0:0:0:0 | [summary param] 0 in NewBufferString | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewBufferString | +| file://:0:0:0:0 | [summary param] 0 in NewConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewConn | +| file://:0:0:0:0 | [summary param] 0 in NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | +| file://:0:0:0:0 | [summary param] 0 in NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | +| file://:0:0:0:0 | [summary param] 0 in NewFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewFile | +| file://:0:0:0:0 | [summary param] 0 in NewListener | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewListener | +| file://:0:0:0:0 | [summary param] 0 in NewReadWriter | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReadWriter | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader | +| file://:0:0:0:0 | [summary param] 0 in NewReaderDict | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReaderDict | +| file://:0:0:0:0 | [summary param] 0 in NewReaderSize | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReaderSize | +| file://:0:0:0:0 | [summary param] 0 in NewScanner | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewScanner | +| file://:0:0:0:0 | [summary param] 0 in NewSectionReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewSectionReader | +| file://:0:0:0:0 | [summary param] 0 in NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | +| file://:0:0:0:0 | [summary param] 0 in NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser | +| file://:0:0:0:0 | [summary param] 0 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | [summary param] 0 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | [summary param] 0 in ParseMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseMediaType | +| file://:0:0:0:0 | [summary param] 0 in ParseMediaType | file://:0:0:0:0 | [summary] to write: return (return[1]) in ParseMediaType | +| file://:0:0:0:0 | [summary param] 0 in ParseQuery | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseQuery | +| file://:0:0:0:0 | [summary param] 0 in ParseRequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseRequestURI | +| file://:0:0:0:0 | [summary param] 0 in PathEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathEscape | +| file://:0:0:0:0 | [summary param] 0 in PathUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathUnescape | +| file://:0:0:0:0 | [summary param] 0 in PushBack | file://:0:0:0:0 | [summary] to write: argument -1 in PushBack | +| file://:0:0:0:0 | [summary param] 0 in PushBack | file://:0:0:0:0 | [summary] to write: return (return[0]) in PushBack | +| file://:0:0:0:0 | [summary param] 0 in PushBackList | file://:0:0:0:0 | [summary] to write: argument -1 in PushBackList | +| file://:0:0:0:0 | [summary param] 0 in PushFront | file://:0:0:0:0 | [summary] to write: argument -1 in PushFront | +| file://:0:0:0:0 | [summary param] 0 in PushFront | file://:0:0:0:0 | [summary] to write: return (return[0]) in PushFront | +| file://:0:0:0:0 | [summary param] 0 in PushFrontList | file://:0:0:0:0 | [summary] to write: argument -1 in PushFrontList | +| file://:0:0:0:0 | [summary param] 0 in Put | file://:0:0:0:0 | [summary] to write: argument -1 in Put | +| file://:0:0:0:0 | [summary param] 0 in QueryEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryEscape | +| file://:0:0:0:0 | [summary param] 0 in QueryUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryUnescape | +| file://:0:0:0:0 | [summary param] 0 in Quote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Quote | +| file://:0:0:0:0 | [summary param] 0 in QuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToASCII | +| file://:0:0:0:0 | [summary param] 0 in QuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToGraphic | +| file://:0:0:0:0 | [summary param] 0 in QuotedPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuotedPrefix | +| file://:0:0:0:0 | [summary param] 0 in Read | file://:0:0:0:0 | [summary] to write: argument 2 in Read | +| file://:0:0:0:0 | [summary param] 0 in ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | +| file://:0:0:0:0 | [summary param] 0 in ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll | +| file://:0:0:0:0 | [summary param] 0 in ReadAtLeast | file://:0:0:0:0 | [summary] to write: argument 1 in ReadAtLeast | +| file://:0:0:0:0 | [summary param] 0 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | [summary param] 0 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom | +| file://:0:0:0:0 | [summary param] 0 in ReadFull | file://:0:0:0:0 | [summary] to write: argument 1 in ReadFull | +| file://:0:0:0:0 | [summary param] 0 in ReadRequest | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadRequest | +| file://:0:0:0:0 | [summary param] 0 in ReadResponse | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadResponse | +| file://:0:0:0:0 | [summary param] 0 in Rel | file://:0:0:0:0 | [summary] to write: return (return[0]) in Rel | +| file://:0:0:0:0 | [summary param] 0 in Remove | file://:0:0:0:0 | [summary] to write: return (return[0]) in Remove | +| file://:0:0:0:0 | [summary param] 0 in Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | +| file://:0:0:0:0 | [summary param] 0 in Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat | +| file://:0:0:0:0 | [summary param] 0 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | [summary param] 0 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | [summary param] 0 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | [summary param] 0 in ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | [summary param] 0 in ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | [summary param] 0 in Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | [summary param] 0 in Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | [summary param] 0 in Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | [summary param] 0 in Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | [summary param] 0 in Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | [summary param] 0 in Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset | +| file://:0:0:0:0 | [summary param] 0 in ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | +| file://:0:0:0:0 | [summary param] 0 in Reverse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Reverse | +| file://:0:0:0:0 | [summary param] 0 in Runes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Runes | +| file://:0:0:0:0 | [summary param] 0 in ScanBytes | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanBytes | +| file://:0:0:0:0 | [summary param] 0 in ScanLines | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanLines | +| file://:0:0:0:0 | [summary param] 0 in ScanRunes | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanRunes | +| file://:0:0:0:0 | [summary param] 0 in ScanWords | file://:0:0:0:0 | [summary] to write: return (return[1]) in ScanWords | +| file://:0:0:0:0 | [summary param] 0 in Send | file://:0:0:0:0 | [summary] to write: argument -1 in Send | +| file://:0:0:0:0 | [summary param] 0 in Server | file://:0:0:0:0 | [summary] to write: return (return[0]) in Server | +| file://:0:0:0:0 | [summary param] 0 in Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | [summary param] 0 in Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | [summary param] 0 in Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | [summary param] 0 in SetBytes | file://:0:0:0:0 | [summary] to write: argument -1 in SetBytes | +| file://:0:0:0:0 | [summary param] 0 in SetIndent | file://:0:0:0:0 | [summary] to write: argument -1 in SetIndent | +| file://:0:0:0:0 | [summary param] 0 in SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | +| file://:0:0:0:0 | [summary param] 0 in SetPointer | file://:0:0:0:0 | [summary] to write: argument -1 in SetPointer | +| file://:0:0:0:0 | [summary param] 0 in SetPrefix | file://:0:0:0:0 | [summary] to write: argument -1 in SetPrefix | +| file://:0:0:0:0 | [summary param] 0 in SetString | file://:0:0:0:0 | [summary] to write: argument -1 in SetString | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | +| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split | +| file://:0:0:0:0 | [summary param] 0 in SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | +| file://:0:0:0:0 | [summary param] 0 in SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter | +| file://:0:0:0:0 | [summary param] 0 in SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | +| file://:0:0:0:0 | [summary param] 0 in SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN | +| file://:0:0:0:0 | [summary param] 0 in SplitHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitHostPort | +| file://:0:0:0:0 | [summary param] 0 in SplitHostPort | file://:0:0:0:0 | [summary] to write: return (return[1]) in SplitHostPort | +| file://:0:0:0:0 | [summary param] 0 in SplitList | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitList | +| file://:0:0:0:0 | [summary param] 0 in SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | +| file://:0:0:0:0 | [summary param] 0 in SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN | +| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 0 in StringBytePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringBytePtr | +| file://:0:0:0:0 | [summary param] 0 in StringByteSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringByteSlice | +| file://:0:0:0:0 | [summary param] 0 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 0 in SwapPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapPointer | +| file://:0:0:0:0 | [summary param] 0 in SwapUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapUintptr | +| file://:0:0:0:0 | [summary param] 0 in TeeReader | file://:0:0:0:0 | [summary] to write: argument 1 in TeeReader | +| file://:0:0:0:0 | [summary param] 0 in TeeReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in TeeReader | +| file://:0:0:0:0 | [summary param] 0 in Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | +| file://:0:0:0:0 | [summary param] 0 in Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title | +| file://:0:0:0:0 | [summary param] 0 in ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | +| file://:0:0:0:0 | [summary param] 0 in ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower | +| file://:0:0:0:0 | [summary param] 0 in ToSlash | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToSlash | +| file://:0:0:0:0 | [summary param] 0 in ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | +| file://:0:0:0:0 | [summary param] 0 in ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle | +| file://:0:0:0:0 | [summary param] 0 in ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | +| file://:0:0:0:0 | [summary param] 0 in ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper | +| file://:0:0:0:0 | [summary param] 0 in ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | [summary param] 0 in ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | [summary param] 0 in Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | +| file://:0:0:0:0 | [summary param] 0 in Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim | +| file://:0:0:0:0 | [summary param] 0 in TrimBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimBytes | +| file://:0:0:0:0 | [summary param] 0 in TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | +| file://:0:0:0:0 | [summary param] 0 in TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft | +| file://:0:0:0:0 | [summary param] 0 in TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | +| file://:0:0:0:0 | [summary param] 0 in TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix | +| file://:0:0:0:0 | [summary param] 0 in TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | +| file://:0:0:0:0 | [summary param] 0 in TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight | +| file://:0:0:0:0 | [summary param] 0 in TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc | +| file://:0:0:0:0 | [summary param] 0 in TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | +| file://:0:0:0:0 | [summary param] 0 in TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace | +| file://:0:0:0:0 | [summary param] 0 in TrimString | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimString | +| file://:0:0:0:0 | [summary param] 0 in TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | +| file://:0:0:0:0 | [summary param] 0 in TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix | +| file://:0:0:0:0 | [summary param] 0 in TrySend | file://:0:0:0:0 | [summary] to write: argument -1 in TrySend | +| file://:0:0:0:0 | [summary param] 0 in Unmarshal | file://:0:0:0:0 | [summary] to write: argument 1 in Unmarshal | +| file://:0:0:0:0 | [summary param] 0 in Unmarshal | file://:0:0:0:0 | [summary] to write: argument 1 in Unmarshal | +| file://:0:0:0:0 | [summary param] 0 in Unmarshal | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unmarshal | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalBinary | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalBinary | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalJSON | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalJSON | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalText | file://:0:0:0:0 | [summary] to write: argument -1 in UnmarshalText | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: argument 1 in UnmarshalWithParams | +| file://:0:0:0:0 | [summary param] 0 in UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnmarshalWithParams | +| file://:0:0:0:0 | [summary param] 0 in Unquote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unquote | +| file://:0:0:0:0 | [summary param] 0 in UnquoteChar | file://:0:0:0:0 | [summary] to write: return (return[2]) in UnquoteChar | +| file://:0:0:0:0 | [summary param] 0 in Unwrap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unwrap | +| file://:0:0:0:0 | [summary param] 0 in User | file://:0:0:0:0 | [summary] to write: return (return[0]) in User | +| file://:0:0:0:0 | [summary param] 0 in UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | +| file://:0:0:0:0 | [summary param] 0 in ValueOf | file://:0:0:0:0 | [summary] to write: return (return[0]) in ValueOf | +| file://:0:0:0:0 | [summary param] 0 in VolumeName | file://:0:0:0:0 | [summary] to write: return (return[0]) in VolumeName | +| file://:0:0:0:0 | [summary param] 0 in WithCancel | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithCancel | +| file://:0:0:0:0 | [summary param] 0 in WithDeadline | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithDeadline | +| file://:0:0:0:0 | [summary param] 0 in WithTimeout | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithTimeout | +| file://:0:0:0:0 | [summary param] 0 in WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write | +| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt | +| file://:0:0:0:0 | [summary param] 0 in WriteField | file://:0:0:0:0 | [summary] to write: argument -1 in WriteField | +| file://:0:0:0:0 | [summary param] 0 in WriteMsgIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgIP | +| file://:0:0:0:0 | [summary param] 0 in WriteMsgUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUDP | +| file://:0:0:0:0 | [summary param] 0 in WriteMsgUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUnix | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString | +| file://:0:0:0:0 | [summary param] 0 in WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | +| file://:0:0:0:0 | [summary param] 0 in WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | +| file://:0:0:0:0 | [summary param] 0 in WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | +| file://:0:0:0:0 | [summary param] 0 in WriteTo | file://:0:0:0:0 | [summary] to write: argument -1 in WriteTo | +| file://:0:0:0:0 | [summary param] 0 in WriteToIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToIP | +| file://:0:0:0:0 | [summary param] 0 in WriteToUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToUDP | +| file://:0:0:0:0 | [summary param] 0 in WriteToUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteToUnix | +| file://:0:0:0:0 | [summary param] 1 in Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | +| file://:0:0:0:0 | [summary param] 1 in Add | file://:0:0:0:0 | [summary] to write: argument -1 in Add | +| file://:0:0:0:0 | [summary param] 1 in AddUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in AddUintptr | +| file://:0:0:0:0 | [summary param] 1 in AddUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in AddUintptr | +| file://:0:0:0:0 | [summary param] 1 in AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote | +| file://:0:0:0:0 | [summary param] 1 in AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII | +| file://:0:0:0:0 | [summary param] 1 in AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic | +| file://:0:0:0:0 | [summary param] 1 in AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice | +| file://:0:0:0:0 | [summary param] 1 in Compact | file://:0:0:0:0 | [summary] to write: argument 0 in Compact | +| file://:0:0:0:0 | [summary param] 1 in Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | +| file://:0:0:0:0 | [summary param] 1 in Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy | +| file://:0:0:0:0 | [summary param] 1 in CopyBuffer | file://:0:0:0:0 | [summary] to write: argument 0 in CopyBuffer | +| file://:0:0:0:0 | [summary param] 1 in CopyN | file://:0:0:0:0 | [summary] to write: argument 0 in CopyN | +| file://:0:0:0:0 | [summary param] 1 in Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | +| file://:0:0:0:0 | [summary param] 1 in Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | +| file://:0:0:0:0 | [summary param] 1 in Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | [summary param] 1 in Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | [summary param] 1 in Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | [summary param] 1 in Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | [summary param] 1 in Decrypt | file://:0:0:0:0 | [summary] to write: argument 0 in Decrypt | +| file://:0:0:0:0 | [summary param] 1 in Decrypt | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decrypt | +| file://:0:0:0:0 | [summary param] 1 in Decrypt | file://:0:0:0:0 | [summary] to write: return (return[0]) in Decrypt | +| file://:0:0:0:0 | [summary param] 1 in Encode | file://:0:0:0:0 | [summary] to write: argument 0 in Encode | +| file://:0:0:0:0 | [summary param] 1 in Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | +| file://:0:0:0:0 | [summary param] 1 in Error | file://:0:0:0:0 | [summary] to write: argument 0 in Error | +| file://:0:0:0:0 | [summary param] 1 in FormatMediaType | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormatMediaType | +| file://:0:0:0:0 | [summary param] 1 in HTMLEscape | file://:0:0:0:0 | [summary] to write: argument 0 in HTMLEscape | +| file://:0:0:0:0 | [summary param] 1 in Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | +| file://:0:0:0:0 | [summary param] 1 in Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | [summary param] 1 in Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join | +| file://:0:0:0:0 | [summary param] 1 in JoinHostPort | file://:0:0:0:0 | [summary] to write: return (return[0]) in JoinHostPort | +| file://:0:0:0:0 | [summary param] 1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore | +| file://:0:0:0:0 | [summary param] 1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | [summary param] 1 in Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | +| file://:0:0:0:0 | [summary param] 1 in Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map | +| file://:0:0:0:0 | [summary param] 1 in MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | +| file://:0:0:0:0 | [summary param] 1 in MarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalWithParams | +| file://:0:0:0:0 | [summary param] 1 in MaxBytesReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in MaxBytesReader | +| file://:0:0:0:0 | [summary param] 1 in NewDecoder | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewDecoder | +| file://:0:0:0:0 | [summary param] 1 in NewRequest | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewRequest | +| file://:0:0:0:0 | [summary param] 1 in Rel | file://:0:0:0:0 | [summary] to write: return (return[0]) in Rel | +| file://:0:0:0:0 | [summary param] 1 in Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | [summary param] 1 in Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set | +| file://:0:0:0:0 | [summary param] 1 in SetCookie | file://:0:0:0:0 | [summary] to write: argument 0 in SetCookie | +| file://:0:0:0:0 | [summary param] 1 in SetIndent | file://:0:0:0:0 | [summary] to write: argument -1 in SetIndent | +| file://:0:0:0:0 | [summary param] 1 in SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex | +| file://:0:0:0:0 | [summary param] 1 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store | +| file://:0:0:0:0 | [summary param] 1 in StorePointer | file://:0:0:0:0 | [summary] to write: argument 0 in StorePointer | +| file://:0:0:0:0 | [summary param] 1 in StoreUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in StoreUintptr | +| file://:0:0:0:0 | [summary param] 1 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap | +| file://:0:0:0:0 | [summary param] 1 in SwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in SwapPointer | +| file://:0:0:0:0 | [summary param] 1 in SwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in SwapUintptr | +| file://:0:0:0:0 | [summary param] 1 in ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial | +| file://:0:0:0:0 | [summary param] 1 in ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | [summary param] 1 in ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 | +| file://:0:0:0:0 | [summary param] 1 in UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword | +| file://:0:0:0:0 | [summary param] 1 in WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | +| file://:0:0:0:0 | [summary param] 1 in WriteField | file://:0:0:0:0 | [summary] to write: argument -1 in WriteField | +| file://:0:0:0:0 | [summary param] 1 in WriteMsgIP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgIP | +| file://:0:0:0:0 | [summary param] 1 in WriteMsgUDP | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUDP | +| file://:0:0:0:0 | [summary param] 1 in WriteMsgUnix | file://:0:0:0:0 | [summary] to write: argument -1 in WriteMsgUnix | +| file://:0:0:0:0 | [summary param] 1 in WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | +| file://:0:0:0:0 | [summary param] 1 in WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString | +| file://:0:0:0:0 | [summary param] 2 in CompareAndSwap | file://:0:0:0:0 | [summary] to write: argument -1 in CompareAndSwap | +| file://:0:0:0:0 | [summary param] 2 in CompareAndSwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapPointer | +| file://:0:0:0:0 | [summary param] 2 in CompareAndSwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapUintptr | +| file://:0:0:0:0 | [summary param] 2 in DecryptPKCS1v15 | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptPKCS1v15 | +| file://:0:0:0:0 | [summary param] 2 in Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | +| file://:0:0:0:0 | [summary param] 2 in MarshalIndent | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalIndent | +| file://:0:0:0:0 | [summary param] 2 in NewRequestWithContext | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewRequestWithContext | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: argument 0 in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] 2 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] 2 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | [summary param] 2 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace | +| file://:0:0:0:0 | [summary param] 2 in ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | [summary param] 2 in ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll | +| file://:0:0:0:0 | [summary param] 2 in UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: argument 1 in UnmarshalWithParams | +| file://:0:0:0:0 | [summary param] 2 in UnmarshalWithParams | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnmarshalWithParams | +| file://:0:0:0:0 | [summary param] 2 in WithValue | file://:0:0:0:0 | [summary] to write: return (return[0]) in WithValue | +| file://:0:0:0:0 | [summary param] 2 in Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | +| file://:0:0:0:0 | [summary param] 3 in DecryptOAEP | file://:0:0:0:0 | [summary] to write: return (return[0]) in DecryptOAEP | +| file://:0:0:0:0 | [summary param] 3 in Indent | file://:0:0:0:0 | [summary] to write: argument 0 in Indent | +| file://:0:0:0:0 | [summary param] -1 in Addr | file://:0:0:0:0 | [summary] to write: return (return[0]) in Addr | +| file://:0:0:0:0 | [summary param] -1 in Back | file://:0:0:0:0 | [summary] to write: return (return[0]) in Back | +| file://:0:0:0:0 | [summary param] -1 in Buffered | file://:0:0:0:0 | [summary] to write: return (return[0]) in Buffered | +| file://:0:0:0:0 | [summary param] -1 in Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | +| file://:0:0:0:0 | [summary param] -1 in Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | +| file://:0:0:0:0 | [summary param] -1 in Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes | +| file://:0:0:0:0 | [summary param] -1 in Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | +| file://:0:0:0:0 | [summary param] -1 in Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | +| file://:0:0:0:0 | [summary param] -1 in Clone | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clone | +| file://:0:0:0:0 | [summary param] -1 in Convert | file://:0:0:0:0 | [summary] to write: return (return[0]) in Convert | +| file://:0:0:0:0 | [summary param] -1 in Decode | file://:0:0:0:0 | [summary] to write: argument 0 in Decode | +| file://:0:0:0:0 | [summary param] -1 in DotReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in DotReader | +| file://:0:0:0:0 | [summary param] -1 in Elem | file://:0:0:0:0 | [summary] to write: return (return[0]) in Elem | +| file://:0:0:0:0 | [summary param] -1 in Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode | +| file://:0:0:0:0 | [summary param] -1 in EscapedPath | file://:0:0:0:0 | [summary] to write: return (return[0]) in EscapedPath | +| file://:0:0:0:0 | [summary param] -1 in Fd | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fd | +| file://:0:0:0:0 | [summary param] -1 in Field | file://:0:0:0:0 | [summary] to write: return (return[0]) in Field | +| file://:0:0:0:0 | [summary param] -1 in FieldByIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByIndex | +| file://:0:0:0:0 | [summary param] -1 in FieldByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByName | +| file://:0:0:0:0 | [summary param] -1 in FieldByNameFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByNameFunc | +| file://:0:0:0:0 | [summary param] -1 in File | file://:0:0:0:0 | [summary] to write: return (return[0]) in File | +| file://:0:0:0:0 | [summary param] -1 in File | file://:0:0:0:0 | [summary] to write: return (return[0]) in File | +| file://:0:0:0:0 | [summary param] -1 in FileName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileName | +| file://:0:0:0:0 | [summary param] -1 in FormName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FormName | +| file://:0:0:0:0 | [summary param] -1 in Front | file://:0:0:0:0 | [summary] to write: return (return[0]) in Front | +| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get | +| file://:0:0:0:0 | [summary param] -1 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | [summary param] -1 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString | +| file://:0:0:0:0 | [summary param] -1 in Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | +| file://:0:0:0:0 | [summary param] -1 in Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | +| file://:0:0:0:0 | [summary param] -1 in Hijack | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hijack | +| file://:0:0:0:0 | [summary param] -1 in Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | +| file://:0:0:0:0 | [summary param] -1 in Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | +| file://:0:0:0:0 | [summary param] -1 in Hijack | file://:0:0:0:0 | [summary] to write: return (return[1]) in Hijack | +| file://:0:0:0:0 | [summary param] -1 in Hostname | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hostname | +| file://:0:0:0:0 | [summary param] -1 in Index | file://:0:0:0:0 | [summary] to write: return (return[0]) in Index | +| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info | +| file://:0:0:0:0 | [summary param] -1 in Init | file://:0:0:0:0 | [summary] to write: return (return[0]) in Init | +| file://:0:0:0:0 | [summary param] -1 in Interface | file://:0:0:0:0 | [summary] to write: return (return[0]) in Interface | +| file://:0:0:0:0 | [summary param] -1 in InterfaceData | file://:0:0:0:0 | [summary] to write: return (return[0]) in InterfaceData | +| file://:0:0:0:0 | [summary param] -1 in Key | file://:0:0:0:0 | [summary] to write: return (return[0]) in Key | +| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load | +| file://:0:0:0:0 | [summary param] -1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore | +| file://:0:0:0:0 | [summary param] -1 in Lookup | file://:0:0:0:0 | [summary] to write: return (return[0]) in Lookup | +| file://:0:0:0:0 | [summary param] -1 in MapIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapIndex | +| file://:0:0:0:0 | [summary param] -1 in MapKeys | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapKeys | +| file://:0:0:0:0 | [summary param] -1 in MapRange | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapRange | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary | +| file://:0:0:0:0 | [summary param] -1 in MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | +| file://:0:0:0:0 | [summary param] -1 in MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | +| file://:0:0:0:0 | [summary param] -1 in MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | +| file://:0:0:0:0 | [summary param] -1 in MarshalJSON | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalJSON | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in MarshalText | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalText | +| file://:0:0:0:0 | [summary param] -1 in Method | file://:0:0:0:0 | [summary] to write: return (return[0]) in Method | +| file://:0:0:0:0 | [summary param] -1 in MethodByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in MethodByName | +| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name | +| file://:0:0:0:0 | [summary param] -1 in Next | file://:0:0:0:0 | [summary] to write: return (return[0]) in Next | +| file://:0:0:0:0 | [summary param] -1 in Next | file://:0:0:0:0 | [summary] to write: return (return[0]) in Next | +| file://:0:0:0:0 | [summary param] -1 in NextPart | file://:0:0:0:0 | [summary] to write: return (return[0]) in NextPart | +| file://:0:0:0:0 | [summary param] -1 in NextRawPart | file://:0:0:0:0 | [summary] to write: return (return[0]) in NextRawPart | +| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open | +| file://:0:0:0:0 | [summary param] -1 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse | +| file://:0:0:0:0 | [summary param] -1 in Password | file://:0:0:0:0 | [summary] to write: return (return[0]) in Password | +| file://:0:0:0:0 | [summary param] -1 in Peek | file://:0:0:0:0 | [summary] to write: return (return[0]) in Peek | +| file://:0:0:0:0 | [summary param] -1 in Pointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Pointer | +| file://:0:0:0:0 | [summary param] -1 in Port | file://:0:0:0:0 | [summary] to write: return (return[0]) in Port | +| file://:0:0:0:0 | [summary param] -1 in Prev | file://:0:0:0:0 | [summary] to write: return (return[0]) in Prev | +| file://:0:0:0:0 | [summary param] -1 in Query | file://:0:0:0:0 | [summary] to write: return (return[0]) in Query | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt | +| file://:0:0:0:0 | [summary param] -1 in ReadBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadBytes | +| file://:0:0:0:0 | [summary param] -1 in ReadBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadBytes | +| file://:0:0:0:0 | [summary param] -1 in ReadCodeLine | file://:0:0:0:0 | [summary] to write: return (return[1]) in ReadCodeLine | +| file://:0:0:0:0 | [summary param] -1 in ReadContinuedLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadContinuedLine | +| file://:0:0:0:0 | [summary param] -1 in ReadContinuedLineBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadContinuedLineBytes | +| file://:0:0:0:0 | [summary param] -1 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | [summary param] -1 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | [summary param] -1 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir | +| file://:0:0:0:0 | [summary param] -1 in ReadDotBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDotBytes | +| file://:0:0:0:0 | [summary param] -1 in ReadDotLines | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDotLines | +| file://:0:0:0:0 | [summary param] -1 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | [summary param] -1 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | [summary param] -1 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile | +| file://:0:0:0:0 | [summary param] -1 in ReadForm | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadForm | +| file://:0:0:0:0 | [summary param] -1 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | +| file://:0:0:0:0 | [summary param] -1 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | +| file://:0:0:0:0 | [summary param] -1 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | +| file://:0:0:0:0 | [summary param] -1 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFrom | +| file://:0:0:0:0 | [summary param] -1 in ReadFromIP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromIP | +| file://:0:0:0:0 | [summary param] -1 in ReadFromUDP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromUDP | +| file://:0:0:0:0 | [summary param] -1 in ReadFromUnix | file://:0:0:0:0 | [summary] to write: argument 0 in ReadFromUnix | +| file://:0:0:0:0 | [summary param] -1 in ReadLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLine | +| file://:0:0:0:0 | [summary param] -1 in ReadLine | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLine | +| file://:0:0:0:0 | [summary param] -1 in ReadLineBytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadLineBytes | +| file://:0:0:0:0 | [summary param] -1 in ReadMIMEHeader | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadMIMEHeader | +| file://:0:0:0:0 | [summary param] -1 in ReadMsgIP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgIP | +| file://:0:0:0:0 | [summary param] -1 in ReadMsgIP | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgIP | +| file://:0:0:0:0 | [summary param] -1 in ReadMsgUDP | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgUDP | +| file://:0:0:0:0 | [summary param] -1 in ReadMsgUDP | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgUDP | +| file://:0:0:0:0 | [summary param] -1 in ReadMsgUnix | file://:0:0:0:0 | [summary] to write: argument 0 in ReadMsgUnix | +| file://:0:0:0:0 | [summary param] -1 in ReadMsgUnix | file://:0:0:0:0 | [summary] to write: argument 1 in ReadMsgUnix | +| file://:0:0:0:0 | [summary param] -1 in ReadResponse | file://:0:0:0:0 | [summary] to write: return (return[1]) in ReadResponse | +| file://:0:0:0:0 | [summary param] -1 in ReadSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadSlice | +| file://:0:0:0:0 | [summary param] -1 in ReadString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadString | +| file://:0:0:0:0 | [summary param] -1 in ReadString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadString | +| file://:0:0:0:0 | [summary param] -1 in Recv | file://:0:0:0:0 | [summary] to write: return (return[0]) in Recv | +| file://:0:0:0:0 | [summary param] -1 in RequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in RequestURI | +| file://:0:0:0:0 | [summary param] -1 in Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | +| file://:0:0:0:0 | [summary param] -1 in Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | +| file://:0:0:0:0 | [summary param] -1 in Reset | file://:0:0:0:0 | [summary] to write: argument 0 in Reset | +| file://:0:0:0:0 | [summary param] -1 in ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference | +| file://:0:0:0:0 | [summary param] -1 in SetOutput | file://:0:0:0:0 | [summary] to write: argument 0 in SetOutput | +| file://:0:0:0:0 | [summary param] -1 in Slice | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice | +| file://:0:0:0:0 | [summary param] -1 in Slice3 | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice3 | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String | +| file://:0:0:0:0 | [summary param] -1 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | [summary param] -1 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub | +| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn | +| file://:0:0:0:0 | [summary param] -1 in Text | file://:0:0:0:0 | [summary] to write: return (return[0]) in Text | +| file://:0:0:0:0 | [summary param] -1 in Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | [summary param] -1 in Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | [summary param] -1 in Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token | +| file://:0:0:0:0 | [summary param] -1 in TryRecv | file://:0:0:0:0 | [summary] to write: return (return[0]) in TryRecv | +| file://:0:0:0:0 | [summary param] -1 in UnsafeAddr | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnsafeAddr | +| file://:0:0:0:0 | [summary param] -1 in Username | file://:0:0:0:0 | [summary] to write: return (return[0]) in Username | +| file://:0:0:0:0 | [summary param] -1 in Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | [summary param] -1 in Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | [summary param] -1 in Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | [summary param] -1 in Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | [summary param] -1 in Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | [summary param] -1 in Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value | +| file://:0:0:0:0 | [summary param] -1 in Values | file://:0:0:0:0 | [summary] to write: return (return[0]) in Values | +| file://:0:0:0:0 | [summary param] -1 in Values | file://:0:0:0:0 | [summary] to write: return (return[0]) in Values | +| file://:0:0:0:0 | [summary param] -1 in Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | +| file://:0:0:0:0 | [summary param] -1 in Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | +| file://:0:0:0:0 | [summary param] -1 in Write | file://:0:0:0:0 | [summary] to write: argument 0 in Write | +| file://:0:0:0:0 | [summary param] -1 in WriteProxy | file://:0:0:0:0 | [summary] to write: argument 0 in WriteProxy | +| file://:0:0:0:0 | [summary param] -1 in WriteSubset | file://:0:0:0:0 | [summary] to write: argument 0 in WriteSubset | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo | +| file://:0:0:0:0 | [summary param] -1 in Writer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Writer | | io.go:14:31:14:43 | "some string" | io.go:14:13:14:44 | call to NewReader | | io.go:16:3:16:3 | definition of w | io.go:16:23:16:27 | &... | | io.go:16:3:16:3 | definition of w | io.go:16:30:16:34 | &... | From b2d3f29ef3f33ea909e1df7e5e588ffa9e74e460 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 25 May 2023 14:26:08 +0200 Subject: [PATCH 487/739] Swift: Fix tests. --- .../CWE-079/UnsafeWebViewFetch.expected | 24 +++++++++---------- .../Security/CWE-089/SqlInjection.expected | 12 +++++----- .../Security/CWE-094/UnsafeJsEval.expected | 18 +++++++------- .../StaticInitializationVector.expected | 12 +++++----- .../CWE-134/UncontrolledFormatString.expected | 12 +++++----- .../CWE-311/CleartextTransmission.expected | 6 ++--- .../CWE-321/HardcodedEncryptionKey.expected | 12 +++++----- .../Security/CWE-760/ConstantSalt.expected | 8 +++---- 8 files changed, 52 insertions(+), 52 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected b/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected index e1968b05209..b21ed3b030c 100644 --- a/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected +++ b/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected @@ -1,7 +1,7 @@ edges -| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) | -| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) | -| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | +| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | +| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | +| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:120:25:120:39 | call to getRemoteData() | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() | @@ -63,8 +63,11 @@ edges | UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() | UnsafeWebViewFetch.swift:211:25:211:25 | htmlData | nodes | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | semmle.label | [summary param] 0 in URL.init(string:) | +| UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | semmle.label | [summary] to write: return (return) in URL.init(string:) | | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | semmle.label | [summary param] 1 in URL.init(string:relativeTo:) | +| UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | semmle.label | [summary] to write: return (return) in URL.init(string:relativeTo:) | | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | +| UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... | semmle.label | try ... | | UnsafeWebViewFetch.swift:94:14:94:37 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | semmle.label | try! ... | @@ -122,16 +125,13 @@ nodes | UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() | semmle.label | call to getRemoteData() | | UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | semmle.label | htmlData | | UnsafeWebViewFetch.swift:211:25:211:25 | htmlData | semmle.label | htmlData | -| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | -| file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) | semmle.label | [summary] to write: return (return) in URL.init(string:) | -| file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) | semmle.label | [summary] to write: return (return) in URL.init(string:relativeTo:) | subpaths -| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) | -| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:132:19:132:61 | call to URL.init(string:relativeTo:) | -| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:150:19:150:41 | call to Data.init(_:) | -| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) | -| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:179:19:179:61 | call to URL.init(string:relativeTo:) | -| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:197:19:197:41 | call to Data.init(_:) | +| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) | +| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:132:19:132:61 | call to URL.init(string:relativeTo:) | +| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:150:19:150:41 | call to Data.init(_:) | +| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) | +| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:179:19:179:61 | call to URL.init(string:relativeTo:) | +| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:197:19:197:41 | call to Data.init(_:) | #select | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | UnsafeWebViewFetch.swift:103:30:103:84 | call to String.init(contentsOf:) | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | Tainted data is used in a WebView fetch without restricting the base URL. | | UnsafeWebViewFetch.swift:106:25:106:25 | data | UnsafeWebViewFetch.swift:105:18:105:72 | call to String.init(contentsOf:) | UnsafeWebViewFetch.swift:106:25:106:25 | data | Tainted data is used in a WebView fetch without restricting the base URL. | diff --git a/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 6b21566c484..7c5466939f2 100644 --- a/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -97,8 +97,8 @@ edges | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:117:16:117:16 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:119:16:119:16 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:132:20:132:20 | remoteString | -| sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:count:) | -| sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | file://:0:0:0:0 | [summary] to write: return (return) in data(using:allowLossyConversion:) | +| sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) | +| sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | @@ -226,10 +226,10 @@ nodes | SQLite.swift:117:16:117:16 | unsafeQuery1 | semmle.label | unsafeQuery1 | | SQLite.swift:119:16:119:16 | unsafeQuery1 | semmle.label | unsafeQuery1 | | SQLite.swift:132:20:132:20 | remoteString | semmle.label | remoteString | -| file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:count:) | semmle.label | [summary] to write: argument 0 in copyBytes(to:count:) | -| file://:0:0:0:0 | [summary] to write: return (return) in data(using:allowLossyConversion:) | semmle.label | [summary] to write: return (return) in data(using:allowLossyConversion:) | | sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | semmle.label | [summary param] this in copyBytes(to:count:) | +| sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) | semmle.label | [summary] to write: argument 0 in copyBytes(to:count:) | | sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | semmle.label | [summary param] this in data(using:allowLossyConversion:) | +| sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) | semmle.label | [summary] to write: return (return) in data(using:allowLossyConversion:) | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | semmle.label | unsafeQuery1 | | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | semmle.label | unsafeQuery2 | @@ -245,8 +245,8 @@ nodes | sqlite3_c_api.swift:202:31:202:31 | buffer | semmle.label | buffer | | sqlite3_c_api.swift:210:31:210:31 | buffer | semmle.label | buffer | subpaths -| sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | file://:0:0:0:0 | [summary] to write: return (return) in data(using:allowLossyConversion:) | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | -| sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:count:) | sqlite3_c_api.swift:190:21:190:21 | [post] buffer | +| sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | +| sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) | sqlite3_c_api.swift:190:21:190:21 | [post] buffer | #select | GRDB.swift:106:41:106:41 | remoteString | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | GRDB.swift:106:41:106:41 | remoteString | This query depends on a $@. | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | user-provided value | | GRDB.swift:108:41:108:41 | remoteString | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | GRDB.swift:108:41:108:41 | remoteString | This query depends on a $@. | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | user-provided value | diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index a85c4c4be1f..de1c23c52a8 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -1,8 +1,8 @@ edges -| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | +| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | +| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | -| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | +| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) | | UnsafeJsEval.swift:165:10:165:37 | try ... | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | | UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | UnsafeJsEval.swift:165:10:165:37 | try ... | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:205:7:205:7 | remoteString | @@ -66,10 +66,13 @@ edges | file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) | nodes | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | +| UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | +| UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:124:21:124:42 | string | semmle.label | string | | UnsafeJsEval.swift:124:70:124:70 | string | semmle.label | string | | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | +| UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | UnsafeJsEval.swift:165:10:165:37 | try ... | semmle.label | try ... | | UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | semmle.label | call to getRemoteData() | @@ -106,15 +109,12 @@ nodes | UnsafeJsEval.swift:318:24:318:87 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | semmle.label | [summary param] 0 in String.init(decoding:as:) | -| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) | semmle.label | [summary] to write: return (return) in String.init(decoding:as:) | -| file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | -| file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | subpaths -| UnsafeJsEval.swift:211:24:211:37 | .utf8 | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) | +| UnsafeJsEval.swift:211:24:211:37 | .utf8 | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) | | UnsafeJsEval.swift:214:24:214:24 | remoteData | file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | -| UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:269:43:269:43 | string | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:269:22:269:124 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | +| UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | +| UnsafeJsEval.swift:269:43:269:43 | string | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:269:22:269:124 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) | #select diff --git a/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected b/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected index f557206f20d..aa6cf49411c 100644 --- a/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected +++ b/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected @@ -1,5 +1,5 @@ edges -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | +| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | rncryptor.swift:68:104:68:104 | myConstIV1 | | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | rncryptor.swift:77:125:77:125 | myConstIV1 | | rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | @@ -40,8 +40,8 @@ edges | test.swift:101:17:101:35 | call to getConstantString() | test.swift:130:39:130:39 | ivString | | test.swift:147:22:147:22 | iv | test.swift:53:19:53:34 | iv | nodes -| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | +| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | rncryptor.swift:60:24:60:24 | 0 | semmle.label | 0 | | rncryptor.swift:61:19:61:27 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | @@ -84,10 +84,10 @@ nodes | test.swift:167:22:167:22 | iv | semmle.label | iv | | test.swift:168:22:168:22 | iv | semmle.label | iv | subpaths -| rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | -| rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:61:19:61:27 | call to Data.init(_:) | -| rncryptor.swift:62:24:62:34 | [...] | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:62:19:62:35 | call to Data.init(_:) | -| rncryptor.swift:63:24:63:24 | iv | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:63:19:63:28 | call to Data.init(_:) | +| rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | +| rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:61:19:61:27 | call to Data.init(_:) | +| rncryptor.swift:62:24:62:34 | [...] | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:62:19:62:35 | call to Data.init(_:) | +| rncryptor.swift:63:24:63:24 | iv | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:63:19:63:28 | call to Data.init(_:) | #select | rncryptor.swift:68:104:68:104 | myConstIV1 | rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:68:104:68:104 | myConstIV1 | The static value '0' is used as an initialization vector for encryption. | | rncryptor.swift:70:104:70:104 | myConstIV2 | rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:70:104:70:104 | myConstIV2 | The static value '123' is used as an initialization vector for encryption. | diff --git a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected index edf2fc3b140..dd2c4f66f74 100644 --- a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected +++ b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected @@ -1,5 +1,5 @@ edges -| UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | +| UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:70:28:70:28 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:73:28:73:28 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:74:28:74:28 | tainted | @@ -23,6 +23,7 @@ edges | UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | nodes | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | semmle.label | [summary param] 0 in NSString.init(string:) | +| UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | semmle.label | [summary] to write: return (return) in NSString.init(string:) | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UncontrolledFormatString.swift:70:28:70:28 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:73:28:73:28 | tainted | semmle.label | tainted | @@ -41,12 +42,11 @@ nodes | UncontrolledFormatString.swift:85:72:85:72 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:88:11:88:11 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:91:61:91:61 | tainted | semmle.label | tainted | -| file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | semmle.label | [summary] to write: return (return) in NSString.init(string:) | subpaths -| UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:81:30:81:54 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:82:48:82:72 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:84:37:84:61 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | +| UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:81:30:81:54 | call to NSString.init(string:) | +| UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:82:48:82:72 | call to NSString.init(string:) | +| UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:84:37:84:61 | call to NSString.init(string:) | +| UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | #select | UncontrolledFormatString.swift:70:28:70:28 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:70:28:70:28 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | | UncontrolledFormatString.swift:73:28:73:28 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:73:28:73:28 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected index c832cf51a15..36c206ed9fd 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -2,7 +2,7 @@ edges | testAlamofire.swift:150:45:150:45 | password | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | | testAlamofire.swift:152:51:152:51 | password | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | | testAlamofire.swift:154:38:154:38 | email | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | -| testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | +| testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | testSend.swift:33:14:33:32 | call to Data.init(_:) | testSend.swift:37:19:37:19 | data2 | | testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:33:14:33:32 | call to Data.init(_:) | @@ -16,7 +16,6 @@ edges | testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... | | testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... | nodes -| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testAlamofire.swift:150:45:150:45 | password | semmle.label | password | | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | @@ -24,6 +23,7 @@ nodes | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testAlamofire.swift:154:38:154:38 | email | semmle.label | email | | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | +| testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | testSend.swift:29:19:29:19 | passwordPlain | semmle.label | passwordPlain | | testSend.swift:33:14:33:32 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | testSend.swift:33:19:33:19 | passwordPlain | semmle.label | passwordPlain | @@ -47,7 +47,7 @@ nodes | testURL.swift:16:55:16:55 | credit_card_no | semmle.label | credit_card_no | | testURL.swift:20:22:20:22 | passwd | semmle.label | passwd | subpaths -| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | testSend.swift:33:14:33:32 | call to Data.init(_:) | +| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | testSend.swift:33:14:33:32 | call to Data.init(_:) | | testSend.swift:54:17:54:17 | password | testSend.swift:41:10:41:18 | data | testSend.swift:41:45:41:45 | data | testSend.swift:54:13:54:25 | call to pad(_:) | #select | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | testAlamofire.swift:150:45:150:45 | password | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:150:45:150:45 | password | password | diff --git a/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected b/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected index 0e7f047e4a4..380823043c0 100644 --- a/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected +++ b/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected @@ -22,7 +22,7 @@ edges | file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self | | file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [encryptionKey] | -| misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | +| misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | value | | misc.swift:46:19:46:38 | call to Data.init(_:) | misc.swift:49:41:49:41 | myConstKey | | misc.swift:46:19:46:38 | call to Data.init(_:) | misc.swift:53:25:53:25 | myConstKey | @@ -37,7 +37,7 @@ edges | misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value | | misc.swift:57:41:57:41 | myConstKey | misc.swift:57:2:57:18 | [post] getter for .config | | misc.swift:57:41:57:41 | myConstKey | misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] | -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | +| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:65:73:65:73 | myConstKey | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:66:73:66:73 | myConstKey | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:67:73:67:73 | myConstKey | @@ -81,10 +81,9 @@ nodes | file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self [encryptionKey] | semmle.label | [post] self [encryptionKey] | -| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | -| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | file://:0:0:0:0 | value | semmle.label | value | | misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | +| misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | misc.swift:30:7:30:7 | value | semmle.label | value | | misc.swift:46:19:46:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | misc.swift:46:24:46:24 | abcdef123456 | semmle.label | abcdef123456 | @@ -96,6 +95,7 @@ nodes | misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] | semmle.label | [post] getter for .config [encryptionKey] | | misc.swift:57:41:57:41 | myConstKey | semmle.label | myConstKey | | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | +| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | rncryptor.swift:60:24:60:24 | abcdef123456 | semmle.label | abcdef123456 | | rncryptor.swift:65:73:65:73 | myConstKey | semmle.label | myConstKey | @@ -114,12 +114,12 @@ nodes | rncryptor.swift:81:102:81:102 | myConstKey | semmle.label | myConstKey | | rncryptor.swift:83:92:83:92 | myConstKey | semmle.label | myConstKey | subpaths -| misc.swift:46:24:46:24 | abcdef123456 | misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | misc.swift:46:19:46:38 | call to Data.init(_:) | +| misc.swift:46:24:46:24 | abcdef123456 | misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | misc.swift:46:19:46:38 | call to Data.init(_:) | | misc.swift:53:25:53:25 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self | misc.swift:53:2:53:2 | [post] config | | misc.swift:53:25:53:25 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self [encryptionKey] | misc.swift:53:2:53:2 | [post] config [encryptionKey] | | misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self | misc.swift:57:2:57:18 | [post] getter for .config | | misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self [encryptionKey] | misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] | -| rncryptor.swift:60:24:60:24 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | +| rncryptor.swift:60:24:60:24 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | #select | cryptoswift.swift:108:21:108:21 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:108:21:108:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | | cryptoswift.swift:109:21:109:21 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:109:21:109:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | diff --git a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected index 8311b02ece9..6dd93198451 100644 --- a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected +++ b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected @@ -1,5 +1,5 @@ edges -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | +| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:63:57:63:57 | myConstantSalt1 | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:68:106:68:106 | myConstantSalt1 | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:71:106:71:106 | myConstantSalt1 | @@ -19,8 +19,8 @@ edges | test.swift:43:35:43:130 | [...] | test.swift:62:59:62:59 | constantSalt | | test.swift:43:35:43:130 | [...] | test.swift:67:53:67:53 | constantSalt | nodes -| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | +| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | rncryptor.swift:59:29:59:29 | abcdef123456 | semmle.label | abcdef123456 | | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | @@ -41,8 +41,8 @@ nodes | test.swift:62:59:62:59 | constantSalt | semmle.label | constantSalt | | test.swift:67:53:67:53 | constantSalt | semmle.label | constantSalt | subpaths -| rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | -| rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | +| rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | +| rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | #select | rncryptor.swift:63:57:63:57 | myConstantSalt1 | rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:63:57:63:57 | myConstantSalt1 | The value 'abcdef123456' is used as a constant salt, which is insecure for hashing passwords. | | rncryptor.swift:65:55:65:55 | myConstantSalt2 | rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:65:55:65:55 | myConstantSalt2 | The value '0' is used as a constant salt, which is insecure for hashing passwords. | From 97b2bdaa9f09067b31715e71ac6c6c223838e0fa Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Fri, 26 May 2023 14:58:39 +0200 Subject: [PATCH 488/739] Java: Fix types of summary parameter nodes. --- .../semmle/code/java/dataflow/internal/DataFlowNodes.qll | 6 ------ .../code/java/dataflow/internal/FlowSummaryImpl.qll | 8 ++++++++ .../java/dataflow/internal/FlowSummaryImplSpecific.qll | 5 +++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll index 8758d0e7c24..8c44e7df5b0 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll @@ -127,8 +127,6 @@ module Public { or result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getType() or - result = this.(SummaryParameterNode).getTypeImpl() - or result = this.(FieldValueNode).getField().getType() } @@ -492,10 +490,6 @@ module Private { override predicate isParameterOf(DataFlowCallable c, int pos) { c.asSummarizedCallable() = this.getSummarizedCallable() and pos = this.getPosition() } - - Type getTypeImpl() { - result = this.getSummarizedCallable().getParameterType(this.getPosition()) - } } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index fa803e6cc92..f98c2669a8b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -505,6 +505,9 @@ module Private { or // Add the post-update node corresponding to the requested argument node outputState(c, s) and isCallbackParameter(s) + or + // Add the parameter node for parameter side-effects + outputState(c, s) and s = SummaryComponentStack::argument(_) } private newtype TSummaryNodeState = @@ -713,6 +716,11 @@ module Private { head = TSyntheticGlobalSummaryComponent(sg) and result = getSyntheticGlobalType(sg) ) + or + exists(ParameterPosition pos | + head = TArgumentSummaryComponent(pos) and + result = getParameterType(c, pos) + ) ) or n = summaryNodeOutputState(c, s) and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index 0d948b7dada..77780aa3a46 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -32,6 +32,11 @@ SummaryCall summaryDataFlowCall(SummaryNode receiver) { result.getReceiver() = r /** Gets the type of content `c`. */ DataFlowType getContentType(Content c) { result = c.getType() } +/** Gets the type of the parameter at the given position. */ +DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { + result = getErasedRepr(c.getParameterType(pos)) +} + /** Gets the return type of kind `rk` for callable `c`. */ DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { result = getErasedRepr(c.getReturnType()) and From 98f51d7f29bd1f06a199a44007b4f90116a0c663 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Fri, 26 May 2023 14:59:25 +0200 Subject: [PATCH 489/739] Dataflow: Sync. --- .../code/csharp/dataflow/internal/FlowSummaryImpl.qll | 8 ++++++++ go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll | 8 ++++++++ .../python/dataflow/new/internal/FlowSummaryImpl.qll | 8 ++++++++ .../lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll | 8 ++++++++ .../codeql/swift/dataflow/internal/FlowSummaryImpl.qll | 8 ++++++++ 5 files changed, 40 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index fa803e6cc92..f98c2669a8b 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -505,6 +505,9 @@ module Private { or // Add the post-update node corresponding to the requested argument node outputState(c, s) and isCallbackParameter(s) + or + // Add the parameter node for parameter side-effects + outputState(c, s) and s = SummaryComponentStack::argument(_) } private newtype TSummaryNodeState = @@ -713,6 +716,11 @@ module Private { head = TSyntheticGlobalSummaryComponent(sg) and result = getSyntheticGlobalType(sg) ) + or + exists(ParameterPosition pos | + head = TArgumentSummaryComponent(pos) and + result = getParameterType(c, pos) + ) ) or n = summaryNodeOutputState(c, s) and diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index fa803e6cc92..f98c2669a8b 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -505,6 +505,9 @@ module Private { or // Add the post-update node corresponding to the requested argument node outputState(c, s) and isCallbackParameter(s) + or + // Add the parameter node for parameter side-effects + outputState(c, s) and s = SummaryComponentStack::argument(_) } private newtype TSummaryNodeState = @@ -713,6 +716,11 @@ module Private { head = TSyntheticGlobalSummaryComponent(sg) and result = getSyntheticGlobalType(sg) ) + or + exists(ParameterPosition pos | + head = TArgumentSummaryComponent(pos) and + result = getParameterType(c, pos) + ) ) or n = summaryNodeOutputState(c, s) and diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index fa803e6cc92..f98c2669a8b 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -505,6 +505,9 @@ module Private { or // Add the post-update node corresponding to the requested argument node outputState(c, s) and isCallbackParameter(s) + or + // Add the parameter node for parameter side-effects + outputState(c, s) and s = SummaryComponentStack::argument(_) } private newtype TSummaryNodeState = @@ -713,6 +716,11 @@ module Private { head = TSyntheticGlobalSummaryComponent(sg) and result = getSyntheticGlobalType(sg) ) + or + exists(ParameterPosition pos | + head = TArgumentSummaryComponent(pos) and + result = getParameterType(c, pos) + ) ) or n = summaryNodeOutputState(c, s) and diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index fa803e6cc92..f98c2669a8b 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -505,6 +505,9 @@ module Private { or // Add the post-update node corresponding to the requested argument node outputState(c, s) and isCallbackParameter(s) + or + // Add the parameter node for parameter side-effects + outputState(c, s) and s = SummaryComponentStack::argument(_) } private newtype TSummaryNodeState = @@ -713,6 +716,11 @@ module Private { head = TSyntheticGlobalSummaryComponent(sg) and result = getSyntheticGlobalType(sg) ) + or + exists(ParameterPosition pos | + head = TArgumentSummaryComponent(pos) and + result = getParameterType(c, pos) + ) ) or n = summaryNodeOutputState(c, s) and diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index fa803e6cc92..f98c2669a8b 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -505,6 +505,9 @@ module Private { or // Add the post-update node corresponding to the requested argument node outputState(c, s) and isCallbackParameter(s) + or + // Add the parameter node for parameter side-effects + outputState(c, s) and s = SummaryComponentStack::argument(_) } private newtype TSummaryNodeState = @@ -713,6 +716,11 @@ module Private { head = TSyntheticGlobalSummaryComponent(sg) and result = getSyntheticGlobalType(sg) ) + or + exists(ParameterPosition pos | + head = TArgumentSummaryComponent(pos) and + result = getParameterType(c, pos) + ) ) or n = summaryNodeOutputState(c, s) and From 2ecce575a9e4f92b55fbc2e259b22bb20a4e0403 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Fri, 26 May 2023 10:16:35 +0200 Subject: [PATCH 490/739] C#: Fix types of summary parameter nodes. --- .../csharp/dataflow/internal/DataFlowPrivate.qll | 10 ---------- .../dataflow/internal/FlowSummaryImplSpecific.qll | 13 +++++++++++++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index b142f1615e9..bbc0ab8a1a2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -1136,16 +1136,6 @@ private module ParameterNodes { override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { this.getSummarizedCallable() = c.asSummarizedCallable() and pos = this.getPosition() } - - override Type getTypeImpl() { - exists(int i | - this.getPosition().getPosition() = i and - result = this.getSummarizedCallable().getParameter(i).getType() - ) - or - this.getPosition().isThisParameter() and - result = this.getSummarizedCallable().getDeclaringType() - } } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index b479bb4387e..362fa414d7b 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -41,6 +41,19 @@ DataFlowType getContentType(Content c) { ) } +/** Gets the type of the parameter at the given position. */ +DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { + exists(Type t | result = Gvn::getGlobalValueNumber(t) | + exists(int i | + pos.getPosition() = i and + t = c.getParameter(i).getType() + ) + or + pos.isThisParameter() and + t = c.getDeclaringType() + ) +} + private DataFlowType getReturnTypeBase(DotNet::Callable c, ReturnKind rk) { exists(Type t | result = Gvn::getGlobalValueNumber(t) | rk instanceof NormalReturnKind and From 5062442982044299a130f2f447b582f109e58a6d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Fri, 9 Jun 2023 15:26:24 +0200 Subject: [PATCH 491/739] Go/Python/Ruby/Swift: Add stub. --- .../semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll | 3 +++ .../python/dataflow/new/internal/FlowSummaryImplSpecific.qll | 3 +++ .../codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll | 3 +++ .../codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll | 3 +++ 4 files changed, 12 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 46b4a44bab1..41ae6b50ce3 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -37,6 +37,9 @@ DataFlowCall summaryDataFlowCall(SummaryNode receiver) { /** Gets the type of content `c`. */ DataFlowType getContentType(Content c) { result = c.getType() } +/** Gets the type of the parameter at the given position. */ +DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() } + /** Gets the return type of kind `rk` for callable `c`. */ DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll index d938de5200a..0f58d6988f0 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll @@ -53,6 +53,9 @@ SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getRec /** Gets the type of content `c`. */ DataFlowType getContentType(Content c) { any() } +/** Gets the type of the parameter at the given position. */ +DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() } + /** Gets the return type of kind `rk` for callable `c`. */ bindingset[c, rk] DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll index f2b0aa01341..d9c0594159a 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll @@ -24,6 +24,9 @@ SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getRec /** Gets the type of content `c`. */ DataFlowType getContentType(ContentSet c) { any() } +/** Gets the type of the parameter at the given position. */ +DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() } + /** Gets the return type of kind `rk` for callable `c`. */ bindingset[c, rk] DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll index f21fe17cd2c..ba84cea946a 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImplSpecific.qll @@ -26,6 +26,9 @@ SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getRec /** Gets the type of content `c`. */ DataFlowType getContentType(ContentSet c) { any() } +/** Gets the type of the parameter at the given position. */ +DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() } + /** Gets the return type of kind `rk` for callable `c`. */ bindingset[c] DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() } From dbcb1c22242d096118c9f4100a91f49ecde5f297 Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Fri, 9 Jun 2023 16:18:30 +0200 Subject: [PATCH 492/739] Ruby: update grammar --- ruby/extractor/Cargo.lock | Bin 31065 -> 31065 bytes ruby/extractor/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/extractor/Cargo.lock b/ruby/extractor/Cargo.lock index 85c546b9b96e189aae02de3062127274df104d7b..852f745b8b886516a89afe1b8fa387da4a011d69 100644 GIT binary patch delta 109 zcmccliSgzq#tkc@{8LksQcR4^Q&TMs43jL<5-m+F%nVbLO^q#5P0do%QjJrSQVfmE em5qo~I9X6xY*HlqWQi!%$^WA{HakU&%K-rJnj-1| delta 99 zcmccliSgzq#tkc@0u0QO%?-@W4b4o9&5e>xEzQ!>5-m~_6H}5bO^i*GjVvrp42{i9 Sl#Pf~IQgQe*k=A{FF61h${ia3 diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index 133233f2f14..ac23836a498 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" [dependencies] tree-sitter = "0.20" tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "203f7bd3c1bbfbd98fc19add4b8fcb213c059205" } -tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "206c7077164372c596ffa8eaadb9435c28941364" } +tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "2edbd437ee901b8fa95861ec538e56efe3ebd127" } clap = { version = "4.2", features = ["derive"] } tracing = "0.1" tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } From 96bce2a4fcd40b80b63594dddc7bea9ef90a2b4f Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:30:33 -0400 Subject: [PATCH 493/739] mrva docs update --- ...ning-codeql-queries-at-scale-with-mrva.rst | 26 ++++++++++++++++++ .../variant-analysis-code-search-language.png | Bin 0 -> 45562 bytes 2 files changed, 26 insertions(+) create mode 100644 docs/codeql/images/codeql-for-visual-studio-code/variant-analysis-code-search-language.png diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index 83dc32edf76..f8b114e34f7 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -153,6 +153,32 @@ For example, if you want to continue analyzing a set of repositories that had re You can then insert the ``new-repo-list`` of repositories into your list of custom repository lists for easy access in the Variant Analysis Repositories panel. +Using code search to add repositories to a custom list +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can use code search directly in the CodeQL extension on VSCode to add a subset of repositories from GitHub.com to a custom list. Note that this feature uses the legacy code search via the code search API. For more information on the syntax to use, see "`Searching code (legacy) <https://docs.github.com/en/search-github/searching-on-github/searching-code>`__." + +For example, to add all repositories in the `rails` organization on GitHub, you can search `org:rails`. + +Custom lists can contain a maximum of 1000 repositories, so at most only the first 1000 repositories returned from your search will be added to your list. + +#. In the Variant Analysis Repositories panel, choose the list that you want to add repositories to. You can create a new list or choose an existing list that already contains repositories. + +#. Right-click on the list you have chosen and then click **Add repositories with GitHub Code Search**. + +#. In the search bar, select a language for your search from the choices in the dropdown. + + .. image:: ../images/codeql-for-visual-studio-code/variant-analysis-code-search-language.png + :alt: Screenshot of the search bar for using code search to add repositories to a custom list. The search bar asks you to choose a language for your search and has a dropdown list of languages to choose from. + +#. Type the search query that you want to use and press **Enter**. + +#. You will see a box in the lower right of VSCode with the text "Searching for repositories...". If you click **Cancel**, no repositories will be added to your list. + +#. Once complete, you will see the resulting repositories appear in the dropdown under your custom list in the Variant Analysis Repositories panel. + +It is possible that some of the resulting repositories do not have CodeQL databases or are not accessible. When you run an analysis on the list, the results view will show you which repositories could not be analyzed. + Troubleshooting variant analysis -------------------------------- diff --git a/docs/codeql/images/codeql-for-visual-studio-code/variant-analysis-code-search-language.png b/docs/codeql/images/codeql-for-visual-studio-code/variant-analysis-code-search-language.png new file mode 100644 index 0000000000000000000000000000000000000000..ac0a7d3d5e951dcdc576db9de2c562d98e1bdd31 GIT binary patch literal 45562 zcmdqJWmr_}7d{Ng2o54BDM%Pdr-ag|fCxwqDI(oN4hTpKScK9Ht<=yUHI$%qDKK=X z^w8b#KI1vRbIz-Nct5-!{@0)D8fG(lp1q$~dp-BM*S&b5`aqr(N(aTm!y{F=cUK(` zkFXdI4<Ac>8hk>&XYm;i4~nw7b4OL-&K+h|Cwp@%TQfYodoQA5h*UM^shjIO?M2TJ zUby|{f=9$S!M!u75Y_N=!nZFlN0OhCX$<Ac|E5QN9-kh~k@gt!Iq12u(fPswi0<7; zMA73r(*}=;muuZuI>l~Sbn%`ftUR5qa;}SW#!pdozo0;;1YtHvU?JVuF>m_Z#J_fg zN79E+m4*MTxjVA(&Yb{!>xi|L?e9FkO+UEXi}X&8Pke;T{P-fs@F-t8`7=i(hpsF1 z8LqSRaN&iIWx)&C6a|{N*?QA01K1{*Cf}c7yfpdDvB`HW;W^*AHWxf%Q%03|LcF*a z*bZCo3wptefyE&@%opBq$qZeUkhtT!t`@2M^^)e*FpLGup(^XVy%5EekbCvDTPg`= zqr{SFN(yxLttWdokIU0DTd(i%$t5OmkrLl|2i@;j&NL@%)lJ~zG<_@Uzjo;OAR2P_ zfq+y5g-9zwl1lhfyW!k#3J)mv9H$Y*73U+kIyOm@O|9f&pBCI@50+>ZpYN+J?z>l+ z#5L8nFndk@u8LC`n|1#+i;N&5<!Og0v?lfS6+^b|ouuIb74PlM4yG>7A8iBXEb@dc z-CanmA)C1hrsMUSo$KWLyAP)Cwr#NJj<45Tvr1imY7}4hu)E`2OhM;u!<OvQ)OCy4 z29mRhrXTSyGLs_MANxPvj3L9*ZD`arA^L85FZ!OWLaVNlu*auoO8K$&LWx!uCKhBL z2fY%XFpTpztz7<GA(@`Hch>iy_v_cMH#GFZ1@M|x6J5OT->^F6Ykm47hT>_QpyzG+ zIz=66g8RPb1bxr(;bnZhFo@6k?R2#-FEQa|W`fWDd%k3EWkiSft`wflJ-wGgZcCsq zb8!%|?H}-s_~tomy{^Oghxj7WL=~qP{or4S9{F8f#eXeL{w$b{oV3T+<?_`Qg5m(3 zaH1&^$Q>h9E=n>M8RL7WxdZy8169v!o?h}prI>uNn!Dmcihaf?E%60!lX{=vD&NJ7 zPs4@$wxlJGg)b4xf86+X?aAeYQ?vE--_$EENS+<2r}<95%1}Y?4I#UVrzTDNoYDA2 zA^Eur{+}<ucuuM7N6E}`k3~H|@Je0__j~$_cO^|6Xz7Ap6n(BRBH(*ND`|e&9AYk! zan_k!BiO2bv|;mc5Z^=*WiE9;!NSXFW0OLKLD|8lwr5<Wwkfv-w$GK39pDFl;&-@y z)8Zi>4|R;c{!9I^5x<;9q3@!OH5EqUj0Jw>AFC$stcpLSmSn19@S*j=p9oy}<a33M z+~tfbq15e5GD<Bhk>uyjcTu2;kDi^s5@mVUg(Zj_@|opx$Y-z5azB)fnH-<JR}#2f z8FA$v`+LlLb#>BtfqDM<M1Oz(TK`uKwvaas9D(YA@1WXL9+Z+1u$CFqbM8F4a^upH z((o%%%ysWn*_tSM?_XkhRqUrOTY1<0{@(k08XwfBIG~i;9MPQp?5^y!T30wOvKK|o za89#Du_daavjxFig=Ami2t)hpJ&;hYk!R4#U?1TKX3OL((3X7vRCzBD`lwN-QCl|U zZDz6d^xONqq^TFb+!U0wBei2%637b+eTV!~xk>49`G~kCQSv=14Vyxjj@BuCxRqcn za>|JIM#XEvCb=fZCW9s#Av>Y6cvZVZy%4>aVfig9>?7>$ErKn*EitU2U@ToNT{az3 z2rHCiX)M?&WMRY8Gn(zL>+C@16+a?){K4O<Ia8v~zqF&Y;X}0b62`ihuD}25_CU0y z{Xp$|iL6gw)_N4aviILAxRIjRyY+=?o_gWY7q3=Lv*I|b4s~-9=X)xOywWNe<?;mv z_ID@lN~ud}*J+)+z;E?63%69Y{bI{!nq_md*CEcR^!uHwY3JM7hAfe4IbY>XC?+i@ zOPjWuc$NB;E3V(Vj=3JD%$|{yL88p5Y>)ijp<|wHF4iI1VdN~oVY=b8fut@Bj0kKo z4wjvDS#*h+|1lrcyQ2G+dnkG+8WSy{bvEa5&chs!oPqwJe#d@fo_=24$j#yRLyINu zra8v+mPnfs%Y*)|(NKGBxZ6mQ@rp%VPi_5iNI+n~7o*HiUh?siO3kIAouLy635o9? z2t7E}71XuXMb)*V<D$i8Be8%Y>2Dk{OK;bW>CS(Uubba&aN<<rqKFWi+BObqJ^TH& z*A0)ctugmy&(SK0SjIKRDhag2mbiOTR8n{K*=oW^2Q~Xc=8KfuM%y;_^!C|1>?>iH zw7Z-hM3DWMT+#T}yPWfbeqMj(pigCjx3yr{zGdR8PqvQ+o-i}pW9N?&`NA>Xc|XoU zM2UFFY|mUF3M7hxNRSAVMV}VwdS-FDYgAxkjq9E658bWH%+KhHS*8@S6y_Sf+$eD@ zxnmL2?agRTU&fUylt5j}e5kq`OuX_u<b2o_<*R0II@Rv0Iln`tNy;7ErIB@O)@kMn zt301`k@Kb9^H0sPjZ0zlNt0q03kkKAq0Sq#<B1jm_G{HP8$z?0ol@n}R`~YyFP_*w zbvaDkEvP1c#A1Kb52^Zw@AK?x`I_OGYQjc;{M4$#dxObyNjj0cS6U^k6nmtLEu0kA zQ=VVtpr}zeb8jeWonPqMmNeE<&qdEp^s<EH(FYyb1P*xXmsXvGuk1zPQ;KLBG|wp7 z;U3+!vE(ymUG26lY3~BmkR6)a5xJ}*SF6MidegFGS*baBsd?f0#<iwnZ;vn4B^bsS zN3X{S^Y-eOdFXaKZLdpkrcj;XjMt{i?a&`8Z}Y*_W8P!3b9~xMTe;i3>aKezn<Tl8 zqpHV~4}DNw+8r@76Z#8ft^?h%$+A-A1to^%USm51GWA=xkqvJf3KsSj3Qmj<6z6&0 z(O(exVDB<q;Y<OKc+xx8nS>;xW~Z5^+=9ndrsv1%K2$yQUhvNwxPR%stKC(*2)hLy zQXacOc!gK*c7a)|nOj>;yA9_Dj(*tF(aVEhOM7iBI(e210;_5lsh4W&ntfCZ(jCoO zAB~PL)^zX4F4-JKZP{SFJC6bn>KMqG<|Jud3)9;wQP}YQ)DVnAX|Bh&)zME3@=rqr z`*ivjv(5Ub86om!@`jABq+EBNd|8{J$fXcs4SArIke0}i6@ZQIBgL=|xQTogc1b!X zJ~len{{;IQ6L-pDt1CKLL!x|5eE#Y9-dB=aG(pH~$^kSHJln#&mfkMxGd)YuL)=R- z0X&8^KisC(IjgoBU^_V$1(lD)yb=*L$3eXzXyN8Ejk;UMuBfr>n&pg*&Y*KKp-o*E z6KAW$t9ZuOD-qMeJKG^*CCe`3A=REI<D;HqJCGei@q3=DGe+B=-pJ=LnlRCbr%JNB zqqaV*yOm7XR3)Ojw{|x_NRaq!XT?k$V8c43YPY8)GR1l42bKyvjCOu3`c6nUx8LGD zc%<+s<m}8z_Mt_iP458f$@+ed9h-U9O2}sC+{o67;5fsRmDO7Jn=ZTa!JA}PnMfq9 zo{H|qZB=e5ZpIwHku_X1RIH2hvN>ejJX*8dpUZm2Ivo;5K#X-TzJg~@h9~_3;@j`n zMdo~cX5KO2dM$p_nM2m3*vjV4Grn|!uR~-LuH%KK!51OESLmAM(ujHSMn>AboVFQ~ zdz;S&dlxNkUwlWTKa)prQuyNHad7R)#d;kW(Q5ZDFP<pz8RLAJ5CC3Zn&~K*D=Xu1 zfMa4jLVP+r2spwAFG+m*e~#tw+3-&N{G0#}FW3r?@bB+D0Pnb;aPY#l`Ro1E+aNq5 z@Ye<KdXhr$zi$&3r=0rVF+LWY!;{gtqo4rZHB6k$%;3(J_AaMFlHY<4&N$rDb;iS^ zX2HGi71Xb-g6j`hY3jJ>C@YDY*xT_Knc5qh@jS6}z+DGV{D~+yv@>%tVt!(03wIWM zB5~#CH$=fP?ql97%s;>4Vk2=yM_HBmj=hr^voH@I58o9@C^Iv&xRa^5sQO*Gzng=< zB(7MxxHyRN^18XX@wnaKv3IiI<-c|77B8OwuYdqI_y)JLJKV+S2{+vN>R%W6-*xVq zIh#0HIk;Ha!<li{H8QqGxJX>Ng1gZ_KY#Vp?1|OCcY-_rJuEOlUfda8ejYyFf36Lh zisL>NRkeCzW~+PG$_~sKxQC?REk5y|-~a8*zjypkOPzmP@(b_@{I}_UPW{>x=4|G4 z$KDRy(?#;%_4>Q<e^371P@ESx^#4r7U-SI)Q!vqzP;uUW7EKcR9)2qdtm7rCyDFOC z9a!1VpDpm44ZLvg;AI-YQfZTkhbN7va92k23I5_3Q7mO6x@qmondi)3@dyZ@_f*sH z0|TC?88gQ>UaI%i<!4lT-RyEUHdMF3-|w-ssuC?RN9-FmHnv;$$@A?MIyHJnB*aQ? zR4pzZE>tddxGWoXFIOJz!w}i_wR`3p6P;P}m?M${TbkkG1msFarFJ>@PMkI&xilXB zufMLTqBOI`$>H&y2$H#ygV}y=A-iEgq;Vx4=Pn9jaFc2a>-vp%L1j{cfSB1A@7G`T zh4-((_0qIyEQgre$qIz+hAC+t?tPCsc_ikPyftpG)_Y|3B<#0l#LVGh1Uy;Lq$1>U zom_3QC;~fC*=s&Yz(sR=UT87dbtd}E^3B~_L(~2XYZrg(G`Vz&DRG4=M_q|yJMQcK zyju$eb;pS!M---cIz<gZnmm0R8X2#%Ra5=hweu6$^~-F%4@@L~?fuUYS&`U|R(w6& zn@u+Fj2DtyF{$rA+}jYT`gUI?+S4#wokgR_xbcHq$LT*!A30mrM-(jQwE!o*c_&hY zm)exuuy$0-6qc>tXj{@L3>lMLxcvLHf${U>!z{RUi$6#1PsbSk@aN(v5-{%w`qMoG zuBEi)syokig+O$3v<rkWC|LWKnW3|P98DYrn~+6Uf=+n)S`jS`r*nnvnLkV)vok@u zd3O?nr*&$QQcLfd8^P_-f4nv8;{Yz0v06yfEzPoLe_BR&KlKvx&SC=+DpR|vrLwq* zQ~Gy*w=!~R=2HZOx)-HQDgI<dfxN2LGaYe7FLUolaZnvI4xRer*dXN0EgX1sIe)N2 zV#*rn?29+d2VdsaF&S89wQ%f{d}KWT2ZMi0@f@N{x99~rs|e?gzWt}praXrb7r&%U z7{e`H<&{FmNjZ%&+o9VMV=Hwh<6L0XG{O3QupKH^-HGa?KUpm4?lAN@GQ;-g*<dj_ zF`bzWMZv_m237qXaW|R|*V}o`$IyrjtKJOr@-bHu-M0$Flp!DO>yFHi8G{ERIbdyz zRV%d_F7rLIB_`YcxOonz0P}UrG47TEcw$plAugvRj2Z|%?;HU`j~BA(A7r+PF>o!y zZ}UD_vN)Bg#MpW@Ox$>;6KP@Hmt}PN+@;u7<(Mox1J9+>?WfyA7EI1lZ{(x1oZGh| zbkQ!^?yL1goyk7O7vEWql;zD2l~^p^uqS7;_S+fv?4C;=-Wo8pFB>vPrb!ZR2jlvq z>JO&m{%YfNAFva@v<thFVNx9tDw0-O`42BvD#9$b76!TnZ3p?B;xsKN%b9KV)~9FQ zg-I4?e$6)!E9re8mhN#suvlD1E47gNRmix{$<fTtgim>M+5|t$xYY7%!v|{&O6L+2 z(HkTfd8PZ<EgRg(vk31W9d2|N)sJ7inv*p+M272&6CpL1&SOT8xy$d0s4*Pc`L=W- za9hycESg*2{P=j{Vu|I~w81mUuESOtYVYKVy63Ce;WGV;LnWP{-*A;|?Se-c%1Gh) zghx&NEG=!cW<|r{-m{uZX=Rh4V)4gE2fcwgItHnu614ugqcz(Jw{W+mBq(B5Jn0UH zOIrSA#qY1IcH97f*n7V<KP}%Tn8~|>T_Z!umcoN$xtYnwcHDiIK}?zIYG#s$wXL_P zJ#q2d-m5M5yVysf)mfrBiu=w<?mpfq@HyffdEht6oeBodvf1FI2d*y7e;ye7bsGOq zI2$g8eVaHrF4wK|uE`^;Tx+7g%6VI}G`*;#?=&f$DTh`rtw$T3jpC__99WK4r)HMw zWtUsZO2REYA2;X}?~UZ^m0I6dna5OG89<!G77Oo8?ae<CFnE(b2`lehDxZ+dI~k0$ z4NuQc#WH4Fqt~a~7b4ZIMYWECi-4^)1;(k-znKSa&UQNK^x}X!wHas2p81bhFo||` z8Up=p)hT4MUwnt@m=u>{O+xuSmn$u9OOoyua40Mpo~)^lXP;}RF>Zubksk3}+aFVU z!pz>)w}!2t3SZbM&)UxU6d8wlfC$mtiney1Skd&(?Ah~-TAnx?_--FrzR@K%yT{P) zHgVLYS@38~6Q#-i_9{n9&qNO?z3^ZiKOJ#W&`-xCEkj6L3{7hi{kb;$_y{}oCvPTv z7hciu3ZvJwdNnZqA}e$syrx>-m>(bR71=F>z_SFU-3NQO*GY<9dbehf_VM5mZM4%6 zc^rJn>G{``K{e&(cZk`pMEdgQx8p+@#G3NNta`3(>@O5FbI<zBjg%J**%Z_qD!f@i zOp3cM>fCVr@wo!Odb)HWziRlS@rYe{$U`Yxxin_Q%k?=0wbmIb$&3q(C_76gsGOz| z%~`Pzhmq_Wi+EiF51m8Y_oid)U`g<g1{%`_$&y}I?tJ2{JM5`G+8z<sbX=IbROPk; zZ+?QFj@DnC`gBgLW3le!7=C^v>cK?$IR?=|lUJRq;}shi1aL!0k><gpbdOs2DTsu* z&k?^#)6_*pc$maCpF9IXv&U!}*sA4+#4Ojj)ZqA2=Wa3!i(z-92Vi4{h>(B)#|2M* z(-!iokgK6L8)|D$jt`0!5Sw4+k=sin&D-anZnUx{$Ci(Kv_FuXe;={9^3>s?m-qKT znhv)KFAEC;w=skxKB{`FD#Za~5B=&Aify=Liyh99)@^_I<a=QK(DueBGAY}Wt~vWx zXcP2|PXTY$qQJ(eb9bZn2~|?%N|e4N7AEuM`T47h?(;P^!$GwXiK2*Nl?~_KF`GU_ z+sX<|=Ga^*Q517LZav|oj>*laocONDQ~8-KSG{*-q{4CXb$&LoU|uwNe`|pr@$OuZ zUOlto1muXpm5k+!n~F~_)kluc8Gr4};V<!Iv^ey*Uj6jD@*fL6h%V%oEQTm21+K@X zaQL1a@6<WUysUc(_c(o)_Obngqxl#9Tw~Ibs~=C5tv4Dr`%F~1+4rImHa>5?>Kwk` z)}K$KugJ<kJ_#g4aqI%`Wk*a?YTM`S-@Xuwfhl2F)s#hE&n9{1=S{uPyMA+Q%$F!x zFYB@6+?P~Gk<5Aoy`bge2e+mpE55BoX+PozJ4-2Ph2WFACK(bN=%@UOA1^Bqr3pS1 z3}s278X4BmONhx8y}rtdJr6`X8=eOFjGj!l_Cls}hn`_-$LjY_Tf!f*1s42Ccv>jf z0=dP#51-JlKI`lioKT_?-IutxnW&!PFcW9d1c`>i;B`l?RU{!+A|_3*E5@d2Oxd5J z!6UdN3eb%R@M%v+_xDrqW-^fQ;<_CVbaw4P{xr=wo65qq?F&cB4kKDr$Xb&6!uFF# z3o@kn{+bIc^ro%K&E#h%Mr*fFtMWdaM_OO%v>`{x?><aaqC`HyN6hV&yUh!AF`e_7 z$#Cm|d<NtqkuG#?Yv)RCwt(uyf##>ZLOXs^9E@Rh1JAhAte$fQ&PApY&(-zisDBcI zUCL^^V_@~x3UyeqQhU$=oYvwGJwqye=yRO$4r<^bN(3FgeXKZHXF~L%c=$YC{>arW zSrmq?rDYPM^xwi;VAHAe(n4b&b9!2Z5Q%884VrAgN-@P|iX&9&%^Qt0hMz+*Fg+`M zy_Fb4?-zkoL<}zB1}Y=4Mw!ANjZ57=Tby<-CI$RqeTfPqFi0c`g^QAe=k}(y^6of9 zte$z{1#8mti&jYV_r8#HxHYR%EIA2&nAq}7eU@q03)Mw1vyR$>Wt%YA<!`{FQ0ItZ zhf8zjM=MM8F-fl)ZVYJZrZ2pMyVBVxpI#oeyeJj<bvDcStN6gEKs|F#$}H!JOQ<f@ z?d8jO`;2o{sSfvyf(huo3i>GNILKQH+M^oSA=it&*BWV-&`#F<xp7_vHf$;oSy4Dm z3tQorl?;O5Th24F-I51fS}YgOA`h9{;hQT==q6D(f<z0Fu^o|B*~SX_Dl+PDCn?`r zbY(W#XB^%@=IL{|CcgpT&+t5|r+3A#)&%=D!+p6mWq8?rHqjzSc+BxGu!@bXc*F4N zXv|8IH!rp?+k}<fx2>S&V7Y20fK0OR75id;Y5xQd%r%rzV))UG&c2&|Xh!S#!y1mc ziL+8IJ^XXDTUB#iYCaU0s9q^1ge+#lB5(i;&vw`WZtM$oyUJlYN_%)`|2vWHe(p-b z@wpcDF%nqOOj6m!!>aewR)6i**Df%(+<*T`92WxlJ%zZG<l;{lwEWOgoeqZwxlAtj zGmCWlz@lElQGFhpb4I6FeQM!l@*#9)tl3qOXv#`zL@!pmo6!DCX+D}4dtF~yBnL(8 z&`D<Haw<>e!_f>`A;ZG~GA`(P-)-Hw(`qW`wIHvUyj%CczEXzKfKK&ou@BAoGn@pe z89Zb3+EnwT$itHzYd@T!XD93{b?g)w_SzX!uJb<n(LghnH4gr8b@U>lq(*1>Is$aO zZK4AUyG;YztBlTO=1kmB-id_`y?=bKz8!=v_L@tRB7wqC%f1HG>qE1n9TdlXLAhuq zt!IIz0&3557t&n;2y8~Lo({;p(RK6FX}ja&4bOsA*w|KI1E3V)flg}W4NlW-LuQzC zHT-ftov2xDLoc%+QhM{*oOq??CB420LJ`A)RzltVs`Qo8lW$NTdbO1m^a79mQAT(- znd^t@ruLp&oZ%WQS^if`U5+17ZQ2K&jD4A~hE<;qP&g4wsgp(ZKqbGA8r(??J{j8r zkwxvi=ZYJvHf_%GCzJ<fC16|S&QCnftc&lTYnrZe?&m|VE`9k`Q$)PDyOXJi5QGuR zBFGamv0ORJ_-?Ia({K?{LeW3kX;dtdM`zQHP}UeoFGPM78GrIA^iDd`l6w;Mc(k?; zqbLH0qkSGuJlzQSN~<@V&*YL$Z@PCt?77mk`c*to�NY?2%45RoO#_cyv&<HQSSS z^F+GdyWa~6mTghAJ<97CZ9@j+G~>CHwzII_XF{;u>>d?v4H>OLZ~xx3E|El&e$uM^ zC_NoM)I6Pt<?6S34;#)W=fqc~4<zfD_8_{;V);vRVks!(<6fbjQgw~k`35Sf&#I76 zjz)DmRBo?3doJ<mwteJxG!@63<o2M+(u@}g%(rr_(*M94o1JMpozn1z{=~cGnN1wD zSkP5#)jn!OK1~}^0X>a)xPS1bV^;+{H1}P&;%T--K9Lps*O|bPbX7_+QNw3g6UcLR zoj117u1k9Qve~HO>&o$;8y-ltI7Q_gdw3LBi^Hbp?F+q||Aw~LIHkj*aw*$?Zjn=* zDM$^3&{yTR=$?vYf4J;e;ardoOw?NMkwIu5<s~cCox<%NMc$!h^VabX*45lF;p}YG zm0b2YCm0{yq7Lj7O4U)MG23;bS5n}jX}0wp{A4)gnAF%RmKNhO$=YqICm<7@9|iwN zb#1QZ5!JIS*$|fZ?rJirIRfe|!HmQyGr?Euv7%KUqnWT5P;g)CdgP*MS0gvYqF#mB z#x~2)&!@pF<0X#}LP$fTtuO;6Cxl3SwcmAmpq;nH$;dbjDhVOqXE+<AeC$qC6?{7E z>Q@Vd*Wvbv{gNAI<<XoQC$R58Gi%i1Awb#|6GT-XhF|D=?@m6;7FC<gihjY&Nej0h zGE?XEW=mhns)E0w=3bnr&SLeW-dusL`l|0Cf%l<9DjCEDD4+UZ<Lf3Q(RVq@F&DT} zCj0h@;N!_)G+$2o`cB8h>6M>>sgs5;Gp9&_m_-Nx9+WS9n?lsL-omXZUsq&2zJnh; z;nmsMz5*LVJfw*&L~5NhiPzax?!lij2HIocnHj3e25ah8al`<*^76vku32Y~?p8i- zUeU|4Yrl_CLA_TLyot~Zr#ef0G>O0uVlv&k9N4t0u0z{@$U0*t(8AHOm*Lq#$Ez@T zmSx1B%JxOSBBkkG9T6(>*4|XaRgrZ5@6_CSrh=z?06zhb*$CjOQ|ENLdj7^!sXEWp zg|`_TMKS@W8&M=j*43|gYX|4pQ;j;A<P|XwQCM}710?xFsk;2Y7qtWRb`U8}rJg62 z^_d0Mw_s1^-BiCvFUZXsW_~M6ldP)KhI<1rw<{Bk*2+P;6y8!ial2We)Mo)q(`O~1 zeSgv(Od3}OgXC2lk1~}6z}m8ba~Cae4Qx*MW206|93mA3^mBt`p)RU)(xLz~D2P;} zTL+#ff`^XIzPU8Z4%MaryA@yHSgy(bZrLC0uAvcg9btDr9k_rR0Iz32P#8Lrj$#(9 zC_~*EO&QZ;j-szCWLAta0FYT{l(d}V-Ur^Jh;s2h0V>n^R(C8qn;O&kVB>H_Hp4&H zKgk~5yg2ctYNfD?e{hpQ8<xiLN{|sIz)kPZ1reenQIIKHz?s-ttr;`V@brZY=Ojrl z^wN0lz_(r%s;)%mu3OtXO6|asqPAgQ>MjB&3!T~&$z!fhI;ml8>4{4F`52n21A~c( zw<Q5XZ{f!eJOzE$M=8L9#b(f>Gn2iCd2;xDHwAei53%tX(OLAd2Fz2zIkc*@>8x~U z*OQ~2kuO}dA1n6M3cR(Owes}hB)#_Ua?^=QBmxsvRG=b9rKr&;`CQ8NcWpdFQhfN5 zIz+{_gTHwy+xvx+i-{=<x}G$r<w86fj`e)!yg}r*BXh)BBn#11Gm!F<KM{-S+RJe6 zINlkDR2)}kY)Gnwr!SeKY>Y&ybVbk6l+CRKplPu4k;_(r^(amWevL`P?DXDJJ~g-d zBB8L=l{*3xHlB~!4^>su@eE;M9zU{c53G-OM6f$tbz{2|Tbd{4*C<SD02nP|z557( zfw`adP;q%msQbbt_9sOVo)1g|?VpRI8>b3C4jB5_xol)cXXV7s9EdzX`Kq%7#nV4D zF!^Aa8?C9Q8NM}aQ!qp?KX#Mz**(fa$j<EPWNi`7keW#%1-LFEMja7}CfbAPdxukP z-<2%)9?X#{bmFUaY_EEJJGnQnWu1tCjDB#K>>`QNCnhS>?1c=D{JujTBiDurslG;K zk?s7KESBGIr;oXgbh6Pxh3n$m$%=b!O#q-KQ^4`I@1ZZf_>8}I7jMgYx2{nJM}t3i zT>W@2X|ank#!F3kjAW}^dh9!n)ZjtSrB&QfpN^*Atz{0VvB~9!n5kXPsny;;H($y; zu}~49ycWPAZC|scRTa(jfeJVzQJ))!b<Ju9Bu9=NlrAfkvq|n<I;ZwIQz9}M=f0nA zVQp!<(@6Le37v(Ko0^eFDF5WTu78t?QmPMQOwET|)n`lxonxS*-)UtU-8(s6IqCRd z)w{?c;jziLG+g>h-$3LZ-JvdwbU66L^ivkIB8CioOVfEQ?uYRHPB4f#2MZN@sirD2 zU(GviqgypL0?5U_uP_0`7+eWJ`eO69kW~=h8h2~l5IPr{)E{Nrt7A;p_lP@pBvA?v z9jzeJ;v~{N9L@1g^YXOFiJah*q*l%RyAWOPz_;6(exEUU8dNM$=FJbc$5yMT&lZmg zY2VCtkXzVOo}hw+SRZdG&OYsxFb|{=Wo0O-t@D7spAd{rXb=bthLWJ&R+hU%pC$uT z8can>Cs;_Pw;G@eBbu+ul{v;7vZ|U}zvgmV9S-w$6MPgSzU7&>F$(Cq(JMs*m+u78 zhD2nz_Ul^2f#9-vW<G=|g(%q+>tp|^b^wdcf%2F7KP^~#d0vWgaQ-rpb)J5?aH5!7 z*~$?Ube^&wxGTs#YsisjRM*7WldAJnrg?g$ZKJLucH6X6XM-dHzn&a;wXtUo@+ore z4*2B<Mu#)~#IF}AnOoYJuOo4crIXsnKsr&ku|=1K{?54>bqqCHW+0^*dtnx?babCE z?;X-|YzoaI0%dY3$yxKKe3b3^ie8`dW>P4LkiP*5Mpo6tsgjk(+7sLMj>m<r@1aVY zy6p3KpF7#zXupBAiu(D|qy|VxdpcZ&$!qhCfn59PD#^Wo$oAV*H&K_~%JMmU-S^(8 zI>WyDMcKPIL)mUX8S#qb9BmRjJUvrUa%a?eo7^<-<2{v7jlmRp8=4s_KmXBHd5G@t zxJ9y;xm*ZcdU>kyDYq(z8?>e&0QEoJpU-rafca#tD>oPLXHfcAk}Hzz%4mts=Gdh> zcX*q<swINn)T~K+DG6I+*KwRE2aIB;pmpE9s*Z9HrOxk2;}_HGD<Aaj=)zGCBi<ot z&OW`tU>dk*6~0sWZDi#%YT~N<yqk_pa{fDX5^8>Ds(PdA6%5}hzCm?|@E$D1>hUHT zu|O9n00_Jn5-ck1)Ki{$TWRs=^Bm8dWpZ!pNffF2ByYMsm@r60#v4ZIfhczVu=C#a zmLA7_zsTb|x0^#5mL>#`YT55O`>^`^3><9{7hhBO320m11J`t2Xowoe>;@2^<9aAs z4)HF(lu3O9?<*gHS5?STy3Pmb!|2qMzsH`g=fSavZ@@D}lBF1f&YBMrN6pJ=!%Wd< zHjw@$I6~q~m^_s>-JSLVhp)mPl1RRc3J0iMbnXo(@W!Y*BuVC2->(nWL(4?p#+Rs3 zhFvoP*?e}(ua9RTmETn;O|5)TuP=(Z+H!sD6NFHp<TUW6(J_z!u0TR4odF+e>o5bG z2m-=E1@Ca+)zM2do3W+GAm)S1g<hH$rrM{|dO?H!7X1QjuzE^$$=J831zJpBo;F5j z-Hp3fCVHY#{opy44!bS&H(gd0mRewB63VWm4vQqnE6iY4BU5FY+Yz-z9)BpP-ETWf zFWiwFIa|ZAzFFQuwg%nbL8bWIcnh52s&|xiQpBF8zY@$WXXT9zq3#3!pQ$Xr23$Je zEUfGW&fll_qONUr!=iTyQ7F|_=RP(0Mu^(60Mt^mC<W<U$8L-5Nq^;KTf<~*bx{JL zk{XyqkRkIfKpCSACDUyDE;3eFZa*;&*Y;D^(WuBkj71!b3ZU-K^<_s$Fp6~gz^LNk zKQxcN`&XI<aM@WL?ymK#jqw|3$jTQys<DmX>eS}E7fyA_`5w#xm8H=bE~aHy<v7_? z)}wIBDaV*qr*sBxi!iW1^sG)ToIzij-><Bn324v0AS)A}AAxqoidrMR&5#_2nvfqN zf#lG(O@p;C{Rw^vyPgmQs@!j!b9?&-Jahau^c1WQK72Red)Di|AdYDih?)trrxG5I z9f`ip4*OWiaaY8kjtEPTiLHCwnBqeUT_;p2Cp*EcY`Zs{VT}a|uDz0t>VcJTj`IOV zAF9uZE%NE7M_HuTvCh%4EA{LQ!#n^)Gv#>NU+wQ*@M)VSA%j`}fcW$<^vkB3e3V{2 z-op{LxrrSA!_L(z3+n^{Scsg^QE2w?8b}4a*yvk9`J2R{SzFO|bFq|~Iaa<tfj{aq z_8@zn)T8H;|3bYg0L1L%-?Dg(L%k?p4s%Mrtc4d1FF+1(s<KtV1rORV8Y_W{T+gAt zkQZZ_gmR?x&JvYveviyAq;D;>vt)1+=dnDa&vR2*#79q?>I&LVxpaQUAT{=ET0@y; z`Nh)eP&L1|1il~>GkZoTt)H{S1y+^4fA<)>PUXsQm~VFc#Jc{dRi`;`Kr>$%HH&OD z>A#hQMCKQC8C*6SRQ6tdcw<dBHMF*U{}EO!TUD6$oQ1KJ+K2<@B~-d^tfK($m7aWW zVoW~Ln@N4oORw1Ug@hqO3YMi8sob1%#2ML-I2RPC)~pUZMBtIgojQws<okuxx_A5X ze?_;CZHUQD?MM;ZILie*Rw&f6S};T{gE}|1M{w*l=c=k~xPK_U##8M3vN!Y5A<YR^ z0WRgUVHEv)EBpnTQFs5k4A=*tSER#X<U;*2Kci+mKY}w^@t-8lDATLL!keUeb5OgK zPbxB4b+8K2`c-C={PuP?mJFlr(S0yH)t<wN<Y=ILU>&{#_<ow;J5#iOX8@T=K&q#B zHO;Z*FW$to#Fz1G3V(h>lZNvw;)@K?P^KihTmL|aKFr+)Ie#XWE_TBHMbr9v%)d!u zau(@uDwa<!ID~-%>Vo*N1*IhMq0r0>nIa*{nA1@M5#4lv=X3=*lG`J0G9n2f%@4mg zcYgMut3CuoV3~>Uyn+|q+^A2n!S(HW;s5n*2S)&|#5*_r)wlnq0;RQZNM_n>GUfNY zpWi42*gb1(x-R~VBL3S9k3g3l#JW*2ApvrKO(TwU_}`J!f6ev(-Hg~Y9e8!EN5bdm z{@dcOwk;BX!5FQYN#MsV@y~Vs=T~?XNc8Bs58br<&yD`S4e&EW7lG|-ZHxH!he6^K z-me8cYOQNZxcvKFRj+`lyZ_m2>e|1f``?k@TV7yD>jnH4&;RM=Kb?*w21B{vc=6Vm z-@BVKMM7>Gb!gLZ@yb8n|7W-?w|$v&?mm=zK=Awgu<hZJT_<$TLBCCpuk;I?XFnhF zCgPuE_+Ll=FB;-Kv6lGC!PuDEQOoPyBbNPkgAcE$-u%NH<M}n5XEV%?w5n3nb$+-| zoM9BwxBW&dJe_=D{f*Cs$LZ!>J%5<QE)upc=#3UAd!VirM7KP2%<_82@Z)nfkLnY8 zi{57I6}fa765{<kvHu>WL89}<OoO~X3|DV0C1>0TaGHtFH+x5Ou0w&d1$)#dh0!TU z)(;@(#A}!T-6Zh*9Pk5mB^Y&WHKT+M`=H-R0+p0GTSR{pmAXbu67@re1S9^v*ME+P zY381GGr2Zpm2d>{k_$vJa}owB{5~)|f<VAc!76HP8Gbh_Y34h?t}gnU-uVByVYrY? zKQ2GPlJs=FwSmfL;ZN6Z1Oa-E&Liq`&_DHz4Y)+g?>BybGJU0s0Ji6djtLC-lN^B< zxHX9EE^fd4=h6E6NR<n6Un#uwfBFR3Bt9d5AjGUws`1!TI@;eNK^WRr@1DthR5SdV zUZg9M$6y$U3>s~L_@Qxy`PP+RSMPqIbpL5xT!^*@(pH_LmCl_&3ljoZ3=+gbzfcIB zkO0vo2VY#0TaI@OB&V#(%O|`K;us}7OkGB7b9YIq_pv$KVwqQu2I`K@&Pg4v{_y#7 z={Il0a*vraAQwbb{o){2Fb5IDo0v2Z70iHCf-p#7hdjKFx!B0v63=fE^d@jPHJH&F zr$*3Jc`+@44|zvI!y_2QsVz*z_#{PSHo3f@W;=clG+iX}&lML}`qgWse1R16w1|Q` zb%Jb|2_NvF{2=J#8?mpe(Jg%JN9uZfxS=9uXh2FtN*7tg^BCOOV>Z#P!*iv^qI)ae zCco%3KkfK?E(aWmf|Z1Ak2!oIb?<jGAc4(i<_A)7YIT&HrTC92|J8$(RYGuIb%#># zBM(leQOD-E{yhEWdCPIYmsx^rkC@oe^Q)nJ3}UXY^)phKK=zs=hG79jGiJ@Y4w1hu zcH~39T#{lOA5b9oDTuW5)@%ZWhZ&`LcAA_48K!adC1*ad!2=5IJUz2$9s}#P7+!mn zc0rQE$6eEaT(Ej^jjw1%ytHz(xYOGhU`KOLG?(6)sPq9DK&jL8{Sw<DffA5Z)(N|N za1NR2*e*z0o3D1giM6-PMI0>$LunRKS<qQZL}fU?&D5_0`j<C376L6!18V26<MGy8 z(X~}|N83mPm5J25%?$3hJAPY)XJ<_9!lOV!-g%~jzdeSx+)pXuy7KzNvepPzBrciE zHn*z3G1Ivuy$qG~=dNR30Esq!AnQWMiP%3HMU~nNl#M8DzW<pNXABD+5(*TC8;}~W z#5WNkh3(=GVrOxTPU)ohbliCXnaf`bjXrgRNgdOQ%*3JxO06+%m)xh`Y_oeEqYA3m zU&aYqy=90{^h@RV21tG)v2V5d`2exc44Q-qfxLYpGIBE~zZImQJNmLUCi~yWSGg`N z@<W<W9bj_`79A}E6?tp=TyJ1vwQTxxU)a679SC*x-S*lZVii`lhok2+Dy9$P=y(;A ztVNqoj#hlOk9_e@Ee1dqiB^JZwV|{}3t2;A%N6g&+<^7hq@TEZF65ODPwxzxka@y+ zt5<I)t*B-`NL;*W8AnXKaS87?^J=-^mrGhq`Qf2cD~ke=@bQ-F;3`lW9Yp*X&k?Zs z_R-J%v<fcN3tt6hEW&ekT?9ow^Wzn7nO~5U!ODghBeydk_hQTJMzDGAApABlU|o9l zG0e2NeIKZQIzeWRmPQ&PY^J&A+H}$4GYnO;*`p{|kL<Dn8m1dkN1GZBLI=77_e>(K za*IuoO(InwrESZi)h7xi6w->{UWvCKOua*N1IU&{IJ<M~v*QK~+zfK7tR0Mes<{x_ zQ8mN3#Fc;j6pi82^CI5*4*L5~K^i)K%xyvf-rp%QVVl!Msh1D*e6?ZvkK2hL1~?tf zAlKh%`+xBU&`Rmjm|7`uX|KJ9B0<Lowa&5V@7=KJ=h|qw8aDVU2bFZ^+^x?+{D9#k z|DHsUg(t5fv03E;xJ#5Z8ss5OU=ki_20+NRh#np%VtV>`Cv&m}=(Z+Nk(2}yYo94x zYYCXjmxoJj>@b+mFDOjD$C70A*(q-{hcVd;8Y(xV@K-Q>EMKMIV*FFhUsCUM0^!$E z0+36LtTk!A$iU{RNbY^c3CFs`z|}gFJeMzy_>&Zm62hvNfQm!-eXs8UYSk$UzAiDB z5-^%}#t;*wT0ab&?~)VX(;?9WNkF4D;&A^vQm;LlyHkNR(R5-Vn8|d$<Tg)8NCvbD z<mX2g_P+-+Sx4K^Jaq6IGK(=-^h6krRye-PE7SX6`G%B_7d>}HOl9D+#GZg!__Vf- z6@$c<Dn^@L*p_d?=frDKEM>B%7V#jzlDXYWYYPTa9JX%vyreXzXOq4R)%o~n6g-kB zXDj&CGfhQG_k)@2|EePg4Li(OmHQsia0-@x7g0|q{-lspmy!)9`!EL{bz8(F$pgzy zFK%gE=y9E+MI902Pgy!%<B6=<86T;2lhS0^Y@)Xx41==cC_3|tQlE*JRY<&!_hx56 z`i;~;B$2<Ea#Vct%N^k<tG=u^UsHCyHFS1Ao+2Am5M@e?vGK;iq7S_fUXgTB`i=o{ zoU5aRnmR_KRZ!|Rl;i@U1A5lr<BYcK-h#DZ{i<>=<vzQqhQ{-B=~nx_kT+3mE$ao7 zxYV`l7(&~px6EG|ZjGAiDXN+&$XN-hz3RQu4fs6x_KO$CPse`^CBivzb|?YTC$8eD z-#-P9w51l3q`#zv!5Lf!jWX2J?-$7m5+C5Sby99%8)l;<7KVwAJ(&z~bt;T!<7hzx z@!8_HWskJ9hN41Ypuib1=py4k^s*YwcvRyNm}kvdpc$AhGYGpittToIJtCK;E#ex{ zAc=V8(n(f)$k*CAkV7C3v&dF|V6gMn3c5%+nmteVj5Ivo&U(c9n1cPNP#&fOa6w5s zp-&c_3d|iUfKWcv`oi2^7m896!)CoZ>}(p(S${yKweLOd)XrTr&ja%Bt>QY$nfHZY zliBm0d6|fwUw66|S-)IBzy_-O@|m?!jzCmS<>eSR+tX#~8+_hG37a&X-I#k9HoOB3 z?K|Slt;DZ^*|`9Z(@c#^Gla{S*f4l)el40l66uyYsb&an1!IN>vL-nA|5R7O*1eKj zncF4IR5F&6a|nB-r|H5vgrr*3S1)KC&2WtLd1=Tf3v>n=V%yxdFxtWSX>fliq7Tyr z(t1Eh@|Kb<uoTeIvB0|z=?(`k2xpyvkQM_e7M#)N(6Oqs@IIf|<O<Vp!FGWw2Bv*c zB1E+lqFev*OV{Z7r;y3Uo4U2ozcP0Jj@wC@IVT|ZTVv0z0^PGiT>2=4eJc3WO3hA^ zSK32|nyl`6>$F1V_7#7c(!_5rJDT-HCe86c9yQR_Kd1}zn`e3ASDkVE+~q({I(n|% zNC}^2HJNCpw!QX+8qZ?mVsNZFP18RLj8V=+*Gh>`J9~;q7u%M_6JoT4w6Em{VvXEH z#Cj|1NKw|P6ByB<FSfXy=LXp6oRF_QF*>@?-M+(*?H~t6p>%2?SV)3F{nYna3yLzH z-hT)3*AW{#0SiZq6OGy0kH(q&s^yn~y4a@lFO6iOf~)9>r7w9o+Ia<74%k8hNL3Z- z8p-r0+;U#j(STnL!BF*oP%c*qNqx`3FQroj_6WOy`a;CJjC2aqY>y@2kU~il3cRvx zkV!q6lYI*SQ!eEzs)wi7?<Bj=T=aYtc;1u+dJU+63O-(KDUJ#Fi|zi8kD1~ON67R8 z2Vv7p?lcB@*X7WcrS?->S~B)+#DgxmX;58b`W44xbt@y8=%o9ZP);EU7T%kd9%)Ml z1`I;WZ<?e)s*l2SPi3fg@DWtYpUUWDuiK}iA&_LLm-rK!+PwIR;;aEBfOGhn(i)vB z<C)zMkl?9$z8|GEoH23ut!F|+Cc5CW=dXA<4F@cp#>yx;vaLB#dy_Y<Qk)R{4@=BL zD(5qhiyQ`3u0mitap=RQ_I~o`;+{M0Q~)s9{6wA49NLItpumucp11~lE5m-G*67tx z=2B(-_>p7HA@c%&b9`!;$42y9L|OwkjRE=z)$bsidzp4cQEVrSJ+XdV|AVEGrX5v3 zNYYrFcO}F*6uQCQSFXIM3(3l)Hn%QxLsRb$SIhs8$@qKCnG0|bAIhnDl(y_pPray@ z^^zt8^FG7(wqJCAFU4sphdpHzSqb1_UB5jctzDM#;{j?*>1B<~2c^jQv8wVR04I)= zhj~IlYBYB5XlG)n;=yqQDG?c?Ezkm6#SDC0r+YkZ53rp84re7&=I*XHn~ToGnkbEw z*&V?sYMF#>V@X>+s1C-edy90WL5mL^^XY_bExRNS7AshHv&E(W1h9+d(lzex^f6AW z%QsJQ=}~ayds6i+nyJ=okm5RG3<J}&`;sD)0R-dv{fD!_dV3yf!_s&12~<}MdI#;G z+8~XijV;lSVOFFQ{NuXyFpuYG<rQ1J=g$R!iUYme{1M1b8F?S?S!@7ZKyy>G^+avW zd~c?T(nqqZlyC-@FEVAXQpa=DEjH)Ax~kgc;Z$=!;Yt}?GrZJgUR~^ZjHh)P0V`=+ z-pe8g3H48rr0dt-AV6-Kf*p-<Bx9mR_4}|N5u;_ih&?<&5E1wk1QjN;KTf}J<MaXU zYX(ToJ}@DUQG6QGIN5X~L>lgXf?+C9Xm%eo3ceU9FOYE4F-?tcN>2@<>p?ID@Q&q7 zce1@(o~lZewP+^52}po8t_gSh7^hO7JFQ#12xMel0_jN(Sw%&XyWdW^-7j-`K;`1? z2?VDmvtwCmS3UFk#(EHyn{{H|&ok_Hldw)h>54Q5460_xetIeI>anO$oPO|mjxTsb z1rLA4_RNO3&;(w!B)kE1;jB;FlEiFaY}vO_N^t`4w_Zn^y(*m`DrFSm-j$KLTMi%l zaUJA>^zNzfY7)Quat)PzK|Y|FD6F}l|Ak&TP!*dedu_i!<}C-I=Ag?OD(k%zM;C-3 zTy*wIDkmg19>(to;>_BksfK7lVp$?i#l+02PE8p<5|u;=t(*ZapO>mhRtSRByFQ5X z@^$*hE~Fj>tfx^dKsIBj;&VyzX~no)Sz*x-aq*SPSifHaYv}|WoT1A#Fj36583j4d z^=CIl#ekOc0Tv*;(bjz?$&*9p8|EFcI*1r#CYBziv}dAL>CV$K3{>rt=u7B5fFuR3 z%Dv{RJKoPhni>ktyltB5StGo|Ri4to1%qeXyt9E?3to@CoeRXW80An;Oauf&s*2Ii z4@A6j-Z<2Tg=beGQBj9{N>QrAnMuo;ST@)b(n~k_%1}8E?+XqdknmPNu07tjIUxL8 zxRzl|PvTwz6xIt_3kxFdYzdlfDg&^-&Yb`*h6P-i!KeEWlYFbhJ7f}lbNjMF21GEG z?6(h;{l*ak1{M<sFzr*P&+>s7v9$My30s@>QhLCkud{at3(&J5kjWz=j0^HTvqv#C zg1MDEMK798p!#8dtLpxxBqFcjP{1Kc3J5RnWQ!`KhMnftc8Ijq_?F_6em|<%prtK} zGiDL>rrm1Q9wDNs5hDe$X%$8wHN)S9-<y3mc|U_aQvGA*mj7iH?*;qu>LD$2D|$LU zNzB&9h_}q_!jq{izWYJNub~71GSLkpLb@E6ay7HxW&<rlPtrnv-VH34jU+B(coY$t zw~cIbW5#$DiT_HPR9*?+k^zp2t?NdSv}SnJ6YiPcs7q<#Gk{6%#r)8@3aIcaR==Cb z3!FNiKSrQj<ry<)d4ZJ0FEvi#^niw{bWBt{)V20KIzw@NaHG$6neKh!Ut0D5S{#ca zvyFf5+s3Y;f2Z=_qxT$un?}*L|B5wn(T^<^AZGI#x*q(_cjFVPQvtOj?Dh1Y&Xobh zbHA36Mdp8Y*?(@C4d|wHj;8fLozs_1X$i<3S2?l*bfxVhsq!GeBW`NlvT}X--y!|o zG~9roy&o=sqXOGvIL(5R^)Al`@NR8%OWBWqu!{Iv2fX67nl$Qa#G>2{qyE#*IvdcL zgwQDB67?PvqhEbCQ2*`_QW}#US(dslj7TX5pPudzGHAaZ60Q|4<Xprb6Ly%%!8tEc z%>3(;gYHOokz~;=bY10)4H9~rd5^QD2To~TvpFqy!+l(Cq?2#Ypyb-0n&qEi`)K_) z@5&yi<8)uFrA^4Ti{=mf-s1&aR)@iD`;SwR28j8WkGVqsFinLBK+Kngih0WZvQ^{$ zyr%}zWwLzKzi#8WbAzJ5$n={NYko6eaF_RhZj8D@`|6K|!+<lK$*xC#G7fdXMczOE zy75ov%0hwR^gCMo76Rg|haG1)#7#f`XgKn|%r*-ZC4VYH^rHk1nL43~<L@hu=a+X? zI=mDyI>h;>)p-fV&+cDz^AG1f_Jb#MSaf-j>JLlBEDOd@S+8^H59j`mTt=OIo?2@R z2M(4X1<cxF;bZ7HyYew%vPK|v?*LpwC$6*!)N@&ZK;I}{*v>izDT+YhIIbZObSQ)U zXgwFC>X^KDQ*r!o2f+B&ApI6T-&rE@+q4ft2^vLP==hDF>EdVu<<MI*v>Ira`Db?l zOHi{1cJn0xPzq3;ty5&&FdY|H{qf{z;v^17apXII{9qiY`x1pu1HKUn7_LvC4o+Cu zAQb~NsE;ZA4V*iLT+#X8LD>-;aFk5?`F!Izdcd^=@SuWT2ix4Q4GNWi>l2%?pD}|e zj(0Vm?@5oI`W8SYEYIj}dOHah+JPFcAu~X_UDp6&nrH1dZn*ma@^I+s;aan6V7@_B z{JT(54)`?C?!*GRy7K`iC<@K{47k)ND**9yYdlIT0dKt|?w@;8Sn?lF_&-CIh7#yf zn9e8g)NHD20DX1~DB^ngUcobHK~Ja5R@b@Za`0yaH$VyzmAgM)ElGkJ20L7phB(F< zaC;>NBs)VE$yes}?#XHm$0U&cdVSSJ!eWjV)WgbRwWxmK5nBqVLO4~M`WyufC~|}2 zL|sg<&TJ33jR<&Xy&!{9znXg-O$&-yF|!U7Eg&Nvh_Y*58Dh2pOsYAk!80E!Hgmni zjgWZ_ZNBXm`S{06Do$IsmPFTK_G!lyz(-q9Lal5I=!C2X{V)`Z9KwnVR$TmvG5v~W zwtR?#-d!!a>KdRMD6-2~$CXXFj&kNX19=jTH_RyZ7%dj1VF>Fo1KduR#t>DxgFjj8 zX<fQV@9zzPW%Slj9Iy+v{7<9v%WLI<DVX#O=m-2*xU`jst5fsq=0ALXL4~_z535(P zvIT70FomZIERCRIG#5V=hbA8;M_UBzegB_y_y0l|m|re&F`!h4N&vG?Pdi5lVqx2Z zyVc)XXJ|~bNk&`VTn$OGEI0ZTRDs!YsR24i+9gg*hDq<^IS+wkf7$^`Hmk=jFgDP= zHf3RSHWPRfj&i+(Z3n-IpB!$;`GwoiDPnz3o#O)~9IwxQ0P1^_NAA;9H{6yVmdAUI z;ixsd*%wLuB91@q+N6><2`%;J(Jwaa0i%vjy%RhvYe3Tt0)9Hu7A6d?mH<3F#ugKR zPZ8z=<(Y3P=h9xS=cYNk1H9h}3Q>N{%zLyr0RH?HGHD|CE(l`Hvx@qzgBlT$n>7to z49N`@AkJxAGG3o*oxvr?dtH_?l;Vu*<e>xx8f@u^1t4{}-dKaZv?cMAEZ=;PC_2R7 zEZ7xGz~e;&Se3&;ft@k8<T#K|A>AI;F)51EA0GwaZ`(6vAu~VG8x-`Rx9WC(kZj=S zx0PJv^-RFZ(TDiq7?GjY{UpXG-~8Zj26Orc-0sT6PHc}ls~j-E_~d?D8(rMm;EFsR zh_Br}&=gOMg}=w~-?L}vL75#;E}g^y)t^9*Tzy1ReoR|uDM!^Z$c5;%P?tGEVDPi- zode28r2~&_XkdXu?-e3m-!3cc2PLGv1%`FvC7P88K+enNXR2b`I14^}mv=A=B<Yse zdFbFYY5}X6AAHzLtBngxk8V1AlYST8vE$mlSKux32{0x@z#A~RzP<r5^6q6`^LT3% z=@-59B{kp{klIfY$oSCL?*InowtS%V@@0bhtxa769mH$YC8ti2UZJl-udJa+P34(# z-~z{7>t2h>yK{W*aWlbj;mf<Fq+WHD{_Jd3%jg9hgSPPE4YcKhq0}PB+@AF(=mH=; zvj-*p?KkhXgkoLR@bIo_;QkjtnB;!TgYAM+{VoybUI6;ZIEXnHS#|agrhcimmv$vF zRSr*AodE_W3~Kx{sO)>*zrfK53AIeQgvollpd=BAtKH=(kWK-m;u(PKlEV)`*}3%Q zXTXD?1bq;WxD03kj)CGq6;7{yA}b%;1gwD-=WFkyEp0IsDq++IHK6jwX*8ko!yl|n zK1BeTW*07RD7mDv;kku13mf3hdC3!^FpculEb0TbQS|F<4(jQV@&30U=1}v82Y~JA z06~VS6bHFxV`M)dHu6aKKvZ9%lk$GGHP8d_GpKILsrgIEPuCTylp%DWJUPaz0AX+s z=peJNDAm8sG1Zuc0W6=Fx}D9+g5J<fVa+s+C-J8&+gutEDSMe8l^++6>JoIQX-Ec< zE`8#Giqw(m?EKA8spBUHkEHxlU*C>h9;+I$7BwJ)apP)-UH2Y4WamE<mFLdPu)ZeI zsWzrkT1O`N|Frj=QBkE`mx_RhqKE_qkuo4iRHEddNX`^U76l}$K!IcdF#;AD$&zy@ z$xt9Dh$JN=N>FlEq7vs^yZg0Ysc-(xk6AOlmTS>%b1U5EKF>b;?7h#ASDuGvo2$J{ zK?^_evvF8r`{y%}Gy1kE^N(}Ws^ZrI%dAuVe5AtJ8non7Q!z_!F9vl<9)Z_4Bgd#y zG<KSV&H(EunSuG+F!7&Vy^I};mI|+*QXhRh?c)qxzmE!x&OZ}<IQ%$sgJr(70{t7G z7Bvk=0zabTkDf!SGFyQ!S)}njEoJpOz?t9vj3dvEyZd$DrvUXDziC&R12~@-j|Hf* zHGUb>Zk)@AQmA>N_d&9w6Jy_-Z{lk0%ZB;xpxpn}AR!T@_Qhwgvwton!Uz{aZC{1~ z;;F=l=Y}bCJKl>fDrJ|;8=j|m^rMAI&PesLqv6L5v)TbD$8nn9Qg6@u^R_->U{E&v z*2$^buR>$Nb^rs^a$zpp>c-r|H9I!G(45RKj(CH`ife3dgcqB6`#IJ#Db=MSs_3kq zAHb2jRvi-kb`PZG<zjL9^Sy|`cdl|#MZ{PFzDf>9aa<|1RRS{EHdlZVj)J9JuR^|l zVy$W6#GhD<1^F5e>g~CbrT?PbV)Cr+i_mEzS{hT2&E*~ewf42~7>7X1fy%OhdVas7 z<nmf(RL7H8?P^}_^<$i(N}W3EX9i~s1xL_o5|in<1L}`nIP4SHc6YQPx9>Dy)he+w zWS}DM>9|RkpV1UmPLz4>yt-L*ROVZ1HL&)4PbXK{6IoG^LC)S_|2Bi1#Zb|U<ASrz z)WOVLj9FvoyCaTeW<Gi9Qrfr6hQ{fP?$$u5TF&<5^LNm!YJHg0**w?j==(NHF?GW+ zfIl1!hp=x&(GA~zhxcMmu4jF-MMcP!9tj)!sjeA*xN8hfe%)(1UgB#s!O*{0F06`T z8wkAk^^uqMH_x@fI#$(NcLx5%_}38Xv0XiDf27^3F6uef81<o{y%L^1(h}D`lxnz2 z8(-C=2`DGdv{Jkwz}&&tTh72DC*@aOWl3q{cUZmu$R;XF_oew5m~JV6-Kj&bfC5gM znZ%AOQsc+4bM&HM;`dk7tgP2Mjw)Jtmegvhigh`eE%nGRRh{?YK#P}s$F1}`8#{ok z@Qm>N&@tvCrj{G50iRNGz1Grh%k*@Jk-f_ES@g}`y@#~dE~9480{a)Oppg^Dhcbt# z(4jwjit@qX^}c7@a}DiMvxwGdT%WHVR9W%mz(j1!du>~%LDa%l@wC-#Lk~}gE|?j) zT)oF+`Y#*k?>Y(POoHQSXdi7?&W9(?frb%wa5lpwKGA@#VdsZ9b~lMmMpcvhQE{ko zXU0X^r*2udB?T92SoT_-6q8c9!B=GaNg#KBG!yk@bhd>@HLeb=W+{<5C7)6@m4Ni5 zC*q@+3eUXEsRf^nvH?vnk&vz#LL*hJO|gp%L@`uzSjEFC=)E@A_n_X>6){+j#pJQ= z?U&r9U;ovI>WjsnU9&S4Zctcu|K*kh<k~l^Rho{ykc}w6oeDZdB^nmI4!!Q)ucE1= zjAq{1UQtC^gIVrFx_(sc3H|`v<ZITzfUmqX4njvtg*&Bw4+58~o5=aHz>_~rh0$Y3 zN4P-YyhH<H1ZU*?e8O=^_9`gdCG-sT^gQH8(`Voi1qd&lp<~eO*x23!nN%7*HKzI| z#JW>l6Pa~uOOrRCG!LEmGE!ln1&zY-vH;e6t*|(@3BHvOYw#Qua-t7p_9@n+R;8J= z9I6CQ7tM%!m&YoAhr)-)1ni!Rcy3of^TqSpRF$tC<2HIw9Zh2;%HxdR__>pjX2ljs zg{xft(uTOg-^<_7oPGITd@R;^pdcRF0@cq|JB!qAoSL+>&T!-`6j}6S?QEBvg<_|S zqS!!?-%HY2qCufEhb`Os1>397kuvn6RX5+q4GbKqUaoLYSs<3QErKOmEfP!mS^|1= zN8%;P9SqNZl_>gfh!h>0_PrgzFEztn#b~eDqMl}0hPPHjGr%pb?xEAQtffkHfZ>qs zK&8uy6lvcbFjO7CH*jJkoXIX*K+Id6=7!Z|OkTPBR0TT|31WbHGXRaaLB(y$Sd&lJ z=>J6O8DypyY|4?YBP&bE_-pWV)E=J^D>dGJNvh=h!iPy3c8|oG0se_KK(MoC(OtuF z8)Kw$fP6e{{Lgt+tIuy<JKYwkMenQBU$0ewxRWc&U}+Yb2;Ro~$QkkqmX>=R1V4~M zhHdf3vy+)Q(1O}NaU9dBo@(8byJa`yMiQIbWRmK`;icv%@xf69EE5+#YQ0DX|Ac{{ zo>wJrNv;vPCFO|(ehm@dPiG!2^1wXQDv_(++*+R>>(;*&fM!~QQ=GZKgL!#L6|<T0 zmx=yg-S~ap*@tji{E53Rf58rJ{7M2@dF&IFXT>hY$bE6E3vRCUS(O+I!7ufn7fR?> zj06`iJv><SQi~$>d#+ClhJA7G8tem{^YzsWJ%*sqQBVI`es1l>6H@!0kd4lz5viPc z!JMR;VmdAZi}=KeI8>S$pHs-ocGO}f*<!Q=w#xWB`l?hn?6o)fu;o$J63$A(dj&m% znc5Na6JU^L(==KEf#(u;%fi36Y}O2D9y_i0sclttIP{#Hmgb{$@<OPO-YLb4_XGOj z%2m8^9-2W@8Nv!^4NvHPtommj>~c?XZ0*U*Y<F57sR5&0?_2~_mN_nqErPQlocyYA zXfEkqA-6|+q|V3hH{n;cMG7(Z!T<)rzJ~{w=K9y;k8S*!l!Nk??B1&@EQp>a-g^hg zTh3wUV;!X$<jP3A3H24_=R9>vQGD`GKMsw9DCx2L*91e0rbC$1ow#xno#_F5MUFw+ z3LUqRjgiMP8s5oZuM6VVaV3h;JKxaGN5Vi)Z4{<YepoADw0Jr%%Z&d)P%UGRt@?N( zR%)0cBT5c!Fg1`)>pm6Z69U?*SFM^22^X*k)=!d@8g{d+<`Q-AePjKlmK<mL!lCV` zh84NX(ugd@u3QBUjIl$F{#7%q;kgmmY?i?+P+y<kUdApO6upu&JyNgZ5Z$B&j<8Wd zx#}uj@^Z&qNMz`#6Z@hnHG`-bv;xvHg)k-<!;?i!@H~&Z7jbT%^Itn|li6<XZ3Q== zntQ4~qhJUjH?pQWJ#=cKE5<h0R|S=$`1aYwz5l0J|A$~3Im~)kD!jFEzAEKCyi&)8 z!dZ`l0$^}REruI4l-=+?^Q#8GPGYK6=zgwJlw<xXgje;VIIT9*S^Cc%ZM&<;<w&ky z4IW1)%30uC-n6KUMIvrMuwSgd?OybK?7e3%z3r!>pNr$4a__9UBc2_}))t4n-2En3 zog1z#Ki7Zjg)U9GP*__I0H<sf7T(xohL3CcH7(7e5FgqiB~tLi9Fo|$W_0%piGD!x z``k&9gqk`2Z+M~)*RUzCw8Ff|3u~i%PElxAgKV!9r3e;5_kK^US$-%guUceIlJ7>h zrS3x0JhVbSqWIdx=|w1uCTvajXZb%hh&=Ykmm<WimJKEk_40x|{gT|-xX=l!N%QSM zk-78a=uYYw;yvg5#G!4GFW8$K_0Cq4<|O$M4VU0}eI2wK`OD8${f-!8tr7`L)54yk z)u$AFiv*!yCOv3pbGD?adlte__K~XFRS`vi^nrnbdQOnUo<3Smb+<o=^eu2|blg4E zY7-kY*C!)4QlF&AGI?~Wv`Y?=CmVF!$zn*>)9MP%tkBv_oi%d*UT4?Uo8=?qcfvLJ z#UP(kcxFAHg&P}m<#|3}mZRea(i?eux>Ogn4r9JPX6eh9TkP6EDH;K~^^ZNV{6@A~ zKearsJ6pGdi)o|4qV3c=zB|%5GoihMs>`566-|Ed=y{YKKZSqZ=CtsSLBmZu)}fA7 z)v(8&blN4}J~4UvI(dC1xv@SxhKI!bKpBTKA8ib~LTjadBhYd~n8ZY{`&M6ln=BI} zgKtax+nrru;wKm^4d%n7icUhxE?L1I@*|+cv(xGdw$qGE#Y*pf>=Tr3OA1GNae78p zSa(mt0J#)3?U|0kxN?Tf4C};9hhSTt4@Xt{(rQU0ZYw%5JU3A3|3Ymvb<yBj@VnXd zPwg(#@y(rK1^H1cFB~*9KaBXWdwH$3mKHSgk>Pz_q>okISQ}s~R4PufugVPWNSG}@ z2&Jj@#A@v!LG+zcP&~<=cv7{vmX@zIXuCPk_NN{|4vk{*&DILy!Mj6?WO6ef|Mle1 zp_r;Bu8K(b(@ZKnH=$*+{N{-2oAQIC6?WyLPZqkEG`TLeMg?9PG!e5@mrAcahjHj) z{}tQu8?S+u8Iigw^*^#bVk+}0bm$#KO8Cx3rD<xV#MK||=(Swqf?OB=?iTeh_o?fp zMeM^H^XY-QhUA#$Oe0O1$iR<9`Du3LE|q`cVXQoGx=L1O%Qz*@d^oC`Yi$yo_3|n$ zIqQac7y9;b{%tLwO3hV3w|2c_Rz)=cWV|dlROyzUb>Ts!`g-=R%^dFzTAMl*XnT{X zD>nMWCoQo~MUcrL`2N+@;j9ZnO(c8|`bOS`Ak3?6LW-SB=BxHsKj|N4A`wD!2bK-H zG*9p+R7+o^*r<Xw?#CP52}_x5Nq?S}YFfZy%P_Zi{&@?K9&0<2Sn>2(7$GYDi2`Vi z)02M%V*NgR|N2Q%4=!r?y@2OW`~mxcq&oDrXu|l`|MrahSJ@?}2;Bxwacu%d2ufBq z_<|FI%_aWWRDS)dC0sP6?rkHXzmowk2wJOsX77K!)L%Vh6enD?@W)kx8Gq@}7kQ!( zwfUdY`d?R1hKq*LGO-hCZ%~K9T~n8T$+Uw-hTxAvxM=&=8)k(5E)l+OHa5!@-+vB~ zf4wp`94@Noo=s4O{eSEx>i>Y|rWt~kBoGCw7N~bQuM)gH4cX9|p?wcE-E+v_dh3Z~ z7%72Nke9us`+r(neYLXKu<q4I1QwXLG#&I$q?NGfi9vp+KNlF%UxFJ@<o684o-==# z&|UE3LL~DLNY?`Pq86N4lM<-Mm0%wYscmxwWg*XWPoAL2Y+(o@CZBLsm+A(;R?FAA zr^*oZbgGBK?)*m&(jJF+OrT-}SJ7Mjg6lGZLhq-+quK03vfn>ENWQadR5xhfzt+Ux zcT19%oO&H)4b;0i=rqj1t7i^+=?mBW1QGo@l3`?#p7L!HAz)tKd@s=Vz#51G{<n<I zF_w^w1MPZWscz_0w}3p{)|a<r2+l`~wUt?G0AVvgvbIJGzDHPMgblybu}u61;csR@ z27jlc=o!F;kCq;5O9grJm5YIGjzu?~iFG46T`MoE4d7iY&ZNOfKK3`YeC7krb%&T@ zmv``4wHe>+n{h7nfcDO{8+vzxbXW-z1aCAUm{jz~knf${+BRe1f=J>VMZ{-Ei3Y2V z)PUzaW>2DNRx@7#z0Ab}3in6RTfi1afxh;Fo!+-gAiPjoo$J35qLY2qBp1J;x32r8 z7w9wU=rlpDhJ}bvfNgUgGPV9>2enb_5(N6i@02`2Cf{W;>S>fU<fx5-PN(QYW-^jh zl=DENF2o1PIQ-}WYVixcdk+N~Vv+t&y0C&WjTX7r*4i{T19gT1q$)siDu_iiUr3Ww z#4wp!`Vis3K@bU7>rdYwANbl&9~L_g$c1AKRV51XS-ItG+84&UHR)bwXr@I$Y@md| ztp@B#L{aHvD3M^#Fpc;$WjT{JCqCDPYhFuvmE*cRH3pfAyu<YYyi=qZ-B~)^9c2zT z*W-4`%V0~CKg?PTl-+B46Ln~r%)0prd%6KxY^#=R`8UEWFlhz-sV$u~w2P2@j7_vn z<T6ydNBxxWZmY%pM~dz-nSv#u)q(-Ueg68Z&|u>M9=50ha%$qP(ure?-9c?LyX1RN zxS<e82RkvpYviMya2`2!WTM&E#gD2PA|hGflV2`wFx8B9%BULxO9qSZIs6gR_H%;5 zqc6YJ_`xcHB`>g_`V(pzI(q`DqTlZqi4FVnHXFIkhP`!xOw(cwg%?`T53*hE1O;;o zV%vy7dKk^j5eC;A!#SgG_74$DG?4FqRk#6<$MOByT#&~GVqg4_xwJ%<Mx&oKd3m7t zng!e}wTuNs2}EW%Xsi;ZSMu3j(L#>jy!j}vRVQl&1^Q7JQ1y;(N`F>1aG2rL6M9K? z5v#^*FpE~Th!IbN;Gp}<pCF!`NhJ5ws_9IW*^ji>uF{}yi+Ey3>r=_O7C~PY4XeCY zMI0We<`Zr+hYj9%b|2Y`R!>b(u8A@-hPI5zJm`N5_u!^|nba8Xyg59Ey>zeu6s|v- zEU{})1qzlv+7xvdQ%X|c;78k#?2Rbl{qd*h2X-{m49Nlt95f^BU}VYhBs)Ln0hgN! zm9SUgrdcnO3!v>VGrboE(`X?Il&3Va4Yhz!ov|kl;Hb4Bi?A6IL@pF1La;<i8ike7 zRp8S749W4eQ7eef>XR;`uw%aJ%>(*@JA^Z^0tLvC`v-jxUeFbtr_WP(p`B?9LS1vD z<AZo>1FT1HUE1?1{_fYusbIcv!Wjo)kO%@TAmh9?$0fEOQxxY?OqHT3Ql*Ar5$U^e zMS&Zi#(m*M@g%)ec*xMsMz}&E@`11TA2q2DWVCMKKdS}X^ZuDU7FxD+dI?W=o7;D7 zXFyBM3zFyJPs%I}8qD2DZeU50LOP_4@~oIjD|c?~J$T$=JdMG$t>^>K!k!&xyuBK7 z+hH^2McOj>Goax|Ad+%iQ&J{7#j7gIj<X_0XxQ@?IF7`8gPJw+S7opgzZIc^#k{5v zJR0ycg)JL4lGE=m8c1yYNJ6qpXT>2XgNkBhPJ&T=&j8Et;Uz-GDm4R=C$?C`-ok6~ z0X3a^ZvxsRg77$b#0&$WX@>OB(#kGmRUwV9R+0H$E??NYFM#4HK>y~uVCFG|&+0&$ zcSsX&@aCxoHpBA5GI%OyOO5Q(GV3)SA!?RS@{>@>$@Tuw*-y)H9=`l&iseFoQjebR zA9kL+-odBTY<xL(S1)(#ufz|4U8l=&wy%p+6Ap=rpWrR=mu83EFY|e{UHQAJ9?5yc z?LX^ABE%Bw7;Fh$pV_Ijn&Egj<9m-#<dsjcX;wJdR@exG>ApzKaGM%C3&93X`D^fO zbu`0KHFrsZ=dh`z2-IhSwx5cN#&groWzt(OPjy9^y%u8J^Cv)u8^|h;^#7>}eOTzO z`qfNlJV4Z8knj4e1xb)=fv6e!_2Vn%gC48=Akvn$(S{e#e6eI&2T#G9;_+(r(q-7n zKO*1C)b+{C4;vn(tMrSCH@tS#8Gy%r9d;Z6UQp6nh^SRCQD;<`_>xj6!A772{n-VB z2qXma0F(IV?5hQ*?2O<HZ&sIOq+uB8Z_z3WcN6{!2e~cC9=@2@87))Gh$*YjLeuBj zba6V@Q?UQsHCPS{2i5UQ#*IygsOpl{&lxS}UF&D*qQHTs)#>@rq1e|*zma8i=3@sW z*nVKmMkM;fwCIS}RUYeO$CB9XPVN*1fNhu!j%kkZOi62?cCLJRR^O<h^V&43K3zlS zauK8R=YkJ!1KPJ}fuvg11fi+_eFZ4e(S}yQ#PLrlWT@pqTRjzuODACoLd%2|@RPRu z8`YJVL}1E$ZVK&0tO;kxLi?s`gQ8o^HwVuyzQg(|)Cz@_Isl5j6A^l3hndiu2qa20 zyK>TXPBySv-T5oo_rI`R9mtKcE*gcsx&Y67>p_FOcdmVjq;6?{mM!p0WoH3_TkFIu z5|Az7w4jbq<UaloiMIL|h(=y(Bnp6ZuHhX*BB}-rC<i$3w~q_#_%#&P8j6}Sr#d0y zonHh>5hO&orP@2af4&;*t+`N}jP}utyYDQcyg5K6*Vw-QtqFlT;{SiZ|NHOY|4@Ty zmTP-$E=TB=-hR>M1bLX2phSvqUqdvc$QBNU&cbzWs7n;4U!LE&67Na664i+}K#x4+ zn3!wfF%U?9%s06-V?)ErZ`Ijw9NIiC(m4Re21t!K^$PPBA3};^74$uO%UwINb$K0T z3f@M+7GI}qTxOqg48$j~-D#>!9dM0B*t(*DQG6TD4kwM!(7ioM@8iTMytV!P1PLtd z7f7Wu{rqO!1(4f6xvZAJf9=&SO~CoRJmiVga{Lw_UU3+fcRtW7cs{`3cU8|R+P3(y zvSGn>zp|A+>)CO{bv37NqIVVcq}WNYBM@-cA<wMo)r6~ibx+F%@_{5ES8Norpra63 zReb=%r>S(P;3EGE_qUaznv~TVx(aT{GT5}l2z9vs`0}uToE>c*3+I-d`tV*|yF{Wa zAY3D%=!^bGW`Nj~TjwA@{a5a3C_$~DG}T{Fy&RMlGnUq(?0B7Pqa}b^KO=F#DpP~i z)yN^~F~3*$R}Ep{plm?*3J$MNLyE(;8HSE+GR4t}1ABe5;S_)Gq}nOk112#+hxOSK z2AvEHU~GDfU^0R2j*L1EK}(3{dJ%Z9US5fRFt)4-g0Zhd`nKS$fzLAl;+&2_YUy2F z`p;s$W392)@K(7*%4DCNNQF{%1<zy(_0hY}payzzvMch!jplUqq#0oyLrho(2qtdR zxf5bv8WNCK2T0Gq2#uIenv6WAkJQscZ5*Vu%j`#+;k;!mkE-QHU(YDA>+g$!;B(}K zNGcfnNQyVq=w#q8EMK{x?Fbyf5F?_BU^MasMCa6*^9_)YlKd->z%xvPq4b%-Dy04L zK#X>=Dp#i)7_Wp!u$P(-%N{>mz6Is@^-pt%h-R*ISUTdyDMC++IWeFx48VowkkB7_ z8I4va=4wE^$z?ORrbJp^ND+eKmbbsc`H*2eiapftF`=ct4-m5Tn@5MuXL<`(-teoS z5ia4%ZRnU$HqYzzLJ{Qvp0ZD~>omHKoJvtKBm}m5X*yUv-5}|2hPvE*w~E-Z7C_Nx z(W9<wL$HQy;!l*mJ>eD!&Cgyl18mA6KmOizs3NT)_Q-P88A4|3S8Q3n?F6}?O&%ty z6KK$b=UE+<lG?~dqJhB7<FEb$GohX7a>XP(ipg{~|MkH!0D1x-Bq&&1y0p7@sKysz zNM;H_)&F6p_><iV-Z&^_pUJQ>=hggINH&;&WCsuZ5+1k%SH(XiR|vbxdd7Qu@2*|j z+sdjdFkD7r3XvDh_Pe;#bZu^bf6shI@<#8fB;{o_tE6lS_52y?4@^Ho9^QMTXzTTa zI>T&lK_MAAPS=b4iRbRaYLXdG)O2N}OpizrrAX;YOOl<D+;ji_=Ud`wtru6vjGE)z zLV8?65!tDOdE9W4S0&SU%yhZOgsk12>1`gfrcf0sIWqv5iQ9!*xdytz&T|}4C_ar5 z_t0CJ`FQ$M$t}Tgm^yL_vW)oF*KUGC)&Bcene|d2Pui<I+}dV?PRp9YeF?^5ueA!= z_GytGI>Ese(RAFn^tMzzIBt!zL;#+IL)ib56^Ef$yLCZll$@FxB>=T}IK;HO7LNam za{f<Ak}yPK;C<Y5a+*u8u;E~~JKhr>9aA6@&L-np^+C9y6?%q+#qGYHHbcMF#Z=qn z6WVu3bzuj`!qU`F!`Vg)-r@qymPN5E+fKv=kC72-$Tz#WSqZkDuwyb|adCG0?>~5; z0KAVGc$GAO!m2QG&PFN9-Vy^22M1;3#|q~>*=WdOZ2*cV8P0?g%dMy^)p+rCaOLPi zve22cXI%@Q1_Xow6jhLudn7Bicjv<akr<~bze$BJ_t9IVBqv9<p#eGbBxPhf4Cvp) zrgV@NnVOnLo_jo(Z5ayFLqdR&b2By%#QSDLZhYh#nDG@gG=eSeY2#fnFe@ed{d5L_ z0-lofxOc)noc-cjl}~nz(L8rU<K%K7!PR(tw+{!m4*Y@Pgnycac6sjtY4*YzC9$p% z>iC~DKAbkYPpO^q{biWWPD^=OQvz&>PN$`%B@PTO4$4YO{<<?_I)VuVf_0Ec@X!WS zmRfS@IYJvz0VvdI*d<~KfIYGi1hS@S5dJ*c086irraA0Hp1Ztb;G&~iPn-zdmO5~6 zptCm|3CaGkn!9z}-77_Sc{P`e;r^)PB{33s)4Padkc%XLcHC(lAwywx;GI=A-XZjx zl0nGFJtr7T=rkKa!^h3DH~5vDi5&6&Lg{MBNKc|s`R2d><3In83xb%lj`t9{D0K!v z`yl&{WB+xzzkXBF2q5|b+gl8wi~c|V5s?Qg*9gxB!j&+8{{tE5tnmAOexp;d9qsKS zV3|!^&Cp1Ba{2P*M@^%RU1AmlyAbX~yO~T4EAOg9cDNz3vpm#*T{OjOdkY7t&rqa3 zh25xeX|hACZ=wd-W9y#K*e^|}KXdr<<x4vl{w8}1lKzJc#`_%Q2Pth=*YZk`xZAHS zS;o5}=P!^H@?XDxO$MVM55z4zb7E16!2%YPH#bj}#V;m+SHAt_P1Tz;>x6FmZdS^C zu(8jEL)Ksew9^mh0}nJZS1}(B!15`nma)fj*uH!Y&3RC_A69wJBjc#>BHU@VPu|h7 z@VQ2MO%DWcGV}9y#Xv71{!M*-l*iV;mhnF;mW()6@)fD>zJ2?6FjHDdfS1gU3EIU> zka65}84eIM9jx+5Z4_zHgJJ-jk{vN1rj9@;8JCP>qx>!lro4KJd60&9*4o^K?9P8K z`ul~5!;#A)dL$10;${mVL6ksI6soL3=g9<4L&hsYX|yUa7uz@v8oxAGhHAmR*t+OC z5Yr1adzm5~V9>&0#$_2o?Km<e?|T%unA4fyH9QH9$K`YB*4G#%JU`zE;Gigt1N(GG z6>vJ{>UWLlris3F6MZkgU0Iy+`>p-{>96kqaz%XLM0v7Ro{)<f&EwE3lq<e9ICt1| zlAFfrN6IKb%LoXqSg+gwTyB0jBF_Ku;~-G*{jiZ`CiF~y-(PCSv=*d~qt$k<;6+aU zy6wvn;x+oW@XT&2GZ$pbJ<)Jzy}#LU7%hxzEV~lU+b{(}0o{rIo;qUPDy?(^#|M!n z>Y8shkZ|u1Emo%^V|IFax{c5C=g)brzaf)XRb3^+Me0QcJR#q?9it{lhy)t!12fx6 zJ^|p4wT;aN8%h(H6`Eyl2R5`nfs7KB;E)i%x&hy<YIP$5FyTDWZU)my3-(xn^!;Vl zmLC$l9j7|wq4~pstZfLZRB)R6Y}q==G!KI-uDSzDo($EKlYYOD$66thako`>DYk0D zzD%_5Hi6ZGqP&Q_z`3>*#R#Qd$1k-c@z?2%pl+1=Iz0T6L>H#b@IHN$mXh+^8dI}6 zF=6re(If1hy$2hBy8riDUz_n&*!lT)dB370n?NZ(4h{|;0kL>EGO+3r2M>=1jD%u^ zF=#>DRX<MYV^ab!BfoHPI{UMyjC+MO6lHDH31J!{eZVvvPgP~j;1Re2HQ!n24TXb= zBuW#A@nB#T*AL(dy-BaJYiDC`ybaVX;rT>P!zLHOWta^8j}yzsf3LycKmD~Dg_+f4 zwJed1?dSN@+wIBn=J+h=+q?tun+N{|j83jW5H#qbP}$JuIZJj!nWNeuW(S(sO-!T$ z>xILR$r=g+bG>U87U`m(IM;y3{E(#K_!O9tcrYM?!h$N?Eru{K93dly@kei<JPQM0 zNpEY|i}&1IYlngymRkh0vZ4-ayK4C6g4ak6fUUAV!F?uF)cf8+oTKX(=%cZSIL&-x z&r2$V2?}SSzqtJA0m0E{HQcbThS$0M_+|nLE7kCDMyX##G!cAIyKg|W(DP8}Dp@ts z{s+bWUa|@I$%$pKXz5uOPC_fe0LZ>kqNk~ZcHTM`z!dH)ON7o5?0&!$2G`oC3BBYG zq$mGAE^a5RgH+;^zzFW=h$4XL$f)B18hroQK`{P|3odH!Eu%^3Q+$QsMmBLbSAs>c zA6%3x--3|iQq7$x_eGxF9WSS$?9%?{I5UN`uWnQXFC#f5OqBcPO~_o^{P9pR+4o0G z4fj6LB>1(l4+*<0B(Gbo@&DZX?18(!WLUS(w?qiu-Mh!M`-rKTxp`yY59-OzQ;n*; znS{PHN>-!YJ*#h3N?%J~4(3XhPjcmdvT8X&DBEt=ZV95?`$rzzMU*lR>!oVtXng$N zToh*esc>f-JV#~SmDr0X1bKfP$)|HuReX;X=Fj?RE&GS(<Znz^$2Rm|rCr_Hd4h2E z-aQHAuyV{C22NlE+C*3|Dar#gvWefbOz68zk$hFOYW(&yO;g3l*U<xI7jUkxDi>gf zF|F|-8FNWYOf>!R?aS^(8&NVsM^D@S-lzEaN2)<8oQY4i_H8Vcx~<whm+-0*QpAq# zeQdRJEhSLzi$t+cN=J#V^cj8pR&sFn;*@aFZRoPuk2N0y&WTrZ|DLg?Z>XK`R`NSp z=~&*!anI#=*-?e=JX&0@+jn<jR|3>G<qsF{dxkTc<4l`rw4hMMj*OTBuTu<<@m$&w zzkHog51QIx2gRN54`qRzT?&edA%{<2Iob<MnJl!PzIwYuag3CLZ|dqEt6VBnxO=x0 zMh|KLOcDp?%|BxR5}w?lCuZ&iGe>|`D!JMsRt)D<=5f)xA3BlLE-G4D^A(4Vh_@6% z1olr#*7L}n%QYxFg)n^FeE`@dK{>wJjzA{po5CJgGF|D69D(5ROh!st1%)R{k>_jp zEWtu~fS#|RqU@qCFWw0zSfwi4tv5Q|AY33{MzQ*4gELbX&N>Q7hy#&%odIV_BVfM~ zkOhYz+r0x+*y(%-lQvD31t-e$Yu3QDu2^s?-hs0b2lKTYen2jP92`H*o<?i9xpxHj z#vx)Ku7<{jhVw}UpY2LMyDzr11IK!Zf+CBru$_v5fgSEU?>fAN5X7hIVcfAl$I?%j z@eYXJsi>$<xy&{>))EvD5z&y9qu5z)<#mu@giTCMll|%W8x8E2r_j7;^`4G}IHUCO z2ZxyK`id+&t{{ULL+q3oj6FtwT&E|rF^*hCP55Sac53m4eS^B(ezKjpZ5F^dg(P5M z)8@zv0`-5RsdobS+da94xN9{;9dp3>1~J^KY^$m-3yH3Z=_&XlfZ!MMz<PNn9Kbp1 zeF5p)NE3H8-|4)K3wQVGK0L@6tYhR-$L9rOWs(7|n{Pu0jCb04Qdl3!<SR8aT3;yL zN04dwNedreu_p&E8LnH}@9JjQ!zL<fz^0XcZHrONwKHbnAdWAT9^u7{x?m=n3rv`M zBb1ZxwmR3IBztJO*gPP+a>Z=$KI6_O00N8;!_}>~w>EjeYPq-oyln(*C0Bu>pY*-} z*-}EV`@#q4vw-3QXY!hq7q3R=w+&rgGf?A<tvx=%0!B%6bJf<nTgEE^y@Wt@Ly6=E z65aBxE-=5gJe`)FD^I9+c~SQ2PjZ|}ytu6@({Z3y_Z2}^bB2wr(db)$xv}RuZtgXq zRfgIolA<$3#<*q&q~vXZGrCDxuz%!5zU#78o0pzDgq++8=tW|^n!nEL2?9C)`0?X5 z!wTxl#w#s^-(3Xq?hq+?CFo_wQotyC7JPkqe0HC&Iwps4Z2=GD#PG%#Tja86u3P0^ z*00jj8wFl(C>K9s$~7rHTs~v>5c+CG_Y)gpQ#AMTJGKus>L92RC`Sc*d)(k*-3V@D z+SqUl8ph|#kbkKAaHSZvhPzdNkkH0kg*;g8CCUJdK=h=)GS|-z&|E+gJmw>iYlC%J z9DDbD_-zVo|6@Ajv!sDYlKi9GfE1aYMk}D^hi6nPNZNW-oo^f>05DK_2s#E5tKt5> zBh7BhGaohKJPDs=?6)g9_8c?Y$KPi80B(L$cWMIL6I`B;tN9!OxnAg*U*w9uEdQj$ zyzwrMR=O_Zvz^8iojhO*MdSx}#1DE9Iuog1N=p7ESJ2$U84WH<c`)f@Un<^tChQ_g zQA448vk|{<d?GOS?IpL2*CPoo>-KY$SgCF#PBluWt*y<I&V)NQ{%HvTOrwy8ynf26 z!?!U)FS!LsY2%$5p@*GP4OpAq%R+aL61e-jz2GmmOw$R)NRY7t-n+MUT$Ip6;d>H5 z<$3XR68f%)LjitCdK^4KO5jGm0>Bq8acqhZ<{<*@Dtm(X-a`cL9BK#>x0~V*5X20- zL3Bu?7VrCz(1ZOAFzu-716Kkc-}@dYJINuG?e*^(<o8cM0Aen%Tq1;jBqgDFOwu_% zWJ0Jo+JL|O8S-L>brIeHDgo{k(Uilt^Mr4s0m2vj#r=UcV52CB&_#B6UkA30P1{qL z(0yyjkbI@W*?IUnv@Js**+B{(l(V2dYn~KoYkhVPXcgE#6|Y}U1Tq5+nFO<G%w0R* zjO5ThsC}TQ<3gfv4?lhKBpCGjd*h6-Vr`%yIgPlDU8Wiu<c{%MX<_lZpZyw>`Co-? ziY`*H14rHjd6g|Cpe=~pz6?S`cF>&h3bIe2*oA~X`meM{1C^`2v_-x11|^^n=+mCz zCrmL1ZH0DF>ZQ`szS1d4rHvEDC;$vP1>HQhdlg%&v=0w4g(DePzQ9Y!DJdy=_eV1j zAS2m;TB40-DTUkMGwt@h@Xt?9oFw^}498_qiV`kTrsL*@YV(EX!^)Mgh-pXSE@;6r zGc(ITpY!bD!-vaUOCXk@0fK5%U_>5NqhSVySpj*573Q>`ddAa@@M{=bAjVsoNd9~k z6jl+zR_*QWrqH??!yr@ZcxhUH+JQ?alvy!c&cGmMg70$H{f7?~L99Cp&BG8R;A0AW zLXAie=?dhk{py}{eZGMt&o<Wh?p5xG?AbFWCMM<*f*wM*?gI310e8PlPip&Wfr1}7 zO)>~u#$pY)BG9(CmOVg0%nSj!!Anby6-Id#5KNa0l;B6{9Ec@~d^HX2CSJ`8gD|R? zms68FFfcG2I$;J&F4;1_Jl~#WAIi%XUGduhPDY`pU91vq`}bD=jjXQNuAdF6=4Fd< z(WB7Eh8fO{x^)ERtYcYz6$gB6P}{dC{=KW4S6`Es_GyOx@ad5P)veNw(mOX?K$g$U z$Ja?LO5bVGrY7^6X8!Ae)}=n!WuwlP%{G<i1tv#<yLj?b=Hh?=uqIGnj~Q}8B6Mi1 zh_iWC2^-%BdN{y4^Na^GgJJ)EOlk*t&q2w_XAUudnYU{Ame;y|o0oP$?ycVZ7svWj zlU}*gFn&z2&B4xtmMa2iwx3p3QwUvR+gJGAEsj9hE~!G|!_(jjvOZ>U@qx;uE$O%i znjjhoMR*z*aB~)DT>f!n#v@`-{@8O^`)wd2Zw*4Y%(UszhLXzCqbwneST<SaDXqB# zx5uO(GG+%E82<URfPglr%}!STsN)`i-eU;JU5%-Z9BC1nKYYD)+EF2a%W*JS{)o_> zulFaoh2}n$yf;XjN5&Gr%=5}dHD-SJrm#I3DoIhrH`FMPH8adR3GK1j%f6f*AjTGq zzWHHMm<O3gdR}=sj=qmk$o?`i=WS}qkW<2AFZ&V?%TEHk@`yTW!Y3P;X<mB89@}!5 zX_*2|suOv+CSeb>_4p*GfPnotSZo{3VN}^W<MvQi&r+GabMldJFx#0kmlygX29Oz4 zyr-ip_ppeiO`GB23g(?!uydt=_fOB3=mmUj-80jA#^rfEB2ASpi_KaxIc|T$)3HL{ zh6R2aO@>jvhD`OO2mXvA-A5y%Z*I0(KBkY+JzW&%xn{}R(kA?#UN@Xrf5-m9%Hf@` zA7@WwlCw&E?AW=aD*-$a7L-YvG?>kE^OJt9MM;kIF)9z6EWdX}7>Pip2QQCOnt&B5 z<#dQ=E>sSJXNTIIs@MDHM?jDJ-sv4scg=F#6bqg|n~bB*t1{?Hg_GV9o^9{x(-)$^ zEyX&XiEzI2;Qrs;$UbE<oDI3tjsqkCOY9@wprEYG@7*@q6d`lzM8DqCXVZ@5z%unZ z!ZfdNu$HiVTB-$X@eVZaN);dpzhYPU{mMH1xQg9cJ0{6-la-U6%kr)hsMjCmR->!j zUB+!^Jq)o%bg4bCk5ISyO*`m8$C1vrr%j_uLB)rIV!-ioR9@nj=a^fuxC~9f9BHhX zeEyC?*1ML9tP!QSCkzgh2B_F9RWXYsBaEh?VwFRpP&zt=IOqQ=8h%ERM)p)WhDPM( zr6fgGDnj;r^P1+`^pn=*BtA)D*QNA{LTSUd?1FXVxFxz{n5pEv;1DPw>T#Z&?LA`I zLFVNX6?6K2sHWg+I}aB>W=cnx4XF?BgX7sfIa$%k31-7igKf*B$#o(P?P^wt#=kQ> zS9$rvr9;n);(wK1&hrEP9F2Adaa$v4-1vtpY5PBTfpn3Ij_zhEzus!ME$|XDviBxW zebY04AIC{gW_U|0)N*22RSKrrsjFXi`7u!+$0Ls&ReUJCb2TX;t7&C^kQ)e2{<Ffa z6A*hL;Eg>ZpEepR>cRu;sx1V}okL=kO@g?{w?R$#>tq}iu9e$EpEXj#JuP0|rKT7^ z2{XZYYLKpqP)>DuFC;9#+=gp4!a?4=1)C8!oIU0eEMDXg4Q%u%b^e+%XQyTGuXqy+ z{|4N-ofU+)G}Uc9%!dbZpz4!9ZF^nYo)m*J`#O%+-1i-S*Yz%ZhTB%~<e3}O*{^z< zkJru)oW?CBLe6Eh@nFX$5|X5*D69CB{&DDFRpB9HnVvpe_ndv8O<&2acvFu<4(~wx zdkWg(4NhfM@qypkWu}qQbL*S?A%yebVny%zo<pK2L_A%5GmXILkA`RWrXh*NS-*O0 zoRNHVy#6P?8|oR;cT_J0!Uv3H_fCEtYsLLn1=X%DQ~skO{I3(=|6|G4ND((hQ?~kz z>aFFx6rkU`IcIYo+%7-w0YZ`%M_I8uz?m#g`<CaOPU2GotwHdKJ{j3(vjg}~#}N<s z+2(d%AE=BQlSpk(o;>MPO`iZZ(sxE7Ho#z*e{s$F)gG(&KQ{JZUFT$ufXz-6>%Bo% z3hk$xJ{*Q==Z^Xy!wj^Iyf!h5tw@I*7~mdaHu@8jU*|#YP$ITLq6^}IaCpo=%{m6; zfQ`YGqcWFeu`fcUhC#$Bd!m7zQ#et{Ycvm;f<Q-$#Bn>^66=A%;z(0&F6!%nuWUNG z9B{_b8on|dRJ|lPy%}@5Y^fGL#*!y^J+RQXiOzYTg`D*F?-PqLLj#3>e`AFKmqWH! z<)w>;x0F7?J8R-Fx+Q2zz>3w7bZ;Ndb9;R-nv(sf4+rD1<QE~NB2`av+0l@3C9k5g zB63PmR(kRgYu4SoRnxBVv^)sxY5<jsZGYpqHh%lZTZz7>c>Mt6G})`I9qW))ZI#|} zir)sO08f>0oyII*<N}({prdN(SY;E8KwyP_%D40r7jGxPxmceRNT6y(aTDccpTpS2 z)}}JUoAOXGWHr2$2>Yt*2Gun{A(wk@LX2wMaik^I7iToify@@DK9i22C+D|pf8)|O z@LtszO71Zs{A<Qdzq;PutCP^(yC}=A8#}e81IU{vDIr_t%W{kgcv<sb0F@=jrk!oU zFZc;c*e1XIbeAcR9F}Je-QJ`Q-P}~dJ&YZTt*9C3+=T*CIA%Pp*Pj`rQj@J$l=-r6 zKviBo2-z^9-!wB18|z~J&a?C<^=)M0T~4)l+822gsH~n`-5u>baUK6s<x5A9E-*Yt zV$CP4L$O@~)t@$&QhLrZGt2AgMLjo)>=^I7m3UBCSfQt}y-m#z9V68Z(jjHRW5<rw z>%<#-fRH0TX>Pd;6TpjCxg<iqvwT;hB+7-H&oYd#ZUTw!TGRctEN{J|U7D2fYiq0D zXiN>a$y*7qR5I*CPo6z<wthq-_m_OCQ}U_wC0awi7>&D7So+;;irw*qBwQmV;%T54 zc1+)dmTgf85Ep%KXQ&}TQ2R@%{Z4To>qYN-2XKg9uG{oUVBksxnOn`_+blFcMnY7Z zT@A`3-GQu=B2f4dsk|z>H7H)fC4NE<7+jUddv^$*p+04G+T8<DTc4p51SQpqYR#VC z1>o<W3{+or<rzz?!rX^5z-pa3eLAlv++hc*N6H`SXn0`sifzupT#-Xk+65k@!UXDh z${#}B_Y8mzJ`uG@=rSo#?Pe``I1C{3Z2ur<$rPY4PuQ>#<s)z-*PyUb7!({2*zv{h z@=gGcEqUYn`bz|=_W%Ea|J$#0;akfQDyose?X8ls1w@GeC~D*jmx0fJOJx3{R~g{` ze74x^b^1%}rW7rp493CL;bQ`XZnYnf7o*J4F)<v7^%0V1io>9+&ZE69&Eb=6!=d$i z75?WZKal>6{%Q_B7jrAlU_5{A-kUdX?iPUrhg6z`z^WjIr_re4e^yojmePj3BnFCV zU~EyyQH8}~iBg(Xv6#8fLT%$&(5fgk$UQC=QQR|)C{jSH8uaMVqvOWbnA^~-mWLfq zugI#vD8jFHCnKs5gGeEe+7>FWW8a{EZwyk1Gl&-wLaS@H$kwdAo%=Bnph0<i`or2{ z{5Hqr<fO)5vWUw5fwGX$&@*0})5gl^^_5wKLc~F;_RS;DHbEOG58Jg;?CSM-sKrAO zwgFDl78j3Pr~n%gM1r_QN}pkFk2D<C1%>l*Afq#RK7IRk8v-MrI?nXAB^e!poroDx zcrRNedDsn9>S}0e&K5)S9gDEc&~lm)-igz}qk=+oDuFyW>2%O6H?+ozF!S<uq?M5> z(evq=LDXR?{>1huw^tDG1$t>SIlTUB9r0UdpnZa9{MIX1TVHwak%_<bbWv|sKfXl= zf-@8SkMUmNi?OGr7+&f*xQTyOJPR$CC9t5lJhvIFGW=DO<@V$WeDDNw<M16qvOmf5 z`=S49w%ht{2UzEhDAm=~JvXK+ymA`Uz#a?HgB$gH7?nev=jAS)oace6M#ya?`+4Ik zA~8SbJ^ntPj`5tCpA3=^vN>4<=Ed;*{PPYBAQ+@Ucy~nKt*$1l{0&6nAt5ZPQN@4n z;!z%(N#ki?om%U-A;!eWXdCx>Jr<x4OF=<FUo$oG`@%&UgQ~JwlVrtS8^cUgOiZ`> ztoo68JmOw|ZgPkP2t~;!r473~B2_vuMo)_ejnPU&DtMV6t4wz!o(|?4Y0q#%1|Gb{ zv|9SnOTzQkBtCzj#(p8oPk71_`h-;U^j3qHdhm$y#w8b?tCzQ89Rq1QJd3<;{v*sV z$eKsmS#B*H@E)x#1E7k$Q3!xcAgPzHv)#JOm%u|FO6{Eh*-ut+fl)YVHkK_gKe0hd zd_e}%;n1B{ID~|5Ao|mc)i|S4^A>tQm#Xe@O}5xk1CgfB-`+|92^Io~#e9EgcF?sR z{c7ufls_UuX=K8X(9PM6cXPfOVQ$<r-Is6T`!OC;TPK#T5IVi7h<#2qKr`gIC`^$N z$5+D)DYucJz~1&CeLcs%ga=pjD%0q;W^Z|gfQ9kVs>M0mXb?@;-ruJI%1(S|k_Bao zcPOoO^3^L>9*9DCTWV_$8Lz{s>1SNKBs|s}9VXmaZesai@Cc%z$2`V&)eS;xz%CFI zaDk$kb?2rgDNjlE1l8oW7JtMj?R&t{3$<F4t{UaJp=igx7hKtMF-8+H+7o!vFr$c1 zP=wk7%NEm>g2x1sy#(CsWeo^BHDHS>X-h9L?^g%SQ2l+~n>UYC?sR@V0K%uD=66in zh;bGN)q%rh>}aS7(~fh}#}LKp!(m)KbhE~oyP*$cZj}&lk($Ae{~(m}L5B>jB^A!K zD{nu3osF>M$h)13l3GgJD3x~VA?ATW_mZ@=-WQ11J?r)3H51NbyB2co?5$3o#^F4K zclI?C?juhj246RTk#df$Pm}RFr`ChF4~O~VhE<y@`n>qt(3f2)*DW6lCp8_YJ7y~O z?bRN8NKADV41$EyXfM~=o^-C9RsJHiY4G(40oE3<)|u>-FlJ_Xiifck!AS>qd}sxn zq#CjA+V0Ap>h^M=``&?c90h$CR}1b;yMvw^N9gES5HKtYB-Vv#rO7C5_@8JZnnrD` zR$`~G0-LI^q_YpN=;@OUD7O)|v=&Z?cw{c$ig<|#wa==?*$l{grQ88ez={LzO1S0| zj~xJo)s{#Kf^i>O_LmnSEons54R%mU#(=P>D61;n`2l<ibZ|db#RC})g2O1w2i@|9 zriOI-t7tBxN>;?2ohE(hQVP->EVR@_WRLiCH+WA_S-%TCr#Um;cJnbXl5hao%#YxY ziop~P?khXRuA#KZQwk=)lNHYME9=To6d*$F^ua}d#1Y77q;XJ#aUu!#&+yLK#v+d0 zhmK!VbG#f8zCo<(ir)%ORFN;d5^Ndk{C!z5fLM1x;rI^hBxy+ni~Ub=wmVa-eR}n- zqf}I1)#pV&SUZv@h9mY(OlAz&Ycw@9E_?OghP}<HcjN$W3&xH#!XeRY#*JSJhL)Yn zptShbj~hs)vhpUt)5~f5gqwiz<NjMtC6tu{gT;PnGr__ri$5_DdO0>KT}C!wlJ&xT z;`_?G->++m!HBI4BYe5@kwAiAkSq$71uPrs51?>^;eZvMRlO7i&A%;<4WLy=zz=?5 zb`HO46n`=(FM8rp2Ar>tR8%`j#`h;pY=ZrW9cq#g=&Q<uUUZhffILZJ?yt$U|AmQ& zvyjeZnO`?0bot~FNd+&PLK?-?^?3q>|1R$#D%Jw2ZfG^M6yl+flmjOCCtFo_EP3wx zx()&*NQzFv8&X|Z(m|!A7uTD>(65THephaMJT>zly!3mAs$qsB8-Y5y2MmR7T)*CY zeZK6)Cd8haL33H7$O`RX3)9tboTYKm>uo!M45S>~MOqSUMzpSkdM{*r0R1G_Pl+Dd z3BvB(Q-z*cJcky6PeDeExE~Wd4#yEF!6jd%LC;K;mTl)<1eKdI^vpg~k-gtpQIesC zG@)n4vOnzi=l}ha_gS@TQr(}Xsmx~Q&ODa5Bj27^wr5t%<;0H18II!X)MONQ<cAxK z<sxXiMqjjI7MITaJcy$T&TZ%|Irz@|Muv;)E-r%gl_62d6~CsDw^4HVsZodJukdT6 z(5ZM7#%@o)<5_~0V-Z<&+te`^wLoJ!=~x?~bD{<PkdIIWB`HbrV8srbW%&SF^hX2g zyc~ajxZgjy&@{}ZXG6!mK=sxQlhsPkbGZbxr3z*DxOP=zoRk7-;B|{mESLp~B<>hb z`Rl3!L?T9((}ts~k*Fqa3YML?1q>hhP`u^)mF-C6h6_k~BVJpw(}DylR!UYISU$D1 zV_U!9|L>njkfF{f|IfrbHhox?`Jke=XEn%kC2?8U=Htns+geQDVE-Z^R2gjk`x3u@ zB0)5Hm+A(KGdOukw;K!NikGmJMPn8R^O6aw^raBdpjr@${h=Bkf$xu89#-MQd}3Xp z`-ud8Uri3`525?a4UH$MTXue9z)rHZNp-gb3Cay;dx;!kZh9VC=ze$&##-uda<@^i zH)c3kQaR7~m>M{YXEAXRS`FVg)lT_jujy8^{+LvBelF<le8Z>oB`$fruO}=YXQtGj zSoC)Er}IH`&h8VO)wY^VokgDZNgLz#R|LXz9t@m})$2UJT)oyWED{Myl`V&#QT|hd zmp#?R-&Dz(Yrkc1iVu?5+GMDh%l(x3j^VX_<Z#}>m=IZ`&t~xsbN+7MXpi-#RAod( z6-91r=SNnCJluIKN=hnR#&)GUm1eu1>~?Q`lgzGB;_C8D)tW@tYkPRMz06G6VXjBj zHh6!=<cZm(YpwB7P5mW0g3DVz+4zU=6_=D@Sc)~;=Es`9D8Jh?4C`R?w5c>dV@}HI z5?VaoqeLr@+FZI+z}MrUO;s)da6rk*NyN<6fD?}i^jveF*A;RQSFYNe^Ko}(Lj#wL zTkBoUGyQq3NnZY^YWY&t%Rt9w`giF1QJypik-znP_1)o@^T$V*9lI@ZRGnjs?M#Y= z#qJFIJDG0}6+CUfSu5~tk)W(s?j1u=3KOQ8Vcl#r{Ef|E3CJU!Rf{s89-D&!aP$2^ z3q7*Y&&!wml^%P#<3CpOvq=wZTl;?;^gOS7!qX(}7rIX}+SV5T?AksoN>G2qe7-^0 zW#x(E#^ShmwJk7<<1bUs)SD_RFQErKiUY)EzvZS$guEQji!#^W-eSn0I&9Vb8AMs7 zF4}Gx>SZw(UvnF;rtSn(l&md8%yw2^rt(zY@#eV%hT_C;!_|BA3pZ6)1;ZtltSrip zZ=1(t|Jb<yktw$5{Ko5k`bdxQCF$|P+7`Evk?ocreXa%sg(3&Nspw2|dflb#t7*pX z*2OykQ|`)ZJ)0GQ>wdL>j;Yr8VbZ;(n>6sFo3EqosxX`4QwP^Cy?dh@FBv8(ZSFZz z(ljvtKANz*;V!s*TwF&cboM(OH#N(_q*xp2jt;*ou-ELr{cO^&yRddzS*I}f=FZj% zS*W?U27~G5m}>Os!;wOp!L8UkIVp85VaoViv#>iYwkuwrQj439Zm_?MAI|X8J^kA8 zek6Jglg{#9%soq}bJB0n-PuT>#pYIEgpC{)(jl+$n-O>!)DW{;rcZXY*=FL<rfxMy z`sjDd3V<IkjgFt{COaqgg}b4AU?L+$_bGnRQ<K?YaOJfC><sa>I4lp>&#?d%z*amR z`wyL{VD&BEa@Kp{{K@9f6+-k!BZ&eUJ9->l^ktfNp>sy;M11vYM*fj56X#ycmJf&R zw--HyQaS6@v!~43=c6Wb2aQo1@j;x-sk&(1cJ`lN(Tmo8Z#_%T^k1>P(DR+(5nUpg zL5@4c78*92hskHwc6XAd&5__TIcYXBATlktt+Jf#-((hFZ3Gf~$0uJJxmBK!YT)NH z*$wr33iIL%W(F7PGf%JJvtzrJvl?nI<YZrZ>0$Eyr0%y#^=HBdckY?HiA9kQ1?sYm zdCzmJMOo7sLl+f<z0jFD<h=Z_V~Bkp9}TSEjuoFM?HuSY9QPL$YH}!y@Zhn&DXSgn zbV)lsmAPX!{1cP$t-LxjHbUK96jnLmGO_M*mJU|cxV)+Ivs*OPNZHRGV?K|yBh|sJ zIaUf+Kk^93xn4<aHaNj8d_D8hB7N$>F;k4KuBQ3+cPC8=v+va-3VNyjF8Pl`5A83Q z4+@ii{NU;(qpf;kt(ARwvFDy`xBCyZPxWuB1nrF<{L<xfi2(lCeal;vM0YOxO{$&Y zc2ZQONZWAtrK%;gVKyeHi>-l^;?zh(hL%uFWK`PCHp(1%t@~$;OWD?+8DR^Tn&a{B zr@ib>&U&I-3f->P_bhxINRG!pApLz9{_~ThC0zp=ivi8OGx(Gys)OOAe*3mM!>-hQ z$vt~Q!{Fx2+PsPfp4!KsNyY#3OTWRc<Ok6G(6q6*eT{oS)t?^xW<XoH(QnIHVK`E7 zrKyqgvCI;&BLSF3Tmsndut)XgcE`spnM<?wZ);4CE!DQ3nu@jCdE>o@Ac2i7@mA@b zD;3#6S5MjtGb?w`ZAfixOH{EZ#!V6sU9lb`av{e#7OaASc|-w4N$2*yYySrV%(7&{ zRT6uMQU}$@3IJmY-1Yc@vy(la>(+1t#od%KL@!QqeH0cs`}WX$qbio)V#-M9HV6OP z*fvT6C}r1f#i8!>+qxHd`h+(==1c<*SR!i*(NOC*xo->Hbu&z?tXxQcNuZ)c7;yVD z=L?<pxTHJuA1~^<0+?@!)W1=Kga99MPtuOqUW8t8epc9i<dN7ZAPDu!Cf^q-%axzH zF(~|o`n5sRo!vVTx|%Qv-<zn7t4A_)@b0<0l&~q)S0kT4KL<XIFsO^hrbxAK#G02n zIS0RqFMUJwjh1|;rU2gQ>4g0if`J=;j+W|TIvx9B-E)&<pG6(kr8h_B)M!Au*|^IJ zAuLZxMz*^L=7Y?jvcNcJuB9z0dh8H^L@Lz1dzW5eHh$cJM)#zjf1~|GKB4WEl9C8m z)URL<{svUl6BE!Uo#Ei%K%EGF_(w<K*T1s%6Cnj%VIkk0SRiE&;<9B1b-A+~x8K%$ zA^_CAPbHi#Xtv;pP&9x}nr>N_msgQmN$VySOZoDLn}vl%oL9?vHKV9;La#-3aJS)> zf~<)d_>Z$2!yx>%Z!Q<eMDzW)Y{{k`ZDXD3oUfltrm|<3TXk)FPpMH6*S>zOSZi(S z_AqqYAbg}#aUs6RGT4(-(+VAk)eEz0ATPdzE5c}-nr_CoWQ;rwwx7fqs3=A}p=nf{ zWjm~KF2+~}Bm9RPI+S!b#fuG^aUpBt63=ZAR<p6+TAP>S=(qYhD%$PAsU2H1|9PtF z<<*{x)4j3@XZDA7qO#6-@ecfvj+9_QlAX|4p_4UGwmi^tV{sm6<A%mqPZ(i2Yt5o9 zIf}=K-@~-(z7;28HiX(B*~?_$50z^Iia7gTqYHOdYftxm9qmUc`k)xOKEJD}qE&dM zs7pAD(o~nqMll4o3QHK@`N!NVaM5PxH@e`_<JN#C`;1n%>DbC{@!_tET-*i!$jhi) K&XvCA^S=PiCi?~e literal 0 HcmV?d00001 From c741fb49be493c215cec25ef992f58b92d0d2a46 Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:42:02 -0400 Subject: [PATCH 494/739] updates --- .../running-codeql-queries-at-scale-with-mrva.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index f8b114e34f7..6d3201ef45a 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -156,7 +156,7 @@ You can then insert the ``new-repo-list`` of repositories into your list of cust Using code search to add repositories to a custom list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can use code search directly in the CodeQL extension on VSCode to add a subset of repositories from GitHub.com to a custom list. Note that this feature uses the legacy code search via the code search API. For more information on the syntax to use, see "`Searching code (legacy) <https://docs.github.com/en/search-github/searching-on-github/searching-code>`__." +You can use code search directly in the CodeQL extension to add a subset of repositories from GitHub.com to a custom list. Note that this feature uses the legacy code search via the code search API. For more information on the syntax to use, see "`Searching code (legacy) <https://docs.github.com/en/search-github/searching-on-github/searching-code>`__." For example, to add all repositories in the `rails` organization on GitHub, you can search `org:rails`. @@ -173,7 +173,7 @@ Custom lists can contain a maximum of 1000 repositories, so at most only the fir #. Type the search query that you want to use and press **Enter**. -#. You will see a box in the lower right of VSCode with the text "Searching for repositories...". If you click **Cancel**, no repositories will be added to your list. +#. You can view the progress of your search in the bottom right corner of the application in a box with the text "Searching for repositories...". If you click **Cancel**, no repositories will be added to your list. #. Once complete, you will see the resulting repositories appear in the dropdown under your custom list in the Variant Analysis Repositories panel. From 112a4adaf248fe65d333e17ac6506e0607b0df7a Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:25:38 -0400 Subject: [PATCH 495/739] update image --- .../variant-analysis-code-search-language.png | Bin 45562 -> 28847 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/codeql/images/codeql-for-visual-studio-code/variant-analysis-code-search-language.png b/docs/codeql/images/codeql-for-visual-studio-code/variant-analysis-code-search-language.png index ac0a7d3d5e951dcdc576db9de2c562d98e1bdd31..5f2eddec6f663cbb91eff42bde8be44a4db296bc 100644 GIT binary patch literal 28847 zcmce7by!qg`z|2J&@*&145<PmA<{WCNQj8iAt5Ca(j7yW5>gTh7_@}I&?QKBr*zlQ zXY-xk_v(Aj-{)|xxn^IRz4xrO_FB)n@B6t|n8qUoB79nW3=9k+B}If51_o9w1_mZ0 z=r(Z1Dx^&m0|WoFwXCd$lB_IL<F$i@we1TG48^c_Nw^x1*C^ZTJsm{wut{a&NIeo} zuoUsKa5Q3x1!YK~Z^5^uTcf!O=bnQhm~=nxW*g(Qgdj~#AjP9N&k%22N{nTf4U9qC zDEFOTqWqRU@awc4uaz37`V=S34;t>IO0=ptP=ho!qJtBQww5;Dy-N&&Axw&V%%Jw( zx5cuuftW87_I8fvdHmWIxVuW8UteAOK6v4OKY;{;Jp6S4G$Av3Uuno_pKX8(BX&C9 zzL-;muZ^2?@S{~A=Pc7=E*>NOVvu8--(DK>KJiay43Iga`g?4Ql(6+~TOZQrp_{>_ zQMypl94_f`7IAS|zkSWOYW?)uEHT5DY!@0FYYq>{mL9m*vI?uGy_f<?WUDICI&@y2 z3SCux%<E)7xi6od#zh2@&A~tG-p;eY?tGSZ|DJigT)^Ii<D*0z#3Me*1hR*nSQ+ZE zUUm~-=ae3ipE@qPlvY6!xVjICGR>{!lf8-%cS6NG#ny&Ur9+C<8C*+0H&$2`5bCch zIA4yiT7C+_Ra<_w^h2AHeaDFN_#|UuRNd$Ju$!sp-onpO3pNGpj^3Wsbt6s-_2KTw zxD$5p8T!#O;^zU|vzh%mR_m;NFO&E6`n}!6NkzY8j5-RwXYE@iHxUq~n>S$6K#5%L z7zY?1CXrw~YifOFhC6Srn5ZbH)cH(R(4#p>wJ_P?LAtf2nI%cXn0LAx!whfR4s%PD z#K&)^gns9P{r&y?kDtf#VYF+cJNqc}Ti^0~dAnhl%qvB}Q--cyMOO+-*^gMjkN7^u zrv}n7OpdwRwSI6AHZv5fCE(PLBwku%;uKa)`1SVb2e2)co;1xE&T&BC97u?Gz46&A zh(6{+Dcq`CjQ;k0xQ71ByO@zu;Gj@WFwuaYGc!vER%xJaEbbBkj;x6W7dZ)=w5j54 z?!XbLU=4`&?JfV$AI$o!S7FXX>p_fC;(Zv0lxJ8h_h~*gPZaao5|tSX(qk($9L%x0 zF{j;HX{4Lesv?yj9BrhUr`u(yqVvHaVZqRpqDC^Bh82T}NdsD#!;s|9{K=tgifmee z0<do#+_`i#2nn-S)U+XCB`sAZSoh<oB`laNa4f_>5jue%hgvsIH60p<+@CEW|4KQ6 zwGqB-YF4Z?CO76~i{~nNOn%IFOk6>7jv3m_`-)x2QXhkdGATeWTrXzQ|4ZwGc@f9D zDiblrBLB*Unnl@NF)vC9rg{cnYG2IR;GJe)7$?{n&lOuzhF)5=gY7Mt7}7)b19TY# zfxWXrIJ1R-aa!0~qFTIL<QLRTnH+<1Rr#2!6JUyWa))!Zw20RD)_B*_0|Ek20TE5M zIB`vPgSCQl@Sjq6kV_;y>G*9<?9TH{env_{${r>Ot<TZmY$Jy&)3ZgC`fJHmBixlw za}^(#Yc1WyCx3c3@!rTC*E=X3*j<`CCGURUTjqSnnXd7pKmh2gr~>-CF+T#HKN44~ zQ((~fbZ7EzC}-ZiqNftMUTUYo_=c^ztxx4X#OIYhU5;0V6J^o#2?<Ep5!o?q@qLSl z&Pna7J|y>Gz68~!OXPmeUjIP*@rUkr{iC#(4{w=J^H)U*w8^(Qwi&chJ+OOF@m|9& z{dv^$qzQ#1>vh9*nIo*D=SQOJMgqySDB1$r)CcPiGOSDmem$_X;Tf1JaDV3Xiq`x6 zq`*~qfOUJG_)x(2?(a?Ii7&T?Uk=iajPxImCR#a+qH@LaoBQ?#l=|<C2p92xP#HYx zqgbQdFzoa0)P7N#V%@D}LExmQt^$`*|5T|^WZ;09MM!E%KCRce4#Vv9dl74;VcTbW z-#p(&Xz*2v$@h6#mTX8D=eSj>=9hj2GqOdi#qVuLZE)2gwJLUD_F?uIwL70OJ`t$h zQ*%h2@7A>_un_GQ={9jvI50nWeUM679Gno`VHzs8;=Jjcw6?JJZgA&WJok9wc;axP zxDMeL<1hMOJid&Mgp4?jq<+);RzE2;kvqOw=5GGQl+G&EX42|>q-QGH;i>(b$qdsS z%lZLS<5g5(aA2QFUbDBt`$g6E@6o@aXVcQsb00l;bgL(%XRn8%=S0_8hto!U<1@iX z>*R}%UC)ww3m+9eD{MEoeqH9Q;v%|qY#P!@I3MZF?=gKe?Y`|fRU@9vxW`x{{zLpo z%st~>MsF=)Ew<r#-PyRsCi$_+v5f<rL&3?Nof!J3J+B`nkSr|jJf0ie{<1)~ruX}N zNPQOGSv29$G28E3;QJUu5Xx!n)F56cnAH1iffz>wmxsg_4~83z`wmB(K#(Ny_QRea z%iBFud<T16InNfJ9Wg_L=t|j^l=78UoBH_69Lr=alX`s^E$Aw^zCK8!L_se!(4n9m zWE3O@rpEFj?w6*rrc=)6Yzg^u1eM&IcHMTam}<xuntS1P$mVvr)~y)2j73q)jWkqs zw9~=LOu8kX!(Oe;!Go2&Uy_wl)|d{BVQ#iw&KFteqFS&an}d*lsz%)XmX+PgJtMqY z?A8FxteRrQvCP#B-M461r?|DsfK;jFYo+}UNS3=~bxL@O<L~x)AFv)tty?{Jer_ki zEG}_bt}B;z*S@o_Q#Y;uPD$*N$`7g^JX1ejDblh|XX3r+>9Xy}&I!~^?bbd{_{uTK zQX_Ugn4K@jL3s~O3AfiXMVU{>U(wg686}w}?k5St2lXmEp7p*y-WR|3fdcQ|`=_*D zyY<E^fBFtL4(ARReDUr2-pT#byPn-c%`C%p=5y^#=7sO)o~PYOzi0I}DqKf<lQZQc zD~rmED!r#qu%sK0WKx^rn~FA0H;S%J&sEmoIdr5C%N?92s+`E|6Wj);e`TbSP~M?h zCO@)Iss31){7hft!e=Ak+o&?Vva217U4q>P4-t>un0=M^;BnE5&KGZf)^*w3E5AGP z#A}LqtpEF<jpZ+%ErZ}1)F$N?s=nP<-Qc6+i%!F-na#T16S*y$%XddM!#=+*gU{<3 zz)Y(W)UL%Je^!59j~&U18h-WttH<2#R5OEuSG2&8?#O1riy=xz9EBGOMvM`Xt|xAN zd%wxPl0D#vdZd$<oqjhza6NH|XqaR4&BGQ!=L}-8>8aHbxAn;3lv|cZJ&Bo*#Vhy3 z*1Tp;`w4`pLQ+}P0;v*sjs@XXKF)W34{Rllb8jUD@)*@Eyjj+|S98?#<m8KGQMI9{ zce+d6Rmfn}55e||$MwQjuAiq1>b5@}{0bpXif-$nNnfcEtKpg1uXb4$JUNaME!%dU ziK_Lyo|*ETKEXLL5>xct{cUpG9H;Pw(Ts^oEKA~!`{$$b{WoQ^HZ|!#dXLbD<>Cas z$N5RK=j$=ulBnZl@jNm3+UQo1hsnvprr)eodzUc$+)&9ditzV!!G&e3&EP1<_5Rrx zJ5G!Iov6cKtCL4N0y7M5JG&@%A!qbj=phLU6M=-amk2uLsQO6dFzG5z&S=j_r9Q>m z=7RC?a?k2)H9v@BIVuJVwEoHzhT%YhAr*$>H{#zz;>7-Y%`uQ2h1rI8!I6<%-Tn*D zk5(WuN-m8ZBRboD6UPrm+b*9Cf@4fhc6q-(X2=|DCk*u|**vDn!PWcy4ePo%jOHp7 zbxqT#`viBl7Y)Y{0pXbzN=E_U)%Jz1l7*TY#$DhTgn^Aoi-7|iVFDisOuB!L<uN%i zZvE#x76wMBH3s(oT=NL{zWIv<J~#LL?{BORSpU5OtM<dK{~lv9-dxJFOR@`m;k{CP z=7fPk$#(O>RMKJvPD)`YA*8k4Ft_S(lM{!(pVTGO{Ot4GQS)dIzz-(^L+;6wMYSd8 zI0$r}FTbtjm{lr-3*X6P7aqwE8<Wx`CkW5a&-eR4E-mGeG?PpCg4%6oc0hbaOpKrK ze((L|`l5~B_MSy`$2&gGSG^u1GjFO-4_27M!b=z=yoBC3%qG5q`!Gg-r^1AQ|0({1 zav$`oUsoH1E*7h+sPIRR^MR`!v*@T$(wn6uY(Dgb)^IEs^iPpfgCh0Lh}t(HHC7|9 z(&AE5tc8VzUFRD7^_lKz=g(18L;X`D<Z%DKr!`FqjKU>hbdHLsp?UIIyF@mW_?fF~ z1+%lTy1IHVMQy8>>T7jugw&rB4U=j}^xMu5_w?$T!){brt$aEBna8yN@jfsdg!KDU z-XgH9CfA3*)U>G)G$jt*hSeyWaE8TbOGNy25i5(7)I)BN{s2vrW9iQy?0=dARFf^v zkH9d<UU8Q@EHJkB?|Q>xsr>aDQ=j4({JYQMRiWQlMd7n@QrM3orF3I<Tb`$9Ot5v1 zX0wu4-KUZLxQd5;B{y5<L5>L#qQIib<>!2Jq7DB14Ma|aiA_xB`|8fc8#+V!$6ykx zq<8O@?R0&Li<PG`n@Ypd>pV|>RR4T;kLuGnsU5+H*a?HEE85b3y#216it+W;W!prC zY5-p5W%iL&U6>yzjnF?b!8%tEsJ5JnABA>>-K0gCWpBlIo6#Su)+1k2j@E~})<?dj z))c$?7@92Boy?S}r3#Ld_@ZUIIyyMt!fQ+zcETy{QNG9EG(y#?CEssMQmwr@+xQ-! zdT88CmH5=idpHqpWN$ZF@qMGPrm!!=%qNp!`aA@~NXW7~+2mlQw^DSwsu`Vj*Em-_ z6!ex5>*qW-O|Oz+q6rpg_<_yHnB>(SiRbm@iTID8jx;g%Qt>PFB99-L?~FWv6(zhc zk47uJ&yRC`a}$PR%+xK&W+~x@w(4SgL3T5><2liLf}PPZqa=3uWlk%PW=V16_#{cs zg$>ger`5}oMulDX@8N8%xVf(0at!WUP$4mLK0Ddjsa^EKH_d~(?9-8*;ENPC6+6|U zqTfiO^}t38F7e~bv=L(mvl^WGk0F>4&MWNK2@MO^gIrhkU9u2PJ#6rg8rQ8-J%_qs z`}#}QS)rLa&q{*XT?MN72+;DcFkAXiPw=9TKD`qh;c;3ZSROM-G+G?m_sOT&{}O1* z_}S5h(@yJTTTDS$TW=%zW{Y>k=yI}zjAUBqF}jh!X~8GxEbEb5)+1A<Ln<$jpbVX@ zhEU8&>gIE+K=?&He}7V+I?^ZfY;)1<cN&(bvd~Ea>-8?%hezomuKjXU&o)NBIR$fE zF5<e%%<lcp@@;FiS!zDp*b|vj*_7OSF4TV8EXT)7Y|1hssgGTs09CwFhS6-!RxUbo zKrBe=-3YJJ$R|4^^2T|jpBH2ap4dC>_+qdd^#dIm)#4cHQx1%GPDbpv0~%r(fwf?N zF+8X_vU}w7ldg&HHY-?xHW#^<flL<-!MMI@r#UKhl`|e)I^UizA3v|KwU!MbECD7f zgIT8J2#5*R3b1--X6+n#BC5y0Snj3}K$NjRN?X;mxXOQMJ<zft@N%f*{A?*feJZa% zM}f|oa#Y_bDsILvCaZ6|3tnFyBXQPopdO~fmly#@jop3n*;#wKj~$gKu4%8uC&OAT z7eP6La^0HX(LonvQmq>A9P~=Q$(*Qka7Z%rC@?as^^$fw`1Q~Zm<c}hZ+2#QG9KDb zt*&7Xxvv-GMQ&JTxPO`r+yHLcaoC^{u!<$1)571y5k%f?;V@$^N(i7{l7Kvmo-DUE z`}X|%>z+|V&u_zDp7w71O5tx$i7iqs+&^8(-0?mTlQr2~GHia+8ct!q(}>F?kkP-K zWVGEIi~8M@zOfK-v59%>w(iOHbo#whlv!J33Ggz<ftfD;G1wB@_spdG@OmKv{`}zg zugmfMO*eT&f+TwGR`W_?zh&65L;Yoi-Sm%PNry;0_Q+JhqT2oNbA?Oe#by%8LrdSq zsD~n=XY(nII1-UGm`qft$P~Ed4(hyc&sJ#VK;qS$)FOX)Z!UU{Ad>(ewfl?&1vNgc z<<>23uuIrc)vk3~=`qag?Xb-BwlJu1{k}GscW!yCAbA!SvyuL0rUZ^cH=XXzGDtLu zl3!$TuMr(K`w}D>xTZX?>VvK&h4nr1gn<1A73Nlp7V>&Yj<~R3vACF5RR`^9Q+n7q zSWv|N50?!K+aczG@MI~(u0pL!5|5z6j2NA$>sN)(`DE~m{tOY9&jeEYe!UXswv`c8 zviDh*z{oVXepMe1S+;d&Jlk<Me{a>8?CLySg{brDoJ%nsRSifU`*&Hd#75KB*Rr11 z{TF-fOq01v3AJ`pMJ;BwEEB6v%^^fQAV@5-WN)#(hBJ#uCV3BvPopyUNzGsv>aiPU z#c%;mDc>0{%R7+X9TZf>KuAH9h-$|M;V#q!z4L2%nXZDsjCP4b8ZSi1TLl`+1dS9K z%~Hdg&_|<2Z$#1ll42YgL`K9t!YlMt%V{hvGUoA)jqy%F&w-ydKpwC5H{(Dr`>C4X zhjMh-JXp!DAf+~J8w9&4V?T8U#1jFN;3byOqh|?$cq2^^vp`4L4&`h1VA6s5o|RdQ z15;qrC~-Hqm;I~EJZ*3ERSB*cS}ldI^|51dvs1W2nzigi0|C6&Sg*p?aj$3PbWmOL zXeG){Vk6SAKU?nV*@{!An>)%MzW8EMh1$rFno6+#Z2ikrui%;x@@3WjEM)O_7eg;G zWHL{k>AHKL4T*BQ8k&z_Gn?b@r6Snwe;DU*@$@E2`e2jKbNlon7{eMgvB9i}P4uF= zz`G7oh)i}8@<XEL5|K$DRQHE-!L;+BS_n7?8er(L#un4fOe-@VBPbIjIRTQ)c0e40 zwMZl{iV52JdxV->nKkQnymvf#Xm@e40;^=JG?+v|xGk6{sL(>NAQA&+yp*w@Al5|C z@8?FW+2)pN-oBFIS*S3M+=RtiDI5}unhfIwjUyo}UQ;0Y<as(xMZ`m_=tUKt>K1RA zrC3~|7>$5@yp_%7@AngdUg~RqgdmXwiy*wiTKIf|SY$X~$@wL$sG5^gj!8!{f3~mL z5~NCt+}ZKHt^wA`U-d$}ss-(ByxBzkzudyKNxyU8D;rI*d{!3ExXg)>SnrMPRR9|! zoa?VIcRbUf63x^!lD#DJZ3iI)uyi<ymp!_c85@#)y$`=$FnYZkv4I#_OAve&9`SV3 zEOlcKtCC5cjKc<4r_Z^Xz1K<W<dTW$1iOu+)FkvG#l_xatZ-LOEo2%^>_1cRI#~8E zX*&L$>TtZ$l8QJrJ?>zMsp|VpK%zf}c8HMR1i7LQ*n&BQP`k6Z*F?-qkdZ7xMzJwF zvp_h-MWxaN#AhxC08dhTFleJ*ZANG<#NQ0G+n$kWreq{F2c|&~f`6IQNqALVFa2b) zL4f)NTJUjr!!cyjU=1>O0ZEGNCt<H|Lt2>JgJ?7bZ1)fN7ii<c;q)vb1ysGbAH7Q@ z56h)(!E*BCq$zTdu$K!m{OH6gOI75O&*fP)hV0NHKNfc880VpEE-@s;2q}4H{)7PE z4E8?Us*xR~#k6;;H-P+1N|9L*5(u*LlGZI-k?4j<f#gt#SCP<_F3f&iY|<v8J&;}o z^H#o!zwilo2Th~wCXvQ(vCZsf5;kUDdnhLgi^(m3Hms8Lc=_X9VW*m?UyD74)qA19 z?ugS<!d*5T-_-~t5Yo>Y*|{LwUZ@4s?V8TxNER=~UGb7R0<#ZHZhL8abuU=mXgE&x zqGX0rP&6!4)$PJZr=$&K3dnuAppC;{@{L9ViqyBZs7YY&&p~cIG#tIFp>aZa5_B$M zNdDUy!q*G}_ETd;p}pB}KKKIAHk<+zZ^raUXekmzuL1>8w$S<>LKrSIf5%ANA-ph; zNyeAVgSDVpRI?Z**Y-oxC5Ohci}NH-AXuRHuQKU%VXu%7!F|&bDk=ex&;(^Jv;|p8 z>MiRA{ahR-WUShL4@82PbLtge$$ocy7{k5YszUvyin5;Rf`m|LMJO#)@N}!BoeF<I z44mKvX`~VgMv<Q59m_}#HNR<#QDjkO@XF$mfe#VcC2SQm^XEd%W$V+L-+6*68d&#e zwBY0!;{7^7uwH!W=wuF~)Tq6A{>4_`4Dri;xOd#KUsM34SIjw`LnuQAZ@o5DCrl*a zccW#9BA0vZVJMMTYo;-QQP^)&V4a%TJ@z_=<PYWXoV(#|RYy<XFEl383v>THwCu#7 z%vUp?aSVXj*1(20*R7N!zDvQth>gVX)rHV5(UAHtTCRZQU;{rx?n}o)Nzu)b8X(E< zX87~XOy(1<*GRIDxe{crd8+0D^!q~;W%{7x$nrQ>Kd8LGZhIyQOnc$1BJhCR>qP`r zk9G4BW7}Rr=0yvR&}gRDekYckPC>*R^FVv=H3ANKaM2wJy{l+4#k}9OBn*2!1~o<5 zj+aioMb1ffgOTV*<T2b+EFXh9ge154I|=#~>}|k>_hktoci3Wp0dc3T!O4$1&a%)c zGqXpw<*j84<ynt|EjmQ8mAxrNA`r~>{+D<LjW<=Uaf}rY#BJXsEIQtz(Gq(SArfZZ zd^;{8=9Lt>Inhb*teIo8WTiT^*FgH>1F_hg+wha8r@Xxx^v|wD=eii;+<mywCS2SB zuIP{=uP~Me{y$7e*^IOq-RAtoy!{z62{QQmZBd+jw|h<_cirdT-$Z~;)>qDMx#rQ* zh7nQ)Y<?P2ub>i!o?G9iXjYIg1Rh-z#@<i$0}wy^R4k9*eL3*eGTe7>$}mWZ^MaW} z%};W-JDVdsq(hfNE~=B|BmAl_fuPgHr-EG#YrYHn4!fOWbb~agk189ZG45+06Hfge zq+Ur)3QUoUJ?{^<Rn3+)9`KdMH@)o`-oQ#lQPM4hq+JyCX`uB4iDHW{M5By59Csfe zE9VHvZY{>iXW$Bd04eC`7%K_0Pcb(I5M{sf@|PAHWMoHjp|GJDB@FAoA4nwcw%#u3 zRK^EMZQhR~Oubl&o+G;Y{enZkoe`oXLFN_WmgrUO$Doh)ij!$Dmql<dW-*>1l^=t% zk#-r}m;1{BivbcGwi-#j^WG=ZN$0`0GpPwOO(c?*;ue{D!6oYJI0ek*{<k*s+mq4V zd(YU681{Z0nFs#>un-l<W`GW>*Z1lm^Qv_R(H8fW#DEOoe%{!qa{{+BFO3^oc?zD3 z5p)01eV<AAb*=(#L3I9d%t2q4>?Mg9%<si#^c^Zp73{doPo18K3#fj;93m3>BbmHq z9Zz)%Ce!_y5JX_Bm6TcaY(1<p1G2VEB9VPkd(d+*gdapB{0%M5z%ItCNf7sl$+p}? zP(mgs$<mm~v5`?a?rEc-gmK`788)kFYzNyYm}g!>FaRTJG9rd5GkFY$2|>LTW(5lY z>yG6To3UIjT%GT{;U(eFHI*!9_J{y2aQNW&f_Pi2@|%O$3z>g*lE`zx7*7|ZByI2i zJ{6<*hT+%oN&KtZ$YJM!GM7F<cQK~yI?L2)c7P;ED&t`S_MIVF`UO3oU=M_S=j?LX zZ6{d&VP~89eF-No6XR@pvE5)!t^lf$^5rhVru5#&)Up@C{UHan_&y=}n~sZZ<4X<) zU6Ai4YY*Fg@dl*ACFjecd%a5LRjAulmsndvOB&y<&}EnzcZ%bCZjwSmILM}iR%jX% zjGpF`O|)LNTT<id?Rkn&{)f^0l+#RMxoH2{n{*NLTn-!Y0S%E7V>U-Gs!80#(d;XI zp+c1k0$rUilkhBXt2V*TLcyQJPms@<=@o-NNMJ>Dz+9`NjbRGOoNT^hfoefqlGkLy zET54WbJVFr%vj-e*f>qZHG56M67zJf*6N}y*hgdp6_AdxJf5pX4j*uw+)y9YC^bO< z$Hk_q_f=+yw@({8Z71#L@*If;`aM}DkXVq7qNWsQKZh8aCS7EV<jyUVQpS^AoNa%c zCgE4h64iCDTBu;VUu~rYE;Bs0_clx}&}z>yu1VT-49hMGVhp_4_8Bwo*oIYvSawih zT}XY!VV1|H)eJAT@an`ro^LF*1L>fuS{_>&`|GwEWjwqzOR$94E)Zm@XYgail4B${ z!Heg+Zln5%uj47svc+BI!-=wc_XGlW)6n`0p6IWky^KwX$B4A~-j(;g&?7Wqb0krH zlT$m@MCeKcQ3mrh(OycH`q?7QZuLha!M66I`(jBN@bM~VHEhJ(AtZKA+<SAl43q}O zL}2(v1}e_c?@{*z@&+l^YH;u<TD3FnYXlgq@3z-K1<6>P(ZLM1tTP0c8o1|g=hU;| zSv=?WqmAJ+3bo=V!s=gRqWVI3neRR;jIf!<xs807UC4DHmn(o!5B%0}OY)ARQG8Ue zkFm-SrDLlK9BmrV$Bs3_cNQSS_}a}PY_mE#s#cj={o+*fp?;|BuJB=_@S@VO{^F%E zS*8*hG~9R8;7zp^iEDlY_gQ#S1FL?-IjQfXMoUy0y+hg<zE3DGn+;jU<JDB&5Q)XD zYIRR90(z|T-BUclvG#Vqbhq?Z@W{}!)A0oq5Oo{YIG~N5XPN$Dfc(aZg$1I3rC+eB z4}qBj(Xi#fhu#ogV$(J4Dd`I^^HP*ONYQqHq~ApAk<8GE_8I49MKN>sBYQ!}&wE9+ z1EX$_$jgGKi#7oX2q~orbSn4VfprC-gUiXFFvUVHNoleymSC18Y^snkqFV?l)6BG| zKJQ7^h>-JcEdoQ5)1EDocer!!HUwTwF08Js{m#7t)GTEl0Heg8Z!T2>)l~vZO)-nz zK~8Do)%1~go_#24A|K}9J@iVQ<B(x6dfdutgzNnHMzYgVoLe=oCwFBXyiw0I=s{4C zgRTT_E~bdjnN5dJ?+^ydJ$Ai;Ky>~A+yT#~Y7-@IF8rrxNMTh&W)?0U>tVKMzx;C^ zxZo8bpulyVMJ&B4_*?ZuN?F5VrOm0by0ipHYd@~_zvTM+HgHGO?%j{lOrXD&&H+WK zgc0S%$HU1$RsJcj@f3G|XZQL4Q51n^vjPB_HuG~E>tB_ORgnsKNEJ-{&z-=5G7HdO z18D6B?0^4|K34S?fhEJvMW}du+w+ePNrZj?g!rG<zIqO#5AzVGza;xso@#j~c1|tg z?e_0!1=|yUFRtbBVEcbJ^d;!6I@~hqa}s|*nS0pGBK}NAh}v_HF?pZ&cF*GGhP%eJ z4vNj6{Am$lt_1{rH3-X^tatfwsZzhM!>m=&iEuy#P&w9Y_>JeMjJrOb{VACL_#@eY z%y;0m|7j957<*)^qvZPFY}EDmY3SCJj<xIkm9d_Es#?v<TcOco$6uRA>g{m8JlA|y z+YTF|_`BVJlq}m!_$4L9LhppJqWpE|sF|YAgGMuR`=0rr2oZ{ZL}%c@-&6)#Uu^4- z?Z8VDI`v17zWEm!`>US;CyH-r#NKS{PXdA{-kZYPfBFyT$k>-y!7w)__a%s4orlY3 z?|0sR)dN^}O|bH~+}27=Tf_U~!NI2MLAW3Oj|VXMo91b~*`Bf%b=~afwVXarY)ItR zvz@H4TVVd{UB#04dnK`T<xTTe^6~L)eknqg7Cg?I064nX!eq7_!NzD&CZK`LC7-z) zP)qvMzOb~M{Pl3wc8n|X^;`qyWTivqaK0vshoiiY6B<9Ka%gO<=1mcx$B%t}^5r+f z=6G3qhS$E*7yateX~%X3oh+H)A!n{He;TXNghw8pt*Wkm5@tg{#p6uBHSxVHEsg$s zv#i&4rq<o{e5+C~fn5zh2;U@pj=P)B^Vs$ry%@7qShHOU{08NxHCWlvgiR4m_DQ?s zRmq7Gtx~1^v{-s>F^Zae+;}MN&%h^V_LqUwF73cL=^nf^mptuM{|d-z5<!5LOiMOV z^`@EV;SzDgI|kih%q;zn%I~H&=)wMKl)-W!vI4dyrJ5E}TR<qD;p69bav-CS<BVtb zkNquH?`5`4CjL#kV1QS1&`ob0Dp2q=HvZka7dHukMh2>U^sf+gFQo>at9F)(!*f7X z5#^7bZx+HOqJ3Mw(SYxm`P9fH4S`&AiKiWs`}3YT8?o`_cKNP=T!Q;gDR7Pc4T~l) zj+PxSHVLe|*zc-vT$HD>x0@(0u_>%(Kgm1OfNw$y$k<iyXP1Ly21r8)X-v~a-w;0$ zdxw>p`q06ZS5@FN{9fTJObLr_>QqTz6v1@;)lm^3d)}+rs+fE|8FCAIE-%yPWdet~ ztA8YDbF3uCz~^+C=O@skFV)45-ny&}v_2NpeTOwa{pBhAgah7>9P>FEermV3(7JsK zMxHg1qd>Cro^5)@`^13mzOkS8VZVYrF@OK0|1I2!>Xi(e^OK!QTqdu+3WwS4Bj1D6 z*|BlU%q^d|0lzvxeDB%OOnM7$Be>VH*-B+(`yc6&1M3=)1fKV1h>P#{Bw?)UyN<sY zsd?j2lyk#6|EGK?hj5lF*+kJjtax|t=>#BlI(*UjRtji+!e4-KPfLfxdjgCok8)CG z_xWI|iP9Hco556uLhMogoa``ifBB#)hgp>C^1G)$sJ*tUS8RX1e_&6>e0Dgf?s@36 zJJ)FMba{3p_<Bk4WF7#ePV>sx6j@=#syc~01~1`thw%~S*g|Vq{1)B2sDc<j*1MPU zp-djw=Vu#5CysU3SLYc$aoy~u=_THKtyCFZk=KC2`bJ(Qk!z0~soio-=TK{s8=#Q~ zD5gB|)(W{)I{GZM(GDP;u{n}}_W{00AB5=F5E3T)qm9wZ60`Q-XQ7f_^T~pC?_G9g zrtM68r>Y#UUNjP|G5s}uUSQ+1HARfc*cR%RG+F$5{{j%I4;8s&l0clAnm+?@2nhW> zPNv^@9wylUNepL9#g=j)2co|pAoX$kaBc9L@AZ|S^QuPuOqMKe&B=_X!Po<bnW<J* znfDj^XF0_jS}Nxw-}F3<A}G1{^Iw|c2R}q!No&M2dA8A5qS;`@s!c3>bXvI795U$j zFGa^9hzJ^fQ{iVpZvg`E1X8k+>5Hml=JN*fCN;_Sv#7c}KB!@@$Oacxh4%VTL4x>U zpDg1Z5Dva%ssm~u%K|f>DndNts!=yAz{q3mBV$P`F-qcMx48$)UnOgrElGa?E6oYp zO;>@&|10cIjQbcRl?5`yrjv=!90~idpCDoiiR;XLkR890<`k{KcM9}bgiuawnX)|( zWU^{buAAAs(^F0e1*C`=hgoOe<#Wa<pRv7H!N0XemIZZls9sKdwSFWdy}A4Z$UALl zY7O9bB(-uN%ylXJT@OP$h=W%-?@$h@=^&?IQ;UnRV2o>I2)`h{>%tw{V%7-)$u{MT zR~<)cBP6497<w(QImhI*57>fMc~q5>praz>ZJ{xTIe*tb4ygZ(5OsFYQl=KzYbm8v zn+DPi1^5)>o}6^Y9+@~~q$MCWmr>>&z0SH8I1rHaj-1w^hhV!s(#`gw<u{S{eSuLY zp7&179ARl{$RkL$#h%fAE@d9Sk}A|0jc19D^7}L=x*%W({)BjYK(@AbR@|C|5KS}V z02z9Pof8hC-KRc9|5->s2!J`s8zb&}0rSOcUkANLFGNHqco?<HvJidbc6ypgL5Fk> zX~Mr9CKKiP{pIlMl8)Sa>@S05%*j0g2wMYs$!;8s=Y)s~i>`=-6(H>IoXRPd$f0=1 z8hnn+GM5YY8`LkE6$B5xVdox4>+a-9ijHCi#(<_R-@~7s*yM(M<-|?i1DUpcdvUQM zK@V>K8VNBv5gPM<*z^=&J^u|0KWY7QnzK2CJzzn()KHHUf#5kpvf2(4HrfbIc0Lu> z_%MBhFQlOSbdl*gSrm`E$`2&>HU9H`#|1=ha4UNO*caW*v<V~#_C5mwmYR-C1Fj%@ z53m0{gn|;@2jUGZGnSG$$%TaFTE$l5rfEQ!w|ydT%EK#?Iwn}}G{6M@k!yBeIEM4V zy+>R|sHu)$A7`QFvz|NR=lfl7r;XiK=uj3(;@v<h7nvo|nTMCLpZ&aBBwSK76lR<+ zR1|BY{_b-wFy~tkJWe(dQ`V}4klH;9Bpd`!=&n+j|7G*kz~x<pJ~l%@Ohv9#d1Q78 zdCxew7OAlx@NC?F2!vqDej8@>6(wb|K%LM5?itICg-K;1lJ9VN%a^~SVCqO;{$;)w zz*Gx~#<RLcw@Zpms5+-`BQ4ewDE*A~NH3y{2-*>rdznwz7(F*j^flFta@~Rgpq3Xo z@=^OLh+3rs<5EM;G=5Y&lkb!}uY^~QFTS9BB(+J7LQDlmh8wK1NW%LJ{gYy7KIQ)H z<Gq0N7Ms2E8_xPa$jCol^@BcZw*KWVzfcq0a3Fi|n`g|}mf7*-VC7JS{DWxk`CC}K zE0WjMmxp<hM^;>9-RRDY4$c7nt3mH#HS)v<PHQn8=HO3L9QzUIh3C7t^WEx42<sG9 z`4%Bw9M~9Zd}LKr9@sc3%nBWB6|Mei(U21WLkA$<ORZ4tTW7hFL9l+K0e0PSzktkK zo7jZZF{9$n46A!b$Zl9R<cfJE8PDr$I)UsN?9zV-Kf9TEnRzULMk0Pk)psn&Ni5jk zae>3TG2C&EDfp1kwj~p9aUsQoKl0vTUfmxA@)jGbQoN=)#F^8wxyEAbiq(dkTsepe zjKG5=<Z>4;KSi&JqqL-I?e#B0Hb7E_SaC+3z3f|HU)xg(gi&dyQ@ON2#f2a~gDo_& zGhN&euYbY(2>h#<0456OeWZu5*Vk=#@(J9!Xj5uQLAur6FZ{py`OycB*KTCKzu{{d z;RC)1PRK+H1#|cS?h)HxAv2}nj)L2%_0?$o)%R;{qxaGuU)p|6Rf%@=8V=V!VypQJ zzft0)mCoTjFBJ$X1s#~TshU6SpH5)TyGhvpPtmxK6&ydHQCz64@@HxSb2L0d${!ov zB~)zse^?&KA7WVz=TI4lPc(ZyrnS<omJzmj&OdFKR@Te2p}V#^A_8bne;~F0prY}w zWBSQB7omYK%iJ6!!>RRiQM6AAj9pi%m$yo+aW|vf&$E}y9xWn=zW;d{01fd{@q1$p zNvr#$=e{w)`Kz?vooSTUYu|ehk)O`UCP5!bxhGCd6E{PoeUmZ%=O=~Iu|cb!6cz;d zJ=#a+SA!1B*=9iwR<UGtY7bdR>uB0hR@~bChW~2qBLe?gEt&v+9MW2C*VeQoTjG&_ zJriII@*kwW2$1t<E=T{XlH|#L*be@h1=)X{l~TH)aHN^<z5dK0fOOvn=o(gz)?X+R z>>sZv6;R14@!<4tj;3LZMOup^|1tc}Yx<8-1lvK$>*fBlziR%W0h`s0AX1s)PxuFT zAq@B-8Ml|#*48?OQ~hv*-(o)EK3;qVrtp%Ogp!=U-~I?FS9|wAxS21$zB_8eefpj? ziOFc8f$M5tmVV{n;NaHoeDg7YizgccaSigfXX?)LMXKKsxE1?e`&2$@SpWRDpJkWZ z|IiaaXqEI&fpm2r42gh2JRW~i<!vzrg3)G2oWqPtw|KN=PnvbApj~NO6y3_q`A8mV zne14hLCpxG589-wv$F&M{_fg0sqA9_7EaXcpllwz94ZEUA`^f(x}qxLvc6=BM%>0L z1EN<`h3&X0gNQR{N$n%^?$7uBJFuZx!E#VGh#@vDr1Qo_lHqe^4e+%i&3^stEM#Mh z<Q1AaPED_Z><&(WuUJicO^jsc8S@i>1K}$~#W=EfoFA^40YLL0i**EVQN@CPDq;sR z0-9;j>N`FiUNrPMAv^EhxNsB1pXlA&TpF$~{NwqN;=}4ZAc`Lr3$w}P0)TpRTQq}> z<mH;W0rhQukX(fZSa^s-D;&yxSNS={iaW)`V2Bl8J3`-D1)Ih*SKBynadUHX%7#9a z^z0*p3*^&brz2;h;H7bb;830+u+VPJUSH1EIjlR`ogZ(xjy$s*2QnL0xWx3kKW;cf z-J?}e`vl%O(GwX~u|tOAsXR4K`oU<yy~RF8N!dn@LMQIsc|&SZK_Oy0A>smR{Ty*U z&MZS}0#r#qJKDY0XBW4A(ab_jf91J!hVQNdkY4}q{OX92QpSNZB=ks?AKc{T0Xb-& zbDo@D77fjx@z~%7m`nyi9`J(30LW(wAXb++%JmR&J8<Hd!S|Q%2);!#h)w|5eszsT zuhRZI;F0L;5j#+=uea)lQI(}-zL{~a&ZagwKAv=#yf{5Du!6+hu&Hmrh}b5B*#a<s zdlDEm-?Tm|XXr>trlh1)0Ja>e!?C3qpehU2^hQ3XA1_aQuPY4zCc?PPz;6+Gv^hR_ zDLr&!=Q%g1v`;5cYZC@M2>=C|&@>f|e27xewjV2QWLJA{ZsdLRE~XB^Xfscjf4(y? zKVS=V#&1~zm~x%_N>6(F9W$9Bix)3Ws{q>a`{ev+V<pbrt7iMhhV3lM`}oE{0g$ms zPw6y?>x%=OkIEEuBF_1hdSw<-fc44qHq#l))&g*q>&&5S`Stfv!!kCNMD$n>U^<{G z2TTdy0j}6)XJU1BxF%>fA#f70;=A@SiFR>;<}dxJp_3HNWA0W;xo;h+A<cEPGds(! znmlJJh`^QQ$A)0-0+Y28kglu2GE30xtE-dxNx<h}&=-8RX&p#S2gv`xsO|#4Uc#zB z{hi9wSEX+5vOQIOJmu6o-V{t=AVlU*FYZykLdimV=THS7OQy{I;CF^z<g~cwu^To8 z<OCr2HBkHh?BH_+@6EY~rqMp&Fr*X=HO9{I{%q`HPnxikelAQ9(itOuoa}u(ZaI>x zME1q7?nlIIUWUidjRjvroGkTo1xEK4pqrd*#!Ej|Dxm9u*St;EZ;jv*1IHn)&w}Bw z6tfH>Seh%ytgVMv4E?%+Dz*XKs9sOr7Ma{Gv1mR;B7PWKnZ<;{j%1RY*}6}>IY-sY z#Ew1(>@Vn~pw<Yg8f05fBn^M$-XfK&;=CW^eD~|VY4*mSuo}zc|5m{bau1<ek6s|4 zk^q91$ldRlnnC%jGRXU=`4BoWWyO|52jBD5m9wi=1xb;Ygwj?JW_rM>6GhG26ig<A z$BWb;$cFH~0o2-O(?49q_ro>PgdDRKxFC;jsQNX)47X*9ZAJ@u${{&`J;|{?S)WR6 zo1Z-mvdjvL?33S|R{`%K?X$-~b2p}hoLr<jHj4{53aR!wDQt5FP-aFd9gL`gnS9V$ z5t^{dQ@IB;R9Nq=9E%L=z5?zL#s_k5S^UD12S|J%jv)-1Had}2H;k}~1W4xBE8cgE z1sx7QHQG7~YuINCtRO#Y+Ihvuh-GHHDDgFHEWWA#hl|aM(+$&u-`I<M9ZmLO{T^P; zj7Fy5PI@4J4@b1sIIk_Jg4?|28v!?f*OPxhJYvoqFIRt;bbfJVZKJ4urj=aM?!ZY{ zCNv-!wv1_loRd>zz6&H5vm3-=WlJNZ2Dutk%#+0?vgfNgF&84HZ>?Sfqp{8>e-h9p zZ2CU<M<6D42QL7x#2i_JqNkLY>2-p-gyVc??*%zF)d~0$Qd!3sdWM`uRyy?vx3eVX zJ_!mi8p>*kX})}wuH+R-;tvQIa&v&wYMLcizw67Z7y$^jhy=jhhvilPe`2k}HjCTd zElhltHigf(y!jZ{p<ihT?l6koN=^uG5Gr^a8^B<@063JEOhT&K7zxp(ev+zlvU3Yh zyEuPF=&q=MB{Xoi5uv9rX@-o45^#VyT;|!ieZtvObNSONP_Sb4+((uclBR?-)$AM) zZxA<5V{?n(v8pzH_U#hwFFM>YSN)8b<jPfVChaOudl#3y_aBQlc>rRD>(%Ls=aV2x z7?p{9qu|PzS+&4O+ef3<`Vb>>+k_B5H0+x{k!C0-q3dosD&G?pi~?tRo@~3AMEjzF zJ!+a(Ervd>1??}1Zs318)&=W3EXisrIKpj>|FDr-=u;ob(RkB?b*;P)!4*s3GE&_B z*VuRIY$5q?`$)P2nDj|{$>_YS=NRu0d(nV`R}efdyKw!{zwpwdAgMTzA-zmXoR42V za~>IHi~5#6$;M&G1JCLZFl^ZWVgwq!a7)%Jp0P2+kF^f7W~qR5>!Y|Ul5v2li9kA3 zE$G1lX=7KNo_%%eV=y?UyjjqtI&==^g1JY5pzl{iaKxFdQ<Ouez*!)7Y||<B0!)O` z9zlO{Qip6TtdELI*BCH$#)xa-GqJD6(b2)($Nf}*rNO|9Oj@pw-@Yx(i2gA(ogVnx zd>SWD`w+`XB00{0JhG!1`2eZ3@nHxs(6RI_UF?6|rSMlVeBiZ*6HTtAc$<)V&c`Ix zGt%F~J*t&%{V%zuBebEPxzX!x#yWQkL7d_M4cG(u1^N;!gA`*IWoCt>E%m{|!J5e2 zsyXSyxb@vo$&1FvkdD(O4kva)=APAiNdA58u$ciylMqfs5VJXC0%^2w*?B3aYmzi& z;*-(Nv2R`7CLBPm*<%i8*JdtXTS4Ia#EO9T6Cpo9R_smUyA8MGU&?^fIyd<Q*IBs2 zbbu^<cmr2H{61_pg(yq)ii@!07O{ILy7M5L1mUPSZA?lpF+hcCz<@BJk{hUbd#K%_ zk=E=KfPo~6{OwJ$I73UC;Y@morGZ1?bO;gYPJD=K#@?@qFH&LNeUmQx-$ea`Et%r8 zAS&j-WLf>-Cf?Ix#J=t_24<KQzA)-S^%{_M`{gLf>cA?9;G1OQx3_>U*w#v00g2<< z3igAMP|PDdu&@Z`DO;uhZF&<coPso2u~nHE`Fy<(UJ*u0)@km}y$O4rBGvk!g_^8B zU%|UAtcrlmampXZWvt_xZ6T~dA=Zf~OWo+}K1M=IfEtPudeQMj-cRyuHHVQwE@%*! zaO|<M%B9<U+QyJ{_pHapw<~%ysh<H#0IE+zCeaYsX$2aVygu!%wq_h^r3`qdO@X+d z&^Pz!iYM5Inkt)SMr<<H;a8AoTbN=V6Uw>Rf)^_(>?Ojhv*=T11kaDveCK$yoAX}~ z9fw(iM;Yf;uyeL#?}{aTR)EwwAV!LZhj++bXjFw#FE9p#KY?%}ITD*qKVnS4GLpv- z>3t*je9lRZ!gxygFs%syrv*6~gdIyY7rYl4D|2X?l+W2O4@*VLdYR-HX~DpbNL}`r zV4t<nC)m0=g!3u_2|maHEo22>f4Jg(ELu85UYPD{?jh+h*qoj`Sp{b#q%rh<`<v`R zw7jo$xkszRHM0vwCN+~whYMT0^0lhK;>>3&aZ?>tkTnTX&Gt4X(XAHVCQ8Z9^bjJP zR7Bk~6MxY5jf-Fk&-rT<K%9e#jOcf1=GB<72xT+w_0q~CErP^*c@A&coHafjU_{Pc zPu5?io;15?iBOZBb_~szNs~*AADl!V#rz>d<bG1h*zil3Jy;G&(ek1;$P);LPdO3h zz=W5@=;uLx*Wf_q@xT&AhVmGW1LiI-cYJqFtG`|~92txDXD%M4K9xi_iMNIQf_4kF z=k=+Vikyx|#_-ac@khqkpu3aTaP_9lrkDd#btPwRQ-WsCw`+QzzK1?%K#|Ad{<=#J zs4q{p-Hhq+FZ+Q6E*h-7%XS!uY`fhx7+0?<kWOU=txa)L6vuZRZ#oFFG^Vw+`D@Do zhca~e4pAq)3>Y%6$|VhDH|*V@7X{Ut<6ySo-v-HIKk=zJs0rP=I8zc#L}bPfclKJ8 z?y*j&{&u=}Zt88@wnHYptY+;{yBCrt4^`X?%NMc624Fq5wU9b_mSauUqpCJON07mO zkP<iEWiczAjHtZ|*2BKRf5PpD`*^urO?t_XG9tMVv^KxuX&cqg9WmeV9V?sBp$KE` zr9R)rqS48%2<mV&iAwS5*jjeql?zR?(~<z!J2vX+UUvRPSX=PkK5tYBO3G}9Xp`3L zDfk@nE+i5e=91<r`>`L(8hP+2ND`#qq;>yOazmtkYSC&f+BbfKeQN4m$8mUa{1PTM zu4NGZIa51E_V^##sm$mP(+jO!%8G0MgRY=hAN>J#Z0#0K8~A5LAf++@(t3c%q5FS- zrBn%JZLLrM6=nXv(wYE-=1hFaS9@dwq(-hL^m_gRG(gmwGY65YG<Hc5(+e5jXk;|} z7Mwpl`P6mn{;cp)*lAKfjkr~v1rb*6({R1or8k*RZyhK<Uk@4zA^R>})5p<1wkWpe zQB1eq<~>yMcl$fpVznAoh_|mU&u<7EkATfkzR8m>IxdZ2#Y<Nx?{iy#YxvXyo_3w; z*DoY*TZ4Z9>8f&Wy$ZKWzyhx)FE4M;V0)9k19WhkdLtkUSs9m*uz2~Z4&X&?rvS_$ zWcsXKuy8bPX=!=xvN`lkZ}evpJkzFTNkYe+=MP1OfkC;dyD;cO+p#%oyn8xdcae8Z zj{*I&@}Nhww{>lQxy!CQnb(jc6kIlH<Xh*mH8Fh2f?wl)VBxu%6-r2lu&e>B)eom$ z1p@W|wb7j>JZR{1`eO3CO;RTC&_2{j-Oe*$H-kP1P*&?kfTU$Fj$yq|-Q^svWHG>T z#xk!jEJaVIoT9``3e9Ss78$w%F1_a#78dr}V^M!E!C-$<73huW<dl1c%$=wJH&29i zb91_8l+pW8Gp5_{&9uu%y{~V~XVlS%-Ut9`zZlh{#P>T`7~OA@SDS#6Pyw*5v8igO z%Vf|lN2Zr4a)HO-M-`ae;~a1ud6HKs#4z%_UCRM{&#r@N51#?ArtT8RVs75JyC(rG zUjbxdbb(Ztf$iha{DV*?pViS4elPT^FVD(88Fl^qS-L%4qq3W^9xAo<&%{7{NCqn^ z1tqO+-;gkk8P`cW#(uT{AjhTh<!Mod!eiObvVhcSa1sA<w=DCr8|ag__iB}7=OhBE z0V!gn%F&Ff9N2KdKR^#&i!-kLq?Y;|5Jn7g<Ii>hp0o4`Zk+Qt?-64)QFqvFCvijs zWEBuYc89`+oqmrMn>4?E440w%t2%%@#P0tVWT*uJq*JZ1eApvMZ7x34Q20}<)_v;% z*7NBdA4`A+mG-2I>SaoJi><f<n+6PvZaCnTR3Wzvtw}dNaT<$TXBV)a;_FVzQk(D* zxI7Dt`RP@rC%IS4!(+6<HqT|*UF_^spZub~awRa0QoLNmZUAep0&Ag1gNtCH5#ah8 zDKS$>75A)A2<mLVyg2CH0*wEf_MX_*r2((lu8&LF8J*@;4wK*FvX?^)cogv@LVkp; z%>THtY5r5#l5Q3mh(4?W@hI%@cw@9T=i^d)yl59IU&S}QN{^p1J2Q1r$n79JGB3Rv z*KaG!ze6b+MQuj7GLw(HjIIU_0tzHw4sq`A*H=t6x4-C09B=TyWx(oW2YA>SgW2na z5LwlQ|7yx>JU}>$*E??_fV&AKvDJfXn0zlvrU88lML&LdGV74brSE+-oY7VcB!Xi` zO2x+ausI;6IxbKb|60ACm0zirOx}laD+i1_anR%xD6lI;D6_BP)x69}RHqXnJZAKI zZ*v3nci7m2#_~0Gm6~v2{zn$;h-0|{9JTA8zjzJfXpsOJ<pqdAB8Vm3??qQtZ;K!d zrLUsO4;t+#dck&E$Mwb`Fqy^RUZqdKHbk;w5(DRwm8We5)U^$W6?<XHzlC0@HD(R_ zUq6>MZ4Z&dpC4aSJGy^vMriMAfpi{0vAPC~5Dvl?ixTkku@bY;6SbDa)w`N{+Xn+6 zb`*1vtTf0e#$)M(&pqn9M@mP?+(!wQWal>T&4UFz+aL+06!c)`l{v6)=S$ICgGVEJ z;Dhw7qA#oVAHMx9$9rMX)O$F-d(x#^DLF+S)=J2pKr!<HTnJLzcfSMbsY+gwXd-8( z-*$?UF{i{-rK`}$S8pVyi!;^Y;LPFy@`0H*LZRV_^6UtUjH(eLJMaUspse`6Cxe84 zWXio0-Sn6JUp(pu-v*1^MOcALItg)2p7(i%9VLv%5G<J=g`rDDux03G_YdGHM*rHu zr|}wO4j$&tG%Q?l^9s*^`GwIRxIWZkWOY@C<iGz*66EEG^@^J`-99Y%q3{E{0KECH zHAnfOKi?fU_uRem(1A<j1Cc+98|NhU&#!ablQ9N4e^hS&QdvMZ-W0Qm(*7?_m%{$Z z3h2Ikr(+MS{<>QfSZlj_%0?9bib$%YfMY8m#vt&IJpKRcf&P)&F(NE1%|I|*nJ(__ z>FM$Q<`9feu?eWmJ{gILzt1%|&`(fa?vlBN9v(kN^LnymLtk$N{h0XEl{cm{nEzXR zL+tf|k1F1xua}U+z@`|HH`})F?mj66{3)rtW+8y{r5P}T*fj>=@Pq)nQ>=k-<s27T zd<p1p`b&aVeGR{RGaUfp{5^z-?l}<Sh<Kw6{&o~$LOLR(eqzH--~4=g=NOph)S44O zwI_kJ`Zplrx^8@{{L$eJ=yPH(=@1)$g+jkC8jyr;6VtCssJ|EJ94R!|*phXo7QNZ3 zWB|kho=DmA+S>(x$xl$M7ypS|Yj|`I?aKk{z;i&9+yo326~IO_H^duY=@qo>p%>k$ zJ@^XPi7KoI*>848+(>@MTa%Um!7sg$wr_Tu{Yrg!VzmpL{dTj4wo*JrC(r^Dz7AN& zM*xdJ%pol3Ujq&SrSX5O`kduQ&Ff`lbxo=6_-HBGTiM6kH9LX>l#13+c%}8=C&q7V z-~8W(nly(1c@~O$I!p4tN}kkWZpBZE45xuyG5sK}p!VOO2mys--3i-`_pGs>7NPnI zn0JoxEToeG`F2=t9mpVvUsnK9jA0BXH(5WpRMp}fFdsxJ@-`)lFz+NC2ETt`<FO5Q zsruKl0mX8M081#9CeS<FR26_prPtsiCT3SIe_=3S<)I+1W6VzaUu9i)IMt8$FWu@= z%0&qY*Ork@pUAi(lu=~MNR+)YLRZF>m7PQqMfN6JW{Sw(v&cxYNBz$G^E{urzQ6zO z<B9v8=e*8qoXFLK6km}$i(gVK!0b0?S#I_GfA><U3p-KhJlDggA6I&b`A+Lp!S?s+ zQSe?&%bv)4UxZMxp5Hu|TR8Y^E_<MT?zP77A}O&jRDs|-Kn;@XvFB4%_X0_2LzG5D z=L5A{bvo5vyYs{MMn%{Yx&dvOw<lVc-}}B+VSp_{8-5EtEz#+|GBds|wYzd{Zn(Up z$ntaJcMPw&!(gfX<b|AAJkujU0dvaFxKf#O6f*WaBNU2(WAZ7KZk1qqkX(3B<fK#d z0{C5cgqiLF3mg7U`I~GkpTPyX3!Ym}?M;$EJuiSy^MipYjm%)Cju1^dNCrQnPg}e* z6W5?)bzPPD``*Jt4vapEpMkQBP0$0({r%tx_w=Frsvj0~U4vR1KMoK6%3RmD)at}$ z8K8@IQ;ULl-j1tY54$A)mKh3szB1D-ADR@Ld*H;O@u#JRe96%v=TpR)yd*+n>(5uz zWAm;;1om$c0+`Kol_}Ln%*l7@3J+n7S<ZhdyYX@6F_YM48+~Dpj93f3uYVdm@__<P z9XLjw(6Ekkx~wi;(|GOlgfm5j=hn&(WrAVgus8z)afzVzt+Ax45Wn%b%h#uit65qT z?5Y1b4{%9Vl#2hHme)Sc7;mp8YH86${6(pu(v1f$TA0pSPG{aPWV>9%>wKW+!QWqo zLVFS)+_TC}yMKf;Rg1{c0RKjb0Us>){x+xcam@pi|A{7`o@|6l58MklPy8bae5V2w z@fFEyA&NxD#&ijso`>WD_8d|ej8U^5ujq*Ua*#`bA0G8TMtn_`7!gb8x{3&v_}-kt zV=)!e$?{(P%V&AN@%ZlB$Hsx|0yvl+Y2-1ySFSZfX>hxK?(F1&BAs7QfT(|7A0+fR z(FSd0-b-UL%3ucM9U`U!;jFLv)!cjk^Li$$Wsu!4;DHd}<3Uth#3HH5Lh#7-Lyev9 z(X(Cs*J4IW#omV~4X1k3uQl;i?>GQCp3r;6L^qcBD&vxBP#TouY<Geldv49X1}mK< zVuqXRObxmMZ0?BHwzVEeO0UJIrl$G;g)AU?6lg<wK#N;Jj&%)mim#8RNWyS?)KMH0 zDLxA4difU9n{7zQ4!{XYngpR2Kfey!U9j~QTBO=<m~R${)B#b~rJFfTMKF*dy5sHd zmFtN`)`LA14cx>x2Wyv)>g0}AEqK(S_2i&Txk&?AhT03C1m_+dKHZjfYmhgJY=#G* z1WaH?Kw2tWT7bOg^T;^}^<J9;FIARN^#~M5=b;uGzu6M2KhrmitWi=VmesT+1B>yw zZO0fc`JNovCubJZYy-C=xs*C|eZJoms&b)HH20=k>2uhIfb_EihmR>P9dg~%F`rT6 z3)7Wd25+BT(@wc}BrA7<BwRoFErj*gG*1!M1a+)I@8UBFB<Y3XCI21zNaZn;C!$k7 z9CE<p!{>YCqW~@O!^`Q2667|E5-P6aL65-9;!5@o^fwdq0G-I4KJcemgC2$qud0qr zo-ZJeEeft3Q|CjdMa02~c+x5ivDN6Cduz0~4hdIWA<&%A#^*r+EQvMp>PPA`Rk!>4 z;zEW1#WdSAKAINsuC!nH84QA|w*#|^Q>;6ZwdTL(l7HaZKSU4ye$2n*lUuotj!t5L z2h4PCiF{l~aV|P|yri>sWUMAFVNtLp<k>Ks<0hqf7qbSjHw|v`Ygwpjv0Z+MR`r?M z{}=<DissK-?_FzA{4q>Mv7G$LG1E=19jNeeCSNue)#*G~v+$Q{kY;*JSsSFCWl&yh z;Jv$wq$dYJ&X|qtboH}?bqWi~L44=A-IY^_eNpfZXvi?J`Oqj}DpSrn&3vi_g?nPN z6s%gy-86)$d?GCnfkJOcVT7L$57%SQ32&2@L7mmCRi7c^t|{<XEbtAjr&t|=W-h;> zC%QoR6cpKd0+?q%5t|bJjSjK8sxo>YQR+WqmKqAxd2HHZSsP=gMf3N^aFGI~2c{+G z<j=C>DwWq0UnwNn5Z5G)%S;QgHwyEE-gf0Zvp9Hg?>*<VM!km@;8$~-WPeYo46m{( zI7Ay?|M+_m;VrNyv77}n!)tf9$R6Iw=O}WczXel?3t#9r=Q6lc<Wbc!$y+ZIbM{8t z``9pFC)TvRh-b_Rqqtqt5wtM!<1Fv?5++Fa&I{`LMR>jEAxyj6OQyVXl1z&h!p48( zZgEl)%l6^V!@pK4*J3aSO+1VIBhN+ju}Vq~Bi>RLg;1xC`0(&$nzw9klN|s49{d42 z63fH+#|Is+iS^;<>w=cPOigLS9KX;=Z(E2+SH~F6PbFYB<&Or0I4YH%Y1=hfIUYXl z>LlLvQnHt7F2H5a`%8dFsj74!X*7H2*)6eS7RI!*eo>z(bU5C?JZlZ&s(ZGbJlYl{ zZc(egn+RJ3ZVC59TP>{^com1k<b+QNlzXh(43;^**38zIC>eoDIoue|c{(93j;n({ zF=fv{eVNqEs?V+Fn><)v%$c_y<s!7Kt=O<rWP<mv&0^;{EqV~vKR&-WD*tWVVt5oV zT|bf)USF(SH!NQpxVr!-yLf)yil#+XYBOa4ED&D1b4G&^Y|2(EGaWW!ICpR>SU_i3 zefz&vK#`S#S6RzdeHb@6{;Zo02oG~882N}a?zNg>)IV1H5Tty!wHA)&+6CqxGcQN7 zi-J|3g-qo=N%#=ZP&zQ|X90I2YFvksV;yz-ny{Ahdn>1>%<*=-uw_J+ep%;SK-K^F zd&KeBxGR_Hk;!`P{s`i0M6Cn#al%wUJrC<lbo&yw2DeUo1$*>v_nT-{cb4@MXj>g- zZ&^f5>d}DPpT1UPdUW{cshh|K6mSsh1sr3TFzqB}{vM#GC^;!>m2DBS4_|(>mc%Ik zC`QGLufqUaV(``pSrae_?&nN^-U#qV;GJzDhtdV8o`{Lyi21S?rjB5=_Z5OMC7g5w zu~NKJi8BES`X`!?s;#*_l}VRg*kY{rB8coX)vdAoB^lXo-*Z$8xIq^8%+Ek;+<k<2 zL`>h%mZnAc_AZ*)&+*uywiQ(jHf`E)XgBvpJxdhsmcWV^pu*NTc@rO(C=dKw^^x@u zIb)xI$a((w()HK{e|npxA){~YU^8%ZmCz!7p(yYbXwZuzT-4Gv*bv@KRW@GA^Q~sO zMuR*r7r8O7K_?xIGvA$&?Gr4oOJMS-^5+Ly;~dLJ1oS47$yC`|#P^Ol8T>5)P%#Bv zf7IjU0*)l$C|=4eAu0Am?_X}F=>o}RnN^=E+<p$7I7v~VVj;JZ&kkO4PlHc__T=Nr z+hU{lKSNk`Kh1}fOOKm^c>mv(EqgAtG9Jzy-8ny+vtWKAdHo1YqeF4U1)rAN-kYsP z{|;*qFyE{fMsd59^9VI6b2Yz91vZQ+!j1VLJ%2npInIMw#AgMqb@%2V#4iR-WaA-^ z^&iC!A6Qu)|6sf!>>M7C$!gNmHn|74aIKz7b;DOkgMu(3C_rx9D&g16Pt{vz-^b$L zU&_eeH<o2>Mct;eiI33k<=;b-?#B?&X7m4STsbcnB3m!x8>30%+JfSbLMsO_tAue} z{aGH?91^?pt#NKvo9GfI%~NugIL&GtPsOTDa-sb2zB>a<E=S%aS`i;Ap(YTJbH^bL z4I`6voJD#z(TPZNBVMvsb;kX$c<4_Bg+L861kbRA*KZJiTRjpQvky}_MvU2?p#i;8 zy-0ma++Em00p<pJm^lz1?HCTNxRi+I?Iw=(aM}acp*+MA`HuMaIb@k8VWxp2b|&sh zxFj4#aqz8k29(F$(wrU14t2kh;?&gWAtpgn^dx$lYC36)`0u=qmDUA~Im>4FZCPFR zxgnV;o1xMUaNG*S|8p<<$D{EGZGd<tR2)|eVUY|HsUZ7+wtp5Lu0FQK79K)m1;j_l zGIhSP)ap~$o<}O<NnTyVc%=Dake{rSpk)|>lpMVZS9|<Hep4X#iz-(-mCs1<TNTR- zxU3Qdgi-^g%TkqN&lpRS(+P8~5LlB-pm3F846&6sDNMxa$crBYl5_8GF2^J!SO*+u zY@2QsS;QEm+J#c29$TQAa}43l+3rjBUUd8*HFfTDsK+zMU?ZF>pvuYKJ6&nxQrFYe zYQHyJJDo-|Z)R>jpup&9rh0L=aJR{OCjdtKHh_s=t%=n>f^-K}v!Z+~p*Ay<2MMth z*^Z6?B%G3s77hRkxgSIXYjiW1z;vOeBX%ys67Yd(0c6*gQ5pt?qYrW@b0+tIwE@&4 zNK=D$`o@y>um*}ymile*B__VA_3RY!sTqMr_Aya%uvsq~N^ejHXddTDupQwWB_Nyh zBYg(CfJ+NotZU)PS|s@LkLyy>mBb7E$dVwW<ndSUbovQRicba$=`%r7``YMlktlfU zQ5Zs?EMBbBCLZjPEJ#yEVZA|hYAX_J(gi+$7QS)b``1@*{ZCkK8a{oC<5C+*ykG}u zz}7kTWa{t{0*8<Q1Ro_P9euqRu3eWS9=_NX@>2PT4~ino3g&W00VU7mHz^DkK&eQS zl^F!BsSgZPnTTJ=Cho~P2(q8$IXkpFd8K}Bm?BZFpzb)K+XHFpFXv$+(UR~Xs}=CK zHHI;M$8G|BzHY(q`RU|n;IB^ps>er$E8HBBu$F!oRrDp!&o>~$a=~4{FiZ>C-u36j zmPUM%N2#VECKVB+jaq_$Stjr#q9ASD9Vkp!xW<T7$X6_vg3l!<;Z!i;1Y6wnmyhua zui|YS=;=kRa*yzp)?}AXkkO<w-e1C3ZcGI6iGw@tHt=N5_M6XtZ$9q<&ks$uZRKhV z400_jA5KSxc|dy1qwr+M4jiC+eau=4H`7(vt#cFc%R@t8>-Apr6JTx&{Phd`6osHi zl;<LL17lb+_p}5=jx>dYreIpr(ciz;B_9R5YB}{{h$|td1BraT`Khwvl*2=S0r<@0 zx*CcQRP>$%n-Bh=GauP__v3@d<eeh;9%$ok8ajRy0V~yo0Db*Vs<bdg_7ES%bLuxV zsJwmz8EGQ~i=WSR0!TcAakmp^NuFL07_=$>=(Y5aaYMoqvmwJ8TSzwF^wa5GWUX!T zdxV#8x$;yvua&R-gCBqLv+Mq9OK0Ok?2L%qloa?bs%GiOspq!{OLBHquo$QKPB%AA z8liQ#{NA=exTb?ACJX0w8PCLkuh918G69pp#UdD=H@+P&OhpM?-bR*EEnsF7PEYsu zz%Wf1a$sOqQ97_jkwVZS+pLC{)a9RZOc6n!KAy!YGc;-dgSJju-Pe5h6}czsd9Ld2 z^@3DJ;--hMAT?Y1dBH6+of|F9?tz#u&(yMMD5Fk{Z+wzFUUm~ljg<;~mT$vvc`!xj zv97cvdpW{5^$0%Yxr94utRfuk>}44=!y2#_`p@Fh9PUBfxyH_$1Z{{zOr1LG{E$<g zQ>Zozrn-Z4QVSMg3_BCgLhc*1VXEx$^jlny?KO$VOhr<>uwf>}Z`!I{51AE=G23d= zEmrN8ZnoilFIw)9%TVWYWZ_SbAa2J8sZxHVb}IYiC?dsxR5NY=D6hyOjET#s{`Iz+ z)rW8{<NT28WC))Nrj;-YU+-qfAO3}+LEcv=Jmdt8595fj)bCF*(M*c1W2b(!PKnj? zmA%8cj|bY~?q6#WWfXHJ_Q#Luk<d<kNNm=tzZ#`a7y)9o@y5BEJ~WtHT5{6VSPHIr zOexL;69r3{em0+-Jv`MydBVH_6~iUR6S?(3F_l4GKf4l~3Q_{(_Ce$tjM|p?G#-ii zOo|`t)xU>xj1Mz{>jX<v-}fTN)%RpIfuz9C=Yc#^fe&i4f#>$6DuKu!iZ7G+J6So= z_k4eWR#n8KvoDQEJfRlAuP6rZLXfXYN+vT&y=`(+u`9Znga78u&Qllz(R!wIH12-f zjNdskNdv>S8cFs%b?ssNke&t&Mbfj+iO-CB=5Nso4zNgB29Ym&1x`h@JwUTv0p$?K z<#R$niNVkxf1F@kznCQRP+y!%=NMJz6CQ=?C8oE*1~Dh)X0C=VKSZ!F+LgUYKnum| z^R!NUCSFkpd-|UZY2m%Kb%r#`<7>jbP^J+=(n<fZhC|6=MV8M!7A4v<*fjBIZY-60 zpkm4y4-|8+tjsB_S($%=TInUv?885rMe2Eq^O~IJ?L*S|d;4WcMF~8UN37G7=@&Z^ zJ)Q+n<|tg>xL3WMKu#-I-ymF<AX|Quqi|C9X07;ys2sx{B}hY+=|CPmP0Z^7HrcRd zj=Mw4CyOZh<(HV*F?f5-(>}(!aNa!B4>}z8`s8XZqpy(j%-K8?J^Cx8O8q<nt$nTx zsLgPU(DceOgvwnmWXvY^kzmydQSaq*KCjxbTkc0UT;oN{Eo-?I(Ai2HQFcvu0~6*M z(G=laeL9IcE5A+oai=iV-M`34+LBFeF_0rs+(BmLP(huN<v!}<SnB=BuTn2lW8DL9 z#unR0_Z%;2BnpX8C?Za5{^uvW^7)VQ5cIvi@Lw^Z;bV?|Q5ceOF0qUV)k)j4sqyJ* z%%Q_uFNM&ZP*Re!XGq&2ehWF{QG$w+YI|{fr_xw_>S3k18DTzRv?r(voaP5_6zUJz z3Z$qQ!b<Mm-y>`NM1-jw1!-7$_8%}za-srMINW~Y<zG$`FQ}S?BQxwd%J;$fVe8K8 zJ^!AXigV2;R>Y@&;uZ)v#imW68*F=6V1l#;NrT}MSho9N%nx<=1wQ#)SmAY5edJ}@ z4DP=#M#yMdJeI1W1zXf|nyfdiJ>z~;D8n3m&QJ325x^e((0$~(hvv#?Ob#Dh5bFyS z>3;FIe-fm*m=H%tBCoB3>0q^YH3YG@?I~jCsT}Pmd&NfpW!j!DP@izYG$66#a(lh5 zkIl`wF#Xc1n<!1_O;5NWRujUVfwVt889qdvA>mTLhi-x4tRKYQ1u$qMB1IpVG7Rhz zfnF3fYo-Vrkpdf>7A!a{2RAn_2S?NQYqp>pAuiIv4{<`)kkRC``#o3v3mVb9AQJmM zVpKm{A4p{lvKHSRpipo9yHqe!=d(47Qxo6_QHpwCxeAaaW;4(8LC1kWcGPoZ7v6Td zc3!f9UG2e<!?MT%lfQRvit1mJ19yi$ZW<v15grnpbIpML%%(=Kf*b~lmKhR|?Ju}J z2-v}3o)Vt`lONEd4Z!S9no!H=gO7zK88D!efU>0TIiC&4@)p1j)-3@~W?!zHs;xJb zaEgevqZ|N+q{B9l%YB(T1v^g&KVjwN0^)l|1UeuHc!h*M8@i4k1QeYY4IbU8iv}To z4i-Mt0I}?MHksx}KLDh1(8vs~Q%ZWm0>6ca$E9)syXyjav|gTSDTa~g?oeso*J-S1 z*$5D})uN`2M@#%H*c?<?PnDy;KsdN#0F;}sa9}ixa4wf0Zh*5n6XLmRK$(mVCIHvt zf_SU@5Qf=^<q=q8Zj^&X#b68@`WxbM{QxL4!TZ1Ey64`LATrt^KEep%!vH??LVHXU z9%vr7`dCofhoFJ=gC=EAPgx|N=`z>z@gUd43HA4l_JooAoNKQ`gG@S4P}JhWB)*IQ zPTiq1IT@}}7{_T3ugUHRz;?%<c-TEK(^Qyxj0=PFmNPQu*~2$QsgQ7;s32VFL`_VD zuk5css~p1oAh0-MG6-#udlP>If&Lx|JC7rJYEC*>V|uNq+0)t9K1yzxJJ9)vc4eu( zkhKxBr!S*%{=*-_2eo9xH9_gd7Di+IXrH`VwqfOf{JG6?w2{W)(qBO6l#a0_>^G+K z<#CcYws1riM8vl?+pzaw`TD^D?AzW<oyo|lJ0KREt()AXt}p(!=aTUthm1C0k6|_s zoN0>}Yj<=3zGos_A7u-DSh5HoXjLH-Qut8KqFvA!P^;YwmEFk`zSa*9kzZ&S2hYYj zsRiynK;%192dE^ob&I~K`)s+2IuntNxTGmc#r_nL$4uHS9k=2Hk~59GcZ-mPoWMzs zuM_qa(2-b@PyN7N(krwW-z>oymMMhtQuTwXDuu*E?&s6j#XcK!tvxwQHsA8@R{j8$ z>IGwOpvEKvp4`Ahs$Q__%hlgDUKqX^ASHLzuJjdAPlwG}>`-QcHq00dvDt`O%fcG0 zRTs7%S+GU#XAVZQM<_eRRv5C!si(cWb1XBjweuFi7+VVG=U`0NiJ9TZoUi#tUTC`N zZ?rQ(gUna$vss!MF-Pw7OioKl4LkQ5R6Rm1a81#VI<)fgJ$WZm{emdQ4~3iuk=^UL z=qCzp75ej$#QtP*3CyLe^js+Fz3=A>CDwgK<P#2ZUx7P`_Kmb&VQZO-(zVC@+%r3+ z-=Iw598qW8>QYqfu8!&-k&TIF(H8J=w9+6b7UUoJ`XX`k)1J*NY%z%ZJ`tYAjk$rd zNPaLSRaS<KpFsogL=4Pv^vGo%GN$L`NOVka3ABzhI3k)$k8K&J+cxW+Sa;q-UFV~t zf(*CDzJHqL@Jded)1-izeR1W+R%7fhvbEVDG{3E;DJAXPH+HK07gc+hP^_IGN`r2k zE%m|5zU1^kzq?a&%k0Hw>O=Kg=l}XKfbhUaGJ`!QNGOo&P~b7FQ`ilTypXm%j02Ds z)Y?n0UPl)!({{We^Lw&phYfv0OrbnL*OR)&)EIy9V8}E5Nm`Ym!&Dm|ZrB!+)1GgC zO|1Vd@8M+q(eFoRhy_E)YChdZThPt@dQe_+uJ1v1kxubh)eaB+TIK8a*7AqfTANPx z`!5`R<j(VL@0#mn)}=4Oyleb&@tZLW^6rt*_Yd-i4`m*ZSlfudYcQ|H^So0G!|_wK z_iv#`I;AQ}fJ10s+U2<{?_S-WbT`e`&^9XNDzcc=cP`&Q=9RVH)A0+wpTR!R4U2q; z#>|vw`_fDFs-!Gh#ms1%THf1h^3X~Aqjczh2*L@)ed%<SB-nNbID^(HT?y6rw?w1| za54@4kWIB!_lWnL$z}K;rQbFD<{~i$(NIj%CN-qw=<{E_Yc*P)7MHiiuY7e+ZzX^Q zwE14Nf24?e=K|JVIsZopjY!d!$k~B%A+i2Y$^MvZKW|m||2Q7~IRR-M4!FU}W@~C~ z#>zp-g#j;BOh}3dI@ykfQpMj6e3j^kNnE>96K5)#%^2KCPgsdicov@cg})NLUgzdY z;F0@rMe-KIVRoWAi~LCth|)f0J~7Xt(=4#=5X2N^+{kqa$r!k;?6Q#&m|^~Eurp`v zK8x4O_p8YkHV<{9t#q71in=%n!*rVO^_ot0XBjUjb!bp|%(rTm8=%Fq;w_8bXy!)K zuj}^wvQRQivBfkn(A}`#J}WxE>V9i?{LT(Bt)>1+_yh%^rueQ#x8cr5onk><sx0|; zA2<c|+I~G(sLBm;?=EmG@5(#!YrU!XqI-G+-ojy^=)lvy_8iN*vA^%Usjlm5u<2f2 z8<Uj8*6Q*0HYgbC8GCzq1sZg|uG;<9C^YXq{JX4D#PnsVLii{s4qlrjw+BBcULSS& zZWXq|O@*aNAX;mb^np@wHbn$m>3rvU?%^ih61`vIpQRE@x<Av&Qj4j*KEpQuQU#r% z_tGQ^Zp7lw^Y(?%>bAUt87}<{a(cSIZJg&HO6XY`vBvPv8jK1iccD=Z>%}6OCVs;4 z!XA#S$&MFR$LTY+_OOvW2zn9Q$5waVc<a*kZzFA!XzmofD7@ZHW_NLo>gqFPpI&_& z{laymydd9t<@fB}-Q<}i#zei-mAeaf%aar&Gt|o}toxmrbo*a~FZADQX7_sAvO+es zgxaGrC|df`RNNK4EuX`7b^Qhvjc~(*7HhqiL!&vxiv>z2KJyAuwzl@(?jPXY&TOYG z%2aZ)o)4JIG>=+4m!x2DSA*lTdvVt6#M5Wvg+4ARUx|F`Sha7YDZ+K}!Dn>4zzh`8 zSmRsZI!>1%&ZIB*^uR1R&SqWkGVdd5?_$^2)}x-Ee&UZ`;yOwgz4y||f1Z;OD=8^y zb9Ik%`_>cb_be6m#VOxxhTT4Cr@pwHpcLag_V~!a7jnVL?)!dzy5SEN2HyIAom>oK zFJ2{t>SP(OMI<zCKE0wNx*B9HntNNa+*9$a9z#O=hJym@BQ}>XpLD9f?<wabO5@}> zxxk>S%l^pLS06?fZPmBizdtvA$&po1#c-#8Oo;x>>M7Zp^?M~Qg`y#6^{y6P@6URu z+m~J0FFGA$F`>u$S;zj~P}Hi6d{p^h))jIOryZq1`spPtLUPSsjs9Ps^Ku;_p+m1z z`wBC`sFRu^lizbAnp`5onAPR(;46l0>j9sI9u~?hmFsfvBZ_O@9L;R?_?p|JC8g^U zES9~yHY+csL$0oD0A9&2Hb1wb7lw7>?>p$7da}1+?AuRMkr}S{#P9NL<(`E+e1~rN zR9C+KDL<Pv#t(T$7t22VTI&?dps%zuF%V9-{#~1PmDOZ@+readJ~qq~5Bhz8!#qF# zrPburk3I5KJrtG9KCPYR-GV}y?kf(DBwAetVl&opb)|Mq>Q7Y6_Rtb56wRDgdG!96 zTl_eQw@ujrtr`AYdM{J!MZaHI`siCUqfxPlSKN1PDFnUbzp%Y~q5*A5X0rbJ-C*C+ zPdc698D5*}K$NhoZfm&2nOznl^_PO>aemaHt!93^4`fFze{9~$8?&llAd%3~viTa* zoh(+wQ2hIQ9RKbuD&}Q+`uIJr6kH7%^>~P7hY3Dd@q7E3rwTm}RV_?)3MRgo=7AOE zZ+A&LN@2(FB<z&R$qT#3lv6l`UhWK<uL`~t_Ob0eT2=106?TedLhKAiYS*ykz~3i{ z0-ubPrsGu}5lz!%)*TRa%h|l-szdtXQuopF=}z{w-%>^O$IhImB>gbu??k+-3|eQz zJ`=Hjwh83lZj8E@WGx1<vCds&;pOFZ-+YG|jkt32AL_s%=G#3X?6GknUfz{iqwZ?0 z-fS%CcZrLryuyQKn`x)=(%TH>(-G_)@h&fK-Bqu-tW*ZjkWu3PMlRxxhY4t^PAtz* zkztJdc7OOjEixG_bHd*-{{fnsZNK3tMT7Orl|kFi;||Ld<r`7-;~&9U4l|#^H}Tz5 z9YI=cp)n*ZMxs3AT2TiyjED~d`#4zIOEz|^zrTN!bOd~mu)eHBGfTHy-Zp>5-z;I~ zDVo}M-*XNxuCZ1sF5wn3<!<#Vw@Jf%I$}$!0+nKn8%3w{afb6N31g|WKE6Q!mI{M| zgE?_KS8Qz0#l<R;t{3rFp<G>X-`!rle);M5qUT{N)k4jdObZe28|NEC4)h0DZ71@` zt@Na8No=vn6tINhQ;z&ORyRs??LhAF<k<OxMyYsunWLClNucKy#%1N#kSM3fLXg=0 zL>+VUS3x76S9jhk+-1Abo;haQGx^%jRB6g|RcZQV>-4<c3hjr`<@ZD?Khs4LnIR31 z(}xXO&*TL)I@i*NeQ}7qY(-tK-nUa%(p#6e#`bVu`{Ojp!CA@*_1-4l6Um%~L~<N; olr%+I*YT$L{!b<28^1|%xt%|-zWIUt?=1T+%U{K1%ii?)KS$F<JOBUy literal 45562 zcmdqJWmr_}7d{Ng2o54BDM%Pdr-ag|fCxwqDI(oN4hTpKScK9Ht<=yUHI$%qDKK=X z^w8b#KI1vRbIz-Nct5-!{@0)D8fG(lp1q$~dp-BM*S&b5`aqr(N(aTm!y{F=cUK(` zkFXdI4<Ac>8hk>&XYm;i4~nw7b4OL-&K+h|Cwp@%TQfYodoQA5h*UM^shjIO?M2TJ zUby|{f=9$S!M!u75Y_N=!nZFlN0OhCX$<Ac|E5QN9-kh~k@gt!Iq12u(fPswi0<7; zMA73r(*}=;muuZuI>l~Sbn%`ftUR5qa;}SW#!pdozo0;;1YtHvU?JVuF>m_Z#J_fg zN79E+m4*MTxjVA(&Yb{!>xi|L?e9FkO+UEXi}X&8Pke;T{P-fs@F-t8`7=i(hpsF1 z8LqSRaN&iIWx)&C6a|{N*?QA01K1{*Cf}c7yfpdDvB`HW;W^*AHWxf%Q%03|LcF*a z*bZCo3wptefyE&@%opBq$qZeUkhtT!t`@2M^^)e*FpLGup(^XVy%5EekbCvDTPg`= zqr{SFN(yxLttWdokIU0DTd(i%$t5OmkrLl|2i@;j&NL@%)lJ~zG<_@Uzjo;OAR2P_ zfq+y5g-9zwl1lhfyW!k#3J)mv9H$Y*73U+kIyOm@O|9f&pBCI@50+>ZpYN+J?z>l+ z#5L8nFndk@u8LC`n|1#+i;N&5<!Og0v?lfS6+^b|ouuIb74PlM4yG>7A8iBXEb@dc z-CanmA)C1hrsMUSo$KWLyAP)Cwr#NJj<45Tvr1imY7}4hu)E`2OhM;u!<OvQ)OCy4 z29mRhrXTSyGLs_MANxPvj3L9*ZD`arA^L85FZ!OWLaVNlu*auoO8K$&LWx!uCKhBL z2fY%XFpTpztz7<GA(@`Hch>iy_v_cMH#GFZ1@M|x6J5OT->^F6Ykm47hT>_QpyzG+ zIz=66g8RPb1bxr(;bnZhFo@6k?R2#-FEQa|W`fWDd%k3EWkiSft`wflJ-wGgZcCsq zb8!%|?H}-s_~tomy{^Oghxj7WL=~qP{or4S9{F8f#eXeL{w$b{oV3T+<?_`Qg5m(3 zaH1&^$Q>h9E=n>M8RL7WxdZy8169v!o?h}prI>uNn!Dmcihaf?E%60!lX{=vD&NJ7 zPs4@$wxlJGg)b4xf86+X?aAeYQ?vE--_$EENS+<2r}<95%1}Y?4I#UVrzTDNoYDA2 zA^Eur{+}<ucuuM7N6E}`k3~H|@Je0__j~$_cO^|6Xz7Ap6n(BRBH(*ND`|e&9AYk! zan_k!BiO2bv|;mc5Z^=*WiE9;!NSXFW0OLKLD|8lwr5<Wwkfv-w$GK39pDFl;&-@y z)8Zi>4|R;c{!9I^5x<;9q3@!OH5EqUj0Jw>AFC$stcpLSmSn19@S*j=p9oy}<a33M z+~tfbq15e5GD<Bhk>uyjcTu2;kDi^s5@mVUg(Zj_@|opx$Y-z5azB)fnH-<JR}#2f z8FA$v`+LlLb#>BtfqDM<M1Oz(TK`uKwvaas9D(YA@1WXL9+Z+1u$CFqbM8F4a^upH z((o%%%ysWn*_tSM?_XkhRqUrOTY1<0{@(k08XwfBIG~i;9MPQp?5^y!T30wOvKK|o za89#Du_daavjxFig=Ami2t)hpJ&;hYk!R4#U?1TKX3OL((3X7vRCzBD`lwN-QCl|U zZDz6d^xONqq^TFb+!U0wBei2%637b+eTV!~xk>49`G~kCQSv=14Vyxjj@BuCxRqcn za>|JIM#XEvCb=fZCW9s#Av>Y6cvZVZy%4>aVfig9>?7>$ErKn*EitU2U@ToNT{az3 z2rHCiX)M?&WMRY8Gn(zL>+C@16+a?){K4O<Ia8v~zqF&Y;X}0b62`ihuD}25_CU0y z{Xp$|iL6gw)_N4aviILAxRIjRyY+=?o_gWY7q3=Lv*I|b4s~-9=X)xOywWNe<?;mv z_ID@lN~ud}*J+)+z;E?63%69Y{bI{!nq_md*CEcR^!uHwY3JM7hAfe4IbY>XC?+i@ zOPjWuc$NB;E3V(Vj=3JD%$|{yL88p5Y>)ijp<|wHF4iI1VdN~oVY=b8fut@Bj0kKo z4wjvDS#*h+|1lrcyQ2G+dnkG+8WSy{bvEa5&chs!oPqwJe#d@fo_=24$j#yRLyINu zra8v+mPnfs%Y*)|(NKGBxZ6mQ@rp%VPi_5iNI+n~7o*HiUh?siO3kIAouLy635o9? z2t7E}71XuXMb)*V<D$i8Be8%Y>2Dk{OK;bW>CS(Uubba&aN<<rqKFWi+BObqJ^TH& z*A0)ctugmy&(SK0SjIKRDhag2mbiOTR8n{K*=oW^2Q~Xc=8KfuM%y;_^!C|1>?>iH zw7Z-hM3DWMT+#T}yPWfbeqMj(pigCjx3yr{zGdR8PqvQ+o-i}pW9N?&`NA>Xc|XoU zM2UFFY|mUF3M7hxNRSAVMV}VwdS-FDYgAxkjq9E658bWH%+KhHS*8@S6y_Sf+$eD@ zxnmL2?agRTU&fUylt5j}e5kq`OuX_u<b2o_<*R0II@Rv0Iln`tNy;7ErIB@O)@kMn zt301`k@Kb9^H0sPjZ0zlNt0q03kkKAq0Sq#<B1jm_G{HP8$z?0ol@n}R`~YyFP_*w zbvaDkEvP1c#A1Kb52^Zw@AK?x`I_OGYQjc;{M4$#dxObyNjj0cS6U^k6nmtLEu0kA zQ=VVtpr}zeb8jeWonPqMmNeE<&qdEp^s<EH(FYyb1P*xXmsXvGuk1zPQ;KLBG|wp7 z;U3+!vE(ymUG26lY3~BmkR6)a5xJ}*SF6MidegFGS*baBsd?f0#<iwnZ;vn4B^bsS zN3X{S^Y-eOdFXaKZLdpkrcj;XjMt{i?a&`8Z}Y*_W8P!3b9~xMTe;i3>aKezn<Tl8 zqpHV~4}DNw+8r@76Z#8ft^?h%$+A-A1to^%USm51GWA=xkqvJf3KsSj3Qmj<6z6&0 z(O(exVDB<q;Y<OKc+xx8nS>;xW~Z5^+=9ndrsv1%K2$yQUhvNwxPR%stKC(*2)hLy zQXacOc!gK*c7a)|nOj>;yA9_Dj(*tF(aVEhOM7iBI(e210;_5lsh4W&ntfCZ(jCoO zAB~PL)^zX4F4-JKZP{SFJC6bn>KMqG<|Jud3)9;wQP}YQ)DVnAX|Bh&)zME3@=rqr z`*ivjv(5Ub86om!@`jABq+EBNd|8{J$fXcs4SArIke0}i6@ZQIBgL=|xQTogc1b!X zJ~len{{;IQ6L-pDt1CKLL!x|5eE#Y9-dB=aG(pH~$^kSHJln#&mfkMxGd)YuL)=R- z0X&8^KisC(IjgoBU^_V$1(lD)yb=*L$3eXzXyN8Ejk;UMuBfr>n&pg*&Y*KKp-o*E z6KAW$t9ZuOD-qMeJKG^*CCe`3A=REI<D;HqJCGei@q3=DGe+B=-pJ=LnlRCbr%JNB zqqaV*yOm7XR3)Ojw{|x_NRaq!XT?k$V8c43YPY8)GR1l42bKyvjCOu3`c6nUx8LGD zc%<+s<m}8z_Mt_iP458f$@+ed9h-U9O2}sC+{o67;5fsRmDO7Jn=ZTa!JA}PnMfq9 zo{H|qZB=e5ZpIwHku_X1RIH2hvN>ejJX*8dpUZm2Ivo;5K#X-TzJg~@h9~_3;@j`n zMdo~cX5KO2dM$p_nM2m3*vjV4Grn|!uR~-LuH%KK!51OESLmAM(ujHSMn>AboVFQ~ zdz;S&dlxNkUwlWTKa)prQuyNHad7R)#d;kW(Q5ZDFP<pz8RLAJ5CC3Zn&~K*D=Xu1 zfMa4jLVP+r2spwAFG+m*e~#tw+3-&N{G0#}FW3r?@bB+D0Pnb;aPY#l`Ro1E+aNq5 z@Ye<KdXhr$zi$&3r=0rVF+LWY!;{gtqo4rZHB6k$%;3(J_AaMFlHY<4&N$rDb;iS^ zX2HGi71Xb-g6j`hY3jJ>C@YDY*xT_Knc5qh@jS6}z+DGV{D~+yv@>%tVt!(03wIWM zB5~#CH$=fP?ql97%s;>4Vk2=yM_HBmj=hr^voH@I58o9@C^Iv&xRa^5sQO*Gzng=< zB(7MxxHyRN^18XX@wnaKv3IiI<-c|77B8OwuYdqI_y)JLJKV+S2{+vN>R%W6-*xVq zIh#0HIk;Ha!<li{H8QqGxJX>Ng1gZ_KY#Vp?1|OCcY-_rJuEOlUfda8ejYyFf36Lh zisL>NRkeCzW~+PG$_~sKxQC?REk5y|-~a8*zjypkOPzmP@(b_@{I}_UPW{>x=4|G4 z$KDRy(?#;%_4>Q<e^371P@ESx^#4r7U-SI)Q!vqzP;uUW7EKcR9)2qdtm7rCyDFOC z9a!1VpDpm44ZLvg;AI-YQfZTkhbN7va92k23I5_3Q7mO6x@qmondi)3@dyZ@_f*sH z0|TC?88gQ>UaI%i<!4lT-RyEUHdMF3-|w-ssuC?RN9-FmHnv;$$@A?MIyHJnB*aQ? zR4pzZE>tddxGWoXFIOJz!w}i_wR`3p6P;P}m?M${TbkkG1msFarFJ>@PMkI&xilXB zufMLTqBOI`$>H&y2$H#ygV}y=A-iEgq;Vx4=Pn9jaFc2a>-vp%L1j{cfSB1A@7G`T zh4-((_0qIyEQgre$qIz+hAC+t?tPCsc_ikPyftpG)_Y|3B<#0l#LVGh1Uy;Lq$1>U zom_3QC;~fC*=s&Yz(sR=UT87dbtd}E^3B~_L(~2XYZrg(G`Vz&DRG4=M_q|yJMQcK zyju$eb;pS!M---cIz<gZnmm0R8X2#%Ra5=hweu6$^~-F%4@@L~?fuUYS&`U|R(w6& zn@u+Fj2DtyF{$rA+}jYT`gUI?+S4#wokgR_xbcHq$LT*!A30mrM-(jQwE!o*c_&hY zm)exuuy$0-6qc>tXj{@L3>lMLxcvLHf${U>!z{RUi$6#1PsbSk@aN(v5-{%w`qMoG zuBEi)syokig+O$3v<rkWC|LWKnW3|P98DYrn~+6Uf=+n)S`jS`r*nnvnLkV)vok@u zd3O?nr*&$QQcLfd8^P_-f4nv8;{Yz0v06yfEzPoLe_BR&KlKvx&SC=+DpR|vrLwq* zQ~Gy*w=!~R=2HZOx)-HQDgI<dfxN2LGaYe7FLUolaZnvI4xRer*dXN0EgX1sIe)N2 zV#*rn?29+d2VdsaF&S89wQ%f{d}KWT2ZMi0@f@N{x99~rs|e?gzWt}praXrb7r&%U z7{e`H<&{FmNjZ%&+o9VMV=Hwh<6L0XG{O3QupKH^-HGa?KUpm4?lAN@GQ;-g*<dj_ zF`bzWMZv_m237qXaW|R|*V}o`$IyrjtKJOr@-bHu-M0$Flp!DO>yFHi8G{ERIbdyz zRV%d_F7rLIB_`YcxOonz0P}UrG47TEcw$plAugvRj2Z|%?;HU`j~BA(A7r+PF>o!y zZ}UD_vN)Bg#MpW@Ox$>;6KP@Hmt}PN+@;u7<(Mox1J9+>?WfyA7EI1lZ{(x1oZGh| zbkQ!^?yL1goyk7O7vEWql;zD2l~^p^uqS7;_S+fv?4C;=-Wo8pFB>vPrb!ZR2jlvq z>JO&m{%YfNAFva@v<thFVNx9tDw0-O`42BvD#9$b76!TnZ3p?B;xsKN%b9KV)~9FQ zg-I4?e$6)!E9re8mhN#suvlD1E47gNRmix{$<fTtgim>M+5|t$xYY7%!v|{&O6L+2 z(HkTfd8PZ<EgRg(vk31W9d2|N)sJ7inv*p+M272&6CpL1&SOT8xy$d0s4*Pc`L=W- za9hycESg*2{P=j{Vu|I~w81mUuESOtYVYKVy63Ce;WGV;LnWP{-*A;|?Se-c%1Gh) zghx&NEG=!cW<|r{-m{uZX=Rh4V)4gE2fcwgItHnu614ugqcz(Jw{W+mBq(B5Jn0UH zOIrSA#qY1IcH97f*n7V<KP}%Tn8~|>T_Z!umcoN$xtYnwcHDiIK}?zIYG#s$wXL_P zJ#q2d-m5M5yVysf)mfrBiu=w<?mpfq@HyffdEht6oeBodvf1FI2d*y7e;ye7bsGOq zI2$g8eVaHrF4wK|uE`^;Tx+7g%6VI}G`*;#?=&f$DTh`rtw$T3jpC__99WK4r)HMw zWtUsZO2REYA2;X}?~UZ^m0I6dna5OG89<!G77Oo8?ae<CFnE(b2`lehDxZ+dI~k0$ z4NuQc#WH4Fqt~a~7b4ZIMYWECi-4^)1;(k-znKSa&UQNK^x}X!wHas2p81bhFo||` z8Up=p)hT4MUwnt@m=u>{O+xuSmn$u9OOoyua40Mpo~)^lXP;}RF>Zubksk3}+aFVU z!pz>)w}!2t3SZbM&)UxU6d8wlfC$mtiney1Skd&(?Ah~-TAnx?_--FrzR@K%yT{P) zHgVLYS@38~6Q#-i_9{n9&qNO?z3^ZiKOJ#W&`-xCEkj6L3{7hi{kb;$_y{}oCvPTv z7hciu3ZvJwdNnZqA}e$syrx>-m>(bR71=F>z_SFU-3NQO*GY<9dbehf_VM5mZM4%6 zc^rJn>G{``K{e&(cZk`pMEdgQx8p+@#G3NNta`3(>@O5FbI<zBjg%J**%Z_qD!f@i zOp3cM>fCVr@wo!Odb)HWziRlS@rYe{$U`Yxxin_Q%k?=0wbmIb$&3q(C_76gsGOz| z%~`Pzhmq_Wi+EiF51m8Y_oid)U`g<g1{%`_$&y}I?tJ2{JM5`G+8z<sbX=IbROPk; zZ+?QFj@DnC`gBgLW3le!7=C^v>cK?$IR?=|lUJRq;}shi1aL!0k><gpbdOs2DTsu* z&k?^#)6_*pc$maCpF9IXv&U!}*sA4+#4Ojj)ZqA2=Wa3!i(z-92Vi4{h>(B)#|2M* z(-!iokgK6L8)|D$jt`0!5Sw4+k=sin&D-anZnUx{$Ci(Kv_FuXe;={9^3>s?m-qKT znhv)KFAEC;w=skxKB{`FD#Za~5B=&Aify=Liyh99)@^_I<a=QK(DueBGAY}Wt~vWx zXcP2|PXTY$qQJ(eb9bZn2~|?%N|e4N7AEuM`T47h?(;P^!$GwXiK2*Nl?~_KF`GU_ z+sX<|=Ga^*Q517LZav|oj>*laocONDQ~8-KSG{*-q{4CXb$&LoU|uwNe`|pr@$OuZ zUOlto1muXpm5k+!n~F~_)kluc8Gr4};V<!Iv^ey*Uj6jD@*fL6h%V%oEQTm21+K@X zaQL1a@6<WUysUc(_c(o)_Obngqxl#9Tw~Ibs~=C5tv4Dr`%F~1+4rImHa>5?>Kwk` z)}K$KugJ<kJ_#g4aqI%`Wk*a?YTM`S-@Xuwfhl2F)s#hE&n9{1=S{uPyMA+Q%$F!x zFYB@6+?P~Gk<5Aoy`bge2e+mpE55BoX+PozJ4-2Ph2WFACK(bN=%@UOA1^Bqr3pS1 z3}s278X4BmONhx8y}rtdJr6`X8=eOFjGj!l_Cls}hn`_-$LjY_Tf!f*1s42Ccv>jf z0=dP#51-JlKI`lioKT_?-IutxnW&!PFcW9d1c`>i;B`l?RU{!+A|_3*E5@d2Oxd5J z!6UdN3eb%R@M%v+_xDrqW-^fQ;<_CVbaw4P{xr=wo65qq?F&cB4kKDr$Xb&6!uFF# z3o@kn{+bIc^ro%K&E#h%Mr*fFtMWdaM_OO%v>`{x?><aaqC`HyN6hV&yUh!AF`e_7 z$#Cm|d<NtqkuG#?Yv)RCwt(uyf##>ZLOXs^9E@Rh1JAhAte$fQ&PApY&(-zisDBcI zUCL^^V_@~x3UyeqQhU$=oYvwGJwqye=yRO$4r<^bN(3FgeXKZHXF~L%c=$YC{>arW zSrmq?rDYPM^xwi;VAHAe(n4b&b9!2Z5Q%884VrAgN-@P|iX&9&%^Qt0hMz+*Fg+`M zy_Fb4?-zkoL<}zB1}Y=4Mw!ANjZ57=Tby<-CI$RqeTfPqFi0c`g^QAe=k}(y^6of9 zte$z{1#8mti&jYV_r8#HxHYR%EIA2&nAq}7eU@q03)Mw1vyR$>Wt%YA<!`{FQ0ItZ zhf8zjM=MM8F-fl)ZVYJZrZ2pMyVBVxpI#oeyeJj<bvDcStN6gEKs|F#$}H!JOQ<f@ z?d8jO`;2o{sSfvyf(huo3i>GNILKQH+M^oSA=it&*BWV-&`#F<xp7_vHf$;oSy4Dm z3tQorl?;O5Th24F-I51fS}YgOA`h9{;hQT==q6D(f<z0Fu^o|B*~SX_Dl+PDCn?`r zbY(W#XB^%@=IL{|CcgpT&+t5|r+3A#)&%=D!+p6mWq8?rHqjzSc+BxGu!@bXc*F4N zXv|8IH!rp?+k}<fx2>S&V7Y20fK0OR75id;Y5xQd%r%rzV))UG&c2&|Xh!S#!y1mc ziL+8IJ^XXDTUB#iYCaU0s9q^1ge+#lB5(i;&vw`WZtM$oyUJlYN_%)`|2vWHe(p-b z@wpcDF%nqOOj6m!!>aewR)6i**Df%(+<*T`92WxlJ%zZG<l;{lwEWOgoeqZwxlAtj zGmCWlz@lElQGFhpb4I6FeQM!l@*#9)tl3qOXv#`zL@!pmo6!DCX+D}4dtF~yBnL(8 z&`D<Haw<>e!_f>`A;ZG~GA`(P-)-Hw(`qW`wIHvUyj%CczEXzKfKK&ou@BAoGn@pe z89Zb3+EnwT$itHzYd@T!XD93{b?g)w_SzX!uJb<n(LghnH4gr8b@U>lq(*1>Is$aO zZK4AUyG;YztBlTO=1kmB-id_`y?=bKz8!=v_L@tRB7wqC%f1HG>qE1n9TdlXLAhuq zt!IIz0&3557t&n;2y8~Lo({;p(RK6FX}ja&4bOsA*w|KI1E3V)flg}W4NlW-LuQzC zHT-ftov2xDLoc%+QhM{*oOq??CB420LJ`A)RzltVs`Qo8lW$NTdbO1m^a79mQAT(- znd^t@ruLp&oZ%WQS^if`U5+17ZQ2K&jD4A~hE<;qP&g4wsgp(ZKqbGA8r(??J{j8r zkwxvi=ZYJvHf_%GCzJ<fC16|S&QCnftc&lTYnrZe?&m|VE`9k`Q$)PDyOXJi5QGuR zBFGamv0ORJ_-?Ia({K?{LeW3kX;dtdM`zQHP}UeoFGPM78GrIA^iDd`l6w;Mc(k?; zqbLH0qkSGuJlzQSN~<@V&*YL$Z@PCt?77mk`c*to�NY?2%45RoO#_cyv&<HQSSS z^F+GdyWa~6mTghAJ<97CZ9@j+G~>CHwzII_XF{;u>>d?v4H>OLZ~xx3E|El&e$uM^ zC_NoM)I6Pt<?6S34;#)W=fqc~4<zfD_8_{;V);vRVks!(<6fbjQgw~k`35Sf&#I76 zjz)DmRBo?3doJ<mwteJxG!@63<o2M+(u@}g%(rr_(*M94o1JMpozn1z{=~cGnN1wD zSkP5#)jn!OK1~}^0X>a)xPS1bV^;+{H1}P&;%T--K9Lps*O|bPbX7_+QNw3g6UcLR zoj117u1k9Qve~HO>&o$;8y-ltI7Q_gdw3LBi^Hbp?F+q||Aw~LIHkj*aw*$?Zjn=* zDM$^3&{yTR=$?vYf4J;e;ardoOw?NMkwIu5<s~cCox<%NMc$!h^VabX*45lF;p}YG zm0b2YCm0{yq7Lj7O4U)MG23;bS5n}jX}0wp{A4)gnAF%RmKNhO$=YqICm<7@9|iwN zb#1QZ5!JIS*$|fZ?rJirIRfe|!HmQyGr?Euv7%KUqnWT5P;g)CdgP*MS0gvYqF#mB z#x~2)&!@pF<0X#}LP$fTtuO;6Cxl3SwcmAmpq;nH$;dbjDhVOqXE+<AeC$qC6?{7E z>Q@Vd*Wvbv{gNAI<<XoQC$R58Gi%i1Awb#|6GT-XhF|D=?@m6;7FC<gihjY&Nej0h zGE?XEW=mhns)E0w=3bnr&SLeW-dusL`l|0Cf%l<9DjCEDD4+UZ<Lf3Q(RVq@F&DT} zCj0h@;N!_)G+$2o`cB8h>6M>>sgs5;Gp9&_m_-Nx9+WS9n?lsL-omXZUsq&2zJnh; z;nmsMz5*LVJfw*&L~5NhiPzax?!lij2HIocnHj3e25ah8al`<*^76vku32Y~?p8i- zUeU|4Yrl_CLA_TLyot~Zr#ef0G>O0uVlv&k9N4t0u0z{@$U0*t(8AHOm*Lq#$Ez@T zmSx1B%JxOSBBkkG9T6(>*4|XaRgrZ5@6_CSrh=z?06zhb*$CjOQ|ENLdj7^!sXEWp zg|`_TMKS@W8&M=j*43|gYX|4pQ;j;A<P|XwQCM}710?xFsk;2Y7qtWRb`U8}rJg62 z^_d0Mw_s1^-BiCvFUZXsW_~M6ldP)KhI<1rw<{Bk*2+P;6y8!ial2We)Mo)q(`O~1 zeSgv(Od3}OgXC2lk1~}6z}m8ba~Cae4Qx*MW206|93mA3^mBt`p)RU)(xLz~D2P;} zTL+#ff`^XIzPU8Z4%MaryA@yHSgy(bZrLC0uAvcg9btDr9k_rR0Iz32P#8Lrj$#(9 zC_~*EO&QZ;j-szCWLAta0FYT{l(d}V-Ur^Jh;s2h0V>n^R(C8qn;O&kVB>H_Hp4&H zKgk~5yg2ctYNfD?e{hpQ8<xiLN{|sIz)kPZ1reenQIIKHz?s-ttr;`V@brZY=Ojrl z^wN0lz_(r%s;)%mu3OtXO6|asqPAgQ>MjB&3!T~&$z!fhI;ml8>4{4F`52n21A~c( zw<Q5XZ{f!eJOzE$M=8L9#b(f>Gn2iCd2;xDHwAei53%tX(OLAd2Fz2zIkc*@>8x~U z*OQ~2kuO}dA1n6M3cR(Owes}hB)#_Ua?^=QBmxsvRG=b9rKr&;`CQ8NcWpdFQhfN5 zIz+{_gTHwy+xvx+i-{=<x}G$r<w86fj`e)!yg}r*BXh)BBn#11Gm!F<KM{-S+RJe6 zINlkDR2)}kY)Gnwr!SeKY>Y&ybVbk6l+CRKplPu4k;_(r^(amWevL`P?DXDJJ~g-d zBB8L=l{*3xHlB~!4^>su@eE;M9zU{c53G-OM6f$tbz{2|Tbd{4*C<SD02nP|z557( zfw`adP;q%msQbbt_9sOVo)1g|?VpRI8>b3C4jB5_xol)cXXV7s9EdzX`Kq%7#nV4D zF!^Aa8?C9Q8NM}aQ!qp?KX#Mz**(fa$j<EPWNi`7keW#%1-LFEMja7}CfbAPdxukP z-<2%)9?X#{bmFUaY_EEJJGnQnWu1tCjDB#K>>`QNCnhS>?1c=D{JujTBiDurslG;K zk?s7KESBGIr;oXgbh6Pxh3n$m$%=b!O#q-KQ^4`I@1ZZf_>8}I7jMgYx2{nJM}t3i zT>W@2X|ank#!F3kjAW}^dh9!n)ZjtSrB&QfpN^*Atz{0VvB~9!n5kXPsny;;H($y; zu}~49ycWPAZC|scRTa(jfeJVzQJ))!b<Ju9Bu9=NlrAfkvq|n<I;ZwIQz9}M=f0nA zVQp!<(@6Le37v(Ko0^eFDF5WTu78t?QmPMQOwET|)n`lxonxS*-)UtU-8(s6IqCRd z)w{?c;jziLG+g>h-$3LZ-JvdwbU66L^ivkIB8CioOVfEQ?uYRHPB4f#2MZN@sirD2 zU(GviqgypL0?5U_uP_0`7+eWJ`eO69kW~=h8h2~l5IPr{)E{Nrt7A;p_lP@pBvA?v z9jzeJ;v~{N9L@1g^YXOFiJah*q*l%RyAWOPz_;6(exEUU8dNM$=FJbc$5yMT&lZmg zY2VCtkXzVOo}hw+SRZdG&OYsxFb|{=Wo0O-t@D7spAd{rXb=bthLWJ&R+hU%pC$uT z8can>Cs;_Pw;G@eBbu+ul{v;7vZ|U}zvgmV9S-w$6MPgSzU7&>F$(Cq(JMs*m+u78 zhD2nz_Ul^2f#9-vW<G=|g(%q+>tp|^b^wdcf%2F7KP^~#d0vWgaQ-rpb)J5?aH5!7 z*~$?Ube^&wxGTs#YsisjRM*7WldAJnrg?g$ZKJLucH6X6XM-dHzn&a;wXtUo@+ore z4*2B<Mu#)~#IF}AnOoYJuOo4crIXsnKsr&ku|=1K{?54>bqqCHW+0^*dtnx?babCE z?;X-|YzoaI0%dY3$yxKKe3b3^ie8`dW>P4LkiP*5Mpo6tsgjk(+7sLMj>m<r@1aVY zy6p3KpF7#zXupBAiu(D|qy|VxdpcZ&$!qhCfn59PD#^Wo$oAV*H&K_~%JMmU-S^(8 zI>WyDMcKPIL)mUX8S#qb9BmRjJUvrUa%a?eo7^<-<2{v7jlmRp8=4s_KmXBHd5G@t zxJ9y;xm*ZcdU>kyDYq(z8?>e&0QEoJpU-rafca#tD>oPLXHfcAk}Hzz%4mts=Gdh> zcX*q<swINn)T~K+DG6I+*KwRE2aIB;pmpE9s*Z9HrOxk2;}_HGD<Aaj=)zGCBi<ot z&OW`tU>dk*6~0sWZDi#%YT~N<yqk_pa{fDX5^8>Ds(PdA6%5}hzCm?|@E$D1>hUHT zu|O9n00_Jn5-ck1)Ki{$TWRs=^Bm8dWpZ!pNffF2ByYMsm@r60#v4ZIfhczVu=C#a zmLA7_zsTb|x0^#5mL>#`YT55O`>^`^3><9{7hhBO320m11J`t2Xowoe>;@2^<9aAs z4)HF(lu3O9?<*gHS5?STy3Pmb!|2qMzsH`g=fSavZ@@D}lBF1f&YBMrN6pJ=!%Wd< zHjw@$I6~q~m^_s>-JSLVhp)mPl1RRc3J0iMbnXo(@W!Y*BuVC2->(nWL(4?p#+Rs3 zhFvoP*?e}(ua9RTmETn;O|5)TuP=(Z+H!sD6NFHp<TUW6(J_z!u0TR4odF+e>o5bG z2m-=E1@Ca+)zM2do3W+GAm)S1g<hH$rrM{|dO?H!7X1QjuzE^$$=J831zJpBo;F5j z-Hp3fCVHY#{opy44!bS&H(gd0mRewB63VWm4vQqnE6iY4BU5FY+Yz-z9)BpP-ETWf zFWiwFIa|ZAzFFQuwg%nbL8bWIcnh52s&|xiQpBF8zY@$WXXT9zq3#3!pQ$Xr23$Je zEUfGW&fll_qONUr!=iTyQ7F|_=RP(0Mu^(60Mt^mC<W<U$8L-5Nq^;KTf<~*bx{JL zk{XyqkRkIfKpCSACDUyDE;3eFZa*;&*Y;D^(WuBkj71!b3ZU-K^<_s$Fp6~gz^LNk zKQxcN`&XI<aM@WL?ymK#jqw|3$jTQys<DmX>eS}E7fyA_`5w#xm8H=bE~aHy<v7_? z)}wIBDaV*qr*sBxi!iW1^sG)ToIzij-><Bn324v0AS)A}AAxqoidrMR&5#_2nvfqN zf#lG(O@p;C{Rw^vyPgmQs@!j!b9?&-Jahau^c1WQK72Red)Di|AdYDih?)trrxG5I z9f`ip4*OWiaaY8kjtEPTiLHCwnBqeUT_;p2Cp*EcY`Zs{VT}a|uDz0t>VcJTj`IOV zAF9uZE%NE7M_HuTvCh%4EA{LQ!#n^)Gv#>NU+wQ*@M)VSA%j`}fcW$<^vkB3e3V{2 z-op{LxrrSA!_L(z3+n^{Scsg^QE2w?8b}4a*yvk9`J2R{SzFO|bFq|~Iaa<tfj{aq z_8@zn)T8H;|3bYg0L1L%-?Dg(L%k?p4s%Mrtc4d1FF+1(s<KtV1rORV8Y_W{T+gAt zkQZZ_gmR?x&JvYveviyAq;D;>vt)1+=dnDa&vR2*#79q?>I&LVxpaQUAT{=ET0@y; z`Nh)eP&L1|1il~>GkZoTt)H{S1y+^4fA<)>PUXsQm~VFc#Jc{dRi`;`Kr>$%HH&OD z>A#hQMCKQC8C*6SRQ6tdcw<dBHMF*U{}EO!TUD6$oQ1KJ+K2<@B~-d^tfK($m7aWW zVoW~Ln@N4oORw1Ug@hqO3YMi8sob1%#2ML-I2RPC)~pUZMBtIgojQws<okuxx_A5X ze?_;CZHUQD?MM;ZILie*Rw&f6S};T{gE}|1M{w*l=c=k~xPK_U##8M3vN!Y5A<YR^ z0WRgUVHEv)EBpnTQFs5k4A=*tSER#X<U;*2Kci+mKY}w^@t-8lDATLL!keUeb5OgK zPbxB4b+8K2`c-C={PuP?mJFlr(S0yH)t<wN<Y=ILU>&{#_<ow;J5#iOX8@T=K&q#B zHO;Z*FW$to#Fz1G3V(h>lZNvw;)@K?P^KihTmL|aKFr+)Ie#XWE_TBHMbr9v%)d!u zau(@uDwa<!ID~-%>Vo*N1*IhMq0r0>nIa*{nA1@M5#4lv=X3=*lG`J0G9n2f%@4mg zcYgMut3CuoV3~>Uyn+|q+^A2n!S(HW;s5n*2S)&|#5*_r)wlnq0;RQZNM_n>GUfNY zpWi42*gb1(x-R~VBL3S9k3g3l#JW*2ApvrKO(TwU_}`J!f6ev(-Hg~Y9e8!EN5bdm z{@dcOwk;BX!5FQYN#MsV@y~Vs=T~?XNc8Bs58br<&yD`S4e&EW7lG|-ZHxH!he6^K z-me8cYOQNZxcvKFRj+`lyZ_m2>e|1f``?k@TV7yD>jnH4&;RM=Kb?*w21B{vc=6Vm z-@BVKMM7>Gb!gLZ@yb8n|7W-?w|$v&?mm=zK=Awgu<hZJT_<$TLBCCpuk;I?XFnhF zCgPuE_+Ll=FB;-Kv6lGC!PuDEQOoPyBbNPkgAcE$-u%NH<M}n5XEV%?w5n3nb$+-| zoM9BwxBW&dJe_=D{f*Cs$LZ!>J%5<QE)upc=#3UAd!VirM7KP2%<_82@Z)nfkLnY8 zi{57I6}fa765{<kvHu>WL89}<OoO~X3|DV0C1>0TaGHtFH+x5Ou0w&d1$)#dh0!TU z)(;@(#A}!T-6Zh*9Pk5mB^Y&WHKT+M`=H-R0+p0GTSR{pmAXbu67@re1S9^v*ME+P zY381GGr2Zpm2d>{k_$vJa}owB{5~)|f<VAc!76HP8Gbh_Y34h?t}gnU-uVByVYrY? zKQ2GPlJs=FwSmfL;ZN6Z1Oa-E&Liq`&_DHz4Y)+g?>BybGJU0s0Ji6djtLC-lN^B< zxHX9EE^fd4=h6E6NR<n6Un#uwfBFR3Bt9d5AjGUws`1!TI@;eNK^WRr@1DthR5SdV zUZg9M$6y$U3>s~L_@Qxy`PP+RSMPqIbpL5xT!^*@(pH_LmCl_&3ljoZ3=+gbzfcIB zkO0vo2VY#0TaI@OB&V#(%O|`K;us}7OkGB7b9YIq_pv$KVwqQu2I`K@&Pg4v{_y#7 z={Il0a*vraAQwbb{o){2Fb5IDo0v2Z70iHCf-p#7hdjKFx!B0v63=fE^d@jPHJH&F zr$*3Jc`+@44|zvI!y_2QsVz*z_#{PSHo3f@W;=clG+iX}&lML}`qgWse1R16w1|Q` zb%Jb|2_NvF{2=J#8?mpe(Jg%JN9uZfxS=9uXh2FtN*7tg^BCOOV>Z#P!*iv^qI)ae zCco%3KkfK?E(aWmf|Z1Ak2!oIb?<jGAc4(i<_A)7YIT&HrTC92|J8$(RYGuIb%#># zBM(leQOD-E{yhEWdCPIYmsx^rkC@oe^Q)nJ3}UXY^)phKK=zs=hG79jGiJ@Y4w1hu zcH~39T#{lOA5b9oDTuW5)@%ZWhZ&`LcAA_48K!adC1*ad!2=5IJUz2$9s}#P7+!mn zc0rQE$6eEaT(Ej^jjw1%ytHz(xYOGhU`KOLG?(6)sPq9DK&jL8{Sw<DffA5Z)(N|N za1NR2*e*z0o3D1giM6-PMI0>$LunRKS<qQZL}fU?&D5_0`j<C376L6!18V26<MGy8 z(X~}|N83mPm5J25%?$3hJAPY)XJ<_9!lOV!-g%~jzdeSx+)pXuy7KzNvepPzBrciE zHn*z3G1Ivuy$qG~=dNR30Esq!AnQWMiP%3HMU~nNl#M8DzW<pNXABD+5(*TC8;}~W z#5WNkh3(=GVrOxTPU)ohbliCXnaf`bjXrgRNgdOQ%*3JxO06+%m)xh`Y_oeEqYA3m zU&aYqy=90{^h@RV21tG)v2V5d`2exc44Q-qfxLYpGIBE~zZImQJNmLUCi~yWSGg`N z@<W<W9bj_`79A}E6?tp=TyJ1vwQTxxU)a679SC*x-S*lZVii`lhok2+Dy9$P=y(;A ztVNqoj#hlOk9_e@Ee1dqiB^JZwV|{}3t2;A%N6g&+<^7hq@TEZF65ODPwxzxka@y+ zt5<I)t*B-`NL;*W8AnXKaS87?^J=-^mrGhq`Qf2cD~ke=@bQ-F;3`lW9Yp*X&k?Zs z_R-J%v<fcN3tt6hEW&ekT?9ow^Wzn7nO~5U!ODghBeydk_hQTJMzDGAApABlU|o9l zG0e2NeIKZQIzeWRmPQ&PY^J&A+H}$4GYnO;*`p{|kL<Dn8m1dkN1GZBLI=77_e>(K za*IuoO(InwrESZi)h7xi6w->{UWvCKOua*N1IU&{IJ<M~v*QK~+zfK7tR0Mes<{x_ zQ8mN3#Fc;j6pi82^CI5*4*L5~K^i)K%xyvf-rp%QVVl!Msh1D*e6?ZvkK2hL1~?tf zAlKh%`+xBU&`Rmjm|7`uX|KJ9B0<Lowa&5V@7=KJ=h|qw8aDVU2bFZ^+^x?+{D9#k z|DHsUg(t5fv03E;xJ#5Z8ss5OU=ki_20+NRh#np%VtV>`Cv&m}=(Z+Nk(2}yYo94x zYYCXjmxoJj>@b+mFDOjD$C70A*(q-{hcVd;8Y(xV@K-Q>EMKMIV*FFhUsCUM0^!$E z0+36LtTk!A$iU{RNbY^c3CFs`z|}gFJeMzy_>&Zm62hvNfQm!-eXs8UYSk$UzAiDB z5-^%}#t;*wT0ab&?~)VX(;?9WNkF4D;&A^vQm;LlyHkNR(R5-Vn8|d$<Tg)8NCvbD z<mX2g_P+-+Sx4K^Jaq6IGK(=-^h6krRye-PE7SX6`G%B_7d>}HOl9D+#GZg!__Vf- z6@$c<Dn^@L*p_d?=frDKEM>B%7V#jzlDXYWYYPTa9JX%vyreXzXOq4R)%o~n6g-kB zXDj&CGfhQG_k)@2|EePg4Li(OmHQsia0-@x7g0|q{-lspmy!)9`!EL{bz8(F$pgzy zFK%gE=y9E+MI902Pgy!%<B6=<86T;2lhS0^Y@)Xx41==cC_3|tQlE*JRY<&!_hx56 z`i;~;B$2<Ea#Vct%N^k<tG=u^UsHCyHFS1Ao+2Am5M@e?vGK;iq7S_fUXgTB`i=o{ zoU5aRnmR_KRZ!|Rl;i@U1A5lr<BYcK-h#DZ{i<>=<vzQqhQ{-B=~nx_kT+3mE$ao7 zxYV`l7(&~px6EG|ZjGAiDXN+&$XN-hz3RQu4fs6x_KO$CPse`^CBivzb|?YTC$8eD z-#-P9w51l3q`#zv!5Lf!jWX2J?-$7m5+C5Sby99%8)l;<7KVwAJ(&z~bt;T!<7hzx z@!8_HWskJ9hN41Ypuib1=py4k^s*YwcvRyNm}kvdpc$AhGYGpittToIJtCK;E#ex{ zAc=V8(n(f)$k*CAkV7C3v&dF|V6gMn3c5%+nmteVj5Ivo&U(c9n1cPNP#&fOa6w5s zp-&c_3d|iUfKWcv`oi2^7m896!)CoZ>}(p(S${yKweLOd)XrTr&ja%Bt>QY$nfHZY zliBm0d6|fwUw66|S-)IBzy_-O@|m?!jzCmS<>eSR+tX#~8+_hG37a&X-I#k9HoOB3 z?K|Slt;DZ^*|`9Z(@c#^Gla{S*f4l)el40l66uyYsb&an1!IN>vL-nA|5R7O*1eKj zncF4IR5F&6a|nB-r|H5vgrr*3S1)KC&2WtLd1=Tf3v>n=V%yxdFxtWSX>fliq7Tyr z(t1Eh@|Kb<uoTeIvB0|z=?(`k2xpyvkQM_e7M#)N(6Oqs@IIf|<O<Vp!FGWw2Bv*c zB1E+lqFev*OV{Z7r;y3Uo4U2ozcP0Jj@wC@IVT|ZTVv0z0^PGiT>2=4eJc3WO3hA^ zSK32|nyl`6>$F1V_7#7c(!_5rJDT-HCe86c9yQR_Kd1}zn`e3ASDkVE+~q({I(n|% zNC}^2HJNCpw!QX+8qZ?mVsNZFP18RLj8V=+*Gh>`J9~;q7u%M_6JoT4w6Em{VvXEH z#Cj|1NKw|P6ByB<FSfXy=LXp6oRF_QF*>@?-M+(*?H~t6p>%2?SV)3F{nYna3yLzH z-hT)3*AW{#0SiZq6OGy0kH(q&s^yn~y4a@lFO6iOf~)9>r7w9o+Ia<74%k8hNL3Z- z8p-r0+;U#j(STnL!BF*oP%c*qNqx`3FQroj_6WOy`a;CJjC2aqY>y@2kU~il3cRvx zkV!q6lYI*SQ!eEzs)wi7?<Bj=T=aYtc;1u+dJU+63O-(KDUJ#Fi|zi8kD1~ON67R8 z2Vv7p?lcB@*X7WcrS?->S~B)+#DgxmX;58b`W44xbt@y8=%o9ZP);EU7T%kd9%)Ml z1`I;WZ<?e)s*l2SPi3fg@DWtYpUUWDuiK}iA&_LLm-rK!+PwIR;;aEBfOGhn(i)vB z<C)zMkl?9$z8|GEoH23ut!F|+Cc5CW=dXA<4F@cp#>yx;vaLB#dy_Y<Qk)R{4@=BL zD(5qhiyQ`3u0mitap=RQ_I~o`;+{M0Q~)s9{6wA49NLItpumucp11~lE5m-G*67tx z=2B(-_>p7HA@c%&b9`!;$42y9L|OwkjRE=z)$bsidzp4cQEVrSJ+XdV|AVEGrX5v3 zNYYrFcO}F*6uQCQSFXIM3(3l)Hn%QxLsRb$SIhs8$@qKCnG0|bAIhnDl(y_pPray@ z^^zt8^FG7(wqJCAFU4sphdpHzSqb1_UB5jctzDM#;{j?*>1B<~2c^jQv8wVR04I)= zhj~IlYBYB5XlG)n;=yqQDG?c?Ezkm6#SDC0r+YkZ53rp84re7&=I*XHn~ToGnkbEw z*&V?sYMF#>V@X>+s1C-edy90WL5mL^^XY_bExRNS7AshHv&E(W1h9+d(lzex^f6AW z%QsJQ=}~ayds6i+nyJ=okm5RG3<J}&`;sD)0R-dv{fD!_dV3yf!_s&12~<}MdI#;G z+8~XijV;lSVOFFQ{NuXyFpuYG<rQ1J=g$R!iUYme{1M1b8F?S?S!@7ZKyy>G^+avW zd~c?T(nqqZlyC-@FEVAXQpa=DEjH)Ax~kgc;Z$=!;Yt}?GrZJgUR~^ZjHh)P0V`=+ z-pe8g3H48rr0dt-AV6-Kf*p-<Bx9mR_4}|N5u;_ih&?<&5E1wk1QjN;KTf}J<MaXU zYX(ToJ}@DUQG6QGIN5X~L>lgXf?+C9Xm%eo3ceU9FOYE4F-?tcN>2@<>p?ID@Q&q7 zce1@(o~lZewP+^52}po8t_gSh7^hO7JFQ#12xMel0_jN(Sw%&XyWdW^-7j-`K;`1? z2?VDmvtwCmS3UFk#(EHyn{{H|&ok_Hldw)h>54Q5460_xetIeI>anO$oPO|mjxTsb z1rLA4_RNO3&;(w!B)kE1;jB;FlEiFaY}vO_N^t`4w_Zn^y(*m`DrFSm-j$KLTMi%l zaUJA>^zNzfY7)Quat)PzK|Y|FD6F}l|Ak&TP!*dedu_i!<}C-I=Ag?OD(k%zM;C-3 zTy*wIDkmg19>(to;>_BksfK7lVp$?i#l+02PE8p<5|u;=t(*ZapO>mhRtSRByFQ5X z@^$*hE~Fj>tfx^dKsIBj;&VyzX~no)Sz*x-aq*SPSifHaYv}|WoT1A#Fj36583j4d z^=CIl#ekOc0Tv*;(bjz?$&*9p8|EFcI*1r#CYBziv}dAL>CV$K3{>rt=u7B5fFuR3 z%Dv{RJKoPhni>ktyltB5StGo|Ri4to1%qeXyt9E?3to@CoeRXW80An;Oauf&s*2Ii z4@A6j-Z<2Tg=beGQBj9{N>QrAnMuo;ST@)b(n~k_%1}8E?+XqdknmPNu07tjIUxL8 zxRzl|PvTwz6xIt_3kxFdYzdlfDg&^-&Yb`*h6P-i!KeEWlYFbhJ7f}lbNjMF21GEG z?6(h;{l*ak1{M<sFzr*P&+>s7v9$My30s@>QhLCkud{at3(&J5kjWz=j0^HTvqv#C zg1MDEMK798p!#8dtLpxxBqFcjP{1Kc3J5RnWQ!`KhMnftc8Ijq_?F_6em|<%prtK} zGiDL>rrm1Q9wDNs5hDe$X%$8wHN)S9-<y3mc|U_aQvGA*mj7iH?*;qu>LD$2D|$LU zNzB&9h_}q_!jq{izWYJNub~71GSLkpLb@E6ay7HxW&<rlPtrnv-VH34jU+B(coY$t zw~cIbW5#$DiT_HPR9*?+k^zp2t?NdSv}SnJ6YiPcs7q<#Gk{6%#r)8@3aIcaR==Cb z3!FNiKSrQj<ry<)d4ZJ0FEvi#^niw{bWBt{)V20KIzw@NaHG$6neKh!Ut0D5S{#ca zvyFf5+s3Y;f2Z=_qxT$un?}*L|B5wn(T^<^AZGI#x*q(_cjFVPQvtOj?Dh1Y&Xobh zbHA36Mdp8Y*?(@C4d|wHj;8fLozs_1X$i<3S2?l*bfxVhsq!GeBW`NlvT}X--y!|o zG~9roy&o=sqXOGvIL(5R^)Al`@NR8%OWBWqu!{Iv2fX67nl$Qa#G>2{qyE#*IvdcL zgwQDB67?PvqhEbCQ2*`_QW}#US(dslj7TX5pPudzGHAaZ60Q|4<Xprb6Ly%%!8tEc z%>3(;gYHOokz~;=bY10)4H9~rd5^QD2To~TvpFqy!+l(Cq?2#Ypyb-0n&qEi`)K_) z@5&yi<8)uFrA^4Ti{=mf-s1&aR)@iD`;SwR28j8WkGVqsFinLBK+Kngih0WZvQ^{$ zyr%}zWwLzKzi#8WbAzJ5$n={NYko6eaF_RhZj8D@`|6K|!+<lK$*xC#G7fdXMczOE zy75ov%0hwR^gCMo76Rg|haG1)#7#f`XgKn|%r*-ZC4VYH^rHk1nL43~<L@hu=a+X? zI=mDyI>h;>)p-fV&+cDz^AG1f_Jb#MSaf-j>JLlBEDOd@S+8^H59j`mTt=OIo?2@R z2M(4X1<cxF;bZ7HyYew%vPK|v?*LpwC$6*!)N@&ZK;I}{*v>izDT+YhIIbZObSQ)U zXgwFC>X^KDQ*r!o2f+B&ApI6T-&rE@+q4ft2^vLP==hDF>EdVu<<MI*v>Ira`Db?l zOHi{1cJn0xPzq3;ty5&&FdY|H{qf{z;v^17apXII{9qiY`x1pu1HKUn7_LvC4o+Cu zAQb~NsE;ZA4V*iLT+#X8LD>-;aFk5?`F!Izdcd^=@SuWT2ix4Q4GNWi>l2%?pD}|e zj(0Vm?@5oI`W8SYEYIj}dOHah+JPFcAu~X_UDp6&nrH1dZn*ma@^I+s;aan6V7@_B z{JT(54)`?C?!*GRy7K`iC<@K{47k)ND**9yYdlIT0dKt|?w@;8Sn?lF_&-CIh7#yf zn9e8g)NHD20DX1~DB^ngUcobHK~Ja5R@b@Za`0yaH$VyzmAgM)ElGkJ20L7phB(F< zaC;>NBs)VE$yes}?#XHm$0U&cdVSSJ!eWjV)WgbRwWxmK5nBqVLO4~M`WyufC~|}2 zL|sg<&TJ33jR<&Xy&!{9znXg-O$&-yF|!U7Eg&Nvh_Y*58Dh2pOsYAk!80E!Hgmni zjgWZ_ZNBXm`S{06Do$IsmPFTK_G!lyz(-q9Lal5I=!C2X{V)`Z9KwnVR$TmvG5v~W zwtR?#-d!!a>KdRMD6-2~$CXXFj&kNX19=jTH_RyZ7%dj1VF>Fo1KduR#t>DxgFjj8 zX<fQV@9zzPW%Slj9Iy+v{7<9v%WLI<DVX#O=m-2*xU`jst5fsq=0ALXL4~_z535(P zvIT70FomZIERCRIG#5V=hbA8;M_UBzegB_y_y0l|m|re&F`!h4N&vG?Pdi5lVqx2Z zyVc)XXJ|~bNk&`VTn$OGEI0ZTRDs!YsR24i+9gg*hDq<^IS+wkf7$^`Hmk=jFgDP= zHf3RSHWPRfj&i+(Z3n-IpB!$;`GwoiDPnz3o#O)~9IwxQ0P1^_NAA;9H{6yVmdAUI z;ixsd*%wLuB91@q+N6><2`%;J(Jwaa0i%vjy%RhvYe3Tt0)9Hu7A6d?mH<3F#ugKR zPZ8z=<(Y3P=h9xS=cYNk1H9h}3Q>N{%zLyr0RH?HGHD|CE(l`Hvx@qzgBlT$n>7to z49N`@AkJxAGG3o*oxvr?dtH_?l;Vu*<e>xx8f@u^1t4{}-dKaZv?cMAEZ=;PC_2R7 zEZ7xGz~e;&Se3&;ft@k8<T#K|A>AI;F)51EA0GwaZ`(6vAu~VG8x-`Rx9WC(kZj=S zx0PJv^-RFZ(TDiq7?GjY{UpXG-~8Zj26Orc-0sT6PHc}ls~j-E_~d?D8(rMm;EFsR zh_Br}&=gOMg}=w~-?L}vL75#;E}g^y)t^9*Tzy1ReoR|uDM!^Z$c5;%P?tGEVDPi- zode28r2~&_XkdXu?-e3m-!3cc2PLGv1%`FvC7P88K+enNXR2b`I14^}mv=A=B<Yse zdFbFYY5}X6AAHzLtBngxk8V1AlYST8vE$mlSKux32{0x@z#A~RzP<r5^6q6`^LT3% z=@-59B{kp{klIfY$oSCL?*InowtS%V@@0bhtxa769mH$YC8ti2UZJl-udJa+P34(# z-~z{7>t2h>yK{W*aWlbj;mf<Fq+WHD{_Jd3%jg9hgSPPE4YcKhq0}PB+@AF(=mH=; zvj-*p?KkhXgkoLR@bIo_;QkjtnB;!TgYAM+{VoybUI6;ZIEXnHS#|agrhcimmv$vF zRSr*AodE_W3~Kx{sO)>*zrfK53AIeQgvollpd=BAtKH=(kWK-m;u(PKlEV)`*}3%Q zXTXD?1bq;WxD03kj)CGq6;7{yA}b%;1gwD-=WFkyEp0IsDq++IHK6jwX*8ko!yl|n zK1BeTW*07RD7mDv;kku13mf3hdC3!^FpculEb0TbQS|F<4(jQV@&30U=1}v82Y~JA z06~VS6bHFxV`M)dHu6aKKvZ9%lk$GGHP8d_GpKILsrgIEPuCTylp%DWJUPaz0AX+s z=peJNDAm8sG1Zuc0W6=Fx}D9+g5J<fVa+s+C-J8&+gutEDSMe8l^++6>JoIQX-Ec< zE`8#Giqw(m?EKA8spBUHkEHxlU*C>h9;+I$7BwJ)apP)-UH2Y4WamE<mFLdPu)ZeI zsWzrkT1O`N|Frj=QBkE`mx_RhqKE_qkuo4iRHEddNX`^U76l}$K!IcdF#;AD$&zy@ z$xt9Dh$JN=N>FlEq7vs^yZg0Ysc-(xk6AOlmTS>%b1U5EKF>b;?7h#ASDuGvo2$J{ zK?^_evvF8r`{y%}Gy1kE^N(}Ws^ZrI%dAuVe5AtJ8non7Q!z_!F9vl<9)Z_4Bgd#y zG<KSV&H(EunSuG+F!7&Vy^I};mI|+*QXhRh?c)qxzmE!x&OZ}<IQ%$sgJr(70{t7G z7Bvk=0zabTkDf!SGFyQ!S)}njEoJpOz?t9vj3dvEyZd$DrvUXDziC&R12~@-j|Hf* zHGUb>Zk)@AQmA>N_d&9w6Jy_-Z{lk0%ZB;xpxpn}AR!T@_Qhwgvwton!Uz{aZC{1~ z;;F=l=Y}bCJKl>fDrJ|;8=j|m^rMAI&PesLqv6L5v)TbD$8nn9Qg6@u^R_->U{E&v z*2$^buR>$Nb^rs^a$zpp>c-r|H9I!G(45RKj(CH`ife3dgcqB6`#IJ#Db=MSs_3kq zAHb2jRvi-kb`PZG<zjL9^Sy|`cdl|#MZ{PFzDf>9aa<|1RRS{EHdlZVj)J9JuR^|l zVy$W6#GhD<1^F5e>g~CbrT?PbV)Cr+i_mEzS{hT2&E*~ewf42~7>7X1fy%OhdVas7 z<nmf(RL7H8?P^}_^<$i(N}W3EX9i~s1xL_o5|in<1L}`nIP4SHc6YQPx9>Dy)he+w zWS}DM>9|RkpV1UmPLz4>yt-L*ROVZ1HL&)4PbXK{6IoG^LC)S_|2Bi1#Zb|U<ASrz z)WOVLj9FvoyCaTeW<Gi9Qrfr6hQ{fP?$$u5TF&<5^LNm!YJHg0**w?j==(NHF?GW+ zfIl1!hp=x&(GA~zhxcMmu4jF-MMcP!9tj)!sjeA*xN8hfe%)(1UgB#s!O*{0F06`T z8wkAk^^uqMH_x@fI#$(NcLx5%_}38Xv0XiDf27^3F6uef81<o{y%L^1(h}D`lxnz2 z8(-C=2`DGdv{Jkwz}&&tTh72DC*@aOWl3q{cUZmu$R;XF_oew5m~JV6-Kj&bfC5gM znZ%AOQsc+4bM&HM;`dk7tgP2Mjw)Jtmegvhigh`eE%nGRRh{?YK#P}s$F1}`8#{ok z@Qm>N&@tvCrj{G50iRNGz1Grh%k*@Jk-f_ES@g}`y@#~dE~9480{a)Oppg^Dhcbt# z(4jwjit@qX^}c7@a}DiMvxwGdT%WHVR9W%mz(j1!du>~%LDa%l@wC-#Lk~}gE|?j) zT)oF+`Y#*k?>Y(POoHQSXdi7?&W9(?frb%wa5lpwKGA@#VdsZ9b~lMmMpcvhQE{ko zXU0X^r*2udB?T92SoT_-6q8c9!B=GaNg#KBG!yk@bhd>@HLeb=W+{<5C7)6@m4Ni5 zC*q@+3eUXEsRf^nvH?vnk&vz#LL*hJO|gp%L@`uzSjEFC=)E@A_n_X>6){+j#pJQ= z?U&r9U;ovI>WjsnU9&S4Zctcu|K*kh<k~l^Rho{ykc}w6oeDZdB^nmI4!!Q)ucE1= zjAq{1UQtC^gIVrFx_(sc3H|`v<ZITzfUmqX4njvtg*&Bw4+58~o5=aHz>_~rh0$Y3 zN4P-YyhH<H1ZU*?e8O=^_9`gdCG-sT^gQH8(`Voi1qd&lp<~eO*x23!nN%7*HKzI| z#JW>l6Pa~uOOrRCG!LEmGE!ln1&zY-vH;e6t*|(@3BHvOYw#Qua-t7p_9@n+R;8J= z9I6CQ7tM%!m&YoAhr)-)1ni!Rcy3of^TqSpRF$tC<2HIw9Zh2;%HxdR__>pjX2ljs zg{xft(uTOg-^<_7oPGITd@R;^pdcRF0@cq|JB!qAoSL+>&T!-`6j}6S?QEBvg<_|S zqS!!?-%HY2qCufEhb`Os1>397kuvn6RX5+q4GbKqUaoLYSs<3QErKOmEfP!mS^|1= zN8%;P9SqNZl_>gfh!h>0_PrgzFEztn#b~eDqMl}0hPPHjGr%pb?xEAQtffkHfZ>qs zK&8uy6lvcbFjO7CH*jJkoXIX*K+Id6=7!Z|OkTPBR0TT|31WbHGXRaaLB(y$Sd&lJ z=>J6O8DypyY|4?YBP&bE_-pWV)E=J^D>dGJNvh=h!iPy3c8|oG0se_KK(MoC(OtuF z8)Kw$fP6e{{Lgt+tIuy<JKYwkMenQBU$0ewxRWc&U}+Yb2;Ro~$QkkqmX>=R1V4~M zhHdf3vy+)Q(1O}NaU9dBo@(8byJa`yMiQIbWRmK`;icv%@xf69EE5+#YQ0DX|Ac{{ zo>wJrNv;vPCFO|(ehm@dPiG!2^1wXQDv_(++*+R>>(;*&fM!~QQ=GZKgL!#L6|<T0 zmx=yg-S~ap*@tji{E53Rf58rJ{7M2@dF&IFXT>hY$bE6E3vRCUS(O+I!7ufn7fR?> zj06`iJv><SQi~$>d#+ClhJA7G8tem{^YzsWJ%*sqQBVI`es1l>6H@!0kd4lz5viPc z!JMR;VmdAZi}=KeI8>S$pHs-ocGO}f*<!Q=w#xWB`l?hn?6o)fu;o$J63$A(dj&m% znc5Na6JU^L(==KEf#(u;%fi36Y}O2D9y_i0sclttIP{#Hmgb{$@<OPO-YLb4_XGOj z%2m8^9-2W@8Nv!^4NvHPtommj>~c?XZ0*U*Y<F57sR5&0?_2~_mN_nqErPQlocyYA zXfEkqA-6|+q|V3hH{n;cMG7(Z!T<)rzJ~{w=K9y;k8S*!l!Nk??B1&@EQp>a-g^hg zTh3wUV;!X$<jP3A3H24_=R9>vQGD`GKMsw9DCx2L*91e0rbC$1ow#xno#_F5MUFw+ z3LUqRjgiMP8s5oZuM6VVaV3h;JKxaGN5Vi)Z4{<YepoADw0Jr%%Z&d)P%UGRt@?N( zR%)0cBT5c!Fg1`)>pm6Z69U?*SFM^22^X*k)=!d@8g{d+<`Q-AePjKlmK<mL!lCV` zh84NX(ugd@u3QBUjIl$F{#7%q;kgmmY?i?+P+y<kUdApO6upu&JyNgZ5Z$B&j<8Wd zx#}uj@^Z&qNMz`#6Z@hnHG`-bv;xvHg)k-<!;?i!@H~&Z7jbT%^Itn|li6<XZ3Q== zntQ4~qhJUjH?pQWJ#=cKE5<h0R|S=$`1aYwz5l0J|A$~3Im~)kD!jFEzAEKCyi&)8 z!dZ`l0$^}REruI4l-=+?^Q#8GPGYK6=zgwJlw<xXgje;VIIT9*S^Cc%ZM&<;<w&ky z4IW1)%30uC-n6KUMIvrMuwSgd?OybK?7e3%z3r!>pNr$4a__9UBc2_}))t4n-2En3 zog1z#Ki7Zjg)U9GP*__I0H<sf7T(xohL3CcH7(7e5FgqiB~tLi9Fo|$W_0%piGD!x z``k&9gqk`2Z+M~)*RUzCw8Ff|3u~i%PElxAgKV!9r3e;5_kK^US$-%guUceIlJ7>h zrS3x0JhVbSqWIdx=|w1uCTvajXZb%hh&=Ykmm<WimJKEk_40x|{gT|-xX=l!N%QSM zk-78a=uYYw;yvg5#G!4GFW8$K_0Cq4<|O$M4VU0}eI2wK`OD8${f-!8tr7`L)54yk z)u$AFiv*!yCOv3pbGD?adlte__K~XFRS`vi^nrnbdQOnUo<3Smb+<o=^eu2|blg4E zY7-kY*C!)4QlF&AGI?~Wv`Y?=CmVF!$zn*>)9MP%tkBv_oi%d*UT4?Uo8=?qcfvLJ z#UP(kcxFAHg&P}m<#|3}mZRea(i?eux>Ogn4r9JPX6eh9TkP6EDH;K~^^ZNV{6@A~ zKearsJ6pGdi)o|4qV3c=zB|%5GoihMs>`566-|Ed=y{YKKZSqZ=CtsSLBmZu)}fA7 z)v(8&blN4}J~4UvI(dC1xv@SxhKI!bKpBTKA8ib~LTjadBhYd~n8ZY{`&M6ln=BI} zgKtax+nrru;wKm^4d%n7icUhxE?L1I@*|+cv(xGdw$qGE#Y*pf>=Tr3OA1GNae78p zSa(mt0J#)3?U|0kxN?Tf4C};9hhSTt4@Xt{(rQU0ZYw%5JU3A3|3Ymvb<yBj@VnXd zPwg(#@y(rK1^H1cFB~*9KaBXWdwH$3mKHSgk>Pz_q>okISQ}s~R4PufugVPWNSG}@ z2&Jj@#A@v!LG+zcP&~<=cv7{vmX@zIXuCPk_NN{|4vk{*&DILy!Mj6?WO6ef|Mle1 zp_r;Bu8K(b(@ZKnH=$*+{N{-2oAQIC6?WyLPZqkEG`TLeMg?9PG!e5@mrAcahjHj) z{}tQu8?S+u8Iigw^*^#bVk+}0bm$#KO8Cx3rD<xV#MK||=(Swqf?OB=?iTeh_o?fp zMeM^H^XY-QhUA#$Oe0O1$iR<9`Du3LE|q`cVXQoGx=L1O%Qz*@d^oC`Yi$yo_3|n$ zIqQac7y9;b{%tLwO3hV3w|2c_Rz)=cWV|dlROyzUb>Ts!`g-=R%^dFzTAMl*XnT{X zD>nMWCoQo~MUcrL`2N+@;j9ZnO(c8|`bOS`Ak3?6LW-SB=BxHsKj|N4A`wD!2bK-H zG*9p+R7+o^*r<Xw?#CP52}_x5Nq?S}YFfZy%P_Zi{&@?K9&0<2Sn>2(7$GYDi2`Vi z)02M%V*NgR|N2Q%4=!r?y@2OW`~mxcq&oDrXu|l`|MrahSJ@?}2;Bxwacu%d2ufBq z_<|FI%_aWWRDS)dC0sP6?rkHXzmowk2wJOsX77K!)L%Vh6enD?@W)kx8Gq@}7kQ!( zwfUdY`d?R1hKq*LGO-hCZ%~K9T~n8T$+Uw-hTxAvxM=&=8)k(5E)l+OHa5!@-+vB~ zf4wp`94@Noo=s4O{eSEx>i>Y|rWt~kBoGCw7N~bQuM)gH4cX9|p?wcE-E+v_dh3Z~ z7%72Nke9us`+r(neYLXKu<q4I1QwXLG#&I$q?NGfi9vp+KNlF%UxFJ@<o684o-==# z&|UE3LL~DLNY?`Pq86N4lM<-Mm0%wYscmxwWg*XWPoAL2Y+(o@CZBLsm+A(;R?FAA zr^*oZbgGBK?)*m&(jJF+OrT-}SJ7Mjg6lGZLhq-+quK03vfn>ENWQadR5xhfzt+Ux zcT19%oO&H)4b;0i=rqj1t7i^+=?mBW1QGo@l3`?#p7L!HAz)tKd@s=Vz#51G{<n<I zF_w^w1MPZWscz_0w}3p{)|a<r2+l`~wUt?G0AVvgvbIJGzDHPMgblybu}u61;csR@ z27jlc=o!F;kCq;5O9grJm5YIGjzu?~iFG46T`MoE4d7iY&ZNOfKK3`YeC7krb%&T@ zmv``4wHe>+n{h7nfcDO{8+vzxbXW-z1aCAUm{jz~knf${+BRe1f=J>VMZ{-Ei3Y2V z)PUzaW>2DNRx@7#z0Ab}3in6RTfi1afxh;Fo!+-gAiPjoo$J35qLY2qBp1J;x32r8 z7w9wU=rlpDhJ}bvfNgUgGPV9>2enb_5(N6i@02`2Cf{W;>S>fU<fx5-PN(QYW-^jh zl=DENF2o1PIQ-}WYVixcdk+N~Vv+t&y0C&WjTX7r*4i{T19gT1q$)siDu_iiUr3Ww z#4wp!`Vis3K@bU7>rdYwANbl&9~L_g$c1AKRV51XS-ItG+84&UHR)bwXr@I$Y@md| ztp@B#L{aHvD3M^#Fpc;$WjT{JCqCDPYhFuvmE*cRH3pfAyu<YYyi=qZ-B~)^9c2zT z*W-4`%V0~CKg?PTl-+B46Ln~r%)0prd%6KxY^#=R`8UEWFlhz-sV$u~w2P2@j7_vn z<T6ydNBxxWZmY%pM~dz-nSv#u)q(-Ueg68Z&|u>M9=50ha%$qP(ure?-9c?LyX1RN zxS<e82RkvpYviMya2`2!WTM&E#gD2PA|hGflV2`wFx8B9%BULxO9qSZIs6gR_H%;5 zqc6YJ_`xcHB`>g_`V(pzI(q`DqTlZqi4FVnHXFIkhP`!xOw(cwg%?`T53*hE1O;;o zV%vy7dKk^j5eC;A!#SgG_74$DG?4FqRk#6<$MOByT#&~GVqg4_xwJ%<Mx&oKd3m7t zng!e}wTuNs2}EW%Xsi;ZSMu3j(L#>jy!j}vRVQl&1^Q7JQ1y;(N`F>1aG2rL6M9K? z5v#^*FpE~Th!IbN;Gp}<pCF!`NhJ5ws_9IW*^ji>uF{}yi+Ey3>r=_O7C~PY4XeCY zMI0We<`Zr+hYj9%b|2Y`R!>b(u8A@-hPI5zJm`N5_u!^|nba8Xyg59Ey>zeu6s|v- zEU{})1qzlv+7xvdQ%X|c;78k#?2Rbl{qd*h2X-{m49Nlt95f^BU}VYhBs)Ln0hgN! zm9SUgrdcnO3!v>VGrboE(`X?Il&3Va4Yhz!ov|kl;Hb4Bi?A6IL@pF1La;<i8ike7 zRp8S749W4eQ7eef>XR;`uw%aJ%>(*@JA^Z^0tLvC`v-jxUeFbtr_WP(p`B?9LS1vD z<AZo>1FT1HUE1?1{_fYusbIcv!Wjo)kO%@TAmh9?$0fEOQxxY?OqHT3Ql*Ar5$U^e zMS&Zi#(m*M@g%)ec*xMsMz}&E@`11TA2q2DWVCMKKdS}X^ZuDU7FxD+dI?W=o7;D7 zXFyBM3zFyJPs%I}8qD2DZeU50LOP_4@~oIjD|c?~J$T$=JdMG$t>^>K!k!&xyuBK7 z+hH^2McOj>Goax|Ad+%iQ&J{7#j7gIj<X_0XxQ@?IF7`8gPJw+S7opgzZIc^#k{5v zJR0ycg)JL4lGE=m8c1yYNJ6qpXT>2XgNkBhPJ&T=&j8Et;Uz-GDm4R=C$?C`-ok6~ z0X3a^ZvxsRg77$b#0&$WX@>OB(#kGmRUwV9R+0H$E??NYFM#4HK>y~uVCFG|&+0&$ zcSsX&@aCxoHpBA5GI%OyOO5Q(GV3)SA!?RS@{>@>$@Tuw*-y)H9=`l&iseFoQjebR zA9kL+-odBTY<xL(S1)(#ufz|4U8l=&wy%p+6Ap=rpWrR=mu83EFY|e{UHQAJ9?5yc z?LX^ABE%Bw7;Fh$pV_Ijn&Egj<9m-#<dsjcX;wJdR@exG>ApzKaGM%C3&93X`D^fO zbu`0KHFrsZ=dh`z2-IhSwx5cN#&groWzt(OPjy9^y%u8J^Cv)u8^|h;^#7>}eOTzO z`qfNlJV4Z8knj4e1xb)=fv6e!_2Vn%gC48=Akvn$(S{e#e6eI&2T#G9;_+(r(q-7n zKO*1C)b+{C4;vn(tMrSCH@tS#8Gy%r9d;Z6UQp6nh^SRCQD;<`_>xj6!A772{n-VB z2qXma0F(IV?5hQ*?2O<HZ&sIOq+uB8Z_z3WcN6{!2e~cC9=@2@87))Gh$*YjLeuBj zba6V@Q?UQsHCPS{2i5UQ#*IygsOpl{&lxS}UF&D*qQHTs)#>@rq1e|*zma8i=3@sW z*nVKmMkM;fwCIS}RUYeO$CB9XPVN*1fNhu!j%kkZOi62?cCLJRR^O<h^V&43K3zlS zauK8R=YkJ!1KPJ}fuvg11fi+_eFZ4e(S}yQ#PLrlWT@pqTRjzuODACoLd%2|@RPRu z8`YJVL}1E$ZVK&0tO;kxLi?s`gQ8o^HwVuyzQg(|)Cz@_Isl5j6A^l3hndiu2qa20 zyK>TXPBySv-T5oo_rI`R9mtKcE*gcsx&Y67>p_FOcdmVjq;6?{mM!p0WoH3_TkFIu z5|Az7w4jbq<UaloiMIL|h(=y(Bnp6ZuHhX*BB}-rC<i$3w~q_#_%#&P8j6}Sr#d0y zonHh>5hO&orP@2af4&;*t+`N}jP}utyYDQcyg5K6*Vw-QtqFlT;{SiZ|NHOY|4@Ty zmTP-$E=TB=-hR>M1bLX2phSvqUqdvc$QBNU&cbzWs7n;4U!LE&67Na664i+}K#x4+ zn3!wfF%U?9%s06-V?)ErZ`Ijw9NIiC(m4Re21t!K^$PPBA3};^74$uO%UwINb$K0T z3f@M+7GI}qTxOqg48$j~-D#>!9dM0B*t(*DQG6TD4kwM!(7ioM@8iTMytV!P1PLtd z7f7Wu{rqO!1(4f6xvZAJf9=&SO~CoRJmiVga{Lw_UU3+fcRtW7cs{`3cU8|R+P3(y zvSGn>zp|A+>)CO{bv37NqIVVcq}WNYBM@-cA<wMo)r6~ibx+F%@_{5ES8Norpra63 zReb=%r>S(P;3EGE_qUaznv~TVx(aT{GT5}l2z9vs`0}uToE>c*3+I-d`tV*|yF{Wa zAY3D%=!^bGW`Nj~TjwA@{a5a3C_$~DG}T{Fy&RMlGnUq(?0B7Pqa}b^KO=F#DpP~i z)yN^~F~3*$R}Ep{plm?*3J$MNLyE(;8HSE+GR4t}1ABe5;S_)Gq}nOk112#+hxOSK z2AvEHU~GDfU^0R2j*L1EK}(3{dJ%Z9US5fRFt)4-g0Zhd`nKS$fzLAl;+&2_YUy2F z`p;s$W392)@K(7*%4DCNNQF{%1<zy(_0hY}payzzvMch!jplUqq#0oyLrho(2qtdR zxf5bv8WNCK2T0Gq2#uIenv6WAkJQscZ5*Vu%j`#+;k;!mkE-QHU(YDA>+g$!;B(}K zNGcfnNQyVq=w#q8EMK{x?Fbyf5F?_BU^MasMCa6*^9_)YlKd->z%xvPq4b%-Dy04L zK#X>=Dp#i)7_Wp!u$P(-%N{>mz6Is@^-pt%h-R*ISUTdyDMC++IWeFx48VowkkB7_ z8I4va=4wE^$z?ORrbJp^ND+eKmbbsc`H*2eiapftF`=ct4-m5Tn@5MuXL<`(-teoS z5ia4%ZRnU$HqYzzLJ{Qvp0ZD~>omHKoJvtKBm}m5X*yUv-5}|2hPvE*w~E-Z7C_Nx z(W9<wL$HQy;!l*mJ>eD!&Cgyl18mA6KmOizs3NT)_Q-P88A4|3S8Q3n?F6}?O&%ty z6KK$b=UE+<lG?~dqJhB7<FEb$GohX7a>XP(ipg{~|MkH!0D1x-Bq&&1y0p7@sKysz zNM;H_)&F6p_><iV-Z&^_pUJQ>=hggINH&;&WCsuZ5+1k%SH(XiR|vbxdd7Qu@2*|j z+sdjdFkD7r3XvDh_Pe;#bZu^bf6shI@<#8fB;{o_tE6lS_52y?4@^Ho9^QMTXzTTa zI>T&lK_MAAPS=b4iRbRaYLXdG)O2N}OpizrrAX;YOOl<D+;ji_=Ud`wtru6vjGE)z zLV8?65!tDOdE9W4S0&SU%yhZOgsk12>1`gfrcf0sIWqv5iQ9!*xdytz&T|}4C_ar5 z_t0CJ`FQ$M$t}Tgm^yL_vW)oF*KUGC)&Bcene|d2Pui<I+}dV?PRp9YeF?^5ueA!= z_GytGI>Ese(RAFn^tMzzIBt!zL;#+IL)ib56^Ef$yLCZll$@FxB>=T}IK;HO7LNam za{f<Ak}yPK;C<Y5a+*u8u;E~~JKhr>9aA6@&L-np^+C9y6?%q+#qGYHHbcMF#Z=qn z6WVu3bzuj`!qU`F!`Vg)-r@qymPN5E+fKv=kC72-$Tz#WSqZkDuwyb|adCG0?>~5; z0KAVGc$GAO!m2QG&PFN9-Vy^22M1;3#|q~>*=WdOZ2*cV8P0?g%dMy^)p+rCaOLPi zve22cXI%@Q1_Xow6jhLudn7Bicjv<akr<~bze$BJ_t9IVBqv9<p#eGbBxPhf4Cvp) zrgV@NnVOnLo_jo(Z5ayFLqdR&b2By%#QSDLZhYh#nDG@gG=eSeY2#fnFe@ed{d5L_ z0-lofxOc)noc-cjl}~nz(L8rU<K%K7!PR(tw+{!m4*Y@Pgnycac6sjtY4*YzC9$p% z>iC~DKAbkYPpO^q{biWWPD^=OQvz&>PN$`%B@PTO4$4YO{<<?_I)VuVf_0Ec@X!WS zmRfS@IYJvz0VvdI*d<~KfIYGi1hS@S5dJ*c086irraA0Hp1Ztb;G&~iPn-zdmO5~6 zptCm|3CaGkn!9z}-77_Sc{P`e;r^)PB{33s)4Padkc%XLcHC(lAwywx;GI=A-XZjx zl0nGFJtr7T=rkKa!^h3DH~5vDi5&6&Lg{MBNKc|s`R2d><3In83xb%lj`t9{D0K!v z`yl&{WB+xzzkXBF2q5|b+gl8wi~c|V5s?Qg*9gxB!j&+8{{tE5tnmAOexp;d9qsKS zV3|!^&Cp1Ba{2P*M@^%RU1AmlyAbX~yO~T4EAOg9cDNz3vpm#*T{OjOdkY7t&rqa3 zh25xeX|hACZ=wd-W9y#K*e^|}KXdr<<x4vl{w8}1lKzJc#`_%Q2Pth=*YZk`xZAHS zS;o5}=P!^H@?XDxO$MVM55z4zb7E16!2%YPH#bj}#V;m+SHAt_P1Tz;>x6FmZdS^C zu(8jEL)Ksew9^mh0}nJZS1}(B!15`nma)fj*uH!Y&3RC_A69wJBjc#>BHU@VPu|h7 z@VQ2MO%DWcGV}9y#Xv71{!M*-l*iV;mhnF;mW()6@)fD>zJ2?6FjHDdfS1gU3EIU> zka65}84eIM9jx+5Z4_zHgJJ-jk{vN1rj9@;8JCP>qx>!lro4KJd60&9*4o^K?9P8K z`ul~5!;#A)dL$10;${mVL6ksI6soL3=g9<4L&hsYX|yUa7uz@v8oxAGhHAmR*t+OC z5Yr1adzm5~V9>&0#$_2o?Km<e?|T%unA4fyH9QH9$K`YB*4G#%JU`zE;Gigt1N(GG z6>vJ{>UWLlris3F6MZkgU0Iy+`>p-{>96kqaz%XLM0v7Ro{)<f&EwE3lq<e9ICt1| zlAFfrN6IKb%LoXqSg+gwTyB0jBF_Ku;~-G*{jiZ`CiF~y-(PCSv=*d~qt$k<;6+aU zy6wvn;x+oW@XT&2GZ$pbJ<)Jzy}#LU7%hxzEV~lU+b{(}0o{rIo;qUPDy?(^#|M!n z>Y8shkZ|u1Emo%^V|IFax{c5C=g)brzaf)XRb3^+Me0QcJR#q?9it{lhy)t!12fx6 zJ^|p4wT;aN8%h(H6`Eyl2R5`nfs7KB;E)i%x&hy<YIP$5FyTDWZU)my3-(xn^!;Vl zmLC$l9j7|wq4~pstZfLZRB)R6Y}q==G!KI-uDSzDo($EKlYYOD$66thako`>DYk0D zzD%_5Hi6ZGqP&Q_z`3>*#R#Qd$1k-c@z?2%pl+1=Iz0T6L>H#b@IHN$mXh+^8dI}6 zF=6re(If1hy$2hBy8riDUz_n&*!lT)dB370n?NZ(4h{|;0kL>EGO+3r2M>=1jD%u^ zF=#>DRX<MYV^ab!BfoHPI{UMyjC+MO6lHDH31J!{eZVvvPgP~j;1Re2HQ!n24TXb= zBuW#A@nB#T*AL(dy-BaJYiDC`ybaVX;rT>P!zLHOWta^8j}yzsf3LycKmD~Dg_+f4 zwJed1?dSN@+wIBn=J+h=+q?tun+N{|j83jW5H#qbP}$JuIZJj!nWNeuW(S(sO-!T$ z>xILR$r=g+bG>U87U`m(IM;y3{E(#K_!O9tcrYM?!h$N?Eru{K93dly@kei<JPQM0 zNpEY|i}&1IYlngymRkh0vZ4-ayK4C6g4ak6fUUAV!F?uF)cf8+oTKX(=%cZSIL&-x z&r2$V2?}SSzqtJA0m0E{HQcbThS$0M_+|nLE7kCDMyX##G!cAIyKg|W(DP8}Dp@ts z{s+bWUa|@I$%$pKXz5uOPC_fe0LZ>kqNk~ZcHTM`z!dH)ON7o5?0&!$2G`oC3BBYG zq$mGAE^a5RgH+;^zzFW=h$4XL$f)B18hroQK`{P|3odH!Eu%^3Q+$QsMmBLbSAs>c zA6%3x--3|iQq7$x_eGxF9WSS$?9%?{I5UN`uWnQXFC#f5OqBcPO~_o^{P9pR+4o0G z4fj6LB>1(l4+*<0B(Gbo@&DZX?18(!WLUS(w?qiu-Mh!M`-rKTxp`yY59-OzQ;n*; znS{PHN>-!YJ*#h3N?%J~4(3XhPjcmdvT8X&DBEt=ZV95?`$rzzMU*lR>!oVtXng$N zToh*esc>f-JV#~SmDr0X1bKfP$)|HuReX;X=Fj?RE&GS(<Znz^$2Rm|rCr_Hd4h2E z-aQHAuyV{C22NlE+C*3|Dar#gvWefbOz68zk$hFOYW(&yO;g3l*U<xI7jUkxDi>gf zF|F|-8FNWYOf>!R?aS^(8&NVsM^D@S-lzEaN2)<8oQY4i_H8Vcx~<whm+-0*QpAq# zeQdRJEhSLzi$t+cN=J#V^cj8pR&sFn;*@aFZRoPuk2N0y&WTrZ|DLg?Z>XK`R`NSp z=~&*!anI#=*-?e=JX&0@+jn<jR|3>G<qsF{dxkTc<4l`rw4hMMj*OTBuTu<<@m$&w zzkHog51QIx2gRN54`qRzT?&edA%{<2Iob<MnJl!PzIwYuag3CLZ|dqEt6VBnxO=x0 zMh|KLOcDp?%|BxR5}w?lCuZ&iGe>|`D!JMsRt)D<=5f)xA3BlLE-G4D^A(4Vh_@6% z1olr#*7L}n%QYxFg)n^FeE`@dK{>wJjzA{po5CJgGF|D69D(5ROh!st1%)R{k>_jp zEWtu~fS#|RqU@qCFWw0zSfwi4tv5Q|AY33{MzQ*4gELbX&N>Q7hy#&%odIV_BVfM~ zkOhYz+r0x+*y(%-lQvD31t-e$Yu3QDu2^s?-hs0b2lKTYen2jP92`H*o<?i9xpxHj z#vx)Ku7<{jhVw}UpY2LMyDzr11IK!Zf+CBru$_v5fgSEU?>fAN5X7hIVcfAl$I?%j z@eYXJsi>$<xy&{>))EvD5z&y9qu5z)<#mu@giTCMll|%W8x8E2r_j7;^`4G}IHUCO z2ZxyK`id+&t{{ULL+q3oj6FtwT&E|rF^*hCP55Sac53m4eS^B(ezKjpZ5F^dg(P5M z)8@zv0`-5RsdobS+da94xN9{;9dp3>1~J^KY^$m-3yH3Z=_&XlfZ!MMz<PNn9Kbp1 zeF5p)NE3H8-|4)K3wQVGK0L@6tYhR-$L9rOWs(7|n{Pu0jCb04Qdl3!<SR8aT3;yL zN04dwNedreu_p&E8LnH}@9JjQ!zL<fz^0XcZHrONwKHbnAdWAT9^u7{x?m=n3rv`M zBb1ZxwmR3IBztJO*gPP+a>Z=$KI6_O00N8;!_}>~w>EjeYPq-oyln(*C0Bu>pY*-} z*-}EV`@#q4vw-3QXY!hq7q3R=w+&rgGf?A<tvx=%0!B%6bJf<nTgEE^y@Wt@Ly6=E z65aBxE-=5gJe`)FD^I9+c~SQ2PjZ|}ytu6@({Z3y_Z2}^bB2wr(db)$xv}RuZtgXq zRfgIolA<$3#<*q&q~vXZGrCDxuz%!5zU#78o0pzDgq++8=tW|^n!nEL2?9C)`0?X5 z!wTxl#w#s^-(3Xq?hq+?CFo_wQotyC7JPkqe0HC&Iwps4Z2=GD#PG%#Tja86u3P0^ z*00jj8wFl(C>K9s$~7rHTs~v>5c+CG_Y)gpQ#AMTJGKus>L92RC`Sc*d)(k*-3V@D z+SqUl8ph|#kbkKAaHSZvhPzdNkkH0kg*;g8CCUJdK=h=)GS|-z&|E+gJmw>iYlC%J z9DDbD_-zVo|6@Ajv!sDYlKi9GfE1aYMk}D^hi6nPNZNW-oo^f>05DK_2s#E5tKt5> zBh7BhGaohKJPDs=?6)g9_8c?Y$KPi80B(L$cWMIL6I`B;tN9!OxnAg*U*w9uEdQj$ zyzwrMR=O_Zvz^8iojhO*MdSx}#1DE9Iuog1N=p7ESJ2$U84WH<c`)f@Un<^tChQ_g zQA448vk|{<d?GOS?IpL2*CPoo>-KY$SgCF#PBluWt*y<I&V)NQ{%HvTOrwy8ynf26 z!?!U)FS!LsY2%$5p@*GP4OpAq%R+aL61e-jz2GmmOw$R)NRY7t-n+MUT$Ip6;d>H5 z<$3XR68f%)LjitCdK^4KO5jGm0>Bq8acqhZ<{<*@Dtm(X-a`cL9BK#>x0~V*5X20- zL3Bu?7VrCz(1ZOAFzu-716Kkc-}@dYJINuG?e*^(<o8cM0Aen%Tq1;jBqgDFOwu_% zWJ0Jo+JL|O8S-L>brIeHDgo{k(Uilt^Mr4s0m2vj#r=UcV52CB&_#B6UkA30P1{qL z(0yyjkbI@W*?IUnv@Js**+B{(l(V2dYn~KoYkhVPXcgE#6|Y}U1Tq5+nFO<G%w0R* zjO5ThsC}TQ<3gfv4?lhKBpCGjd*h6-Vr`%yIgPlDU8Wiu<c{%MX<_lZpZyw>`Co-? ziY`*H14rHjd6g|Cpe=~pz6?S`cF>&h3bIe2*oA~X`meM{1C^`2v_-x11|^^n=+mCz zCrmL1ZH0DF>ZQ`szS1d4rHvEDC;$vP1>HQhdlg%&v=0w4g(DePzQ9Y!DJdy=_eV1j zAS2m;TB40-DTUkMGwt@h@Xt?9oFw^}498_qiV`kTrsL*@YV(EX!^)Mgh-pXSE@;6r zGc(ITpY!bD!-vaUOCXk@0fK5%U_>5NqhSVySpj*573Q>`ddAa@@M{=bAjVsoNd9~k z6jl+zR_*QWrqH??!yr@ZcxhUH+JQ?alvy!c&cGmMg70$H{f7?~L99Cp&BG8R;A0AW zLXAie=?dhk{py}{eZGMt&o<Wh?p5xG?AbFWCMM<*f*wM*?gI310e8PlPip&Wfr1}7 zO)>~u#$pY)BG9(CmOVg0%nSj!!Anby6-Id#5KNa0l;B6{9Ec@~d^HX2CSJ`8gD|R? zms68FFfcG2I$;J&F4;1_Jl~#WAIi%XUGduhPDY`pU91vq`}bD=jjXQNuAdF6=4Fd< z(WB7Eh8fO{x^)ERtYcYz6$gB6P}{dC{=KW4S6`Es_GyOx@ad5P)veNw(mOX?K$g$U z$Ja?LO5bVGrY7^6X8!Ae)}=n!WuwlP%{G<i1tv#<yLj?b=Hh?=uqIGnj~Q}8B6Mi1 zh_iWC2^-%BdN{y4^Na^GgJJ)EOlk*t&q2w_XAUudnYU{Ame;y|o0oP$?ycVZ7svWj zlU}*gFn&z2&B4xtmMa2iwx3p3QwUvR+gJGAEsj9hE~!G|!_(jjvOZ>U@qx;uE$O%i znjjhoMR*z*aB~)DT>f!n#v@`-{@8O^`)wd2Zw*4Y%(UszhLXzCqbwneST<SaDXqB# zx5uO(GG+%E82<URfPglr%}!STsN)`i-eU;JU5%-Z9BC1nKYYD)+EF2a%W*JS{)o_> zulFaoh2}n$yf;XjN5&Gr%=5}dHD-SJrm#I3DoIhrH`FMPH8adR3GK1j%f6f*AjTGq zzWHHMm<O3gdR}=sj=qmk$o?`i=WS}qkW<2AFZ&V?%TEHk@`yTW!Y3P;X<mB89@}!5 zX_*2|suOv+CSeb>_4p*GfPnotSZo{3VN}^W<MvQi&r+GabMldJFx#0kmlygX29Oz4 zyr-ip_ppeiO`GB23g(?!uydt=_fOB3=mmUj-80jA#^rfEB2ASpi_KaxIc|T$)3HL{ zh6R2aO@>jvhD`OO2mXvA-A5y%Z*I0(KBkY+JzW&%xn{}R(kA?#UN@Xrf5-m9%Hf@` zA7@WwlCw&E?AW=aD*-$a7L-YvG?>kE^OJt9MM;kIF)9z6EWdX}7>Pip2QQCOnt&B5 z<#dQ=E>sSJXNTIIs@MDHM?jDJ-sv4scg=F#6bqg|n~bB*t1{?Hg_GV9o^9{x(-)$^ zEyX&XiEzI2;Qrs;$UbE<oDI3tjsqkCOY9@wprEYG@7*@q6d`lzM8DqCXVZ@5z%unZ z!ZfdNu$HiVTB-$X@eVZaN);dpzhYPU{mMH1xQg9cJ0{6-la-U6%kr)hsMjCmR->!j zUB+!^Jq)o%bg4bCk5ISyO*`m8$C1vrr%j_uLB)rIV!-ioR9@nj=a^fuxC~9f9BHhX zeEyC?*1ML9tP!QSCkzgh2B_F9RWXYsBaEh?VwFRpP&zt=IOqQ=8h%ERM)p)WhDPM( zr6fgGDnj;r^P1+`^pn=*BtA)D*QNA{LTSUd?1FXVxFxz{n5pEv;1DPw>T#Z&?LA`I zLFVNX6?6K2sHWg+I}aB>W=cnx4XF?BgX7sfIa$%k31-7igKf*B$#o(P?P^wt#=kQ> zS9$rvr9;n);(wK1&hrEP9F2Adaa$v4-1vtpY5PBTfpn3Ij_zhEzus!ME$|XDviBxW zebY04AIC{gW_U|0)N*22RSKrrsjFXi`7u!+$0Ls&ReUJCb2TX;t7&C^kQ)e2{<Ffa z6A*hL;Eg>ZpEepR>cRu;sx1V}okL=kO@g?{w?R$#>tq}iu9e$EpEXj#JuP0|rKT7^ z2{XZYYLKpqP)>DuFC;9#+=gp4!a?4=1)C8!oIU0eEMDXg4Q%u%b^e+%XQyTGuXqy+ z{|4N-ofU+)G}Uc9%!dbZpz4!9ZF^nYo)m*J`#O%+-1i-S*Yz%ZhTB%~<e3}O*{^z< zkJru)oW?CBLe6Eh@nFX$5|X5*D69CB{&DDFRpB9HnVvpe_ndv8O<&2acvFu<4(~wx zdkWg(4NhfM@qypkWu}qQbL*S?A%yebVny%zo<pK2L_A%5GmXILkA`RWrXh*NS-*O0 zoRNHVy#6P?8|oR;cT_J0!Uv3H_fCEtYsLLn1=X%DQ~skO{I3(=|6|G4ND((hQ?~kz z>aFFx6rkU`IcIYo+%7-w0YZ`%M_I8uz?m#g`<CaOPU2GotwHdKJ{j3(vjg}~#}N<s z+2(d%AE=BQlSpk(o;>MPO`iZZ(sxE7Ho#z*e{s$F)gG(&KQ{JZUFT$ufXz-6>%Bo% z3hk$xJ{*Q==Z^Xy!wj^Iyf!h5tw@I*7~mdaHu@8jU*|#YP$ITLq6^}IaCpo=%{m6; zfQ`YGqcWFeu`fcUhC#$Bd!m7zQ#et{Ycvm;f<Q-$#Bn>^66=A%;z(0&F6!%nuWUNG z9B{_b8on|dRJ|lPy%}@5Y^fGL#*!y^J+RQXiOzYTg`D*F?-PqLLj#3>e`AFKmqWH! z<)w>;x0F7?J8R-Fx+Q2zz>3w7bZ;Ndb9;R-nv(sf4+rD1<QE~NB2`av+0l@3C9k5g zB63PmR(kRgYu4SoRnxBVv^)sxY5<jsZGYpqHh%lZTZz7>c>Mt6G})`I9qW))ZI#|} zir)sO08f>0oyII*<N}({prdN(SY;E8KwyP_%D40r7jGxPxmceRNT6y(aTDccpTpS2 z)}}JUoAOXGWHr2$2>Yt*2Gun{A(wk@LX2wMaik^I7iToify@@DK9i22C+D|pf8)|O z@LtszO71Zs{A<Qdzq;PutCP^(yC}=A8#}e81IU{vDIr_t%W{kgcv<sb0F@=jrk!oU zFZc;c*e1XIbeAcR9F}Je-QJ`Q-P}~dJ&YZTt*9C3+=T*CIA%Pp*Pj`rQj@J$l=-r6 zKviBo2-z^9-!wB18|z~J&a?C<^=)M0T~4)l+822gsH~n`-5u>baUK6s<x5A9E-*Yt zV$CP4L$O@~)t@$&QhLrZGt2AgMLjo)>=^I7m3UBCSfQt}y-m#z9V68Z(jjHRW5<rw z>%<#-fRH0TX>Pd;6TpjCxg<iqvwT;hB+7-H&oYd#ZUTw!TGRctEN{J|U7D2fYiq0D zXiN>a$y*7qR5I*CPo6z<wthq-_m_OCQ}U_wC0awi7>&D7So+;;irw*qBwQmV;%T54 zc1+)dmTgf85Ep%KXQ&}TQ2R@%{Z4To>qYN-2XKg9uG{oUVBksxnOn`_+blFcMnY7Z zT@A`3-GQu=B2f4dsk|z>H7H)fC4NE<7+jUddv^$*p+04G+T8<DTc4p51SQpqYR#VC z1>o<W3{+or<rzz?!rX^5z-pa3eLAlv++hc*N6H`SXn0`sifzupT#-Xk+65k@!UXDh z${#}B_Y8mzJ`uG@=rSo#?Pe``I1C{3Z2ur<$rPY4PuQ>#<s)z-*PyUb7!({2*zv{h z@=gGcEqUYn`bz|=_W%Ea|J$#0;akfQDyose?X8ls1w@GeC~D*jmx0fJOJx3{R~g{` ze74x^b^1%}rW7rp493CL;bQ`XZnYnf7o*J4F)<v7^%0V1io>9+&ZE69&Eb=6!=d$i z75?WZKal>6{%Q_B7jrAlU_5{A-kUdX?iPUrhg6z`z^WjIr_re4e^yojmePj3BnFCV zU~EyyQH8}~iBg(Xv6#8fLT%$&(5fgk$UQC=QQR|)C{jSH8uaMVqvOWbnA^~-mWLfq zugI#vD8jFHCnKs5gGeEe+7>FWW8a{EZwyk1Gl&-wLaS@H$kwdAo%=Bnph0<i`or2{ z{5Hqr<fO)5vWUw5fwGX$&@*0})5gl^^_5wKLc~F;_RS;DHbEOG58Jg;?CSM-sKrAO zwgFDl78j3Pr~n%gM1r_QN}pkFk2D<C1%>l*Afq#RK7IRk8v-MrI?nXAB^e!poroDx zcrRNedDsn9>S}0e&K5)S9gDEc&~lm)-igz}qk=+oDuFyW>2%O6H?+ozF!S<uq?M5> z(evq=LDXR?{>1huw^tDG1$t>SIlTUB9r0UdpnZa9{MIX1TVHwak%_<bbWv|sKfXl= zf-@8SkMUmNi?OGr7+&f*xQTyOJPR$CC9t5lJhvIFGW=DO<@V$WeDDNw<M16qvOmf5 z`=S49w%ht{2UzEhDAm=~JvXK+ymA`Uz#a?HgB$gH7?nev=jAS)oace6M#ya?`+4Ik zA~8SbJ^ntPj`5tCpA3=^vN>4<=Ed;*{PPYBAQ+@Ucy~nKt*$1l{0&6nAt5ZPQN@4n z;!z%(N#ki?om%U-A;!eWXdCx>Jr<x4OF=<FUo$oG`@%&UgQ~JwlVrtS8^cUgOiZ`> ztoo68JmOw|ZgPkP2t~;!r473~B2_vuMo)_ejnPU&DtMV6t4wz!o(|?4Y0q#%1|Gb{ zv|9SnOTzQkBtCzj#(p8oPk71_`h-;U^j3qHdhm$y#w8b?tCzQ89Rq1QJd3<;{v*sV z$eKsmS#B*H@E)x#1E7k$Q3!xcAgPzHv)#JOm%u|FO6{Eh*-ut+fl)YVHkK_gKe0hd zd_e}%;n1B{ID~|5Ao|mc)i|S4^A>tQm#Xe@O}5xk1CgfB-`+|92^Io~#e9EgcF?sR z{c7ufls_UuX=K8X(9PM6cXPfOVQ$<r-Is6T`!OC;TPK#T5IVi7h<#2qKr`gIC`^$N z$5+D)DYucJz~1&CeLcs%ga=pjD%0q;W^Z|gfQ9kVs>M0mXb?@;-ruJI%1(S|k_Bao zcPOoO^3^L>9*9DCTWV_$8Lz{s>1SNKBs|s}9VXmaZesai@Cc%z$2`V&)eS;xz%CFI zaDk$kb?2rgDNjlE1l8oW7JtMj?R&t{3$<F4t{UaJp=igx7hKtMF-8+H+7o!vFr$c1 zP=wk7%NEm>g2x1sy#(CsWeo^BHDHS>X-h9L?^g%SQ2l+~n>UYC?sR@V0K%uD=66in zh;bGN)q%rh>}aS7(~fh}#}LKp!(m)KbhE~oyP*$cZj}&lk($Ae{~(m}L5B>jB^A!K zD{nu3osF>M$h)13l3GgJD3x~VA?ATW_mZ@=-WQ11J?r)3H51NbyB2co?5$3o#^F4K zclI?C?juhj246RTk#df$Pm}RFr`ChF4~O~VhE<y@`n>qt(3f2)*DW6lCp8_YJ7y~O z?bRN8NKADV41$EyXfM~=o^-C9RsJHiY4G(40oE3<)|u>-FlJ_Xiifck!AS>qd}sxn zq#CjA+V0Ap>h^M=``&?c90h$CR}1b;yMvw^N9gES5HKtYB-Vv#rO7C5_@8JZnnrD` zR$`~G0-LI^q_YpN=;@OUD7O)|v=&Z?cw{c$ig<|#wa==?*$l{grQ88ez={LzO1S0| zj~xJo)s{#Kf^i>O_LmnSEons54R%mU#(=P>D61;n`2l<ibZ|db#RC})g2O1w2i@|9 zriOI-t7tBxN>;?2ohE(hQVP->EVR@_WRLiCH+WA_S-%TCr#Um;cJnbXl5hao%#YxY ziop~P?khXRuA#KZQwk=)lNHYME9=To6d*$F^ua}d#1Y77q;XJ#aUu!#&+yLK#v+d0 zhmK!VbG#f8zCo<(ir)%ORFN;d5^Ndk{C!z5fLM1x;rI^hBxy+ni~Ub=wmVa-eR}n- zqf}I1)#pV&SUZv@h9mY(OlAz&Ycw@9E_?OghP}<HcjN$W3&xH#!XeRY#*JSJhL)Yn zptShbj~hs)vhpUt)5~f5gqwiz<NjMtC6tu{gT;PnGr__ri$5_DdO0>KT}C!wlJ&xT z;`_?G->++m!HBI4BYe5@kwAiAkSq$71uPrs51?>^;eZvMRlO7i&A%;<4WLy=zz=?5 zb`HO46n`=(FM8rp2Ar>tR8%`j#`h;pY=ZrW9cq#g=&Q<uUUZhffILZJ?yt$U|AmQ& zvyjeZnO`?0bot~FNd+&PLK?-?^?3q>|1R$#D%Jw2ZfG^M6yl+flmjOCCtFo_EP3wx zx()&*NQzFv8&X|Z(m|!A7uTD>(65THephaMJT>zly!3mAs$qsB8-Y5y2MmR7T)*CY zeZK6)Cd8haL33H7$O`RX3)9tboTYKm>uo!M45S>~MOqSUMzpSkdM{*r0R1G_Pl+Dd z3BvB(Q-z*cJcky6PeDeExE~Wd4#yEF!6jd%LC;K;mTl)<1eKdI^vpg~k-gtpQIesC zG@)n4vOnzi=l}ha_gS@TQr(}Xsmx~Q&ODa5Bj27^wr5t%<;0H18II!X)MONQ<cAxK z<sxXiMqjjI7MITaJcy$T&TZ%|Irz@|Muv;)E-r%gl_62d6~CsDw^4HVsZodJukdT6 z(5ZM7#%@o)<5_~0V-Z<&+te`^wLoJ!=~x?~bD{<PkdIIWB`HbrV8srbW%&SF^hX2g zyc~ajxZgjy&@{}ZXG6!mK=sxQlhsPkbGZbxr3z*DxOP=zoRk7-;B|{mESLp~B<>hb z`Rl3!L?T9((}ts~k*Fqa3YML?1q>hhP`u^)mF-C6h6_k~BVJpw(}DylR!UYISU$D1 zV_U!9|L>njkfF{f|IfrbHhox?`Jke=XEn%kC2?8U=Htns+geQDVE-Z^R2gjk`x3u@ zB0)5Hm+A(KGdOukw;K!NikGmJMPn8R^O6aw^raBdpjr@${h=Bkf$xu89#-MQd}3Xp z`-ud8Uri3`525?a4UH$MTXue9z)rHZNp-gb3Cay;dx;!kZh9VC=ze$&##-uda<@^i zH)c3kQaR7~m>M{YXEAXRS`FVg)lT_jujy8^{+LvBelF<le8Z>oB`$fruO}=YXQtGj zSoC)Er}IH`&h8VO)wY^VokgDZNgLz#R|LXz9t@m})$2UJT)oyWED{Myl`V&#QT|hd zmp#?R-&Dz(Yrkc1iVu?5+GMDh%l(x3j^VX_<Z#}>m=IZ`&t~xsbN+7MXpi-#RAod( z6-91r=SNnCJluIKN=hnR#&)GUm1eu1>~?Q`lgzGB;_C8D)tW@tYkPRMz06G6VXjBj zHh6!=<cZm(YpwB7P5mW0g3DVz+4zU=6_=D@Sc)~;=Es`9D8Jh?4C`R?w5c>dV@}HI z5?VaoqeLr@+FZI+z}MrUO;s)da6rk*NyN<6fD?}i^jveF*A;RQSFYNe^Ko}(Lj#wL zTkBoUGyQq3NnZY^YWY&t%Rt9w`giF1QJypik-znP_1)o@^T$V*9lI@ZRGnjs?M#Y= z#qJFIJDG0}6+CUfSu5~tk)W(s?j1u=3KOQ8Vcl#r{Ef|E3CJU!Rf{s89-D&!aP$2^ z3q7*Y&&!wml^%P#<3CpOvq=wZTl;?;^gOS7!qX(}7rIX}+SV5T?AksoN>G2qe7-^0 zW#x(E#^ShmwJk7<<1bUs)SD_RFQErKiUY)EzvZS$guEQji!#^W-eSn0I&9Vb8AMs7 zF4}Gx>SZw(UvnF;rtSn(l&md8%yw2^rt(zY@#eV%hT_C;!_|BA3pZ6)1;ZtltSrip zZ=1(t|Jb<yktw$5{Ko5k`bdxQCF$|P+7`Evk?ocreXa%sg(3&Nspw2|dflb#t7*pX z*2OykQ|`)ZJ)0GQ>wdL>j;Yr8VbZ;(n>6sFo3EqosxX`4QwP^Cy?dh@FBv8(ZSFZz z(ljvtKANz*;V!s*TwF&cboM(OH#N(_q*xp2jt;*ou-ELr{cO^&yRddzS*I}f=FZj% zS*W?U27~G5m}>Os!;wOp!L8UkIVp85VaoViv#>iYwkuwrQj439Zm_?MAI|X8J^kA8 zek6Jglg{#9%soq}bJB0n-PuT>#pYIEgpC{)(jl+$n-O>!)DW{;rcZXY*=FL<rfxMy z`sjDd3V<IkjgFt{COaqgg}b4AU?L+$_bGnRQ<K?YaOJfC><sa>I4lp>&#?d%z*amR z`wyL{VD&BEa@Kp{{K@9f6+-k!BZ&eUJ9->l^ktfNp>sy;M11vYM*fj56X#ycmJf&R zw--HyQaS6@v!~43=c6Wb2aQo1@j;x-sk&(1cJ`lN(Tmo8Z#_%T^k1>P(DR+(5nUpg zL5@4c78*92hskHwc6XAd&5__TIcYXBATlktt+Jf#-((hFZ3Gf~$0uJJxmBK!YT)NH z*$wr33iIL%W(F7PGf%JJvtzrJvl?nI<YZrZ>0$Eyr0%y#^=HBdckY?HiA9kQ1?sYm zdCzmJMOo7sLl+f<z0jFD<h=Z_V~Bkp9}TSEjuoFM?HuSY9QPL$YH}!y@Zhn&DXSgn zbV)lsmAPX!{1cP$t-LxjHbUK96jnLmGO_M*mJU|cxV)+Ivs*OPNZHRGV?K|yBh|sJ zIaUf+Kk^93xn4<aHaNj8d_D8hB7N$>F;k4KuBQ3+cPC8=v+va-3VNyjF8Pl`5A83Q z4+@ii{NU;(qpf;kt(ARwvFDy`xBCyZPxWuB1nrF<{L<xfi2(lCeal;vM0YOxO{$&Y zc2ZQONZWAtrK%;gVKyeHi>-l^;?zh(hL%uFWK`PCHp(1%t@~$;OWD?+8DR^Tn&a{B zr@ib>&U&I-3f->P_bhxINRG!pApLz9{_~ThC0zp=ivi8OGx(Gys)OOAe*3mM!>-hQ z$vt~Q!{Fx2+PsPfp4!KsNyY#3OTWRc<Ok6G(6q6*eT{oS)t?^xW<XoH(QnIHVK`E7 zrKyqgvCI;&BLSF3Tmsndut)XgcE`spnM<?wZ);4CE!DQ3nu@jCdE>o@Ac2i7@mA@b zD;3#6S5MjtGb?w`ZAfixOH{EZ#!V6sU9lb`av{e#7OaASc|-w4N$2*yYySrV%(7&{ zRT6uMQU}$@3IJmY-1Yc@vy(la>(+1t#od%KL@!QqeH0cs`}WX$qbio)V#-M9HV6OP z*fvT6C}r1f#i8!>+qxHd`h+(==1c<*SR!i*(NOC*xo->Hbu&z?tXxQcNuZ)c7;yVD z=L?<pxTHJuA1~^<0+?@!)W1=Kga99MPtuOqUW8t8epc9i<dN7ZAPDu!Cf^q-%axzH zF(~|o`n5sRo!vVTx|%Qv-<zn7t4A_)@b0<0l&~q)S0kT4KL<XIFsO^hrbxAK#G02n zIS0RqFMUJwjh1|;rU2gQ>4g0if`J=;j+W|TIvx9B-E)&<pG6(kr8h_B)M!Au*|^IJ zAuLZxMz*^L=7Y?jvcNcJuB9z0dh8H^L@Lz1dzW5eHh$cJM)#zjf1~|GKB4WEl9C8m z)URL<{svUl6BE!Uo#Ei%K%EGF_(w<K*T1s%6Cnj%VIkk0SRiE&;<9B1b-A+~x8K%$ zA^_CAPbHi#Xtv;pP&9x}nr>N_msgQmN$VySOZoDLn}vl%oL9?vHKV9;La#-3aJS)> zf~<)d_>Z$2!yx>%Z!Q<eMDzW)Y{{k`ZDXD3oUfltrm|<3TXk)FPpMH6*S>zOSZi(S z_AqqYAbg}#aUs6RGT4(-(+VAk)eEz0ATPdzE5c}-nr_CoWQ;rwwx7fqs3=A}p=nf{ zWjm~KF2+~}Bm9RPI+S!b#fuG^aUpBt63=ZAR<p6+TAP>S=(qYhD%$PAsU2H1|9PtF z<<*{x)4j3@XZDA7qO#6-@ecfvj+9_QlAX|4p_4UGwmi^tV{sm6<A%mqPZ(i2Yt5o9 zIf}=K-@~-(z7;28HiX(B*~?_$50z^Iia7gTqYHOdYftxm9qmUc`k)xOKEJD}qE&dM zs7pAD(o~nqMll4o3QHK@`N!NVaM5PxH@e`_<JN#C`;1n%>DbC{@!_tET-*i!$jhi) K&XvCA^S=PiCi?~e From a602e9e9b40ec1b177bb1db08867cb8b00974b78 Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:31:14 -0400 Subject: [PATCH 496/739] fix format --- .../running-codeql-queries-at-scale-with-mrva.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index 6d3201ef45a..4a312834ba0 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -158,7 +158,7 @@ Using code search to add repositories to a custom list You can use code search directly in the CodeQL extension to add a subset of repositories from GitHub.com to a custom list. Note that this feature uses the legacy code search via the code search API. For more information on the syntax to use, see "`Searching code (legacy) <https://docs.github.com/en/search-github/searching-on-github/searching-code>`__." -For example, to add all repositories in the `rails` organization on GitHub, you can search `org:rails`. +For example, to add all repositories in the ``rails`` organization on GitHub, you can search ```org:rails``. Custom lists can contain a maximum of 1000 repositories, so at most only the first 1000 repositories returned from your search will be added to your list. From 427f2a488c2ca29ea01e8e664ac730ad4cbaa2e5 Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:31:27 -0400 Subject: [PATCH 497/739] fix --- .../running-codeql-queries-at-scale-with-mrva.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index 4a312834ba0..3f508ed95c5 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -158,7 +158,7 @@ Using code search to add repositories to a custom list You can use code search directly in the CodeQL extension to add a subset of repositories from GitHub.com to a custom list. Note that this feature uses the legacy code search via the code search API. For more information on the syntax to use, see "`Searching code (legacy) <https://docs.github.com/en/search-github/searching-on-github/searching-code>`__." -For example, to add all repositories in the ``rails`` organization on GitHub, you can search ```org:rails``. +For example, to add all repositories in the ``rails`` organization on GitHub, you can search ``org:rails``. Custom lists can contain a maximum of 1000 repositories, so at most only the first 1000 repositories returned from your search will be added to your list. From d3941ae9354451b3e4580a92fae0460cd48b2a37 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Wed, 7 Jun 2023 12:37:06 +0100 Subject: [PATCH 498/739] Kotlin: Avoid using deprecated APIs --- .../src/main/kotlin/KotlinFileExtractor.kt | 16 ++++++------ .../src/main/kotlin/utils/GetByFqName.kt | 25 ++++--------------- .../v_1_4_32/FirIncompatiblePluginAPI.kt | 5 ---- .../versions/v_1_4_32/ReferenceEntity.kt | 20 +++++++++++++++ .../v_1_8_0/FirIncompatiblePluginAPI.kt | 4 --- .../utils/versions/v_1_8_0/ReferenceEntity.kt | 24 ++++++++++++++++++ 6 files changed, 57 insertions(+), 37 deletions(-) delete mode 100644 java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/FirIncompatiblePluginAPI.kt create mode 100644 java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/ReferenceEntity.kt delete mode 100644 java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/FirIncompatiblePluginAPI.kt create mode 100644 java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/ReferenceEntity.kt diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index a3bc20d9eda..c471662e631 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -2397,9 +2397,9 @@ open class KotlinFileExtractor( return result } - private fun findTopLevelFunctionOrWarn(functionFilter: String, type: String, parameterTypes: Array<String>, warnAgainstElement: IrElement): IrFunction? { + private fun findTopLevelFunctionOrWarn(functionPkg: String, functionName: String, type: String, parameterTypes: Array<String>, warnAgainstElement: IrElement): IrFunction? { - val fn = getFunctionsByFqName(pluginContext, functionFilter) + val fn = getFunctionsByFqName(pluginContext, functionPkg, functionName) .firstOrNull { fnSymbol -> fnSymbol.owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type && fnSymbol.owner.valueParameters.map { it.type.classFqName?.asString() }.toTypedArray() contentEquals parameterTypes @@ -2410,15 +2410,15 @@ open class KotlinFileExtractor( extractExternalClassLater(fn.parentAsClass) } } else { - logger.errorElement("Couldn't find JVM intrinsic function $functionFilter in $type", warnAgainstElement) + logger.errorElement("Couldn't find JVM intrinsic function $functionPkg $functionName in $type", warnAgainstElement) } return fn } - private fun findTopLevelPropertyOrWarn(propertyFilter: String, type: String, warnAgainstElement: IrElement): IrProperty? { + private fun findTopLevelPropertyOrWarn(propertyPkg: String, propertyName: String, type: String, warnAgainstElement: IrElement): IrProperty? { - val prop = getPropertiesByFqName(pluginContext, propertyFilter) + val prop = getPropertiesByFqName(pluginContext, propertyPkg, propertyName) .firstOrNull { it.owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type } ?.owner @@ -2427,7 +2427,7 @@ open class KotlinFileExtractor( extractExternalClassLater(prop.parentAsClass) } } else { - logger.errorElement("Couldn't find JVM intrinsic property $propertyFilter in $type", warnAgainstElement) + logger.errorElement("Couldn't find JVM intrinsic property $propertyPkg $propertyName in $type", warnAgainstElement) } return prop @@ -3019,7 +3019,7 @@ open class KotlinFileExtractor( } isBuiltinCall(c, "<get-java>", "kotlin.jvm") -> { // Special case for KClass<*>.java, which is used in the Parcelize plugin. In normal cases, this is already rewritten to the property referenced below: - findTopLevelPropertyOrWarn("kotlin.jvm.java", "kotlin.jvm.JvmClassMappingKt", c)?.let { javaProp -> + findTopLevelPropertyOrWarn("kotlin.jvm", "java", "kotlin.jvm.JvmClassMappingKt", c)?.let { javaProp -> val getter = javaProp.getter if (getter == null) { logger.error("Couldn't find getter of `kotlin.jvm.JvmClassMappingKt::java`") @@ -3051,7 +3051,7 @@ open class KotlinFileExtractor( "kotlin.jvm.internal.ArrayIteratorsKt" } - findTopLevelFunctionOrWarn("kotlin.jvm.internal.iterator", typeFilter, arrayOf(parentClass.kotlinFqName.asString()), c)?.let { iteratorFn -> + findTopLevelFunctionOrWarn("kotlin.jvm.internal", "iterator", typeFilter, arrayOf(parentClass.kotlinFqName.asString()), c)?.let { iteratorFn -> val dispatchReceiver = c.dispatchReceiver if (dispatchReceiver == null) { logger.errorElement("No dispatch receiver found for array iterator call", c) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/GetByFqName.kt b/java/kotlin-extractor/src/main/kotlin/utils/GetByFqName.kt index 57815fc4409..b429224bc71 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/GetByFqName.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/GetByFqName.kt @@ -1,33 +1,18 @@ package com.github.codeql.utils -import org.jetbrains.kotlin.backend.common.extensions.FirIncompatiblePluginAPI import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name fun getClassByFqName(pluginContext: IrPluginContext, fqName: String): IrClassSymbol? { return getClassByFqName(pluginContext, FqName(fqName)) } -fun getClassByFqName(pluginContext: IrPluginContext, fqName: FqName): IrClassSymbol? { - @OptIn(FirIncompatiblePluginAPI::class) - return pluginContext.referenceClass(fqName) +fun getFunctionsByFqName(pluginContext: IrPluginContext, pkgName: String, name: String): Collection<IrSimpleFunctionSymbol> { + return getFunctionsByFqName(pluginContext, FqName(pkgName), Name.identifier(name)) } -fun getFunctionsByFqName(pluginContext: IrPluginContext, fqName: String): Collection<IrSimpleFunctionSymbol> { - return getFunctionsByFqName(pluginContext, FqName(fqName)) -} - -private fun getFunctionsByFqName(pluginContext: IrPluginContext, fqName: FqName): Collection<IrSimpleFunctionSymbol> { - @OptIn(FirIncompatiblePluginAPI::class) - return pluginContext.referenceFunctions(fqName) -} - -fun getPropertiesByFqName(pluginContext: IrPluginContext, fqName: String): Collection<IrPropertySymbol> { - return getPropertiesByFqName(pluginContext, FqName(fqName)) -} - -private fun getPropertiesByFqName(pluginContext: IrPluginContext, fqName: FqName): Collection<IrPropertySymbol> { - @OptIn(FirIncompatiblePluginAPI::class) - return pluginContext.referenceProperties(fqName) +fun getPropertiesByFqName(pluginContext: IrPluginContext, pkgName: String, name: String): Collection<IrPropertySymbol> { + return getPropertiesByFqName(pluginContext, FqName(pkgName), Name.identifier(name)) } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/FirIncompatiblePluginAPI.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/FirIncompatiblePluginAPI.kt deleted file mode 100644 index 45d573da9c7..00000000000 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/FirIncompatiblePluginAPI.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.jetbrains.kotlin.backend.common.extensions - -@RequiresOptIn("This API is not available after FIR") -annotation class FirIncompatiblePluginAPI - diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/ReferenceEntity.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/ReferenceEntity.kt new file mode 100644 index 00000000000..755772d90c6 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/ReferenceEntity.kt @@ -0,0 +1,20 @@ +package com.github.codeql.utils + +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name + +fun getClassByFqName(pluginContext: IrPluginContext, fqName: FqName): IrClassSymbol? { + return pluginContext.referenceClass(fqName) +} + +fun getFunctionsByFqName(pluginContext: IrPluginContext, pkgName: FqName, name: Name): Collection<IrSimpleFunctionSymbol> { + val fqName = pkgName.child(name) + return pluginContext.referenceFunctions(fqName) +} + +fun getPropertiesByFqName(pluginContext: IrPluginContext, pkgName: FqName, name: Name): Collection<IrPropertySymbol> { + val fqName = pkgName.child(name) + return pluginContext.referenceProperties(fqName) +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/FirIncompatiblePluginAPI.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/FirIncompatiblePluginAPI.kt deleted file mode 100644 index 48829cc30c5..00000000000 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/FirIncompatiblePluginAPI.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.github.codeql - -// The compiler provides the annotation class, so we don't need to do -// anything diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/ReferenceEntity.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/ReferenceEntity.kt new file mode 100644 index 00000000000..8d70b66cf27 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/ReferenceEntity.kt @@ -0,0 +1,24 @@ +package com.github.codeql.utils + +import org.jetbrains.kotlin.backend.common.extensions.FirIncompatiblePluginAPI +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.CallableId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name + +fun getClassByFqName(pluginContext: IrPluginContext, fqName: FqName): IrClassSymbol? { + val id = ClassId.topLevel(fqName) + return pluginContext.referenceClass(id) +} + +fun getFunctionsByFqName(pluginContext: IrPluginContext, pkgName: FqName, name: Name): Collection<IrSimpleFunctionSymbol> { + val id = CallableId(pkgName, name) + return pluginContext.referenceFunctions(id) +} + +fun getPropertiesByFqName(pluginContext: IrPluginContext, pkgName: FqName, name: Name): Collection<IrPropertySymbol> { + val id = CallableId(pkgName, name) + return pluginContext.referenceProperties(id) +} From d81ba80406d6dadcb026be10ce07cec7d99ceec4 Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 9 Jun 2023 14:27:26 -0400 Subject: [PATCH 499/739] Update docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst Co-authored-by: Felicity Chapman <felicitymay@github.com> --- .../running-codeql-queries-at-scale-with-mrva.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index 3f508ed95c5..fd34e389d74 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -171,7 +171,7 @@ Custom lists can contain a maximum of 1000 repositories, so at most only the fir .. image:: ../images/codeql-for-visual-studio-code/variant-analysis-code-search-language.png :alt: Screenshot of the search bar for using code search to add repositories to a custom list. The search bar asks you to choose a language for your search and has a dropdown list of languages to choose from. -#. Type the search query that you want to use and press **Enter**. +#. In the search bar, type the search query that you want to use and press **Enter**. #. You can view the progress of your search in the bottom right corner of the application in a box with the text "Searching for repositories...". If you click **Cancel**, no repositories will be added to your list. From 9abe3e3da464c3f65f7641e31b2e1a7a06163ac9 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Fri, 9 Jun 2023 14:35:37 -0400 Subject: [PATCH 500/739] Shared: use a module as input to 'KindValidation' --- .../code/csharp/dataflow/ExternalFlow.qll | 17 +++++------ go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 17 ++++------- .../code/java/dataflow/ExternalFlow.qll | 17 +++++------ .../data/internal/ApiGraphModels.qll | 17 ++++------- .../data/internal/ApiGraphModels.qll | 17 ++++------- .../data/internal/ApiGraphModels.qll | 17 ++++------- shared/mad/codeql/mad/ModelValidation.qll | 29 ++++++++++++------- .../codeql/swift/dataflow/ExternalFlow.qll | 17 ++++------- 8 files changed, 63 insertions(+), 85 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index ae1c928b92c..501b140b886 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -205,20 +205,17 @@ module ModelValidation { ) } - /** Holds if a summary model exists for the given `kind`. */ - private predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } + private module KindValConfig implements SharedModelVal::KindValidationConfigSig { + predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } - /** Holds if a sink model exists for the given `kind`. */ - private predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } + predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } - /** Holds if a source model exists for the given `kind`. */ - private predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } - /** Holds if a neutral model exists for the given `kind`. */ - private predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) } + predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) } + } - private module KindVal = - SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; + private module KindVal = SharedModelVal::KindValidation<KindValConfig>; private string getInvalidModelSignature() { exists( diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 448196fb1a0..4306471893a 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -189,20 +189,15 @@ module ModelValidation { ) } - /** Holds if a summary model exists for the given `kind`. */ - private predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } + private module KindValConfig implements SharedModelVal::KindValidationConfigSig { + predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } - /** Holds if a sink model exists for the given `kind`. */ - private predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } + predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } - /** Holds if a source model exists for the given `kind`. */ - private predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + } - /** Holds if a neutral model exists for the given `kind`. */ - private predicate neutralKind(string kind) { none() } - - private module KindVal = - SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; + private module KindVal = SharedModelVal::KindValidation<KindValConfig>; private string getInvalidModelSignature() { exists( diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index b0a5b702fa0..c04126d5f7f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -266,20 +266,17 @@ module ModelValidation { ) } - /** Holds if a summary model exists for the given `kind`. */ - private predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } + private module KindValConfig implements SharedModelVal::KindValidationConfigSig { + predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } - /** Holds if a sink model exists for the given `kind`. */ - private predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } + predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } - /** Holds if a source model exists for the given `kind`. */ - private predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } - /** Holds if a neutral model exists for the given `kind`. */ - private predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) } + predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) } + } - private module KindVal = - SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; + private module KindVal = SharedModelVal::KindValidation<KindValConfig>; private string getInvalidModelSignature() { exists( diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll index f3474d452f4..2b765765e99 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -655,20 +655,15 @@ module ModelOutput { import Specific::ModelOutputSpecific private import codeql.mad.ModelValidation as SharedModelVal - /** Holds if a summary model exists for the given `kind`. */ - private predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } + private module KindValConfig implements SharedModelVal::KindValidationConfigSig { + predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } - /** Holds if a sink model exists for the given `kind`. */ - private predicate sinkKind(string kind) { sinkModel(_, _, kind) } + predicate sinkKind(string kind) { sinkModel(_, _, kind) } - /** Holds if a source model exists for the given `kind`. */ - private predicate sourceKind(string kind) { sourceModel(_, _, kind) } + predicate sourceKind(string kind) { sourceModel(_, _, kind) } + } - /** Holds if a neutral model exists for the given `kind`. */ - private predicate neutralKind(string kind) { none() } - - private module KindVal = - SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; + private module KindVal = SharedModelVal::KindValidation<KindValConfig>; /** * Gets an error message relating to an invalid CSV row in a model. diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index f3474d452f4..2b765765e99 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -655,20 +655,15 @@ module ModelOutput { import Specific::ModelOutputSpecific private import codeql.mad.ModelValidation as SharedModelVal - /** Holds if a summary model exists for the given `kind`. */ - private predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } + private module KindValConfig implements SharedModelVal::KindValidationConfigSig { + predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } - /** Holds if a sink model exists for the given `kind`. */ - private predicate sinkKind(string kind) { sinkModel(_, _, kind) } + predicate sinkKind(string kind) { sinkModel(_, _, kind) } - /** Holds if a source model exists for the given `kind`. */ - private predicate sourceKind(string kind) { sourceModel(_, _, kind) } + predicate sourceKind(string kind) { sourceModel(_, _, kind) } + } - /** Holds if a neutral model exists for the given `kind`. */ - private predicate neutralKind(string kind) { none() } - - private module KindVal = - SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; + private module KindVal = SharedModelVal::KindValidation<KindValConfig>; /** * Gets an error message relating to an invalid CSV row in a model. diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll index f3474d452f4..2b765765e99 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -655,20 +655,15 @@ module ModelOutput { import Specific::ModelOutputSpecific private import codeql.mad.ModelValidation as SharedModelVal - /** Holds if a summary model exists for the given `kind`. */ - private predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } + private module KindValConfig implements SharedModelVal::KindValidationConfigSig { + predicate summaryKind(string kind) { summaryModel(_, _, _, _, kind) } - /** Holds if a sink model exists for the given `kind`. */ - private predicate sinkKind(string kind) { sinkModel(_, _, kind) } + predicate sinkKind(string kind) { sinkModel(_, _, kind) } - /** Holds if a source model exists for the given `kind`. */ - private predicate sourceKind(string kind) { sourceModel(_, _, kind) } + predicate sourceKind(string kind) { sourceModel(_, _, kind) } + } - /** Holds if a neutral model exists for the given `kind`. */ - private predicate neutralKind(string kind) { none() } - - private module KindVal = - SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; + private module KindVal = SharedModelVal::KindValidation<KindValConfig>; /** * Gets an error message relating to an invalid CSV row in a model. diff --git a/shared/mad/codeql/mad/ModelValidation.qll b/shared/mad/codeql/mad/ModelValidation.qll index 0486a4b07a2..d5108c2eeec 100644 --- a/shared/mad/codeql/mad/ModelValidation.qll +++ b/shared/mad/codeql/mad/ModelValidation.qll @@ -2,14 +2,23 @@ * Provides classes and predicates related to validating models-as-data rows. */ -/** Holds if a model exists for the given `kind`. */ -signature predicate modelKindSig(string kind); +/** Provides predicates for determining if a model exists for a given `kind`. */ +signature module KindValidationConfigSig { + /** Holds if a summary model exists for the given `kind`. */ + predicate summaryKind(string kind); + + /** Holds if a sink model exists for the given `kind`. */ + predicate sinkKind(string kind); + + /** Holds if a source model exists for the given `kind`. */ + predicate sourceKind(string kind); + + /** Holds if a neutral model exists for the given `kind`. */ + default predicate neutralKind(string kind) { none() } +} /** Provides validation for models-as-data summary, sink, source, and neutral kinds. */ -module KindValidation< - modelKindSig/1 summaryKind, modelKindSig/1 sinkKind, modelKindSig/1 sourceKind, - modelKindSig/1 neutralKind> -{ +module KindValidation<KindValidationConfigSig Config> { /** A valid models-as-data sink kind. */ private class ValidSinkKind extends string { bindingset[this] @@ -150,12 +159,12 @@ module KindValidation< /** Gets an error message relating to an invalid kind in a model. */ string getInvalidModelKind() { - exists(string kind | summaryKind(kind) | + exists(string kind | Config::summaryKind(kind) | not kind instanceof ValidSummaryKind and result = "Invalid kind \"" + kind + "\" in summary model." ) or - exists(string kind, string msg | sinkKind(kind) | + exists(string kind, string msg | Config::sinkKind(kind) | not kind instanceof ValidSinkKind and msg = "Invalid kind \"" + kind + "\" in sink model." and // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. @@ -164,12 +173,12 @@ module KindValidation< else result = msg ) or - exists(string kind | sourceKind(kind) | + exists(string kind | Config::sourceKind(kind) | not kind instanceof ValidSourceKind and result = "Invalid kind \"" + kind + "\" in source model." ) or - exists(string kind | neutralKind(kind) | + exists(string kind | Config::neutralKind(kind) | not kind instanceof ValidNeutralKind and result = "Invalid kind \"" + kind + "\" in neutral model." ) diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index d55563604c6..ba680b1b138 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -264,20 +264,15 @@ module CsvValidation { ) } - /** Holds if a summary model exists for the given `kind`. */ - private predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } + private module KindValConfig implements SharedModelVal::KindValidationConfigSig { + predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) } - /** Holds if a sink model exists for the given `kind`. */ - private predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } + predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) } - /** Holds if a source model exists for the given `kind`. */ - private predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) } + } - /** Holds if a neutral model exists for the given `kind`. */ - private predicate neutralKind(string kind) { none() } - - private module KindVal = - SharedModelVal::KindValidation<summaryKind/1, sinkKind/1, sourceKind/1, neutralKind/1>; + private module KindVal = SharedModelVal::KindValidation<KindValConfig>; private string getInvalidModelSubtype() { exists(string pred, string row | From 52acf5e8bea8d7e0ddc744ead0bc9dd5a3ec2d88 Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 9 Jun 2023 16:08:30 -0400 Subject: [PATCH 501/739] updates based on feedback --- ...nning-codeql-queries-at-scale-with-mrva.rst | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index fd34e389d74..f225b3e8097 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -153,10 +153,16 @@ For example, if you want to continue analyzing a set of repositories that had re You can then insert the ``new-repo-list`` of repositories into your list of custom repository lists for easy access in the Variant Analysis Repositories panel. -Using code search to add repositories to a custom list +Using GitHub code search to add repositories to a custom list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can use code search directly in the CodeQL extension to add a subset of repositories from GitHub.com to a custom list. Note that this feature uses the legacy code search via the code search API. For more information on the syntax to use, see "`Searching code (legacy) <https://docs.github.com/en/search-github/searching-on-github/searching-code>`__." +You can use code search directly in the CodeQL extension to add a subset of repositories from GitHub.com to a custom list. + +.. pull-quote:: + + Note + + This feature uses the legacy code search via the code search API. For more information on the syntax to use, see "`Searching code (legacy) <https://docs.github.com/en/search-github/searching-on-github/searching-code>`__." For example, to add all repositories in the ``rails`` organization on GitHub, you can search ``org:rails``. @@ -166,18 +172,16 @@ Custom lists can contain a maximum of 1000 repositories, so at most only the fir #. Right-click on the list you have chosen and then click **Add repositories with GitHub Code Search**. -#. In the search bar, select a language for your search from the choices in the dropdown. +#. In the pop-up that appears at the top of the application, under the search bar, select a language for your search from the choices in the dropdown. .. image:: ../images/codeql-for-visual-studio-code/variant-analysis-code-search-language.png :alt: Screenshot of the search bar for using code search to add repositories to a custom list. The search bar asks you to choose a language for your search and has a dropdown list of languages to choose from. #. In the search bar, type the search query that you want to use and press **Enter**. -#. You can view the progress of your search in the bottom right corner of the application in a box with the text "Searching for repositories...". If you click **Cancel**, no repositories will be added to your list. +You can view the progress of your search in the bottom right corner of the application in a box with the text "Searching for repositories...". If you click **Cancel**, no repositories will be added to your list. Once complete, you will see the resulting repositories appear in the dropdown under your custom list in the Variant Analysis Repositories panel. -#. Once complete, you will see the resulting repositories appear in the dropdown under your custom list in the Variant Analysis Repositories panel. - -It is possible that some of the resulting repositories do not have CodeQL databases or are not accessible. When you run an analysis on the list, the results view will show you which repositories could not be analyzed. +Not all resulting repositories will have CodeQL databases or allow access to be analyzed. When you run an analysis on the list, the Variant Analysis Results view will show you which repositories could not be analyzed. Troubleshooting variant analysis -------------------------------- From c30f259f9df9c20684068b221ea53541f96f1811 Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Fri, 9 Jun 2023 16:28:34 -0400 Subject: [PATCH 502/739] provide more info --- .../running-codeql-queries-at-scale-with-mrva.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index f225b3e8097..f4ab2c1e3ee 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -181,7 +181,7 @@ Custom lists can contain a maximum of 1000 repositories, so at most only the fir You can view the progress of your search in the bottom right corner of the application in a box with the text "Searching for repositories...". If you click **Cancel**, no repositories will be added to your list. Once complete, you will see the resulting repositories appear in the dropdown under your custom list in the Variant Analysis Repositories panel. -Not all resulting repositories will have CodeQL databases or allow access to be analyzed. When you run an analysis on the list, the Variant Analysis Results view will show you which repositories could not be analyzed. +Not all resulting repositories will have CodeQL databases or allow access to be analyzed. When you run an analysis on the list, the Variant Analysis Results view will show you which repositories were analyzed, which denied access, and which had no CodeQL database. Troubleshooting variant analysis -------------------------------- From a628384d836f02293507259e3f6a504529c605db Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 00:18:38 +0000 Subject: [PATCH 503/739] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 2 +- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index acfd9b9224c..447797aff24 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -58,7 +58,7 @@ java.io,49,,45,,22,,,,,,,,,,,,,,27,,,,,,,,,,,,,,,,,,,43,2 java.lang,18,,92,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36 java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20, java.nio,47,,35,,3,,,,,,,,,,,,,,44,,,,,,,,,,,,,,,,,,,35, -java.sql,13,,3,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,1 +java.sql,13,,2,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2, java.util,44,,484,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440 javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, javax.faces.context,2,7,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 3e2043369dc..8464e0ca23e 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -18,10 +18,10 @@ Java framework & library support `Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,41,7,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,, `JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,, - Java Standard Library,``java.*``,3,683,184,76,,9,,,17 + Java Standard Library,``java.*``,3,682,184,76,,9,,,17 Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,115,4,,28,14,,35 Others,"``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,899,528,66,,18,18,,195 - Totals,,255,9199,1997,263,10,122,33,1,385 + Totals,,255,9198,1997,263,10,122,33,1,385 From 452af312ff079846cf1dfe5083f8ffac55ea20fb Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Mon, 12 Jun 2023 10:07:26 +0200 Subject: [PATCH 504/739] Ruby: change note --- ruby/ql/src/change-notes/2023-06-12-map_filter.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ruby/ql/src/change-notes/2023-06-12-map_filter.md diff --git a/ruby/ql/src/change-notes/2023-06-12-map_filter.md b/ruby/ql/src/change-notes/2023-06-12-map_filter.md new file mode 100644 index 00000000000..ac5803a6096 --- /dev/null +++ b/ruby/ql/src/change-notes/2023-06-12-map_filter.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Fixed a bug in how `map_filter` calls are analyzed. Previously, such calls would + appear to the return the receiver of the call, but now the return value of the callback + is properly taken into account. From 68b6d6207e57def18ac771988c3d52a257f63305 Mon Sep 17 00:00:00 2001 From: Felicity Chapman <felicitymay@github.com> Date: Mon, 12 Jun 2023 09:35:20 +0100 Subject: [PATCH 505/739] Update docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst --- .../running-codeql-queries-at-scale-with-mrva.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index f4ab2c1e3ee..e82b0243294 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -154,7 +154,7 @@ For example, if you want to continue analyzing a set of repositories that had re You can then insert the ``new-repo-list`` of repositories into your list of custom repository lists for easy access in the Variant Analysis Repositories panel. Using GitHub code search to add repositories to a custom list -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can use code search directly in the CodeQL extension to add a subset of repositories from GitHub.com to a custom list. From cdf1c2639dde5f0aa0f315838a6ed5c7b7fa7102 Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Mon, 12 Jun 2023 11:03:22 +0200 Subject: [PATCH 506/739] C#: Only include `CoreLib.dll` when `UseMscorlib` option is set --- .../BuildAnalysis.cs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs index fc974c7ded6..f4f1cba4d89 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs @@ -100,18 +100,6 @@ namespace Semmle.BuildAnalyser dllDirNames.Add(runtimeLocation); } - if (options.UseMscorlib) - { - // Add mscorlib.dll or System.Private.CoreLib.dll to the list of DLLs to reference. - var loc = typeof(object).Assembly.Location; - var dir = Path.GetDirectoryName(loc); - if (dir != null) - { - progressMonitor.Log(Util.Logging.Severity.Debug, $"Adding folder {dir} to DLL search path."); - dllDirNames.Add(dir); - } - } - // These files can sometimes prevent `dotnet restore` from working correctly. using (new FileRenamer(sourceDir.GetFiles("global.json", SearchOption.AllDirectories))) using (new FileRenamer(sourceDir.GetFiles("Directory.Build.props", SearchOption.AllDirectories))) @@ -132,6 +120,11 @@ namespace Semmle.BuildAnalyser UseReference(filename); } + if (options.UseMscorlib) + { + UseReference(typeof(object).Assembly.Location); + } + ResolveConflicts(); // Output the findings From f8ff575ff026aafd6ac880ce5b9a68761ad57c88 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Mon, 12 Jun 2023 11:37:57 +0200 Subject: [PATCH 507/739] C#: Fix bugs in misc models. --- .../ext/System.Collections.Generic.model.yml | 10 +++++----- .../ext/System.Collections.Immutable.model.yml | 18 +++++++++--------- .../System.Collections.Specialized.model.yml | 2 +- csharp/ql/lib/ext/System.Collections.model.yml | 18 +++++++++--------- csharp/ql/lib/ext/System.Data.model.yml | 2 +- .../System.Runtime.CompilerServices.model.yml | 4 ++-- csharp/ql/lib/ext/System.model.yml | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/csharp/ql/lib/ext/System.Collections.Generic.model.yml b/csharp/ql/lib/ext/System.Collections.Generic.model.yml index 3029690b03f..7640b88b97d 100644 --- a/csharp/ql/lib/ext/System.Collections.Generic.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Generic.model.yml @@ -40,7 +40,7 @@ extensions: - ["System.Collections.Generic", "LinkedList<>", False, "FindLast", "(T)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections.Generic", "LinkedList<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.LinkedList<>+Enumerator.Current]", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "AddRange", "(System.Collections.Generic.IEnumerable<T>)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - - ["System.Collections.Generic", "List<>", False, "AsReadOnly", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Generic", "List<>", False, "AsReadOnly", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "Find", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "Find", "(System.Predicate<T>)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "FindAll", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] @@ -48,10 +48,10 @@ extensions: - ["System.Collections.Generic", "List<>", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.List<>+Enumerator.Current]", "value", "manual"] - - ["System.Collections.Generic", "List<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Generic", "List<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "InsertRange", "(System.Int32,System.Collections.Generic.IEnumerable<T>)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"] - - ["System.Collections.Generic", "List<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections.Generic", "List<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Generic", "List<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Generic", "List<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Generic", "Queue<>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Collections.Generic", "Queue<>", False, "CopyTo", "(T[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] - ["System.Collections.Generic", "Queue<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.Queue<>+Enumerator.Current]", "value", "manual"] @@ -79,7 +79,7 @@ extensions: - ["System.Collections.Generic", "SortedList<,>+KeyList", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Collections.Generic", "SortedList<,>+ValueList", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Collections.Generic", "SortedSet<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.SortedSet<>+Enumerator.Current]", "value", "manual"] - - ["System.Collections.Generic", "SortedSet<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Generic", "SortedSet<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Generic", "Stack<>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Collections.Generic", "Stack<>", False, "CopyTo", "(T[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] - ["System.Collections.Generic", "Stack<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.Stack<>+Enumerator.Current]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.Immutable.model.yml b/csharp/ql/lib/ext/System.Collections.Immutable.model.yml index b2bd1b6a774..680cf56647c 100644 --- a/csharp/ql/lib/ext/System.Collections.Immutable.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Immutable.model.yml @@ -20,7 +20,7 @@ extensions: - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "AddRange<>", "(System.Collections.Immutable.ImmutableArray<TDerived>+Builder)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "AddRange<>", "(TDerived[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current]", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(TKey,TValue)", "", "Argument[0]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] @@ -49,11 +49,11 @@ extensions: - ["System.Collections.Immutable", "ImmutableList<>", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current]", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableList<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableList<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>", False, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>", False, "InsertRange", "(System.Int32,System.Collections.Generic.IEnumerable<T>)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableList<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableList<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableList<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableList<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "AddRange", "(System.Collections.Generic.IEnumerable<T>)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Find", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] @@ -63,10 +63,10 @@ extensions: - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current]", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "InsertRange", "(System.Int32,System.Collections.Generic.IEnumerable<T>)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableQueue<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableQueue<>+Enumerator.Current]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableSortedDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableSortedDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] @@ -85,8 +85,8 @@ extensions: - ["System.Collections.Immutable", "ImmutableSortedDictionary<,>+Builder", False, "get_Values", "()", "", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "Add", "(T)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current]", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections.Immutable", "ImmutableSortedSet<>+Builder", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current]", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableSortedSet<>+Builder", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Immutable", "ImmutableSortedSet<>+Builder", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableStack<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableStack<>+Enumerator.Current]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.Specialized.model.yml b/csharp/ql/lib/ext/System.Collections.Specialized.model.yml index 8456af24f14..96b947f2423 100644 --- a/csharp/ql/lib/ext/System.Collections.Specialized.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Specialized.model.yml @@ -9,7 +9,7 @@ extensions: - ["System.Collections.Specialized", "NameValueCollection", False, "Add", "(System.Collections.Specialized.NameValueCollection)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Collections.Specialized", "NameValueCollection", True, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Collections.Specialized", "NameValueCollection", False, "CopyTo", "(System.Array,System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] - - ["System.Collections.Specialized", "OrderedDictionary", False, "AsReadOnly", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections.Specialized", "OrderedDictionary", False, "AsReadOnly", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Specialized", "StringCollection", False, "Add", "(System.String)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["System.Collections.Specialized", "StringCollection", False, "AddRange", "(System.String[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Specialized", "StringCollection", False, "CopyTo", "(System.String[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.model.yml b/csharp/ql/lib/ext/System.Collections.model.yml index 9aa2c2489c9..e2c556916d2 100644 --- a/csharp/ql/lib/ext/System.Collections.model.yml +++ b/csharp/ql/lib/ext/System.Collections.model.yml @@ -4,17 +4,17 @@ extensions: extensible: summaryModel data: - ["System.Collections", "ArrayList", False, "AddRange", "(System.Collections.ICollection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - - ["System.Collections", "ArrayList", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "ArrayList", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "ArrayList", False, "FixedSize", "(System.Collections.ArrayList)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "ArrayList", False, "FixedSize", "(System.Collections.IList)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "ArrayList", False, "GetEnumerator", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.IEnumerator.Current]", "value", "manual"] - - ["System.Collections", "ArrayList", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "ArrayList", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "ArrayList", False, "InsertRange", "(System.Int32,System.Collections.ICollection)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections", "ArrayList", False, "Repeat", "(System.Object,System.Int32)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] - - ["System.Collections", "ArrayList", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections", "ArrayList", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections", "BitArray", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections", "Hashtable", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "ArrayList", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "ArrayList", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "BitArray", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "Hashtable", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "Hashtable", False, "Hashtable", "(System.Collections.IDictionary)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Collections", "Hashtable", False, "Hashtable", "(System.Collections.IDictionary)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] - ["System.Collections", "Hashtable", False, "Hashtable", "(System.Collections.IDictionary,System.Collections.IEqualityComparer)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] @@ -43,9 +43,9 @@ extensions: - ["System.Collections", "IList", True, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections", "IList", True, "set_Item", "(System.Int32,System.Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] - ["System.Collections", "Queue", True, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - - ["System.Collections", "Queue", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "Queue", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "Queue", False, "Peek", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - - ["System.Collections", "SortedList", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "SortedList", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "SortedList", False, "GetByIndex", "(System.Int32)", "", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "ReturnValue", "value", "manual"] - ["System.Collections", "SortedList", False, "GetValueList", "()", "", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "SortedList", False, "SortedList", "(System.Collections.IDictionary)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] @@ -53,6 +53,6 @@ extensions: - ["System.Collections", "SortedList", False, "SortedList", "(System.Collections.IDictionary,System.Collections.IComparer)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Collections", "SortedList", False, "SortedList", "(System.Collections.IDictionary,System.Collections.IComparer)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] - ["System.Collections", "Stack", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - - ["System.Collections", "Stack", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Collections", "Stack", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "Stack", False, "Peek", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Collections", "Stack", False, "Pop", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.model.yml b/csharp/ql/lib/ext/System.Data.model.yml index 26f650c96a5..6331e67c067 100644 --- a/csharp/ql/lib/ext/System.Data.model.yml +++ b/csharp/ql/lib/ext/System.Data.model.yml @@ -58,7 +58,7 @@ extensions: - ["System.Data", "IDataParameterCollection", True, "set_Item", "(System.String,System.Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] - ["System.Data", "ITableMappingCollection", True, "get_Item", "(System.String)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["System.Data", "ITableMappingCollection", True, "set_Item", "(System.String,System.Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"] - - ["System.Data", "PropertyCollection", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Data", "PropertyCollection", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Data", "TypedTableBaseExtensions", False, "AsEnumerable<>", "(System.Data.TypedTableBase<TRow>)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System.Data", "TypedTableBaseExtensions", False, "ElementAtOrDefault<>", "(System.Data.TypedTableBase<TRow>,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] - ["System.Data", "TypedTableBaseExtensions", False, "OrderBy<,>", "(System.Data.TypedTableBase<TRow>,System.Func<TRow,TKey>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml b/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml index bd28d9168fd..efe8a9a8abf 100644 --- a/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml +++ b/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml @@ -6,6 +6,6 @@ extensions: - ["System.Runtime.CompilerServices", "ConditionalWeakTable<,>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Runtime.CompilerServices", "ConfiguredTaskAwaitable<>", False, "GetAwaiter", "()", "", "Argument[this].SyntheticField[m_configuredTaskAwaiter]", "ReturnValue", "value", "manual"] - ["System.Runtime.CompilerServices", "ConfiguredTaskAwaitable<>+ConfiguredTaskAwaiter", False, "GetResult", "()", "", "Argument[this].SyntheticField[m_task_configured_task_awaitable].Property[System.Threading.Tasks.Task<>.Result]", "ReturnValue", "value", "manual"] - - ["System.Runtime.CompilerServices", "ReadOnlyCollectionBuilder<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Runtime.CompilerServices", "ReadOnlyCollectionBuilder<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Runtime.CompilerServices", "ReadOnlyCollectionBuilder<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["System.Runtime.CompilerServices", "ReadOnlyCollectionBuilder<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Runtime.CompilerServices", "TaskAwaiter<>", False, "GetResult", "()", "", "Argument[this].SyntheticField[m_task_task_awaiter].Property[System.Threading.Tasks.Task<>.Result]", "ReturnValue", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.model.yml b/csharp/ql/lib/ext/System.model.yml index b0f74507b87..9b4fc9615ab 100644 --- a/csharp/ql/lib/ext/System.model.yml +++ b/csharp/ql/lib/ext/System.model.yml @@ -13,7 +13,7 @@ extensions: - ["System", "Array", False, "AsReadOnly<>", "(T[])", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] - ["System", "Array", False, "Clear", "(System.Array)", "", "Argument[0].WithoutElement", "Argument[0]", "value", "manual"] - ["System", "Array", False, "Clear", "(System.Array,System.Int32,System.Int32)", "", "Argument[0].WithoutElement", "Argument[0]", "value", "manual"] - - ["System", "Array", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"] + - ["System", "Array", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System", "Array", False, "CopyTo", "(System.Array,System.Int64)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] - ["System", "Array", False, "Find<>", "(T[],System.Predicate<T>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - ["System", "Array", False, "Find<>", "(T[],System.Predicate<T>)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] From 88fe0f089ee5dd4f311326b1c3ad20857765752a Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Mon, 12 Jun 2023 13:17:55 +0200 Subject: [PATCH 508/739] C#: Fix expected output. --- .../library-tests/dataflow/delegates/DelegateFlow.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected index 723086b649f..610ff1f06d9 100644 --- a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected @@ -51,5 +51,5 @@ viableLambda | DelegateFlow.cs:125:9:125:25 | function pointer call | file://:0:0:0:0 | (none) | DelegateFlow.cs:7:17:7:18 | M2 | | DelegateFlow.cs:132:9:132:11 | delegate call | DelegateFlow.cs:135:25:135:40 | call to method M19 | DelegateFlow.cs:135:29:135:36 | (...) => ... | | DelegateFlow.cs:132:9:132:11 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:131:17:131:24 | (...) => ... | -| file://:0:0:0:0 | [summary] call to parameter position 0 of Lazy in Lazy | DelegateFlow.cs:105:9:105:24 | object creation of type Lazy<Int32> | DelegateFlow.cs:104:23:104:30 | (...) => ... | -| file://:0:0:0:0 | [summary] call to parameter position 0 of Lazy in Lazy | DelegateFlow.cs:107:9:107:24 | object creation of type Lazy<Int32> | DelegateFlow.cs:106:13:106:20 | (...) => ... | +| file://:0:0:0:0 | [summary] call to [summary param] position 0 in Lazy in Lazy | DelegateFlow.cs:105:9:105:24 | object creation of type Lazy<Int32> | DelegateFlow.cs:104:23:104:30 | (...) => ... | +| file://:0:0:0:0 | [summary] call to [summary param] position 0 in Lazy in Lazy | DelegateFlow.cs:107:9:107:24 | object creation of type Lazy<Int32> | DelegateFlow.cs:106:13:106:20 | (...) => ... | From eec012d308f4e502aefefb4a8d6c2eaa6ebf22ef Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Mon, 12 Jun 2023 13:18:13 +0200 Subject: [PATCH 509/739] Java: Fix test --- .../localAdditionalTaintStep.ql | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.ql b/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.ql index cd51fbc746a..51abe1a6c5a 100644 --- a/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.ql +++ b/java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.ql @@ -12,15 +12,20 @@ predicate taintFlowUpdate(DataFlow::ParameterNode p1, DataFlow::ParameterNode p2 exists(DataFlow::PostUpdateNode ret | localTaint(p1, ret) | ret.getPreUpdateNode() = p2) } +predicate summaryStep(FlowSummaryNode src, FlowSummaryNode sink) { + FlowSummaryImpl::Private::Steps::summaryLocalStep(src.getSummaryNode(), sink.getSummaryNode(), + false) or + FlowSummaryImpl::Private::Steps::summaryReadStep(src.getSummaryNode(), _, sink.getSummaryNode()) or + FlowSummaryImpl::Private::Steps::summaryStoreStep(src.getSummaryNode(), _, sink.getSummaryNode()) +} + from DataFlow::Node src, DataFlow::Node sink where ( localAdditionalTaintStep(src, sink) or FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink, _) ) and - not FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) and - not FlowSummaryImpl::Private::Steps::summaryReadStep(src, _, sink) and - not FlowSummaryImpl::Private::Steps::summaryStoreStep(src, _, sink) + not summaryStep(src, sink) or exists(ArgumentNode arg, MethodAccess call, DataFlow::ParameterNode p, int i | src = arg and From 949d4491f93319a52d9d36e9510e08989d47c3de Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Mon, 12 Jun 2023 13:18:28 +0200 Subject: [PATCH 510/739] C#: Remove summaries for void-returning Reverse methods. --- csharp/ql/lib/ext/System.Collections.Generic.model.yml | 2 -- csharp/ql/lib/ext/System.Collections.Immutable.model.yml | 3 --- csharp/ql/lib/ext/System.Collections.model.yml | 2 -- csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml | 2 -- 4 files changed, 9 deletions(-) diff --git a/csharp/ql/lib/ext/System.Collections.Generic.model.yml b/csharp/ql/lib/ext/System.Collections.Generic.model.yml index 7640b88b97d..26ef7027b5e 100644 --- a/csharp/ql/lib/ext/System.Collections.Generic.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Generic.model.yml @@ -50,8 +50,6 @@ extensions: - ["System.Collections.Generic", "List<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.List<>+Enumerator.Current]", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Generic", "List<>", False, "InsertRange", "(System.Int32,System.Collections.Generic.IEnumerable<T>)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"] - - ["System.Collections.Generic", "List<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections.Generic", "List<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Generic", "Queue<>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Collections.Generic", "Queue<>", False, "CopyTo", "(T[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"] - ["System.Collections.Generic", "Queue<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.Queue<>+Enumerator.Current]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.Immutable.model.yml b/csharp/ql/lib/ext/System.Collections.Immutable.model.yml index 680cf56647c..1a71a78100e 100644 --- a/csharp/ql/lib/ext/System.Collections.Immutable.model.yml +++ b/csharp/ql/lib/ext/System.Collections.Immutable.model.yml @@ -20,7 +20,6 @@ extensions: - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "AddRange<>", "(System.Collections.Immutable.ImmutableArray<TDerived>+Builder)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "AddRange<>", "(TDerived[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current]", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(TKey,TValue)", "", "Argument[0]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] @@ -65,8 +64,6 @@ extensions: - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "InsertRange", "(System.Int32,System.Collections.Generic.IEnumerable<T>)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections.Immutable", "ImmutableQueue<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableQueue<>+Enumerator.Current]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableSortedDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] - ["System.Collections.Immutable", "ImmutableSortedDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Collections.model.yml b/csharp/ql/lib/ext/System.Collections.model.yml index e2c556916d2..ef098a6bfe5 100644 --- a/csharp/ql/lib/ext/System.Collections.model.yml +++ b/csharp/ql/lib/ext/System.Collections.model.yml @@ -11,8 +11,6 @@ extensions: - ["System.Collections", "ArrayList", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "ArrayList", False, "InsertRange", "(System.Int32,System.Collections.ICollection)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"] - ["System.Collections", "ArrayList", False, "Repeat", "(System.Object,System.Int32)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] - - ["System.Collections", "ArrayList", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Collections", "ArrayList", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "BitArray", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "Hashtable", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Collections", "Hashtable", False, "Hashtable", "(System.Collections.IDictionary)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"] diff --git a/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml b/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml index efe8a9a8abf..1e664b73e4a 100644 --- a/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml +++ b/csharp/ql/lib/ext/System.Runtime.CompilerServices.model.yml @@ -6,6 +6,4 @@ extensions: - ["System.Runtime.CompilerServices", "ConditionalWeakTable<,>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"] - ["System.Runtime.CompilerServices", "ConfiguredTaskAwaitable<>", False, "GetAwaiter", "()", "", "Argument[this].SyntheticField[m_configuredTaskAwaiter]", "ReturnValue", "value", "manual"] - ["System.Runtime.CompilerServices", "ConfiguredTaskAwaitable<>+ConfiguredTaskAwaiter", False, "GetResult", "()", "", "Argument[this].SyntheticField[m_task_configured_task_awaitable].Property[System.Threading.Tasks.Task<>.Result]", "ReturnValue", "value", "manual"] - - ["System.Runtime.CompilerServices", "ReadOnlyCollectionBuilder<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - - ["System.Runtime.CompilerServices", "ReadOnlyCollectionBuilder<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["System.Runtime.CompilerServices", "TaskAwaiter<>", False, "GetResult", "()", "", "Argument[this].SyntheticField[m_task_task_awaiter].Property[System.Threading.Tasks.Task<>.Result]", "ReturnValue", "value", "manual"] From 082c9a26d81ca9734b5ec72b13423680d9ec5e59 Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Mon, 12 Jun 2023 09:22:42 -0400 Subject: [PATCH 511/739] Update docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst Co-authored-by: Felicity Chapman <felicitymay@github.com> --- .../running-codeql-queries-at-scale-with-mrva.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index e82b0243294..9160a941718 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -181,7 +181,7 @@ Custom lists can contain a maximum of 1000 repositories, so at most only the fir You can view the progress of your search in the bottom right corner of the application in a box with the text "Searching for repositories...". If you click **Cancel**, no repositories will be added to your list. Once complete, you will see the resulting repositories appear in the dropdown under your custom list in the Variant Analysis Repositories panel. -Not all resulting repositories will have CodeQL databases or allow access to be analyzed. When you run an analysis on the list, the Variant Analysis Results view will show you which repositories were analyzed, which denied access, and which had no CodeQL database. +Some of the resulting repositories will not have CodeQL databases and some may not allow access by the CodeQL extension for Visual Studio Code. When you run an analysis on the list, the Variant Analysis Results view will show you which repositories were analyzed, which denied access, and which had no CodeQL database. Troubleshooting variant analysis -------------------------------- From 8c59ec2ec74c6822a6e41dafc62e69b0ca7736aa Mon Sep 17 00:00:00 2001 From: Sarita Iyer <66540150+saritai@users.noreply.github.com> Date: Mon, 12 Jun 2023 09:59:58 -0400 Subject: [PATCH 512/739] revise maximum info --- .../running-codeql-queries-at-scale-with-mrva.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst index f4ab2c1e3ee..d5c9c4197b0 100644 --- a/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst +++ b/docs/codeql/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva.rst @@ -166,7 +166,7 @@ You can use code search directly in the CodeQL extension to add a subset of repo For example, to add all repositories in the ``rails`` organization on GitHub, you can search ``org:rails``. -Custom lists can contain a maximum of 1000 repositories, so at most only the first 1000 repositories returned from your search will be added to your list. +You can add a maximum of 1000 repositories to a custom list per search. #. In the Variant Analysis Repositories panel, choose the list that you want to add repositories to. You can create a new list or choose an existing list that already contains repositories. From bc7cb1ec476201248288dfabc34a5634f162e92a Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Mon, 12 Jun 2023 15:41:05 +0200 Subject: [PATCH 513/739] C#: Fix some qltests. --- .../experimental/CWE-918/RequestForgery.cs | 18 ------- csharp/ql/test/experimental/CWE-918/options | 1 + .../dataflow/library/FlowSummaries.expected | 47 ++++++++----------- .../library/FlowSummariesFiltered.expected | 47 ++++++++----------- .../CWE-079/StoredXSS/XSS.cs | 18 ------- .../CWE-079/StoredXSS/options | 1 + .../CWE-327/InsecureSQLConnection/options | 1 + .../CWE-327/InsecureSQLConnection/stubs.cs | 23 --------- 8 files changed, 41 insertions(+), 115 deletions(-) create mode 100644 csharp/ql/test/experimental/CWE-918/options create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/options create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/options diff --git a/csharp/ql/test/experimental/CWE-918/RequestForgery.cs b/csharp/ql/test/experimental/CWE-918/RequestForgery.cs index 32347505b35..1c81fae4b91 100644 --- a/csharp/ql/test/experimental/CWE-918/RequestForgery.cs +++ b/csharp/ql/test/experimental/CWE-918/RequestForgery.cs @@ -38,21 +38,3 @@ namespace RequestForgery.Controllers } } } -// Missing stubs: -namespace System.Net.Http -{ - public class HttpClient - { - public async Task SendAsync(HttpRequestMessage request) => throw null; - } - - public class HttpRequestMessage - { - public HttpRequestMessage(HttpMethod method, string requestUri) => throw null; - } - - public class HttpMethod - { - public static readonly HttpMethod Get; - } -} diff --git a/csharp/ql/test/experimental/CWE-918/options b/csharp/ql/test/experimental/CWE-918/options new file mode 100644 index 00000000000..33d3af2e8b1 --- /dev/null +++ b/csharp/ql/test/experimental/CWE-918/options @@ -0,0 +1 @@ +semmle-extractor-options: /r:System.Net.Http.dll diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 46defadf531..70b7ae5b121 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -1087,7 +1087,7 @@ summary | System.Collections.Generic;List<>;false;Add;(System.Object);;Argument[0];Argument[this].Element;value;manual | | System.Collections.Generic;List<>;false;Add;(T);;Argument[0];Argument[this].Element;value;manual | | System.Collections.Generic;List<>;false;AddRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this].Element;value;manual | -| System.Collections.Generic;List<>;false;AsReadOnly;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Generic;List<>;false;AsReadOnly;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Generic;List<>;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | | System.Collections.Generic;List<>;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Collections.Generic;List<>;false;CopyTo;(T[]);;Argument[this];Argument[0].Element;taint;df-generated | @@ -1101,13 +1101,11 @@ summary | System.Collections.Generic;List<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Collections.Generic;List<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.List<>+Enumerator.Current];value;manual | | System.Collections.Generic;List<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Collections.Generic;List<>;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Generic;List<>;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Generic;List<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Generic;List<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Generic;List<>;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual | | System.Collections.Generic;List<>;false;List;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Collections.Generic;List<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Generic;List<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections.Generic;List<>;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System.Collections.Generic;List<>;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | | System.Collections.Generic;List<>;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | @@ -1231,7 +1229,7 @@ summary | System.Collections.Generic;SortedSet<>;false;GetViewBetween;(T,T);;Argument[1];ReturnValue;taint;df-generated | | System.Collections.Generic;SortedSet<>;false;GetViewBetween;(T,T);;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Generic;SortedSet<>;false;IntersectWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Collections.Generic;SortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Generic;SortedSet<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Generic;SortedSet<>;false;SortedSet;(System.Collections.Generic.IComparer<T>);;Argument[0];Argument[this];taint;df-generated | | System.Collections.Generic;SortedSet<>;false;SortedSet;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[this];taint;df-generated | | System.Collections.Generic;SortedSet<>;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | @@ -1290,7 +1288,6 @@ summary | System.Collections.Immutable;ImmutableArray<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections.Immutable;ImmutableArray<>+Builder;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableArray<>+Builder;false;MoveToImmutable;();;Argument[this];ReturnValue;taint;df-generated | -| System.Collections.Immutable;ImmutableArray<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableArray<>+Builder;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System.Collections.Immutable;ImmutableArray<>+Builder;false;set_Item;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableArray<>+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated | @@ -1487,12 +1484,10 @@ summary | System.Collections.Immutable;ImmutableList<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current];value;manual | -| System.Collections.Immutable;ImmutableList<>+Builder;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableList<>+Builder;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual | -| System.Collections.Immutable;ImmutableList<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableList<>+Builder;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;ToImmutable;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableList<>+Builder;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;get_SyncRoot;();;Argument[this];ReturnValue;taint;df-generated | @@ -1520,7 +1515,7 @@ summary | System.Collections.Immutable;ImmutableList<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Collections.Immutable;ImmutableList<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections.Immutable;ImmutableList<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current];value;manual | -| System.Collections.Immutable;ImmutableList<>;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableList<>;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableList<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableList<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableList<>;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual | @@ -1537,8 +1532,8 @@ summary | System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[1];Argument[this];taint;df-generated | | System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[1];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[this];ReturnValue;taint;df-generated | -| System.Collections.Immutable;ImmutableList<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableList<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableList<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableList<>;false;Reverse;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[this];taint;df-generated | | System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[1];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[this];ReturnValue;taint;df-generated | @@ -1676,7 +1671,7 @@ summary | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;df-generated | @@ -1703,7 +1698,7 @@ summary | System.Collections.Immutable;ImmutableSortedSet<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable<T>);;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[this];ReturnValue;taint;df-generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[this];ReturnValue;taint;df-generated | @@ -1897,7 +1892,7 @@ summary | System.Collections.Specialized;NotifyCollectionChangedEventArgs;false;get_OldItems;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Specialized;OrderedDictionary;false;Add;(System.Object,System.Object);;Argument[0];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Specialized;OrderedDictionary;false;Add;(System.Object,System.Object);;Argument[1];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | -| System.Collections.Specialized;OrderedDictionary;false;AsReadOnly;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Specialized;OrderedDictionary;false;AsReadOnly;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Specialized;OrderedDictionary;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | | System.Collections.Specialized;OrderedDictionary;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Collections.Specialized;OrderedDictionary;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | @@ -1938,21 +1933,19 @@ summary | System.Collections;ArrayList;false;AddRange;(System.Collections.ICollection);;Argument[0].Element;Argument[this].Element;value;manual | | System.Collections;ArrayList;false;ArrayList;(System.Collections.ICollection);;Argument[0].Element;Argument[this];taint;df-generated | | System.Collections;ArrayList;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | -| System.Collections;ArrayList;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;ArrayList;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;CopyTo;(System.Array);;Argument[this];Argument[0].Element;taint;df-generated | | System.Collections;ArrayList;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Collections;ArrayList;false;FixedSize;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;FixedSize;(System.Collections.IList);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections;ArrayList;false;GetEnumerator;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Collections;ArrayList;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;ArrayList;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Collections;ArrayList;false;InsertRange;(System.Int32,System.Collections.ICollection);;Argument[1].Element;Argument[this].Element;value;manual | | System.Collections;ArrayList;false;ReadOnly;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;ArrayList;false;ReadOnly;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;ArrayList;false;Repeat;(System.Object,System.Int32);;Argument[0];ReturnValue.Element;value;manual | -| System.Collections;ArrayList;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections;ArrayList;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;SetRange;(System.Int32,System.Collections.ICollection);;Argument[1].Element;Argument[this];taint;df-generated | | System.Collections;ArrayList;false;Synchronized;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;ArrayList;false;Synchronized;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated | @@ -1960,7 +1953,7 @@ summary | System.Collections;ArrayList;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | | System.Collections;ArrayList;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Collections;BitArray;false;And;(System.Collections.BitArray);;Argument[this];ReturnValue;value;df-generated | -| System.Collections;BitArray;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;BitArray;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;BitArray;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Collections;BitArray;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections;BitArray;false;LeftShift;(System.Int32);;Argument[this];ReturnValue;value;df-generated | @@ -2007,7 +2000,7 @@ summary | System.Collections;Hashtable;false;Add;(System.Object,System.Object);;Argument[0];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections;Hashtable;false;Add;(System.Object,System.Object);;Argument[1];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections;Hashtable;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | -| System.Collections;Hashtable;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;Hashtable;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;Hashtable;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Collections;Hashtable;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections;Hashtable;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated | @@ -2055,7 +2048,7 @@ summary | System.Collections;IList;true;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System.Collections;IList;true;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Collections;Queue;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | -| System.Collections;Queue;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;Queue;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;Queue;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Collections;Queue;false;Dequeue;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections;Queue;false;Enqueue;(System.Object);;Argument[0];Argument[this];taint;df-generated | @@ -2071,7 +2064,7 @@ summary | System.Collections;SortedList;false;Add;(System.Object,System.Object);;Argument[0];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections;SortedList;false;Add;(System.Object,System.Object);;Argument[1];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections;SortedList;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | -| System.Collections;SortedList;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;SortedList;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;SortedList;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Collections;SortedList;false;GetByIndex;(System.Int32);;Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue;value;manual | | System.Collections;SortedList;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | @@ -2093,7 +2086,7 @@ summary | System.Collections;SortedList;false;set_Item;(System.Object,System.Object);;Argument[0];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections;SortedList;false;set_Item;(System.Object,System.Object);;Argument[1];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections;Stack;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | -| System.Collections;Stack;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;Stack;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;Stack;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Collections;Stack;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections;Stack;false;Peek;();;Argument[this].Element;ReturnValue;value;manual | @@ -3090,7 +3083,7 @@ summary | System.Data;InternalDataCollectionBase;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System.Data;InternalDataCollectionBase;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Data;InternalDataCollectionBase;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | -| System.Data;PropertyCollection;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Data;PropertyCollection;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Data;TypedTableBase<>;false;Cast<>;();;Argument[this];ReturnValue;taint;df-generated | | System.Data;TypedTableBase<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Data;TypedTableBase<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | @@ -7346,8 +7339,6 @@ summary | System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual | | System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;ReadOnlyCollectionBuilder;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | | System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | @@ -10702,7 +10693,7 @@ summary | System;Array;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | | System;Array;false;Clear;(System.Array);;Argument[0].WithoutElement;Argument[0];value;manual | | System;Array;false;Clear;(System.Array,System.Int32,System.Int32);;Argument[0].WithoutElement;Argument[0];value;manual | -| System;Array;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System;Array;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System;Array;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual | | System;Array;false;CopyTo;(System.Array,System.Int64);;Argument[this].Element;Argument[0].Element;value;manual | | System;Array;false;Fill<>;(T[],T);;Argument[1];Argument[0].Element;taint;df-generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 4ae26655169..e1af1614843 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -707,7 +707,7 @@ summary | System.Collections.Generic;LinkedListNode<>;false;set_Value;(T);;Argument[0];Argument[this];taint;df-generated | | System.Collections.Generic;List<>+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Generic;List<>;false;AddRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this].Element;value;manual | -| System.Collections.Generic;List<>;false;AsReadOnly;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Generic;List<>;false;AsReadOnly;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Generic;List<>;false;CopyTo;(T[]);;Argument[this];Argument[0].Element;taint;df-generated | | System.Collections.Generic;List<>;false;Find;(System.Predicate<T>);;Argument[this].Element;Argument[0].Parameter[0];value;manual | | System.Collections.Generic;List<>;false;Find;(System.Predicate<T>);;Argument[this].Element;ReturnValue;value;manual | @@ -716,11 +716,9 @@ summary | System.Collections.Generic;List<>;false;FindLast;(System.Predicate<T>);;Argument[this].Element;Argument[0].Parameter[0];value;manual | | System.Collections.Generic;List<>;false;FindLast;(System.Predicate<T>);;Argument[this].Element;ReturnValue;value;manual | | System.Collections.Generic;List<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.List<>+Enumerator.Current];value;manual | -| System.Collections.Generic;List<>;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Generic;List<>;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Generic;List<>;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual | | System.Collections.Generic;List<>;false;List;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Collections.Generic;List<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Generic;List<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections.Generic;List<>;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | | System.Collections.Generic;PriorityQueue<,>+UnorderedItemsCollection+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Generic;PriorityQueue<,>+UnorderedItemsCollection;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated | @@ -786,7 +784,7 @@ summary | System.Collections.Generic;SortedSet<>;false;GetViewBetween;(T,T);;Argument[1];ReturnValue;taint;df-generated | | System.Collections.Generic;SortedSet<>;false;GetViewBetween;(T,T);;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Generic;SortedSet<>;false;IntersectWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Collections.Generic;SortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Generic;SortedSet<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Generic;SortedSet<>;false;SortedSet;(System.Collections.Generic.IComparer<T>);;Argument[0];Argument[this];taint;df-generated | | System.Collections.Generic;SortedSet<>;false;SortedSet;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[this];taint;df-generated | | System.Collections.Generic;SortedSet<>;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | @@ -837,7 +835,6 @@ summary | System.Collections.Immutable;ImmutableArray<>+Builder;false;AddRange<>;(TDerived[]);;Argument[0].Element;Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableArray<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Collections.Immutable;ImmutableArray<>+Builder;false;MoveToImmutable;();;Argument[this];ReturnValue;taint;df-generated | -| System.Collections.Immutable;ImmutableArray<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableArray<>+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableArray<>;false;Add;(T);;Argument[0];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableArray<>;false;AddRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;ReturnValue;taint;df-generated | @@ -971,10 +968,8 @@ summary | System.Collections.Immutable;ImmutableList<>+Builder;false;FindLast;(System.Predicate<T>);;Argument[this].Element;Argument[0].Parameter[0];value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;FindLast;(System.Predicate<T>);;Argument[this].Element;ReturnValue;value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current];value;manual | -| System.Collections.Immutable;ImmutableList<>+Builder;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableList<>+Builder;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual | -| System.Collections.Immutable;ImmutableList<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableList<>+Builder;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableList<>+Builder;false;ToImmutable;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableList<>+Builder;false;get_SyncRoot;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableList<>+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated | @@ -992,7 +987,7 @@ summary | System.Collections.Immutable;ImmutableList<>;false;FindLast;(System.Predicate<T>);;Argument[this].Element;Argument[0].Parameter[0];value;manual | | System.Collections.Immutable;ImmutableList<>;false;FindLast;(System.Predicate<T>);;Argument[this].Element;ReturnValue;value;manual | | System.Collections.Immutable;ImmutableList<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current];value;manual | -| System.Collections.Immutable;ImmutableList<>;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableList<>;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableList<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableList<>;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual | | System.Collections.Immutable;ImmutableList<>;false;Remove;(T);;Argument[this];ReturnValue;taint;df-generated | @@ -1008,8 +1003,8 @@ summary | System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[1];Argument[this];taint;df-generated | | System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[1];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[this];ReturnValue;taint;df-generated | -| System.Collections.Immutable;ImmutableList<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableList<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableList<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableList<>;false;Reverse;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[this];taint;df-generated | | System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[1];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[this];ReturnValue;taint;df-generated | @@ -1106,7 +1101,7 @@ summary | System.Collections.Immutable;ImmutableSortedSet;false;ToImmutableSortedSet<>;(System.Collections.Immutable.ImmutableSortedSet<TSource>+Builder);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;df-generated | @@ -1124,7 +1119,7 @@ summary | System.Collections.Immutable;ImmutableSortedSet<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable<T>);;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[this];ReturnValue;taint;df-generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[this];ReturnValue;taint;df-generated | @@ -1237,7 +1232,7 @@ summary | System.Collections.Specialized;NotifyCollectionChangedEventArgs;false;NotifyCollectionChangedEventArgs;(System.Collections.Specialized.NotifyCollectionChangedAction,System.Object,System.Object,System.Int32);;Argument[2];Argument[this];taint;df-generated | | System.Collections.Specialized;NotifyCollectionChangedEventArgs;false;get_NewItems;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections.Specialized;NotifyCollectionChangedEventArgs;false;get_OldItems;();;Argument[this];ReturnValue;taint;df-generated | -| System.Collections.Specialized;OrderedDictionary;false;AsReadOnly;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections.Specialized;OrderedDictionary;false;AsReadOnly;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections.Specialized;OrderedDictionary;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[this];Argument[0];taint;df-generated | | System.Collections.Specialized;OrderedDictionary;false;OrderedDictionary;(System.Int32,System.Collections.IEqualityComparer);;Argument[1];Argument[this];taint;df-generated | | System.Collections.Specialized;OrderedDictionary;false;OrderedDictionary;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[this];taint;df-generated | @@ -1258,24 +1253,22 @@ summary | System.Collections;ArrayList;false;Adapter;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;ArrayList;false;AddRange;(System.Collections.ICollection);;Argument[0].Element;Argument[this].Element;value;manual | | System.Collections;ArrayList;false;ArrayList;(System.Collections.ICollection);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Collections;ArrayList;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;ArrayList;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;CopyTo;(System.Array);;Argument[this];Argument[0].Element;taint;df-generated | | System.Collections;ArrayList;false;FixedSize;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;FixedSize;(System.Collections.IList);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;GetEnumerator;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Collections;ArrayList;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;ArrayList;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;InsertRange;(System.Int32,System.Collections.ICollection);;Argument[1].Element;Argument[this].Element;value;manual | | System.Collections;ArrayList;false;ReadOnly;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;ArrayList;false;ReadOnly;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;ArrayList;false;Repeat;(System.Object,System.Int32);;Argument[0];ReturnValue.Element;value;manual | -| System.Collections;ArrayList;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections;ArrayList;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Collections;ArrayList;false;SetRange;(System.Int32,System.Collections.ICollection);;Argument[1].Element;Argument[this];taint;df-generated | | System.Collections;ArrayList;false;Synchronized;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;ArrayList;false;Synchronized;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;ArrayList;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | | System.Collections;BitArray;false;And;(System.Collections.BitArray);;Argument[this];ReturnValue;value;df-generated | -| System.Collections;BitArray;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;BitArray;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;BitArray;false;LeftShift;(System.Int32);;Argument[this];ReturnValue;value;df-generated | | System.Collections;BitArray;false;Not;();;Argument[this];ReturnValue;value;df-generated | | System.Collections;BitArray;false;Or;(System.Collections.BitArray);;Argument[this];ReturnValue;value;df-generated | @@ -1300,7 +1293,7 @@ summary | System.Collections;DictionaryEntry;false;get_Value;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections;DictionaryEntry;false;set_Key;(System.Object);;Argument[0];Argument[this];taint;df-generated | | System.Collections;DictionaryEntry;false;set_Value;(System.Object);;Argument[0];Argument[this];taint;df-generated | -| System.Collections;Hashtable;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;Hashtable;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;Hashtable;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections;Hashtable;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[this];Argument[0];taint;df-generated | | System.Collections;Hashtable;false;Hashtable;(System.Collections.IDictionary);;Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | @@ -1341,7 +1334,7 @@ summary | System.Collections;IList;true;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual | | System.Collections;IList;true;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Collections;Queue;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | -| System.Collections;Queue;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;Queue;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;Queue;false;Dequeue;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections;Queue;false;Enqueue;(System.Object);;Argument[0];Argument[this];taint;df-generated | | System.Collections;Queue;false;Peek;();;Argument[this].Element;ReturnValue;value;manual | @@ -1350,7 +1343,7 @@ summary | System.Collections;Queue;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | | System.Collections;ReadOnlyCollectionBase;false;get_InnerList;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections;ReadOnlyCollectionBase;false;get_SyncRoot;();;Argument[this];ReturnValue;taint;df-generated | -| System.Collections;SortedList;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;SortedList;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;SortedList;false;GetByIndex;(System.Int32);;Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue;value;manual | | System.Collections;SortedList;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated | | System.Collections;SortedList;false;GetKey;(System.Int32);;Argument[this];ReturnValue;taint;df-generated | @@ -1365,7 +1358,7 @@ summary | System.Collections;SortedList;false;Synchronized;(System.Collections.SortedList);;Argument[0].Element;ReturnValue;taint;df-generated | | System.Collections;SortedList;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | | System.Collections;Stack;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual | -| System.Collections;Stack;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Collections;Stack;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Collections;Stack;false;Peek;();;Argument[this].Element;ReturnValue;value;manual | | System.Collections;Stack;false;Pop;();;Argument[this].Element;ReturnValue;value;manual | | System.Collections;Stack;false;Push;(System.Object);;Argument[0];Argument[this];taint;df-generated | @@ -2244,7 +2237,7 @@ summary | System.Data;ITableMappingCollection;true;get_Item;(System.String);;Argument[this].Element;ReturnValue;value;manual | | System.Data;ITableMappingCollection;true;set_Item;(System.String,System.Object);;Argument[1];Argument[this].Element;value;manual | | System.Data;InternalDataCollectionBase;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | -| System.Data;PropertyCollection;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System.Data;PropertyCollection;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System.Data;TypedTableBase<>;false;Cast<>;();;Argument[this];ReturnValue;taint;df-generated | | System.Data;TypedTableBaseExtensions;false;AsEnumerable<>;(System.Data.TypedTableBase<TRow>);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Data;TypedTableBaseExtensions;false;ElementAtOrDefault<>;(System.Data.TypedTableBase<TRow>,System.Int32);;Argument[0].Element;ReturnValue;value;manual | @@ -6001,8 +5994,6 @@ summary | System.Runtime.CompilerServices;PoolingAsyncValueTaskMethodBuilder<>;false;SetResult;(TResult);;Argument[0];Argument[this];taint;df-generated | | System.Runtime.CompilerServices;PoolingAsyncValueTaskMethodBuilder<>;false;get_Task;();;Argument[this];ReturnValue;taint;df-generated | | System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;ReadOnlyCollectionBuilder;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated | -| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual | | System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated | | System.Runtime.CompilerServices;RuntimeWrappedException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[this];Argument[0];taint;df-generated | | System.Runtime.CompilerServices;RuntimeWrappedException;false;RuntimeWrappedException;(System.Object);;Argument[0];Argument[this];taint;df-generated | @@ -9028,7 +9019,7 @@ summary | System;Array;false;AsReadOnly<>;(T[]);;Argument[0].Element;ReturnValue.Element;value;manual | | System;Array;false;Clear;(System.Array);;Argument[0].WithoutElement;Argument[0];value;manual | | System;Array;false;Clear;(System.Array,System.Int32,System.Int32);;Argument[0].WithoutElement;Argument[0];value;manual | -| System;Array;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual | +| System;Array;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual | | System;Array;false;CopyTo;(System.Array,System.Int64);;Argument[this].Element;Argument[0].Element;value;manual | | System;Array;false;Fill<>;(T[],T);;Argument[1];Argument[0].Element;taint;df-generated | | System;Array;false;Fill<>;(T[],T,System.Int32,System.Int32);;Argument[1];Argument[0].Element;taint;df-generated | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.cs b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.cs index 650f636f875..da82672c6df 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.cs @@ -135,21 +135,3 @@ namespace Test } } } - -namespace System.Net -{ - public class HttpListenerResponse - { - public System.IO.Stream OutputStream => null; - } - - class HttpListenerContext - { - public HttpListenerResponse Response => null; - } - - class HttpListener - { - public HttpListenerContext GetContext() => null; - } -} diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/options b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/options new file mode 100644 index 00000000000..a95668cbc59 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/options @@ -0,0 +1 @@ +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Net.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/options b/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/options new file mode 100644 index 00000000000..445f576fc95 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/options @@ -0,0 +1 @@ +semmle-extractor-options: /r:System.Data.Common.dll diff --git a/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/stubs.cs b/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/stubs.cs index 26461fc0224..833a5902326 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/stubs.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/stubs.cs @@ -12,29 +12,6 @@ namespace System namespace Common { - // Generated from `System.Data.Common.DbConnectionStringBuilder` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089` - public class DbConnectionStringBuilder : System.Collections.IEnumerable, System.Collections.IDictionary, System.Collections.ICollection - { - System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() => throw null; - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; - bool System.Collections.ICollection.IsSynchronized { get => throw null; } - bool System.Collections.IDictionary.Contains(object keyword) => throw null; - object System.Collections.ICollection.SyncRoot { get => throw null; } - public object this[object keyword] { get => throw null; set => throw null; } - public bool IsReadOnly { get => throw null; } - public override string ToString() => throw null; - public string ConnectionString { get => throw null; set => throw null; } - public virtual System.Collections.ICollection Keys { get => throw null; } - public virtual System.Collections.ICollection Values { get => throw null; } - public virtual bool IsFixedSize { get => throw null; } - public virtual int Count { get => throw null; } - public virtual void Clear() => throw null; - void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null; - void System.Collections.IDictionary.Add(object keyword, object value) => throw null; - void System.Collections.IDictionary.Remove(object keyword) => throw null; - public void Dispose() => throw null; - } - // Generated from `System.Data.Common.DbConnection` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089` abstract public class DbConnection : System.IDisposable, System.Data.IDbConnection { From cd6f738f723fa2688c531068c71ad1d07d9ea36b Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Tue, 6 Jun 2023 14:42:49 +0200 Subject: [PATCH 514/739] add mongoose.Types.ObjectId.isValid as a sanitizer-guard for NoSQL injection --- .../semmle/javascript/security/TaintedObject.qll | 16 ++++++++++++++++ .../CWE-089/untyped/DatabaseAccesses.expected | 2 ++ .../CWE-089/untyped/SqlInjection.expected | 7 +++++++ .../Security/CWE-089/untyped/mongoose.js | 8 +++++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll b/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll index eac7dd4e762..3022bded373 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll @@ -120,6 +120,22 @@ module TaintedObject { override predicate sanitizes(boolean outcome, Expr e) { e = x and outcome = polarity } } + /** A guard that checks whether an input a valid string identifier using `mongoose.Types.ObjectId.isValid` */ + class ObjectIdGuard extends SanitizerGuard instanceof API::CallNode { + ObjectIdGuard() { + this = + API::moduleImport("mongoose") + .getMember("Types") + .getMember("ObjectId") + .getMember("isValid") + .getACall() + } + + override predicate sanitizes(boolean outcome, Expr e, FlowLabel lbl) { + e = super.getAnArgument().asExpr() and outcome = true and lbl = label() + } + } + /** * A sanitizer guard that validates an input against a JSON schema. */ diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected index ffac58c8553..cfc87dfd13a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected @@ -42,6 +42,8 @@ | mongoose.js:97:2:97:52 | Documen ... query)) | | mongoose.js:99:2:99:50 | Documen ... query)) | | mongoose.js:113:2:113:53 | Documen ... () { }) | +| mongoose.js:134:6:134:55 | Documen ... on(){}) | +| mongoose.js:136:6:136:55 | Documen ... on(){}) | | mysql.js:8:9:11:47 | connect ... ds) {}) | | mysql.js:14:9:16:47 | connect ... ds) {}) | | mysql.js:19:9:20:48 | connect ... ds) {}) | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index 6eba7711032..02b502c52ad 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -283,6 +283,8 @@ nodes | mongoose.js:130:16:130:26 | { _id: id } | | mongoose.js:130:16:130:26 | { _id: id } | | mongoose.js:130:23:130:24 | id | +| mongoose.js:136:33:136:37 | query | +| mongoose.js:136:33:136:37 | query | | mongooseJsonParse.js:19:11:19:20 | query | | mongooseJsonParse.js:19:19:19:20 | {} | | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | @@ -688,6 +690,8 @@ edges | mongoose.js:20:11:20:20 | query | mongoose.js:111:14:111:18 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:113:31:113:35 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:113:31:113:35 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:136:33:136:37 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:136:33:136:37 | query | | mongoose.js:20:19:20:20 | {} | mongoose.js:20:11:20:20 | query | | mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title | | mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title | @@ -758,6 +762,8 @@ edges | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:111:14:111:18 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:113:31:113:35 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:113:31:113:35 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:136:33:136:37 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:136:33:136:37 | query | | mongoose.js:24:25:24:29 | query | mongoose.js:24:24:24:30 | [query] | | mongoose.js:24:25:24:29 | query | mongoose.js:24:24:24:30 | [query] | | mongoose.js:115:6:115:22 | id | mongoose.js:123:20:123:21 | id | @@ -1008,6 +1014,7 @@ edges | mongoose.js:128:22:128:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:128:22:128:25 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:129:21:129:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:129:21:129:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:130:16:130:26 | { _id: id } | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:130:16:130:26 | { _id: id } | This query object depends on a $@. | mongoose.js:115:11:115:22 | req.query.id | user-provided value | +| mongoose.js:136:33:136:37 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:136:33:136:37 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | | mongooseJsonParse.js:23:19:23:23 | query | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:23:19:23:23 | query | This query object depends on a $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | user-provided value | | mongooseModelClient.js:11:16:11:24 | { id: v } | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:11:16:11:24 | { id: v } | This query object depends on a $@. | mongooseModelClient.js:10:22:10:29 | req.body | user-provided value | | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | This query object depends on a $@. | mongooseModelClient.js:12:22:12:29 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js b/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js index baeb13b1fbc..59cf991c87b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js @@ -104,7 +104,7 @@ app.post('/documents/find', (req, res) => { new innocent(X, Y, query); function getQueryConstructor() { - return Mongoose.Query; + return Mongoose.Query; } var C = getQueryConstructor(); @@ -129,4 +129,10 @@ app.post('/documents/find', (req, res) => { Document.updateOne(cond, Y); // NOT OK Document.find({ _id: id }); // NOT OK Document.find({ _id: { $eq: id } }); // OK + + if (Mongoose.Types.ObjectId.isValid(query)) { + Document.findByIdAndUpdate(query, X, function(){}); // OK - is sanitized + } else { + Document.findByIdAndUpdate(query, X, function(){}); // NOT OK + } }); From 3fd9f26b52829043a0b62db03255a9dfc33f7238 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 12 Jun 2023 16:40:42 +0200 Subject: [PATCH 515/739] use consistent indentation in mongoose.js --- .../CWE-089/untyped/DatabaseAccesses.expected | 6 +- .../CWE-089/untyped/SqlInjection.expected | 426 +++++++++--------- .../Security/CWE-089/untyped/mongoose.js | 84 ++-- 3 files changed, 258 insertions(+), 258 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected index cfc87dfd13a..0f95e5464fb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected @@ -27,7 +27,7 @@ | mongoose.js:63:2:63:34 | Documen ... then(X) | | mongoose.js:65:2:65:51 | Documen ... on(){}) | | mongoose.js:67:2:68:27 | new Mon ... on(){}) | -| mongoose.js:71:5:78:9 | Documen ... .exec() | +| mongoose.js:71:2:78:9 | Documen ... .exec() | | mongoose.js:85:2:85:52 | Documen ... query)) | | mongoose.js:86:2:86:52 | Documen ... query)) | | mongoose.js:87:2:87:57 | Documen ... query)) | @@ -42,8 +42,8 @@ | mongoose.js:97:2:97:52 | Documen ... query)) | | mongoose.js:99:2:99:50 | Documen ... query)) | | mongoose.js:113:2:113:53 | Documen ... () { }) | -| mongoose.js:134:6:134:55 | Documen ... on(){}) | -| mongoose.js:136:6:136:55 | Documen ... on(){}) | +| mongoose.js:134:3:134:52 | Documen ... on(){}) | +| mongoose.js:136:3:136:52 | Documen ... on(){}) | | mysql.js:8:9:11:47 | connect ... ds) {}) | | mysql.js:14:9:16:47 | connect ... ds) {}) | | mysql.js:19:9:20:48 | connect ... ds) {}) | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index 02b502c52ad..c241751da3e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -174,38 +174,38 @@ nodes | mongodb_bodySafe.js:24:19:24:33 | req.query.title | | mongodb_bodySafe.js:29:16:29:20 | query | | mongodb_bodySafe.js:29:16:29:20 | query | -| mongoose.js:20:11:20:20 | query | -| mongoose.js:20:19:20:20 | {} | -| mongoose.js:21:19:21:26 | req.body | -| mongoose.js:21:19:21:26 | req.body | -| mongoose.js:21:19:21:32 | req.body.title | -| mongoose.js:24:24:24:30 | [query] | -| mongoose.js:24:24:24:30 | [query] | -| mongoose.js:24:25:24:29 | query | -| mongoose.js:27:20:27:24 | query | -| mongoose.js:27:20:27:24 | query | -| mongoose.js:30:25:30:29 | query | -| mongoose.js:30:25:30:29 | query | -| mongoose.js:33:24:33:28 | query | -| mongoose.js:33:24:33:28 | query | -| mongoose.js:36:31:36:35 | query | -| mongoose.js:36:31:36:35 | query | -| mongoose.js:39:19:39:23 | query | -| mongoose.js:39:19:39:23 | query | -| mongoose.js:42:22:42:26 | query | -| mongoose.js:42:22:42:26 | query | -| mongoose.js:45:31:45:35 | query | -| mongoose.js:45:31:45:35 | query | -| mongoose.js:48:31:48:35 | query | -| mongoose.js:48:31:48:35 | query | -| mongoose.js:51:31:51:35 | query | -| mongoose.js:51:31:51:35 | query | -| mongoose.js:54:25:54:29 | query | -| mongoose.js:54:25:54:29 | query | -| mongoose.js:57:21:57:25 | query | -| mongoose.js:57:21:57:25 | query | -| mongoose.js:60:25:60:29 | query | -| mongoose.js:60:25:60:29 | query | +| mongoose.js:20:8:20:17 | query | +| mongoose.js:20:16:20:17 | {} | +| mongoose.js:21:16:21:23 | req.body | +| mongoose.js:21:16:21:23 | req.body | +| mongoose.js:21:16:21:29 | req.body.title | +| mongoose.js:24:21:24:27 | [query] | +| mongoose.js:24:21:24:27 | [query] | +| mongoose.js:24:22:24:26 | query | +| mongoose.js:27:17:27:21 | query | +| mongoose.js:27:17:27:21 | query | +| mongoose.js:30:22:30:26 | query | +| mongoose.js:30:22:30:26 | query | +| mongoose.js:33:21:33:25 | query | +| mongoose.js:33:21:33:25 | query | +| mongoose.js:36:28:36:32 | query | +| mongoose.js:36:28:36:32 | query | +| mongoose.js:39:16:39:20 | query | +| mongoose.js:39:16:39:20 | query | +| mongoose.js:42:19:42:23 | query | +| mongoose.js:42:19:42:23 | query | +| mongoose.js:45:28:45:32 | query | +| mongoose.js:45:28:45:32 | query | +| mongoose.js:48:28:48:32 | query | +| mongoose.js:48:28:48:32 | query | +| mongoose.js:51:28:51:32 | query | +| mongoose.js:51:28:51:32 | query | +| mongoose.js:54:22:54:26 | query | +| mongoose.js:54:22:54:26 | query | +| mongoose.js:57:18:57:22 | query | +| mongoose.js:57:18:57:22 | query | +| mongoose.js:60:22:60:26 | query | +| mongoose.js:60:22:60:26 | query | | mongoose.js:63:21:63:25 | query | | mongoose.js:63:21:63:25 | query | | mongoose.js:65:32:65:36 | query | @@ -214,10 +214,10 @@ nodes | mongoose.js:67:27:67:31 | query | | mongoose.js:68:8:68:12 | query | | mongoose.js:68:8:68:12 | query | -| mongoose.js:71:20:71:24 | query | -| mongoose.js:71:20:71:24 | query | -| mongoose.js:72:16:72:20 | query | -| mongoose.js:72:16:72:20 | query | +| mongoose.js:71:17:71:21 | query | +| mongoose.js:71:17:71:21 | query | +| mongoose.js:72:10:72:14 | query | +| mongoose.js:72:10:72:14 | query | | mongoose.js:73:8:73:12 | query | | mongoose.js:73:8:73:12 | query | | mongoose.js:74:7:74:11 | query | @@ -283,8 +283,8 @@ nodes | mongoose.js:130:16:130:26 | { _id: id } | | mongoose.js:130:16:130:26 | { _id: id } | | mongoose.js:130:23:130:24 | id | -| mongoose.js:136:33:136:37 | query | -| mongoose.js:136:33:136:37 | query | +| mongoose.js:136:30:136:34 | query | +| mongoose.js:136:30:136:34 | query | | mongooseJsonParse.js:19:11:19:20 | query | | mongooseJsonParse.js:19:19:19:20 | {} | | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | @@ -625,147 +625,147 @@ edges | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:24:25:24:29 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:27:20:27:24 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:27:20:27:24 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:30:25:30:29 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:30:25:30:29 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:33:24:33:28 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:33:24:33:28 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:36:31:36:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:36:31:36:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:39:19:39:23 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:39:19:39:23 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:42:22:42:26 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:42:22:42:26 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:45:31:45:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:45:31:45:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:48:31:48:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:48:31:48:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:51:31:51:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:51:31:51:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:54:25:54:29 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:54:25:54:29 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:57:21:57:25 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:57:21:57:25 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:60:25:60:29 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:60:25:60:29 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:63:21:63:25 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:63:21:63:25 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:65:32:65:36 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:65:32:65:36 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:67:27:67:31 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:67:27:67:31 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:68:8:68:12 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:68:8:68:12 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:71:20:71:24 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:71:20:71:24 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:72:16:72:20 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:72:16:72:20 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:73:8:73:12 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:73:8:73:12 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:74:7:74:11 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:74:7:74:11 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:75:16:75:20 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:75:16:75:20 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:77:10:77:14 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:77:10:77:14 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:82:46:82:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:82:46:82:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:83:47:83:51 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:83:47:83:51 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:85:46:85:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:85:46:85:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:87:51:87:55 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:87:51:87:55 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:89:46:89:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:89:46:89:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:92:46:92:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:92:46:92:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:94:51:94:55 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:94:51:94:55 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:96:46:96:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:96:46:96:50 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:111:14:111:18 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:111:14:111:18 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:113:31:113:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:113:31:113:35 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:136:33:136:37 | query | -| mongoose.js:20:11:20:20 | query | mongoose.js:136:33:136:37 | query | -| mongoose.js:20:19:20:20 | {} | mongoose.js:20:11:20:20 | query | -| mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title | -| mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:20:11:20:20 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:20:19:20:20 | {} | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:24:25:24:29 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:27:20:27:24 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:27:20:27:24 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:30:25:30:29 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:30:25:30:29 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:33:24:33:28 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:33:24:33:28 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:36:31:36:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:36:31:36:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:39:19:39:23 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:39:19:39:23 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:42:22:42:26 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:42:22:42:26 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:45:31:45:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:45:31:45:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:48:31:48:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:48:31:48:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:51:31:51:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:51:31:51:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:54:25:54:29 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:54:25:54:29 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:57:21:57:25 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:57:21:57:25 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:60:25:60:29 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:60:25:60:29 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:63:21:63:25 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:63:21:63:25 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:65:32:65:36 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:65:32:65:36 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:67:27:67:31 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:67:27:67:31 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:68:8:68:12 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:68:8:68:12 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:71:20:71:24 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:71:20:71:24 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:16:72:20 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:16:72:20 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:8:73:12 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:8:73:12 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:7:74:11 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:7:74:11 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:75:16:75:20 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:75:16:75:20 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:77:10:77:14 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:77:10:77:14 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:46:82:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:46:82:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:83:47:83:51 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:83:47:83:51 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:85:46:85:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:85:46:85:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:87:51:87:55 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:87:51:87:55 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:89:46:89:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:89:46:89:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:92:46:92:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:92:46:92:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:94:51:94:55 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:94:51:94:55 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:96:46:96:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:96:46:96:50 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:111:14:111:18 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:111:14:111:18 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:113:31:113:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:113:31:113:35 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:136:33:136:37 | query | -| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:136:33:136:37 | query | -| mongoose.js:24:25:24:29 | query | mongoose.js:24:24:24:30 | [query] | -| mongoose.js:24:25:24:29 | query | mongoose.js:24:24:24:30 | [query] | +| mongoose.js:20:8:20:17 | query | mongoose.js:24:22:24:26 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:27:17:27:21 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:27:17:27:21 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:30:22:30:26 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:30:22:30:26 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:33:21:33:25 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:33:21:33:25 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:36:28:36:32 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:36:28:36:32 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:39:16:39:20 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:39:16:39:20 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:42:19:42:23 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:42:19:42:23 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:45:28:45:32 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:45:28:45:32 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:48:28:48:32 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:48:28:48:32 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:51:28:51:32 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:51:28:51:32 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:54:22:54:26 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:54:22:54:26 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:57:18:57:22 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:57:18:57:22 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:60:22:60:26 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:60:22:60:26 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:63:21:63:25 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:63:21:63:25 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:65:32:65:36 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:65:32:65:36 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:67:27:67:31 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:67:27:67:31 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:68:8:68:12 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:68:8:68:12 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:71:17:71:21 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:71:17:71:21 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:72:10:72:14 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:72:10:72:14 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:73:8:73:12 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:73:8:73:12 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:74:7:74:11 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:74:7:74:11 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:75:16:75:20 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:75:16:75:20 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:77:10:77:14 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:77:10:77:14 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:82:46:82:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:82:46:82:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:83:47:83:51 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:83:47:83:51 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:85:46:85:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:85:46:85:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:87:51:87:55 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:87:51:87:55 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:89:46:89:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:89:46:89:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:92:46:92:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:92:46:92:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:94:51:94:55 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:94:51:94:55 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:96:46:96:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:96:46:96:50 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:111:14:111:18 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:111:14:111:18 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:113:31:113:35 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:113:31:113:35 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:136:30:136:34 | query | +| mongoose.js:20:8:20:17 | query | mongoose.js:136:30:136:34 | query | +| mongoose.js:20:16:20:17 | {} | mongoose.js:20:8:20:17 | query | +| mongoose.js:21:16:21:23 | req.body | mongoose.js:21:16:21:29 | req.body.title | +| mongoose.js:21:16:21:23 | req.body | mongoose.js:21:16:21:29 | req.body.title | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:20:8:20:17 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:20:16:20:17 | {} | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:24:22:24:26 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:27:17:27:21 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:27:17:27:21 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:30:22:30:26 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:30:22:30:26 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:33:21:33:25 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:33:21:33:25 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:36:28:36:32 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:36:28:36:32 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:39:16:39:20 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:39:16:39:20 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:42:19:42:23 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:42:19:42:23 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:45:28:45:32 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:45:28:45:32 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:48:28:48:32 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:48:28:48:32 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:51:28:51:32 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:51:28:51:32 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:54:22:54:26 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:54:22:54:26 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:57:18:57:22 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:57:18:57:22 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:60:22:60:26 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:60:22:60:26 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:63:21:63:25 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:63:21:63:25 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:65:32:65:36 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:65:32:65:36 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:67:27:67:31 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:67:27:67:31 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:68:8:68:12 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:68:8:68:12 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:71:17:71:21 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:71:17:71:21 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:72:10:72:14 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:72:10:72:14 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:73:8:73:12 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:73:8:73:12 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:74:7:74:11 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:74:7:74:11 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:75:16:75:20 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:75:16:75:20 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:77:10:77:14 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:77:10:77:14 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:82:46:82:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:82:46:82:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:83:47:83:51 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:83:47:83:51 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:85:46:85:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:85:46:85:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:87:51:87:55 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:87:51:87:55 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:89:46:89:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:89:46:89:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:92:46:92:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:92:46:92:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:94:51:94:55 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:94:51:94:55 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:96:46:96:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:96:46:96:50 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:111:14:111:18 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:111:14:111:18 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:113:31:113:35 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:113:31:113:35 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:136:30:136:34 | query | +| mongoose.js:21:16:21:29 | req.body.title | mongoose.js:136:30:136:34 | query | +| mongoose.js:24:22:24:26 | query | mongoose.js:24:21:24:27 | [query] | +| mongoose.js:24:22:24:26 | query | mongoose.js:24:21:24:27 | [query] | | mongoose.js:115:6:115:22 | id | mongoose.js:123:20:123:21 | id | | mongoose.js:115:6:115:22 | id | mongoose.js:123:20:123:21 | id | | mongoose.js:115:6:115:22 | id | mongoose.js:130:23:130:24 | id | @@ -966,39 +966,39 @@ edges | mongodb.js:85:12:85:24 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:85:12:85:24 | { tags: tag } | This query object depends on a $@. | mongodb.js:70:13:70:25 | req.query.tag | user-provided value | | mongodb.js:112:14:112:18 | query | mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | This query object depends on a $@. | mongodb.js:107:17:107:29 | queries.title | user-provided value | | mongodb_bodySafe.js:29:16:29:20 | query | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | This query object depends on a $@. | mongodb_bodySafe.js:24:19:24:33 | req.query.title | user-provided value | -| mongoose.js:24:24:24:30 | [query] | mongoose.js:21:19:21:26 | req.body | mongoose.js:24:24:24:30 | [query] | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:27:20:27:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:27:20:27:24 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:30:25:30:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:30:25:30:29 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:33:24:33:28 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:33:24:33:28 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:36:31:36:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:36:31:36:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:39:19:39:23 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:39:19:39:23 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:42:22:42:26 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:42:22:42:26 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:45:31:45:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:45:31:45:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:48:31:48:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:48:31:48:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:51:31:51:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:51:31:51:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:54:25:54:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:54:25:54:29 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:57:21:57:25 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:57:21:57:25 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:60:25:60:29 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:60:25:60:29 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:63:21:63:25 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:63:21:63:25 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:65:32:65:36 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:65:32:65:36 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:67:27:67:31 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:67:27:67:31 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:68:8:68:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:68:8:68:12 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:71:20:71:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:71:20:71:24 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:72:16:72:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:72:16:72:20 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:73:8:73:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:73:8:73:12 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:74:7:74:11 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:74:7:74:11 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:75:16:75:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:75:16:75:20 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:77:10:77:14 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:77:10:77:14 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:82:46:82:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:82:46:82:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:83:47:83:51 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:83:47:83:51 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:85:46:85:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:85:46:85:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:87:51:87:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:87:51:87:55 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:89:46:89:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:89:46:89:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:92:46:92:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:92:46:92:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:94:51:94:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:94:51:94:55 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:96:46:96:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:96:46:96:50 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:111:14:111:18 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:111:14:111:18 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | -| mongoose.js:113:31:113:35 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:113:31:113:35 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:24:21:24:27 | [query] | mongoose.js:21:16:21:23 | req.body | mongoose.js:24:21:24:27 | [query] | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:27:17:27:21 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:27:17:27:21 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:30:22:30:26 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:30:22:30:26 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:33:21:33:25 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:33:21:33:25 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:36:28:36:32 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:36:28:36:32 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:39:16:39:20 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:39:16:39:20 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:42:19:42:23 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:42:19:42:23 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:45:28:45:32 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:45:28:45:32 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:48:28:48:32 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:48:28:48:32 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:51:28:51:32 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:51:28:51:32 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:54:22:54:26 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:54:22:54:26 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:57:18:57:22 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:57:18:57:22 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:60:22:60:26 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:60:22:60:26 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:63:21:63:25 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:63:21:63:25 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:65:32:65:36 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:65:32:65:36 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:67:27:67:31 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:67:27:67:31 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:68:8:68:12 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:68:8:68:12 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:71:17:71:21 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:71:17:71:21 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:72:10:72:14 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:72:10:72:14 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:73:8:73:12 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:73:8:73:12 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:74:7:74:11 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:74:7:74:11 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:75:16:75:20 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:75:16:75:20 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:77:10:77:14 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:77:10:77:14 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:82:46:82:50 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:82:46:82:50 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:83:47:83:51 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:83:47:83:51 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:85:46:85:50 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:85:46:85:50 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:87:51:87:55 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:87:51:87:55 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:89:46:89:50 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:89:46:89:50 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:92:46:92:50 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:92:46:92:50 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:94:51:94:55 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:94:51:94:55 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:96:46:96:50 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:96:46:96:50 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:111:14:111:18 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:111:14:111:18 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | +| mongoose.js:113:31:113:35 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:113:31:113:35 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | | mongoose.js:116:22:116:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:116:22:116:25 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:117:21:117:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:117:21:117:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:118:21:118:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:118:21:118:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | @@ -1014,7 +1014,7 @@ edges | mongoose.js:128:22:128:25 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:128:22:128:25 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:129:21:129:24 | cond | mongoose.js:115:32:115:45 | req.query.cond | mongoose.js:129:21:129:24 | cond | This query object depends on a $@. | mongoose.js:115:32:115:45 | req.query.cond | user-provided value | | mongoose.js:130:16:130:26 | { _id: id } | mongoose.js:115:11:115:22 | req.query.id | mongoose.js:130:16:130:26 | { _id: id } | This query object depends on a $@. | mongoose.js:115:11:115:22 | req.query.id | user-provided value | -| mongoose.js:136:33:136:37 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:136:33:136:37 | query | This query object depends on a $@. | mongoose.js:21:19:21:26 | req.body | user-provided value | +| mongoose.js:136:30:136:34 | query | mongoose.js:21:16:21:23 | req.body | mongoose.js:136:30:136:34 | query | This query object depends on a $@. | mongoose.js:21:16:21:23 | req.body | user-provided value | | mongooseJsonParse.js:23:19:23:23 | query | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:23:19:23:23 | query | This query object depends on a $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | user-provided value | | mongooseModelClient.js:11:16:11:24 | { id: v } | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:11:16:11:24 | { id: v } | This query object depends on a $@. | mongooseModelClient.js:10:22:10:29 | req.body | user-provided value | | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | This query object depends on a $@. | mongooseModelClient.js:12:22:12:29 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js b/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js index 59cf991c87b..3092a60b2cd 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js @@ -9,57 +9,57 @@ const app = Express(); app.use(BodyParser.json()); const Document = Mongoose.model('Document', { - title: { - type: String, - unique: true - }, - type: String + title: { + type: String, + unique: true + }, + type: String }); app.post('/documents/find', (req, res) => { - const query = {}; - query.title = req.body.title; + const query = {}; + query.title = req.body.title; - // NOT OK: query is tainted by user-provided object value - Document.aggregate([query]); + // NOT OK: query is tainted by user-provided object value + Document.aggregate([query]); - // NOT OK: query is tainted by user-provided object value - Document.count(query); + // NOT OK: query is tainted by user-provided object value + Document.count(query); - // NOT OK: query is tainted by user-provided object value - Document.deleteMany(query); + // NOT OK: query is tainted by user-provided object value + Document.deleteMany(query); - // NOT OK: query is tainted by user-provided object value - Document.deleteOne(query); + // NOT OK: query is tainted by user-provided object value + Document.deleteOne(query); - // NOT OK: query is tainted by user-provided object value - Document.distinct('type', query); + // NOT OK: query is tainted by user-provided object value + Document.distinct('type', query); - // NOT OK: query is tainted by user-provided object value - Document.find(query); + // NOT OK: query is tainted by user-provided object value + Document.find(query); - // NOT OK: query is tainted by user-provided object value - Document.findOne(query); + // NOT OK: query is tainted by user-provided object value + Document.findOne(query); - // NOT OK: query is tainted by user-provided object value - Document.findOneAndDelete(query); + // NOT OK: query is tainted by user-provided object value + Document.findOneAndDelete(query); - // NOT OK: query is tainted by user-provided object value - Document.findOneAndRemove(query); + // NOT OK: query is tainted by user-provided object value + Document.findOneAndRemove(query); - // NOT OK: query is tainted by user-provided object value - Document.findOneAndUpdate(query); + // NOT OK: query is tainted by user-provided object value + Document.findOneAndUpdate(query); - // NOT OK: query is tainted by user-provided object value - Document.replaceOne(query); + // NOT OK: query is tainted by user-provided object value + Document.replaceOne(query); - // NOT OK: query is tainted by user-provided object value - Document.update(query); + // NOT OK: query is tainted by user-provided object value + Document.update(query); - // NOT OK: query is tainted by user-provided object value - Document.updateMany(query); + // NOT OK: query is tainted by user-provided object value + Document.updateMany(query); - // NOT OK: query is tainted by user-provided object value + // NOT OK: query is tainted by user-provided object value Document.updateOne(query).then(X); Document.findByIdAndUpdate(X, query, function(){}); // NOT OK @@ -68,8 +68,8 @@ app.post('/documents/find', (req, res) => { .and(query, function(){}) // NOT OK ; - Document.where(query) // NOT OK - `.where()` on a Model. - .where(query) // NOT OK - `.where()` on a Query. + Document.where(query) // NOT OK - `.where()` on a Model. + .where(query) // NOT OK - `.where()` on a Query. .and(query) // NOT OK .or(query) // NOT OK .distinct(X, query) // NOT OK @@ -97,7 +97,7 @@ app.post('/documents/find', (req, res) => { Document.find(X).then(Y, (err) => err.count(query)); // OK Document.count(X, (err, res) => res.count(query)); // OK (res is a number) - + function innocent(X, Y, query) { // To detect if API-graphs were used incorrectly. return new Mongoose.Query("constant", "constant", "constant"); } @@ -130,9 +130,9 @@ app.post('/documents/find', (req, res) => { Document.find({ _id: id }); // NOT OK Document.find({ _id: { $eq: id } }); // OK - if (Mongoose.Types.ObjectId.isValid(query)) { - Document.findByIdAndUpdate(query, X, function(){}); // OK - is sanitized - } else { - Document.findByIdAndUpdate(query, X, function(){}); // NOT OK - } + if (Mongoose.Types.ObjectId.isValid(query)) { + Document.findByIdAndUpdate(query, X, function(){}); // OK - is sanitized + } else { + Document.findByIdAndUpdate(query, X, function(){}); // NOT OK + } }); From 652636404594c682b2b4859fbca99cb64f10cac9 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Mon, 12 Jun 2023 21:18:31 +0200 Subject: [PATCH 516/739] Python: Add modeling of `flask.render_template_string` --- ...2023-06-12-flask-render-template-string.md | 4 ++ .../ql/lib/semmle/python/frameworks/Flask.qll | 54 +++++++++++++++++++ .../frameworks/flask/taint_test.py | 29 +++++++++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 python/ql/lib/change-notes/2023-06-12-flask-render-template-string.md diff --git a/python/ql/lib/change-notes/2023-06-12-flask-render-template-string.md b/python/ql/lib/change-notes/2023-06-12-flask-render-template-string.md new file mode 100644 index 00000000000..d9f1a2e5d5c --- /dev/null +++ b/python/ql/lib/change-notes/2023-06-12-flask-render-template-string.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added modeling of taint flow through the template argument of `flask.render_template_string` and `flask.stream_template_string`. diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index 940af5000ab..fd611e146f4 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -13,6 +13,7 @@ private import semmle.python.frameworks.Stdlib private import semmle.python.ApiGraphs private import semmle.python.frameworks.internal.InstanceTaintStepsHelper private import semmle.python.security.dataflow.PathInjectionCustomizations +private import semmle.python.dataflow.new.FlowSummary /** * Provides models for the `flask` PyPI package. @@ -587,4 +588,57 @@ module Flask { private class FlaskLogger extends Stdlib::Logger::InstanceSource { FlaskLogger() { this = FlaskApp::instance().getMember("logger").asSource() } } + + /** + * A flow summary for `flask.render_template_string`. + * + * see https://flask.palletsprojects.com/en/2.3.x/api/#flask.render_template_string + */ + private class RenderTemplateStringSummary extends SummarizedCallable { + RenderTemplateStringSummary() { this = "flask.render_template_string" } + + override DataFlow::CallCfgNode getACall() { + result = API::moduleImport("flask").getMember("render_template_string").getACall() + } + + override DataFlow::ArgumentNode getACallback() { + result = + API::moduleImport("flask") + .getMember("render_template_string") + .getAValueReachableFromSource() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** + * A flow summary for `flask.stream_template_string`. + * + * see https://flask.palletsprojects.com/en/2.3.x/api/#flask.stream_template_string + */ + private class StreamTemplateStringSummary extends SummarizedCallable { + StreamTemplateStringSummary() { this = "flask.stream_template_string" } + + override DataFlow::CallCfgNode getACall() { + result = API::moduleImport("flask").getMember("stream_template_string").getACall() + } + + override DataFlow::ArgumentNode getACallback() { + result = + API::moduleImport("flask") + .getMember("stream_template_string") + .getAValueReachableFromSource() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and + // Technically it's `Iterator[str]`, but list will do :) + output = "ReturnValue.ListElement" and + preservesValue = false + } + } } diff --git a/python/ql/test/library-tests/frameworks/flask/taint_test.py b/python/ql/test/library-tests/frameworks/flask/taint_test.py index dcca8ff6681..227aecbf745 100644 --- a/python/ql/test/library-tests/frameworks/flask/taint_test.py +++ b/python/ql/test/library-tests/frameworks/flask/taint_test.py @@ -1,4 +1,4 @@ -from flask import Flask, request +from flask import Flask, request, render_template_string, stream_template_string app = Flask(__name__) @app.route("/test_taint/<name>/<int:number>") # $routeSetup="/test_taint/<name>/<int:number>" @@ -215,7 +215,34 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route gd(), # $ tainted ) + # ---------------------------------- + # non-request related taint-steps + # ---------------------------------- + # render_template_string + source = TAINTED_STRING + ensure_tainted(source) # $ tainted + res = render_template_string(source) + ensure_tainted(res) # $ tainted + + # since template variables are auto-escaped, we don't treat result as tainted + # see https://flask.palletsprojects.com/en/2.3.x/api/#flask.render_template_string + res = render_template_string("Hello {{ foo }}", foo=TAINTED_STRING) + ensure_not_tainted(res) + + + # stream_template_string + source = TAINTED_STRING + ensure_tainted(source) # $ tainted + res = stream_template_string(source) + for x in res: + ensure_tainted(x) # $ tainted + + # since template variables are auto-escaped, we don't treat result as tainted + # see https://flask.palletsprojects.com/en/2.3.x/api/#flask.stream_template_string + res = stream_template_string("Hello {{ foo }}", foo=TAINTED_STRING) + for x in res: + ensure_not_tainted(x) @app.route("/debug/<foo>/<bar>", methods=['GET']) # $routeSetup="/debug/<foo>/<bar>" From 2a5173c33194e0ae30f7ca4b58f13a9b72452733 Mon Sep 17 00:00:00 2001 From: yoff <lerchedahl@gmail.com> Date: Tue, 13 Jun 2023 10:04:46 +0200 Subject: [PATCH 517/739] Update python/ql/lib/semmle/python/frameworks/Stdlib.qll Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com> --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index b4412909cf1..4d8f1280177 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4134,7 +4134,7 @@ private module StdlibPrivate { } /** - * A flow summary for `dict.setdefault` at specifi key. + * A flow summary for `dict.setdefault` at specific content. * See https://docs.python.org/3.10/library/stdtypes.html#dict.setdefault * This summary handles read and store steps. See `DictSetdefaultSummary` * for the dataflow steps. From d035491c6fd8fe36e3ff922aa77fc0f2045ab2da Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 13 Jun 2023 10:13:42 +0200 Subject: [PATCH 518/739] Go: Remove commented out code from test --- .../semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql | 6 ------ 1 file changed, 6 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql index d0a3946616a..17194265598 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql @@ -84,9 +84,3 @@ module TaintFlowTest implements TestSig { } import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>> -// from TaintConfiguration cfg, DataFlow::PartialPathNode source, DataFlow::PartialPathNode sink -// where -// cfg.hasPartialFlow(source, sink, _) -// and -// source.getNode().hasLocationInfo(_, 22, _, _, _) -// select sink, source, sink, "Partial flow from unsanitized user data" From 577bbd531d0a12cbf8885dd40fc818ded2885d64 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 13 Jun 2023 09:46:19 +0200 Subject: [PATCH 519/739] C#: Base tests on stubs, move extractor options to options file and updated expected test output. --- .../experimental/CWE-918/RequestForgery.cs | 2 - .../CWE-918/RequestForgery.expected | 8 ++-- csharp/ql/test/experimental/CWE-918/options | 4 +- .../CWE-327/InsecureSQLConnection/options | 3 +- .../CWE-327/InsecureSQLConnection/stubs.cs | 48 ------------------- 5 files changed, 9 insertions(+), 56 deletions(-) delete mode 100644 csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/stubs.cs diff --git a/csharp/ql/test/experimental/CWE-918/RequestForgery.cs b/csharp/ql/test/experimental/CWE-918/RequestForgery.cs index 1c81fae4b91..02e851d8df1 100644 --- a/csharp/ql/test/experimental/CWE-918/RequestForgery.cs +++ b/csharp/ql/test/experimental/CWE-918/RequestForgery.cs @@ -1,5 +1,3 @@ -// semmle-extractor-options: ${testdir}/../../resources/stubs/System.Web.cs /r:System.Threading.Tasks.dll /r:System.Collections.Specialized.dll /r:System.Runtime.dll /r:System.Private.Uri.dll - using System; using System.Threading.Tasks; using System.Web.Mvc; diff --git a/csharp/ql/test/experimental/CWE-918/RequestForgery.expected b/csharp/ql/test/experimental/CWE-918/RequestForgery.expected index fb85f080a4c..4c499ad4be6 100644 --- a/csharp/ql/test/experimental/CWE-918/RequestForgery.expected +++ b/csharp/ql/test/experimental/CWE-918/RequestForgery.expected @@ -1,8 +1,8 @@ edges -| RequestForgery.cs:14:52:14:54 | url : String | RequestForgery.cs:16:66:16:68 | access to parameter url | +| RequestForgery.cs:12:52:12:54 | url : String | RequestForgery.cs:14:66:14:68 | access to parameter url | nodes -| RequestForgery.cs:14:52:14:54 | url : String | semmle.label | url : String | -| RequestForgery.cs:16:66:16:68 | access to parameter url | semmle.label | access to parameter url | +| RequestForgery.cs:12:52:12:54 | url : String | semmle.label | url : String | +| RequestForgery.cs:14:66:14:68 | access to parameter url | semmle.label | access to parameter url | subpaths #select -| RequestForgery.cs:16:66:16:68 | access to parameter url | RequestForgery.cs:14:52:14:54 | url : String | RequestForgery.cs:16:66:16:68 | access to parameter url | The URL of this request depends on a $@. | RequestForgery.cs:14:52:14:54 | url | user-provided value | +| RequestForgery.cs:14:66:14:68 | access to parameter url | RequestForgery.cs:12:52:12:54 | url : String | RequestForgery.cs:14:66:14:68 | access to parameter url | The URL of this request depends on a $@. | RequestForgery.cs:12:52:12:54 | url | user-provided value | diff --git a/csharp/ql/test/experimental/CWE-918/options b/csharp/ql/test/experimental/CWE-918/options index 33d3af2e8b1..09b08bf4d27 100644 --- a/csharp/ql/test/experimental/CWE-918/options +++ b/csharp/ql/test/experimental/CWE-918/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Net.Http.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../resources/stubs/System.Web.cs \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/options b/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/options index 445f576fc95..94ad1a6f02b 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/options @@ -1 +1,2 @@ -semmle-extractor-options: /r:System.Data.Common.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj diff --git a/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/stubs.cs b/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/stubs.cs deleted file mode 100644 index 833a5902326..00000000000 --- a/csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/stubs.cs +++ /dev/null @@ -1,48 +0,0 @@ -// This file contains auto-generated code. - -namespace System -{ - namespace Data - { - // Generated from `System.Data.IDbConnection` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089` - public interface IDbConnection : System.IDisposable - { - string ConnectionString { get; set; } - } - - namespace Common - { - // Generated from `System.Data.Common.DbConnection` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089` - abstract public class DbConnection : System.IDisposable, System.Data.IDbConnection - { - public abstract string ConnectionString { get; set; } - public void Dispose() => throw null; - } - - } - namespace SqlClient - { - // Generated from `System.Data.SqlClient.SqlConnectionStringBuilder` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089` - public class SqlConnectionStringBuilder : System.Data.Common.DbConnectionStringBuilder - { - public SqlConnectionStringBuilder() => throw null; - public SqlConnectionStringBuilder(string connectionString) => throw null; - public bool Encrypt { get => throw null; set => throw null; } - public override System.Collections.ICollection Keys { get => throw null; } - public override System.Collections.ICollection Values { get => throw null; } - public override bool IsFixedSize { get => throw null; } - public override void Clear() => throw null; - } - - // Generated from `System.Data.SqlClient.SqlConnection` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089` - public class SqlConnection : System.Data.Common.DbConnection, System.ICloneable - { - object System.ICloneable.Clone() => throw null; - public SqlConnection() => throw null; - public SqlConnection(string connectionString) => throw null; - public override string ConnectionString { get => throw null; set => throw null; } - } - - } - } -} From b709ed47e16078211432e2a253fe83edaf4415dc Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 13 Jun 2023 11:20:15 +0200 Subject: [PATCH 520/739] python: add test --- python/ql/test/experimental/dataflow/coverage/test_builtins.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/ql/test/experimental/dataflow/coverage/test_builtins.py b/python/ql/test/experimental/dataflow/coverage/test_builtins.py index 301871cfc61..ee3f41dd9b2 100644 --- a/python/ql/test/experimental/dataflow/coverage/test_builtins.py +++ b/python/ql/test/experimental/dataflow/coverage/test_builtins.py @@ -231,6 +231,9 @@ def test_dict_get(): SINK(v) #$ flow="SOURCE, l:-2 -> v" v1 = d.get("non-existing", SOURCE) SINK(v1) #$ flow="SOURCE, l:-1 -> v1" + k = "k" + v2 = d.get(k) + SINK(v2) #$ flow="SOURCE, l:-7 -> v2" @expects(2) def test_dict_popitem(): From 8cae151883999562eb07308557f2d848c53e8db5 Mon Sep 17 00:00:00 2001 From: yoff <lerchedahl@gmail.com> Date: Tue, 13 Jun 2023 11:22:54 +0200 Subject: [PATCH 521/739] Update python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll Co-authored-by: Asger F <asgerf@github.com> --- .../dataflow/typetracking-summaries/TestSummaries.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll b/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll index 1a6a504e1ee..c139308c00e 100644 --- a/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll @@ -4,7 +4,7 @@ private import semmle.python.ApiGraphs /** * This module ensures that the `callStep` predicate in - * our type tracker implelemtation does not refer to the + * our type tracker implementation does not refer to the * `getACall` predicate on `SummarizedCallable`. */ module RecursionGuard { From 2d616d494e8ba2c184eaa336fe4d4bc33bba6624 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 13 Jun 2023 11:23:14 +0200 Subject: [PATCH 522/739] C#/Ruby: Add fields as per review comments. --- .../dataflow/internal/DataFlowPrivate.qll | 35 ++++++++++--------- .../dataflow/internal/FlowSummaryImpl.qll | 2 +- .../go/dataflow/internal/FlowSummaryImpl.qll | 2 +- .../dataflow/internal/FlowSummaryImpl.qll | 2 +- .../dataflow/new/internal/FlowSummaryImpl.qll | 2 +- .../dataflow/internal/DataFlowPrivate.qll | 26 ++++++++------ .../dataflow/internal/FlowSummaryImpl.qll | 2 +- .../dataflow/internal/FlowSummaryImpl.qll | 2 +- 8 files changed, 40 insertions(+), 33 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index bbc0ab8a1a2..a3aed9f9097 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -1125,16 +1125,14 @@ private module ParameterNodes { /** A parameter for a library callable with a flow summary. */ class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode { - SummaryParameterNode() { - FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) - } + private ParameterPosition pos_; - private ParameterPosition getPosition() { - FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + SummaryParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), pos_) } override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { - this.getSummarizedCallable() = c.asSummarizedCallable() and pos = this.getPosition() + this.getSummarizedCallable() = c.asSummarizedCallable() and pos = pos_ } } } @@ -1305,12 +1303,15 @@ private module ArgumentNodes { } private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNodeImpl { + private DataFlowCall call_; + private ArgumentPosition pos_; + SummaryArgumentNode() { - FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _) + FlowSummaryImpl::Private::summaryArgumentNode(call_, this.getSummaryNode(), pos_) } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos) + call = call_ and pos = pos_ } } } @@ -1593,11 +1594,14 @@ private module OutNodes { } private class SummaryOutNode extends FlowSummaryNode, OutNode { - SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) } + private DataFlowCall call; + private ReturnKind kind_; - override DataFlowCall getCall(ReturnKind kind) { - FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind) + SummaryOutNode() { + FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), kind_) } + + override DataFlowCall getCall(ReturnKind kind) { result = call and kind = kind_ } } } @@ -2120,15 +2124,14 @@ private module PostUpdateNodes { } private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode { + private FlowSummaryImpl::Private::SummaryNode preUpdateNode; + SummaryPostUpdateNode() { - FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), _) and + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), preUpdateNode) and not summaryPostUpdateNodeIsOutOrRef(this, _) } - override Node getPreUpdateNode() { - FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), - result.(FlowSummaryNode).getSummaryNode()) - } + override Node getPreUpdateNode() { result.(FlowSummaryNode).getSummaryNode() = preUpdateNode } } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index f98c2669a8b..03c215e1f67 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -570,7 +570,7 @@ module Private { summaryParameterNodeRange(c, pos) } - class SummaryNode extends TSummaryNode { + abstract class SummaryNode extends TSummaryNode { abstract string toString(); abstract SummarizedCallable getSummarizedCallable(); diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index f98c2669a8b..03c215e1f67 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -570,7 +570,7 @@ module Private { summaryParameterNodeRange(c, pos) } - class SummaryNode extends TSummaryNode { + abstract class SummaryNode extends TSummaryNode { abstract string toString(); abstract SummarizedCallable getSummarizedCallable(); diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index f98c2669a8b..03c215e1f67 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -570,7 +570,7 @@ module Private { summaryParameterNodeRange(c, pos) } - class SummaryNode extends TSummaryNode { + abstract class SummaryNode extends TSummaryNode { abstract string toString(); abstract SummarizedCallable getSummarizedCallable(); diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index f98c2669a8b..03c215e1f67 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -570,7 +570,7 @@ module Private { summaryParameterNodeRange(c, pos) } - class SummaryNode extends TSummaryNode { + abstract class SummaryNode extends TSummaryNode { abstract string toString(); abstract SummarizedCallable getSummarizedCallable(); diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index ecb9393f127..0fb0bac0462 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -751,18 +751,16 @@ private module ParameterNodes { /** A parameter for a library callable with a flow summary. */ class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode { - SummaryParameterNode() { - FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) - } + private ParameterPosition pos_; - private ParameterPosition getPosition() { - FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + SummaryParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), pos_) } override Parameter getParameter() { none() } override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { - this.getSummarizedCallable() = c.asLibraryCallable() and pos = this.getPosition() + this.getSummarizedCallable() = c.asLibraryCallable() and pos = pos_ } } } @@ -847,8 +845,11 @@ private module ArgumentNodes { } private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode { + private DataFlowCall call_; + private ArgumentPosition pos_; + SummaryArgumentNode() { - FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _) + FlowSummaryImpl::Private::summaryArgumentNode(call_, this.getSummaryNode(), pos_) } override predicate sourceArgumentOf(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos) { @@ -856,7 +857,7 @@ private module ArgumentNodes { } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos) + call = call_ and pos = pos_ } } @@ -1063,11 +1064,14 @@ private module OutNodes { } private class SummaryOutNode extends FlowSummaryNode, OutNode { - SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) } + private DataFlowCall call; + private ReturnKind kind_; - override DataFlowCall getCall(ReturnKind kind) { - FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind) + SummaryOutNode() { + FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), kind_) } + + override DataFlowCall getCall(ReturnKind kind) { result = call and kind = kind_ } } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index f98c2669a8b..03c215e1f67 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -570,7 +570,7 @@ module Private { summaryParameterNodeRange(c, pos) } - class SummaryNode extends TSummaryNode { + abstract class SummaryNode extends TSummaryNode { abstract string toString(); abstract SummarizedCallable getSummarizedCallable(); diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index f98c2669a8b..03c215e1f67 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -570,7 +570,7 @@ module Private { summaryParameterNodeRange(c, pos) } - class SummaryNode extends TSummaryNode { + abstract class SummaryNode extends TSummaryNode { abstract string toString(); abstract SummarizedCallable getSummarizedCallable(); From 203f8226cb29d183d7b5bb6a2daa65819058ff22 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 13 Jun 2023 11:32:06 +0200 Subject: [PATCH 523/739] ruby/python: make `SummaryTypeTracker` private --- .../python/dataflow/new/internal/TypeTrackerSpecific.qll | 4 ++-- ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index 11e49f5f510..6acc4036c16 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -179,7 +179,7 @@ private predicate argumentPositionMatch( ) } -module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { +private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { // Dataflow nodes class Node = DataFlowPublic::Node; @@ -258,4 +258,4 @@ module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { Node callTo(SummarizedCallable callable) { result = callable.getACallSimple() } } -module TypeTrackerSummaryFlow = SummaryTypeTracker::SummaryFlow<SummaryTypeTrackerInput>; +private module TypeTrackerSummaryFlow = SummaryTypeTracker::SummaryFlow<SummaryTypeTrackerInput>; diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll index a096f33bd5c..b344fcf127f 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll @@ -350,7 +350,7 @@ predicate isNonLocal(SummaryComponent component) { private import SummaryTypeTracker as SummaryTypeTracker private import codeql.ruby.dataflow.FlowSummary as FlowSummary -module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { +private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { // Dataflow nodes class Node = DataFlow::Node; @@ -448,4 +448,4 @@ module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { Node callTo(SummarizedCallable callable) { result.asExpr().getExpr() = callable.getACallSimple() } } -module TypeTrackerSummaryFlow = SummaryTypeTracker::SummaryFlow<SummaryTypeTrackerInput>; +private module TypeTrackerSummaryFlow = SummaryTypeTracker::SummaryFlow<SummaryTypeTrackerInput>; From b5961c7f6be954beb91b8ecd6cedb4e7dbfe0a15 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 13 Jun 2023 11:37:19 +0200 Subject: [PATCH 524/739] ruby: move to internal folder --- config/identical-files.json | 4 ++-- ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll | 2 +- .../ruby/typetracking/{ => internal}/SummaryTypeTracker.qll | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename ruby/ql/lib/codeql/ruby/typetracking/{ => internal}/SummaryTypeTracker.qll (100%) diff --git a/config/identical-files.json b/config/identical-files.json index 7a66b2d52f4..39dadd75ab3 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -525,7 +525,7 @@ ], "SummaryTypeTracker": [ "python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll", - "ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll" + "ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll" ], "AccessPathSyntax": [ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/AccessPathSyntax.qll", @@ -603,4 +603,4 @@ "python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll", "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" ] -} +} \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll index b344fcf127f..484dbdd4197 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll @@ -347,7 +347,7 @@ predicate isNonLocal(SummaryComponent component) { component = SC::withContent(_) } -private import SummaryTypeTracker as SummaryTypeTracker +private import internal.SummaryTypeTracker as SummaryTypeTracker private import codeql.ruby.dataflow.FlowSummary as FlowSummary private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { diff --git a/ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll similarity index 100% rename from ruby/ql/lib/codeql/ruby/typetracking/SummaryTypeTracker.qll rename to ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll From e11f6b5107f80a167e5fbe069114ca0fd211a264 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 13 Jun 2023 11:42:53 +0200 Subject: [PATCH 525/739] ruby/python: adjust shared file - move `isNonLocal` to the top - missing backtics --- .../dataflow/new/internal/SummaryTypeTracker.qll | 16 ++++++++-------- .../typetracking/internal/SummaryTypeTracker.qll | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll index 4e0636826b8..d1a65e1c3e5 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll @@ -133,6 +133,13 @@ signature module Output<Input I> { * Implementation of the summary type tracker, that is type tracking through flow summaries. */ module SummaryFlow<Input I> implements Output<I> { + pragma[nomagic] + private predicate isNonLocal(I::SummaryComponent component) { + component = I::content(_) + or + component = I::withContent(_) + } + pragma[nomagic] private predicate hasLoadSummary( I::SummarizedCallable callable, I::TypeTrackerContent contents, I::SummaryComponentStack input, @@ -210,15 +217,8 @@ module SummaryFlow<Input I> implements Output<I> { ) } - pragma[nomagic] - private predicate isNonLocal(I::SummaryComponent component) { - component = I::content(_) - or - component = I::withContent(_) - } - /** - * Gets a data flow I::Node corresponding an argument or return value of `call`, + * Gets a data flow `I::Node` corresponding an argument or return value of `call`, * as specified by `component`. */ bindingset[call, component] diff --git a/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll index 4e0636826b8..d1a65e1c3e5 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll @@ -133,6 +133,13 @@ signature module Output<Input I> { * Implementation of the summary type tracker, that is type tracking through flow summaries. */ module SummaryFlow<Input I> implements Output<I> { + pragma[nomagic] + private predicate isNonLocal(I::SummaryComponent component) { + component = I::content(_) + or + component = I::withContent(_) + } + pragma[nomagic] private predicate hasLoadSummary( I::SummarizedCallable callable, I::TypeTrackerContent contents, I::SummaryComponentStack input, @@ -210,15 +217,8 @@ module SummaryFlow<Input I> implements Output<I> { ) } - pragma[nomagic] - private predicate isNonLocal(I::SummaryComponent component) { - component = I::content(_) - or - component = I::withContent(_) - } - /** - * Gets a data flow I::Node corresponding an argument or return value of `call`, + * Gets a data flow `I::Node` corresponding an argument or return value of `call`, * as specified by `component`. */ bindingset[call, component] From 33ad15e989f2db19b9ba3c4298b5a536581c0bc7 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 13 Jun 2023 11:48:06 +0200 Subject: [PATCH 526/739] ruby: use aliases --- .../ruby/typetracking/TypeTrackerSpecific.qll | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll index 484dbdd4197..d14c182d127 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll @@ -394,28 +394,18 @@ private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { class SummaryComponentStack = FlowSummary::SummaryComponentStack; - SummaryComponentStack singleton(SummaryComponent component) { - result = FlowSummary::SummaryComponentStack::singleton(component) - } + predicate singleton = FlowSummary::SummaryComponentStack::singleton/1; - SummaryComponentStack push(SummaryComponent component, SummaryComponentStack stack) { - result = FlowSummary::SummaryComponentStack::push(component, stack) - } + predicate push = FlowSummary::SummaryComponentStack::push/2; // Relating content to summaries - SummaryComponent content(TypeTrackerContent contents) { - result = FlowSummary::SummaryComponent::content(contents) - } + predicate content = FlowSummary::SummaryComponent::content/1; - SummaryComponent withoutContent(TypeTrackerContent contents) { - result = FlowSummary::SummaryComponent::withoutContent(contents) - } + predicate withoutContent = FlowSummary::SummaryComponent::withoutContent/1; - SummaryComponent withContent(TypeTrackerContent contents) { - result = FlowSummary::SummaryComponent::withContent(contents) - } + predicate withContent = FlowSummary::SummaryComponent::withContent/1; - SummaryComponent return() { result = FlowSummary::SummaryComponent::return() } + predicate return = FlowSummary::SummaryComponent::return/0; // Callables class SummarizedCallable = FlowSummary::SummarizedCallable; From 2b7fc94aef7f845e155b6bd8ce2546dfc29facc0 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Tue, 13 Jun 2023 12:11:28 +0200 Subject: [PATCH 527/739] Python: Fix validTest.py expectation --- .../ql/test/experimental/dataflow/coverage/test_builtins.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/test/experimental/dataflow/coverage/test_builtins.py b/python/ql/test/experimental/dataflow/coverage/test_builtins.py index ee3f41dd9b2..629e2600280 100644 --- a/python/ql/test/experimental/dataflow/coverage/test_builtins.py +++ b/python/ql/test/experimental/dataflow/coverage/test_builtins.py @@ -57,7 +57,7 @@ def test_list_from_set(): s = {SOURCE} l = list(s) SINK(l[0]) #$ flow="SOURCE, l:-2 -> l[0]" - + @expects(2) def test_list_from_dict(): d = {SOURCE: 'v', NONSOURCE: 'v2'} @@ -224,7 +224,7 @@ def test_dict_pop(): v2 = d.pop("non-existing", SOURCE) SINK(v2) #$ flow="SOURCE, l:-1 -> v2" -@expects(2) +@expects(3) def test_dict_get(): d = {'k': SOURCE} v = d.get("k") @@ -357,4 +357,4 @@ def test_next_dict(): d = {SOURCE: "val"} i = iter(d) n = next(i) - SINK(n) #$ MISSING: flow="SOURCE, l:-3 -> n" \ No newline at end of file + SINK(n) #$ MISSING: flow="SOURCE, l:-3 -> n" From af1ca7fec74d9011a78fce06460af3905da0ce42 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@users.noreply.github.com> Date: Tue, 13 Jun 2023 12:37:31 +0100 Subject: [PATCH 528/739] Update ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll Co-authored-by: Asger F <asgerf@github.com> --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 5ea8ad38f29..bfdd988ac19 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -14,7 +14,7 @@ private class CallMethodNode extends DataFlow::MethodNode { private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, CallMethodNode call) { t.start() and - result = call.getAReturnNode() + result = call.getAReturnNode().getALocalSource() or exists(TypeBackTracker t2 | result = trackRackResponse(t2, call).backtrack(t2, t)) } From 977ceb89fd8538b75cbf58584d4c24d009ae2f26 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 13 Jun 2023 12:42:46 +0100 Subject: [PATCH 529/739] Ruby: rack - remove PotentialResponseNode#getAStatusCode --- .../frameworks/rack/internal/Response.qll | 20 ++++--------------- .../frameworks/rack/Rack.expected | 8 -------- .../library-tests/frameworks/rack/Rack.ql | 6 ------ 3 files changed, 4 insertions(+), 30 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index d5ca488fcda..9d998c780ae 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -12,25 +12,11 @@ private import App as A /** Contains implementation details for modeling `Rack::Response`. */ module Private { - private DataFlow::LocalSourceNode trackInt(TypeTracker t, int i) { - t.start() and - result.getConstantValue().isInt(i) - or - exists(TypeTracker t2 | result = trackInt(t2, i).track(t2, t)) - } - - private DataFlow::Node trackInt(int i) { trackInt(TypeTracker::end(), i).flowsTo(result) } - /** A `DataFlow::Node` that may be a rack response. This is detected heuristically, if something "looks like" a rack response syntactically then we consider it to be a potential response node. */ class PotentialResponseNode extends DataFlow::ArrayLiteralNode { // [status, headers, body] PotentialResponseNode() { this.getNumberOfArguments() = 3 } - /** - * Gets an HTTP status code that may be returned in this response. - */ - int getAStatusCode() { this.getElement(0) = trackInt(result) } - /** Gets the headers returned with this response. */ DataFlow::Node getHeaders() { result = this.getElement(1) } @@ -87,8 +73,10 @@ module Public { /** A `DataFlow::Node` returned from a rack request that has a redirect HTTP status code. */ class RedirectResponse extends ResponseNode, Http::Server::HttpRedirectResponse::Range { - RedirectResponse() { this.getAStatusCode() = [300, 301, 302, 303, 307, 308] } + private DataFlow::Node redirectLocation; - override DataFlow::Node getRedirectLocation() { result = getHeaderValue(this, "location") } + RedirectResponse() { redirectLocation = getHeaderValue(this, "location") } + + override DataFlow::Node getRedirectLocation() { result = redirectLocation } } } diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index 157168f0bd8..a2671c95cb7 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -4,14 +4,6 @@ rackApps | rack.rb:24:1:37:3 | Logger | rack.rb:30:12:30:14 | env | | rack.rb:39:1:45:3 | Redirector | rack.rb:40:12:40:14 | env | | rack.rb:59:1:75:3 | Baz | rack.rb:60:12:60:14 | env | -rackResponseStatusCodes -| rack.rb:8:5:8:38 | call to [] | 200 | -| rack.rb:8:5:8:38 | call to [] | 500 | -| rack.rb:20:5:20:27 | call to [] | <unknown> | -| rack.rb:35:5:35:26 | call to [] | <unknown> | -| rack.rb:43:5:43:45 | call to [] | 302 | -| rack.rb:66:7:66:22 | call to [] | 200 | -| rack.rb:73:5:73:21 | call to [] | 400 | rackResponseContentTypes | rack.rb:8:5:8:38 | call to [] | rack.rb:7:34:7:45 | "text/plain" | | rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:54 | call to mime_type | diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 8e0bcee4244..1b019cdd3a0 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -6,12 +6,6 @@ query predicate rackApps(Rack::App::AppCandidate c, DataFlow::ParameterNode env) env = c.getEnv() } -query predicate rackResponseStatusCodes(Rack::Response::ResponseNode resp, string status) { - if exists(resp.getAStatusCode()) - then status = resp.getAStatusCode().toString() - else status = "<unknown>" -} - query predicate rackResponseContentTypes( Rack::Response::ResponseNode resp, DataFlow::Node contentType ) { From 75ccbe58ee27d656b8ae99c39d6a0f48592b489e Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 13 Jun 2023 12:44:29 +0100 Subject: [PATCH 530/739] Ruby: rack - use Mimetype rather than MimeType in predicate names for consistency with concepts --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll | 4 ++-- ruby/ql/test/library-tests/frameworks/rack/Rack.ql | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll index f9bd42c15b0..c7682c25638 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll @@ -5,7 +5,7 @@ private import codeql.ruby.ApiGraphs private import codeql.ruby.DataFlow -private predicate mimeTypeMatches(string ext, string mimeType) { +private predicate mimetypeMatches(string ext, string mimeType) { ext = ".123" and mimeType = "application/vnd.lotus-1-2-3" or ext = ".3dml" and mimeType = "text/vnd.in3d.3dml" @@ -1306,6 +1306,6 @@ module Mime { } /** Gets the canonical MIME type string returned by this call. */ - string getMimeType() { mimeTypeMatches(this.getExtension(), result) } + string getMimetype() { mimetypeMatches(this.getExtension(), result) } } } diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 1b019cdd3a0..e1f1c506994 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -13,7 +13,7 @@ query predicate rackResponseContentTypes( } query predicate mimetypeCalls(Rack::Mime::MimetypeCall c, string mimetype) { - mimetype = c.getMimeType() + mimetype = c.getMimetype() } query predicate redirectResponses(Rack::Response::RedirectResponse resp, DataFlow::Node location) { From 9690ff617749ded8c0dab4dde89c89f627154b5a Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 13 Jun 2023 13:34:05 +0200 Subject: [PATCH 531/739] C#: Address review comments. --- .../csharp/frameworks/EntityFramework.qll | 96 +++++++++---------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 6030537aa65..83bdcdcc04e 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -370,17 +370,46 @@ module EntityFramework { ) } - pragma[nomagic] - string getSyntheticNames( - SummaryComponentStack input, SummaryComponentStack output, DbContextClassSetProperty dbSet - ) { - exists(Property mapped | - this = dbSet.getDbContextClass() and - input(this, input, mapped) and - output(this, output, mapped, dbSet) and - result = dbSet.getSyntheticName() + "#" + SummaryComponentStack::getComponentStack(output) + /** + * Holds if `input` is a valid summary component stack for property `mapped` for this. + */ + pragma[noinline] + predicate input(SummaryComponentStack input, Property mapped) { + exists(PropertyContent head, SummaryComponentStack tail | + this.requiresComponentStackIn(head, _, tail, _) and + head.getProperty() = mapped and + mapped = this.getAColumnProperty(_) and + input = SummaryComponentStack::push(SummaryComponent::content(head), tail) ) } + + /** + * Holds if `output` is a valid summary component stack for the getter of `dbSet` + * for property `mapped` for this. + */ + pragma[noinline] + predicate output(SummaryComponentStack output, Property mapped, DbContextClassSetProperty dbSet) { + exists(PropertyContent head, SummaryComponentStack tail | + this.requiresComponentStackOut(head, _, tail, _, dbSet) and + head.getProperty() = mapped and + mapped = this.getAColumnProperty(_) and + output = SummaryComponentStack::push(SummaryComponent::content(head), tail) + ) + } + + /** + * Gets the synthetic name for the getter of `dbSet` for property `mapped` for this, + * where `output` is a valid summary component stack for the getter of `dbSet` + * for the property `mapped`. + */ + pragma[nomagic] + string getSyntheticName( + SummaryComponentStack output, Property mapped, DbContextClassSetProperty dbSet + ) { + this = dbSet.getDbContextClass() and + this.output(output, mapped, dbSet) and + result = dbSet.getFullName() + "#" + SummaryComponentStack::getComponentStack(output) + } } private class DbContextClassSetProperty extends Property { @@ -389,9 +418,9 @@ module EntityFramework { DbContextClassSetProperty() { this = c.getADbSetProperty(_) } /** - * Gets the string representation for a synthetic identifier for this. + * Gets the fully qualified name for this. */ - string getSyntheticName() { + string getFullName() { exists(string qualifier, string type, string name | this.hasQualifiedName(qualifier, type, name) | @@ -400,41 +429,11 @@ module EntityFramework { } /** - * Gets the context class where this is a Db set property. + * Gets the context class where this is a DbSet property. */ DbContextClass getDbContextClass() { result = c } } - /** - * Holds if `input` is a valid summary component stack for property `mapped` - * for the context class `c`. - */ - pragma[noinline] - predicate input(DbContextClass c, SummaryComponentStack input, Property mapped) { - exists(PropertyContent head, SummaryComponentStack tail | - c.requiresComponentStackIn(head, _, tail, _) and - head.getProperty() = mapped and - mapped = c.getAColumnProperty(_) and - input = SummaryComponentStack::push(SummaryComponent::content(head), tail) - ) - } - - /** - * Holds if `output` is a valid summary component stack for the getter of `dbSet` - * for property `mapped` for the context class `c`. - */ - pragma[noinline] - predicate output( - DbContextClass c, SummaryComponentStack output, Property mapped, DbContextClassSetProperty dbSet - ) { - exists(PropertyContent head, SummaryComponentStack tail | - c.requiresComponentStackOut(head, _, tail, _, dbSet) and - head.getProperty() = mapped and - mapped = c.getAColumnProperty(_) and - output = SummaryComponentStack::push(SummaryComponent::content(head), tail) - ) - } - private class DbContextClassSetPropertySynthetic extends EFSummarizedCallable { private DbContextClassSetProperty p; @@ -445,7 +444,7 @@ module EntityFramework { ) { exists(string name, DbContextClass c | preservesValue = true and - name = c.getSyntheticNames(_, output, p) and + name = c.getSyntheticName(output, _, p) and input = SummaryComponentStack::syntheticGlobal(name) ) } @@ -459,21 +458,20 @@ module EntityFramework { override predicate propagatesFlow( SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - exists(string name | + exists(string name, Property mapped | preservesValue = true and - name = c.getSyntheticNames(input, _, _) and + c.input(input, mapped) and + name = c.getSyntheticName(_, mapped, _) and output = SummaryComponentStack::syntheticGlobal(name) ) } } /** - * Add all `DbContext` property names as potential synthetic globals. + * Add all possible synthetic global names. */ private class EFSummarizedCallableSyntheticGlobal extends SummaryComponent::SyntheticGlobal { - EFSummarizedCallableSyntheticGlobal() { - this = any(DbContextClass c).getSyntheticNames(_, _, _) - } + EFSummarizedCallableSyntheticGlobal() { this = any(DbContextClass c).getSyntheticName(_, _, _) } } private class DbContextSaveChangesRequiredSummaryComponentStack extends RequiredSummaryComponentStack From 775f3eaf5682561732584f75e4c3cc74e25bd1ac Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 13 Jun 2023 17:07:41 +0200 Subject: [PATCH 532/739] python: make copy a dataflow step --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 4d8f1280177..edbe6317b46 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -3973,7 +3973,7 @@ private module StdlibPrivate { or input = "Argument[self]" and output = "ReturnValue" and - preservesValue = false + preservesValue = true } } From b72c93ff4fa25b3fdd4ab284a9ee2631dbc14047 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Fri, 9 Jun 2023 13:11:55 +0200 Subject: [PATCH 533/739] python: remove remaining explicit taint steps --- .../new/internal/TaintTrackingPrivate.qll | 19 ------------ .../dataflow/summaries/summaries.expected | 3 -- .../test_collections.py | 28 ++++++++--------- .../Security/CWE-022-TarSlip/TarSlip.expected | 31 ------------------- .../UnsafeUnpack.expected | 10 ------ .../CWE-022-UnsafeUnpacking/UnsafeUnpack.py | 2 +- .../frameworks/aiohttp/taint_test.py | 6 ++-- .../frameworks/multidict/taint_test.py | 12 +++---- .../frameworks/stdlib/http_server.py | 4 +-- 9 files changed, 26 insertions(+), 89 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 78fb529b05a..6adab46f246 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -183,25 +183,6 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { // longer -- but there needs to be a matching read-step for the store-step, and we // don't provide that right now. DataFlowPrivate::comprehensionStoreStep(nodeFrom, _, nodeTo) - or - // functions operating on collections - exists(DataFlow::CallCfgNode call | call = nodeTo | - call = API::builtin(["sorted", "reversed", "iter", "next"]).getACall() and - call.getArg(0) = nodeFrom - ) - or - // dict methods - exists(DataFlow::MethodCallNode call, string methodName | call = nodeTo | - methodName in ["values", "items"] and - call.calls(nodeFrom, methodName) - ) - or - // list.append, set.add - exists(DataFlow::MethodCallNode call, DataFlow::Node obj | - call.calls(obj, ["append", "add"]) and - obj = nodeTo.(DataFlow::PostUpdateNode).getPreUpdateNode() and - call.getArg(0) = nodeFrom - ) } /** diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.expected b/python/ql/test/experimental/dataflow/summaries/summaries.expected index b566cbdedc6..47cab4224a4 100644 --- a/python/ql/test/experimental/dataflow/summaries/summaries.expected +++ b/python/ql/test/experimental/dataflow/summaries/summaries.expected @@ -4,9 +4,7 @@ edges | summaries.py:36:18:36:54 | ControlFlowNode for apply_lambda() | summaries.py:37:6:37:19 | ControlFlowNode for tainted_lambda | | summaries.py:36:48:36:53 | ControlFlowNode for SOURCE | summaries.py:36:18:36:54 | ControlFlowNode for apply_lambda() | | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | -| summaries.py:44:25:44:32 | ControlFlowNode for List | summaries.py:45:6:45:20 | ControlFlowNode for Subscript | | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | -| summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | summaries.py:44:25:44:32 | ControlFlowNode for List | | summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | summaries.py:45:6:45:20 | ControlFlowNode for Subscript | | summaries.py:51:18:51:46 | ControlFlowNode for list_map() [List element] | summaries.py:52:6:52:19 | ControlFlowNode for tainted_mapped [List element] | @@ -36,7 +34,6 @@ nodes | summaries.py:36:48:36:53 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | summaries.py:37:6:37:19 | ControlFlowNode for tainted_lambda | semmle.label | ControlFlowNode for tainted_lambda | | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | semmle.label | ControlFlowNode for reversed() [List element] | -| summaries.py:44:25:44:32 | ControlFlowNode for List | semmle.label | ControlFlowNode for List | | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | | summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | semmle.label | ControlFlowNode for tainted_list [List element] | diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index 50f9a613f9b..1eaa5e44aa2 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -31,8 +31,8 @@ def test_construction(): list(tainted_list), # $ tainted list(tainted_tuple), # $ tainted list(tainted_set), # $ tainted - list(tainted_dict.values()), # $ tainted - list(tainted_dict.items()), # $ tainted + list(tainted_dict.values()), # $ MISSING: tainted + list(tainted_dict.items()), # $ MISSING: tainted tuple(tainted_list), # $ tainted set(tainted_list), # $ tainted @@ -56,10 +56,10 @@ def test_access(x, y, z): tainted_list[x], # $ tainted tainted_list[y:z], # $ tainted - sorted(tainted_list), # $ tainted - reversed(tainted_list), # $ tainted - iter(tainted_list), # $ tainted - next(iter(tainted_list)), # $ tainted + sorted(tainted_list), # $ MISSING: tainted + reversed(tainted_list), # $ MISSING: tainted + iter(tainted_list), # $ MISSING: tainted + next(iter(tainted_list)), # $ MISSING: tainted [i for i in tainted_list], # $ tainted [tainted_list for _i in [1,2,3]], # $ MISSING: tainted ) @@ -70,7 +70,7 @@ def test_access(x, y, z): for h in tainted_list: ensure_tainted(h) # $ tainted for i in reversed(tainted_list): - ensure_tainted(i) # $ tainted + ensure_tainted(i) # $ MISSING: tainted def test_access_explicit(x, y, z): tainted_list = [TAINTED_STRING] @@ -80,10 +80,10 @@ def test_access_explicit(x, y, z): tainted_list[x], # $ tainted tainted_list[y:z], # $ tainted - sorted(tainted_list)[0], # $ tainted + sorted(tainted_list)[0], # $ MISSING: tainted reversed(tainted_list)[0], # $ tainted - iter(tainted_list), # $ tainted - next(iter(tainted_list)), # $ tainted + iter(tainted_list), # $ MISSING: tainted + next(iter(tainted_list)), # $ MISSING: tainted [i for i in tainted_list], # $ tainted [tainted_list for i in [1,2,3]], # $ MISSING: tainted [TAINTED_STRING for i in [1,2,3]], # $ tainted @@ -109,9 +109,9 @@ def test_dict_access(x): ) for v in tainted_dict.values(): - ensure_tainted(v) # $ tainted + ensure_tainted(v) # $ MISSING: tainted for k, v in tainted_dict.items(): - ensure_tainted(v) # $ tainted + ensure_tainted(v) # $ MISSING: tainted def test_named_tuple(): # TODO: namedtuple currently not handled @@ -194,7 +194,7 @@ def list_append(): ensure_not_tainted(my_list) my_list.append(tainted_string) - ensure_tainted(my_list) # $ tainted + ensure_tainted(my_list) # $ MISSING: tainted def list_extend(): @@ -262,7 +262,7 @@ def set_add(): ensure_not_tainted(my_set) my_set.add(tainted_string) - ensure_tainted(my_set) # $ tainted + ensure_tainted(my_set) # $ MISSING: tainted # Make tests runable diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected index 9a5571a8033..96a0dea5697 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected @@ -1,11 +1,4 @@ edges -| TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:17:5:17:10 | GSSA Variable member | -| TarSlipImprov.py:17:5:17:10 | GSSA Variable member | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | -| TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:28:9:28:14 | SSA variable member | -| TarSlipImprov.py:28:9:28:14 | SSA variable member | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | -| TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | -| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | -| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | | TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | | TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:56:9:56:13 | GSSA Variable entry | @@ -26,8 +19,6 @@ edges | TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | | TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | -| TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:233:9:233:9 | GSSA Variable f | -| TarSlipImprov.py:233:9:233:9 | GSSA Variable f | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | | TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | | TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:265:9:265:13 | GSSA Variable entry | @@ -40,18 +31,7 @@ edges | TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | | TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | -| TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:306:5:306:10 | GSSA Variable member | -| TarSlipImprov.py:306:5:306:10 | GSSA Variable member | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | nodes -| TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| TarSlipImprov.py:17:5:17:10 | GSSA Variable member | semmle.label | GSSA Variable member | -| TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | -| TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | semmle.label | ControlFlowNode for tarfile | -| TarSlipImprov.py:28:9:28:14 | SSA variable member | semmle.label | SSA variable member | -| TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | -| TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | semmle.label | ControlFlowNode for members_filter1() | -| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | @@ -86,9 +66,6 @@ nodes | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | -| TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| TarSlipImprov.py:233:9:233:9 | GSSA Variable f | semmle.label | GSSA Variable f | -| TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | semmle.label | ControlFlowNode for members | | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | @@ -110,15 +87,9 @@ nodes | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | -| TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| TarSlipImprov.py:306:5:306:10 | GSSA Variable member | semmle.label | GSSA Variable member | -| TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths -| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | #select -| TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | ControlFlowNode for result | -| TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | ControlFlowNode for members_filter1() | | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | ControlFlowNode for entry | | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | ControlFlowNode for entry | | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | TarSlipImprov.py:88:6:88:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:88:6:88:43 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | ControlFlowNode for tar | @@ -133,7 +104,6 @@ subpaths | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | ControlFlowNode for tar | | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | ControlFlowNode for tar | | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | ControlFlowNode for tar | -| TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | ControlFlowNode for members | | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | ControlFlowNode for entry | | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | ControlFlowNode for entry | @@ -143,5 +113,4 @@ subpaths | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | ControlFlowNode for tar | | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | ControlFlowNode for tar | | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | ControlFlowNode for tar | -| TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | ControlFlowNode for result | | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index f32d3037bbc..93ca771caaa 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -23,10 +23,6 @@ edges | UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | | UnsafeUnpack.py:118:38:118:47 | ControlFlowNode for Attribute | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | | UnsafeUnpack.py:140:23:140:35 | ControlFlowNode for Attribute | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | -| UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | UnsafeUnpack.py:163:23:163:28 | SSA variable member | -| UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | -| UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | -| UnsafeUnpack.py:163:23:163:28 | SSA variable member | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | | UnsafeUnpack.py:174:15:174:26 | ControlFlowNode for Attribute | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | | UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | nodes @@ -61,11 +57,6 @@ nodes | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | semmle.label | ControlFlowNode for uploaded_file_path | | UnsafeUnpack.py:140:23:140:35 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | -| UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | semmle.label | SSA variable chunk | -| UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | -| UnsafeUnpack.py:163:23:163:28 | SSA variable member | semmle.label | SSA variable member | -| UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | UnsafeUnpack.py:174:15:174:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | semmle.label | ControlFlowNode for tmp | @@ -82,6 +73,5 @@ subpaths | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | UnsafeUnpack.py:108:22:108:34 | ControlFlowNode for Attribute | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | Unsafe extraction from a malicious tarball retrieved from a remote location. | | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | Unsafe extraction from a malicious tarball retrieved from a remote location. | | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | UnsafeUnpack.py:140:23:140:35 | ControlFlowNode for Attribute | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | Unsafe extraction from a malicious tarball retrieved from a remote location. | -| UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | Unsafe extraction from a malicious tarball retrieved from a remote location. | | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | UnsafeUnpack.py:79:16:79:28 | ControlFlowNode for Attribute | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | Unsafe extraction from a malicious tarball retrieved from a remote location. | | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | Unsafe extraction from a malicious tarball retrieved from a remote location. | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.py b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.py index 6b533462d23..3f4f2319690 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.py @@ -164,7 +164,7 @@ def simple_upload(request): if member.issym(): raise ValueError("But it is a symlink") result.append(member) - tar.extractall(path=tempfile.mkdtemp(), members=result) # $result=BAD + tar.extractall(path=tempfile.mkdtemp(), members=result) # $ MISSING: result=BAD tar.close() diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index ec475a592ab..6c0a60530b5 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -40,10 +40,10 @@ async def test_taint(request: web.Request): # $ requestHandler request.cookies["key"], # $ tainted request.cookies.get("key"), # $ tainted request.cookies.keys(), # $ MISSING: tainted - request.cookies.values(), # $ tainted - request.cookies.items(), # $ tainted + request.cookies.values(), # $ MISSING: tainted + request.cookies.items(), # $ MISSING: tainted list(request.cookies), # $ tainted - iter(request.cookies), # $ tainted + iter(request.cookies), # $ MISSING: tainted # aiohttp.StreamReader diff --git a/python/ql/test/library-tests/frameworks/multidict/taint_test.py b/python/ql/test/library-tests/frameworks/multidict/taint_test.py index 8fbac79888f..4410e2b2a6f 100644 --- a/python/ql/test/library-tests/frameworks/multidict/taint_test.py +++ b/python/ql/test/library-tests/frameworks/multidict/taint_test.py @@ -13,11 +13,11 @@ ensure_tainted( mdp.getone("key"), # $ tainted mdp.getall("key"), # $ tainted mdp.keys(), # $ MISSING: tainted - mdp.values(), # $ tainted - mdp.items(), # $ tainted + mdp.values(), # $ MISSING: tainted + mdp.items(), # $ MISSING: tainted mdp.copy(), # $ tainted list(mdp), # $ tainted - iter(mdp), # $ tainted + iter(mdp), # $ MISSING: tainted ) # TODO: This is an invalid CIMultiDictProxy construction... but for the purpose of @@ -33,9 +33,9 @@ ensure_tainted( ci_mdp.getone("key"), # $ tainted ci_mdp.getall("key"), # $ tainted ci_mdp.keys(), # $ MISSING: tainted - ci_mdp.values(), # $ tainted - ci_mdp.items(), # $ tainted + ci_mdp.values(), # $ MISSING: tainted + ci_mdp.items(), # $ MISSING: tainted ci_mdp.copy(), # $ tainted list(ci_mdp), # $ tainted - iter(ci_mdp), # $ tainted + iter(ci_mdp), # $ MISSING: tainted ) diff --git a/python/ql/test/library-tests/frameworks/stdlib/http_server.py b/python/ql/test/library-tests/frameworks/stdlib/http_server.py index 27ec2211f4b..3dbc832c397 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/http_server.py +++ b/python/ql/test/library-tests/frameworks/stdlib/http_server.py @@ -60,8 +60,8 @@ class MyHandler(BaseHTTPRequestHandler): self.headers.get('Foo'), # $ tainted self.headers.get_all('Foo'), # $ tainted self.headers.keys(), # $ tainted - self.headers.values(), # $ tainted - self.headers.items(), # $ tainted + self.headers.values(), # $ MISSING: tainted + self.headers.items(), # $ MISSING: tainted self.headers.as_bytes(), # $ tainted self.headers.as_string(), # $ tainted str(self.headers), # $ tainted From 4b4b9bf9da0d8451e383065008dbf06b4735501b Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Fri, 9 Jun 2023 16:08:02 +0200 Subject: [PATCH 534/739] python: add missing summaries For append/add: The new results in the experimental tar slip query show that we do not recognize the sanitisers. --- .../lib/semmle/python/frameworks/Stdlib.qll | 277 +++++++++++++++++- .../experimental/dataflow/coverage/test.py | 2 +- .../dataflow/coverage/test_builtins.py | 34 +-- .../dataflow/summaries/summaries.expected | 5 + .../test_collections.py | 26 +- .../Security/CWE-022-TarSlip/TarSlip.expected | 47 +++ .../UnsafeUnpack.expected | 14 + .../CWE-022-UnsafeUnpacking/UnsafeUnpack.py | 2 +- .../frameworks/aiohttp/taint_test.py | 8 +- .../frameworks/multidict/taint_test.py | 16 +- .../frameworks/stdlib/http_server.py | 4 +- 11 files changed, 388 insertions(+), 47 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index bfd9144020d..641dba0779e 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -3883,6 +3883,9 @@ private module StdlibPrivate { } } + // --------------------------------------------------------------------------- + // Flow summaries for functions operating on containers + // --------------------------------------------------------------------------- /** A flow summary for `reversed`. */ class ReversedSummary extends SummarizedCallable { ReversedSummary() { this = "builtins.reversed" } @@ -3894,9 +3897,114 @@ private module StdlibPrivate { } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[0].ListElement" and + ( + input = "Argument[0].ListElement" + or + input = "Argument[0].SetElement" + or + exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() | + input = "Argument[0].TupleElement[" + i.toString() + "]" + ) + // TODO: Once we have DictKeyContent, we need to transform that into ListElementContent + ) and output = "ReturnValue.ListElement" and preservesValue = true + or + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** A flow summary for `sorted`. */ + class SortedSummary extends SummarizedCallable { + SortedSummary() { this = "builtins.sorted" } + + override DataFlow::CallCfgNode getACall() { result = API::builtin("sorted").getACall() } + + override DataFlow::ArgumentNode getACallback() { + result = API::builtin("sorted").getAValueReachableFromSource() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + exists(string content | + content = "ListElement" + or + content = "SetElement" + or + exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() | + content = "TupleElement[" + i.toString() + "]" + ) + | + // TODO: Once we have DictKeyContent, we need to transform that into ListElementContent + input = "Argument[0]." + content and + output = "ReturnValue.ListElement" and + preservesValue = true + ) + or + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** A flow summary for `iter`. */ + class IterSummary extends SummarizedCallable { + IterSummary() { this = "builtins.iter" } + + override DataFlow::CallCfgNode getACall() { result = API::builtin("iter").getACall() } + + override DataFlow::ArgumentNode getACallback() { + result = API::builtin("iter").getAValueReachableFromSource() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + ( + input = "Argument[0].ListElement" + or + input = "Argument[0].SetElement" + or + exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() | + input = "Argument[0].TupleElement[" + i.toString() + "]" + ) + // TODO: Once we have DictKeyContent, we need to transform that into ListElementContent + ) and + output = "ReturnValue.ListElement" and + preservesValue = true + or + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** A flow summary for `next`. */ + class NextSummary extends SummarizedCallable { + NextSummary() { this = "builtins.next" } + + override DataFlow::CallCfgNode getACall() { result = API::builtin("next").getACall() } + + override DataFlow::ArgumentNode getACallback() { + result = API::builtin("next").getAValueReachableFromSource() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + ( + input = "Argument[0].ListElement" + or + input = "Argument[0].SetElement" + or + exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() | + input = "Argument[0].TupleElement[" + i.toString() + "]" + ) + // TODO: Once we have DictKeyContent, we need to transform that into ListElementContent + ) and + output = "ReturnValue" and + preservesValue = true + or + input = "Argument[1]" and + output = "ReturnValue" and + preservesValue = true } } @@ -4127,6 +4235,173 @@ private module StdlibPrivate { preservesValue = true } } + + /** + * A flow summary for `dict.values`. + * + * See https://docs.python.org/3.10/library/stdtypes.html#dict.values + */ + class DictValues extends SummarizedCallable { + DictValues() { this = "dict.values" } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).calls(_, "values") + } + + override DataFlow::ArgumentNode getACallback() { + result.(DataFlow::AttrRead).getAttributeName() = "values" + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | + input = "Argument[self].DictionaryElement[" + key + "]" and + output = "ReturnValue.ListElement" and + preservesValue = true + ) + or + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** + * A flow summary for `dict.keys`. + * + * See https://docs.python.org/3.10/library/stdtypes.html#dict.keys + */ + class DictKeys extends SummarizedCallable { + DictKeys() { this = "dict.keys" } + + override DataFlow::CallCfgNode getACall() { result.(DataFlow::MethodCallNode).calls(_, "keys") } + + override DataFlow::ArgumentNode getACallback() { + result.(DataFlow::AttrRead).getAttributeName() = "keys" + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + // TODO: Once we have DictKeyContent, we need to transform that into ListElementContent + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** + * A flow summary for `dict.items`. + * + * See https://docs.python.org/3.10/library/stdtypes.html#dict.items + */ + class DictItems extends SummarizedCallable { + DictItems() { this = "dict.items" } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).calls(_, "items") + } + + override DataFlow::ArgumentNode getACallback() { + result.(DataFlow::AttrRead).getAttributeName() = "items" + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | + input = "Argument[self].DictionaryElement[" + key + "]" and + output = "ReturnValue.ListElement.TupleElement[1]" and + preservesValue = true + ) + or + // TODO: Add the keys to output list + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** + * A flow summary for `list.append`. + * + * See https://docs.python.org/3.10/library/stdtypes.html#typesseq-mutable + */ + class ListAppend extends SummarizedCallable { + ListAppend() { this = "list.append" } + + override DataFlow::CallCfgNode getACall() { + result.(DataFlow::MethodCallNode).calls(_, "append") + } + + override DataFlow::ArgumentNode getACallback() { + result.(DataFlow::AttrRead).getAttributeName() = "append" + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + // existing elements + input = "Argument[self].ListElement" and + output = "ReturnValue.ListElement" and + preservesValue = true + or + // newly added element returned + input = "Argument[0]" and + output = "ReturnValue.ListElement" and + preservesValue = true + or + // newly added element added to this + input = "Argument[0]" and + output = "Argument[self].ListElement" and + preservesValue = true + or + // transfer taint from new element to this + input = "Argument[0]" and + output = "Argument[self]" and + preservesValue = false + or + // transfer taint from new element to return value + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /** + * A flow summary for `set.add`. + * + * See https://docs.python.org/3.10/library/stdtypes.html#frozenset.add + */ + class SetAdd extends SummarizedCallable { + SetAdd() { this = "set.add" } + + override DataFlow::CallCfgNode getACall() { result.(DataFlow::MethodCallNode).calls(_, "add") } + + override DataFlow::ArgumentNode getACallback() { + result.(DataFlow::AttrRead).getAttributeName() = "add" + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + // existing elements + input = "Argument[self].SetElement" and + output = "ReturnValue.SetElement" and + preservesValue = true + or + // newly added element returned + input = "Argument[0]" and + output = "ReturnValue.SetElement" and + preservesValue = true + or + // newly added element added to this + input = "Argument[0]" and + output = "Argument[self].SetElement" and + preservesValue = true + or + // transfer taint from new element to this + input = "Argument[0]" and + output = "Argument[self]" and + preservesValue = false + or + // transfer taint from new element to return value + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + } + } } // --------------------------------------------------------------------------- diff --git a/python/ql/test/experimental/dataflow/coverage/test.py b/python/ql/test/experimental/dataflow/coverage/test.py index f35339e4dca..81623c58ea0 100644 --- a/python/ql/test/experimental/dataflow/coverage/test.py +++ b/python/ql/test/experimental/dataflow/coverage/test.py @@ -192,7 +192,7 @@ def test_nested_comprehension_deep_with_local_flow(): def test_nested_comprehension_dict(): d = {"s": [SOURCE]} x = [y for k, v in d.items() for y in v] - SINK(x[0]) #$ MISSING:flow="SOURCE, l:-2 -> x[0]" + SINK(x[0]) #$ flow="SOURCE, l:-2 -> x[0]" def test_nested_comprehension_paren(): diff --git a/python/ql/test/experimental/dataflow/coverage/test_builtins.py b/python/ql/test/experimental/dataflow/coverage/test_builtins.py index 629e2600280..24592337076 100644 --- a/python/ql/test/experimental/dataflow/coverage/test_builtins.py +++ b/python/ql/test/experimental/dataflow/coverage/test_builtins.py @@ -171,7 +171,7 @@ def test_list_copy(): def test_list_append(): l = [NONSOURCE] l.append(SOURCE) - SINK(l[1]) #$ MISSING: flow="SOURCE, l:-1 -> l[1]" + SINK(l[1]) #$ flow="SOURCE, l:-1 -> l[1]" ### Set @@ -188,7 +188,7 @@ def test_set_copy(): def test_set_add(): s = set([]) s.add(SOURCE) - SINK(s.pop()) #$ MISSING: flow="SOURCE, l:-2 -> s.pop()" + SINK(s.pop()) #$ flow="SOURCE, l:-1 -> s.pop()" ### Dict @@ -202,7 +202,7 @@ def test_dict_values(): d = {'k': SOURCE} vals = d.values() val_list = list(vals) - SINK(val_list[0]) #$ MISSING: flow="SOURCE, l:-3 -> val_list[0]" + SINK(val_list[0]) #$ flow="SOURCE, l:-3 -> val_list[0]" @expects(4) def test_dict_items(): @@ -210,9 +210,9 @@ def test_dict_items(): items = d.items() item_list = list(items) SINK_F(item_list[0][0]) # expecting FP due to imprecise flow - SINK(item_list[0][1]) #$ MISSING: flow="SOURCE, l:-4 -> item_list[0][1]" + SINK(item_list[0][1]) #$ flow="SOURCE, l:-4 -> item_list[0][1]" SINK(item_list[1][0]) #$ MISSING: flow="SOURCE, l:-5 -> item_list[1][0]" - SINK_F(item_list[1][1]) # expecting FP due to imprecise flow + SINK_F(item_list[1][1]) #$ SPURIOUS: flow="SOURCE, l:-6 -> item_list[1][1]" @expects(3) def test_dict_pop(): @@ -257,17 +257,17 @@ def test_dict_copy(): def test_sorted_list(): l0 = [SOURCE] l = sorted(l0) - SINK(l[0]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]" + SINK(l[0]) #$ flow="SOURCE, l:-2 -> l[0]" def test_sorted_tuple(): t = (SOURCE,) l = sorted(t) - SINK(l[0]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]" + SINK(l[0]) #$ flow="SOURCE, l:-2 -> l[0]" def test_sorted_set(): s = {SOURCE} l = sorted(s) - SINK(l[0]) #$ MISSING: flow="SOURCE, l:-2 -> l[0]" + SINK(l[0]) #$ flow="SOURCE, l:-2 -> l[0]" def test_sorted_dict(): d = {SOURCE: "val"} @@ -289,8 +289,8 @@ def test_reversed_tuple(): t = (SOURCE, NONSOURCE) r = reversed(t) l = list(r) - SINK_F(l[0]) - SINK(l[1]) #$ MISSING: flow="SOURCE, l:-4 -> l[1]" + SINK_F(l[0]) #$ SPURIOUS: flow="SOURCE, l:-3 -> l[0]" + SINK(l[1]) #$ flow="SOURCE, l:-4 -> l[1]" @expects(2) def test_reversed_dict(): @@ -306,19 +306,19 @@ def test_iter_list(): l0 = [SOURCE] i = iter(l0) l = list(i) - SINK(l[0]) #$ MISSING: flow="SOURCE, l:-3 -> l[0]" + SINK(l[0]) #$ flow="SOURCE, l:-3 -> l[0]" def test_iter_tuple(): t = (SOURCE,) i = iter(t) l = list(i) - SINK(l[0]) #$ MISSING: flow="SOURCE, l:-3 -> l[0]" + SINK(l[0]) #$ flow="SOURCE, l:-3 -> l[0]" def test_iter_set(): t = {SOURCE} i = iter(t) l = list(i) - SINK(l[0]) #$ MISSING: flow="SOURCE, l:-3 -> l[0]" + SINK(l[0]) #$ flow="SOURCE, l:-3 -> l[0]" def test_iter_dict(): d = {SOURCE: "val"} @@ -331,7 +331,7 @@ def test_iter_iter(): l0 = [SOURCE] i = iter(iter(l0)) l = list(i) - SINK(l[0]) #$ MISSING: flow="SOURCE, l:-3 -> l[0]" + SINK(l[0]) #$ flow="SOURCE, l:-3 -> l[0]" ### next @@ -339,19 +339,19 @@ def test_next_list(): l = [SOURCE] i = iter(l) n = next(i) - SINK(n) #$ MISSING: flow="SOURCE, l:-3 -> n" + SINK(n) #$ flow="SOURCE, l:-3 -> n" def test_next_tuple(): t = (SOURCE,) i = iter(t) n = next(i) - SINK(n) #$ MISSING: flow="SOURCE, l:-3 -> n" + SINK(n) #$ flow="SOURCE, l:-3 -> n" def test_next_set(): s = {SOURCE} i = iter(s) n = next(i) - SINK(n) #$ MISSING: flow="SOURCE, l:-3 -> n" + SINK(n) #$ flow="SOURCE, l:-3 -> n" def test_next_dict(): d = {SOURCE: "val"} diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.expected b/python/ql/test/experimental/dataflow/summaries/summaries.expected index 47cab4224a4..1d8a9f1eb0c 100644 --- a/python/ql/test/experimental/dataflow/summaries/summaries.expected +++ b/python/ql/test/experimental/dataflow/summaries/summaries.expected @@ -3,8 +3,11 @@ edges | summaries.py:32:20:32:25 | ControlFlowNode for SOURCE | summaries.py:32:11:32:26 | ControlFlowNode for identity() | | summaries.py:36:18:36:54 | ControlFlowNode for apply_lambda() | summaries.py:37:6:37:19 | ControlFlowNode for tainted_lambda | | summaries.py:36:48:36:53 | ControlFlowNode for SOURCE | summaries.py:36:18:36:54 | ControlFlowNode for apply_lambda() | +| summaries.py:44:16:44:33 | ControlFlowNode for reversed() | summaries.py:45:6:45:20 | ControlFlowNode for Subscript | | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | +| summaries.py:44:25:44:32 | ControlFlowNode for List | summaries.py:44:16:44:33 | ControlFlowNode for reversed() | | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | +| summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | summaries.py:44:25:44:32 | ControlFlowNode for List | | summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | summaries.py:45:6:45:20 | ControlFlowNode for Subscript | | summaries.py:51:18:51:46 | ControlFlowNode for list_map() [List element] | summaries.py:52:6:52:19 | ControlFlowNode for tainted_mapped [List element] | @@ -33,7 +36,9 @@ nodes | summaries.py:36:18:36:54 | ControlFlowNode for apply_lambda() | semmle.label | ControlFlowNode for apply_lambda() | | summaries.py:36:48:36:53 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | summaries.py:37:6:37:19 | ControlFlowNode for tainted_lambda | semmle.label | ControlFlowNode for tainted_lambda | +| summaries.py:44:16:44:33 | ControlFlowNode for reversed() | semmle.label | ControlFlowNode for reversed() | | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | semmle.label | ControlFlowNode for reversed() [List element] | +| summaries.py:44:25:44:32 | ControlFlowNode for List | semmle.label | ControlFlowNode for List | | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | | summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | semmle.label | ControlFlowNode for tainted_list [List element] | diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index 1eaa5e44aa2..0e2aae93554 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -31,8 +31,8 @@ def test_construction(): list(tainted_list), # $ tainted list(tainted_tuple), # $ tainted list(tainted_set), # $ tainted - list(tainted_dict.values()), # $ MISSING: tainted - list(tainted_dict.items()), # $ MISSING: tainted + list(tainted_dict.values()), # $ tainted + list(tainted_dict.items()), # $ tainted tuple(tainted_list), # $ tainted set(tainted_list), # $ tainted @@ -56,9 +56,9 @@ def test_access(x, y, z): tainted_list[x], # $ tainted tainted_list[y:z], # $ tainted - sorted(tainted_list), # $ MISSING: tainted - reversed(tainted_list), # $ MISSING: tainted - iter(tainted_list), # $ MISSING: tainted + sorted(tainted_list), # $ tainted + reversed(tainted_list), # $ tainted + iter(tainted_list), # $ tainted next(iter(tainted_list)), # $ MISSING: tainted [i for i in tainted_list], # $ tainted [tainted_list for _i in [1,2,3]], # $ MISSING: tainted @@ -70,7 +70,7 @@ def test_access(x, y, z): for h in tainted_list: ensure_tainted(h) # $ tainted for i in reversed(tainted_list): - ensure_tainted(i) # $ MISSING: tainted + ensure_tainted(i) # $ tainted def test_access_explicit(x, y, z): tainted_list = [TAINTED_STRING] @@ -80,10 +80,10 @@ def test_access_explicit(x, y, z): tainted_list[x], # $ tainted tainted_list[y:z], # $ tainted - sorted(tainted_list)[0], # $ MISSING: tainted + sorted(tainted_list)[0], # $ tainted reversed(tainted_list)[0], # $ tainted - iter(tainted_list), # $ MISSING: tainted - next(iter(tainted_list)), # $ MISSING: tainted + iter(tainted_list), # $ tainted + next(iter(tainted_list)), # $ tainted [i for i in tainted_list], # $ tainted [tainted_list for i in [1,2,3]], # $ MISSING: tainted [TAINTED_STRING for i in [1,2,3]], # $ tainted @@ -109,9 +109,9 @@ def test_dict_access(x): ) for v in tainted_dict.values(): - ensure_tainted(v) # $ MISSING: tainted + ensure_tainted(v) # $ tainted for k, v in tainted_dict.items(): - ensure_tainted(v) # $ MISSING: tainted + ensure_tainted(v) # $ tainted def test_named_tuple(): # TODO: namedtuple currently not handled @@ -194,7 +194,7 @@ def list_append(): ensure_not_tainted(my_list) my_list.append(tainted_string) - ensure_tainted(my_list) # $ MISSING: tainted + ensure_tainted(my_list) # $ tainted def list_extend(): @@ -262,7 +262,7 @@ def set_add(): ensure_not_tainted(my_set) my_set.add(tainted_string) - ensure_tainted(my_set) # $ MISSING: tainted + ensure_tainted(my_set) # $ tainted # Make tests runable diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected index 96a0dea5697..0042b85512c 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected @@ -1,4 +1,15 @@ edges +| TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:17:5:17:10 | GSSA Variable member | +| TarSlipImprov.py:17:5:17:10 | GSSA Variable member | TarSlipImprov.py:20:19:20:24 | ControlFlowNode for member | +| TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | +| TarSlipImprov.py:20:19:20:24 | ControlFlowNode for member | TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result | +| TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:28:9:28:14 | SSA variable member | +| TarSlipImprov.py:28:9:28:14 | SSA variable member | TarSlipImprov.py:35:23:35:28 | ControlFlowNode for member | +| TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | +| TarSlipImprov.py:35:23:35:28 | ControlFlowNode for member | TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result | +| TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | | TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | | TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:56:9:56:13 | GSSA Variable entry | @@ -19,6 +30,10 @@ edges | TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | | TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | +| TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:233:9:233:9 | GSSA Variable f | +| TarSlipImprov.py:233:9:233:9 | GSSA Variable f | TarSlipImprov.py:235:28:235:28 | ControlFlowNode for f | +| TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | +| TarSlipImprov.py:235:28:235:28 | ControlFlowNode for f | TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members | | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | | TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | | TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:265:9:265:13 | GSSA Variable entry | @@ -31,7 +46,24 @@ edges | TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | | TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | +| TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:306:5:306:10 | GSSA Variable member | +| TarSlipImprov.py:306:5:306:10 | GSSA Variable member | TarSlipImprov.py:309:19:309:24 | ControlFlowNode for member | +| TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | +| TarSlipImprov.py:309:19:309:24 | ControlFlowNode for member | TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result | nodes +| TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:17:5:17:10 | GSSA Variable member | semmle.label | GSSA Variable member | +| TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | +| TarSlipImprov.py:20:19:20:24 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | +| TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | +| TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | semmle.label | ControlFlowNode for tarfile | +| TarSlipImprov.py:28:9:28:14 | SSA variable member | semmle.label | SSA variable member | +| TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | +| TarSlipImprov.py:35:23:35:28 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | +| TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | +| TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | semmle.label | ControlFlowNode for members_filter1() | +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | @@ -66,6 +98,11 @@ nodes | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:233:9:233:9 | GSSA Variable f | semmle.label | GSSA Variable f | +| TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members | semmle.label | [post] ControlFlowNode for members | +| TarSlipImprov.py:235:28:235:28 | ControlFlowNode for f | semmle.label | ControlFlowNode for f | +| TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | semmle.label | ControlFlowNode for members | | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | @@ -87,9 +124,17 @@ nodes | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:306:5:306:10 | GSSA Variable member | semmle.label | GSSA Variable member | +| TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | +| TarSlipImprov.py:309:19:309:24 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | +| TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | #select +| TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | ControlFlowNode for result | +| TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | ControlFlowNode for members_filter1() | | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | ControlFlowNode for entry | | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | ControlFlowNode for entry | | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | TarSlipImprov.py:88:6:88:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:88:6:88:43 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | ControlFlowNode for tar | @@ -104,6 +149,7 @@ subpaths | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | ControlFlowNode for tar | | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | ControlFlowNode for tar | | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | ControlFlowNode for members | | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | ControlFlowNode for entry | | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | ControlFlowNode for entry | @@ -113,4 +159,5 @@ subpaths | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | ControlFlowNode for tar | | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | ControlFlowNode for tar | | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | ControlFlowNode for result | | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index 93ca771caaa..6813bf887db 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -23,6 +23,12 @@ edges | UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | UnsafeUnpack.py:116:17:116:21 | SSA variable ufile | | UnsafeUnpack.py:118:38:118:47 | ControlFlowNode for Attribute | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | | UnsafeUnpack.py:140:23:140:35 | ControlFlowNode for Attribute | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | +| UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | UnsafeUnpack.py:163:23:163:28 | SSA variable member | +| UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | +| UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | +| UnsafeUnpack.py:163:23:163:28 | SSA variable member | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | +| UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | +| UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | | UnsafeUnpack.py:174:15:174:26 | ControlFlowNode for Attribute | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | | UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | nodes @@ -57,6 +63,13 @@ nodes | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | semmle.label | ControlFlowNode for uploaded_file_path | | UnsafeUnpack.py:140:23:140:35 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| UnsafeUnpack.py:158:23:158:27 | SSA variable chunk | semmle.label | SSA variable chunk | +| UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| UnsafeUnpack.py:158:32:158:54 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| UnsafeUnpack.py:163:23:163:28 | SSA variable member | semmle.label | SSA variable member | +| UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | +| UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | +| UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | UnsafeUnpack.py:174:15:174:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | semmle.label | ControlFlowNode for tmp | @@ -73,5 +86,6 @@ subpaths | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | UnsafeUnpack.py:108:22:108:34 | ControlFlowNode for Attribute | UnsafeUnpack.py:112:35:112:43 | ControlFlowNode for file_path | Unsafe extraction from a malicious tarball retrieved from a remote location. | | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | UnsafeUnpack.py:116:27:116:39 | ControlFlowNode for Attribute | UnsafeUnpack.py:120:41:120:58 | ControlFlowNode for uploaded_file_path | Unsafe extraction from a malicious tarball retrieved from a remote location. | | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | UnsafeUnpack.py:140:23:140:35 | ControlFlowNode for Attribute | UnsafeUnpack.py:142:49:142:51 | ControlFlowNode for tar | Unsafe extraction from a malicious tarball retrieved from a remote location. | +| UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | UnsafeUnpack.py:158:32:158:44 | ControlFlowNode for Attribute | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | Unsafe extraction from a malicious tarball retrieved from a remote location. | | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | UnsafeUnpack.py:79:16:79:28 | ControlFlowNode for Attribute | UnsafeUnpack.py:176:1:176:34 | ControlFlowNode for Attribute() | Unsafe extraction from a malicious tarball retrieved from a remote location. | | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | Unsafe extraction from a malicious tarball retrieved from a remote location. | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.py b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.py index 3f4f2319690..6b533462d23 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.py @@ -164,7 +164,7 @@ def simple_upload(request): if member.issym(): raise ValueError("But it is a symlink") result.append(member) - tar.extractall(path=tempfile.mkdtemp(), members=result) # $ MISSING: result=BAD + tar.extractall(path=tempfile.mkdtemp(), members=result) # $result=BAD tar.close() diff --git a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py index 6c0a60530b5..54da5726803 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py +++ b/python/ql/test/library-tests/frameworks/aiohttp/taint_test.py @@ -39,11 +39,11 @@ async def test_taint(request: web.Request): # $ requestHandler request.cookies, # $ tainted request.cookies["key"], # $ tainted request.cookies.get("key"), # $ tainted - request.cookies.keys(), # $ MISSING: tainted - request.cookies.values(), # $ MISSING: tainted - request.cookies.items(), # $ MISSING: tainted + request.cookies.keys(), # $ tainted + request.cookies.values(), # $ tainted + request.cookies.items(), # $ tainted list(request.cookies), # $ tainted - iter(request.cookies), # $ MISSING: tainted + iter(request.cookies), # $ tainted # aiohttp.StreamReader diff --git a/python/ql/test/library-tests/frameworks/multidict/taint_test.py b/python/ql/test/library-tests/frameworks/multidict/taint_test.py index 4410e2b2a6f..77b4f00f271 100644 --- a/python/ql/test/library-tests/frameworks/multidict/taint_test.py +++ b/python/ql/test/library-tests/frameworks/multidict/taint_test.py @@ -12,12 +12,12 @@ ensure_tainted( mdp.get("key"), # $ tainted mdp.getone("key"), # $ tainted mdp.getall("key"), # $ tainted - mdp.keys(), # $ MISSING: tainted - mdp.values(), # $ MISSING: tainted - mdp.items(), # $ MISSING: tainted + mdp.keys(), # $ tainted + mdp.values(), # $ tainted + mdp.items(), # $ tainted mdp.copy(), # $ tainted list(mdp), # $ tainted - iter(mdp), # $ MISSING: tainted + iter(mdp), # $ tainted ) # TODO: This is an invalid CIMultiDictProxy construction... but for the purpose of @@ -32,10 +32,10 @@ ensure_tainted( ci_mdp.get("key"), # $ tainted ci_mdp.getone("key"), # $ tainted ci_mdp.getall("key"), # $ tainted - ci_mdp.keys(), # $ MISSING: tainted - ci_mdp.values(), # $ MISSING: tainted - ci_mdp.items(), # $ MISSING: tainted + ci_mdp.keys(), # $ tainted + ci_mdp.values(), # $ tainted + ci_mdp.items(), # $ tainted ci_mdp.copy(), # $ tainted list(ci_mdp), # $ tainted - iter(ci_mdp), # $ MISSING: tainted + iter(ci_mdp), # $ tainted ) diff --git a/python/ql/test/library-tests/frameworks/stdlib/http_server.py b/python/ql/test/library-tests/frameworks/stdlib/http_server.py index 3dbc832c397..27ec2211f4b 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/http_server.py +++ b/python/ql/test/library-tests/frameworks/stdlib/http_server.py @@ -60,8 +60,8 @@ class MyHandler(BaseHTTPRequestHandler): self.headers.get('Foo'), # $ tainted self.headers.get_all('Foo'), # $ tainted self.headers.keys(), # $ tainted - self.headers.values(), # $ MISSING: tainted - self.headers.items(), # $ MISSING: tainted + self.headers.values(), # $ tainted + self.headers.items(), # $ tainted self.headers.as_bytes(), # $ tainted self.headers.as_string(), # $ tainted str(self.headers), # $ tainted From f1de75340053e523d2813d337f18f35b455aaba0 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Tue, 13 Jun 2023 21:59:51 +0200 Subject: [PATCH 535/739] python: add changenote --- .../ql/lib/change-notes/2023-06-13-container-store-steps.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/lib/change-notes/2023-06-13-container-store-steps.md diff --git a/python/ql/lib/change-notes/2023-06-13-container-store-steps.md b/python/ql/lib/change-notes/2023-06-13-container-store-steps.md new file mode 100644 index 00000000000..1edff243128 --- /dev/null +++ b/python/ql/lib/change-notes/2023-06-13-container-store-steps.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* More precise modelling of several container functions and methods. From ae8bf5ed3c0f29b1d26c156b8688bdc16ed2d8fa Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 12 Jun 2023 11:33:17 +0200 Subject: [PATCH 536/739] delete old deprecations --- .../lib/semmle/python/security/Exceptions.qll | 103 ------ .../ql/lib/semmle/python/security/Paths.qll | 16 - .../python/security/injection/Command.qll | 263 --------------- .../semmle/python/security/injection/Sql.qll | 83 ----- .../semmle/python/security/strings/Basic.qll | 124 ------- .../semmle/python/security/strings/Common.qll | 14 - .../python/security/strings/External.qll | 318 ------------------ .../python/security/strings/Untrusted.qll | 10 - .../semmle/python/web/ClientHttpRequest.qll | 2 - python/ql/lib/semmle/python/web/Http.qll | 119 ------- .../lib/semmle/python/web/HttpConstants.qll | 7 - .../ql/lib/semmle/python/web/HttpRedirect.qll | 7 - .../ql/lib/semmle/python/web/HttpRequest.qll | 10 - .../ql/lib/semmle/python/web/HttpResponse.qll | 10 - .../lib/semmle/python/web/bottle/General.qll | 46 --- .../lib/semmle/python/web/bottle/Redirect.qll | 28 -- .../lib/semmle/python/web/bottle/Request.qll | 80 ----- .../lib/semmle/python/web/bottle/Response.qll | 52 --- .../semmle/python/web/cherrypy/General.qll | 44 --- .../semmle/python/web/cherrypy/Request.qll | 41 --- .../semmle/python/web/cherrypy/Response.qll | 18 - .../lib/semmle/python/web/client/Requests.qll | 22 -- .../lib/semmle/python/web/client/StdLib.qll | 55 --- python/ql/lib/semmle/python/web/django/Db.qll | 50 --- .../lib/semmle/python/web/django/General.qll | 136 -------- .../ql/lib/semmle/python/web/django/Model.qll | 69 ---- .../lib/semmle/python/web/django/Redirect.qll | 37 -- .../lib/semmle/python/web/django/Request.qll | 78 ----- .../lib/semmle/python/web/django/Response.qll | 79 ----- .../semmle/python/web/django/Sanitizers.qll | 6 - .../lib/semmle/python/web/django/Shared.qll | 72 ---- .../lib/semmle/python/web/falcon/General.qll | 46 --- .../lib/semmle/python/web/falcon/Request.qll | 37 -- .../lib/semmle/python/web/falcon/Response.qll | 28 -- .../lib/semmle/python/web/flask/General.qll | 104 ------ .../lib/semmle/python/web/flask/Redirect.qll | 26 -- .../lib/semmle/python/web/flask/Request.qll | 80 ----- .../lib/semmle/python/web/flask/Response.qll | 55 --- .../semmle/python/web/pyramid/Redirect.qll | 33 -- .../lib/semmle/python/web/pyramid/Request.qll | 25 -- .../semmle/python/web/pyramid/Response.qll | 37 -- .../ql/lib/semmle/python/web/pyramid/View.qll | 9 - .../lib/semmle/python/web/stdlib/Request.qll | 126 ------- .../lib/semmle/python/web/stdlib/Response.qll | 43 --- .../semmle/python/web/tornado/Redirect.qll | 28 -- .../lib/semmle/python/web/tornado/Request.qll | 69 ---- .../semmle/python/web/tornado/Response.qll | 47 --- .../lib/semmle/python/web/tornado/Tornado.qll | 50 --- .../semmle/python/web/turbogears/Request.qll | 26 -- .../semmle/python/web/turbogears/Response.qll | 31 -- .../python/web/turbogears/TurboGears.qll | 37 -- .../lib/semmle/python/web/twisted/Request.qll | 30 -- .../semmle/python/web/twisted/Response.qll | 45 --- .../lib/semmle/python/web/twisted/Twisted.qll | 52 --- .../lib/semmle/python/web/webob/Request.qll | 38 --- .../experimental/Security/CWE-074/JinjaBad.py | 19 -- .../Security/CWE-074/JinjaGood.py | 20 -- .../Security/CWE-074/TemplateInjection.qhelp | 24 -- .../Security/CWE-074/TemplateInjection.ql | 35 -- .../experimental/Security/CWE-091/Xslt.qhelp | 18 - .../src/experimental/Security/CWE-091/Xslt.ql | 36 -- .../src/experimental/Security/CWE-091/xslt.py | 14 - .../semmle/python/security/injection/XSLT.qll | 42 --- .../semmle/python/templates/Airspeed.qll | 27 -- .../semmle/python/templates/Bottle.qll | 48 --- .../semmle/python/templates/Chameleon.qll | 29 -- .../semmle/python/templates/Cheetah.qll | 39 --- .../semmle/python/templates/Chevron.qll | 36 -- .../python/templates/DjangoTemplate.qll | 35 -- .../semmle/python/templates/FlaskTemplate.qll | 28 -- .../semmle/python/templates/Genshi.qll | 53 --- .../semmle/python/templates/Jinja.qll | 49 --- .../semmle/python/templates/Mako.qll | 27 -- .../semmle/python/templates/SSTISink.qll | 7 - .../semmle/python/templates/Ssti.qll | 13 - .../semmle/python/templates/TRender.qll | 27 -- .../3/library-tests/taint/strings/Taint.qll | 44 --- .../taint/strings/TestTaint.expected | 1 - .../library-tests/taint/strings/TestTaint.ql | 33 -- .../3/library-tests/taint/strings/test.py | 5 - .../3/library-tests/taint/unpacking/Taint.qll | 27 -- .../taint/unpacking/TestTaint.expected | 9 - .../taint/unpacking/TestTaint.ql | 19 -- .../3/library-tests/taint/unpacking/test.py | 31 -- .../CWE-074/TemplateInjection.expected | 60 ---- .../Security/CWE-074/TemplateInjection.qlref | 1 - .../Security/CWE-091/Xslt.expected | 47 --- .../query-tests/Security/CWE-091/Xslt.qlref | 1 - .../query-tests/Security/CWE-091/xslt.py | 14 - .../semmle/python/templates/Airspeed.py | 10 - .../templates/AirspeedSSTISinks.expected | 2 - .../python/templates/AirspeedSSTISinks.ql | 5 - .../semmle/python/templates/Bottle.py | 17 - .../python/templates/BottleSSTISinks.expected | 3 - .../python/templates/BottleSSTISinks.ql | 5 - .../semmle/python/templates/Chameleon.py | 5 - .../templates/ChameleonSSTISinks.expected | 2 - .../python/templates/ChameleonSSTISinks.ql | 5 - .../templates/CheetahSSTISinks.expected | 3 - .../python/templates/CheetahSSTISinks.ql | 5 - .../semmle/python/templates/CheetahSinks.py | 20 -- .../templates/ChevronSSTISinks.expected | 2 - .../python/templates/ChevronSSTISinks.ql | 5 - .../semmle/python/templates/ChevronSinks.py | 22 -- .../python/templates/DjangoSSTISinks.expected | 2 - .../python/templates/DjangoSSTISinks.ql | 5 - .../python/templates/DjangoTemplates.py | 39 --- .../semmle/python/templates/Genshi.py | 10 - .../python/templates/GenshiSSTISinks.expected | 3 - .../python/templates/GenshiSSTISinks.ql | 5 - .../python/templates/Jinja2Templates.py | 17 - .../python/templates/JinjaSSTISinks.expected | 4 - .../semmle/python/templates/JinjaSSTISinks.ql | 5 - .../semmle/python/templates/Mako.py | 5 - .../python/templates/MakoSSTISinks.expected | 2 - .../semmle/python/templates/MakoSSTISinks.ql | 5 - .../semmle/python/templates/TRender.py | 6 - .../templates/TRenderSSTISinks.expected | 2 - .../python/templates/TRenderSSTISinks.ql | 5 - .../semmle/python/templates/options | 1 - .../custom-sanitizer/SanitizedEdges.expected | 23 -- .../custom-sanitizer/SanitizedEdges.ql | 6 - .../examples/custom-sanitizer/Taint.qll | 77 ----- .../custom-sanitizer/TestTaint.expected | 28 -- .../examples/custom-sanitizer/TestTaint.ql | 31 -- .../examples/custom-sanitizer/test.py | 110 ------ .../command-execution/CommandSinks.expected | 18 - .../command-execution/CommandSinks.ql | 6 - .../security/command-execution/fabric-LICENSE | 22 -- .../command-execution/fabric_v1_test.py | 10 - .../command-execution/fabric_v2_test.py | 33 -- .../security/command-execution/invoke_test.py | 32 -- .../security/command-execution/options | 1 - .../security/fabric-v1-execute/Taint.qll | 24 -- .../fabric-v1-execute/TestTaint.expected | 10 - .../security/fabric-v1-execute/TestTaint.ql | 33 -- .../security/fabric-v1-execute/options | 1 - .../security/fabric-v1-execute/test.py | 28 -- .../library-tests/taint/collections/Taint.qll | 27 -- .../taint/collections/TestStep.expected | 63 ---- .../taint/collections/TestStep.ql | 11 - .../taint/collections/TestTaint.expected | 33 -- .../taint/collections/TestTaint.ql | 19 -- .../library-tests/taint/collections/test.py | 71 ---- .../taint/config/RockPaperScissors.ql | 1 - .../test/library-tests/taint/config/Simple.ql | 1 - .../taint/example/ExampleConfig.ql | 1 - .../exception_traceback/TestNode.expected | 27 -- .../taint/exception_traceback/TestNode.ql | 7 - .../exception_traceback/TestSource.expected | 10 - .../taint/exception_traceback/TestSource.ql | 9 - .../exception_traceback/TestStep.expected | 16 - .../taint/exception_traceback/TestStep.ql | 12 - .../taint/exception_traceback/test.py | 34 -- .../taint/flowpath_regression/Config.qll | 45 --- .../taint/flowpath_regression/Path.expected | 1 - .../taint/flowpath_regression/Path.ql | 6 - .../taint/flowpath_regression/test.py | 22 -- .../taint/namedtuple/SanitizedEdges.expected | 7 - .../taint/namedtuple/SanitizedEdges.ql | 6 - .../library-tests/taint/namedtuple/Taint.qll | 45 --- .../taint/namedtuple/TestTaint.expected | 15 - .../taint/namedtuple/TestTaint.ql | 19 -- .../library-tests/taint/namedtuple/test.py | 44 --- .../library-tests/taint/strings/Taint.qll | 44 --- .../taint/strings/TestStep.expected | 162 --------- .../library-tests/taint/strings/TestStep.ql | 11 - .../taint/strings/TestTaint.expected | 63 ---- .../library-tests/taint/strings/TestTaint.ql | 19 -- .../test/library-tests/taint/strings/test.py | 134 -------- .../library-tests/taint/unpacking/Taint.qll | 27 -- .../taint/unpacking/TestStep.expected | 41 --- .../library-tests/taint/unpacking/TestStep.ql | 11 - .../taint/unpacking/TestTaint.expected | 33 -- .../taint/unpacking/TestTaint.ql | 19 -- .../library-tests/taint/unpacking/test.py | 58 ---- 176 files changed, 5913 deletions(-) delete mode 100644 python/ql/lib/semmle/python/security/Exceptions.qll delete mode 100644 python/ql/lib/semmle/python/security/Paths.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Command.qll delete mode 100644 python/ql/lib/semmle/python/security/injection/Sql.qll delete mode 100644 python/ql/lib/semmle/python/security/strings/Basic.qll delete mode 100644 python/ql/lib/semmle/python/security/strings/Common.qll delete mode 100644 python/ql/lib/semmle/python/security/strings/External.qll delete mode 100644 python/ql/lib/semmle/python/security/strings/Untrusted.qll delete mode 100644 python/ql/lib/semmle/python/web/ClientHttpRequest.qll delete mode 100644 python/ql/lib/semmle/python/web/Http.qll delete mode 100644 python/ql/lib/semmle/python/web/HttpConstants.qll delete mode 100644 python/ql/lib/semmle/python/web/HttpRedirect.qll delete mode 100644 python/ql/lib/semmle/python/web/HttpRequest.qll delete mode 100644 python/ql/lib/semmle/python/web/HttpResponse.qll delete mode 100644 python/ql/lib/semmle/python/web/bottle/General.qll delete mode 100644 python/ql/lib/semmle/python/web/bottle/Redirect.qll delete mode 100644 python/ql/lib/semmle/python/web/bottle/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/bottle/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/cherrypy/General.qll delete mode 100644 python/ql/lib/semmle/python/web/cherrypy/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/cherrypy/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/client/Requests.qll delete mode 100644 python/ql/lib/semmle/python/web/client/StdLib.qll delete mode 100644 python/ql/lib/semmle/python/web/django/Db.qll delete mode 100644 python/ql/lib/semmle/python/web/django/General.qll delete mode 100644 python/ql/lib/semmle/python/web/django/Model.qll delete mode 100644 python/ql/lib/semmle/python/web/django/Redirect.qll delete mode 100644 python/ql/lib/semmle/python/web/django/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/django/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/django/Sanitizers.qll delete mode 100644 python/ql/lib/semmle/python/web/django/Shared.qll delete mode 100644 python/ql/lib/semmle/python/web/falcon/General.qll delete mode 100644 python/ql/lib/semmle/python/web/falcon/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/falcon/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/flask/General.qll delete mode 100644 python/ql/lib/semmle/python/web/flask/Redirect.qll delete mode 100644 python/ql/lib/semmle/python/web/flask/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/flask/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/pyramid/Redirect.qll delete mode 100644 python/ql/lib/semmle/python/web/pyramid/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/pyramid/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/pyramid/View.qll delete mode 100644 python/ql/lib/semmle/python/web/stdlib/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/stdlib/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/tornado/Redirect.qll delete mode 100644 python/ql/lib/semmle/python/web/tornado/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/tornado/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/tornado/Tornado.qll delete mode 100644 python/ql/lib/semmle/python/web/turbogears/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/turbogears/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/turbogears/TurboGears.qll delete mode 100644 python/ql/lib/semmle/python/web/twisted/Request.qll delete mode 100644 python/ql/lib/semmle/python/web/twisted/Response.qll delete mode 100644 python/ql/lib/semmle/python/web/twisted/Twisted.qll delete mode 100644 python/ql/lib/semmle/python/web/webob/Request.qll delete mode 100644 python/ql/src/experimental/Security/CWE-074/JinjaBad.py delete mode 100644 python/ql/src/experimental/Security/CWE-074/JinjaGood.py delete mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp delete mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql delete mode 100644 python/ql/src/experimental/Security/CWE-091/Xslt.qhelp delete mode 100644 python/ql/src/experimental/Security/CWE-091/Xslt.ql delete mode 100644 python/ql/src/experimental/Security/CWE-091/xslt.py delete mode 100644 python/ql/src/experimental/semmle/python/templates/Airspeed.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/Bottle.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/Chameleon.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/Cheetah.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/Chevron.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/DjangoTemplate.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/FlaskTemplate.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/Genshi.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/Jinja.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/Mako.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/SSTISink.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/Ssti.qll delete mode 100644 python/ql/src/experimental/semmle/python/templates/TRender.qll delete mode 100644 python/ql/test/3/library-tests/taint/strings/Taint.qll delete mode 100644 python/ql/test/3/library-tests/taint/strings/TestTaint.expected delete mode 100644 python/ql/test/3/library-tests/taint/strings/TestTaint.ql delete mode 100644 python/ql/test/3/library-tests/taint/strings/test.py delete mode 100644 python/ql/test/3/library-tests/taint/unpacking/Taint.qll delete mode 100644 python/ql/test/3/library-tests/taint/unpacking/TestTaint.expected delete mode 100644 python/ql/test/3/library-tests/taint/unpacking/TestTaint.ql delete mode 100644 python/ql/test/3/library-tests/taint/unpacking/test.py delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.expected delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.qlref delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.expected delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.qlref delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-091/xslt.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/Airspeed.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/Bottle.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/Chameleon.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/CheetahSinks.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/ChevronSinks.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/DjangoTemplates.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/Genshi.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/Jinja2Templates.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/Mako.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/TRender.py delete mode 100644 python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.expected delete mode 100644 python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.ql delete mode 100644 python/ql/test/experimental/semmle/python/templates/options delete mode 100644 python/ql/test/library-tests/examples/custom-sanitizer/SanitizedEdges.expected delete mode 100644 python/ql/test/library-tests/examples/custom-sanitizer/SanitizedEdges.ql delete mode 100644 python/ql/test/library-tests/examples/custom-sanitizer/Taint.qll delete mode 100644 python/ql/test/library-tests/examples/custom-sanitizer/TestTaint.expected delete mode 100644 python/ql/test/library-tests/examples/custom-sanitizer/TestTaint.ql delete mode 100644 python/ql/test/library-tests/examples/custom-sanitizer/test.py delete mode 100644 python/ql/test/library-tests/security/command-execution/CommandSinks.expected delete mode 100644 python/ql/test/library-tests/security/command-execution/CommandSinks.ql delete mode 100644 python/ql/test/library-tests/security/command-execution/fabric-LICENSE delete mode 100644 python/ql/test/library-tests/security/command-execution/fabric_v1_test.py delete mode 100644 python/ql/test/library-tests/security/command-execution/fabric_v2_test.py delete mode 100644 python/ql/test/library-tests/security/command-execution/invoke_test.py delete mode 100644 python/ql/test/library-tests/security/command-execution/options delete mode 100644 python/ql/test/library-tests/security/fabric-v1-execute/Taint.qll delete mode 100644 python/ql/test/library-tests/security/fabric-v1-execute/TestTaint.expected delete mode 100644 python/ql/test/library-tests/security/fabric-v1-execute/TestTaint.ql delete mode 100644 python/ql/test/library-tests/security/fabric-v1-execute/options delete mode 100644 python/ql/test/library-tests/security/fabric-v1-execute/test.py delete mode 100644 python/ql/test/library-tests/taint/collections/Taint.qll delete mode 100644 python/ql/test/library-tests/taint/collections/TestStep.expected delete mode 100644 python/ql/test/library-tests/taint/collections/TestStep.ql delete mode 100644 python/ql/test/library-tests/taint/collections/TestTaint.expected delete mode 100644 python/ql/test/library-tests/taint/collections/TestTaint.ql delete mode 100644 python/ql/test/library-tests/taint/collections/test.py delete mode 100644 python/ql/test/library-tests/taint/exception_traceback/TestNode.expected delete mode 100644 python/ql/test/library-tests/taint/exception_traceback/TestNode.ql delete mode 100644 python/ql/test/library-tests/taint/exception_traceback/TestSource.expected delete mode 100644 python/ql/test/library-tests/taint/exception_traceback/TestSource.ql delete mode 100644 python/ql/test/library-tests/taint/exception_traceback/TestStep.expected delete mode 100644 python/ql/test/library-tests/taint/exception_traceback/TestStep.ql delete mode 100644 python/ql/test/library-tests/taint/exception_traceback/test.py delete mode 100644 python/ql/test/library-tests/taint/flowpath_regression/Config.qll delete mode 100644 python/ql/test/library-tests/taint/flowpath_regression/Path.expected delete mode 100644 python/ql/test/library-tests/taint/flowpath_regression/Path.ql delete mode 100644 python/ql/test/library-tests/taint/flowpath_regression/test.py delete mode 100644 python/ql/test/library-tests/taint/namedtuple/SanitizedEdges.expected delete mode 100644 python/ql/test/library-tests/taint/namedtuple/SanitizedEdges.ql delete mode 100644 python/ql/test/library-tests/taint/namedtuple/Taint.qll delete mode 100644 python/ql/test/library-tests/taint/namedtuple/TestTaint.expected delete mode 100644 python/ql/test/library-tests/taint/namedtuple/TestTaint.ql delete mode 100644 python/ql/test/library-tests/taint/namedtuple/test.py delete mode 100644 python/ql/test/library-tests/taint/strings/Taint.qll delete mode 100644 python/ql/test/library-tests/taint/strings/TestStep.expected delete mode 100644 python/ql/test/library-tests/taint/strings/TestStep.ql delete mode 100644 python/ql/test/library-tests/taint/strings/TestTaint.expected delete mode 100644 python/ql/test/library-tests/taint/strings/TestTaint.ql delete mode 100644 python/ql/test/library-tests/taint/strings/test.py delete mode 100644 python/ql/test/library-tests/taint/unpacking/Taint.qll delete mode 100644 python/ql/test/library-tests/taint/unpacking/TestStep.expected delete mode 100644 python/ql/test/library-tests/taint/unpacking/TestStep.ql delete mode 100644 python/ql/test/library-tests/taint/unpacking/TestTaint.expected delete mode 100644 python/ql/test/library-tests/taint/unpacking/TestTaint.ql delete mode 100644 python/ql/test/library-tests/taint/unpacking/test.py diff --git a/python/ql/lib/semmle/python/security/Exceptions.qll b/python/ql/lib/semmle/python/security/Exceptions.qll deleted file mode 100644 index a335d4e3c35..00000000000 --- a/python/ql/lib/semmle/python/security/Exceptions.qll +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Provides classes and predicates for tracking exceptions and information - * associated with exceptions. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic - -deprecated private Value traceback_function(string name) { - result = Module::named("traceback").attr(name) -} - -/** - * This represents information relating to an exception, for instance the - * message, arguments or parts of the exception traceback. - */ -deprecated class ExceptionInfo extends StringKind { - ExceptionInfo() { this = "exception.info" } - - override string repr() { result = "exception info" } -} - -/** - * A class representing sources of information about - * execution state exposed in tracebacks and the like. - */ -abstract deprecated class ErrorInfoSource extends TaintSource { } - -/** - * This kind represents exceptions themselves. - */ -deprecated class ExceptionKind extends TaintKind { - ExceptionKind() { this = "exception.kind" } - - override string repr() { result = "exception" } - - override TaintKind getTaintOfAttribute(string name) { - name = "args" and result instanceof ExceptionInfoSequence - or - name = "message" and result instanceof ExceptionInfo - } -} - -/** - * A source of exception objects, either explicitly created, or captured by an - * `except` statement. - */ -deprecated class ExceptionSource extends ErrorInfoSource { - ExceptionSource() { - exists(ClassValue cls | - cls.getASuperType() = ClassValue::baseException() and - this.(ControlFlowNode).pointsTo().getClass() = cls - ) - or - this = any(ExceptStmt s).getName().getAFlowNode() - } - - override string toString() { result = "exception.source" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionKind } -} - -/** - * Represents a sequence of pieces of information relating to an exception, - * for instance the contents of the `args` attribute, or the stack trace. - */ -deprecated class ExceptionInfoSequence extends SequenceKind { - ExceptionInfoSequence() { this.getItem() instanceof ExceptionInfo } -} - -/** - * Represents calls to functions in the `traceback` module that return - * sequences of exception information. - */ -deprecated class CallToTracebackFunction extends ErrorInfoSource { - CallToTracebackFunction() { - exists(string name | - name in [ - "extract_tb", "extract_stack", "format_list", "format_exception_only", "format_exception", - "format_tb", "format_stack" - ] - | - this = traceback_function(name).getACall() - ) - } - - override string toString() { result = "exception.info.sequence.source" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfoSequence } -} - -/** - * Represents calls to functions in the `traceback` module that return a single - * string of information about an exception. - */ -deprecated class FormattedTracebackSource extends ErrorInfoSource { - FormattedTracebackSource() { this = traceback_function("format_exc").getACall() } - - override string toString() { result = "exception.info.source" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo } -} diff --git a/python/ql/lib/semmle/python/security/Paths.qll b/python/ql/lib/semmle/python/security/Paths.qll deleted file mode 100644 index 9288a1eff61..00000000000 --- a/python/ql/lib/semmle/python/security/Paths.qll +++ /dev/null @@ -1,16 +0,0 @@ -import semmle.python.dataflow.Implementation - -deprecated module TaintTrackingPaths { - predicate edge(TaintTrackingNode src, TaintTrackingNode dest, string label) { - exists(TaintTrackingNode source, TaintTrackingNode sink | - source.getConfiguration().hasFlowPath(source, sink) and - source.getASuccessor*() = src and - src.getASuccessor(label) = dest and - dest.getASuccessor*() = sink - ) - } -} - -deprecated query predicate edges(TaintTrackingNode fromnode, TaintTrackingNode tonode) { - TaintTrackingPaths::edge(fromnode, tonode, _) -} diff --git a/python/ql/lib/semmle/python/security/injection/Command.qll b/python/ql/lib/semmle/python/security/injection/Command.qll deleted file mode 100644 index b8ae8b94563..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Command.qll +++ /dev/null @@ -1,263 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious OS commands. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -/** Abstract taint sink that is potentially vulnerable to malicious shell commands. */ -abstract deprecated class CommandSink extends TaintSink { } - -deprecated private ModuleObject osOrPopenModule() { result.getName() = ["os", "popen2"] } - -deprecated private Object makeOsCall() { - exists(string name | result = ModuleObject::named("subprocess").attr(name) | - name = ["Popen", "call", "check_call", "check_output", "run"] - ) -} - -/**Special case for first element in sequence. */ -deprecated class FirstElementKind extends TaintKind { - FirstElementKind() { this = "sequence[" + any(ExternalStringKind key) + "][0]" } - - override string repr() { result = "first item in sequence of " + this.getItem().repr() } - - /** Gets the taint kind for item in this sequence. */ - ExternalStringKind getItem() { this = "sequence[" + result + "][0]" } -} - -deprecated class FirstElementFlow extends DataFlowExtension::DataFlowNode { - FirstElementFlow() { this = any(SequenceNode s).getElement(0) } - - override ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) { - result.(SequenceNode).getElement(0) = this and tokind.(FirstElementKind).getItem() = fromkind - } -} - -/** - * A taint sink that is potentially vulnerable to malicious shell commands. - * The `vuln` in `subprocess.call(shell=vuln)` and similar calls. - */ -deprecated class ShellCommand extends CommandSink { - override string toString() { result = "shell command" } - - ShellCommand() { - exists(CallNode call, Object istrue | - call.getFunction().refersTo(makeOsCall()) and - call.getAnArg() = this and - call.getArgByName("shell").refersTo(istrue) and - istrue.booleanValue() = true - ) - or - exists(CallNode call, string name | - call.getAnArg() = this and - call.getFunction().refersTo(osOrPopenModule().attr(name)) - | - name = ["system", "popen"] or - name.matches("popen_") - ) - or - exists(CallNode call | - call.getAnArg() = this and - call.getFunction().refersTo(ModuleObject::named("commands")) - ) - } - - override predicate sinks(TaintKind kind) { - /* Tainted string command */ - kind instanceof ExternalStringKind - or - /* List (or tuple) containing a tainted string command */ - kind instanceof ExternalStringSequenceKind - } -} - -/** - * A taint sink that is potentially vulnerable to malicious shell commands. - * The `vuln` in `subprocess.call(vuln, ...)` and similar calls. - */ -deprecated class OsCommandFirstArgument extends CommandSink { - override string toString() { result = "OS command first argument" } - - OsCommandFirstArgument() { - not this instanceof ShellCommand and - exists(CallNode call | - call.getFunction().refersTo(makeOsCall()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { - /* Tainted string command */ - kind instanceof ExternalStringKind - or - /* List (or tuple) whose first element is tainted */ - kind instanceof FirstElementKind - } -} - -// -------------------------------------------------------------------------- // -// Modeling of the 'invoke' package and 'fabric' package (v 2.x) -// -// Since fabric build so closely upon invoke, we model them together to avoid -// duplication -// -------------------------------------------------------------------------- // -/** - * A taint sink that is potentially vulnerable to malicious shell commands. - * The `vuln` in `invoke.run(vuln, ...)` and similar calls. - */ -deprecated class InvokeRun extends CommandSink { - InvokeRun() { - this = Value::named("invoke.run").(FunctionValue).getArgumentForCall(_, 0) - or - this = Value::named("invoke.sudo").(FunctionValue).getArgumentForCall(_, 0) - } - - override string toString() { result = "InvokeRun" } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -/** - * Internal TaintKind to track the invoke.Context instance passed to functions - * marked with @invoke.task - */ -deprecated private class InvokeContextArg extends TaintKind { - InvokeContextArg() { this = "InvokeContextArg" } -} - -/** Internal TaintSource to track the context passed to functions marked with @invoke.task */ -deprecated private class InvokeContextArgSource extends TaintSource { - InvokeContextArgSource() { - exists(Function f, Expr decorator | - count(f.getADecorator()) = 1 and - ( - decorator = f.getADecorator() and not decorator instanceof Call - or - decorator = f.getADecorator().(Call).getFunc() - ) and - ( - decorator.pointsTo(Value::named("invoke.task")) - or - decorator.pointsTo(Value::named("fabric.task")) - ) - | - this.(ControlFlowNode).getNode() = f.getArg(0) - ) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof InvokeContextArg } -} - -/** - * A taint sink that is potentially vulnerable to malicious shell commands. - * The `vuln` in `invoke.Context().run(vuln, ...)` and similar calls. - */ -deprecated class InvokeContextRun extends CommandSink { - InvokeContextRun() { - exists(CallNode call | - any(InvokeContextArg k).taints(call.getFunction().(AttrNode).getObject("run")) - or - call = Value::named("invoke.Context").(ClassValue).lookup("run").getACall() - or - // fabric.connection.Connection is a subtype of invoke.context.Context - // since fabric.Connection.run has a decorator, it doesn't work with FunctionValue :| - // and `Value::named("fabric.Connection").(ClassValue).lookup("run").getACall()` returned no results, - // so here is the hacky solution that works :\ - call.getFunction().(AttrNode).getObject("run").pointsTo().getClass() = - Value::named("fabric.Connection") - | - this = call.getArg(0) - or - this = call.getArgByName("command") - ) - } - - override string toString() { result = "InvokeContextRun" } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -/** - * A taint sink that is potentially vulnerable to malicious shell commands. - * The `vuln` in `fabric.Group().run(vuln, ...)` and similar calls. - */ -deprecated class FabricGroupRun extends CommandSink { - FabricGroupRun() { - exists(ClassValue cls | - cls.getASuperType() = Value::named("fabric.Group") and - this = cls.lookup("run").(FunctionValue).getArgumentForCall(_, 1) - ) - } - - override string toString() { result = "FabricGroupRun" } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -// -------------------------------------------------------------------------- // -// Modeling of the 'invoke' package and 'fabric' package (v 1.x) -// -------------------------------------------------------------------------- // -deprecated class FabricV1Commands extends CommandSink { - FabricV1Commands() { - // since `run` and `sudo` are decorated, we can't use FunctionValue's :( - exists(CallNode call | - call = Value::named("fabric.api.local").getACall() - or - call = Value::named("fabric.api.run").getACall() - or - call = Value::named("fabric.api.sudo").getACall() - | - this = call.getArg(0) - or - this = call.getArgByName("command") - ) - } - - override string toString() { result = "FabricV1Commands" } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -/** - * An extension that propagates taint from the arguments of `fabric.api.execute(func, arg0, arg1, ...)` - * to the parameters of `func`, since this will call `func(arg0, arg1, ...)`. - */ -deprecated class FabricExecuteExtension extends DataFlowExtension::DataFlowNode { - CallNode call; - - FabricExecuteExtension() { - call = Value::named("fabric.api.execute").getACall() and - ( - this = call.getArg(any(int i | i > 0)) - or - this = call.getArgByName(any(string s | not s = "task")) - ) - } - - override ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) { - tokind = fromkind and - exists(CallableValue func | - ( - call.getArg(0).pointsTo(func) - or - call.getArgByName("task").pointsTo(func) - ) and - exists(int i | - // execute(func, arg0, arg1) => func(arg0, arg1) - this = call.getArg(i) and - result = func.getParameter(i - 1) - ) - or - exists(string name | - this = call.getArgByName(name) and - result = func.getParameterByName(name) - ) - ) - } -} diff --git a/python/ql/lib/semmle/python/security/injection/Sql.qll b/python/ql/lib/semmle/python/security/injection/Sql.qll deleted file mode 100644 index b2e2cd47715..00000000000 --- a/python/ql/lib/semmle/python/security/injection/Sql.qll +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious SQL queries or parts of queries. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.security.SQL - -deprecated private StringObject first_part(ControlFlowNode command) { - command.(BinaryExprNode).getOp() instanceof Add and - command.(BinaryExprNode).getLeft().refersTo(result) - or - exists(CallNode call, SequenceObject seq | call = command | - call = theStrType().lookupAttribute("join") and - call.getArg(0).refersTo(seq) and - seq.getInferredElement(0) = result - ) - or - command.(BinaryExprNode).getOp() instanceof Mod and - command.getNode().(StrConst).getLiteralObject() = result -} - -/** Holds if `command` appears to be a SQL command string of which `inject` is a part. */ -deprecated predicate probable_sql_command(ControlFlowNode command, ControlFlowNode inject) { - exists(string prefix | - inject = command.getAChild*() and - first_part(command).getText().regexpMatch(" *" + prefix + ".*") - | - prefix = "CREATE" or prefix = "SELECT" - ) -} - -/** - * A taint kind representing a DB cursor. - * This will be overridden to provide specific kinds of DB cursor. - */ -abstract deprecated class DbCursor extends TaintKind { - bindingset[this] - DbCursor() { any() } - - string getExecuteMethodName() { result = "execute" } -} - -/** - * A part of a string that appears to be a SQL command and is thus - * vulnerable to malicious input. - */ -deprecated class SimpleSqlStringInjection extends SqlInjectionSink { - override string toString() { result = "simple SQL string injection" } - - SimpleSqlStringInjection() { probable_sql_command(_, this) } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -/** - * A taint source representing sources of DB connections. - * This will be overridden to provide specific kinds of DB connection sources. - */ -abstract deprecated class DbConnectionSource extends TaintSource { } - -/** - * A taint sink that is vulnerable to malicious SQL queries. - * The `vuln` in `db.connection.execute(vuln)` and similar. - */ -deprecated class DbConnectionExecuteArgument extends SqlInjectionSink { - override string toString() { result = "db.connection.execute" } - - DbConnectionExecuteArgument() { - exists(CallNode call, DbCursor cursor, string name | - cursor.taints(call.getFunction().(AttrNode).getObject(name)) and - cursor.getExecuteMethodName() = name and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/lib/semmle/python/security/strings/Basic.qll b/python/ql/lib/semmle/python/security/strings/Basic.qll deleted file mode 100644 index 6bbae862c32..00000000000 --- a/python/ql/lib/semmle/python/security/strings/Basic.qll +++ /dev/null @@ -1,124 +0,0 @@ -import python -private import Common -import semmle.python.dataflow.TaintTracking - -/** An extensible kind of taint representing any kind of string. */ -abstract deprecated class StringKind extends TaintKind { - bindingset[this] - StringKind() { this = this } - - override TaintKind getTaintOfMethodResult(string name) { - name in [ - "capitalize", "casefold", "center", "expandtabs", "format", "format_map", "ljust", "lstrip", - "lower", "replace", "rjust", "rstrip", "strip", "swapcase", "title", "upper", "zfill", - /* encode/decode is technically not correct, but close enough */ - "encode", "decode" - ] and - result = this - or - name in ["partition", "rpartition", "rsplit", "split", "splitlines"] and - result.(SequenceKind).getItem() = this - } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - result = this and - ( - slice(fromnode, tonode) or - tonode.(BinaryExprNode).getAnOperand() = fromnode or - os_path_join(fromnode, tonode) or - str_format(fromnode, tonode) or - encode_decode(fromnode, tonode) or - to_str(fromnode, tonode) or - f_string(fromnode, tonode) - ) - or - result = this and copy_call(fromnode, tonode) - } - - override ClassValue getType() { - result = Value::named("bytes") or - result = Value::named("str") or - result = Value::named("unicode") - } -} - -deprecated private class StringEqualitySanitizer extends Sanitizer { - StringEqualitySanitizer() { this = "string equality sanitizer" } - - /* The test `if untrusted == "KNOWN_VALUE":` sanitizes `untrusted` on its `true` edge. */ - override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { - taint instanceof StringKind and - exists(ControlFlowNode const, Cmpop op | const.getNode() instanceof StrConst | - ( - test.getTest().(CompareNode).operands(const, op, _) - or - test.getTest().(CompareNode).operands(_, op, const) - ) and - ( - op instanceof Eq and test.getSense() = true - or - op instanceof NotEq and test.getSense() = false - ) - ) - } -} - -/** tonode = ....format(fromnode) */ -deprecated private predicate str_format(ControlFlowNode fromnode, CallNode tonode) { - tonode.getFunction().(AttrNode).getName() = "format" and - tonode.getAnArg() = fromnode -} - -/** tonode = codec.[en|de]code(fromnode) */ -deprecated private predicate encode_decode(ControlFlowNode fromnode, CallNode tonode) { - exists(FunctionObject func, string name | - not func.getFunction().isMethod() and - func.getACall() = tonode and - tonode.getAnArg() = fromnode and - func.getName() = name - | - name = "encode" or - name = "decode" or - name = "decodestring" - ) -} - -/** tonode = str(fromnode) */ -deprecated private predicate to_str(ControlFlowNode fromnode, CallNode tonode) { - tonode.getAnArg() = fromnode and - ( - tonode = ClassValue::bytes().getACall() - or - tonode = ClassValue::unicode().getACall() - ) -} - -/** tonode = fromnode[:] */ -deprecated private predicate slice(ControlFlowNode fromnode, SubscriptNode tonode) { - exists(Slice all | - all = tonode.getIndex().getNode() and - not exists(all.getStart()) and - not exists(all.getStop()) and - tonode.getObject() = fromnode - ) -} - -/** tonode = os.path.join(..., fromnode, ...) */ -deprecated private predicate os_path_join(ControlFlowNode fromnode, CallNode tonode) { - tonode = Value::named("os.path.join").getACall() and - tonode.getAnArg() = fromnode -} - -/** tonode = f"... {fromnode} ..." */ -deprecated private predicate f_string(ControlFlowNode fromnode, ControlFlowNode tonode) { - tonode.getNode().(Fstring).getAValue() = fromnode.getNode() -} - -/** - * A kind of "taint", representing a dictionary mapping str->"taint" - * - * DEPRECATED: Use `ExternalStringDictKind` instead. - */ -deprecated class StringDictKind extends DictKind { - StringDictKind() { this.getValue() instanceof StringKind } -} diff --git a/python/ql/lib/semmle/python/security/strings/Common.qll b/python/ql/lib/semmle/python/security/strings/Common.qll deleted file mode 100644 index cb19fdd5461..00000000000 --- a/python/ql/lib/semmle/python/security/strings/Common.qll +++ /dev/null @@ -1,14 +0,0 @@ -import python - -/** A call that returns a copy (or similar) of the argument */ -deprecated predicate copy_call(ControlFlowNode fromnode, CallNode tonode) { - tonode.getFunction().(AttrNode).getObject("copy") = fromnode - or - exists(ModuleValue copy, string name | name = "copy" or name = "deepcopy" | - copy.attr(name).(FunctionValue).getACall() = tonode and - tonode.getArg(0) = fromnode - ) - or - tonode.getFunction().pointsTo(Value::named("reversed")) and - tonode.getArg(0) = fromnode -} diff --git a/python/ql/lib/semmle/python/security/strings/External.qll b/python/ql/lib/semmle/python/security/strings/External.qll deleted file mode 100644 index a5116e42e4e..00000000000 --- a/python/ql/lib/semmle/python/security/strings/External.qll +++ /dev/null @@ -1,318 +0,0 @@ -import python -import Basic -private import Common - -/** - * An extensible kind of taint representing an externally controlled string. - */ -abstract deprecated class ExternalStringKind extends StringKind { - bindingset[this] - ExternalStringKind() { this = this } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - result = StringKind.super.getTaintForFlowStep(fromnode, tonode) - or - tonode.(SequenceNode).getElement(_) = fromnode and - result.(ExternalStringSequenceKind).getItem() = this - or - json_load(fromnode, tonode) and result.(ExternalJsonKind).getValue() = this - or - tonode.(DictNode).getAValue() = fromnode and result.(ExternalStringDictKind).getValue() = this - or - urlsplit(fromnode, tonode) and result.(ExternalUrlSplitResult).getItem() = this - or - urlparse(fromnode, tonode) and result.(ExternalUrlParseResult).getItem() = this - or - parse_qs(fromnode, tonode) and result.(ExternalStringDictKind).getValue() = this - or - parse_qsl(fromnode, tonode) and result.(SequenceKind).getItem().(SequenceKind).getItem() = this - } -} - -/** A kind of "taint", representing a sequence, with a "taint" member */ -deprecated class ExternalStringSequenceKind extends SequenceKind { - ExternalStringSequenceKind() { this.getItem() instanceof ExternalStringKind } -} - -/** - * An hierarchical dictionary or list where the entire structure is externally controlled - * This is typically a parsed JSON object. - */ -deprecated class ExternalJsonKind extends TaintKind { - ExternalJsonKind() { this = "json[" + any(ExternalStringKind key) + "]" } - - /** Gets the taint kind for item in this sequence */ - TaintKind getValue() { - this = "json[" + result + "]" - or - result = this - } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - this.taints(fromnode) and - json_subscript_taint(tonode, fromnode, this, result) - or - result = this and copy_call(fromnode, tonode) - } - - override TaintKind getTaintOfMethodResult(string name) { - name = "get" and result = this.getValue() - } -} - -/** A kind of "taint", representing a dictionary mapping keys to tainted strings. */ -deprecated class ExternalStringDictKind extends DictKind { - ExternalStringDictKind() { this.getValue() instanceof ExternalStringKind } -} - -/** - * A kind of "taint", representing a dictionary mapping keys to sequences of - * tainted strings. - */ -deprecated class ExternalStringSequenceDictKind extends DictKind { - ExternalStringSequenceDictKind() { this.getValue() instanceof ExternalStringSequenceKind } -} - -/** TaintKind for the result of `urlsplit(tainted_string)` */ -deprecated class ExternalUrlSplitResult extends ExternalStringSequenceKind { - // https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlsplit - override TaintKind getTaintOfAttribute(string name) { - result = super.getTaintOfAttribute(name) - or - name in [ - // namedtuple field names - "scheme", "netloc", "path", "query", "fragment", - // class methods - "password", "username", "hostname", - ] and - result instanceof ExternalStringKind - } - - override TaintKind getTaintOfMethodResult(string name) { - result = super.getTaintOfMethodResult(name) - or - name = "geturl" and - result instanceof ExternalStringKind - } -} - -/** TaintKind for the result of `urlparse(tainted_string)` */ -deprecated class ExternalUrlParseResult extends ExternalStringSequenceKind { - // https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlparse - override TaintKind getTaintOfAttribute(string name) { - result = super.getTaintOfAttribute(name) - or - name in [ - // namedtuple field names - "scheme", "netloc", "path", "params", "query", "fragment", - // class methods - "username", "password", "hostname", - ] and - result instanceof ExternalStringKind - } - - override TaintKind getTaintOfMethodResult(string name) { - result = super.getTaintOfMethodResult(name) - or - name = "geturl" and - result instanceof ExternalStringKind - } -} - -/* Helper for getTaintForStep() */ -pragma[noinline] -deprecated private predicate json_subscript_taint( - SubscriptNode sub, ControlFlowNode obj, ExternalJsonKind seq, TaintKind key -) { - sub.isLoad() and - sub.getObject() = obj and - key = seq.getValue() -} - -deprecated private predicate json_load(ControlFlowNode fromnode, CallNode tonode) { - tonode = Value::named("json.loads").getACall() and - tonode.getArg(0) = fromnode -} - -deprecated private predicate urlsplit(ControlFlowNode fromnode, CallNode tonode) { - // This could be implemented as `exists(FunctionValue` without the explicit six part, - // but then our tests will need to import +100 modules, so for now this slightly - // altered version gets to live on. - exists(Value urlsplit | - ( - urlsplit = Value::named("six.moves.urllib.parse.urlsplit") - or - // Python 2 - urlsplit = Value::named("urlparse.urlsplit") - or - // Python 3 - urlsplit = Value::named("urllib.parse.urlsplit") - ) and - tonode = urlsplit.getACall() and - tonode.getArg(0) = fromnode - ) -} - -deprecated private predicate urlparse(ControlFlowNode fromnode, CallNode tonode) { - // This could be implemented as `exists(FunctionValue` without the explicit six part, - // but then our tests will need to import +100 modules, so for now this slightly - // altered version gets to live on. - exists(Value urlparse | - ( - urlparse = Value::named("six.moves.urllib.parse.urlparse") - or - // Python 2 - urlparse = Value::named("urlparse.urlparse") - or - // Python 3 - urlparse = Value::named("urllib.parse.urlparse") - ) and - tonode = urlparse.getACall() and - tonode.getArg(0) = fromnode - ) -} - -deprecated private predicate parse_qs(ControlFlowNode fromnode, CallNode tonode) { - // This could be implemented as `exists(FunctionValue` without the explicit six part, - // but then our tests will need to import +100 modules, so for now this slightly - // altered version gets to live on. - exists(Value parse_qs | - ( - parse_qs = Value::named("six.moves.urllib.parse.parse_qs") - or - // Python 2 - parse_qs = Value::named("urlparse.parse_qs") - or - // Python 2 deprecated version of `urlparse.parse_qs` - parse_qs = Value::named("cgi.parse_qs") - or - // Python 3 - parse_qs = Value::named("urllib.parse.parse_qs") - ) and - tonode = parse_qs.getACall() and - ( - tonode.getArg(0) = fromnode - or - tonode.getArgByName("qs") = fromnode - ) - ) -} - -deprecated private predicate parse_qsl(ControlFlowNode fromnode, CallNode tonode) { - // This could be implemented as `exists(FunctionValue` without the explicit six part, - // but then our tests will need to import +100 modules, so for now this slightly - // altered version gets to live on. - exists(Value parse_qsl | - ( - parse_qsl = Value::named("six.moves.urllib.parse.parse_qsl") - or - // Python 2 - parse_qsl = Value::named("urlparse.parse_qsl") - or - // Python 2 deprecated version of `urlparse.parse_qsl` - parse_qsl = Value::named("cgi.parse_qsl") - or - // Python 3 - parse_qsl = Value::named("urllib.parse.parse_qsl") - ) and - tonode = parse_qsl.getACall() and - ( - tonode.getArg(0) = fromnode - or - tonode.getArgByName("qs") = fromnode - ) - ) -} - -/** A kind of "taint", representing an open file-like object from an external source. */ -deprecated class ExternalFileObject extends TaintKind { - ExternalStringKind valueKind; - - ExternalFileObject() { this = "file[" + valueKind + "]" } - - /** Gets the taint kind for the contents of this file */ - TaintKind getValue() { result = valueKind } - - override TaintKind getTaintOfMethodResult(string name) { - name in ["read", "readline"] and result = this.getValue() - or - name = "readlines" and result.(SequenceKind).getItem() = this.getValue() - } - - override TaintKind getTaintForIteration() { result = this.getValue() } -} - -/** - * Temporary sanitizer for the tainted result from `urlsplit` and `urlparse`. Can be used to reduce FPs until - * we have better support for namedtuples. - * - * Will clear **all** taint on a test of the kind. That is, on the true edge of any matching test, - * all fields/indexes will be cleared of taint. - * - * Handles: - * - `if splitres.netloc == "KNOWN_VALUE"` - * - `if splitres[0] == "KNOWN_VALUE"` - */ -deprecated class UrlsplitUrlparseTempSanitizer extends Sanitizer { - // TODO: remove this once we have better support for named tuples - UrlsplitUrlparseTempSanitizer() { this = "UrlsplitUrlparseTempSanitizer" } - - override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { - ( - taint instanceof ExternalUrlSplitResult - or - taint instanceof ExternalUrlParseResult - ) and - exists(ControlFlowNode full_use | - full_use.(SubscriptNode).getObject() = test.getInput().getAUse() - or - full_use.(AttrNode).getObject() = test.getInput().getAUse() - | - this.clears_taint(full_use, test.getTest(), test.getSense()) - ) - } - - private predicate clears_taint(ControlFlowNode tainted, ControlFlowNode test, boolean sense) { - this.test_equality_with_const(test, tainted, sense) - or - this.test_in_const_seq(test, tainted, sense) - or - test.(UnaryExprNode).getNode().getOp() instanceof Not and - exists(ControlFlowNode nested_test | - nested_test = test.(UnaryExprNode).getOperand() and - this.clears_taint(tainted, nested_test, sense.booleanNot()) - ) - } - - /** holds for `== "KNOWN_VALUE"` on `true` edge, and `!= "KNOWN_VALUE"` on `false` edge */ - private predicate test_equality_with_const(CompareNode cmp, ControlFlowNode tainted, boolean sense) { - exists(ControlFlowNode const, Cmpop op | const.getNode() instanceof StrConst | - ( - cmp.operands(const, op, tainted) - or - cmp.operands(tainted, op, const) - ) and - ( - op instanceof Eq and sense = true - or - op instanceof NotEq and sense = false - ) - ) - } - - /** holds for `in ["KNOWN_VALUE", ...]` on `true` edge, and `not in ["KNOWN_VALUE", ...]` on `false` edge */ - private predicate test_in_const_seq(CompareNode cmp, ControlFlowNode tainted, boolean sense) { - exists(SequenceNode const_seq, Cmpop op | - forall(ControlFlowNode elem | elem = const_seq.getAnElement() | - elem.getNode() instanceof StrConst - ) - | - cmp.operands(tainted, op, const_seq) and - ( - op instanceof In and sense = true - or - op instanceof NotIn and sense = false - ) - ) - } -} diff --git a/python/ql/lib/semmle/python/security/strings/Untrusted.qll b/python/ql/lib/semmle/python/security/strings/Untrusted.qll deleted file mode 100644 index 2916b723a8f..00000000000 --- a/python/ql/lib/semmle/python/security/strings/Untrusted.qll +++ /dev/null @@ -1,10 +0,0 @@ -import python -import External - -/** - * A kind of taint representing an externally controlled string. - * This class is a simple sub-class of `ExternalStringKind`. - */ -deprecated class UntrustedStringKind extends ExternalStringKind { - UntrustedStringKind() { this = "externally controlled string" } -} diff --git a/python/ql/lib/semmle/python/web/ClientHttpRequest.qll b/python/ql/lib/semmle/python/web/ClientHttpRequest.qll deleted file mode 100644 index edcd236e031..00000000000 --- a/python/ql/lib/semmle/python/web/ClientHttpRequest.qll +++ /dev/null @@ -1,2 +0,0 @@ -import semmle.python.web.client.StdLib -import semmle.python.web.client.Requests diff --git a/python/ql/lib/semmle/python/web/Http.qll b/python/ql/lib/semmle/python/web/Http.qll deleted file mode 100644 index 85100e6524e..00000000000 --- a/python/ql/lib/semmle/python/web/Http.qll +++ /dev/null @@ -1,119 +0,0 @@ -import python -import semmle.python.dataflow.Implementation -import semmle.python.security.strings.External -import HttpConstants - -/** Generic taint source from a http request */ -abstract deprecated class HttpRequestTaintSource extends TaintSource { } - -/** - * Taint kind representing the WSGI environment. - * As specified in PEP 3333. https://www.python.org/dev/peps/pep-3333/#environ-variables - */ -deprecated class WsgiEnvironment extends TaintKind { - WsgiEnvironment() { this = "wsgi.environment" } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - result = this and Implementation::copyCall(fromnode, tonode) - or - result = this and - tonode.(CallNode).getFunction().pointsTo(ClassValue::dict()) and - tonode.(CallNode).getArg(0) = fromnode - or - exists(Value key, string text | - tonode.(CallNode).getFunction().(AttrNode).getObject("get") = fromnode and - tonode.(CallNode).getArg(0).pointsTo(key) - or - tonode.(SubscriptNode).getObject() = fromnode and - tonode.isLoad() and - tonode.(SubscriptNode).getIndex().pointsTo(key) - | - key = Value::forString(text) and - result instanceof ExternalStringKind and - ( - text = "QUERY_STRING" or - text = "PATH_INFO" or - text.matches("HTTP\\_%") - ) - ) - } -} - -/** - * A standard morsel object from a HTTP request, a value in a cookie, - * typically an instance of `http.cookies.Morsel` - */ -deprecated class UntrustedMorsel extends TaintKind { - UntrustedMorsel() { this = "http.Morsel" } - - override TaintKind getTaintOfAttribute(string name) { - result instanceof ExternalStringKind and - name = "value" - } -} - -/** A standard cookie object from a HTTP request, typically an instance of `http.cookies.SimpleCookie` */ -deprecated class UntrustedCookie extends TaintKind { - UntrustedCookie() { this = "http.Cookie" } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - tonode.(SubscriptNode).getObject() = fromnode and - result instanceof UntrustedMorsel - } -} - -abstract deprecated class CookieOperation extends @py_flow_node { - /** Gets a textual representation of this element. */ - abstract string toString(); - - abstract ControlFlowNode getKey(); - - abstract ControlFlowNode getValue(); -} - -abstract deprecated class CookieGet extends CookieOperation { } - -abstract deprecated class CookieSet extends CookieOperation { } - -/** Generic taint sink in a http response */ -abstract deprecated class HttpResponseTaintSink extends TaintSink { - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -abstract deprecated class HttpRedirectTaintSink extends TaintSink { - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -deprecated module Client { - // TODO: user-input in other than URL: - // - `data`, `json` for `requests.post` - // - `body` for `HTTPConnection.request` - // - headers? - // TODO: Add more library support - // - urllib3 https://github.com/urllib3/urllib3 - // - httpx https://github.com/encode/httpx - /** - * An outgoing http request - * - * For example: - * conn = HTTPConnection('example.com') - * conn.request('GET', '/path') - */ - abstract class HttpRequest extends ControlFlowNode { - /** - * Get any ControlFlowNode that is used to construct the final URL. - * - * In the HTTPConnection example, there is a result for both `'example.com'` and for `'/path'`. - */ - abstract ControlFlowNode getAUrlPart(); - - abstract string getMethodUpper(); - } - - /** Taint sink for the URL-part of an outgoing http request */ - class HttpRequestUrlTaintSink extends TaintSink { - HttpRequestUrlTaintSink() { this = any(HttpRequest r).getAUrlPart() } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } -} diff --git a/python/ql/lib/semmle/python/web/HttpConstants.qll b/python/ql/lib/semmle/python/web/HttpConstants.qll deleted file mode 100644 index e5cebb57729..00000000000 --- a/python/ql/lib/semmle/python/web/HttpConstants.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** Gets an HTTP verb, in upper case */ -deprecated string httpVerb() { - result in ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"] -} - -/** Gets an HTTP verb, in lower case */ -deprecated string httpVerbLower() { result = httpVerb().toLowerCase() } diff --git a/python/ql/lib/semmle/python/web/HttpRedirect.qll b/python/ql/lib/semmle/python/web/HttpRedirect.qll deleted file mode 100644 index cfbe35f30f1..00000000000 --- a/python/ql/lib/semmle/python/web/HttpRedirect.qll +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.security.strings.Basic -import semmle.python.web.django.Redirect -import semmle.python.web.flask.Redirect -import semmle.python.web.tornado.Redirect -import semmle.python.web.pyramid.Redirect -import semmle.python.web.bottle.Redirect diff --git a/python/ql/lib/semmle/python/web/HttpRequest.qll b/python/ql/lib/semmle/python/web/HttpRequest.qll deleted file mode 100644 index 88dd36049b4..00000000000 --- a/python/ql/lib/semmle/python/web/HttpRequest.qll +++ /dev/null @@ -1,10 +0,0 @@ -import semmle.python.web.django.Request -import semmle.python.web.flask.Request -import semmle.python.web.tornado.Request -import semmle.python.web.pyramid.Request -import semmle.python.web.twisted.Request -import semmle.python.web.bottle.Request -import semmle.python.web.turbogears.Request -import semmle.python.web.falcon.Request -import semmle.python.web.cherrypy.Request -import semmle.python.web.stdlib.Request diff --git a/python/ql/lib/semmle/python/web/HttpResponse.qll b/python/ql/lib/semmle/python/web/HttpResponse.qll deleted file mode 100644 index 25a4221ce68..00000000000 --- a/python/ql/lib/semmle/python/web/HttpResponse.qll +++ /dev/null @@ -1,10 +0,0 @@ -import semmle.python.web.django.Response -import semmle.python.web.flask.Response -import semmle.python.web.pyramid.Response -import semmle.python.web.tornado.Response -import semmle.python.web.twisted.Response -import semmle.python.web.bottle.Response -import semmle.python.web.turbogears.Response -import semmle.python.web.falcon.Response -import semmle.python.web.cherrypy.Response -import semmle.python.web.stdlib.Response diff --git a/python/ql/lib/semmle/python/web/bottle/General.qll b/python/ql/lib/semmle/python/web/bottle/General.qll deleted file mode 100644 index cbb42c97305..00000000000 --- a/python/ql/lib/semmle/python/web/bottle/General.qll +++ /dev/null @@ -1,46 +0,0 @@ -import python -import semmle.python.web.Http -import semmle.python.types.Extensions - -/** Gets the bottle module */ -deprecated ModuleValue theBottleModule() { result = Module::named("bottle") } - -/** Gets the bottle.Bottle class */ -deprecated ClassValue theBottleClass() { result = theBottleModule().attr("Bottle") } - -/** - * Holds if `route` is routed to `func` - * by decorating `func` with `app.route(route)` or `route(route)` - */ -deprecated predicate bottle_route(CallNode route_call, ControlFlowNode route, Function func) { - exists(CallNode decorator_call, string name | - route_call.getFunction().(AttrNode).getObject(name).pointsTo().getClass() = theBottleClass() or - route_call.getFunction().pointsTo(theBottleModule().attr(name)) - | - (name = "route" or name = httpVerbLower()) and - decorator_call.getFunction() = route_call and - route_call.getArg(0) = route and - decorator_call.getArg(0).getNode().(FunctionExpr).getInnerScope() = func - ) -} - -deprecated class BottleRoute extends ControlFlowNode { - BottleRoute() { bottle_route(this, _, _) } - - string getUrl() { - exists(StrConst url | - bottle_route(this, url.getAFlowNode(), _) and - result = url.getText() - ) - } - - Function getFunction() { bottle_route(this, _, result) } - - Parameter getANamedArgument() { - exists(string name, Function func | - func = this.getFunction() and - func.getArgByName(name) = result and - this.getUrl().matches("%<" + name + ">%") - ) - } -} diff --git a/python/ql/lib/semmle/python/web/bottle/Redirect.qll b/python/ql/lib/semmle/python/web/bottle/Redirect.qll deleted file mode 100644 index 6525cc058eb..00000000000 --- a/python/ql/lib/semmle/python/web/bottle/Redirect.qll +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Provides class representing the `bottle.redirect` function. - * This module is intended to be imported into a taint-tracking query - * to extend `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.bottle.General - -deprecated FunctionValue bottle_redirect() { result = theBottleModule().attr("redirect") } - -/** - * An argument to the `bottle.redirect` function. - */ -deprecated class BottleRedirect extends TaintSink { - override string toString() { result = "bottle.redirect" } - - BottleRedirect() { - exists(CallNode call | - bottle_redirect().getACall() = call and - this = call.getAnArg() - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } -} diff --git a/python/ql/lib/semmle/python/web/bottle/Request.qll b/python/ql/lib/semmle/python/web/bottle/Request.qll deleted file mode 100644 index 3de4748b30e..00000000000 --- a/python/ql/lib/semmle/python/web/bottle/Request.qll +++ /dev/null @@ -1,80 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.External -import semmle.python.web.Http -import semmle.python.web.bottle.General - -deprecated private Value theBottleRequestObject() { result = theBottleModule().attr("request") } - -deprecated class BottleRequestKind extends TaintKind { - BottleRequestKind() { this = "bottle.request" } - - override TaintKind getTaintOfAttribute(string name) { - result instanceof BottleFormsDict and - (name = "cookies" or name = "query" or name = "form") - or - result instanceof ExternalStringKind and - (name = "query_string" or name = "url_args") - or - result.(DictKind).getValue() instanceof FileUpload and - name = "files" - } -} - -deprecated private class RequestSource extends HttpRequestTaintSource { - RequestSource() { this.(ControlFlowNode).pointsTo(theBottleRequestObject()) } - - override predicate isSourceOf(TaintKind kind) { kind instanceof BottleRequestKind } -} - -deprecated class BottleFormsDict extends TaintKind { - BottleFormsDict() { this = "bottle.FormsDict" } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - /* Cannot use `getTaintOfAttribute(name)` as it wouldn't bind `name` */ - exists(string name | - fromnode = tonode.(AttrNode).getObject(name) and - result instanceof ExternalStringKind - | - name != "get" and name != "getunicode" and name != "getall" - ) - } - - override TaintKind getTaintOfMethodResult(string name) { - (name = "get" or name = "getunicode") and - result instanceof ExternalStringKind - or - name = "getall" and result.(SequenceKind).getItem() instanceof ExternalStringKind - } -} - -deprecated class FileUpload extends TaintKind { - FileUpload() { this = "bottle.FileUpload" } - - override TaintKind getTaintOfAttribute(string name) { - name = "filename" and result instanceof ExternalStringKind - or - name = "raw_filename" and result instanceof ExternalStringKind - or - name = "file" and result instanceof UntrustedFile - } -} - -deprecated class UntrustedFile extends TaintKind { - UntrustedFile() { this = "Untrusted file" } -} - -// -// TO DO.. File uploads -- Should check about file uploads for other frameworks as well. -// Move UntrustedFile to shared location -// -/** A parameter to a bottle request handler function */ -deprecated class BottleRequestParameter extends HttpRequestTaintSource { - BottleRequestParameter() { - exists(BottleRoute route | route.getANamedArgument() = this.(ControlFlowNode).getNode()) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "bottle handler function argument" } -} diff --git a/python/ql/lib/semmle/python/web/bottle/Response.qll b/python/ql/lib/semmle/python/web/bottle/Response.qll deleted file mode 100644 index f027c6be1a5..00000000000 --- a/python/ql/lib/semmle/python/web/bottle/Response.qll +++ /dev/null @@ -1,52 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.web.Http -import semmle.python.web.bottle.General - -/** - * A bottle.Response object - * This isn't really a "taint", but we use the value tracking machinery to - * track the flow of response objects. - */ -deprecated class BottleResponse extends TaintKind { - BottleResponse() { this = "bottle.response" } -} - -deprecated private Value theBottleResponseObject() { result = theBottleModule().attr("response") } - -deprecated class BottleResponseBodyAssignment extends HttpResponseTaintSink { - BottleResponseBodyAssignment() { - exists(DefinitionNode lhs | - lhs.getValue() = this and - lhs.(AttrNode).getObject("body").pointsTo(theBottleResponseObject()) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } -} - -deprecated class BottleHandlerFunctionResult extends HttpResponseTaintSink { - BottleHandlerFunctionResult() { - exists(BottleRoute route, Return ret | - ret.getScope() = route.getFunction() and - ret.getValue().getAFlowNode() = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } - - override string toString() { result = "bottle handler function result" } -} - -deprecated class BottleCookieSet extends CookieSet, CallNode { - BottleCookieSet() { - any(BottleResponse r).taints(this.getFunction().(AttrNode).getObject("set_cookie")) - } - - override string toString() { result = CallNode.super.toString() } - - override ControlFlowNode getKey() { result = this.getArg(0) } - - override ControlFlowNode getValue() { result = this.getArg(1) } -} diff --git a/python/ql/lib/semmle/python/web/cherrypy/General.qll b/python/ql/lib/semmle/python/web/cherrypy/General.qll deleted file mode 100644 index 40becc70a50..00000000000 --- a/python/ql/lib/semmle/python/web/cherrypy/General.qll +++ /dev/null @@ -1,44 +0,0 @@ -import python -import semmle.python.web.Http - -deprecated module CherryPy { - FunctionValue expose() { result = Value::named("cherrypy.expose") } -} - -deprecated class CherryPyExposedFunction extends Function { - CherryPyExposedFunction() { - this.getADecorator().pointsTo(CherryPy::expose()) - or - this.getADecorator().(Call).getFunc().pointsTo(CherryPy::expose()) - } -} - -deprecated class CherryPyRoute extends CallNode { - CherryPyRoute() { - /* cherrypy.quickstart(root, script_name, config) */ - Value::named("cherrypy.quickstart").(FunctionValue).getACall() = this - or - /* cherrypy.tree.mount(root, script_name, config) */ - this.getFunction().(AttrNode).getObject("mount").pointsTo(Value::named("cherrypy.tree")) - } - - ClassValue getAppClass() { - this.getArg(0).pointsTo().getClass() = result - or - this.getArgByName("root").pointsTo().getClass() = result - } - - string getPath() { - exists(Value path | path = Value::forString(result) | - this.getArg(1).pointsTo(path) - or - this.getArgByName("script_name").pointsTo(path) - ) - } - - ClassValue getConfig() { - this.getArg(2).pointsTo().getClass() = result - or - this.getArgByName("config").pointsTo().getClass() = result - } -} diff --git a/python/ql/lib/semmle/python/web/cherrypy/Request.qll b/python/ql/lib/semmle/python/web/cherrypy/Request.qll deleted file mode 100644 index b3c096f8bdd..00000000000 --- a/python/ql/lib/semmle/python/web/cherrypy/Request.qll +++ /dev/null @@ -1,41 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.Http -import semmle.python.web.cherrypy.General - -/** The cherrypy.request local-proxy object */ -deprecated class CherryPyRequest extends TaintKind { - CherryPyRequest() { this = "cherrypy.request" } - - override TaintKind getTaintOfAttribute(string name) { - name = "params" and result instanceof ExternalStringDictKind - or - name = "cookie" and result instanceof UntrustedCookie - } - - override TaintKind getTaintOfMethodResult(string name) { - name in ["getHeader", "getCookie", "getUser", "getPassword"] and - result instanceof ExternalStringKind - } -} - -deprecated class CherryPyExposedFunctionParameter extends HttpRequestTaintSource { - CherryPyExposedFunctionParameter() { - exists(Parameter p | - p = any(CherryPyExposedFunction f).getAnArg() and - not p.isSelf() and - p.asName().getAFlowNode() = this - ) - } - - override string toString() { result = "CherryPy handler function parameter" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } -} - -deprecated class CherryPyRequestSource extends HttpRequestTaintSource { - CherryPyRequestSource() { this.(ControlFlowNode).pointsTo(Value::named("cherrypy.request")) } - - override predicate isSourceOf(TaintKind kind) { kind instanceof CherryPyRequest } -} diff --git a/python/ql/lib/semmle/python/web/cherrypy/Response.qll b/python/ql/lib/semmle/python/web/cherrypy/Response.qll deleted file mode 100644 index 124a9f9b7d0..00000000000 --- a/python/ql/lib/semmle/python/web/cherrypy/Response.qll +++ /dev/null @@ -1,18 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.web.Http -import semmle.python.web.cherrypy.General - -deprecated class CherryPyExposedFunctionResult extends HttpResponseTaintSink { - CherryPyExposedFunctionResult() { - exists(Return ret | - ret.getScope() instanceof CherryPyExposedFunction and - ret.getValue().getAFlowNode() = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } - - override string toString() { result = "cherrypy handler function result" } -} diff --git a/python/ql/lib/semmle/python/web/client/Requests.qll b/python/ql/lib/semmle/python/web/client/Requests.qll deleted file mode 100644 index 9adf2c8120f..00000000000 --- a/python/ql/lib/semmle/python/web/client/Requests.qll +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Modeling outgoing HTTP requests using the `requests` package - * https://pypi.org/project/requests/ - */ - -import python -private import semmle.python.web.Http - -deprecated class RequestsHttpRequest extends Client::HttpRequest, CallNode { - CallableValue func; - string method; - - RequestsHttpRequest() { - method = httpVerbLower() and - func = Module::named("requests").attr(method) and - this = func.getACall() - } - - override ControlFlowNode getAUrlPart() { result = func.getNamedArgumentForCall(this, "url") } - - override string getMethodUpper() { result = method.toUpperCase() } -} diff --git a/python/ql/lib/semmle/python/web/client/StdLib.qll b/python/ql/lib/semmle/python/web/client/StdLib.qll deleted file mode 100644 index b8a533c410f..00000000000 --- a/python/ql/lib/semmle/python/web/client/StdLib.qll +++ /dev/null @@ -1,55 +0,0 @@ -import python -private import semmle.python.web.Http - -deprecated ClassValue httpConnectionClass() { - // Python 2 - result = Value::named("httplib.HTTPConnection") - or - result = Value::named("httplib.HTTPSConnection") - or - // Python 3 - result = Value::named("http.client.HTTPConnection") - or - result = Value::named("http.client.HTTPSConnection") - or - // six - result = Value::named("six.moves.http_client.HTTPConnection") - or - result = Value::named("six.moves.http_client.HTTPSConnection") -} - -deprecated class HttpConnectionHttpRequest extends Client::HttpRequest, CallNode { - CallNode constructor_call; - CallableValue func; - - HttpConnectionHttpRequest() { - exists(ClassValue cls, AttrNode call_origin, Value constructor_call_value | - cls = httpConnectionClass() and - func = cls.lookup("request") and - this = func.getACall() and - // since you can do `r = conn.request; r('GET', path)`, we need to find the origin - this.getFunction().pointsTo(_, _, call_origin) and - // Since HTTPSConnection is a subtype of HTTPConnection, up until this point, `cls` could be either class, - // because `HTTPSConnection.request == HTTPConnection.request`. To avoid generating 2 results, we filter - // on the actual class used as the constructor - call_origin.getObject().pointsTo(_, constructor_call_value, constructor_call) and - cls = constructor_call_value.getClass() and - constructor_call = cls.getACall() - ) - } - - override ControlFlowNode getAUrlPart() { - result = func.getNamedArgumentForCall(this, "url") - or - result = constructor_call.getArg(0) - or - result = constructor_call.getArgByName("host") - } - - override string getMethodUpper() { - exists(string method | - result = method.toUpperCase() and - func.getNamedArgumentForCall(this, "method").pointsTo(Value::forString(method)) - ) - } -} diff --git a/python/ql/lib/semmle/python/web/django/Db.qll b/python/ql/lib/semmle/python/web/django/Db.qll deleted file mode 100644 index bb089f5f0fe..00000000000 --- a/python/ql/lib/semmle/python/web/django/Db.qll +++ /dev/null @@ -1,50 +0,0 @@ -import python -import semmle.python.security.injection.Sql - -/** - * A taint kind representing a django cursor object. - */ -deprecated class DjangoDbCursor extends DbCursor { - DjangoDbCursor() { this = "django.db.connection.cursor" } -} - -deprecated private Value theDjangoConnectionObject() { - result = Value::named("django.db.connection") -} - -/** - * A kind of taint source representing sources of django cursor objects. - */ -deprecated class DjangoDbCursorSource extends DbConnectionSource { - DjangoDbCursorSource() { - exists(AttrNode cursor | - this.(CallNode).getFunction() = cursor and - cursor.getObject("cursor").pointsTo(theDjangoConnectionObject()) - ) - } - - override string toString() { result = "django.db.connection.cursor" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoDbCursor } -} - -deprecated ClassValue theDjangoRawSqlClass() { - result = Value::named("django.db.models.expressions.RawSQL") -} - -/** - * A sink of taint on calls to `django.db.models.expressions.RawSQL`. This - * allows arbitrary SQL statements to be executed, which is a security risk. - */ -deprecated class DjangoRawSqlSink extends SqlInjectionSink { - DjangoRawSqlSink() { - exists(CallNode call | - call = theDjangoRawSqlClass().getACall() and - this = call.getArg(0) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "django.db.models.expressions.RawSQL(sink,...)" } -} diff --git a/python/ql/lib/semmle/python/web/django/General.qll b/python/ql/lib/semmle/python/web/django/General.qll deleted file mode 100644 index 1b179b35f9a..00000000000 --- a/python/ql/lib/semmle/python/web/django/General.qll +++ /dev/null @@ -1,136 +0,0 @@ -import python -import semmle.python.regex -import semmle.python.web.Http - -// TODO: Since django uses `path = partial(...)`, our analysis doesn't understand this is -// a FunctionValue, so we can't use `FunctionValue.getArgumentForCall` -// https://github.com/django/django/blob/master/django/urls/conf.py#L76 -abstract deprecated class DjangoRoute extends CallNode { - DjangoViewHandler getViewHandler() { - result = view_handler_from_view_arg(this.getArg(1)) - or - result = view_handler_from_view_arg(this.getArgByName("view")) - } - - abstract string getANamedArgument(); - - /** - * Get the number of positional arguments that will be passed to the view. - * Will only return a result if there are no named arguments. - */ - abstract int getNumPositionalArguments(); -} - -/** - * For function based views -- also see `DjangoClassBasedViewHandler` - * https://docs.djangoproject.com/en/1.11/topics/http/views/ - * https://docs.djangoproject.com/en/3.0/topics/http/views/ - */ -deprecated class DjangoViewHandler extends PythonFunctionValue { - /** Gets the index of the 'request' argument */ - int getRequestArgIndex() { result = 0 } -} - -/** - * Class based views - * https://docs.djangoproject.com/en/1.11/topics/class-based-views/ - * https://docs.djangoproject.com/en/3.0/topics/class-based-views/ - */ -deprecated private class DjangoViewClass extends ClassValue { - DjangoViewClass() { - Value::named("django.views.generic.View") = this.getASuperType() - or - Value::named("django.views.View") = this.getASuperType() - } -} - -deprecated class DjangoClassBasedViewHandler extends DjangoViewHandler { - DjangoClassBasedViewHandler() { exists(DjangoViewClass cls | cls.lookup(httpVerbLower()) = this) } - - override int getRequestArgIndex() { - // due to `self` being the first parameter - result = 1 - } -} - -/** - * Gets the function that will handle requests when `view_arg` is used as the view argument to a - * django route. That is, this methods handles Class-based Views and its `as_view()` function. - */ -deprecated private DjangoViewHandler view_handler_from_view_arg(ControlFlowNode view_arg) { - // Function-based view - result = view_arg.pointsTo() - or - // Class-based view - exists(ClassValue cls | - cls = view_arg.(CallNode).getFunction().(AttrNode).getObject("as_view").pointsTo() and - result = cls.lookup(httpVerbLower()) - ) -} - -// We need this "dummy" class, since otherwise the regex argument would not be considered -// a regex (RegexString is abstract) -deprecated class DjangoRouteRegex extends RegexString { - DjangoRouteRegex() { exists(DjangoRegexRoute route | route.getRouteArg() = this.getAFlowNode()) } -} - -deprecated class DjangoRegexRoute extends DjangoRoute { - ControlFlowNode route; - - DjangoRegexRoute() { - exists(FunctionValue route_maker | - // Django 1.x: https://docs.djangoproject.com/en/1.11/ref/urls/#django.conf.urls.url - Value::named("django.conf.urls.url") = route_maker and - route_maker.getArgumentForCall(this, 0) = route - ) - or - // Django 2.x and 3.x: https://docs.djangoproject.com/en/3.0/ref/urls/#re-path - this = Value::named("django.urls.re_path").getACall() and - ( - route = this.getArg(0) - or - route = this.getArgByName("route") - ) - } - - ControlFlowNode getRouteArg() { result = route } - - override string getANamedArgument() { - exists(DjangoRouteRegex regex | regex.getAFlowNode() = route | - result = regex.getGroupName(_, _) - ) - } - - override int getNumPositionalArguments() { - not exists(this.getANamedArgument()) and - exists(DjangoRouteRegex regex | regex.getAFlowNode() = route | - result = count(regex.getGroupNumber(_, _)) - ) - } -} - -deprecated class DjangoPathRoute extends DjangoRoute { - ControlFlowNode route; - - DjangoPathRoute() { - // Django 2.x and 3.x: https://docs.djangoproject.com/en/3.0/ref/urls/#path - this = Value::named("django.urls.path").getACall() and - ( - route = this.getArg(0) - or - route = this.getArgByName("route") - ) - } - - override string getANamedArgument() { - // regexp taken from django: - // https://github.com/django/django/blob/7d1bf29977bb368d7c28e7c6eb146db3b3009ae7/django/urls/resolvers.py#L199 - exists(StrConst route_str, string match | - route_str = route.getNode() and - match = route_str.getText().regexpFind("<(?:(?<converter>[^>:]+):)?(?<parameter>\\w+)>", _, _) and - result = match.regexpCapture("<(?:(?<converter>[^>:]+):)?(?<parameter>\\w+)>", 2) - ) - } - - override int getNumPositionalArguments() { none() } -} diff --git a/python/ql/lib/semmle/python/web/django/Model.qll b/python/ql/lib/semmle/python/web/django/Model.qll deleted file mode 100644 index 944eec4f799..00000000000 --- a/python/ql/lib/semmle/python/web/django/Model.qll +++ /dev/null @@ -1,69 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.Http -import semmle.python.security.injection.Sql - -/** A django model class */ -deprecated class DjangoModel extends ClassValue { - DjangoModel() { Value::named("django.db.models.Model") = this.getASuperType() } -} - -/** A "taint" for django database tables */ -deprecated class DjangoDbTableObjects extends TaintKind { - DjangoDbTableObjects() { this = "django.db.models.Model.objects" } - - override TaintKind getTaintOfMethodResult(string name) { - result = this and - name in [ - "filter", "exclude", "none", "all", "union", "intersection", "difference", "select_related", - "prefetch_related", "extra", "defer", "only", "annotate", "using", "select_for_update", - "raw", "order_by", "reverse", "distinct", "values", "values_list", "dates", "datetimes" - ] - } -} - -/** Django model objects, which are sources of django database table "taint" */ -deprecated class DjangoModelObjects extends TaintSource { - DjangoModelObjects() { - this.(AttrNode).isLoad() and this.(AttrNode).getObject("objects").pointsTo(any(DjangoModel m)) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoDbTableObjects } - - override string toString() { result = "django.db.models.Model.objects" } -} - -/** - * A call to the `raw` method on a django model. This allows a raw SQL query - * to be sent to the database, which is a security risk. - */ -deprecated class DjangoModelRawCall extends SqlInjectionSink { - DjangoModelRawCall() { - exists(CallNode raw_call, ControlFlowNode queryset | this = raw_call.getArg(0) | - raw_call.getFunction().(AttrNode).getObject("raw") = queryset and - any(DjangoDbTableObjects objs).taints(queryset) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "django.models.QuerySet.raw(sink,...)" } -} - -/** - * A call to the `extra` method on a django model. This allows a raw SQL query - * to be sent to the database, which is a security risk. - */ -deprecated class DjangoModelExtraCall extends SqlInjectionSink { - DjangoModelExtraCall() { - exists(CallNode extra_call, ControlFlowNode queryset | this = extra_call.getArg(0) | - extra_call.getFunction().(AttrNode).getObject("extra") = queryset and - any(DjangoDbTableObjects objs).taints(queryset) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "django.models.QuerySet.extra(sink,...)" } -} diff --git a/python/ql/lib/semmle/python/web/django/Redirect.qll b/python/ql/lib/semmle/python/web/django/Redirect.qll deleted file mode 100644 index 0319f18190f..00000000000 --- a/python/ql/lib/semmle/python/web/django/Redirect.qll +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Provides class representing the `django.redirect` function. - * This module is intended to be imported into a taint-tracking query - * to extend `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -private import semmle.python.web.django.Shared -private import semmle.python.web.Http - -/** - * The URL argument for a call to the `django.shortcuts.redirect` function. - */ -deprecated class DjangoShortcutsRedirectSink extends HttpRedirectTaintSink { - override string toString() { result = "DjangoShortcutsRedirectSink" } - - DjangoShortcutsRedirectSink() { - this = Value::named("django.shortcuts.redirect").(FunctionValue).getArgumentForCall(_, 0) - } -} - -/** - * The URL argument when instantiating a Django Redirect Response. - */ -deprecated class DjangoRedirectResponseSink extends HttpRedirectTaintSink { - DjangoRedirectResponseSink() { - exists(CallNode call | call = any(DjangoRedirectResponseClass cls).getACall() | - this = call.getArg(0) - or - this = call.getArgByName("redirect_to") - ) - } - - override string toString() { result = "DjangoRedirectResponseSink" } -} diff --git a/python/ql/lib/semmle/python/web/django/Request.qll b/python/ql/lib/semmle/python/web/django/Request.qll deleted file mode 100644 index 7e7358595e5..00000000000 --- a/python/ql/lib/semmle/python/web/django/Request.qll +++ /dev/null @@ -1,78 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http -import semmle.python.web.django.General - -/** A django.request.HttpRequest object */ -deprecated class DjangoRequest extends TaintKind { - DjangoRequest() { this = "django.request.HttpRequest" } - - override TaintKind getTaintOfAttribute(string name) { - (name = "GET" or name = "POST") and - result instanceof DjangoQueryDict - } - - override TaintKind getTaintOfMethodResult(string name) { - (name = "body" or name = "path") and - result instanceof ExternalStringKind - } -} - -/* Helper for getTaintForStep() */ -pragma[noinline] -deprecated private predicate subscript_taint(SubscriptNode sub, ControlFlowNode obj, TaintKind kind) { - sub.getObject() = obj and - kind instanceof ExternalStringKind -} - -/** A django.request.QueryDict object */ -deprecated class DjangoQueryDict extends TaintKind { - DjangoQueryDict() { this = "django.http.request.QueryDict" } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - this.taints(fromnode) and - subscript_taint(tonode, fromnode, result) - } - - override TaintKind getTaintOfMethodResult(string name) { - name = "get" and result instanceof ExternalStringKind - } -} - -/** A Django request parameter */ -deprecated class DjangoRequestSource extends HttpRequestTaintSource { - DjangoRequestSource() { - exists(DjangoRoute route, DjangoViewHandler view, int request_arg_index | - route.getViewHandler() = view and - request_arg_index = view.getRequestArgIndex() and - this = view.getScope().getArg(request_arg_index).asName().getAFlowNode() - ) - } - - override string toString() { result = "Django request source" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoRequest } -} - -/** An argument specified in a url routing table */ -deprecated class DjangoRequestParameter extends HttpRequestTaintSource { - DjangoRequestParameter() { - exists(DjangoRoute route, Function f, DjangoViewHandler view, int request_arg_index | - route.getViewHandler() = view and - request_arg_index = view.getRequestArgIndex() and - f = view.getScope() - | - this.(ControlFlowNode).getNode() = f.getArgByName(route.getANamedArgument()) - or - exists(int i | i >= 0 | - i < route.getNumPositionalArguments() and - // +1 because first argument is always the request - this.(ControlFlowNode).getNode() = f.getArg(request_arg_index + 1 + i) - ) - ) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "django.http.request.parameter" } -} diff --git a/python/ql/lib/semmle/python/web/django/Response.qll b/python/ql/lib/semmle/python/web/django/Response.qll deleted file mode 100644 index 3444884dd32..00000000000 --- a/python/ql/lib/semmle/python/web/django/Response.qll +++ /dev/null @@ -1,79 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -private import semmle.python.web.django.Shared -private import semmle.python.web.Http - -/** INTERNAL class used for tracking a django response object. */ -deprecated private class DjangoResponseKind extends TaintKind { - DjangoResponseKind() { this = "django.response.HttpResponse" } -} - -/** INTERNAL taint-source used for tracking a django response object. */ -deprecated private class DjangoResponseSource extends TaintSource { - DjangoResponseSource() { exists(DjangoContentResponseClass cls | cls.getACall() = this) } - - override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoResponseKind } - - override string toString() { result = "django.http.response.HttpResponse" } -} - -/** A write to a django response, which is vulnerable to external data (xss) */ -deprecated class DjangoResponseWrite extends HttpResponseTaintSink { - DjangoResponseWrite() { - exists(AttrNode meth, CallNode call | - call.getFunction() = meth and - any(DjangoResponseKind response).taints(meth.getObject("write")) and - this = call.getArg(0) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } - - override string toString() { result = "django.Response.write(...)" } -} - -/** - * An argument to initialization of a django response. - */ -deprecated class DjangoResponseContent extends HttpResponseTaintSink { - DjangoContentResponseClass cls; - CallNode call; - - DjangoResponseContent() { - call = cls.getACall() and - this = cls.getContentArg(call) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } - - override string toString() { result = "django.Response(...)" } -} - -/** - * An argument to initialization of a django response, which is vulnerable to external data (XSS). - */ -deprecated class DjangoResponseContentXSSVulnerable extends DjangoResponseContent { - override DjangoXSSVulnerableResponseClass cls; - - DjangoResponseContentXSSVulnerable() { - not exists(cls.getContentTypeArg(call)) - or - exists(StringValue s | - cls.getContentTypeArg(call).pointsTo(s) and - s.getText().matches("text/html%") - ) - } -} - -deprecated class DjangoCookieSet extends CookieSet, CallNode { - DjangoCookieSet() { - any(DjangoResponseKind r).taints(this.getFunction().(AttrNode).getObject("set_cookie")) - } - - override string toString() { result = CallNode.super.toString() } - - override ControlFlowNode getKey() { result = this.getArg(0) } - - override ControlFlowNode getValue() { result = this.getArg(1) } -} diff --git a/python/ql/lib/semmle/python/web/django/Sanitizers.qll b/python/ql/lib/semmle/python/web/django/Sanitizers.qll deleted file mode 100644 index e1694a1c481..00000000000 --- a/python/ql/lib/semmle/python/web/django/Sanitizers.qll +++ /dev/null @@ -1,6 +0,0 @@ -import python -/* - * Sanitizers - * No django sanitizers implemented yet. - */ - diff --git a/python/ql/lib/semmle/python/web/django/Shared.qll b/python/ql/lib/semmle/python/web/django/Shared.qll deleted file mode 100644 index bc156249d25..00000000000 --- a/python/ql/lib/semmle/python/web/django/Shared.qll +++ /dev/null @@ -1,72 +0,0 @@ -import python - -/** A class that is a Django Redirect Response (subclass of `django.http.HttpResponseRedirectBase`). */ -deprecated class DjangoRedirectResponseClass extends ClassValue { - DjangoRedirectResponseClass() { - exists(ClassValue redirect_base | - // version 1.x - redirect_base = Value::named("django.http.response.HttpResponseRedirectBase") - or - // version 2.x and 3.x - redirect_base = Value::named("django.http.HttpResponseRedirectBase") - | - this.getASuperType() = redirect_base - ) - } -} - -/** - * A class that is a Django Response, which can contain content. - * A subclass of `django.http.HttpResponse` that is not a `DjangoRedirectResponseClass`. - */ -deprecated class DjangoContentResponseClass extends ClassValue { - ClassValue base; - - DjangoContentResponseClass() { - ( - // version 1.x - base = Value::named("django.http.response.HttpResponse") - or - // version 2.x and 3.x - // https://docs.djangoproject.com/en/2.2/ref/request-response/#httpresponse-objects - base = Value::named("django.http.HttpResponse") - ) and - this.getASuperType() = base - } - - // The reason these two methods are defined in this class (and not in the Sink - // definition that uses this class), is that if we were to add support for - // `django.http.response.HttpResponseNotAllowed` it would make much more sense to add - // the custom logic in this class (or subclass), than to handle all of it in the sink - // definition. - /** Gets the `content` argument of a `call` to the constructor */ - ControlFlowNode getContentArg(CallNode call) { none() } - - /** Gets the `content_type` argument of a `call` to the constructor */ - ControlFlowNode getContentTypeArg(CallNode call) { none() } -} - -/** A class that is a Django Response, and is vulnerable to XSS. */ -deprecated class DjangoXSSVulnerableResponseClass extends DjangoContentResponseClass { - DjangoXSSVulnerableResponseClass() { - // We want to avoid FPs on subclasses that are not exposed to XSS, for example `JsonResponse`. - // The easiest way is to disregard any subclass that has a special `__init__` method. - // It's not guaranteed to remove all FPs, or not to generate FNs, but compared to our - // previous implementation that would treat 0-th argument to _any_ subclass as a sink, - // this gets us much closer to reality. - this.lookup("__init__") = base.lookup("__init__") and - not this instanceof DjangoRedirectResponseClass - } - - override ControlFlowNode getContentArg(CallNode call) { - result = call.getArg(0) - or - result = call.getArgByName("content") - } - - override ControlFlowNode getContentTypeArg(CallNode call) { - result = call.getArg(1) - or - result = call.getArgByName("content_type") - } -} diff --git a/python/ql/lib/semmle/python/web/falcon/General.qll b/python/ql/lib/semmle/python/web/falcon/General.qll deleted file mode 100644 index 5f9cce57611..00000000000 --- a/python/ql/lib/semmle/python/web/falcon/General.qll +++ /dev/null @@ -1,46 +0,0 @@ -import python -import semmle.python.web.Http - -/** Gets the falcon API class */ -deprecated ClassValue theFalconAPIClass() { result = Value::named("falcon.API") } - -/** Holds if `route` is routed to `resource` */ -deprecated private predicate api_route( - CallNode route_call, ControlFlowNode route, ClassValue resource -) { - route_call.getFunction().(AttrNode).getObject("add_route").pointsTo().getClass() = - theFalconAPIClass() and - route_call.getArg(0) = route and - route_call.getArg(1).pointsTo().getClass() = resource -} - -deprecated private predicate route(FalconRoute route, Function target, string funcname) { - route.getResourceClass().lookup("on_" + funcname).(FunctionValue).getScope() = target -} - -deprecated class FalconRoute extends ControlFlowNode { - FalconRoute() { api_route(this, _, _) } - - string getUrl() { - exists(StrConst url | - api_route(this, url.getAFlowNode(), _) and - result = url.getText() - ) - } - - ClassValue getResourceClass() { api_route(this, _, result) } - - FalconHandlerFunction getHandlerFunction(string method) { route(this, result, method) } -} - -deprecated class FalconHandlerFunction extends Function { - FalconHandlerFunction() { route(_, this, _) } - - private string methodName() { route(_, this, result) } - - string getMethod() { result = this.methodName().toUpperCase() } - - Parameter getRequest() { result = this.getArg(1) } - - Parameter getResponse() { result = this.getArg(2) } -} diff --git a/python/ql/lib/semmle/python/web/falcon/Request.qll b/python/ql/lib/semmle/python/web/falcon/Request.qll deleted file mode 100644 index ac4c92f3ad0..00000000000 --- a/python/ql/lib/semmle/python/web/falcon/Request.qll +++ /dev/null @@ -1,37 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http -import semmle.python.web.falcon.General - -/** https://falcon.readthedocs.io/en/stable/api/request_and_response.html */ -deprecated class FalconRequest extends TaintKind { - FalconRequest() { this = "falcon.request" } - - override TaintKind getTaintOfAttribute(string name) { - name = "env" and result instanceof WsgiEnvironment - or - result instanceof ExternalStringKind and - name in ["uri", "url", "forwarded_uri", "relative_uri", "query_string"] - or - result instanceof ExternalStringDictKind and - (name = "cookies" or name = "params") - or - name = "stream" and result instanceof ExternalFileObject - } - - override TaintKind getTaintOfMethodResult(string name) { - name = "get_param" and result instanceof ExternalStringKind - or - name = "get_param_as_json" and result instanceof ExternalJsonKind - or - name = "get_param_as_list" and result instanceof ExternalStringSequenceKind - } -} - -deprecated class FalconRequestParameter extends HttpRequestTaintSource { - FalconRequestParameter() { - exists(FalconHandlerFunction f | f.getRequest() = this.(ControlFlowNode).getNode()) - } - - override predicate isSourceOf(TaintKind k) { k instanceof FalconRequest } -} diff --git a/python/ql/lib/semmle/python/web/falcon/Response.qll b/python/ql/lib/semmle/python/web/falcon/Response.qll deleted file mode 100644 index ae5562b6432..00000000000 --- a/python/ql/lib/semmle/python/web/falcon/Response.qll +++ /dev/null @@ -1,28 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http -import semmle.python.web.falcon.General - -/** https://falcon.readthedocs.io/en/stable/api/request_and_response.html */ -deprecated class FalconResponse extends TaintKind { - FalconResponse() { this = "falcon.response" } -} - -/** Only used internally to track the response parameter */ -deprecated private class FalconResponseParameter extends TaintSource { - FalconResponseParameter() { - exists(FalconHandlerFunction f | f.getResponse() = this.(ControlFlowNode).getNode()) - } - - override predicate isSourceOf(TaintKind k) { k instanceof FalconResponse } -} - -deprecated class FalconResponseBodySink extends HttpResponseTaintSink { - FalconResponseBodySink() { - exists(AttrNode attr | any(FalconResponse f).taints(attr.getObject("body")) | - attr.(DefinitionNode).getValue() = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } -} diff --git a/python/ql/lib/semmle/python/web/flask/General.qll b/python/ql/lib/semmle/python/web/flask/General.qll deleted file mode 100644 index cc4d992f9ff..00000000000 --- a/python/ql/lib/semmle/python/web/flask/General.qll +++ /dev/null @@ -1,104 +0,0 @@ -import python -import semmle.python.web.Http -import semmle.python.web.flask.Response - -/** Gets the flask app class */ -deprecated ClassValue theFlaskClass() { result = Value::named("flask.Flask") } - -/** Gets the flask MethodView class */ -deprecated ClassValue theFlaskMethodViewClass() { result = Value::named("flask.views.MethodView") } - -deprecated ClassValue theFlaskReponseClass() { result = Value::named("flask.Response") } - -/** - * Holds if `route` is routed to `func` - * by decorating `func` with `app.route(route)` - */ -deprecated predicate app_route(ControlFlowNode route, Function func) { - exists(CallNode route_call, CallNode decorator_call | - route_call.getFunction().(AttrNode).getObject("route").pointsTo().getClass() = theFlaskClass() and - decorator_call.getFunction() = route_call and - route_call.getArg(0) = route and - decorator_call.getArg(0).getNode().(FunctionExpr).getInnerScope() = func - ) -} - -/* Helper for add_url_rule */ -deprecated private predicate add_url_rule_call(ControlFlowNode regex, ControlFlowNode callable) { - exists(CallNode call | - call.getFunction().(AttrNode).getObject("add_url_rule").pointsTo().getClass() = theFlaskClass() and - regex = call.getArg(0) - | - callable = call.getArg(2) or - callable = call.getArgByName("view_func") - ) -} - -/** Holds if urls matching `regex` are routed to `func` */ -deprecated predicate add_url_rule(ControlFlowNode regex, Function func) { - exists(ControlFlowNode callable | add_url_rule_call(regex, callable) | - exists(PythonFunctionValue f | f.getScope() = func and callable.pointsTo(f)) - or - /* MethodView.as_view() */ - exists(MethodViewClass view_cls | view_cls.asTaint().taints(callable) | - func = view_cls.lookup(httpVerbLower()).(FunctionValue).getScope() - ) - /* TODO: -- Handle Views that aren't MethodViews */ - ) -} - -/** - * Holds if urls matching `regex` are routed to `func` using - * any of flask's routing mechanisms. - */ -deprecated predicate flask_routing(ControlFlowNode regex, Function func) { - app_route(regex, func) - or - add_url_rule(regex, func) -} - -/** A class that extends flask.views.MethodView */ -deprecated private class MethodViewClass extends ClassValue { - MethodViewClass() { this.getASuperType() = theFlaskMethodViewClass() } - - /* As we are restricted to strings for taint kinds, we need to map these classes to strings. */ - string taintString() { result = "flask/" + this.getQualifiedName() + ".as.view" } - - /* As we are restricted to strings for taint kinds, we need to map these classes to strings. */ - TaintKind asTaint() { result = this.taintString() } -} - -deprecated private class MethodViewTaint extends TaintKind { - MethodViewTaint() { any(MethodViewClass cls).taintString() = this } -} - -/** A source of method view "taint"s. */ -deprecated private class AsView extends TaintSource { - AsView() { - exists(ClassValue view_class | - view_class.getASuperType() = theFlaskMethodViewClass() and - this.(CallNode).getFunction().(AttrNode).getObject("as_view").pointsTo(view_class) - ) - } - - override string toString() { result = "flask.MethodView.as_view()" } - - override predicate isSourceOf(TaintKind kind) { - exists(MethodViewClass view_class | - kind = view_class.asTaint() and - this.(CallNode).getFunction().(AttrNode).getObject("as_view").pointsTo(view_class) - ) - } -} - -deprecated class FlaskCookieSet extends CookieSet, CallNode { - FlaskCookieSet() { - any(FlaskResponseTaintKind t).taints(this.getFunction().(AttrNode).getObject("set_cookie")) - } - - override string toString() { result = CallNode.super.toString() } - - override ControlFlowNode getKey() { result = this.getArg(0) } - - override ControlFlowNode getValue() { result = this.getArg(1) } -} diff --git a/python/ql/lib/semmle/python/web/flask/Redirect.qll b/python/ql/lib/semmle/python/web/flask/Redirect.qll deleted file mode 100644 index f178c2520ea..00000000000 --- a/python/ql/lib/semmle/python/web/flask/Redirect.qll +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Provides class representing the `flask.redirect` function. - * This module is intended to be imported into a taint-tracking query - * to extend `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.flask.General - -deprecated FunctionValue flask_redirect() { result = Value::named("flask.redirect") } - -/** - * Represents an argument to the `flask.redirect` function. - */ -deprecated class FlaskRedirect extends HttpRedirectTaintSink { - override string toString() { result = "flask.redirect" } - - FlaskRedirect() { - exists(CallNode call | - flask_redirect().getACall() = call and - this = call.getAnArg() - ) - } -} diff --git a/python/ql/lib/semmle/python/web/flask/Request.qll b/python/ql/lib/semmle/python/web/flask/Request.qll deleted file mode 100644 index ea9a59dc45e..00000000000 --- a/python/ql/lib/semmle/python/web/flask/Request.qll +++ /dev/null @@ -1,80 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http -import semmle.python.web.flask.General - -deprecated private Value theFlaskRequestObject() { result = Value::named("flask.request") } - -/** Holds if `attr` is an access of attribute `name` of the flask request object */ -deprecated private predicate flask_request_attr(AttrNode attr, string name) { - attr.isLoad() and - attr.getObject(name).pointsTo(theFlaskRequestObject()) -} - -/** Source of external data from a flask request */ -deprecated class FlaskRequestData extends HttpRequestTaintSource { - FlaskRequestData() { - not this instanceof FlaskRequestArgs and - exists(string name | flask_request_attr(this, name) | - name in ["path", "full_path", "base_url", "url"] - ) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "flask.request" } -} - -/** Source of dictionary whose values are externally controlled */ -deprecated class FlaskRequestArgs extends HttpRequestTaintSource { - FlaskRequestArgs() { - exists(string attr | flask_request_attr(this, attr) | - attr in ["args", "form", "values", "files", "headers", "json"] - ) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } - - override string toString() { result = "flask.request.args" } -} - -/** Source of dictionary whose values are externally controlled */ -deprecated class FlaskRequestJson extends HttpRequestTaintSource { - FlaskRequestJson() { flask_request_attr(this, "json") } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalJsonKind } - - override string toString() { result = "flask.request.json" } -} - -/** - * A parameter to a flask request handler, that can capture a part of the URL (as specified in - * the url-pattern of a route). - * - * For example, the `name` parameter in: - * ``` - * @app.route('/hello/<name>') - * def hello(name): - * ``` - */ -deprecated class FlaskRoutedParameter extends HttpRequestTaintSource { - FlaskRoutedParameter() { - exists(string name, Function func, StrConst url_pattern | - this.(ControlFlowNode).getNode() = func.getArgByName(name) and - flask_routing(url_pattern.getAFlowNode(), func) and - exists(string match | - match = url_pattern.getS().regexpFind(werkzeug_rule_re(), _, _) and - name = match.regexpCapture(werkzeug_rule_re(), 4) - ) - ) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } -} - -deprecated private string werkzeug_rule_re() { - // since flask uses werkzeug internally, we are using its routing rules from - // https://github.com/pallets/werkzeug/blob/4dc8d6ab840d4b78cbd5789cef91b01e3bde01d5/src/werkzeug/routing.py#L138-L151 - result = - "(?<static>[^<]*)<(?:(?<converter>[a-zA-Z_][a-zA-Z0-9_]*)(?:\\((?<args>.*?)\\))?\\:)?(?<variable>[a-zA-Z_][a-zA-Z0-9_]*)>" -} diff --git a/python/ql/lib/semmle/python/web/flask/Response.qll b/python/ql/lib/semmle/python/web/flask/Response.qll deleted file mode 100644 index 1e489c56b46..00000000000 --- a/python/ql/lib/semmle/python/web/flask/Response.qll +++ /dev/null @@ -1,55 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.flask.General - -/** - * A flask response, which is vulnerable to any sort of - * http response malice. - */ -deprecated class FlaskRoutedResponse extends HttpResponseTaintSink { - FlaskRoutedResponse() { - exists(PythonFunctionValue response | - flask_routing(_, response.getScope()) and - this = response.getAReturnedNode() - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } - - override string toString() { result = "flask.routed.response" } -} - -deprecated class FlaskResponseArgument extends HttpResponseTaintSink { - FlaskResponseArgument() { - exists(CallNode call | - ( - call.getFunction().pointsTo(theFlaskReponseClass()) - or - call.getFunction().pointsTo(Value::named("flask.make_response")) - ) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } - - override string toString() { result = "flask.response.argument" } -} - -deprecated class FlaskResponseTaintKind extends TaintKind { - FlaskResponseTaintKind() { this = "flask.Response" } -} - -deprecated class FlaskResponseConfiguration extends TaintTracking::Configuration { - FlaskResponseConfiguration() { this = "Flask response configuration" } - - override predicate isSource(DataFlow::Node node, TaintKind kind) { - kind instanceof FlaskResponseTaintKind and - ( - node.asCfgNode().(CallNode).getFunction().pointsTo(theFlaskReponseClass()) - or - node.asCfgNode().(CallNode).getFunction().pointsTo(Value::named("flask.make_response")) - ) - } -} diff --git a/python/ql/lib/semmle/python/web/pyramid/Redirect.qll b/python/ql/lib/semmle/python/web/pyramid/Redirect.qll deleted file mode 100644 index 852df8cf422..00000000000 --- a/python/ql/lib/semmle/python/web/pyramid/Redirect.qll +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Provides class representing the `pyramid.redirect` function. - * This module is intended to be imported into a taint-tracking query - * to extend `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.Http - -deprecated private ClassValue redirectClass() { - exists(ModuleValue ex | ex.getName() = "pyramid.httpexceptions" | - ex.attr("HTTPFound") = result - or - ex.attr("HTTPTemporaryRedirect") = result - ) -} - -/** - * Represents an argument to the `tornado.redirect` function. - */ -deprecated class PyramidRedirect extends HttpRedirectTaintSink { - override string toString() { result = "pyramid.redirect" } - - PyramidRedirect() { - exists(CallNode call | call.getFunction().pointsTo(redirectClass()) | - call.getArg(0) = this - or - call.getArgByName("location") = this - ) - } -} diff --git a/python/ql/lib/semmle/python/web/pyramid/Request.qll b/python/ql/lib/semmle/python/web/pyramid/Request.qll deleted file mode 100644 index df84cc84440..00000000000 --- a/python/ql/lib/semmle/python/web/pyramid/Request.qll +++ /dev/null @@ -1,25 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http -private import semmle.python.web.webob.Request -private import semmle.python.web.pyramid.View - -deprecated class PyramidRequest extends BaseWebobRequest { - PyramidRequest() { this = "pyramid.request" } - - override ClassValue getType() { result = Value::named("pyramid.request.Request") } -} - -/** Source of pyramid request objects */ -deprecated class PyramidViewArgument extends HttpRequestTaintSource { - PyramidViewArgument() { - exists(Function view_func | - is_pyramid_view_function(view_func) and - this.(ControlFlowNode).getNode() = view_func.getArg(0) - ) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof PyramidRequest } - - override string toString() { result = "pyramid.view.argument" } -} diff --git a/python/ql/lib/semmle/python/web/pyramid/Response.qll b/python/ql/lib/semmle/python/web/pyramid/Response.qll deleted file mode 100644 index 0512e7e7f4d..00000000000 --- a/python/ql/lib/semmle/python/web/pyramid/Response.qll +++ /dev/null @@ -1,37 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.Http -private import semmle.python.web.pyramid.View - -/** - * A pyramid response, which is vulnerable to any sort of - * http response malice. - */ -deprecated class PyramidRoutedResponse extends HttpResponseTaintSink { - PyramidRoutedResponse() { - exists(PythonFunctionValue view | - is_pyramid_view_function(view.getScope()) and - this = view.getAReturnedNode() - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } - - override string toString() { result = "pyramid.routed.response" } -} - -deprecated class PyramidCookieSet extends CookieSet, CallNode { - PyramidCookieSet() { - exists(ControlFlowNode f | - f = this.getFunction().(AttrNode).getObject("set_cookie") and - f.pointsTo().getClass() = Value::named("pyramid.response.Response") - ) - } - - override string toString() { result = CallNode.super.toString() } - - override ControlFlowNode getKey() { result = this.getArg(0) } - - override ControlFlowNode getValue() { result = this.getArg(1) } -} diff --git a/python/ql/lib/semmle/python/web/pyramid/View.qll b/python/ql/lib/semmle/python/web/pyramid/View.qll deleted file mode 100644 index 37d9334cb07..00000000000 --- a/python/ql/lib/semmle/python/web/pyramid/View.qll +++ /dev/null @@ -1,9 +0,0 @@ -import python - -deprecated ModuleValue thePyramidViewModule() { result.getName() = "pyramid.view" } - -deprecated Value thePyramidViewConfig() { result = thePyramidViewModule().attr("view_config") } - -deprecated predicate is_pyramid_view_function(Function func) { - func.getADecorator().pointsTo().getClass() = thePyramidViewConfig() -} diff --git a/python/ql/lib/semmle/python/web/stdlib/Request.qll b/python/ql/lib/semmle/python/web/stdlib/Request.qll deleted file mode 100644 index ff850233616..00000000000 --- a/python/ql/lib/semmle/python/web/stdlib/Request.qll +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Provides the sources and taint-flow for HTTP servers defined using the standard library (stdlib). - * Specifically, we model `HttpRequestTaintSource`s from instances of `BaseHTTPRequestHandler` - * (or subclasses) and form parsing using `cgi.FieldStorage`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http - -/** Source of BaseHttpRequestHandler instances. */ -deprecated class StdLibRequestSource extends HttpRequestTaintSource { - StdLibRequestSource() { - exists(ClassValue cls | - cls.getABaseType+() = Value::named("BaseHTTPServer.BaseHTTPRequestHandler") - or - cls.getABaseType+() = Value::named("http.server.BaseHTTPRequestHandler") - | - this.(ControlFlowNode).pointsTo().getClass() = cls - ) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof BaseHTTPRequestHandlerKind } -} - -/** TaintKind for an instance of BaseHttpRequestHandler. */ -deprecated class BaseHTTPRequestHandlerKind extends TaintKind { - BaseHTTPRequestHandlerKind() { this = "BaseHTTPRequestHandlerKind" } - - override TaintKind getTaintOfAttribute(string name) { - name in ["requestline", "path"] and - result instanceof ExternalStringKind - or - name = "headers" and - result instanceof HTTPMessageKind - or - name = "rfile" and - result instanceof ExternalFileObject - } -} - -/** TaintKind for headers (instance of HttpMessage). */ -deprecated class HTTPMessageKind extends ExternalStringDictKind { - override TaintKind getTaintOfMethodResult(string name) { - result = super.getTaintOfMethodResult(name) - or - name = "get_all" and - result.(SequenceKind).getItem() = this.getValue() - or - name in ["as_bytes", "as_string"] and - result instanceof ExternalStringKind - } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - result = super.getTaintForFlowStep(fromnode, tonode) - or - exists(ClassValue cls | cls = ClassValue::unicode() or cls = ClassValue::bytes() | - tonode = cls.getACall() and - tonode.(CallNode).getArg(0) = fromnode and - result instanceof ExternalStringKind - ) - } -} - -/** Source of parsed HTTP forms (by using the `cgi` module). */ -deprecated class CgiFieldStorageSource extends HttpRequestTaintSource { - CgiFieldStorageSource() { this = Value::named("cgi.FieldStorage").getACall() } - - override predicate isSourceOf(TaintKind kind) { kind instanceof CgiFieldStorageFormKind } -} - -/** TaintKind for a parsed HTTP form. */ -deprecated class CgiFieldStorageFormKind extends TaintKind { - /* - * There is a slight difference between how we model form/fields and how it is handled by the code. - * In the code - * ``` - * form = cgi.FieldStorage() - * field = form['myfield'] - * ``` - * both `form` and `field` have the type `cgi.FieldStorage`. This allows the code to represent - * nested forms as `form['nested_form']['myfield']`. However, since HTML forms can't be nested - * we ignore that detail since it allows for a more clean modeling. - */ - - CgiFieldStorageFormKind() { this = "CgiFieldStorageFormKind" } - - override TaintKind getTaintOfAttribute(string name) { - name = "value" and result.(SequenceKind).getItem() instanceof CgiFieldStorageFieldKind - } - - override TaintKind getTaintOfMethodResult(string name) { - name = "getvalue" and - ( - result instanceof ExternalStringKind - or - result.(SequenceKind).getItem() instanceof ExternalStringKind - ) - or - name = "getfirst" and - result instanceof ExternalStringKind - or - name = "getlist" and - result.(SequenceKind).getItem() instanceof ExternalStringKind - } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - tonode.(SubscriptNode).getObject() = fromnode and - ( - result instanceof CgiFieldStorageFieldKind - or - result.(SequenceKind).getItem() instanceof CgiFieldStorageFieldKind - ) - } -} - -/** TaintKind for the field of a parsed HTTP form. */ -deprecated class CgiFieldStorageFieldKind extends TaintKind { - CgiFieldStorageFieldKind() { this = "CgiFieldStorageFieldKind" } - - override TaintKind getTaintOfAttribute(string name) { - name in ["filename", "value"] and result instanceof ExternalStringKind - or - name = "file" and result instanceof ExternalFileObject - } -} diff --git a/python/ql/lib/semmle/python/web/stdlib/Response.qll b/python/ql/lib/semmle/python/web/stdlib/Response.qll deleted file mode 100644 index 651201e204d..00000000000 --- a/python/ql/lib/semmle/python/web/stdlib/Response.qll +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Provides the sinks for HTTP servers defined with standard library (stdlib). - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http - -deprecated private predicate is_wfile(AttrNode wfile) { - exists(ClassValue cls | - // Python 2 - cls.getABaseType+() = Value::named("BaseHTTPServer.BaseHTTPRequestHandler") - or - // Python 3 - cls.getABaseType+() = Value::named("http.server.BaseHTTPRequestHandler") - | - wfile.getObject("wfile").pointsTo().getClass() = cls - ) -} - -/** Sink for `h.wfile.write` where `h` is an instance of BaseHttpRequestHandler. */ -deprecated class StdLibWFileWriteSink extends HttpResponseTaintSink { - StdLibWFileWriteSink() { - exists(CallNode call | - is_wfile(call.getFunction().(AttrNode).getObject("write")) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -/** Sink for `h.wfile.writelines` where `h` is an instance of BaseHttpRequestHandler. */ -deprecated class StdLibWFileWritelinesSink extends HttpResponseTaintSink { - StdLibWFileWritelinesSink() { - exists(CallNode call | - is_wfile(call.getFunction().(AttrNode).getObject("writelines")) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringSequenceKind } -} diff --git a/python/ql/lib/semmle/python/web/tornado/Redirect.qll b/python/ql/lib/semmle/python/web/tornado/Redirect.qll deleted file mode 100644 index 87965a9be23..00000000000 --- a/python/ql/lib/semmle/python/web/tornado/Redirect.qll +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Provides class representing the `tornado.redirect` function. - * This module is intended to be imported into a taint-tracking query - * to extend `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.Http -import Tornado - -/** - * Represents an argument to the `tornado.redirect` function. - */ -deprecated class TornadoHttpRequestHandlerRedirect extends HttpRedirectTaintSink { - override string toString() { result = "tornado.HttpRequestHandler.redirect" } - - TornadoHttpRequestHandlerRedirect() { - exists(CallNode call, ControlFlowNode node | - node = call.getFunction().(AttrNode).getObject("redirect") and - isTornadoRequestHandlerInstance(node) and - this = call.getArg(0) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } -} diff --git a/python/ql/lib/semmle/python/web/tornado/Request.qll b/python/ql/lib/semmle/python/web/tornado/Request.qll deleted file mode 100644 index 77a02c230ae..00000000000 --- a/python/ql/lib/semmle/python/web/tornado/Request.qll +++ /dev/null @@ -1,69 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http -import Tornado - -/** A tornado.request.HttpRequest object */ -deprecated class TornadoRequest extends TaintKind { - TornadoRequest() { this = "tornado.request.HttpRequest" } - - override TaintKind getTaintOfAttribute(string name) { - result instanceof ExternalStringDictKind and - ( - name = "headers" or - name = "cookies" - ) - or - result instanceof ExternalStringKind and - ( - name = "uri" or - name = "query" or - name = "body" - ) - or - result instanceof ExternalStringSequenceDictKind and - ( - name = "arguments" or - name = "query_arguments" or - name = "body_arguments" - ) - } -} - -deprecated class TornadoRequestSource extends HttpRequestTaintSource { - TornadoRequestSource() { isTornadoRequestHandlerInstance(this.(AttrNode).getObject("request")) } - - override string toString() { result = "Tornado request source" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoRequest } -} - -deprecated class TornadoExternalInputSource extends HttpRequestTaintSource { - TornadoExternalInputSource() { - exists(string name | - name in ["get_argument", "get_query_argument", "get_body_argument", "decode_argument"] - | - this = callToNamedTornadoRequestHandlerMethod(name) - ) - } - - override string toString() { result = "Tornado request method" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } -} - -deprecated class TornadoExternalInputListSource extends HttpRequestTaintSource { - TornadoExternalInputListSource() { - exists(string name | - name = "get_arguments" or - name = "get_query_arguments" or - name = "get_body_arguments" - | - this = callToNamedTornadoRequestHandlerMethod(name) - ) - } - - override string toString() { result = "Tornado request method" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } -} diff --git a/python/ql/lib/semmle/python/web/tornado/Response.qll b/python/ql/lib/semmle/python/web/tornado/Response.qll deleted file mode 100644 index fed57b14a02..00000000000 --- a/python/ql/lib/semmle/python/web/tornado/Response.qll +++ /dev/null @@ -1,47 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -private import semmle.python.web.Http -import Tornado - -deprecated class TornadoConnection extends TaintKind { - TornadoConnection() { this = "tornado.http.connection" } -} - -deprecated class TornadoConnectionSource extends TaintSource { - TornadoConnectionSource() { - isTornadoRequestHandlerInstance(this.(AttrNode).getObject("connection")) - } - - override string toString() { result = "Tornado http connection source" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoConnection } -} - -deprecated class TornadoConnectionWrite extends HttpResponseTaintSink { - override string toString() { result = "tornado.connection.write" } - - TornadoConnectionWrite() { - exists(CallNode call, ControlFlowNode conn | - conn = call.getFunction().(AttrNode).getObject("write") and - this = call.getAnArg() and - exists(TornadoConnection tc | tc.taints(conn)) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } -} - -deprecated class TornadoHttpRequestHandlerWrite extends HttpResponseTaintSink { - override string toString() { result = "tornado.HttpRequestHandler.write" } - - TornadoHttpRequestHandlerWrite() { - exists(CallNode call, ControlFlowNode node | - node = call.getFunction().(AttrNode).getObject("write") and - this = call.getAnArg() and - isTornadoRequestHandlerInstance(node) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } -} diff --git a/python/ql/lib/semmle/python/web/tornado/Tornado.qll b/python/ql/lib/semmle/python/web/tornado/Tornado.qll deleted file mode 100644 index 798ecff43ff..00000000000 --- a/python/ql/lib/semmle/python/web/tornado/Tornado.qll +++ /dev/null @@ -1,50 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http - -deprecated private ClassValue theTornadoRequestHandlerClass() { - result = Value::named("tornado.web.RequestHandler") -} - -deprecated ClassValue aTornadoRequestHandlerClass() { - result.getABaseType+() = theTornadoRequestHandlerClass() -} - -/** - * Holds if `node` is likely to refer to an instance of a tornado - * `RequestHandler` class. - */ -deprecated predicate isTornadoRequestHandlerInstance(ControlFlowNode node) { - node.pointsTo().getClass() = aTornadoRequestHandlerClass() - or - /* - * In some cases, the points-to analysis won't capture all instances we care - * about. For these, we use the following syntactic check. First, that - * `node` appears inside a method of a subclass of - * `tornado.web.RequestHandler`: - */ - - node.getScope().getEnclosingScope() = aTornadoRequestHandlerClass().getScope() and - /* Secondly, that `node` refers to the `self` argument: */ - node.isLoad() and - node.(NameNode).isSelf() -} - -deprecated CallNode callToNamedTornadoRequestHandlerMethod(string name) { - isTornadoRequestHandlerInstance(result.getFunction().(AttrNode).getObject(name)) -} - -deprecated class TornadoCookieSet extends CookieSet, CallNode { - TornadoCookieSet() { - exists(ControlFlowNode f | - f = this.getFunction().(AttrNode).getObject("set_cookie") and - isTornadoRequestHandlerInstance(f) - ) - } - - override string toString() { result = CallNode.super.toString() } - - override ControlFlowNode getKey() { result = this.getArg(0) } - - override ControlFlowNode getValue() { result = this.getArg(1) } -} diff --git a/python/ql/lib/semmle/python/web/turbogears/Request.qll b/python/ql/lib/semmle/python/web/turbogears/Request.qll deleted file mode 100644 index 48e063d0f99..00000000000 --- a/python/ql/lib/semmle/python/web/turbogears/Request.qll +++ /dev/null @@ -1,26 +0,0 @@ -import python -import semmle.python.security.strings.External -import semmle.python.web.Http -import TurboGears - -deprecated private class ValidatedMethodParameter extends Parameter { - ValidatedMethodParameter() { - exists(string name, TurboGearsControllerMethod method | - method.getArgByName(name) = this and - method.getValidationDict().getItem(_).(KeyValuePair).getKey().(StrConst).getText() = name - ) - } -} - -deprecated class UnvalidatedControllerMethodParameter extends HttpRequestTaintSource { - UnvalidatedControllerMethodParameter() { - exists(Parameter p | - any(TurboGearsControllerMethod m | not m.getName() = "onerror").getAnArg() = p and - not p instanceof ValidatedMethodParameter and - not p.isSelf() and - p.(Name).getAFlowNode() = this - ) - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/lib/semmle/python/web/turbogears/Response.qll b/python/ql/lib/semmle/python/web/turbogears/Response.qll deleted file mode 100644 index 331de6bce48..00000000000 --- a/python/ql/lib/semmle/python/web/turbogears/Response.qll +++ /dev/null @@ -1,31 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic -import semmle.python.web.Http -import TurboGears - -deprecated class ControllerMethodReturnValue extends HttpResponseTaintSink { - override string toString() { result = "TurboGears ControllerMethodReturnValue" } - - ControllerMethodReturnValue() { - exists(TurboGearsControllerMethod m | - m.getAReturnValueFlowNode() = this and - not m.isTemplated() - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof StringKind } -} - -deprecated class ControllerMethodTemplatedReturnValue extends HttpResponseTaintSink { - override string toString() { result = "TurboGears ControllerMethodTemplatedReturnValue" } - - ControllerMethodTemplatedReturnValue() { - exists(TurboGearsControllerMethod m | - m.getAReturnValueFlowNode() = this and - m.isTemplated() - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringDictKind } -} diff --git a/python/ql/lib/semmle/python/web/turbogears/TurboGears.qll b/python/ql/lib/semmle/python/web/turbogears/TurboGears.qll deleted file mode 100644 index 87006afe03a..00000000000 --- a/python/ql/lib/semmle/python/web/turbogears/TurboGears.qll +++ /dev/null @@ -1,37 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking - -deprecated private ClassValue theTurboGearsControllerClass() { - result = Value::named("tg.TGController") -} - -deprecated ClassValue aTurboGearsControllerClass() { - result.getABaseType+() = theTurboGearsControllerClass() -} - -deprecated class TurboGearsControllerMethod extends Function { - ControlFlowNode decorator; - - TurboGearsControllerMethod() { - aTurboGearsControllerClass().getScope() = this.getScope() and - decorator = this.getADecorator().getAFlowNode() and - /* Is decorated with @expose() or @expose(path) */ - ( - decorator.(CallNode).getFunction().(NameNode).getId() = "expose" - or - decorator.pointsTo().getClass() = Value::named("tg.expose") - ) - } - - private ControlFlowNode templateName() { result = decorator.(CallNode).getArg(0) } - - predicate isTemplated() { exists(this.templateName()) } - - Dict getValidationDict() { - exists(Call call | - call = this.getADecorator() and - call.getFunc().(Name).getId() = "validate" and - call.getArg(0).pointsTo(_, result) - ) - } -} diff --git a/python/ql/lib/semmle/python/web/twisted/Request.qll b/python/ql/lib/semmle/python/web/twisted/Request.qll deleted file mode 100644 index d1bcf879f0f..00000000000 --- a/python/ql/lib/semmle/python/web/twisted/Request.qll +++ /dev/null @@ -1,30 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http -import Twisted - -/** A twisted.web.http.Request object */ -deprecated class TwistedRequest extends TaintKind { - TwistedRequest() { this = "twisted.request.http.Request" } - - override TaintKind getTaintOfAttribute(string name) { - result instanceof ExternalStringSequenceDictKind and - name = "args" - or - result instanceof ExternalStringKind and - name = "uri" - } - - override TaintKind getTaintOfMethodResult(string name) { - name in ["getHeader", "getCookie", "getUser", "getPassword"] and - result instanceof ExternalStringKind - } -} - -deprecated class TwistedRequestSource extends HttpRequestTaintSource { - TwistedRequestSource() { isTwistedRequestInstance(this) } - - override string toString() { result = "Twisted request source" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof TwistedRequest } -} diff --git a/python/ql/lib/semmle/python/web/twisted/Response.qll b/python/ql/lib/semmle/python/web/twisted/Response.qll deleted file mode 100644 index 65313ab5280..00000000000 --- a/python/ql/lib/semmle/python/web/twisted/Response.qll +++ /dev/null @@ -1,45 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http -import semmle.python.security.strings.Basic -import Twisted -import Request - -deprecated class TwistedResponse extends HttpResponseTaintSink { - TwistedResponse() { - exists(PythonFunctionValue func, string name | - isKnownRequestHandlerMethodName(name) and - name = func.getName() and - func = getTwistedRequestHandlerMethod(name) and - this = func.getAReturnedNode() - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "Twisted response" } -} - -/** - * A sink of taint in the form of a "setter" method on a twisted request - * object, which affects the properties of the subsequent response sent to this - * request. - */ -deprecated class TwistedRequestSetter extends HttpResponseTaintSink { - TwistedRequestSetter() { - exists(CallNode call, ControlFlowNode node, string name | - ( - name = "setHeader" or - name = "addCookie" or - name = "write" - ) and - any(TwistedRequest t).taints(node) and - node = call.getFunction().(AttrNode).getObject(name) and - this = call.getAnArg() - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "Twisted request setter" } -} diff --git a/python/ql/lib/semmle/python/web/twisted/Twisted.qll b/python/ql/lib/semmle/python/web/twisted/Twisted.qll deleted file mode 100644 index 54dd1d959e8..00000000000 --- a/python/ql/lib/semmle/python/web/twisted/Twisted.qll +++ /dev/null @@ -1,52 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking - -deprecated private ClassValue theTwistedHttpRequestClass() { - result = Value::named("twisted.web.http.Request") -} - -deprecated private ClassValue theTwistedHttpResourceClass() { - result = Value::named("twisted.web.resource.Resource") -} - -deprecated ClassValue aTwistedRequestHandlerClass() { - result.getABaseType+() = theTwistedHttpResourceClass() -} - -deprecated FunctionValue getTwistedRequestHandlerMethod(string name) { - result = aTwistedRequestHandlerClass().declaredAttribute(name) -} - -bindingset[name] -deprecated predicate isKnownRequestHandlerMethodName(string name) { - name = "render" or - name.matches("render_%") -} - -/** - * Holds if `node` is likely to refer to an instance of the twisted - * `Request` class. - */ -deprecated predicate isTwistedRequestInstance(NameNode node) { - node.pointsTo().getClass() = theTwistedHttpRequestClass() - or - /* - * In points-to analysis cannot infer that a given object is an instance of - * the `twisted.web.http.Request` class, we also include any parameter - * called `request` that appears inside a subclass of a request handler - * class, and the appropriate arguments of known request handler methods. - */ - - exists(Function func | - func = node.getScope() and - func.getEnclosingScope() = aTwistedRequestHandlerClass().getScope() - | - /* Any parameter called `request` */ - node.getId() = "request" and - node.isParameter() - or - /* Any request parameter of a known request handler method */ - isKnownRequestHandlerMethodName(func.getName()) and - node.getNode() = func.getArg(1) - ) -} diff --git a/python/ql/lib/semmle/python/web/webob/Request.qll b/python/ql/lib/semmle/python/web/webob/Request.qll deleted file mode 100644 index 3c085b1d02d..00000000000 --- a/python/ql/lib/semmle/python/web/webob/Request.qll +++ /dev/null @@ -1,38 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.Http - -abstract deprecated class BaseWebobRequest extends TaintKind { - bindingset[this] - BaseWebobRequest() { any() } - - override TaintKind getTaintOfAttribute(string name) { - result instanceof ExternalStringDictKind and - ( - name = "GET" or - name = "POST" or - name = "headers" - ) - or - result instanceof ExternalStringKind and - name = "body" - } - - override TaintKind getTaintOfMethodResult(string name) { - result = this and - ( - name = "copy" or - name = "copy_get" or - name = "copy_body" - ) - or - result instanceof ExternalStringKind and - name = "as_bytes" - } -} - -deprecated class WebobRequest extends BaseWebobRequest { - WebobRequest() { this = "webob.Request" } - - override ClassValue getType() { result = Value::named("webob.request.Request") } -} diff --git a/python/ql/src/experimental/Security/CWE-074/JinjaBad.py b/python/ql/src/experimental/Security/CWE-074/JinjaBad.py deleted file mode 100644 index aaac3ec819e..00000000000 --- a/python/ql/src/experimental/Security/CWE-074/JinjaBad.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from jinja2 import Template as Jinja2_Template -from jinja2 import Environment, DictLoader, escape - - -def a(request): - # Load the template - template = request.GET['template'] - t = Jinja2_Template(template) - name = request.GET['name'] - # Render the template with the context data - html = t.render(name=escape(name)) - return HttpResponse(html) - - -urlpatterns = [ - path('a', a), -] diff --git a/python/ql/src/experimental/Security/CWE-074/JinjaGood.py b/python/ql/src/experimental/Security/CWE-074/JinjaGood.py deleted file mode 100644 index a1b60561850..00000000000 --- a/python/ql/src/experimental/Security/CWE-074/JinjaGood.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from jinja2 import Template as Jinja2_Template -from jinja2 import Environment, DictLoader, escape - - -def a(request): - # Load the template - template = request.GET['template'] - env = SandboxedEnvironment(undefined=StrictUndefined) - t = env.from_string(template) - name = request.GET['name'] - # Render the template with the context data - html = t.render(name=escape(name)) - return HttpResponse(html) - - -urlpatterns = [ - path('a', a), -] diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp deleted file mode 100644 index b044243fc8e..00000000000 --- a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp +++ /dev/null @@ -1,24 +0,0 @@ -<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> -<qhelp> - <overview> - <p> - Template Injection occurs when user input is embedded in a template in an unsafe manner. - When an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side is results in Server Side Template Injection. - </p> - </overview> - <recommendation> - <p> - To fix this, ensure that an untrusted value is not used as a template. If the application requirements do not alow this, use a sandboxed environment where access to unsafe attributes and methods is prohibited. - </p> - </recommendation> - <example> - <p>Consider the example given below, an untrusted HTTP parameter `template` is used to generate a Jinja2 template string. This can lead to remote code execution. </p> - <sample src="JinjaBad.py" /> - - <p>Here we have fixed the problem by using the Jinja sandbox environment for evaluating untrusted code.</p> - <sample src="JinjaGood.py" /> - </example> - <references> - <li>Portswigger : [Server Side Template Injection](https://portswigger.net/web-security/server-side-template-injection)</li> - </references> -</qhelp> diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql b/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql deleted file mode 100644 index cbc3536ad7d..00000000000 --- a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @name Server Side Template Injection - * @description Using user-controlled data to create a template can cause security issues. - * @kind path-problem - * @problem.severity error - * @precision high - * @id py/template-injection - * @tags security - * experimental - * external/cwe/cwe-074 - */ - -import python -import semmle.python.security.Paths -/* Sources */ -import semmle.python.web.HttpRequest -/* Sinks */ -import experimental.semmle.python.templates.Ssti -/* Flow */ -import semmle.python.security.strings.Untrusted - -class TemplateInjectionConfiguration extends TaintTracking::Configuration { - TemplateInjectionConfiguration() { this = "Template injection configuration" } - - deprecated override predicate isSource(TaintTracking::Source source) { - source instanceof HttpRequestTaintSource - } - - deprecated override predicate isSink(TaintTracking::Sink sink) { sink instanceof SSTISink } -} - -from TemplateInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink -where config.hasFlowPath(src, sink) -select sink.getSink(), src, sink, "This Template depends on $@.", src.getSource(), - "a user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-091/Xslt.qhelp b/python/ql/src/experimental/Security/CWE-091/Xslt.qhelp deleted file mode 100644 index 307314f00df..00000000000 --- a/python/ql/src/experimental/Security/CWE-091/Xslt.qhelp +++ /dev/null @@ -1,18 +0,0 @@ -<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> -<qhelp> - <overview> - <p> - Processing an unvalidated XSL stylesheet can allow an attacker to change the structure and contents of the resultant XML, include arbitrary files from the file system, or execute arbitrary code. - </p> - </overview> - <recommendation> - <p> - This vulnerability can be prevented by not allowing untrusted user input to be passed as an XSL stylesheet. - If the application logic necessitates processing untrusted XSL stylesheets, the input should be properly filtered and sanitized before use. - </p> - </recommendation> - <example> - <p>In the example below, the XSL stylesheet is controlled by the user and hence leads to a vulnerability.</p> - <sample src="xslt.py" /> - </example> -</qhelp> diff --git a/python/ql/src/experimental/Security/CWE-091/Xslt.ql b/python/ql/src/experimental/Security/CWE-091/Xslt.ql deleted file mode 100644 index 77f405f5f5a..00000000000 --- a/python/ql/src/experimental/Security/CWE-091/Xslt.ql +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @name XSLT query built from user-controlled sources - * @description Building a XSLT query from user-controlled sources is vulnerable to insertion of - * malicious XSLT code by the user. - * @kind path-problem - * @problem.severity error - * @precision high - * @id py/xslt-injection - * @tags security - * experimental - * external/cwe/cwe-643 - */ - -import python -import semmle.python.security.Paths -/* Sources */ -import semmle.python.web.HttpRequest -/* Sinks */ -import experimental.semmle.python.security.injection.XSLT - -class XsltInjectionConfiguration extends TaintTracking::Configuration { - XsltInjectionConfiguration() { this = "XSLT injection configuration" } - - deprecated override predicate isSource(TaintTracking::Source source) { - source instanceof HttpRequestTaintSource - } - - deprecated override predicate isSink(TaintTracking::Sink sink) { - sink instanceof XSLTInjection::XSLTInjectionSink - } -} - -from XsltInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink -where config.hasFlowPath(src, sink) -select sink.getSink(), src, sink, "This XSLT query depends on $@.", src.getSource(), - "a user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-091/xslt.py b/python/ql/src/experimental/Security/CWE-091/xslt.py deleted file mode 100644 index 1655916c7e0..00000000000 --- a/python/ql/src/experimental/Security/CWE-091/xslt.py +++ /dev/null @@ -1,14 +0,0 @@ -from lxml import etree -from io import StringIO -from flask import Flask, request - -app = Flask(__name__) - - -@app.route("/xslt") -def bad(): - xsltQuery = request.args.get('xml', '') - xslt_root = etree.XML(xsltQuery) - f = StringIO('<foo><bar></bar></foo>') - tree = etree.parse(f) - result_tree = tree.xslt(xslt_root) # Not OK diff --git a/python/ql/src/experimental/semmle/python/security/injection/XSLT.qll b/python/ql/src/experimental/semmle/python/security/injection/XSLT.qll index 4d0057f8dc1..ff3f7189b18 100644 --- a/python/ql/src/experimental/semmle/python/security/injection/XSLT.qll +++ b/python/ql/src/experimental/semmle/python/security/injection/XSLT.qll @@ -8,7 +8,6 @@ import python import semmle.python.dataflow.TaintTracking -import semmle.python.web.HttpRequest /** Models XSLT Injection related classes and functions */ module XsltInjection { @@ -21,21 +20,6 @@ module XsltInjection { /** DEPRECATED: Alias for XsltInjectionSink */ deprecated class XSLTInjectionSink = XsltInjectionSink; - /** - * A kind of "taint", representing an untrusted XML string - */ - deprecated private class ExternalXmlStringKind extends ExternalStringKind { - ExternalXmlStringKind() { this = "etree.XML string" } - - override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { - etreeXml(fromnode, tonode) and result instanceof ExternalXmlKind - or - etreeFromStringList(fromnode, tonode) and result instanceof ExternalXmlKind - or - etreeFromString(fromnode, tonode) and result instanceof ExternalXmlKind - } - } - /** * A kind of "taint", representing a XML encoded string */ @@ -43,32 +27,6 @@ module XsltInjection { ExternalXmlKind() { this = "lxml etree xml" } } - private predicate etreeXml(ControlFlowNode fromnode, CallNode tonode) { - // etree.XML("<xmlContent>") - exists(CallNode call | call.getFunction().(AttrNode).getObject("XML").pointsTo(etree()) | - call.getArg(0) = fromnode and - call = tonode - ) - } - - private predicate etreeFromString(ControlFlowNode fromnode, CallNode tonode) { - // etree.fromstring(text, parser=None) - exists(CallNode call | call.getFunction().(AttrNode).getObject("fromstring").pointsTo(etree()) | - call.getArg(0) = fromnode and - call = tonode - ) - } - - private predicate etreeFromStringList(ControlFlowNode fromnode, CallNode tonode) { - // etree.fromstringlist(strings, parser=None) - exists(CallNode call | - call.getFunction().(AttrNode).getObject("fromstringlist").pointsTo(etree()) - | - call.getArg(0) = fromnode and - call = tonode - ) - } - /** * A Sink representing an argument to the `etree.XSLT` call. * diff --git a/python/ql/src/experimental/semmle/python/templates/Airspeed.qll b/python/ql/src/experimental/semmle/python/templates/Airspeed.qll deleted file mode 100644 index dc266ac0f82..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Airspeed.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** Provides classes which model the `airspeed` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the ClassValue representing `airspeed.Template` */ -deprecated ClassValue theAirspeedTemplateClass() { result = Value::named("airspeed.Template") } - -/** - * A sink representing the `airspeed.Template` class instantiation argument. - * - * import airspeed - * temp = airspeed.Template(`"sink"`) - */ -deprecated class AirspeedTemplateSink extends SSTISink { - override string toString() { result = "argument to airspeed.Template()" } - - AirspeedTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theAirspeedTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/Bottle.qll b/python/ql/src/experimental/semmle/python/templates/Bottle.qll deleted file mode 100644 index 1f5bd2bba85..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Bottle.qll +++ /dev/null @@ -1,48 +0,0 @@ -/** Provides classes which model the `bottle` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the ClassValue representing `bottle.SimpleTemplate` */ -deprecated ClassValue theBottleSimpleTemplateClass() { - result = Value::named("bottle.SimpleTemplate") -} - -/** - * A sink representing the `bottle.SimpleTemplate` class instantiation argument. - * - * from bottle import SimpleTemplate - * template = SimpleTemplate(`sink`) - */ -deprecated class BottleSimpleTemplateSink extends SSTISink { - override string toString() { result = "argument to bottle.SimpleTemplate()" } - - BottleSimpleTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theBottleSimpleTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -/** - * A sink representing the `bottle.template` function call argument. - * - * from bottle import template - * tmp = template(`sink`) - */ -deprecated class BottleTemplateSink extends SSTISink { - override string toString() { result = "argument to bottle.template()" } - - BottleTemplateSink() { - exists(CallNode call | - call.getFunction() = theBottleModule().attr("template").getAReference() and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/Chameleon.qll b/python/ql/src/experimental/semmle/python/templates/Chameleon.qll deleted file mode 100644 index f094dda97b5..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Chameleon.qll +++ /dev/null @@ -1,29 +0,0 @@ -/** Provides classes which model the `Chameleon` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the ClassValue representing `chameleon.PageTemplate` */ -deprecated ClassValue theChameleonPageTemplateClass() { - result = Value::named("chameleon.PageTemplate") -} - -/** - * A sink representing the `chameleon.PageTemplate` class instantiation argument. - * - * from chameleon import PageTemplate - * template = PageTemplate(`sink`) - */ -deprecated class ChameleonTemplateSink extends SSTISink { - override string toString() { result = "argument to Chameleon.PageTemplate()" } - - ChameleonTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theChameleonPageTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/Cheetah.qll b/python/ql/src/experimental/semmle/python/templates/Cheetah.qll deleted file mode 100644 index 9812fdb7c88..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Cheetah.qll +++ /dev/null @@ -1,39 +0,0 @@ -/** Provides classes which model the `Cheetah3` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the ClassValue representing `Cheetah.Template.Template` */ -deprecated ClassValue theCheetahTemplateClass() { - result = Value::named("Cheetah.Template.Template") -} - -/** - * A sink representing the instantiation argument of any class which derives from - * the `Cheetah.Template.Template` class . - * - * from Cheetah.Template import Template - * class Template3(Template): - * title = 'Hello World Example!' - * contents = 'Hello World!' - * t3 = Template3("sink") - * - * This will also detect cases of the following type : - * - * from Cheetah.Template import Template - * t3 = Template("sink") - */ -deprecated class CheetahTemplateInstantiationSink extends SSTISink { - override string toString() { result = "argument to Cheetah.Template.Template()" } - - CheetahTemplateInstantiationSink() { - exists(CallNode call, ClassValue cv | - cv.getASuperType() = theCheetahTemplateClass() and - call.getFunction().pointsTo(cv) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/Chevron.qll b/python/ql/src/experimental/semmle/python/templates/Chevron.qll deleted file mode 100644 index cc93016891c..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Chevron.qll +++ /dev/null @@ -1,36 +0,0 @@ -/** Provides classes which model the `chevron` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the Value representing `chevron.render` function */ -deprecated Value theChevronRenderFunc() { result = Value::named("chevron.render") } - -/** - * A sink representing the `chevron.render` function call argument. - * - * import chevron - * tmp = chevron.render(`sink`,{ 'key' : 'value' }) - */ -deprecated class ChevronRenderSink extends SSTISink { - override string toString() { result = "argument to chevron.render()" } - - ChevronRenderSink() { - exists(CallNode call | - call.getFunction() = theChevronRenderFunc().getAReference() and - call.getArg(0) = this - ) - // TODO: this should also detect : - // import chevron - // args = { - // 'template': 'sink', - // 'data': { - // 'mustache': 'World' - // } - // } - // chevron.render(**args) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/DjangoTemplate.qll b/python/ql/src/experimental/semmle/python/templates/DjangoTemplate.qll deleted file mode 100644 index 1089ab872ec..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/DjangoTemplate.qll +++ /dev/null @@ -1,35 +0,0 @@ -/** Provides classes which model the `DjangoTemplate` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -deprecated ClassValue theDjangoTemplateClass() { result = Value::named("django.template.Template") } - -/** - * A sink representing `django.template.Template` class instantiation argument. - * - * from django.template import Template - * template = Template(`sink`) - */ -deprecated class DjangoTemplateTemplateSink extends SSTISink { - override string toString() { result = "argument to Django.template()" } - - DjangoTemplateTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theDjangoTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} -// TODO (intentionally commented out QLDoc, since qlformat will delete those lines otherwise) -// /** -// * Sinks representing the django.template.Template class instantiation. -// * -// * from django.template import engines -// * -// * django_engine = engines["django"] -// * template = django_engine.from_string(`sink`) -// */ diff --git a/python/ql/src/experimental/semmle/python/templates/FlaskTemplate.qll b/python/ql/src/experimental/semmle/python/templates/FlaskTemplate.qll deleted file mode 100644 index c0f3c90235d..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/FlaskTemplate.qll +++ /dev/null @@ -1,28 +0,0 @@ -/** Provides classes which model templates in the`flask` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -deprecated Value theFlaskRenderTemplateClass() { - result = Value::named("flask.render_template_string") -} - -/** - * A sink representing `flask.render_template_string` function call argument. - * - * from flask import render_template_string - * render_template_string(`sink`) - */ -deprecated class FlaskTemplateSink extends SSTISink { - override string toString() { result = "argument to flask.render_template_string()" } - - FlaskTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theFlaskRenderTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/Genshi.qll b/python/ql/src/experimental/semmle/python/templates/Genshi.qll deleted file mode 100644 index c808d7c60f8..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Genshi.qll +++ /dev/null @@ -1,53 +0,0 @@ -/** Provides classes which model the `Genshi` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the ClassValue representing `Genshi.template.TextTemplate` */ -deprecated ClassValue theGenshiTextTemplateClass() { - result = Value::named("genshi.template.TextTemplate") -} - -/** returns the ClassValue representing `Genshi.template.MarkupTemplate` */ -deprecated ClassValue theGenshiMarkupTemplateClass() { - result = Value::named("genshi.template.MarkupTemplate") -} - -/** - * A sink representing the `genshi.template.TextTemplate` class instantiation argument. - * - * from genshi.template import TextTemplate - * tmpl = TextTemplate('sink') - */ -deprecated class GenshiTextTemplateSink extends SSTISink { - override string toString() { result = "argument to genshi.template.TextTemplate()" } - - GenshiTextTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theGenshiTextTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -/** - * A sink representing the `genshi.template.MarkupTemplate` class instantiation argument. - * - * from genshi.template import MarkupTemplate - * tmpl = MarkupTemplate('sink') - */ -deprecated class GenshiMarkupTemplateSink extends SSTISink { - override string toString() { result = "argument to genshi.template.MarkupTemplate()" } - - GenshiMarkupTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theGenshiMarkupTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/Jinja.qll b/python/ql/src/experimental/semmle/python/templates/Jinja.qll deleted file mode 100644 index 44bc103cf04..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Jinja.qll +++ /dev/null @@ -1,49 +0,0 @@ -/** Provides classes which model the `Jinja2` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the ClassValue representing `jinja2.Template` */ -deprecated ClassValue theJinja2TemplateClass() { result = Value::named("jinja2.Template") } - -/** returns the ClassValue representing `jinja2.Template` */ -deprecated Value theJinja2FromStringValue() { result = Value::named("jinja2.from_string") } - -/** - * A sink representing the `jinja2.Template` class instantiation argument. - * - * from jinja2 import Template - * template = Template(`sink`) - */ -deprecated class Jinja2TemplateSink extends SSTISink { - override string toString() { result = "argument to jinja2.Template()" } - - Jinja2TemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theJinja2TemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} - -/** - * A sink representing the `jinja2.from_string` function call argument. - * - * from jinja2 import from_string - * template = from_string(`sink`) - */ -deprecated class Jinja2FromStringSink extends SSTISink { - override string toString() { result = "argument to jinja2.from_string()" } - - Jinja2FromStringSink() { - exists(CallNode call | - call.getFunction().pointsTo(theJinja2FromStringValue()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/Mako.qll b/python/ql/src/experimental/semmle/python/templates/Mako.qll deleted file mode 100644 index b8634b3001a..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Mako.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** Provides classes which model the `Mako` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the ClassValue representing `mako.template.Template` */ -deprecated ClassValue theMakoTemplateClass() { result = Value::named("mako.template.Template") } - -/** - * A sink representing the `mako.template.Template` class instantiation argument. - * - * from mako.template import Template - * mytemplate = Template("hello world!") - */ -deprecated class MakoTemplateSink extends SSTISink { - override string toString() { result = "argument to mako.template.Template()" } - - MakoTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theMakoTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/src/experimental/semmle/python/templates/SSTISink.qll b/python/ql/src/experimental/semmle/python/templates/SSTISink.qll deleted file mode 100644 index 1a68fe17b68..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/SSTISink.qll +++ /dev/null @@ -1,7 +0,0 @@ -import semmle.python.dataflow.TaintTracking - -/** - * A generic taint sink that is vulnerable to template inclusions. - * The `temp` in `jinja2.Template(temp)` and similar. - */ -abstract deprecated class SSTISink extends TaintSink { } diff --git a/python/ql/src/experimental/semmle/python/templates/Ssti.qll b/python/ql/src/experimental/semmle/python/templates/Ssti.qll deleted file mode 100644 index eb4f8d0ec2f..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/Ssti.qll +++ /dev/null @@ -1,13 +0,0 @@ -/** Imports all files which model potential SSTI sinks */ - -import experimental.semmle.python.templates.Airspeed -import experimental.semmle.python.templates.Bottle -import experimental.semmle.python.templates.Chameleon -import experimental.semmle.python.templates.Cheetah -import experimental.semmle.python.templates.Chevron -import experimental.semmle.python.templates.DjangoTemplate -import experimental.semmle.python.templates.FlaskTemplate -import experimental.semmle.python.templates.Genshi -import experimental.semmle.python.templates.Jinja -import experimental.semmle.python.templates.Mako -import experimental.semmle.python.templates.TRender diff --git a/python/ql/src/experimental/semmle/python/templates/TRender.qll b/python/ql/src/experimental/semmle/python/templates/TRender.qll deleted file mode 100644 index 8d5431ad9e0..00000000000 --- a/python/ql/src/experimental/semmle/python/templates/TRender.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** Provides classes which model the `TRender` package. */ - -import python -import semmle.python.web.HttpRequest -import experimental.semmle.python.templates.SSTISink - -/** returns the ClassValue representing `trender.TRender` */ -deprecated ClassValue theTRenderTemplateClass() { result = Value::named("trender.TRender") } - -/** - * A sink representing the `trender.TRender` class instantiation argument. - * - * from trender import TRender - * template = TRender(`sink`) - */ -deprecated class TRenderTemplateSink extends SSTISink { - override string toString() { result = "argument to trender.TRender()" } - - TRenderTemplateSink() { - exists(CallNode call | - call.getFunction().pointsTo(theTRenderTemplateClass()) and - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } -} diff --git a/python/ql/test/3/library-tests/taint/strings/Taint.qll b/python/ql/test/3/library-tests/taint/strings/Taint.qll deleted file mode 100644 index 3368a1c4f70..00000000000 --- a/python/ql/test/3/library-tests/taint/strings/Taint.qll +++ /dev/null @@ -1,44 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.security.Exceptions - -class SimpleSource extends TaintSource { - SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "taint source" } -} - -class ListSource extends TaintSource { - ListSource() { this.(NameNode).getId() = "TAINTED_LIST" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } - - override string toString() { result = "list taint source" } -} - -class DictSource extends TaintSource { - DictSource() { this.(NameNode).getId() = "TAINTED_DICT" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } - - override string toString() { result = "dict taint source" } -} - -class ExceptionInfoSource extends TaintSource { - ExceptionInfoSource() { this.(NameNode).getId() = "TAINTED_EXCEPTION_INFO" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo } - - override string toString() { result = "Exception info source" } -} - -class ExternalFileObjectSource extends TaintSource { - ExternalFileObjectSource() { this.(NameNode).getId() = "TAINTED_FILE" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalFileObject } - - override string toString() { result = "Tainted file source" } -} diff --git a/python/ql/test/3/library-tests/taint/strings/TestTaint.expected b/python/ql/test/3/library-tests/taint/strings/TestTaint.expected deleted file mode 100644 index 3e5e988f825..00000000000 --- a/python/ql/test/3/library-tests/taint/strings/TestTaint.expected +++ /dev/null @@ -1 +0,0 @@ -| test.py:4 | ok | fstring | Fstring | externally controlled string | diff --git a/python/ql/test/3/library-tests/taint/strings/TestTaint.ql b/python/ql/test/3/library-tests/taint/strings/TestTaint.ql deleted file mode 100644 index 7b9c6025c9d..00000000000 --- a/python/ql/test/3/library-tests/taint/strings/TestTaint.ql +++ /dev/null @@ -1,33 +0,0 @@ -import python -import semmle.python.security.TaintTracking -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted -import Taint - -from - Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res, - string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - ( - call.getFunc().(Name).getId() = "ensure_tainted" and - expected_taint = true - or - call.getFunc().(Name).getId() = "ensure_not_tainted" and - expected_taint = false - ) and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "<NO TAINT>" and - has_taint = false - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) and - has_taint = true - ) and - if expected_taint = has_taint then test_res = "ok " else test_res = "fail" -// if expected_taint = has_taint then test_res = "✓" else test_res = "✕" -select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(), - taint_string diff --git a/python/ql/test/3/library-tests/taint/strings/test.py b/python/ql/test/3/library-tests/taint/strings/test.py deleted file mode 100644 index e1c25b5dccc..00000000000 --- a/python/ql/test/3/library-tests/taint/strings/test.py +++ /dev/null @@ -1,5 +0,0 @@ -def fstring(): - tainted_string = TAINTED_STRING - ensure_tainted( - f"foo {tainted_string} bar" - ) diff --git a/python/ql/test/3/library-tests/taint/unpacking/Taint.qll b/python/ql/test/3/library-tests/taint/unpacking/Taint.qll deleted file mode 100644 index 010b9738c5c..00000000000 --- a/python/ql/test/3/library-tests/taint/unpacking/Taint.qll +++ /dev/null @@ -1,27 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -class SimpleSource extends TaintSource { - SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "taint source" } -} - -class ListSource extends TaintSource { - ListSource() { this.(NameNode).getId() = "TAINTED_LIST" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } - - override string toString() { result = "list taint source" } -} - -class DictSource extends TaintSource { - DictSource() { this.(NameNode).getId() = "TAINTED_DICT" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } - - override string toString() { result = "dict taint source" } -} diff --git a/python/ql/test/3/library-tests/taint/unpacking/TestTaint.expected b/python/ql/test/3/library-tests/taint/unpacking/TestTaint.expected deleted file mode 100644 index b6aacc7d670..00000000000 --- a/python/ql/test/3/library-tests/taint/unpacking/TestTaint.expected +++ /dev/null @@ -1,9 +0,0 @@ -| test.py:11 | extended_unpacking | first | externally controlled string | -| test.py:11 | extended_unpacking | last | externally controlled string | -| test.py:11 | extended_unpacking | rest | [externally controlled string] | -| test.py:16 | also_allowed | a | [externally controlled string] | -| test.py:24 | also_allowed | b | NO TAINT | -| test.py:24 | also_allowed | c | NO TAINT | -| test.py:31 | nested | x | externally controlled string | -| test.py:31 | nested | xs | [externally controlled string] | -| test.py:31 | nested | ys | [externally controlled string] | diff --git a/python/ql/test/3/library-tests/taint/unpacking/TestTaint.ql b/python/ql/test/3/library-tests/taint/unpacking/TestTaint.ql deleted file mode 100644 index 47883578516..00000000000 --- a/python/ql/test/3/library-tests/taint/unpacking/TestTaint.ql +++ /dev/null @@ -1,19 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from Call call, Expr arg, string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - call.getFunc().(Name).getId() = "test" and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "NO TAINT" - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) - ) -select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(), - taint_string diff --git a/python/ql/test/3/library-tests/taint/unpacking/test.py b/python/ql/test/3/library-tests/taint/unpacking/test.py deleted file mode 100644 index 6807ddebee8..00000000000 --- a/python/ql/test/3/library-tests/taint/unpacking/test.py +++ /dev/null @@ -1,31 +0,0 @@ -# Extended Iterable Unpacking -- PEP 3132 -# https://www.python.org/dev/peps/pep-3132/ - - -def test(*args): - pass - - -def extended_unpacking(): - first, *rest, last = TAINTED_LIST - test(first, rest, last) - - -def also_allowed(): - *a, = TAINTED_LIST - test(a) - - # for b, *c in [(1, 2, 3), (4, 5, 6, 7)]: - # print(c) - # i=0; c=[2,3] - # i=1; c=[5,6,7] - - for b, *c in [TAINTED_LIST, TAINTED_LIST]: - test(b, c) # TODO: mark `c` as [taint] - -def nested(): - l = TAINTED_LIST - ll = [l,l] - - [[x, *xs], ys] = ll - test(x, xs, ys) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.expected deleted file mode 100644 index 058a53bdf91..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.expected +++ /dev/null @@ -1,60 +0,0 @@ -edges -| AirspeedSsti.py:10:16:10:27 | dict of externally controlled string | AirspeedSsti.py:10:16:10:43 | externally controlled string | -| AirspeedSsti.py:10:16:10:27 | dict of externally controlled string | AirspeedSsti.py:10:16:10:43 | externally controlled string | -| AirspeedSsti.py:10:16:10:43 | externally controlled string | AirspeedSsti.py:11:30:11:37 | externally controlled string | -| AirspeedSsti.py:10:16:10:43 | externally controlled string | AirspeedSsti.py:11:30:11:37 | externally controlled string | -| ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:10:16:10:43 | externally controlled string | -| ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:10:16:10:43 | externally controlled string | -| ChevronSsti.py:10:16:10:43 | externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string | -| ChevronSsti.py:10:16:10:43 | externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string | -| DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | -| DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | -| DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | -| DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | -| DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | DjangoTemplates.py:8:16:8:38 | externally controlled string | -| DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | DjangoTemplates.py:8:16:8:38 | externally controlled string | -| DjangoTemplates.py:8:16:8:38 | externally controlled string | DjangoTemplates.py:9:18:9:25 | externally controlled string | -| DjangoTemplates.py:8:16:8:38 | externally controlled string | DjangoTemplates.py:9:18:9:25 | externally controlled string | -| FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string | -| FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string | -| JinjaSsti.py:7:7:7:13 | django.request.HttpRequest | JinjaSsti.py:9:16:9:22 | django.request.HttpRequest | -| JinjaSsti.py:7:7:7:13 | django.request.HttpRequest | JinjaSsti.py:9:16:9:22 | django.request.HttpRequest | -| JinjaSsti.py:9:16:9:22 | django.request.HttpRequest | JinjaSsti.py:9:16:9:26 | django.http.request.QueryDict | -| JinjaSsti.py:9:16:9:22 | django.request.HttpRequest | JinjaSsti.py:9:16:9:26 | django.http.request.QueryDict | -| JinjaSsti.py:9:16:9:26 | django.http.request.QueryDict | JinjaSsti.py:9:16:9:38 | externally controlled string | -| JinjaSsti.py:9:16:9:26 | django.http.request.QueryDict | JinjaSsti.py:9:16:9:38 | externally controlled string | -| JinjaSsti.py:9:16:9:38 | externally controlled string | JinjaSsti.py:10:25:10:32 | externally controlled string | -| JinjaSsti.py:9:16:9:38 | externally controlled string | JinjaSsti.py:10:25:10:32 | externally controlled string | -| JinjaSsti.py:16:7:16:13 | django.request.HttpRequest | JinjaSsti.py:19:16:19:22 | django.request.HttpRequest | -| JinjaSsti.py:16:7:16:13 | django.request.HttpRequest | JinjaSsti.py:19:16:19:22 | django.request.HttpRequest | -| JinjaSsti.py:19:16:19:22 | django.request.HttpRequest | JinjaSsti.py:19:16:19:26 | django.http.request.QueryDict | -| JinjaSsti.py:19:16:19:22 | django.request.HttpRequest | JinjaSsti.py:19:16:19:26 | django.http.request.QueryDict | -| JinjaSsti.py:19:16:19:26 | django.http.request.QueryDict | JinjaSsti.py:19:16:19:38 | externally controlled string | -| JinjaSsti.py:19:16:19:26 | django.http.request.QueryDict | JinjaSsti.py:19:16:19:38 | externally controlled string | -| JinjaSsti.py:19:16:19:38 | externally controlled string | JinjaSsti.py:20:28:20:35 | externally controlled string | -| JinjaSsti.py:19:16:19:38 | externally controlled string | JinjaSsti.py:20:28:20:35 | externally controlled string | -| MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:8:16:8:22 | django.request.HttpRequest | -| MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:8:16:8:22 | django.request.HttpRequest | -| MakoSsti.py:8:16:8:22 | django.request.HttpRequest | MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | -| MakoSsti.py:8:16:8:22 | django.request.HttpRequest | MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | -| MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | MakoSsti.py:8:16:8:38 | externally controlled string | -| MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | MakoSsti.py:8:16:8:38 | externally controlled string | -| MakoSsti.py:8:16:8:38 | externally controlled string | MakoSsti.py:9:27:9:34 | externally controlled string | -| MakoSsti.py:8:16:8:38 | externally controlled string | MakoSsti.py:9:27:9:34 | externally controlled string | -| TRender.py:5:13:5:19 | django.request.HttpRequest | TRender.py:6:16:6:22 | django.request.HttpRequest | -| TRender.py:5:13:5:19 | django.request.HttpRequest | TRender.py:6:16:6:22 | django.request.HttpRequest | -| TRender.py:6:16:6:22 | django.request.HttpRequest | TRender.py:6:16:6:26 | django.http.request.QueryDict | -| TRender.py:6:16:6:22 | django.request.HttpRequest | TRender.py:6:16:6:26 | django.http.request.QueryDict | -| TRender.py:6:16:6:26 | django.http.request.QueryDict | TRender.py:6:16:6:38 | externally controlled string | -| TRender.py:6:16:6:26 | django.http.request.QueryDict | TRender.py:6:16:6:38 | externally controlled string | -| TRender.py:6:16:6:38 | externally controlled string | TRender.py:7:24:7:31 | externally controlled string | -| TRender.py:6:16:6:38 | externally controlled string | TRender.py:7:24:7:31 | externally controlled string | -#select -| AirspeedSsti.py:11:30:11:37 | template | AirspeedSsti.py:10:16:10:27 | dict of externally controlled string | AirspeedSsti.py:11:30:11:37 | externally controlled string | This Template depends on $@. | AirspeedSsti.py:10:16:10:27 | Attribute | a user-provided value | -| ChevronSsti.py:11:27:11:34 | template | ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string | This Template depends on $@. | ChevronSsti.py:10:16:10:27 | Attribute | a user-provided value | -| DjangoTemplates.py:9:18:9:25 | template | DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:9:18:9:25 | externally controlled string | This Template depends on $@. | DjangoTemplates.py:6:8:6:14 | request | a user-provided value | -| FlaskTemplate.py:17:41:17:68 | Attribute() | FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string | This Template depends on $@. | FlaskTemplate.py:17:41:17:52 | Attribute | a user-provided value | -| JinjaSsti.py:10:25:10:32 | template | JinjaSsti.py:7:7:7:13 | django.request.HttpRequest | JinjaSsti.py:10:25:10:32 | externally controlled string | This Template depends on $@. | JinjaSsti.py:7:7:7:13 | request | a user-provided value | -| JinjaSsti.py:20:28:20:35 | template | JinjaSsti.py:16:7:16:13 | django.request.HttpRequest | JinjaSsti.py:20:28:20:35 | externally controlled string | This Template depends on $@. | JinjaSsti.py:16:7:16:13 | request | a user-provided value | -| MakoSsti.py:9:27:9:34 | template | MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:9:27:9:34 | externally controlled string | This Template depends on $@. | MakoSsti.py:6:10:6:16 | request | a user-provided value | -| TRender.py:7:24:7:31 | template | TRender.py:5:13:5:19 | django.request.HttpRequest | TRender.py:7:24:7:31 | externally controlled string | This Template depends on $@. | TRender.py:5:13:5:19 | request | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.qlref b/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.qlref deleted file mode 100644 index 90efec9f636..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE-074/TemplateInjection.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.expected b/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.expected deleted file mode 100644 index 89f19160f69..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.expected +++ /dev/null @@ -1,47 +0,0 @@ -edges -| xslt.py:10:17:10:28 | dict of etree.XML string | xslt.py:10:17:10:43 | etree.XML string | -| xslt.py:10:17:10:28 | dict of etree.XML string | xslt.py:10:17:10:43 | etree.XML string | -| xslt.py:10:17:10:43 | etree.XML string | xslt.py:11:27:11:35 | etree.XML string | -| xslt.py:10:17:10:43 | etree.XML string | xslt.py:11:27:11:35 | etree.XML string | -| xslt.py:11:17:11:36 | lxml etree xml | xslt.py:14:29:14:37 | lxml etree xml | -| xslt.py:11:17:11:36 | lxml etree xml | xslt.py:14:29:14:37 | lxml etree xml | -| xslt.py:11:27:11:35 | etree.XML string | xslt.py:11:17:11:36 | lxml etree xml | -| xslt.py:11:27:11:35 | etree.XML string | xslt.py:11:17:11:36 | lxml etree xml | -| xsltInjection.py:10:17:10:28 | dict of etree.XML string | xsltInjection.py:10:17:10:43 | etree.XML string | -| xsltInjection.py:10:17:10:28 | dict of etree.XML string | xsltInjection.py:10:17:10:43 | etree.XML string | -| xsltInjection.py:10:17:10:43 | etree.XML string | xsltInjection.py:11:27:11:35 | etree.XML string | -| xsltInjection.py:10:17:10:43 | etree.XML string | xsltInjection.py:11:27:11:35 | etree.XML string | -| xsltInjection.py:11:17:11:36 | lxml etree xml | xsltInjection.py:12:28:12:36 | lxml etree xml | -| xsltInjection.py:11:17:11:36 | lxml etree xml | xsltInjection.py:12:28:12:36 | lxml etree xml | -| xsltInjection.py:11:27:11:35 | etree.XML string | xsltInjection.py:11:17:11:36 | lxml etree xml | -| xsltInjection.py:11:27:11:35 | etree.XML string | xsltInjection.py:11:17:11:36 | lxml etree xml | -| xsltInjection.py:17:17:17:28 | dict of etree.XML string | xsltInjection.py:17:17:17:43 | etree.XML string | -| xsltInjection.py:17:17:17:28 | dict of etree.XML string | xsltInjection.py:17:17:17:43 | etree.XML string | -| xsltInjection.py:17:17:17:43 | etree.XML string | xsltInjection.py:18:27:18:35 | etree.XML string | -| xsltInjection.py:17:17:17:43 | etree.XML string | xsltInjection.py:18:27:18:35 | etree.XML string | -| xsltInjection.py:18:17:18:36 | lxml etree xml | xsltInjection.py:21:29:21:37 | lxml etree xml | -| xsltInjection.py:18:17:18:36 | lxml etree xml | xsltInjection.py:21:29:21:37 | lxml etree xml | -| xsltInjection.py:18:27:18:35 | etree.XML string | xsltInjection.py:18:17:18:36 | lxml etree xml | -| xsltInjection.py:18:27:18:35 | etree.XML string | xsltInjection.py:18:17:18:36 | lxml etree xml | -| xsltInjection.py:26:17:26:28 | dict of etree.XML string | xsltInjection.py:26:17:26:43 | etree.XML string | -| xsltInjection.py:26:17:26:28 | dict of etree.XML string | xsltInjection.py:26:17:26:43 | etree.XML string | -| xsltInjection.py:26:17:26:43 | etree.XML string | xsltInjection.py:27:27:27:35 | etree.XML string | -| xsltInjection.py:26:17:26:43 | etree.XML string | xsltInjection.py:27:27:27:35 | etree.XML string | -| xsltInjection.py:27:17:27:36 | lxml etree xml | xsltInjection.py:31:24:31:32 | lxml etree xml | -| xsltInjection.py:27:17:27:36 | lxml etree xml | xsltInjection.py:31:24:31:32 | lxml etree xml | -| xsltInjection.py:27:27:27:35 | etree.XML string | xsltInjection.py:27:17:27:36 | lxml etree xml | -| xsltInjection.py:27:27:27:35 | etree.XML string | xsltInjection.py:27:17:27:36 | lxml etree xml | -| xsltInjection.py:35:17:35:28 | dict of etree.XML string | xsltInjection.py:35:17:35:43 | etree.XML string | -| xsltInjection.py:35:17:35:28 | dict of etree.XML string | xsltInjection.py:35:17:35:43 | etree.XML string | -| xsltInjection.py:35:17:35:43 | etree.XML string | xsltInjection.py:36:34:36:42 | etree.XML string | -| xsltInjection.py:35:17:35:43 | etree.XML string | xsltInjection.py:36:34:36:42 | etree.XML string | -| xsltInjection.py:36:17:36:43 | lxml etree xml | xsltInjection.py:40:24:40:32 | lxml etree xml | -| xsltInjection.py:36:17:36:43 | lxml etree xml | xsltInjection.py:40:24:40:32 | lxml etree xml | -| xsltInjection.py:36:34:36:42 | etree.XML string | xsltInjection.py:36:17:36:43 | lxml etree xml | -| xsltInjection.py:36:34:36:42 | etree.XML string | xsltInjection.py:36:17:36:43 | lxml etree xml | -#select -| xslt.py:14:29:14:37 | xslt_root | xslt.py:10:17:10:28 | dict of etree.XML string | xslt.py:14:29:14:37 | lxml etree xml | This XSLT query depends on $@. | xslt.py:10:17:10:28 | Attribute | a user-provided value | -| xsltInjection.py:12:28:12:36 | xslt_root | xsltInjection.py:10:17:10:28 | dict of etree.XML string | xsltInjection.py:12:28:12:36 | lxml etree xml | This XSLT query depends on $@. | xsltInjection.py:10:17:10:28 | Attribute | a user-provided value | -| xsltInjection.py:21:29:21:37 | xslt_root | xsltInjection.py:17:17:17:28 | dict of etree.XML string | xsltInjection.py:21:29:21:37 | lxml etree xml | This XSLT query depends on $@. | xsltInjection.py:17:17:17:28 | Attribute | a user-provided value | -| xsltInjection.py:31:24:31:32 | xslt_root | xsltInjection.py:26:17:26:28 | dict of etree.XML string | xsltInjection.py:31:24:31:32 | lxml etree xml | This XSLT query depends on $@. | xsltInjection.py:26:17:26:28 | Attribute | a user-provided value | -| xsltInjection.py:40:24:40:32 | xslt_root | xsltInjection.py:35:17:35:28 | dict of etree.XML string | xsltInjection.py:40:24:40:32 | lxml etree xml | This XSLT query depends on $@. | xsltInjection.py:35:17:35:28 | Attribute | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.qlref b/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.qlref deleted file mode 100644 index 988d13e98a6..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE-091/Xslt.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091/xslt.py b/python/ql/test/experimental/query-tests/Security/CWE-091/xslt.py deleted file mode 100644 index 1655916c7e0..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-091/xslt.py +++ /dev/null @@ -1,14 +0,0 @@ -from lxml import etree -from io import StringIO -from flask import Flask, request - -app = Flask(__name__) - - -@app.route("/xslt") -def bad(): - xsltQuery = request.args.get('xml', '') - xslt_root = etree.XML(xsltQuery) - f = StringIO('<foo><bar></bar></foo>') - tree = etree.parse(f) - result_tree = tree.xslt(xslt_root) # Not OK diff --git a/python/ql/test/experimental/semmle/python/templates/Airspeed.py b/python/ql/test/experimental/semmle/python/templates/Airspeed.py deleted file mode 100644 index a41d70432a0..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/Airspeed.py +++ /dev/null @@ -1,10 +0,0 @@ -from bottle import Bottle, route, request, redirect, response -import airspeed - - -app = Bottle() - - -@route('/other') -def a(): - return airspeed.Template("sink") diff --git a/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.expected deleted file mode 100644 index e938211434c..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.expected +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (AirspeedSSTISinks.ql:4,6-14) -| Airspeed.py:10:30:10:35 | argument to airspeed.Template() | diff --git a/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.ql deleted file mode 100644 index e9c51ef11ad..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.Airspeed - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/Bottle.py b/python/ql/test/experimental/semmle/python/templates/Bottle.py deleted file mode 100644 index f6b2fec090e..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/Bottle.py +++ /dev/null @@ -1,17 +0,0 @@ -from bottle import Bottle, route, request, redirect, response, SimpleTemplate -from bottle import template as temp - - -app = Bottle() - - -@route('/other') -def a(): - template = "test" - tpl = SimpleTemplate(template) - - -@route('/other2') -def b(): - template = "test" - return temp(template, name='World') diff --git a/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.expected deleted file mode 100644 index 1802708c2de..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.expected +++ /dev/null @@ -1,3 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (BottleSSTISinks.ql:4,6-14) -| Bottle.py:11:26:11:33 | argument to bottle.SimpleTemplate() | -| Bottle.py:17:17:17:24 | argument to bottle.template() | diff --git a/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.ql deleted file mode 100644 index c0ba59ef957..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.Bottle - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/Chameleon.py b/python/ql/test/experimental/semmle/python/templates/Chameleon.py deleted file mode 100644 index 6d96f0752a9..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/Chameleon.py +++ /dev/null @@ -1,5 +0,0 @@ -from chameleon import PageTemplate - - -def chameleon(): - template = PageTemplate("sink") diff --git a/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.expected deleted file mode 100644 index d6a46986f11..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.expected +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (ChameleonSSTISinks.ql:4,6-14) -| Chameleon.py:5:29:5:34 | argument to Chameleon.PageTemplate() | diff --git a/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.ql deleted file mode 100644 index ee9d41434af..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.Chameleon - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.expected deleted file mode 100644 index 3971b25e356..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.expected +++ /dev/null @@ -1,3 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (CheetahSSTISinks.ql:4,6-14) -| CheetahSinks.py:10:21:10:26 | argument to Cheetah.Template.Template() | -| CheetahSinks.py:20:20:20:25 | argument to Cheetah.Template.Template() | diff --git a/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.ql deleted file mode 100644 index 10c6c79a4d5..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.Cheetah - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/CheetahSinks.py b/python/ql/test/experimental/semmle/python/templates/CheetahSinks.py deleted file mode 100644 index 0bb3364a178..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/CheetahSinks.py +++ /dev/null @@ -1,20 +0,0 @@ -from bottle import Bottle, route, request, redirect, response, SimpleTemplate -from Cheetah.Template import Template - - -app = Bottle() - - -@route('/other') -def a(): - return Template("sink") - - -class Template3(Template): - title = 'Hello World Example!' - contents = 'Hello World!' - - -@route('/other2') -def b(): - t3 = Template3("sink") diff --git a/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.expected deleted file mode 100644 index 50ebb008209..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.expected +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (ChevronSSTISinks.ql:4,6-14) -| ChevronSinks.py:10:27:10:32 | argument to chevron.render() | diff --git a/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.ql deleted file mode 100644 index 545c1f8f79a..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.Chevron - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/ChevronSinks.py b/python/ql/test/experimental/semmle/python/templates/ChevronSinks.py deleted file mode 100644 index 26d35708bb6..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/ChevronSinks.py +++ /dev/null @@ -1,22 +0,0 @@ -from bottle import Bottle, route, request, redirect, response, SimpleTemplate -import chevron - - -app = Bottle() - - -@route('/other') -def a(): - return chevron.render("sink", {"key": "value"}) - - -@route('/other2') -def b(): - sink = { - 'template': "template", - - 'data': { - 'key': 'value' - } - } - return chevron.render(**sink) diff --git a/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.expected deleted file mode 100644 index a38fdbc323f..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.expected +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (DjangoSSTISinks.ql:4,6-14) -| DjangoTemplates.py:9:18:9:25 | argument to Django.template() | diff --git a/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.ql deleted file mode 100644 index eecd31aeb87..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.DjangoTemplate - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/DjangoTemplates.py b/python/ql/test/experimental/semmle/python/templates/DjangoTemplates.py deleted file mode 100644 index 981109bf7dc..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/DjangoTemplates.py +++ /dev/null @@ -1,39 +0,0 @@ -from django.urls import path -from django.http import HttpResponse -from django.template import Template, Context, Engine, engines - - -def dj(request): - # Load the template - template = request.GET['template'] - t = Template(template) - ctx = Context(locals()) - html = t.render(ctx) - return HttpResponse(html) - - -def djEngine(request): - # Load the template - template = request.GET['template'] - - django_engine = engines['django'] - t = django_engine.from_string(template) - ctx = Context(locals()) - html = t.render(ctx) - return HttpResponse(html) - - -def djEngineJinja(request): - # Load the template - template = request.GET['template'] - - django_engine = engines['jinja'] - t = django_engine.from_string(template) - ctx = Context(locals()) - html = t.render(ctx) - return HttpResponse(html) - - -urlpatterns = [ - path('', dj) -] diff --git a/python/ql/test/experimental/semmle/python/templates/Genshi.py b/python/ql/test/experimental/semmle/python/templates/Genshi.py deleted file mode 100644 index 7c46a2b31dc..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/Genshi.py +++ /dev/null @@ -1,10 +0,0 @@ - - -def genshi1(): - from genshi.template import MarkupTemplate - tmpl = MarkupTemplate('sink') - - -def genshi2(): - from genshi.template import TextTemplate - tmpl = TextTemplate('sink') \ No newline at end of file diff --git a/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.expected deleted file mode 100644 index cfc22364413..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.expected +++ /dev/null @@ -1,3 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (GenshiSSTISinks.ql:4,6-14) -| Genshi.py:5:27:5:32 | argument to genshi.template.MarkupTemplate() | -| Genshi.py:10:25:10:30 | argument to genshi.template.TextTemplate() | diff --git a/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.ql deleted file mode 100644 index f0d87e97ec1..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.Genshi - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/Jinja2Templates.py b/python/ql/test/experimental/semmle/python/templates/Jinja2Templates.py deleted file mode 100644 index e52538d4946..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/Jinja2Templates.py +++ /dev/null @@ -1,17 +0,0 @@ -from jinja2 import Template as Jinja2_Template -from jinja2 import Environment, DictLoader, escape - - -def jinja(): - t = Jinja2_Template("sink") - - -def jinja2(): - random = "esdad" + "asdad" - t = Jinja2_Template(random) - - -def jinja3(): - random = 1234 - t = Jinja2_Template("sink"+random) - diff --git a/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.expected deleted file mode 100644 index 7b91c934947..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.expected +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (JinjaSSTISinks.ql:4,6-14) -| Jinja2Templates.py:6:25:6:30 | argument to jinja2.Template() | -| Jinja2Templates.py:11:25:11:30 | argument to jinja2.Template() | -| Jinja2Templates.py:16:25:16:37 | argument to jinja2.Template() | diff --git a/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.ql deleted file mode 100644 index ca80d8bc570..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.Jinja - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/Mako.py b/python/ql/test/experimental/semmle/python/templates/Mako.py deleted file mode 100644 index 3af60b164ea..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/Mako.py +++ /dev/null @@ -1,5 +0,0 @@ - - -def mako(): - from mako.template import Template - mytemplate = Template("sink") diff --git a/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.expected deleted file mode 100644 index 005e14f218a..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.expected +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (MakoSSTISinks.ql:4,6-14) -| Mako.py:5:27:5:32 | argument to mako.template.Template() | diff --git a/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.ql deleted file mode 100644 index eed89420c54..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.Mako - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/TRender.py b/python/ql/test/experimental/semmle/python/templates/TRender.py deleted file mode 100644 index 6ed5a799942..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/TRender.py +++ /dev/null @@ -1,6 +0,0 @@ - - -def trender(): - from trender import TRender - template = '@greet world!' - compiled = TRender(template) diff --git a/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.expected deleted file mode 100644 index 26dea55a6c8..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.expected +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: Type SSTISink has been deprecated and may be removed in future (TRenderSSTISinks.ql:4,6-14) -| TRender.py:6:24:6:31 | argument to trender.TRender() | diff --git a/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.ql deleted file mode 100644 index ec3a1bba57f..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.ql +++ /dev/null @@ -1,5 +0,0 @@ -import python -import experimental.semmle.python.templates.TRender - -from SSTISink s -select s diff --git a/python/ql/test/experimental/semmle/python/templates/options b/python/ql/test/experimental/semmle/python/templates/options deleted file mode 100644 index c3bc9413072..00000000000 --- a/python/ql/test/experimental/semmle/python/templates/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --lang=3 --max-import-depth=3 -p ../../../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/examples/custom-sanitizer/SanitizedEdges.expected b/python/ql/test/library-tests/examples/custom-sanitizer/SanitizedEdges.expected deleted file mode 100644 index 22c6f68f1d7..00000000000 --- a/python/ql/test/library-tests/examples/custom-sanitizer/SanitizedEdges.expected +++ /dev/null @@ -1,23 +0,0 @@ -| MySanitizerHandlingNot | externally controlled string | test.py:13 | Pi(s_0) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:18 | Pi(s_5) [false] | -| MySanitizerHandlingNot | externally controlled string | test.py:28 | Pi(s_0) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:34 | Pi(s_10) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:40 | Pi(s_12) [false] | -| MySanitizerHandlingNot | externally controlled string | test.py:50 | Pi(s_0) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:56 | Pi(s_10) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:62 | Pi(s_12) [false] | -| MySanitizerHandlingNot | externally controlled string | test.py:76 | Pi(s_3) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:82 | Pi(s_0) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:87 | Pi(s_5) [false] | -| MySanitizerHandlingNot | externally controlled string | test.py:97 | Pi(s_0) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:102 | Pi(s_7) [true] | -| MySanitizerHandlingNot | externally controlled string | test.py:107 | Pi(s_12) [true] | -| MySimpleSanitizer | externally controlled string | test.py:13 | Pi(s_0) [true] | -| MySimpleSanitizer | externally controlled string | test.py:28 | Pi(s_0) [true] | -| MySimpleSanitizer | externally controlled string | test.py:34 | Pi(s_10) [true] | -| MySimpleSanitizer | externally controlled string | test.py:50 | Pi(s_0) [true] | -| MySimpleSanitizer | externally controlled string | test.py:56 | Pi(s_10) [true] | -| MySimpleSanitizer | externally controlled string | test.py:76 | Pi(s_3) [true] | -| MySimpleSanitizer | externally controlled string | test.py:97 | Pi(s_0) [true] | -| MySimpleSanitizer | externally controlled string | test.py:102 | Pi(s_7) [true] | -| MySimpleSanitizer | externally controlled string | test.py:107 | Pi(s_12) [true] | diff --git a/python/ql/test/library-tests/examples/custom-sanitizer/SanitizedEdges.ql b/python/ql/test/library-tests/examples/custom-sanitizer/SanitizedEdges.ql deleted file mode 100644 index d523f79a963..00000000000 --- a/python/ql/test/library-tests/examples/custom-sanitizer/SanitizedEdges.ql +++ /dev/null @@ -1,6 +0,0 @@ -import python -import Taint - -from Sanitizer s, TaintKind taint, PyEdgeRefinement test -where s.sanitizingEdge(taint, test) -select s, taint, test.getTest().getLocation().toString(), test.getRepresentation() diff --git a/python/ql/test/library-tests/examples/custom-sanitizer/Taint.qll b/python/ql/test/library-tests/examples/custom-sanitizer/Taint.qll deleted file mode 100644 index 343caa1131f..00000000000 --- a/python/ql/test/library-tests/examples/custom-sanitizer/Taint.qll +++ /dev/null @@ -1,77 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -class SimpleSource extends TaintSource { - SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "taint source" } -} - -class MySimpleSanitizer extends Sanitizer { - MySimpleSanitizer() { this = "MySimpleSanitizer" } - - /* - * The test `if is_safe(arg):` sanitizes `arg` on its `true` edge. - * - * Can't handle `if not is_safe(arg):` :\ that's why it's called MySimpleSanitizer - */ - - override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { - taint instanceof ExternalStringKind and - exists(CallNode call | test.getTest() = call and test.getSense() = true | - call = Value::named("test.is_safe").getACall() and - test.getInput().getAUse() = call.getAnArg() - ) - } -} - -class MySanitizerHandlingNot extends Sanitizer { - MySanitizerHandlingNot() { this = "MySanitizerHandlingNot" } - - /** Holds if the test `if is_safe(arg):` sanitizes `arg` on its `true` edge. */ - override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { - taint instanceof ExternalStringKind and - clears_taint_on_true(test.getTest(), test.getSense(), test) - } -} - -/** - * Helper predicate that recurses into any nesting of `not` - * - * To reduce the number of tuples this predicate holds for, we include the `PyEdgeRefinement` and - * ensure that `test` is a part of this `PyEdgeRefinement` (instead of just taking the - * `edge_refinement.getInput().getAUse()` part as a part of the predicate). Without including - * `PyEdgeRefinement` as an argument *any* `CallNode c` to `test.is_safe` would be a result of - * this predicate, since the tuple where `test = c` and `sense = true` would hold. - */ -private predicate clears_taint_on_true( - ControlFlowNode test, boolean sense, PyEdgeRefinement edge_refinement -) { - edge_refinement.getTest().getNode().(Expr).getASubExpression*() = test.getNode() and - ( - test = Value::named("test.is_safe").getACall() and - edge_refinement.getInput().getAUse() = test.(CallNode).getAnArg() and - sense = true - or - test.(UnaryExprNode).getNode().getOp() instanceof Not and - exists(ControlFlowNode nested_test | - nested_test = test.(UnaryExprNode).getOperand() and - clears_taint_on_true(nested_test, sense.booleanNot(), edge_refinement) - ) - ) -} - -class TestConfig extends TaintTracking::Configuration { - TestConfig() { this = "TestConfig" } - - override predicate isSanitizer(Sanitizer sanitizer) { - sanitizer instanceof MySanitizerHandlingNot - } - - override predicate isSource(TaintTracking::Source source) { source instanceof SimpleSource } - - override predicate isSink(TaintTracking::Sink sink) { none() } -} diff --git a/python/ql/test/library-tests/examples/custom-sanitizer/TestTaint.expected b/python/ql/test/library-tests/examples/custom-sanitizer/TestTaint.expected deleted file mode 100644 index 269eb47a37f..00000000000 --- a/python/ql/test/library-tests/examples/custom-sanitizer/TestTaint.expected +++ /dev/null @@ -1,28 +0,0 @@ -| test.py:14 | test_basic | s | <NO TAINT> | ok | -| test.py:16 | test_basic | s | externally controlled string | ok | -| test.py:19 | test_basic | s | externally controlled string | ok | -| test.py:21 | test_basic | s | <NO TAINT> | ok | -| test.py:29 | test_or | s | externally controlled string | ok | -| test.py:31 | test_or | s | externally controlled string | ok | -| test.py:35 | test_or | s | externally controlled string | ok | -| test.py:37 | test_or | s | externally controlled string | ok | -| test.py:41 | test_or | s | externally controlled string | ok | -| test.py:43 | test_or | s | externally controlled string | ok | -| test.py:51 | test_and | s | <NO TAINT> | ok | -| test.py:53 | test_and | s | externally controlled string | ok | -| test.py:57 | test_and | s | externally controlled string | ok | -| test.py:59 | test_and | s | <NO TAINT> | ok | -| test.py:63 | test_and | s | externally controlled string | ok | -| test.py:65 | test_and | s | <NO TAINT> | ok | -| test.py:73 | test_tricky | s | externally controlled string | failure | -| test.py:77 | test_tricky | s_ | externally controlled string | failure | -| test.py:83 | test_nesting_not | s | <NO TAINT> | ok | -| test.py:85 | test_nesting_not | s | externally controlled string | ok | -| test.py:88 | test_nesting_not | s | externally controlled string | ok | -| test.py:90 | test_nesting_not | s | <NO TAINT> | ok | -| test.py:98 | test_nesting_not_with_and_true | s | externally controlled string | ok | -| test.py:100 | test_nesting_not_with_and_true | s | <NO TAINT> | ok | -| test.py:103 | test_nesting_not_with_and_true | s | <NO TAINT> | ok | -| test.py:105 | test_nesting_not_with_and_true | s | externally controlled string | ok | -| test.py:108 | test_nesting_not_with_and_true | s | externally controlled string | ok | -| test.py:110 | test_nesting_not_with_and_true | s | <NO TAINT> | ok | diff --git a/python/ql/test/library-tests/examples/custom-sanitizer/TestTaint.ql b/python/ql/test/library-tests/examples/custom-sanitizer/TestTaint.ql deleted file mode 100644 index 431e96e4d5d..00000000000 --- a/python/ql/test/library-tests/examples/custom-sanitizer/TestTaint.ql +++ /dev/null @@ -1,31 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from - Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res, - string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - ( - call.getFunc().(Name).getId() = "ensure_tainted" and - expected_taint = true - or - call.getFunc().(Name).getId() = "ensure_not_tainted" and - expected_taint = false - ) and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "<NO TAINT>" and - has_taint = false - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) and - has_taint = true - ) and - if expected_taint = has_taint then test_res = "ok" else test_res = "failure" -// if expected_taint = has_taint then test_res = "✓" else test_res = "✕" -select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(), - taint_string, test_res diff --git a/python/ql/test/library-tests/examples/custom-sanitizer/test.py b/python/ql/test/library-tests/examples/custom-sanitizer/test.py deleted file mode 100644 index e0bf29f4ee6..00000000000 --- a/python/ql/test/library-tests/examples/custom-sanitizer/test.py +++ /dev/null @@ -1,110 +0,0 @@ -def random_choice(): - return bool(GLOBAL_UNKOWN_VAR) - -def is_safe(arg): - return UNKNOWN_FUNC(arg) - -def true_func(): - return True - -def test_basic(): - s = TAINTED_STRING - - if is_safe(s): - ensure_not_tainted(s) - else: - ensure_tainted(s) - - if not is_safe(s): - ensure_tainted(s) - else: - ensure_not_tainted(s) - - -def test_or(): - s = TAINTED_STRING - - # x or y - if is_safe(s) or random_choice(): - ensure_tainted(s) # might be tainted - else: - ensure_tainted(s) # must be tainted - - # not (x or y) - if not(is_safe(s) or random_choice()): - ensure_tainted(s) # must be tainted - else: - ensure_tainted(s) # might be tainted - - # not (x or y) == not x and not y [de Morgan's laws] - if not is_safe(s) and not random_choice(): - ensure_tainted(s) # must be tainted - else: - ensure_tainted(s) # might be tainted - - -def test_and(): - s = TAINTED_STRING - - # x and y - if is_safe(s) and random_choice(): - ensure_not_tainted(s) # must not be tainted - else: - ensure_tainted(s) # might be tainted - - # not (x and y) - if not(is_safe(s) and random_choice()): - ensure_tainted(s) # might be tainted - else: - ensure_not_tainted(s) - - # not (x and y) == not x or not y [de Morgan's laws] - if not is_safe(s) or not random_choice(): - ensure_tainted(s) # might be tainted - else: - ensure_not_tainted(s) - - -def test_tricky(): - s = TAINTED_STRING - - x = is_safe(s) - if x: - ensure_not_tainted(s) # FP - - s_ = s - if is_safe(s): - ensure_not_tainted(s_) # FP - -def test_nesting_not(): - s = TAINTED_STRING - - if not(not(is_safe(s))): - ensure_not_tainted(s) - else: - ensure_tainted(s) - - if not(not(not(is_safe(s)))): - ensure_tainted(s) - else: - ensure_not_tainted(s) - -# Adding `and True` makes the sanitizer trigger when it would otherwise not. See output in -# SanitizedEdges.expected and compare with `test_nesting_not` and `test_basic` -def test_nesting_not_with_and_true(): - s = TAINTED_STRING - - if not(is_safe(s) and True): - ensure_tainted(s) - else: - ensure_not_tainted(s) - - if not(not(is_safe(s) and True)): - ensure_not_tainted(s) - else: - ensure_tainted(s) - - if not(not(not(is_safe(s) and True))): - ensure_tainted(s) - else: - ensure_not_tainted(s) diff --git a/python/ql/test/library-tests/security/command-execution/CommandSinks.expected b/python/ql/test/library-tests/security/command-execution/CommandSinks.expected deleted file mode 100644 index 425a0471399..00000000000 --- a/python/ql/test/library-tests/security/command-execution/CommandSinks.expected +++ /dev/null @@ -1,18 +0,0 @@ -WARNING: Type CommandSink has been deprecated and may be removed in future (CommandSinks.ql:4,6-17) -| fabric_v1_test.py:8:7:8:28 | FabricV1Commands | externally controlled string | -| fabric_v1_test.py:9:5:9:27 | FabricV1Commands | externally controlled string | -| fabric_v1_test.py:10:6:10:38 | FabricV1Commands | externally controlled string | -| fabric_v2_test.py:10:16:10:25 | InvokeContextRun | externally controlled string | -| fabric_v2_test.py:12:15:12:36 | InvokeContextRun | externally controlled string | -| fabric_v2_test.py:16:45:16:54 | FabricGroupRun | externally controlled string | -| fabric_v2_test.py:21:10:21:13 | FabricGroupRun | externally controlled string | -| fabric_v2_test.py:31:14:31:41 | InvokeContextRun | externally controlled string | -| fabric_v2_test.py:33:15:33:64 | InvokeContextRun | externally controlled string | -| invoke_test.py:8:12:8:21 | InvokeRun | externally controlled string | -| invoke_test.py:9:20:9:40 | InvokeRun | externally controlled string | -| invoke_test.py:12:17:12:24 | InvokeRun | externally controlled string | -| invoke_test.py:13:25:13:32 | InvokeRun | externally controlled string | -| invoke_test.py:17:11:17:40 | InvokeContextRun | externally controlled string | -| invoke_test.py:21:11:21:32 | InvokeContextRun | externally controlled string | -| invoke_test.py:27:11:27:25 | InvokeContextRun | externally controlled string | -| invoke_test.py:32:11:32:25 | InvokeContextRun | externally controlled string | diff --git a/python/ql/test/library-tests/security/command-execution/CommandSinks.ql b/python/ql/test/library-tests/security/command-execution/CommandSinks.ql deleted file mode 100644 index 797b527d568..00000000000 --- a/python/ql/test/library-tests/security/command-execution/CommandSinks.ql +++ /dev/null @@ -1,6 +0,0 @@ -import python -import semmle.python.security.injection.Command - -from CommandSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind diff --git a/python/ql/test/library-tests/security/command-execution/fabric-LICENSE b/python/ql/test/library-tests/security/command-execution/fabric-LICENSE deleted file mode 100644 index 10e0dcedd55..00000000000 --- a/python/ql/test/library-tests/security/command-execution/fabric-LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2020 Jeff Forcier. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/python/ql/test/library-tests/security/command-execution/fabric_v1_test.py b/python/ql/test/library-tests/security/command-execution/fabric_v1_test.py deleted file mode 100644 index 82f34dde6d2..00000000000 --- a/python/ql/test/library-tests/security/command-execution/fabric_v1_test.py +++ /dev/null @@ -1,10 +0,0 @@ -"""tests for the 'fabric' package (v1.x) - -See http://docs.fabfile.org/en/1.14/tutorial.html -""" - -from fabric.api import run, local, sudo - -local('echo local execution') -run('echo remote execution') -sudo('echo remote execution with sudo') diff --git a/python/ql/test/library-tests/security/command-execution/fabric_v2_test.py b/python/ql/test/library-tests/security/command-execution/fabric_v2_test.py deleted file mode 100644 index 0854db3ea0b..00000000000 --- a/python/ql/test/library-tests/security/command-execution/fabric_v2_test.py +++ /dev/null @@ -1,33 +0,0 @@ -"""tests for the 'fabric' package (v2.x) - -Most of these examples are taken from the fabric documentation: http://docs.fabfile.org/en/2.5/getting-started.html -See fabric-LICENSE for its' license. -""" - -from fabric import Connection - -c = Connection('web1') -result = c.run('uname -s') - -c.run(command='echo run with kwargs') - - -from fabric import SerialGroup as Group -results = Group('web1', 'web2', 'mac1').run('uname -s') - - -from fabric import SerialGroup as Group -pool = Group('web1', 'web2', 'web3') -pool.run('ls') - - - -# using the 'fab' command-line tool - -from fabric import task - -@task -def upload_and_unpack(c): - if c.run('test -f /opt/mydata/myfile', warn=True).failed: - c.put('myfiles.tgz', '/opt/mydata') - c.run('tar -C /opt/mydata -xzvf /opt/mydata/myfiles.tgz') diff --git a/python/ql/test/library-tests/security/command-execution/invoke_test.py b/python/ql/test/library-tests/security/command-execution/invoke_test.py deleted file mode 100644 index 9bc2213b617..00000000000 --- a/python/ql/test/library-tests/security/command-execution/invoke_test.py +++ /dev/null @@ -1,32 +0,0 @@ -"""tests for the 'invoke' package - -see https://www.pyinvoke.org/ -""" - -import invoke - -invoke.run('echo run') -invoke.run(command='echo run with kwarg') - -def with_sudo(): - invoke.sudo('whoami') - invoke.sudo(command='whoami') - -def manual_context(): - c = invoke.Context() - c.run('echo run from manual context') -manual_context() - -def foo_helper(c): - c.run('echo from foo_helper') - -# for use with the 'invoke' command-line tool -@invoke.task -def foo(c): - # 'c' is a invoke.context.Context - c.run('echo task foo') - foo_helper(c) - -@invoke.task() -def bar(c): - c.run('echo task bar') diff --git a/python/ql/test/library-tests/security/command-execution/options b/python/ql/test/library-tests/security/command-execution/options deleted file mode 100644 index 1d132442a3b..00000000000 --- a/python/ql/test/library-tests/security/command-execution/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/security/fabric-v1-execute/Taint.qll b/python/ql/test/library-tests/security/fabric-v1-execute/Taint.qll deleted file mode 100644 index 7d1a812be92..00000000000 --- a/python/ql/test/library-tests/security/fabric-v1-execute/Taint.qll +++ /dev/null @@ -1,24 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.security.injection.Command - -class SimpleSource extends TaintSource { - SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "taint source" } -} - -class FabricExecuteTestConfiguration extends TaintTracking::Configuration { - FabricExecuteTestConfiguration() { this = "FabricExecuteTestConfiguration" } - - override predicate isSource(TaintTracking::Source source) { source instanceof SimpleSource } - - override predicate isSink(TaintTracking::Sink sink) { sink instanceof CommandSink } - - override predicate isExtension(TaintTracking::Extension extension) { - extension instanceof FabricExecuteExtension - } -} diff --git a/python/ql/test/library-tests/security/fabric-v1-execute/TestTaint.expected b/python/ql/test/library-tests/security/fabric-v1-execute/TestTaint.expected deleted file mode 100644 index edd58bbb75f..00000000000 --- a/python/ql/test/library-tests/security/fabric-v1-execute/TestTaint.expected +++ /dev/null @@ -1,10 +0,0 @@ -| test.py:8 | ok | unsafe | cmd | externally controlled string | -| test.py:8 | ok | unsafe | cmd2 | externally controlled string | -| test.py:9 | ok | unsafe | safe_arg | <NO TAINT> | -| test.py:9 | ok | unsafe | safe_optional | <NO TAINT> | -| test.py:16 | ok | unsafe | cmd | externally controlled string | -| test.py:16 | ok | unsafe | cmd2 | externally controlled string | -| test.py:17 | ok | unsafe | safe_arg | <NO TAINT> | -| test.py:17 | ok | unsafe | safe_optional | <NO TAINT> | -| test.py:23 | ok | some_http_handler | cmd | externally controlled string | -| test.py:23 | ok | some_http_handler | cmd2 | externally controlled string | diff --git a/python/ql/test/library-tests/security/fabric-v1-execute/TestTaint.ql b/python/ql/test/library-tests/security/fabric-v1-execute/TestTaint.ql deleted file mode 100644 index 7b9c6025c9d..00000000000 --- a/python/ql/test/library-tests/security/fabric-v1-execute/TestTaint.ql +++ /dev/null @@ -1,33 +0,0 @@ -import python -import semmle.python.security.TaintTracking -import semmle.python.web.HttpRequest -import semmle.python.security.strings.Untrusted -import Taint - -from - Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res, - string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - ( - call.getFunc().(Name).getId() = "ensure_tainted" and - expected_taint = true - or - call.getFunc().(Name).getId() = "ensure_not_tainted" and - expected_taint = false - ) and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "<NO TAINT>" and - has_taint = false - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) and - has_taint = true - ) and - if expected_taint = has_taint then test_res = "ok " else test_res = "fail" -// if expected_taint = has_taint then test_res = "✓" else test_res = "✕" -select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(), - taint_string diff --git a/python/ql/test/library-tests/security/fabric-v1-execute/options b/python/ql/test/library-tests/security/fabric-v1-execute/options deleted file mode 100644 index 1d132442a3b..00000000000 --- a/python/ql/test/library-tests/security/fabric-v1-execute/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/ diff --git a/python/ql/test/library-tests/security/fabric-v1-execute/test.py b/python/ql/test/library-tests/security/fabric-v1-execute/test.py deleted file mode 100644 index 7a1cd9ab377..00000000000 --- a/python/ql/test/library-tests/security/fabric-v1-execute/test.py +++ /dev/null @@ -1,28 +0,0 @@ -"""Test that shows fabric.api.execute propagates taint""" - -from fabric.api import run, execute - - -def unsafe(cmd, safe_arg, cmd2=None, safe_optional=5): - run('./venv/bin/activate && {}'.format(cmd)) - ensure_tainted(cmd, cmd2) - ensure_not_tainted(safe_arg, safe_optional) - - -class Foo(object): - - def unsafe(self, cmd, safe_arg, cmd2=None, safe_optional=5): - run('./venv/bin/activate && {}'.format(cmd)) - ensure_tainted(cmd, cmd2) - ensure_not_tainted(safe_arg, safe_optional) - - -def some_http_handler(): - cmd = TAINTED_STRING - cmd2 = TAINTED_STRING - ensure_tainted(cmd, cmd2) - - execute(unsafe, cmd=cmd, safe_arg='safe_arg', cmd2=cmd2) - - foo = Foo() - execute(foo.unsafe, cmd, 'safe_arg', cmd2) diff --git a/python/ql/test/library-tests/taint/collections/Taint.qll b/python/ql/test/library-tests/taint/collections/Taint.qll deleted file mode 100644 index 010b9738c5c..00000000000 --- a/python/ql/test/library-tests/taint/collections/Taint.qll +++ /dev/null @@ -1,27 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -class SimpleSource extends TaintSource { - SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "taint source" } -} - -class ListSource extends TaintSource { - ListSource() { this.(NameNode).getId() = "TAINTED_LIST" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } - - override string toString() { result = "list taint source" } -} - -class DictSource extends TaintSource { - DictSource() { this.(NameNode).getId() = "TAINTED_DICT" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } - - override string toString() { result = "dict taint source" } -} diff --git a/python/ql/test/library-tests/taint/collections/TestStep.expected b/python/ql/test/library-tests/taint/collections/TestStep.expected deleted file mode 100644 index a9591db0b9f..00000000000 --- a/python/ql/test/library-tests/taint/collections/TestStep.expected +++ /dev/null @@ -1,63 +0,0 @@ -| Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | --> | Taint [externally controlled string] | test.py:14 | test.py:14:14:14:25 | tainted_list | | -| Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | --> | Taint [externally controlled string] | test.py:20 | test.py:20:15:20:26 | tainted_list | | -| Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | --> | Taint [externally controlled string] | test.py:21 | test.py:21:13:21:24 | tainted_list | | -| Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | --> | Taint [externally controlled string] | test.py:22 | test.py:22:19:22:30 | tainted_list | | -| Taint [externally controlled string] | test.py:10 | test.py:10:22:10:36 | Tuple | | --> | Taint [externally controlled string] | test.py:15 | test.py:15:14:15:26 | tainted_tuple | | -| Taint [externally controlled string] | test.py:14 | test.py:14:9:14:26 | list() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:10:23:10 | a | | -| Taint [externally controlled string] | test.py:14 | test.py:14:14:14:25 | tainted_list | | --> | Taint [externally controlled string] | test.py:14 | test.py:14:9:14:26 | list() | | -| Taint [externally controlled string] | test.py:15 | test.py:15:9:15:27 | list() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:13:23:13 | b | | -| Taint [externally controlled string] | test.py:15 | test.py:15:14:15:26 | tainted_tuple | | --> | Taint [externally controlled string] | test.py:15 | test.py:15:9:15:27 | list() | | -| Taint [externally controlled string] | test.py:17 | test.py:17:9:17:35 | list() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:19:23:19 | d | | -| Taint [externally controlled string] | test.py:17 | test.py:17:14:17:34 | Attribute() | | --> | Taint [externally controlled string] | test.py:17 | test.py:17:9:17:35 | list() | | -| Taint [externally controlled string] | test.py:20 | test.py:20:9:20:27 | tuple() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:25:23:25 | f | | -| Taint [externally controlled string] | test.py:20 | test.py:20:15:20:26 | tainted_list | | --> | Taint [externally controlled string] | test.py:20 | test.py:20:9:20:27 | tuple() | | -| Taint [externally controlled string] | test.py:21 | test.py:21:9:21:25 | set() | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:28:23:28 | g | | -| Taint [externally controlled string] | test.py:21 | test.py:21:13:21:24 | tainted_list | | --> | Taint [externally controlled string] | test.py:21 | test.py:21:9:21:25 | set() | | -| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:27 | test.py:27:9:27:20 | tainted_list | | -| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:28 | test.py:28:9:28:20 | tainted_list | | -| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:29 | test.py:29:9:29:20 | tainted_list | | -| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:30 | test.py:30:9:30:20 | tainted_list | | -| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:31 | test.py:31:15:31:26 | tainted_list | | -| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:33 | test.py:33:14:33:25 | tainted_list | | -| Taint [externally controlled string] | test.py:26 | test.py:26:20:26:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:35 | test.py:35:23:35:34 | tainted_list | | -| Taint [externally controlled string] | test.py:27 | test.py:27:9:27:20 | tainted_list | | --> | Taint externally controlled string | test.py:27 | test.py:27:9:27:23 | Subscript | | -| Taint [externally controlled string] | test.py:28 | test.py:28:9:28:20 | tainted_list | | --> | Taint externally controlled string | test.py:28 | test.py:28:9:28:23 | Subscript | | -| Taint [externally controlled string] | test.py:29 | test.py:29:9:29:20 | tainted_list | | --> | Taint [externally controlled string] | test.py:29 | test.py:29:9:29:25 | Subscript | | -| Taint [externally controlled string] | test.py:29 | test.py:29:9:29:25 | Subscript | | --> | Taint [externally controlled string] | test.py:32 | test.py:32:16:32:16 | c | | -| Taint [externally controlled string] | test.py:30 | test.py:30:9:30:20 | tainted_list | | --> | Taint [externally controlled string] | test.py:30 | test.py:30:9:30:27 | Attribute() | | -| Taint [externally controlled string] | test.py:30 | test.py:30:9:30:27 | Attribute() | | --> | Taint [externally controlled string] | test.py:32 | test.py:32:19:32:19 | d | | -| Taint [externally controlled string] | test.py:31 | test.py:31:15:31:26 | tainted_list | | --> | Taint externally controlled string | test.py:32 | test.py:32:22:32:22 | e | | -| Taint [externally controlled string] | test.py:31 | test.py:31:15:31:26 | tainted_list | | --> | Taint externally controlled string | test.py:32 | test.py:32:25:32:25 | f | | -| Taint [externally controlled string] | test.py:31 | test.py:31:15:31:26 | tainted_list | | --> | Taint externally controlled string | test.py:32 | test.py:32:28:32:28 | g | | -| Taint [externally controlled string] | test.py:33 | test.py:33:14:33:25 | tainted_list | | --> | Taint externally controlled string | test.py:33 | test.py:33:5:33:26 | For | | -| Taint [externally controlled string] | test.py:35 | test.py:35:14:35:35 | reversed() | | --> | Taint externally controlled string | test.py:35 | test.py:35:5:35:36 | For | | -| Taint [externally controlled string] | test.py:35 | test.py:35:23:35:34 | tainted_list | | --> | Taint [externally controlled string] | test.py:35 | test.py:35:14:35:35 | reversed() | | -| Taint [externally controlled string] | test.py:44 | test.py:44:14:44:34 | Attribute() | | --> | Taint externally controlled string | test.py:44 | test.py:44:5:44:35 | For | | -| Taint externally controlled string | test.py:8 | test.py:8:22:8:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:9 | test.py:9:21:9:34 | tainted_string | | -| Taint externally controlled string | test.py:8 | test.py:8:22:8:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:10 | test.py:10:22:10:35 | tainted_string | | -| Taint externally controlled string | test.py:8 | test.py:8:22:8:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:11 | test.py:11:20:11:33 | tainted_string | | -| Taint externally controlled string | test.py:8 | test.py:8:22:8:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:12 | test.py:12:28:12:41 | tainted_string | | -| Taint externally controlled string | test.py:9 | test.py:9:21:9:34 | tainted_string | | --> | Taint [externally controlled string] | test.py:9 | test.py:9:20:9:35 | List | | -| Taint externally controlled string | test.py:10 | test.py:10:22:10:35 | tainted_string | | --> | Taint [externally controlled string] | test.py:10 | test.py:10:22:10:36 | Tuple | | -| Taint externally controlled string | test.py:12 | test.py:12:28:12:41 | tainted_string | | --> | Taint {externally controlled string} | test.py:12 | test.py:12:20:12:42 | Dict | | -| Taint externally controlled string | test.py:27 | test.py:27:9:27:23 | Subscript | | --> | Taint externally controlled string | test.py:32 | test.py:32:10:32:10 | a | | -| Taint externally controlled string | test.py:28 | test.py:28:9:28:23 | Subscript | | --> | Taint externally controlled string | test.py:32 | test.py:32:13:32:13 | b | | -| Taint externally controlled string | test.py:33 | test.py:33:5:33:26 | For | | --> | Taint externally controlled string | test.py:34 | test.py:34:14:34:14 | h | | -| Taint externally controlled string | test.py:35 | test.py:35:5:35:36 | For | | --> | Taint externally controlled string | test.py:36 | test.py:36:14:36:14 | i | | -| Taint externally controlled string | test.py:40 | test.py:40:9:40:28 | Subscript | | --> | Taint externally controlled string | test.py:43 | test.py:43:10:43:10 | a | | -| Taint externally controlled string | test.py:41 | test.py:41:9:41:23 | Subscript | | --> | Taint externally controlled string | test.py:43 | test.py:43:13:43:13 | b | | -| Taint externally controlled string | test.py:44 | test.py:44:5:44:35 | For | | --> | Taint externally controlled string | test.py:45 | test.py:45:14:45:14 | d | | -| Taint externally controlled string | test.py:62 | test.py:62:34:62:47 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:62 | test.py:62:5:62:47 | BinaryExpr | | -| Taint {externally controlled string} | test.py:12 | test.py:12:20:12:42 | Dict | | --> | Taint {externally controlled string} | test.py:17 | test.py:17:14:17:25 | tainted_dict | | -| Taint {externally controlled string} | test.py:12 | test.py:12:20:12:42 | Dict | | --> | Taint {externally controlled string} | test.py:18 | test.py:18:14:18:25 | tainted_dict | | -| Taint {externally controlled string} | test.py:17 | test.py:17:14:17:25 | tainted_dict | | --> | Taint [externally controlled string] | test.py:17 | test.py:17:14:17:34 | Attribute() | | -| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:40 | test.py:40:9:40:20 | tainted_dict | | -| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:41 | test.py:41:9:41:20 | tainted_dict | | -| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:42 | test.py:42:9:42:20 | tainted_dict | | -| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:44 | test.py:44:14:44:25 | tainted_dict | | -| Taint {externally controlled string} | test.py:39 | test.py:39:20:39:31 | TAINTED_DICT | | --> | Taint {externally controlled string} | test.py:46 | test.py:46:17:46:28 | tainted_dict | | -| Taint {externally controlled string} | test.py:40 | test.py:40:9:40:20 | tainted_dict | | --> | Taint externally controlled string | test.py:40 | test.py:40:9:40:28 | Subscript | | -| Taint {externally controlled string} | test.py:41 | test.py:41:9:41:20 | tainted_dict | | --> | Taint externally controlled string | test.py:41 | test.py:41:9:41:23 | Subscript | | -| Taint {externally controlled string} | test.py:42 | test.py:42:9:42:20 | tainted_dict | | --> | Taint {externally controlled string} | test.py:42 | test.py:42:9:42:27 | Attribute() | | -| Taint {externally controlled string} | test.py:42 | test.py:42:9:42:27 | Attribute() | | --> | Taint {externally controlled string} | test.py:43 | test.py:43:16:43:16 | c | | -| Taint {externally controlled string} | test.py:44 | test.py:44:14:44:25 | tainted_dict | | --> | Taint [externally controlled string] | test.py:44 | test.py:44:14:44:34 | Attribute() | | diff --git a/python/ql/test/library-tests/taint/collections/TestStep.ql b/python/ql/test/library-tests/taint/collections/TestStep.ql deleted file mode 100644 index 177edce3498..00000000000 --- a/python/ql/test/library-tests/taint/collections/TestStep.ql +++ /dev/null @@ -1,11 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from TaintedNode n, TaintedNode s -where - n.getLocation().getFile().getShortName() = "test.py" and - s.getLocation().getFile().getShortName() = "test.py" and - s = n.getASuccessor() -select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext(), - " --> ", "Taint " + s.getTaintKind(), s.getLocation().toString(), s.getAstNode(), s.getContext() diff --git a/python/ql/test/library-tests/taint/collections/TestTaint.expected b/python/ql/test/library-tests/taint/collections/TestTaint.expected deleted file mode 100644 index aae51236e6d..00000000000 --- a/python/ql/test/library-tests/taint/collections/TestTaint.expected +++ /dev/null @@ -1,33 +0,0 @@ -| test.py:23 | test_construction | a | [externally controlled string] | -| test.py:23 | test_construction | b | [externally controlled string] | -| test.py:23 | test_construction | c | NO TAINT | -| test.py:23 | test_construction | d | [externally controlled string] | -| test.py:23 | test_construction | e | NO TAINT | -| test.py:23 | test_construction | f | [externally controlled string] | -| test.py:23 | test_construction | g | [externally controlled string] | -| test.py:23 | test_construction | h | NO TAINT | -| test.py:32 | test_access | a | externally controlled string | -| test.py:32 | test_access | b | externally controlled string | -| test.py:32 | test_access | c | [externally controlled string] | -| test.py:32 | test_access | d | [externally controlled string] | -| test.py:32 | test_access | e | externally controlled string | -| test.py:32 | test_access | f | externally controlled string | -| test.py:32 | test_access | g | externally controlled string | -| test.py:34 | test_access | h | externally controlled string | -| test.py:36 | test_access | i | externally controlled string | -| test.py:43 | test_dict_access | a | externally controlled string | -| test.py:43 | test_dict_access | b | externally controlled string | -| test.py:43 | test_dict_access | c | {externally controlled string} | -| test.py:45 | test_dict_access | d | externally controlled string | -| test.py:47 | test_dict_access | e | NO TAINT | -| test.py:58 | test_named_tuple | a | NO TAINT | -| test.py:58 | test_named_tuple | b | NO TAINT | -| test.py:58 | test_named_tuple | c | NO TAINT | -| test.py:58 | test_named_tuple | d | NO TAINT | -| test.py:58 | test_named_tuple | e | NO TAINT | -| test.py:58 | test_named_tuple | f | NO TAINT | -| test.py:67 | test_defaultdict | a | NO TAINT | -| test.py:67 | test_defaultdict | b | NO TAINT | -| test.py:67 | test_defaultdict | c | NO TAINT | -| test.py:69 | test_defaultdict | d | NO TAINT | -| test.py:71 | test_defaultdict | e | NO TAINT | diff --git a/python/ql/test/library-tests/taint/collections/TestTaint.ql b/python/ql/test/library-tests/taint/collections/TestTaint.ql deleted file mode 100644 index 47883578516..00000000000 --- a/python/ql/test/library-tests/taint/collections/TestTaint.ql +++ /dev/null @@ -1,19 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from Call call, Expr arg, string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - call.getFunc().(Name).getId() = "test" and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "NO TAINT" - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) - ) -select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(), - taint_string diff --git a/python/ql/test/library-tests/taint/collections/test.py b/python/ql/test/library-tests/taint/collections/test.py deleted file mode 100644 index 445effe19ce..00000000000 --- a/python/ql/test/library-tests/taint/collections/test.py +++ /dev/null @@ -1,71 +0,0 @@ -from collections import defaultdict, namedtuple - -# Use to show only interesting results in qltest output -def test(*args): - pass - -def test_construction(): - tainted_string = TAINTED_STRING - tainted_list = [tainted_string] - tainted_tuple = (tainted_string,) - tainted_set = {tainted_string} # TODO: set currently not handled - tainted_dict = {'key': tainted_string} - - a = list(tainted_list) - b = list(tainted_tuple) - c = list(tainted_set) # TODO: set currently not handled - d = list(tainted_dict.values()) - e = list(tainted_dict.items()) # TODO: dict.items() currently not handled - - f = tuple(tainted_list) - g = set(tainted_list) - h = frozenset(tainted_list) # TODO: frozenset constructor currently not handled - test(a, b, c, d, e, f, g, h) - -def test_access(): - tainted_list = TAINTED_LIST - a = tainted_list[0] - b = tainted_list[x] - c = tainted_list[y:z] - d = tainted_list.copy() - e, f, g = tainted_list - test(a, b, c, d, e, f, g) - for h in tainted_list: - test(h) - for i in reversed(tainted_list): - test(i) - -def test_dict_access(x): - tainted_dict = TAINTED_DICT - a = tainted_dict["name"] - b = tainted_dict[x] - c = tainted_dict.copy() - test(a, b, c) - for d in tainted_dict.values(): - test(d) - for _, e in tainted_dict.items(): # TODO: dict.items() currently not handled - test(e) - -def test_named_tuple(): # TODO: namedtuple currently not handled - Point = namedtuple('Point', ['x', 'y']) - point = Point(TAINTED_STRING, 'const') - - a = point[0] - b = point.x - c = point[1] - d = point.y - e, f = point - test(a, b, c, d, e, f) - -def test_defaultdict(key, x): # TODO: defaultdict currently not handled - tainted_default_dict = defaultdict(str) - tainted_default_dict[key] += TAINTED_STRING - - a = tainted_dict["name"] - b = tainted_dict[x] - c = tainted_dict.copy() - test(a, b, c) - for d in tainted_dict.values(): - test(d) - for _, e in tainted_dict.items(): - test(e) diff --git a/python/ql/test/library-tests/taint/config/RockPaperScissors.ql b/python/ql/test/library-tests/taint/config/RockPaperScissors.ql index 8d6170351f1..9fc258159ae 100644 --- a/python/ql/test/library-tests/taint/config/RockPaperScissors.ql +++ b/python/ql/test/library-tests/taint/config/RockPaperScissors.ql @@ -5,7 +5,6 @@ import python import semmle.python.dataflow.TaintTracking import TaintLib -import semmle.python.security.Paths from RockPaperScissorConfig config, TaintedPathSource src, TaintedPathSink sink where config.hasFlowPath(src, sink) diff --git a/python/ql/test/library-tests/taint/config/Simple.ql b/python/ql/test/library-tests/taint/config/Simple.ql index 9a87a67c9f1..7617ec0a434 100644 --- a/python/ql/test/library-tests/taint/config/Simple.ql +++ b/python/ql/test/library-tests/taint/config/Simple.ql @@ -5,7 +5,6 @@ import python import semmle.python.dataflow.TaintTracking import TaintLib -import semmle.python.security.Paths from SimpleConfig config, TaintedPathSource src, TaintedPathSink sink where config.hasFlowPath(src, sink) diff --git a/python/ql/test/library-tests/taint/example/ExampleConfig.ql b/python/ql/test/library-tests/taint/example/ExampleConfig.ql index e406fc73e21..ea1dd879a95 100644 --- a/python/ql/test/library-tests/taint/example/ExampleConfig.ql +++ b/python/ql/test/library-tests/taint/example/ExampleConfig.ql @@ -7,7 +7,6 @@ import python import DilbertConfig -import semmle.python.security.Paths from DilbertConfig config, TaintedPathSource src, TaintedPathSink sink where config.hasFlowPath(src, sink) diff --git a/python/ql/test/library-tests/taint/exception_traceback/TestNode.expected b/python/ql/test/library-tests/taint/exception_traceback/TestNode.expected deleted file mode 100644 index b0b2a23b14b..00000000000 --- a/python/ql/test/library-tests/taint/exception_traceback/TestNode.expected +++ /dev/null @@ -1,27 +0,0 @@ -| test.py:10:11:10:47 | test.py:10 | MyException() | exception.kind | -| test.py:15:25:15:25 | test.py:15 | e | exception.kind | -| test.py:16:13:16:34 | test.py:16 | Attribute() | exception.info | -| test.py:17:15:17:15 | test.py:17 | s | exception.info | -| test.py:19:13:19:36 | test.py:19 | Attribute() | [exception.info] | -| test.py:20:13:20:37 | test.py:20 | Attribute() | [exception.info] | -| test.py:21:13:21:36 | test.py:21 | Attribute() | [exception.info] | -| test.py:21:35:21:35 | test.py:21 | t | [exception.info] | -| test.py:22:13:22:58 | test.py:22 | Attribute() | [exception.info] | -| test.py:23:13:23:57 | test.py:23 | Attribute() | [exception.info] | -| test.py:24:13:24:35 | test.py:24 | Attribute() | [exception.info] | -| test.py:25:13:25:36 | test.py:25 | Attribute() | [exception.info] | -| test.py:26:25:26:25 | test.py:26 | e | exception.kind | -| test.py:26:25:26:33 | test.py:26 | Attribute | exception.info | -| test.py:26:25:26:41 | test.py:26 | Tuple | [[exception.info]] | -| test.py:26:25:26:41 | test.py:26 | Tuple | [exception.info] | -| test.py:26:36:26:36 | test.py:26 | e | exception.kind | -| test.py:26:36:26:41 | test.py:26 | Attribute | [exception.info] | -| test.py:27:19:27:19 | test.py:27 | t | [exception.info] | -| test.py:27:22:27:22 | test.py:27 | u | [exception.info] | -| test.py:27:25:27:25 | test.py:27 | v | [exception.info] | -| test.py:27:28:27:28 | test.py:27 | w | [exception.info] | -| test.py:27:31:27:31 | test.py:27 | x | [exception.info] | -| test.py:27:34:27:34 | test.py:27 | y | [exception.info] | -| test.py:27:37:27:37 | test.py:27 | z | [exception.info] | -| test.py:27:40:27:46 | test.py:27 | message | exception.info | -| test.py:27:49:27:52 | test.py:27 | args | [exception.info] | diff --git a/python/ql/test/library-tests/taint/exception_traceback/TestNode.ql b/python/ql/test/library-tests/taint/exception_traceback/TestNode.ql deleted file mode 100644 index f3c7e98de94..00000000000 --- a/python/ql/test/library-tests/taint/exception_traceback/TestNode.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import semmle.python.security.Exceptions -import semmle.python.web.HttpResponse - -from TaintedNode node -where not node.getLocation().getFile().inStdlib() -select node.getLocation(), node.getNode().asAstNode().toString(), node.getTaintKind() diff --git a/python/ql/test/library-tests/taint/exception_traceback/TestSource.expected b/python/ql/test/library-tests/taint/exception_traceback/TestSource.expected deleted file mode 100644 index e8b2074bc28..00000000000 --- a/python/ql/test/library-tests/taint/exception_traceback/TestSource.expected +++ /dev/null @@ -1,10 +0,0 @@ -| test.py:10 | MyException() | exception.kind | -| test.py:15 | e | exception.kind | -| test.py:16 | Attribute() | exception.info | -| test.py:19 | Attribute() | [exception.info] | -| test.py:20 | Attribute() | [exception.info] | -| test.py:21 | Attribute() | [exception.info] | -| test.py:22 | Attribute() | [exception.info] | -| test.py:23 | Attribute() | [exception.info] | -| test.py:24 | Attribute() | [exception.info] | -| test.py:25 | Attribute() | [exception.info] | diff --git a/python/ql/test/library-tests/taint/exception_traceback/TestSource.ql b/python/ql/test/library-tests/taint/exception_traceback/TestSource.ql deleted file mode 100644 index d892afe9999..00000000000 --- a/python/ql/test/library-tests/taint/exception_traceback/TestSource.ql +++ /dev/null @@ -1,9 +0,0 @@ -import python -import semmle.python.security.Exceptions -import semmle.python.web.HttpResponse - -from TaintSource src, TaintKind kind -where - src.isSourceOf(kind) and - not src.getLocation().getFile().inStdlib() -select src.getLocation().toString(), src.(ControlFlowNode).getNode().toString(), kind diff --git a/python/ql/test/library-tests/taint/exception_traceback/TestStep.expected b/python/ql/test/library-tests/taint/exception_traceback/TestStep.expected deleted file mode 100644 index 196c1e92c2c..00000000000 --- a/python/ql/test/library-tests/taint/exception_traceback/TestStep.expected +++ /dev/null @@ -1,16 +0,0 @@ -| Taint [exception.info] | test.py:19 | Attribute() | | --> | Taint [exception.info] | test.py:21 | t | | -| Taint [exception.info] | test.py:19 | Attribute() | | --> | Taint [exception.info] | test.py:27 | t | | -| Taint [exception.info] | test.py:20 | Attribute() | | --> | Taint [exception.info] | test.py:27 | u | | -| Taint [exception.info] | test.py:21 | Attribute() | | --> | Taint [exception.info] | test.py:27 | v | | -| Taint [exception.info] | test.py:22 | Attribute() | | --> | Taint [exception.info] | test.py:27 | w | | -| Taint [exception.info] | test.py:23 | Attribute() | | --> | Taint [exception.info] | test.py:27 | x | | -| Taint [exception.info] | test.py:24 | Attribute() | | --> | Taint [exception.info] | test.py:27 | y | | -| Taint [exception.info] | test.py:25 | Attribute() | | --> | Taint [exception.info] | test.py:27 | z | | -| Taint [exception.info] | test.py:26 | Attribute | | --> | Taint [[exception.info]] | test.py:26 | Tuple | | -| Taint [exception.info] | test.py:26 | Attribute | | --> | Taint [exception.info] | test.py:27 | args | | -| Taint exception.info | test.py:16 | Attribute() | | --> | Taint exception.info | test.py:17 | s | | -| Taint exception.info | test.py:26 | Attribute | | --> | Taint [exception.info] | test.py:26 | Tuple | | -| Taint exception.info | test.py:26 | Attribute | | --> | Taint exception.info | test.py:27 | message | | -| Taint exception.kind | test.py:15 | e | | --> | Taint exception.kind | test.py:26 | e | | -| Taint exception.kind | test.py:26 | e | | --> | Taint [exception.info] | test.py:26 | Attribute | | -| Taint exception.kind | test.py:26 | e | | --> | Taint exception.info | test.py:26 | Attribute | | diff --git a/python/ql/test/library-tests/taint/exception_traceback/TestStep.ql b/python/ql/test/library-tests/taint/exception_traceback/TestStep.ql deleted file mode 100644 index b1ab12d0f25..00000000000 --- a/python/ql/test/library-tests/taint/exception_traceback/TestStep.ql +++ /dev/null @@ -1,12 +0,0 @@ -import python -import semmle.python.security.Exceptions -import semmle.python.web.HttpResponse - -from TaintedNode n, TaintedNode s -where - s = n.getASuccessor() and - not n.getLocation().getFile().inStdlib() and - not s.getLocation().getFile().inStdlib() -select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getNode().toString(), - n.getContext(), " --> ", "Taint " + s.getTaintKind(), s.getLocation().toString(), - s.getNode().toString(), s.getContext() diff --git a/python/ql/test/library-tests/taint/exception_traceback/test.py b/python/ql/test/library-tests/taint/exception_traceback/test.py deleted file mode 100644 index 20573aa8f8b..00000000000 --- a/python/ql/test/library-tests/taint/exception_traceback/test.py +++ /dev/null @@ -1,34 +0,0 @@ -from __future__ import print_function - -import traceback -import sys - -class MyException(Exception): - pass - -def raise_secret_exception(): - raise MyException("Message", "secret info") - -def foo(): - try: - raise_secret_exception() - except Exception as e: - s = traceback.format_exc() - print(s) - etype, evalue, tb = sys.exc_info() - t = traceback.extract_tb(tb) - u = traceback.extract_stack() - v = traceback.format_list(t) - w = traceback.format_exception_only(etype, evalue) - x = traceback.format_exception(etype, evalue, tb) - y = traceback.format_tb(tb) - z = traceback.format_stack() - message, args = e.message, e.args - print(tb, t, u, v, w, x, y, z, message, args) - - -foo() - - -#For test to find stdlib -import os diff --git a/python/ql/test/library-tests/taint/flowpath_regression/Config.qll b/python/ql/test/library-tests/taint/flowpath_regression/Config.qll deleted file mode 100644 index ae9d0e3c332..00000000000 --- a/python/ql/test/library-tests/taint/flowpath_regression/Config.qll +++ /dev/null @@ -1,45 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -class FooSource extends TaintSource { - FooSource() { this.(CallNode).getFunction().(NameNode).getId() = "foo_source" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof UntrustedStringKind } - - override string toString() { result = "FooSource" } -} - -class FooSink extends TaintSink { - FooSink() { - exists(CallNode call | - call.getFunction().(NameNode).getId() = "foo_sink" and - call.getAnArg() = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof UntrustedStringKind } - - override string toString() { result = "FooSink" } -} - -class FooConfig extends TaintTracking::Configuration { - FooConfig() { this = "FooConfig" } - - override predicate isSource(TaintTracking::Source source) { source instanceof FooSource } - - override predicate isSink(TaintTracking::Sink sink) { sink instanceof FooSink } -} - -class BarSink extends TaintSink { - BarSink() { - exists(CallNode call | - call.getFunction().(NameNode).getId() = "bar_sink" and - call.getAnArg() = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof UntrustedStringKind } - - override string toString() { result = "BarSink" } -} diff --git a/python/ql/test/library-tests/taint/flowpath_regression/Path.expected b/python/ql/test/library-tests/taint/flowpath_regression/Path.expected deleted file mode 100644 index b03f12e8b9a..00000000000 --- a/python/ql/test/library-tests/taint/flowpath_regression/Path.expected +++ /dev/null @@ -1 +0,0 @@ -| test.py:16:9:16:20 | foo_source() | test.py:17:14:17:14 | x | diff --git a/python/ql/test/library-tests/taint/flowpath_regression/Path.ql b/python/ql/test/library-tests/taint/flowpath_regression/Path.ql deleted file mode 100644 index 43562780859..00000000000 --- a/python/ql/test/library-tests/taint/flowpath_regression/Path.ql +++ /dev/null @@ -1,6 +0,0 @@ -import python -import Config - -from FooConfig config, TaintedPathSource src, TaintedPathSink sink -where config.hasFlowPath(src, sink) -select src.getSource(), sink.getSink() diff --git a/python/ql/test/library-tests/taint/flowpath_regression/test.py b/python/ql/test/library-tests/taint/flowpath_regression/test.py deleted file mode 100644 index 7287649330b..00000000000 --- a/python/ql/test/library-tests/taint/flowpath_regression/test.py +++ /dev/null @@ -1,22 +0,0 @@ -def foo_source(): - return 'foo' - - -def foo_sink(x): - if x == 'foo': - print('fire the foo missiles') - - -def bar_sink(x): - if x == 'bar': - print('fire the bar missiles') - - -def should_report(): - x = foo_source() - foo_sink(x) - - -def should_not_report(): - x = foo_source() - bar_sink(x) diff --git a/python/ql/test/library-tests/taint/namedtuple/SanitizedEdges.expected b/python/ql/test/library-tests/taint/namedtuple/SanitizedEdges.expected deleted file mode 100644 index 0adf64dfd5d..00000000000 --- a/python/ql/test/library-tests/taint/namedtuple/SanitizedEdges.expected +++ /dev/null @@ -1,7 +0,0 @@ -| UrlsplitUrlparseTempSanitizer | [externally controlled string] | test.py:21 | Pi(urlsplit_res_0) [true] | -| UrlsplitUrlparseTempSanitizer | [externally controlled string] | test.py:24 | Pi(urlsplit_res_3) [true] | -| UrlsplitUrlparseTempSanitizer | [externally controlled string] | test.py:27 | Pi(urlsplit_res_6) [true] | -| UrlsplitUrlparseTempSanitizer | [externally controlled string] | test.py:30 | Pi(urlsplit_res_9) [true] | -| string equality sanitizer | externally controlled string | test.py:21 | Pi(urlsplit_res_0) [true] | -| string equality sanitizer | externally controlled string | test.py:24 | Pi(urlsplit_res_3) [true] | -| string equality sanitizer | externally controlled string | test.py:27 | Pi(urlsplit_res_6) [true] | diff --git a/python/ql/test/library-tests/taint/namedtuple/SanitizedEdges.ql b/python/ql/test/library-tests/taint/namedtuple/SanitizedEdges.ql deleted file mode 100644 index d523f79a963..00000000000 --- a/python/ql/test/library-tests/taint/namedtuple/SanitizedEdges.ql +++ /dev/null @@ -1,6 +0,0 @@ -import python -import Taint - -from Sanitizer s, TaintKind taint, PyEdgeRefinement test -where s.sanitizingEdge(taint, test) -select s, taint, test.getTest().getLocation().toString(), test.getRepresentation() diff --git a/python/ql/test/library-tests/taint/namedtuple/Taint.qll b/python/ql/test/library-tests/taint/namedtuple/Taint.qll deleted file mode 100644 index 0dc3c71ec84..00000000000 --- a/python/ql/test/library-tests/taint/namedtuple/Taint.qll +++ /dev/null @@ -1,45 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -class SimpleSource extends TaintSource { - SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "taint source" } -} - -class ListSource extends TaintSource { - ListSource() { this.(NameNode).getId() = "TAINTED_LIST" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } - - override string toString() { result = "list taint source" } -} - -class DictSource extends TaintSource { - DictSource() { this.(NameNode).getId() = "TAINTED_DICT" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } - - override string toString() { result = "dict taint source" } -} - -class TestConfig extends TaintTracking::Configuration { - TestConfig() { this = "TestConfig" } - - override predicate isSanitizer(Sanitizer sanitizer) { - sanitizer instanceof UrlsplitUrlparseTempSanitizer - } - - override predicate isSource(TaintTracking::Source source) { - source instanceof SimpleSource - or - source instanceof ListSource - or - source instanceof DictSource - } - - override predicate isSink(TaintTracking::Sink sink) { none() } -} diff --git a/python/ql/test/library-tests/taint/namedtuple/TestTaint.expected b/python/ql/test/library-tests/taint/namedtuple/TestTaint.expected deleted file mode 100644 index 62b589299dd..00000000000 --- a/python/ql/test/library-tests/taint/namedtuple/TestTaint.expected +++ /dev/null @@ -1,15 +0,0 @@ -| test.py:13 | test_basic | a | externally controlled string | -| test.py:13 | test_basic | b | externally controlled string | -| test.py:13 | test_basic | c | externally controlled string | -| test.py:13 | test_basic | d | externally controlled string | -| test.py:13 | test_basic | urlsplit_res | [externally controlled string] | -| test.py:19 | test_sanitizer | Attribute | externally controlled string | -| test.py:22 | test_sanitizer | Attribute | NO TAINT | -| test.py:25 | test_sanitizer | Subscript | NO TAINT | -| test.py:28 | test_sanitizer | Attribute | NO TAINT | -| test.py:31 | test_sanitizer | Attribute | NO TAINT | -| test.py:34 | test_sanitizer | Attribute | externally controlled string | -| test.py:44 | test_namedtuple | a | NO TAINT | -| test.py:44 | test_namedtuple | b | NO TAINT | -| test.py:44 | test_namedtuple | c | NO TAINT | -| test.py:44 | test_namedtuple | d | NO TAINT | diff --git a/python/ql/test/library-tests/taint/namedtuple/TestTaint.ql b/python/ql/test/library-tests/taint/namedtuple/TestTaint.ql deleted file mode 100644 index 47883578516..00000000000 --- a/python/ql/test/library-tests/taint/namedtuple/TestTaint.ql +++ /dev/null @@ -1,19 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from Call call, Expr arg, string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - call.getFunc().(Name).getId() = "test" and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "NO TAINT" - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) - ) -select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(), - taint_string diff --git a/python/ql/test/library-tests/taint/namedtuple/test.py b/python/ql/test/library-tests/taint/namedtuple/test.py deleted file mode 100644 index ec6304f5073..00000000000 --- a/python/ql/test/library-tests/taint/namedtuple/test.py +++ /dev/null @@ -1,44 +0,0 @@ -from six.moves.urllib.parse import urlsplit - -# Currently we don't have support for namedtuples in general, but do have special support -# for `urlsplit` (and `urlparse`) - -def test_basic(): - tainted_string = TAINTED_STRING - urlsplit_res = urlsplit(tainted_string) - a = urlsplit_res.netloc # field access - b = urlsplit_res.hostname # property - c = urlsplit_res[3] # indexing - _, _, d, _, _ = urlsplit(tainted_string) # unpacking - test(a, b, c, d, urlsplit_res) - -def test_sanitizer(): - tainted_string = TAINTED_STRING - urlsplit_res = urlsplit(tainted_string) - - test(urlsplit_res.netloc) # should be tainted - - if urlsplit_res.netloc == "OK": - test(urlsplit_res.netloc) - - if urlsplit_res[2] == "OK": - test(urlsplit_res[0]) - - if urlsplit_res.netloc == "OK": - test(urlsplit_res.path) # FN - - if urlsplit_res.netloc in ["OK"]: - test(urlsplit_res.netloc) - - if urlsplit_res.netloc in ["OK", non_constant()]: - test(urlsplit_res.netloc) # should be tainted - -def test_namedtuple(): - tainted_string = TAINTED_STRING - Point = namedtuple('Point', ['x', 'y']) - p = Point('safe', tainted_string) - a = p.x - b = p.y - c = p[0] - d = p[1] - test(a, b, c, d) # TODO: FN, at least p.y and p[1] should be tainted diff --git a/python/ql/test/library-tests/taint/strings/Taint.qll b/python/ql/test/library-tests/taint/strings/Taint.qll deleted file mode 100644 index 3368a1c4f70..00000000000 --- a/python/ql/test/library-tests/taint/strings/Taint.qll +++ /dev/null @@ -1,44 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted -import semmle.python.security.Exceptions - -class SimpleSource extends TaintSource { - SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "taint source" } -} - -class ListSource extends TaintSource { - ListSource() { this.(NameNode).getId() = "TAINTED_LIST" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } - - override string toString() { result = "list taint source" } -} - -class DictSource extends TaintSource { - DictSource() { this.(NameNode).getId() = "TAINTED_DICT" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } - - override string toString() { result = "dict taint source" } -} - -class ExceptionInfoSource extends TaintSource { - ExceptionInfoSource() { this.(NameNode).getId() = "TAINTED_EXCEPTION_INFO" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo } - - override string toString() { result = "Exception info source" } -} - -class ExternalFileObjectSource extends TaintSource { - ExternalFileObjectSource() { this.(NameNode).getId() = "TAINTED_FILE" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalFileObject } - - override string toString() { result = "Tainted file source" } -} diff --git a/python/ql/test/library-tests/taint/strings/TestStep.expected b/python/ql/test/library-tests/taint/strings/TestStep.expected deleted file mode 100644 index 4dc6682ee81..00000000000 --- a/python/ql/test/library-tests/taint/strings/TestStep.expected +++ /dev/null @@ -1,162 +0,0 @@ -| Taint [[externally controlled string]] | test.py:74 | test.py:74:9:74:33 | parse_qsl() | | --> | Taint [[externally controlled string]] | test.py:75 | test.py:75:19:75:19 | d | | -| Taint [externally controlled string] | test.py:71 | test.py:71:9:71:32 | urlsplit() | | --> | Taint [externally controlled string] | test.py:75 | test.py:75:10:75:10 | a | | -| Taint [externally controlled string] | test.py:72 | test.py:72:9:72:32 | urlparse() | | --> | Taint [externally controlled string] | test.py:75 | test.py:75:13:75:13 | b | | -| Taint [externally controlled string] | test.py:104 | test.py:104:9:104:37 | Attribute() | | --> | Taint externally controlled string | test.py:104 | test.py:104:9:104:40 | Subscript | | -| Taint [externally controlled string] | test.py:108 | test.py:108:9:108:38 | Attribute() | | --> | Taint externally controlled string | test.py:108 | test.py:108:9:108:41 | Subscript | | -| Taint [externally controlled string] | test.py:110 | test.py:110:9:110:37 | Attribute() | | --> | Taint externally controlled string | test.py:110 | test.py:110:9:110:41 | Subscript | | -| Taint [externally controlled string] | test.py:113 | test.py:113:9:113:30 | Attribute() | | --> | Taint externally controlled string | test.py:113 | test.py:113:9:113:33 | Subscript | | -| Taint [externally controlled string] | test.py:115 | test.py:115:9:115:35 | Attribute() | | --> | Taint externally controlled string | test.py:115 | test.py:115:9:115:38 | Subscript | | -| Taint exception.info | test.py:45 | test.py:45:22:45:26 | taint | p1 = exception.info | --> | Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info | -| Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info | --> | Taint exception.info | test.py:46 | test.py:46:12:46:22 | func() | p1 = exception.info | -| Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info | --> | Taint exception.info | test.py:53 | test.py:53:19:53:21 | arg | p0 = exception.info | -| Taint exception.info | test.py:49 | test.py:49:12:49:33 | TAINTED_EXCEPTION_INFO | | --> | Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | | -| Taint exception.info | test.py:50 | test.py:50:11:50:41 | cross_over() | | --> | Taint exception.info | test.py:51 | test.py:51:10:51:12 | res | | -| Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | | --> | Taint exception.info | test.py:45 | test.py:45:22:45:26 | taint | p1 = exception.info | -| Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | | --> | Taint exception.info | test.py:50 | test.py:50:11:50:41 | cross_over() | | -| Taint exception.info | test.py:53 | test.py:53:19:53:21 | arg | p0 = exception.info | --> | Taint exception.info | test.py:54 | test.py:54:12:54:14 | arg | p0 = exception.info | -| Taint externally controlled string | test.py:6 | test.py:6:22:6:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:7 | test.py:7:31:7:44 | tainted_string | | -| Taint externally controlled string | test.py:7 | test.py:7:31:7:44 | tainted_string | | --> | Taint json[externally controlled string] | test.py:7 | test.py:7:20:7:45 | Attribute() | | -| Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint externally controlled string | test.py:9 | test.py:9:9:9:9 | a | | -| Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint externally controlled string | test.py:11 | test.py:11:10:11:10 | a | | -| Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint externally controlled string | test.py:10 | test.py:10:9:10:9 | b | | -| Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint externally controlled string | test.py:11 | test.py:11:13:11:13 | b | | -| Taint externally controlled string | test.py:10 | test.py:10:9:10:14 | Subscript | | --> | Taint externally controlled string | test.py:11 | test.py:11:16:11:16 | c | | -| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:15 | test.py:15:9:15:22 | tainted_string | | -| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:16 | test.py:16:9:16:22 | tainted_string | | -| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:17 | test.py:17:9:17:22 | tainted_string | | -| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:18 | test.py:18:9:18:22 | tainted_string | | -| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:19 | test.py:19:18:19:31 | tainted_string | | -| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:20 | test.py:20:14:20:27 | tainted_string | | -| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:21 | test.py:21:9:21:22 | tainted_string | | -| Taint externally controlled string | test.py:15 | test.py:15:9:15:22 | tainted_string | | --> | Taint externally controlled string | test.py:15 | test.py:15:9:15:31 | Attribute() | | -| Taint externally controlled string | test.py:15 | test.py:15:9:15:31 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:10:22:10 | a | | -| Taint externally controlled string | test.py:16 | test.py:16:9:16:22 | tainted_string | | --> | Taint externally controlled string | test.py:16 | test.py:16:9:16:29 | Attribute() | | -| Taint externally controlled string | test.py:16 | test.py:16:9:16:29 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:13:22:13 | b | | -| Taint externally controlled string | test.py:17 | test.py:17:9:17:22 | tainted_string | | --> | Taint externally controlled string | test.py:17 | test.py:17:9:17:25 | Subscript | | -| Taint externally controlled string | test.py:17 | test.py:17:9:17:25 | Subscript | | --> | Taint externally controlled string | test.py:22 | test.py:22:16:22:16 | c | | -| Taint externally controlled string | test.py:18 | test.py:18:9:18:22 | tainted_string | | --> | Taint externally controlled string | test.py:18 | test.py:18:9:18:27 | Subscript | | -| Taint externally controlled string | test.py:18 | test.py:18:9:18:27 | Subscript | | --> | Taint externally controlled string | test.py:22 | test.py:22:19:22:19 | d | | -| Taint externally controlled string | test.py:19 | test.py:19:9:19:32 | reversed() | | --> | Taint externally controlled string | test.py:22 | test.py:22:22:22:22 | e | | -| Taint externally controlled string | test.py:19 | test.py:19:18:19:31 | tainted_string | | --> | Taint externally controlled string | test.py:19 | test.py:19:9:19:32 | reversed() | | -| Taint externally controlled string | test.py:20 | test.py:20:9:20:28 | copy() | | --> | Taint externally controlled string | test.py:22 | test.py:22:25:22:25 | f | | -| Taint externally controlled string | test.py:20 | test.py:20:14:20:27 | tainted_string | | --> | Taint externally controlled string | test.py:20 | test.py:20:9:20:28 | copy() | | -| Taint externally controlled string | test.py:21 | test.py:21:9:21:22 | tainted_string | | --> | Taint externally controlled string | test.py:21 | test.py:21:9:21:30 | Attribute() | | -| Taint externally controlled string | test.py:21 | test.py:21:9:21:30 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:28:22:28 | g | | -| Taint externally controlled string | test.py:25 | test.py:25:22:25:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:26 | test.py:26:8:26:21 | tainted_string | | -| Taint externally controlled string | test.py:25 | test.py:25:22:25:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:29 | test.py:29:14:29:27 | tainted_string | | -| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:33 | test.py:33:8:33:21 | tainted_string | | -| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:33 | test.py:33:34:33:47 | tainted_string | | -| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:36 | test.py:36:14:36:27 | tainted_string | | -| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:40 | test.py:40:13:40:26 | tainted_string | | -| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:41 | test.py:41:15:41:28 | tainted_string | | -| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:42 | test.py:42:15:42:28 | tainted_string | | -| Taint externally controlled string | test.py:40 | test.py:40:9:40:27 | str() | | --> | Taint externally controlled string | test.py:43 | test.py:43:10:43:10 | a | | -| Taint externally controlled string | test.py:40 | test.py:40:13:40:26 | tainted_string | | --> | Taint externally controlled string | test.py:40 | test.py:40:9:40:27 | str() | | -| Taint externally controlled string | test.py:41 | test.py:41:9:41:29 | bytes() | | --> | Taint externally controlled string | test.py:43 | test.py:43:13:43:13 | b | | -| Taint externally controlled string | test.py:41 | test.py:41:15:41:28 | tainted_string | | --> | Taint externally controlled string | test.py:41 | test.py:41:9:41:29 | bytes() | | -| Taint externally controlled string | test.py:42 | test.py:42:9:42:46 | bytes() | | --> | Taint externally controlled string | test.py:43 | test.py:43:16:43:16 | c | | -| Taint externally controlled string | test.py:42 | test.py:42:15:42:28 | tainted_string | | --> | Taint externally controlled string | test.py:42 | test.py:42:9:42:46 | bytes() | | -| Taint externally controlled string | test.py:45 | test.py:45:22:45:26 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string | -| Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:46 | test.py:46:12:46:22 | func() | p1 = externally controlled string | -| Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:53 | test.py:53:19:53:21 | arg | p0 = externally controlled string | -| Taint externally controlled string | test.py:53 | test.py:53:19:53:21 | arg | p0 = externally controlled string | --> | Taint externally controlled string | test.py:54 | test.py:54:12:54:14 | arg | p0 = externally controlled string | -| Taint externally controlled string | test.py:57 | test.py:57:11:57:24 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | | -| Taint externally controlled string | test.py:58 | test.py:58:11:58:41 | cross_over() | | --> | Taint externally controlled string | test.py:59 | test.py:59:10:59:12 | res | | -| Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | | --> | Taint externally controlled string | test.py:45 | test.py:45:22:45:26 | taint | p1 = externally controlled string | -| Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | | --> | Taint externally controlled string | test.py:58 | test.py:58:11:58:41 | cross_over() | | -| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:71 | test.py:71:18:71:31 | tainted_string | | -| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:72 | test.py:72:18:72:31 | tainted_string | | -| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:73 | test.py:73:18:73:31 | tainted_string | | -| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:74 | test.py:74:19:74:32 | tainted_string | | -| Taint externally controlled string | test.py:71 | test.py:71:18:71:31 | tainted_string | | --> | Taint [externally controlled string] | test.py:71 | test.py:71:9:71:32 | urlsplit() | | -| Taint externally controlled string | test.py:72 | test.py:72:18:72:31 | tainted_string | | --> | Taint [externally controlled string] | test.py:72 | test.py:72:9:72:32 | urlparse() | | -| Taint externally controlled string | test.py:73 | test.py:73:18:73:31 | tainted_string | | --> | Taint {externally controlled string} | test.py:73 | test.py:73:9:73:32 | parse_qs() | | -| Taint externally controlled string | test.py:74 | test.py:74:19:74:32 | tainted_string | | --> | Taint [[externally controlled string]] | test.py:74 | test.py:74:9:74:33 | parse_qsl() | | -| Taint externally controlled string | test.py:78 | test.py:78:22:78:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:80 | test.py:80:9:80:22 | tainted_string | | -| Taint externally controlled string | test.py:78 | test.py:78:22:78:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:82 | test.py:82:12:82:25 | tainted_string | | -| Taint externally controlled string | test.py:80 | test.py:80:9:80:22 | tainted_string | | --> | Taint externally controlled string | test.py:80 | test.py:80:9:80:30 | Attribute() | | -| Taint externally controlled string | test.py:80 | test.py:80:9:80:30 | Attribute() | | --> | Taint externally controlled string | test.py:85 | test.py:85:10:85:10 | a | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:91 | test.py:91:9:91:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:92 | test.py:92:9:92:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:93 | test.py:93:9:93:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:94 | test.py:94:9:94:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:96 | test.py:96:9:96:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:97 | test.py:97:9:97:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:98 | test.py:98:9:98:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:99 | test.py:99:9:99:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:100 | test.py:100:9:100:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:101 | test.py:101:9:101:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:102 | test.py:102:9:102:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:103 | test.py:103:9:103:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:104 | test.py:104:9:104:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:105 | test.py:105:9:105:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:106 | test.py:106:9:106:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:107 | test.py:107:9:107:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:108 | test.py:108:9:108:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:109 | test.py:109:9:109:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:110 | test.py:110:9:110:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:111 | test.py:111:9:111:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:112 | test.py:112:9:112:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:113 | test.py:113:9:113:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:114 | test.py:114:9:114:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:115 | test.py:115:9:115:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:116 | test.py:116:9:116:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:117 | test.py:117:9:117:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:118 | test.py:118:9:118:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:121 | test.py:121:9:121:22 | tainted_string | | -| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:122 | test.py:122:9:122:22 | tainted_string | | -| Taint externally controlled string | test.py:91 | test.py:91:9:91:22 | tainted_string | | --> | Taint externally controlled string | test.py:91 | test.py:91:9:91:35 | Attribute() | | -| Taint externally controlled string | test.py:92 | test.py:92:9:92:22 | tainted_string | | --> | Taint externally controlled string | test.py:92 | test.py:92:9:92:33 | Attribute() | | -| Taint externally controlled string | test.py:93 | test.py:93:9:93:22 | tainted_string | | --> | Taint externally controlled string | test.py:93 | test.py:93:9:93:31 | Attribute() | | -| Taint externally controlled string | test.py:94 | test.py:94:9:94:22 | tainted_string | | --> | Taint externally controlled string | test.py:94 | test.py:94:9:94:38 | Attribute() | | -| Taint externally controlled string | test.py:95 | test.py:95:9:95:22 | tainted_string | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:38 | Attribute() | | -| Taint externally controlled string | test.py:95 | test.py:95:9:95:38 | Attribute() | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:54 | Attribute() | | -| Taint externally controlled string | test.py:96 | test.py:96:9:96:22 | tainted_string | | --> | Taint externally controlled string | test.py:96 | test.py:96:9:96:35 | Attribute() | | -| Taint externally controlled string | test.py:97 | test.py:97:9:97:22 | tainted_string | | --> | Taint externally controlled string | test.py:97 | test.py:97:9:97:37 | Attribute() | | -| Taint externally controlled string | test.py:98 | test.py:98:9:98:22 | tainted_string | | --> | Taint externally controlled string | test.py:98 | test.py:98:9:98:46 | Attribute() | | -| Taint externally controlled string | test.py:99 | test.py:99:9:99:22 | tainted_string | | --> | Taint externally controlled string | test.py:99 | test.py:99:9:99:33 | Attribute() | | -| Taint externally controlled string | test.py:100 | test.py:100:9:100:22 | tainted_string | | --> | Taint externally controlled string | test.py:100 | test.py:100:9:100:30 | Attribute() | | -| Taint externally controlled string | test.py:101 | test.py:101:9:101:22 | tainted_string | | --> | Taint externally controlled string | test.py:101 | test.py:101:9:101:31 | Attribute() | | -| Taint externally controlled string | test.py:102 | test.py:102:9:102:22 | tainted_string | | --> | Taint externally controlled string | test.py:102 | test.py:102:9:102:35 | Attribute() | | -| Taint externally controlled string | test.py:103 | test.py:103:9:103:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:103 | test.py:103:9:103:37 | Attribute() | | -| Taint externally controlled string | test.py:104 | test.py:104:9:104:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:104 | test.py:104:9:104:37 | Attribute() | | -| Taint externally controlled string | test.py:105 | test.py:105:9:105:22 | tainted_string | | --> | Taint externally controlled string | test.py:105 | test.py:105:9:105:42 | Attribute() | | -| Taint externally controlled string | test.py:106 | test.py:106:9:106:22 | tainted_string | | --> | Taint externally controlled string | test.py:106 | test.py:106:9:106:33 | Attribute() | | -| Taint externally controlled string | test.py:107 | test.py:107:9:107:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:107 | test.py:107:9:107:38 | Attribute() | | -| Taint externally controlled string | test.py:108 | test.py:108:9:108:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:108 | test.py:108:9:108:38 | Attribute() | | -| Taint externally controlled string | test.py:109 | test.py:109:9:109:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:109 | test.py:109:9:109:37 | Attribute() | | -| Taint externally controlled string | test.py:110 | test.py:110:9:110:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:110 | test.py:110:9:110:37 | Attribute() | | -| Taint externally controlled string | test.py:111 | test.py:111:9:111:22 | tainted_string | | --> | Taint externally controlled string | test.py:111 | test.py:111:9:111:31 | Attribute() | | -| Taint externally controlled string | test.py:112 | test.py:112:9:112:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:112 | test.py:112:9:112:30 | Attribute() | | -| Taint externally controlled string | test.py:113 | test.py:113:9:113:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:113 | test.py:113:9:113:30 | Attribute() | | -| Taint externally controlled string | test.py:114 | test.py:114:9:114:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:114 | test.py:114:9:114:35 | Attribute() | | -| Taint externally controlled string | test.py:115 | test.py:115:9:115:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:115 | test.py:115:9:115:35 | Attribute() | | -| Taint externally controlled string | test.py:116 | test.py:116:9:116:22 | tainted_string | | --> | Taint externally controlled string | test.py:116 | test.py:116:9:116:30 | Attribute() | | -| Taint externally controlled string | test.py:117 | test.py:117:9:117:22 | tainted_string | | --> | Taint externally controlled string | test.py:117 | test.py:117:9:117:33 | Attribute() | | -| Taint externally controlled string | test.py:118 | test.py:118:9:118:22 | tainted_string | | --> | Taint externally controlled string | test.py:118 | test.py:118:9:118:30 | Attribute() | | -| Taint externally controlled string | test.py:121 | test.py:121:9:121:22 | tainted_string | | --> | Taint externally controlled string | test.py:121 | test.py:121:9:121:30 | Attribute() | | -| Taint externally controlled string | test.py:122 | test.py:122:9:122:22 | tainted_string | | --> | Taint externally controlled string | test.py:122 | test.py:122:9:122:33 | Attribute() | | -| Taint externally controlled string | test.py:133 | test.py:133:5:133:29 | For | | --> | Taint externally controlled string | test.py:134 | test.py:134:14:134:17 | line | | -| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:128 | test.py:128:9:128:20 | tainted_file | | -| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:129 | test.py:129:9:129:20 | tainted_file | | -| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:130 | test.py:130:9:130:20 | tainted_file | | -| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:131 | test.py:131:9:131:20 | tainted_file | | -| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:133 | test.py:133:17:133:28 | tainted_file | | -| Taint file[externally controlled string] | test.py:129 | test.py:129:9:129:20 | tainted_file | | --> | Taint externally controlled string | test.py:129 | test.py:129:9:129:27 | Attribute() | | -| Taint file[externally controlled string] | test.py:130 | test.py:130:9:130:20 | tainted_file | | --> | Taint externally controlled string | test.py:130 | test.py:130:9:130:31 | Attribute() | | -| Taint file[externally controlled string] | test.py:131 | test.py:131:9:131:20 | tainted_file | | --> | Taint [externally controlled string] | test.py:131 | test.py:131:9:131:32 | Attribute() | | -| Taint file[externally controlled string] | test.py:133 | test.py:133:17:133:28 | tainted_file | | --> | Taint externally controlled string | test.py:133 | test.py:133:5:133:29 | For | | -| Taint json[externally controlled string] | test.py:7 | test.py:7:20:7:45 | Attribute() | | --> | Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | | -| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | | --> | Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | | -| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | | --> | Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | | -| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | | -| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:10:11:10 | a | | -| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | | --> | Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | | -| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | | --> | Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | | -| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | | -| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:13:11:13 | b | | -| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | | --> | Taint externally controlled string | test.py:10 | test.py:10:9:10:14 | Subscript | | -| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:14 | Subscript | | -| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:14 | Subscript | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:16:11:16 | c | | -| Taint {externally controlled string} | test.py:73 | test.py:73:9:73:32 | parse_qs() | | --> | Taint {externally controlled string} | test.py:75 | test.py:75:16:75:16 | c | | diff --git a/python/ql/test/library-tests/taint/strings/TestStep.ql b/python/ql/test/library-tests/taint/strings/TestStep.ql deleted file mode 100644 index 177edce3498..00000000000 --- a/python/ql/test/library-tests/taint/strings/TestStep.ql +++ /dev/null @@ -1,11 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from TaintedNode n, TaintedNode s -where - n.getLocation().getFile().getShortName() = "test.py" and - s.getLocation().getFile().getShortName() = "test.py" and - s = n.getASuccessor() -select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext(), - " --> ", "Taint " + s.getTaintKind(), s.getLocation().toString(), s.getAstNode(), s.getContext() diff --git a/python/ql/test/library-tests/taint/strings/TestTaint.expected b/python/ql/test/library-tests/taint/strings/TestTaint.expected deleted file mode 100644 index afc30f98899..00000000000 --- a/python/ql/test/library-tests/taint/strings/TestTaint.expected +++ /dev/null @@ -1,63 +0,0 @@ -| test.py:11 | test_json | a | externally controlled string | -| test.py:11 | test_json | a | json[externally controlled string] | -| test.py:11 | test_json | b | externally controlled string | -| test.py:11 | test_json | b | json[externally controlled string] | -| test.py:11 | test_json | c | externally controlled string | -| test.py:11 | test_json | c | json[externally controlled string] | -| test.py:22 | test_str | a | externally controlled string | -| test.py:22 | test_str | b | externally controlled string | -| test.py:22 | test_str | c | externally controlled string | -| test.py:22 | test_str | d | externally controlled string | -| test.py:22 | test_str | e | externally controlled string | -| test.py:22 | test_str | f | externally controlled string | -| test.py:22 | test_str | g | externally controlled string | -| test.py:27 | test_const_sanitizer1 | tainted_string | NO TAINT | -| test.py:29 | test_const_sanitizer1 | tainted_string | externally controlled string | -| test.py:34 | test_const_sanitizer2 | tainted_string | NO TAINT | -| test.py:36 | test_const_sanitizer2 | tainted_string | externally controlled string | -| test.py:43 | test_str2 | a | externally controlled string | -| test.py:43 | test_str2 | b | externally controlled string | -| test.py:43 | test_str2 | c | externally controlled string | -| test.py:51 | test_exc_info | res | exception.info | -| test.py:59 | test_untrusted | res | externally controlled string | -| test.py:75 | test_urlsplit_urlparse | a | [externally controlled string] | -| test.py:75 | test_urlsplit_urlparse | b | [externally controlled string] | -| test.py:75 | test_urlsplit_urlparse | c | {externally controlled string} | -| test.py:75 | test_urlsplit_urlparse | d | [[externally controlled string]] | -| test.py:85 | test_method_reference | a | externally controlled string | -| test.py:85 | test_method_reference | b | NO TAINT | -| test.py:91 | test_str_methods | Attribute() | externally controlled string | -| test.py:92 | test_str_methods | Attribute() | externally controlled string | -| test.py:93 | test_str_methods | Attribute() | externally controlled string | -| test.py:94 | test_str_methods | Attribute() | externally controlled string | -| test.py:95 | test_str_methods | Attribute() | externally controlled string | -| test.py:96 | test_str_methods | Attribute() | externally controlled string | -| test.py:97 | test_str_methods | Attribute() | externally controlled string | -| test.py:98 | test_str_methods | Attribute() | externally controlled string | -| test.py:99 | test_str_methods | Attribute() | externally controlled string | -| test.py:100 | test_str_methods | Attribute() | externally controlled string | -| test.py:101 | test_str_methods | Attribute() | externally controlled string | -| test.py:102 | test_str_methods | Attribute() | externally controlled string | -| test.py:103 | test_str_methods | Attribute() | [externally controlled string] | -| test.py:104 | test_str_methods | Subscript | externally controlled string | -| test.py:105 | test_str_methods | Attribute() | externally controlled string | -| test.py:106 | test_str_methods | Attribute() | externally controlled string | -| test.py:107 | test_str_methods | Attribute() | [externally controlled string] | -| test.py:108 | test_str_methods | Subscript | externally controlled string | -| test.py:109 | test_str_methods | Attribute() | [externally controlled string] | -| test.py:110 | test_str_methods | Subscript | externally controlled string | -| test.py:111 | test_str_methods | Attribute() | externally controlled string | -| test.py:112 | test_str_methods | Attribute() | [externally controlled string] | -| test.py:113 | test_str_methods | Subscript | externally controlled string | -| test.py:114 | test_str_methods | Attribute() | [externally controlled string] | -| test.py:115 | test_str_methods | Subscript | externally controlled string | -| test.py:116 | test_str_methods | Attribute() | externally controlled string | -| test.py:117 | test_str_methods | Attribute() | externally controlled string | -| test.py:118 | test_str_methods | Attribute() | externally controlled string | -| test.py:121 | test_str_methods | Attribute() | externally controlled string | -| test.py:122 | test_str_methods | Attribute() | externally controlled string | -| test.py:128 | test_tainted_file | tainted_file | file[externally controlled string] | -| test.py:129 | test_tainted_file | Attribute() | externally controlled string | -| test.py:130 | test_tainted_file | Attribute() | externally controlled string | -| test.py:131 | test_tainted_file | Attribute() | [externally controlled string] | -| test.py:134 | test_tainted_file | line | externally controlled string | diff --git a/python/ql/test/library-tests/taint/strings/TestTaint.ql b/python/ql/test/library-tests/taint/strings/TestTaint.ql deleted file mode 100644 index 47883578516..00000000000 --- a/python/ql/test/library-tests/taint/strings/TestTaint.ql +++ /dev/null @@ -1,19 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from Call call, Expr arg, string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - call.getFunc().(Name).getId() = "test" and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "NO TAINT" - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) - ) -select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(), - taint_string diff --git a/python/ql/test/library-tests/taint/strings/test.py b/python/ql/test/library-tests/taint/strings/test.py deleted file mode 100644 index 78a0712ceca..00000000000 --- a/python/ql/test/library-tests/taint/strings/test.py +++ /dev/null @@ -1,134 +0,0 @@ -import json -from copy import copy -import sys - -def test_json(): - tainted_string = TAINTED_STRING - tainted_json = json.loads(tainted_string) - a = tainted_json["x"] - b = a.get("y") - c = b["z"] - test(a, b, c) - -def test_str(): - tainted_string = TAINTED_STRING - a = tainted_string.ljust(8) - b = tainted_string.copy() - c = tainted_string[:] - d = tainted_string[::2] - e = reversed(tainted_string) - f = copy(tainted_string) - g = tainted_string.strip() - test(a, b, c, d, e, f, g) - -def test_const_sanitizer1(): - tainted_string = TAINTED_STRING - if tainted_string == "OK": - test(tainted_string) # not tainted - else: - test(tainted_string) # still tainted - -def test_const_sanitizer2(): - tainted_string = TAINTED_STRING - if tainted_string == "OK" or tainted_string == "ALSO_OK": - test(tainted_string) # not tainted - else: - test(tainted_string) # still tainted - -def test_str2(): - tainted_string = TAINTED_STRING - a = str(tainted_string) - b = bytes(tainted_string) # This is an error in Python 3 - c = bytes(tainted_string, encoding="utf8") # This is an error in Python 2 - test(a, b, c) - -def cross_over(func, taint): - return func(taint) - -def test_exc_info(): - info = TAINTED_EXCEPTION_INFO - res = cross_over(exc_info_call, info) - test(res) - -def exc_info_call(arg): - return arg - -def test_untrusted(): - ext = TAINTED_STRING - res = cross_over(untrusted_call, ext) - test(res) - -def exc_untrusted_call(arg): - return arg - -if sys.version_info[0] == 2: - from urlparse import urlsplit, urlparse, parse_qs, parse_qsl -if sys.version_info[0] == 3: - from urllib.parse import urlsplit, urlparse, parse_qs, parse_qsl - -def test_urlsplit_urlparse(): - tainted_string = TAINTED_STRING - a = urlsplit(tainted_string) - b = urlparse(tainted_string) - c = parse_qs(tainted_string) - d = parse_qsl(tainted_string) - test(a, b, c, d) - -def test_method_reference(): - tainted_string = TAINTED_STRING - - a = tainted_string.title() - - func = tainted_string.title - b = func() - - test(a, b) # TODO: `b` not tainted - -def test_str_methods(): - tainted_string = TAINTED_STRING - - test( - tainted_string.capitalize(), - tainted_string.casefold(), - tainted_string.center(), - tainted_string.encode('utf-8'), - tainted_string.encode('utf-8').decode('utf-8'), - tainted_string.expandtabs(), - tainted_string.format(foo=42), - tainted_string.format_map({'foo': 42}), - tainted_string.ljust(100), - tainted_string.lower(), - tainted_string.lstrip(), - tainted_string.lstrip('w.'), - tainted_string.partition(';'), - tainted_string.partition(';')[0], - tainted_string.replace('/', '', 1), - tainted_string.rjust(100), - tainted_string.rpartition(';'), - tainted_string.rpartition(';')[2], - tainted_string.rsplit(';', 4), - tainted_string.rsplit(';', 4)[-1], - tainted_string.rstrip(), - tainted_string.split(), - tainted_string.split()[0], - tainted_string.splitlines(), - tainted_string.splitlines()[0], - tainted_string.strip(), - tainted_string.swapcase(), - tainted_string.title(), - # ignoring, as I have never seen this in practice - # tainted_string.translate(translation_table), - tainted_string.upper(), - tainted_string.zfill(100), - ) - -def test_tainted_file(): - tainted_file = TAINTED_FILE - test( - tainted_file, - tainted_file.read(), - tainted_file.readline(), - tainted_file.readlines(), - ) - for line in tainted_file: - test(line) diff --git a/python/ql/test/library-tests/taint/unpacking/Taint.qll b/python/ql/test/library-tests/taint/unpacking/Taint.qll deleted file mode 100644 index 010b9738c5c..00000000000 --- a/python/ql/test/library-tests/taint/unpacking/Taint.qll +++ /dev/null @@ -1,27 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Untrusted - -class SimpleSource extends TaintSource { - SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "taint source" } -} - -class ListSource extends TaintSource { - ListSource() { this.(NameNode).getId() = "TAINTED_LIST" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } - - override string toString() { result = "list taint source" } -} - -class DictSource extends TaintSource { - DictSource() { this.(NameNode).getId() = "TAINTED_DICT" } - - override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } - - override string toString() { result = "dict taint source" } -} diff --git a/python/ql/test/library-tests/taint/unpacking/TestStep.expected b/python/ql/test/library-tests/taint/unpacking/TestStep.expected deleted file mode 100644 index 5d800e6b5b8..00000000000 --- a/python/ql/test/library-tests/taint/unpacking/TestStep.expected +++ /dev/null @@ -1,41 +0,0 @@ -| Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | --> | Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | -| Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | --> | Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | -| Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | --> | Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | -| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:22:23:22 | b | | -| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint [externally controlled string] | test.py:23 | test.py:23:25:23:25 | c | | -| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint externally controlled string | test.py:23 | test.py:23:10:23:11 | a1 | | -| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint externally controlled string | test.py:23 | test.py:23:14:23:15 | a2 | | -| Taint [[externally controlled string]] | test.py:22 | test.py:22:28:22:29 | ll | | --> | Taint externally controlled string | test.py:23 | test.py:23:18:23:19 | a3 | | -| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint [externally controlled string] | test.py:27 | test.py:27:22:27:22 | b | | -| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint [externally controlled string] | test.py:27 | test.py:27:25:27:25 | c | | -| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint externally controlled string | test.py:27 | test.py:27:10:27:11 | a1 | | -| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint externally controlled string | test.py:27 | test.py:27:14:27:15 | a2 | | -| Taint [[externally controlled string]] | test.py:26 | test.py:26:28:26:29 | ll | | --> | Taint externally controlled string | test.py:27 | test.py:27:18:27:19 | a3 | | -| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint [externally controlled string] | test.py:31 | test.py:31:22:31:22 | b | | -| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint [externally controlled string] | test.py:31 | test.py:31:25:31:25 | c | | -| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint externally controlled string | test.py:31 | test.py:31:10:31:11 | a1 | | -| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint externally controlled string | test.py:31 | test.py:31:14:31:15 | a2 | | -| Taint [[externally controlled string]] | test.py:30 | test.py:30:28:30:29 | ll | | --> | Taint externally controlled string | test.py:31 | test.py:31:18:31:19 | a3 | | -| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:10:48:10 | a | | -| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:13:48:13 | b | | -| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:16:48:16 | c | | -| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:19:48:19 | d | | -| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:22:48:22 | e | | -| Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | --> | Taint externally controlled string | test.py:48 | test.py:48:25:48:25 | f | | -| Taint [externally controlled string] | test.py:6 | test.py:6:9:6:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:7 | test.py:7:15:7:15 | l | | -| Taint [externally controlled string] | test.py:7 | test.py:7:15:7:15 | l | | --> | Taint externally controlled string | test.py:8 | test.py:8:10:8:10 | a | | -| Taint [externally controlled string] | test.py:7 | test.py:7:15:7:15 | l | | --> | Taint externally controlled string | test.py:8 | test.py:8:13:8:13 | b | | -| Taint [externally controlled string] | test.py:7 | test.py:7:15:7:15 | l | | --> | Taint externally controlled string | test.py:8 | test.py:8:16:8:16 | c | | -| Taint [externally controlled string] | test.py:12 | test.py:12:9:12:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:13 | test.py:13:17:13:17 | l | | -| Taint [externally controlled string] | test.py:13 | test.py:13:17:13:17 | l | | --> | Taint externally controlled string | test.py:14 | test.py:14:10:14:10 | a | | -| Taint [externally controlled string] | test.py:13 | test.py:13:17:13:17 | l | | --> | Taint externally controlled string | test.py:14 | test.py:14:13:14:13 | b | | -| Taint [externally controlled string] | test.py:13 | test.py:13:17:13:17 | l | | --> | Taint externally controlled string | test.py:14 | test.py:14:16:14:16 | c | | -| Taint [externally controlled string] | test.py:18 | test.py:18:9:18:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:19 | test.py:19:11:19:11 | l | | -| Taint [externally controlled string] | test.py:18 | test.py:18:9:18:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:19 | test.py:19:14:19:14 | l | | -| Taint [externally controlled string] | test.py:18 | test.py:18:9:18:20 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:19 | test.py:19:17:19:17 | l | | -| Taint [externally controlled string] | test.py:19 | test.py:19:11:19:11 | l | | --> | Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | -| Taint [externally controlled string] | test.py:19 | test.py:19:14:19:14 | l | | --> | Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | -| Taint [externally controlled string] | test.py:19 | test.py:19:17:19:17 | l | | --> | Taint [[externally controlled string]] | test.py:19 | test.py:19:10:19:18 | List | | -| Taint [externally controlled string] | test.py:43 | test.py:43:20:43:31 | TAINTED_LIST | | --> | Taint [externally controlled string] | test.py:47 | test.py:47:28:47:39 | tainted_list | | -| Taint [externally controlled string] | test.py:47 | test.py:47:28:47:39 | tainted_list | | --> | Taint [[externally controlled string]] | test.py:47 | test.py:47:28:47:54 | Tuple | | -| Taint [externally controlled string] | test.py:55 | test.py:55:27:55:38 | TAINTED_LIST | | --> | Taint [[externally controlled string]] | test.py:55 | test.py:55:25:55:40 | List | | diff --git a/python/ql/test/library-tests/taint/unpacking/TestStep.ql b/python/ql/test/library-tests/taint/unpacking/TestStep.ql deleted file mode 100644 index 177edce3498..00000000000 --- a/python/ql/test/library-tests/taint/unpacking/TestStep.ql +++ /dev/null @@ -1,11 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from TaintedNode n, TaintedNode s -where - n.getLocation().getFile().getShortName() = "test.py" and - s.getLocation().getFile().getShortName() = "test.py" and - s = n.getASuccessor() -select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext(), - " --> ", "Taint " + s.getTaintKind(), s.getLocation().toString(), s.getAstNode(), s.getContext() diff --git a/python/ql/test/library-tests/taint/unpacking/TestTaint.expected b/python/ql/test/library-tests/taint/unpacking/TestTaint.expected deleted file mode 100644 index d1bad70f811..00000000000 --- a/python/ql/test/library-tests/taint/unpacking/TestTaint.expected +++ /dev/null @@ -1,33 +0,0 @@ -| test.py:8 | unpacking | a | externally controlled string | -| test.py:8 | unpacking | b | externally controlled string | -| test.py:8 | unpacking | c | externally controlled string | -| test.py:14 | unpacking_to_list | a | externally controlled string | -| test.py:14 | unpacking_to_list | b | externally controlled string | -| test.py:14 | unpacking_to_list | c | externally controlled string | -| test.py:23 | nested | a1 | externally controlled string | -| test.py:23 | nested | a2 | externally controlled string | -| test.py:23 | nested | a3 | externally controlled string | -| test.py:23 | nested | b | [externally controlled string] | -| test.py:23 | nested | c | [externally controlled string] | -| test.py:27 | nested | a1 | externally controlled string | -| test.py:27 | nested | a2 | externally controlled string | -| test.py:27 | nested | a3 | externally controlled string | -| test.py:27 | nested | b | [externally controlled string] | -| test.py:27 | nested | c | [externally controlled string] | -| test.py:31 | nested | a1 | externally controlled string | -| test.py:31 | nested | a2 | externally controlled string | -| test.py:31 | nested | a3 | externally controlled string | -| test.py:31 | nested | b | [externally controlled string] | -| test.py:31 | nested | c | [externally controlled string] | -| test.py:38 | unpack_from_set | a | NO TAINT | -| test.py:38 | unpack_from_set | b | NO TAINT | -| test.py:38 | unpack_from_set | c | NO TAINT | -| test.py:48 | contrived_1 | a | externally controlled string | -| test.py:48 | contrived_1 | b | externally controlled string | -| test.py:48 | contrived_1 | c | externally controlled string | -| test.py:48 | contrived_1 | d | externally controlled string | -| test.py:48 | contrived_1 | e | externally controlled string | -| test.py:48 | contrived_1 | f | externally controlled string | -| test.py:56 | contrived_2 | a | NO TAINT | -| test.py:56 | contrived_2 | b | NO TAINT | -| test.py:56 | contrived_2 | c | NO TAINT | diff --git a/python/ql/test/library-tests/taint/unpacking/TestTaint.ql b/python/ql/test/library-tests/taint/unpacking/TestTaint.ql deleted file mode 100644 index 47883578516..00000000000 --- a/python/ql/test/library-tests/taint/unpacking/TestTaint.ql +++ /dev/null @@ -1,19 +0,0 @@ -import python -import semmle.python.dataflow.TaintTracking -import Taint - -from Call call, Expr arg, string taint_string -where - call.getLocation().getFile().getShortName() = "test.py" and - call.getFunc().(Name).getId() = "test" and - arg = call.getAnArg() and - ( - not exists(TaintedNode tainted | tainted.getAstNode() = arg) and - taint_string = "NO TAINT" - or - exists(TaintedNode tainted | tainted.getAstNode() = arg | - taint_string = tainted.getTaintKind().toString() - ) - ) -select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(), - taint_string diff --git a/python/ql/test/library-tests/taint/unpacking/test.py b/python/ql/test/library-tests/taint/unpacking/test.py deleted file mode 100644 index df3961ad6ab..00000000000 --- a/python/ql/test/library-tests/taint/unpacking/test.py +++ /dev/null @@ -1,58 +0,0 @@ -def test(*args): - pass - - -def unpacking(): - l = TAINTED_LIST - a, b, c = l - test(a, b, c) - - -def unpacking_to_list(): - l = TAINTED_LIST - [a, b, c] = l - test(a, b, c) - - -def nested(): - l = TAINTED_LIST - ll = [l, l, l] - - # list - [[a1, a2, a3], b, c] = ll - test(a1, a2, a3, b, c) - - # tuple - ((a1, a2, a3), b, c) = ll - test(a1, a2, a3, b, c) - - # mixed - [(a1, a2, a3), b, c] = ll - test(a1, a2, a3, b, c) - - -def unpack_from_set(): - # no guarantee on ordering ... don't know why you would ever do this - a, b, c = {"foo", "bar", TAINTED_STRING} - # either all should be tainted, or none of them - test(a, b, c) - - -def contrived_1(): - # A contrived example. Don't know why anyone would ever actually do this. - tainted_list = TAINTED_LIST - no_taint_list = [1,2,3] - - # We don't handle this case currently, since we mark `d`, `e` and `f` as tainted. - (a, b, c), (d, e, f) = tainted_list, no_taint_list - test(a, b, c, d, e, f) - - -def contrived_2(): - # A contrived example. Don't know why anyone would ever actually do this. - - # We currently only handle taint nested 2 levels. - [[[ (a,b,c) ]]] = [[[ TAINTED_LIST ]]] - test(a, b, c) - -# For Python 3, see https://www.python.org/dev/peps/pep-3132/ From 3a436d1f84acd3ac1f1c563324909d14e1d24010 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 12 Jun 2023 11:56:44 +0200 Subject: [PATCH 537/739] do a quick-and-dirty conversion of py/hardcoded-credentials to the new dataflow library --- .../Security/CWE-798/HardcodedCredentials.ql | 39 +++++++------------ .../HardcodedCredentials.expected | 20 +++++++--- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/python/ql/src/Security/CWE-798/HardcodedCredentials.ql b/python/ql/src/Security/CWE-798/HardcodedCredentials.ql index 4c9818e91f8..d1d29a78ff5 100644 --- a/python/ql/src/Security/CWE-798/HardcodedCredentials.ql +++ b/python/ql/src/Security/CWE-798/HardcodedCredentials.ql @@ -13,13 +13,10 @@ */ import python -import semmle.python.security.Paths -import semmle.python.dataflow.TaintTracking +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking import semmle.python.filters.Tests - -class HardcodedValue extends TaintKind { - HardcodedValue() { this = "hard coded value" } -} +import DataFlow::PathGraph bindingset[char, fraction] predicate fewer_characters_than(StrConst str, string char, float fraction) { @@ -78,31 +75,27 @@ predicate maybeCredential(ControlFlowNode f) { ) } -class HardcodedValueSource extends TaintSource { - HardcodedValueSource() { maybeCredential(this) } - - override predicate isSourceOf(TaintKind kind) { kind instanceof HardcodedValue } +class HardcodedValueSource extends DataFlow::Node { + HardcodedValueSource() { maybeCredential(this.asCfgNode()) } } -class CredentialSink extends TaintSink { +class CredentialSink extends DataFlow::Node { CredentialSink() { exists(string name | name.regexpMatch(getACredentialRegex()) and not name.matches("%file") | - any(FunctionValue func).getNamedArgumentForCall(_, name) = this + any(FunctionValue func).getNamedArgumentForCall(_, name) = this.asCfgNode() or - exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this) + exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this.asCfgNode()) or exists(CompareNode cmp, NameNode n | n.getId() = name | - cmp.operands(this, any(Eq eq), n) + cmp.operands(this.asCfgNode(), any(Eq eq), n) or - cmp.operands(n, any(Eq eq), this) + cmp.operands(n, any(Eq eq), this.asCfgNode()) ) ) } - - override predicate sinks(TaintKind kind) { kind instanceof HardcodedValue } } /** @@ -118,16 +111,14 @@ private string getACredentialRegex() { class HardcodedCredentialsConfiguration extends TaintTracking::Configuration { HardcodedCredentialsConfiguration() { this = "Hardcoded credentials configuration" } - override predicate isSource(TaintTracking::Source source) { - source instanceof HardcodedValueSource - } + override predicate isSource(DataFlow::Node source) { source instanceof HardcodedValueSource } - override predicate isSink(TaintTracking::Sink sink) { sink instanceof CredentialSink } + override predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink } } -from HardcodedCredentialsConfiguration config, TaintedPathSource src, TaintedPathSink sink +from HardcodedCredentialsConfiguration config, DataFlow::PathNode src, DataFlow::PathNode sink where config.hasFlowPath(src, sink) and - not any(TestScope test).contains(src.getAstNode()) -select src.getSource(), src, sink, "This hardcoded value is $@.", sink.getNode(), + not any(TestScope test).contains(src.getNode().asCfgNode().getNode()) +select src.getNode(), src, sink, "This hardcoded value is $@.", sink.getNode(), "used as credentials" diff --git a/python/ql/test/query-tests/Security/CWE-798-HardcodedCredentials/HardcodedCredentials.expected b/python/ql/test/query-tests/Security/CWE-798-HardcodedCredentials/HardcodedCredentials.expected index efea6e2f054..61251a633e2 100644 --- a/python/ql/test/query-tests/Security/CWE-798-HardcodedCredentials/HardcodedCredentials.expected +++ b/python/ql/test/query-tests/Security/CWE-798-HardcodedCredentials/HardcodedCredentials.expected @@ -1,8 +1,16 @@ edges -| test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value | -| test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value | -| test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value | -| test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value | +| test.py:5:1:5:8 | GSSA Variable USERNAME | test.py:14:18:14:25 | ControlFlowNode for USERNAME | +| test.py:5:12:5:24 | ControlFlowNode for Str | test.py:5:1:5:8 | GSSA Variable USERNAME | +| test.py:6:1:6:8 | GSSA Variable PASSWORD | test.py:15:18:15:25 | ControlFlowNode for PASSWORD | +| test.py:6:12:6:25 | ControlFlowNode for Str | test.py:6:1:6:8 | GSSA Variable PASSWORD | +nodes +| test.py:5:1:5:8 | GSSA Variable USERNAME | semmle.label | GSSA Variable USERNAME | +| test.py:5:12:5:24 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str | +| test.py:6:1:6:8 | GSSA Variable PASSWORD | semmle.label | GSSA Variable PASSWORD | +| test.py:6:12:6:25 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str | +| test.py:14:18:14:25 | ControlFlowNode for USERNAME | semmle.label | ControlFlowNode for USERNAME | +| test.py:15:18:15:25 | ControlFlowNode for PASSWORD | semmle.label | ControlFlowNode for PASSWORD | +subpaths #select -| test.py:5:12:5:24 | Str | test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value | This hardcoded value is $@. | test.py:14:18:14:25 | USERNAME | used as credentials | -| test.py:6:12:6:25 | Str | test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value | This hardcoded value is $@. | test.py:15:18:15:25 | PASSWORD | used as credentials | +| test.py:5:12:5:24 | ControlFlowNode for Str | test.py:5:12:5:24 | ControlFlowNode for Str | test.py:14:18:14:25 | ControlFlowNode for USERNAME | This hardcoded value is $@. | test.py:14:18:14:25 | ControlFlowNode for USERNAME | used as credentials | +| test.py:6:12:6:25 | ControlFlowNode for Str | test.py:6:12:6:25 | ControlFlowNode for Str | test.py:15:18:15:25 | ControlFlowNode for PASSWORD | This hardcoded value is $@. | test.py:15:18:15:25 | ControlFlowNode for PASSWORD | used as credentials | From e463819bc2873e921df69e2cdb8b268a8e96118c Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 12 Jun 2023 14:43:48 +0200 Subject: [PATCH 538/739] get `ParamSource.ql` to compile by deleting import that got deleted - I have no if this is a good change --- python/ql/test/library-tests/taint/general/ParamSource.ql | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/ql/test/library-tests/taint/general/ParamSource.ql b/python/ql/test/library-tests/taint/general/ParamSource.ql index 7ac2b7699ef..9ebc909cc28 100644 --- a/python/ql/test/library-tests/taint/general/ParamSource.ql +++ b/python/ql/test/library-tests/taint/general/ParamSource.ql @@ -1,7 +1,5 @@ import python import semmle.python.dataflow.TaintTracking -/* Standard library sink */ -import semmle.python.security.injection.Command class TestKind extends TaintKind { TestKind() { this = "test" } From 6e001ec062a23cead042d5ec1a13840042a5b0ec Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 12 Jun 2023 14:47:22 +0200 Subject: [PATCH 539/739] deprecate `SqlInjectionSink` - it's not used anywhere --- python/ql/lib/semmle/python/security/SQL.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/security/SQL.qll b/python/ql/lib/semmle/python/security/SQL.qll index 4d2ef6218cc..6485402b78a 100644 --- a/python/ql/lib/semmle/python/security/SQL.qll +++ b/python/ql/lib/semmle/python/security/SQL.qll @@ -1,4 +1,4 @@ import python import semmle.python.dataflow.TaintTracking -abstract class SqlInjectionSink extends TaintSink { } +abstract deprecated class SqlInjectionSink extends TaintSink { } From 1f8f111ef6a64e01efa2a9dac374fd23d1be32f7 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 12 Jun 2023 14:59:18 +0200 Subject: [PATCH 540/739] reintroduce DataFlowType - otherwise nothing in the old DataFlow library would compile --- .../ql/lib/semmle/python/dataflow/old/TaintTracking.qll | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll index 0ce4bc27790..d0293522404 100644 --- a/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll +++ b/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll @@ -664,6 +664,14 @@ module DataFlow { } } +deprecated private class DataFlowType extends TaintKind { + // this only exists to avoid an empty recursion error in the type checker + DataFlowType() { + this = "Data flow" and + 1 = 2 + } +} + pragma[noinline] private predicate dict_construct(ControlFlowNode itemnode, ControlFlowNode dictnode) { dictnode.(DictNode).getAValue() = itemnode From bfe7e62f35f8485759d0a6c7e81073b5d7e6e5c7 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 12 Jun 2023 20:15:40 +0200 Subject: [PATCH 541/739] update some expected outputs - some tests no longer have an edges relation - and XsltSinks lost a result --- .../Security/CWE-091/XsltSinks.expected | 1 - .../taint/config/RockPaperScissors.expected | 96 ------------------- .../taint/config/Simple.expected | 96 ------------------- .../taint/example/ExampleConfig.expected | 26 ----- 4 files changed, 219 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091/XsltSinks.expected b/python/ql/test/experimental/query-tests/Security/CWE-091/XsltSinks.expected index 7150b3046e2..dec055bc8e0 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-091/XsltSinks.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-091/XsltSinks.expected @@ -1,4 +1,3 @@ -| xslt.py:14:29:14:37 | lxml.etree.parse.xslt | lxml etree xml | | xsltInjection.py:12:28:12:36 | lxml.etree.XSLT | lxml etree xml | | xsltInjection.py:21:29:21:37 | lxml.etree.parse.xslt | lxml etree xml | | xsltInjection.py:31:24:31:32 | lxml.etree.parse.xslt | lxml etree xml | diff --git a/python/ql/test/library-tests/taint/config/RockPaperScissors.expected b/python/ql/test/library-tests/taint/config/RockPaperScissors.expected index 0639e4bf227..ae34dcd904e 100644 --- a/python/ql/test/library-tests/taint/config/RockPaperScissors.expected +++ b/python/ql/test/library-tests/taint/config/RockPaperScissors.expected @@ -1,99 +1,3 @@ -edges -| carrier.py:17:9:17:31 | .attr = simple.test | carrier.py:18:10:18:10 | .attr = simple.test | -| carrier.py:17:25:17:30 | simple.test | carrier.py:17:9:17:31 | .attr = simple.test | -| carrier.py:18:10:18:10 | .attr = simple.test | carrier.py:18:10:18:15 | simple.test | -| carrier.py:21:9:21:28 | explicit.carrier | carrier.py:22:10:22:10 | explicit.carrier | -| carrier.py:22:10:22:10 | explicit.carrier | carrier.py:22:10:22:22 | simple.test | -| carrier.py:25:9:25:36 | .attr = simple.test | carrier.py:26:10:26:10 | .attr = simple.test | -| carrier.py:25:13:25:35 | .attr = simple.test | carrier.py:25:9:25:36 | .attr = simple.test | -| carrier.py:25:29:25:34 | simple.test | carrier.py:25:13:25:35 | .attr = simple.test | -| carrier.py:26:10:26:10 | .attr = simple.test | carrier.py:26:10:26:21 | simple.test | -| carrier.py:29:9:29:33 | explicit.carrier | carrier.py:30:10:30:10 | explicit.carrier | -| carrier.py:29:13:29:32 | explicit.carrier | carrier.py:29:9:29:33 | explicit.carrier | -| carrier.py:30:10:30:10 | explicit.carrier | carrier.py:30:10:30:22 | simple.test | -| carrier.py:33:9:33:45 | .attr = explicit.carrier | carrier.py:34:9:34:9 | .attr = explicit.carrier | -| carrier.py:33:25:33:44 | explicit.carrier | carrier.py:33:9:33:45 | .attr = explicit.carrier | -| carrier.py:34:9:34:9 | .attr = explicit.carrier | carrier.py:34:9:34:14 | explicit.carrier | -| carrier.py:34:9:34:14 | explicit.carrier | carrier.py:35:10:35:10 | explicit.carrier | -| carrier.py:35:10:35:10 | explicit.carrier | carrier.py:35:10:35:22 | simple.test | -| deep.py:20:5:20:14 | simple.test | deep.py:22:6:22:6 | simple.test | -| deep.py:20:8:20:13 | simple.test | deep.py:20:5:20:14 | simple.test | -| module.py:3:13:3:18 | simple.test | test.py:85:8:85:13 | .dangerous = simple.test | -| module.py:3:13:3:18 | simple.test | test.py:88:9:88:14 | .dangerous = simple.test | -| module.py:3:13:3:18 | simple.test | test.py:110:11:110:16 | .dangerous = simple.test | -| module.py:3:13:3:18 | simple.test | test.py:115:11:115:16 | .dangerous = simple.test | -| module.py:3:13:3:18 | simple.test | test.py:155:20:155:38 | simple.test | -| module.py:7:12:7:17 | simple.test | test.py:100:9:100:31 | simple.test | -| rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:25:9:25:9 | rock | -| rockpaperscissors.py:25:9:25:9 | rock | rockpaperscissors.py:25:9:25:16 | scissors | -| rockpaperscissors.py:25:9:25:16 | scissors | rockpaperscissors.py:25:9:25:23 | paper | -| rockpaperscissors.py:25:9:25:23 | paper | rockpaperscissors.py:26:14:26:14 | paper | -| sanitizer.py:9:9:9:20 | SQL injection | sanitizer.py:13:19:13:19 | SQL injection | -| sanitizer.py:16:9:16:20 | Command injection | sanitizer.py:20:20:20:20 | Command injection | -| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:26:19:26:19 | SQL injection | -| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:28:19:28:19 | SQL injection | -| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:33:20:33:20 | Command injection | -| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:35:20:35:20 | Command injection | -| test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test | -| test.py:10:12:10:17 | simple.test | test.py:16:9:16:16 | simple.test | -| test.py:10:12:10:17 | simple.test | test.py:24:9:24:16 | simple.test | -| test.py:10:12:10:17 | simple.test | test.py:44:12:44:22 | simple.test | -| test.py:12:10:12:12 | simple.test | test.py:13:10:13:12 | simple.test | -| test.py:16:9:16:16 | simple.test | test.py:17:10:17:10 | simple.test | -| test.py:20:9:20:14 | simple.test | test.py:21:10:21:10 | simple.test | -| test.py:21:10:21:10 | simple.test | test.py:12:10:12:12 | simple.test | -| test.py:24:9:24:16 | simple.test | test.py:25:10:25:10 | simple.test | -| test.py:25:10:25:10 | simple.test | test.py:12:10:12:12 | simple.test | -| test.py:37:13:37:18 | simple.test | test.py:41:14:41:14 | simple.test | -| test.py:44:12:44:22 | simple.test | test.py:54:9:54:17 | simple.test | -| test.py:46:11:46:13 | simple.test | test.py:47:10:47:12 | simple.test | -| test.py:47:10:47:12 | simple.test | test.py:12:10:12:12 | simple.test | -| test.py:49:17:49:19 | simple.test | test.py:51:14:51:16 | simple.test | -| test.py:51:14:51:16 | simple.test | test.py:12:10:12:12 | simple.test | -| test.py:54:9:54:17 | simple.test | test.py:55:11:55:11 | simple.test | -| test.py:55:11:55:11 | simple.test | test.py:46:11:46:13 | simple.test | -| test.py:62:13:62:18 | simple.test | test.py:63:17:63:17 | simple.test | -| test.py:63:17:63:17 | simple.test | test.py:49:17:49:19 | simple.test | -| test.py:67:13:67:18 | simple.test | test.py:70:17:70:17 | simple.test | -| test.py:70:17:70:17 | simple.test | test.py:49:17:49:19 | simple.test | -| test.py:76:9:76:14 | simple.test | test.py:77:13:77:13 | simple.test | -| test.py:77:9:77:14 | simple.test | test.py:78:10:78:10 | simple.test | -| test.py:77:13:77:13 | simple.test | test.py:77:9:77:14 | simple.test | -| test.py:85:8:85:13 | .dangerous = simple.test | test.py:88:9:88:14 | .dangerous = simple.test | -| test.py:85:8:85:13 | .dangerous = simple.test | test.py:110:11:110:16 | .dangerous = simple.test | -| test.py:85:8:85:13 | .dangerous = simple.test | test.py:115:11:115:16 | .dangerous = simple.test | -| test.py:88:9:88:14 | .dangerous = simple.test | test.py:88:9:88:24 | simple.test | -| test.py:88:9:88:24 | simple.test | test.py:89:10:89:10 | simple.test | -| test.py:100:9:100:31 | simple.test | test.py:101:10:101:10 | simple.test | -| test.py:105:12:105:14 | .x = simple.test | test.py:106:10:106:12 | .x = simple.test | -| test.py:106:10:106:12 | .x = simple.test | test.py:106:10:106:14 | simple.test | -| test.py:110:11:110:16 | .dangerous = simple.test | test.py:110:11:110:26 | simple.test | -| test.py:110:11:110:26 | simple.test | test.py:111:10:111:10 | .x = simple.test | -| test.py:111:10:111:10 | .x = simple.test | test.py:111:10:111:12 | simple.test | -| test.py:115:11:115:16 | .dangerous = simple.test | test.py:115:11:115:26 | simple.test | -| test.py:115:11:115:26 | simple.test | test.py:116:13:116:13 | .x = simple.test | -| test.py:116:9:116:14 | .x = simple.test | test.py:117:12:117:12 | .x = simple.test | -| test.py:116:13:116:13 | .x = simple.test | test.py:116:9:116:14 | .x = simple.test | -| test.py:117:12:117:12 | .x = simple.test | test.py:105:12:105:14 | .x = simple.test | -| test.py:126:13:126:25 | simple.test | test.py:130:21:130:21 | simple.test | -| test.py:128:13:128:18 | simple.test | test.py:132:14:132:14 | simple.test | -| test.py:155:20:155:38 | simple.test | test.py:156:6:156:11 | simple.test | -| test.py:159:10:159:15 | simple.test | test.py:160:14:160:14 | simple.test | -| test.py:163:9:163:14 | simple.test | test.py:165:10:165:10 | simple.test | -| test.py:178:9:178:14 | simple.test | test.py:180:14:180:14 | simple.test | -| test.py:178:9:178:14 | simple.test | test.py:186:14:186:14 | simple.test | -| test.py:195:9:195:14 | simple.test | test.py:197:14:197:14 | simple.test | -| test.py:195:9:195:14 | simple.test | test.py:199:14:199:14 | simple.test | -| test.py:208:11:208:18 | sequence of simple.test | test.py:209:14:209:16 | sequence of simple.test | -| test.py:208:12:208:17 | simple.test | test.py:208:11:208:18 | sequence of simple.test | -| test.py:209:5:209:17 | simple.test | test.py:210:15:210:15 | simple.test | -| test.py:209:14:209:16 | sequence of simple.test | test.py:209:5:209:17 | simple.test | -| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | iterable.simple | -| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | sequence of simple.test | -| test.py:213:5:213:33 | simple.test | test.py:214:14:214:14 | simple.test | -| test.py:213:14:213:32 | iterable.simple | test.py:213:5:213:33 | simple.test | -| test.py:213:14:213:32 | sequence of simple.test | test.py:213:5:213:33 | simple.test | -#select | rockpaperscissors.py:13:10:13:17 | SCISSORS | rockpaperscissors.py:13:10:13:17 | scissors | rockpaperscissors.py:13:10:13:17 | scissors | $@ loses to $@. | rockpaperscissors.py:13:10:13:17 | SCISSORS | scissors | rockpaperscissors.py:13:10:13:17 | SCISSORS | scissors | | rockpaperscissors.py:16:11:16:14 | ROCK | rockpaperscissors.py:16:11:16:14 | rock | rockpaperscissors.py:16:11:16:14 | rock | $@ loses to $@. | rockpaperscissors.py:16:11:16:14 | ROCK | rock | rockpaperscissors.py:16:11:16:14 | ROCK | rock | | rockpaperscissors.py:26:14:26:14 | y | rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:26:14:26:14 | paper | $@ loses to $@. | rockpaperscissors.py:24:9:24:12 | ROCK | rock | rockpaperscissors.py:26:14:26:14 | y | paper | diff --git a/python/ql/test/library-tests/taint/config/Simple.expected b/python/ql/test/library-tests/taint/config/Simple.expected index 108f0f12015..78a86d7a0c8 100644 --- a/python/ql/test/library-tests/taint/config/Simple.expected +++ b/python/ql/test/library-tests/taint/config/Simple.expected @@ -1,99 +1,3 @@ -edges -| carrier.py:17:9:17:31 | .attr = simple.test | carrier.py:18:10:18:10 | .attr = simple.test | -| carrier.py:17:25:17:30 | simple.test | carrier.py:17:9:17:31 | .attr = simple.test | -| carrier.py:18:10:18:10 | .attr = simple.test | carrier.py:18:10:18:15 | simple.test | -| carrier.py:21:9:21:28 | explicit.carrier | carrier.py:22:10:22:10 | explicit.carrier | -| carrier.py:22:10:22:10 | explicit.carrier | carrier.py:22:10:22:22 | simple.test | -| carrier.py:25:9:25:36 | .attr = simple.test | carrier.py:26:10:26:10 | .attr = simple.test | -| carrier.py:25:13:25:35 | .attr = simple.test | carrier.py:25:9:25:36 | .attr = simple.test | -| carrier.py:25:29:25:34 | simple.test | carrier.py:25:13:25:35 | .attr = simple.test | -| carrier.py:26:10:26:10 | .attr = simple.test | carrier.py:26:10:26:21 | simple.test | -| carrier.py:29:9:29:33 | explicit.carrier | carrier.py:30:10:30:10 | explicit.carrier | -| carrier.py:29:13:29:32 | explicit.carrier | carrier.py:29:9:29:33 | explicit.carrier | -| carrier.py:30:10:30:10 | explicit.carrier | carrier.py:30:10:30:22 | simple.test | -| carrier.py:33:9:33:45 | .attr = explicit.carrier | carrier.py:34:9:34:9 | .attr = explicit.carrier | -| carrier.py:33:25:33:44 | explicit.carrier | carrier.py:33:9:33:45 | .attr = explicit.carrier | -| carrier.py:34:9:34:9 | .attr = explicit.carrier | carrier.py:34:9:34:14 | explicit.carrier | -| carrier.py:34:9:34:14 | explicit.carrier | carrier.py:35:10:35:10 | explicit.carrier | -| carrier.py:35:10:35:10 | explicit.carrier | carrier.py:35:10:35:22 | simple.test | -| deep.py:20:5:20:14 | simple.test | deep.py:22:6:22:6 | simple.test | -| deep.py:20:8:20:13 | simple.test | deep.py:20:5:20:14 | simple.test | -| module.py:3:13:3:18 | simple.test | test.py:85:8:85:13 | .dangerous = simple.test | -| module.py:3:13:3:18 | simple.test | test.py:88:9:88:14 | .dangerous = simple.test | -| module.py:3:13:3:18 | simple.test | test.py:110:11:110:16 | .dangerous = simple.test | -| module.py:3:13:3:18 | simple.test | test.py:115:11:115:16 | .dangerous = simple.test | -| module.py:3:13:3:18 | simple.test | test.py:155:20:155:38 | simple.test | -| module.py:7:12:7:17 | simple.test | test.py:100:9:100:31 | simple.test | -| rockpaperscissors.py:24:9:24:12 | rock | rockpaperscissors.py:25:9:25:9 | rock | -| rockpaperscissors.py:25:9:25:9 | rock | rockpaperscissors.py:25:9:25:16 | scissors | -| rockpaperscissors.py:25:9:25:16 | scissors | rockpaperscissors.py:25:9:25:23 | paper | -| rockpaperscissors.py:25:9:25:23 | paper | rockpaperscissors.py:26:14:26:14 | paper | -| sanitizer.py:9:9:9:20 | SQL injection | sanitizer.py:13:19:13:19 | SQL injection | -| sanitizer.py:16:9:16:20 | Command injection | sanitizer.py:20:20:20:20 | Command injection | -| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:26:19:26:19 | SQL injection | -| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:28:19:28:19 | SQL injection | -| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:33:20:33:20 | Command injection | -| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:35:20:35:20 | Command injection | -| test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test | -| test.py:10:12:10:17 | simple.test | test.py:16:9:16:16 | simple.test | -| test.py:10:12:10:17 | simple.test | test.py:24:9:24:16 | simple.test | -| test.py:10:12:10:17 | simple.test | test.py:44:12:44:22 | simple.test | -| test.py:12:10:12:12 | simple.test | test.py:13:10:13:12 | simple.test | -| test.py:16:9:16:16 | simple.test | test.py:17:10:17:10 | simple.test | -| test.py:20:9:20:14 | simple.test | test.py:21:10:21:10 | simple.test | -| test.py:21:10:21:10 | simple.test | test.py:12:10:12:12 | simple.test | -| test.py:24:9:24:16 | simple.test | test.py:25:10:25:10 | simple.test | -| test.py:25:10:25:10 | simple.test | test.py:12:10:12:12 | simple.test | -| test.py:37:13:37:18 | simple.test | test.py:41:14:41:14 | simple.test | -| test.py:44:12:44:22 | simple.test | test.py:54:9:54:17 | simple.test | -| test.py:46:11:46:13 | simple.test | test.py:47:10:47:12 | simple.test | -| test.py:47:10:47:12 | simple.test | test.py:12:10:12:12 | simple.test | -| test.py:49:17:49:19 | simple.test | test.py:51:14:51:16 | simple.test | -| test.py:51:14:51:16 | simple.test | test.py:12:10:12:12 | simple.test | -| test.py:54:9:54:17 | simple.test | test.py:55:11:55:11 | simple.test | -| test.py:55:11:55:11 | simple.test | test.py:46:11:46:13 | simple.test | -| test.py:62:13:62:18 | simple.test | test.py:63:17:63:17 | simple.test | -| test.py:63:17:63:17 | simple.test | test.py:49:17:49:19 | simple.test | -| test.py:67:13:67:18 | simple.test | test.py:70:17:70:17 | simple.test | -| test.py:70:17:70:17 | simple.test | test.py:49:17:49:19 | simple.test | -| test.py:76:9:76:14 | simple.test | test.py:77:13:77:13 | simple.test | -| test.py:77:9:77:14 | simple.test | test.py:78:10:78:10 | simple.test | -| test.py:77:13:77:13 | simple.test | test.py:77:9:77:14 | simple.test | -| test.py:85:8:85:13 | .dangerous = simple.test | test.py:88:9:88:14 | .dangerous = simple.test | -| test.py:85:8:85:13 | .dangerous = simple.test | test.py:110:11:110:16 | .dangerous = simple.test | -| test.py:85:8:85:13 | .dangerous = simple.test | test.py:115:11:115:16 | .dangerous = simple.test | -| test.py:88:9:88:14 | .dangerous = simple.test | test.py:88:9:88:24 | simple.test | -| test.py:88:9:88:24 | simple.test | test.py:89:10:89:10 | simple.test | -| test.py:100:9:100:31 | simple.test | test.py:101:10:101:10 | simple.test | -| test.py:105:12:105:14 | .x = simple.test | test.py:106:10:106:12 | .x = simple.test | -| test.py:106:10:106:12 | .x = simple.test | test.py:106:10:106:14 | simple.test | -| test.py:110:11:110:16 | .dangerous = simple.test | test.py:110:11:110:26 | simple.test | -| test.py:110:11:110:26 | simple.test | test.py:111:10:111:10 | .x = simple.test | -| test.py:111:10:111:10 | .x = simple.test | test.py:111:10:111:12 | simple.test | -| test.py:115:11:115:16 | .dangerous = simple.test | test.py:115:11:115:26 | simple.test | -| test.py:115:11:115:26 | simple.test | test.py:116:13:116:13 | .x = simple.test | -| test.py:116:9:116:14 | .x = simple.test | test.py:117:12:117:12 | .x = simple.test | -| test.py:116:13:116:13 | .x = simple.test | test.py:116:9:116:14 | .x = simple.test | -| test.py:117:12:117:12 | .x = simple.test | test.py:105:12:105:14 | .x = simple.test | -| test.py:126:13:126:25 | simple.test | test.py:130:21:130:21 | simple.test | -| test.py:128:13:128:18 | simple.test | test.py:132:14:132:14 | simple.test | -| test.py:155:20:155:38 | simple.test | test.py:156:6:156:11 | simple.test | -| test.py:159:10:159:15 | simple.test | test.py:160:14:160:14 | simple.test | -| test.py:163:9:163:14 | simple.test | test.py:165:10:165:10 | simple.test | -| test.py:178:9:178:14 | simple.test | test.py:180:14:180:14 | simple.test | -| test.py:178:9:178:14 | simple.test | test.py:186:14:186:14 | simple.test | -| test.py:195:9:195:14 | simple.test | test.py:197:14:197:14 | simple.test | -| test.py:195:9:195:14 | simple.test | test.py:199:14:199:14 | simple.test | -| test.py:208:11:208:18 | sequence of simple.test | test.py:209:14:209:16 | sequence of simple.test | -| test.py:208:12:208:17 | simple.test | test.py:208:11:208:18 | sequence of simple.test | -| test.py:209:5:209:17 | simple.test | test.py:210:15:210:15 | simple.test | -| test.py:209:14:209:16 | sequence of simple.test | test.py:209:5:209:17 | simple.test | -| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | iterable.simple | -| test.py:210:15:210:15 | simple.test | test.py:213:14:213:32 | sequence of simple.test | -| test.py:213:5:213:33 | simple.test | test.py:214:14:214:14 | simple.test | -| test.py:213:14:213:32 | iterable.simple | test.py:213:5:213:33 | simple.test | -| test.py:213:14:213:32 | sequence of simple.test | test.py:213:5:213:33 | simple.test | -#select | carrier.py:18:10:18:15 | Attribute | carrier.py:17:25:17:30 | simple.test | carrier.py:18:10:18:15 | simple.test | $@ flows to $@. | carrier.py:17:25:17:30 | SOURCE | simple.test | carrier.py:18:10:18:15 | Attribute | simple.test | | carrier.py:26:10:26:21 | Attribute() | carrier.py:25:29:25:34 | simple.test | carrier.py:26:10:26:21 | simple.test | $@ flows to $@. | carrier.py:25:29:25:34 | SOURCE | simple.test | carrier.py:26:10:26:21 | Attribute() | simple.test | | deep.py:22:6:22:6 | x | deep.py:20:8:20:13 | simple.test | deep.py:22:6:22:6 | simple.test | $@ flows to $@. | deep.py:20:8:20:13 | SOURCE | simple.test | deep.py:22:6:22:6 | x | simple.test | diff --git a/python/ql/test/library-tests/taint/example/ExampleConfig.expected b/python/ql/test/library-tests/taint/example/ExampleConfig.expected index 5127ff1e794..ed1bd0fe0ec 100644 --- a/python/ql/test/library-tests/taint/example/ExampleConfig.expected +++ b/python/ql/test/library-tests/taint/example/ExampleConfig.expected @@ -1,29 +1,3 @@ -edges -| example.py:17:14:17:21 | Dilbert | example.py:18:13:18:18 | Dilbert | -| example.py:17:14:17:21 | Wally | example.py:18:13:18:18 | Wally | -| example.py:22:14:22:21 | Dilbert | example.py:23:20:23:25 | Dilbert | -| example.py:23:14:23:26 | Dilbert | example.py:24:13:24:18 | Dilbert | -| example.py:23:20:23:25 | Dilbert | example.py:23:14:23:26 | Dilbert | -| example.py:28:14:28:21 | Dilbert | example.py:29:13:29:18 | Dilbert | -| example.py:28:14:28:21 | Wally | example.py:29:13:29:18 | Wally | -| example.py:33:14:33:21 | Dilbert | example.py:34:24:34:29 | Dilbert | -| example.py:34:12:34:30 | .worker = Dilbert | example.py:37:20:37:23 | .worker = Dilbert | -| example.py:34:24:34:29 | Dilbert | example.py:34:12:34:30 | .worker = Dilbert | -| example.py:37:14:37:31 | Dilbert | example.py:39:13:39:18 | Dilbert | -| example.py:37:20:37:23 | .worker = Dilbert | example.py:37:20:37:30 | Dilbert | -| example.py:37:20:37:30 | Dilbert | example.py:37:14:37:31 | Dilbert | -| example.py:57:14:57:21 | Dilbert | example.py:58:22:58:27 | Dilbert | -| example.py:57:14:57:21 | Wally | example.py:58:22:58:27 | Wally | -| example.py:58:14:58:28 | Dilbert | example.py:60:13:60:18 | Dilbert | -| example.py:58:14:58:28 | Wally | example.py:60:13:60:18 | Wally | -| example.py:58:22:58:27 | Dilbert | example.py:58:14:58:28 | Dilbert | -| example.py:58:22:58:27 | Wally | example.py:58:14:58:28 | Wally | -| example.py:64:14:64:21 | Dilbert | example.py:65:20:65:25 | Dilbert | -| example.py:65:14:65:26 | Dilbert | example.py:66:22:66:27 | Dilbert | -| example.py:65:20:65:25 | Dilbert | example.py:65:14:65:26 | Dilbert | -| example.py:66:14:66:28 | Dilbert | example.py:68:13:68:18 | Dilbert | -| example.py:66:22:66:27 | Dilbert | example.py:66:14:66:28 | Dilbert | -#select | example.py:18:13:18:18 | worker | example.py:17:14:17:21 | Dilbert | example.py:18:13:18:18 | Dilbert | $@ goes to a $@. | example.py:17:14:17:21 | ENGINEER | Dilbert | example.py:18:13:18:18 | worker | meeting | | example.py:18:13:18:18 | worker | example.py:17:14:17:21 | Wally | example.py:18:13:18:18 | Wally | $@ goes to a $@. | example.py:17:14:17:21 | ENGINEER | Wally | example.py:18:13:18:18 | worker | meeting | | example.py:24:13:24:18 | worker | example.py:22:14:22:21 | Dilbert | example.py:24:13:24:18 | Dilbert | $@ goes to a $@. | example.py:22:14:22:21 | ENGINEER | Dilbert | example.py:24:13:24:18 | worker | meeting | From df61c4dd62856ab064574fba444652142d2ae295 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 12 Jun 2023 22:09:47 +0200 Subject: [PATCH 542/739] reintroduce the experiemental queries that use deprecated features --- .../ql/lib/semmle/python/security/Paths.qll | 16 + .../semmle/python/security/strings/Basic.qll | 124 +++++++ .../semmle/python/security/strings/Common.qll | 14 + .../python/security/strings/External.qll | 318 ++++++++++++++++++ .../python/security/strings/Untrusted.qll | 10 + python/ql/lib/semmle/python/web/Http.qll | 119 +++++++ .../lib/semmle/python/web/HttpConstants.qll | 7 + .../ql/lib/semmle/python/web/HttpRequest.qll | 10 + .../lib/semmle/python/web/bottle/General.qll | 46 +++ .../lib/semmle/python/web/bottle/Request.qll | 80 +++++ .../semmle/python/web/cherrypy/General.qll | 44 +++ .../semmle/python/web/cherrypy/Request.qll | 41 +++ .../lib/semmle/python/web/django/General.qll | 136 ++++++++ .../lib/semmle/python/web/django/Request.qll | 78 +++++ .../lib/semmle/python/web/falcon/General.qll | 46 +++ .../lib/semmle/python/web/falcon/Request.qll | 37 ++ .../lib/semmle/python/web/flask/General.qll | 104 ++++++ .../lib/semmle/python/web/flask/Request.qll | 80 +++++ .../lib/semmle/python/web/flask/Response.qll | 55 +++ .../lib/semmle/python/web/pyramid/Request.qll | 25 ++ .../ql/lib/semmle/python/web/pyramid/View.qll | 9 + .../lib/semmle/python/web/stdlib/Request.qll | 126 +++++++ .../lib/semmle/python/web/tornado/Request.qll | 69 ++++ .../lib/semmle/python/web/tornado/Tornado.qll | 50 +++ .../semmle/python/web/turbogears/Request.qll | 26 ++ .../python/web/turbogears/TurboGears.qll | 37 ++ .../lib/semmle/python/web/twisted/Request.qll | 30 ++ .../lib/semmle/python/web/twisted/Twisted.qll | 52 +++ .../lib/semmle/python/web/webob/Request.qll | 38 +++ .../Security/CWE-074/TemplateInjection.qhelp | 24 ++ .../Security/CWE-074/TemplateInjection.ql | 35 ++ .../experimental/Security/CWE-091/Xslt.qhelp | 18 + .../src/experimental/Security/CWE-091/Xslt.ql | 36 ++ .../src/experimental/Security/CWE-091/xslt.py | 14 + .../semmle/python/security/injection/XSLT.qll | 42 +++ .../semmle/python/templates/Airspeed.qll | 27 ++ .../semmle/python/templates/Bottle.qll | 48 +++ .../semmle/python/templates/Chameleon.qll | 29 ++ .../semmle/python/templates/Cheetah.qll | 39 +++ .../semmle/python/templates/Chevron.qll | 36 ++ .../python/templates/DjangoTemplate.qll | 35 ++ .../semmle/python/templates/FlaskTemplate.qll | 28 ++ .../semmle/python/templates/Genshi.qll | 53 +++ .../semmle/python/templates/Jinja.qll | 49 +++ .../semmle/python/templates/Mako.qll | 27 ++ .../semmle/python/templates/SSTISink.qll | 7 + .../semmle/python/templates/Ssti.qll | 13 + .../semmle/python/templates/TRender.qll | 27 ++ .../CWE-074/TemplateInjection.expected | 60 ++++ .../Security/CWE-074/TemplateInjection.qlref | 1 + .../Security/CWE-091/Xslt.expected | 47 +++ .../query-tests/Security/CWE-091/Xslt.qlref | 1 + .../Security/CWE-091/XsltSinks.expected | 1 + .../query-tests/Security/CWE-091/xslt.py | 14 + 54 files changed, 2538 insertions(+) create mode 100644 python/ql/lib/semmle/python/security/Paths.qll create mode 100644 python/ql/lib/semmle/python/security/strings/Basic.qll create mode 100644 python/ql/lib/semmle/python/security/strings/Common.qll create mode 100644 python/ql/lib/semmle/python/security/strings/External.qll create mode 100644 python/ql/lib/semmle/python/security/strings/Untrusted.qll create mode 100644 python/ql/lib/semmle/python/web/Http.qll create mode 100644 python/ql/lib/semmle/python/web/HttpConstants.qll create mode 100644 python/ql/lib/semmle/python/web/HttpRequest.qll create mode 100644 python/ql/lib/semmle/python/web/bottle/General.qll create mode 100644 python/ql/lib/semmle/python/web/bottle/Request.qll create mode 100644 python/ql/lib/semmle/python/web/cherrypy/General.qll create mode 100644 python/ql/lib/semmle/python/web/cherrypy/Request.qll create mode 100644 python/ql/lib/semmle/python/web/django/General.qll create mode 100644 python/ql/lib/semmle/python/web/django/Request.qll create mode 100644 python/ql/lib/semmle/python/web/falcon/General.qll create mode 100644 python/ql/lib/semmle/python/web/falcon/Request.qll create mode 100644 python/ql/lib/semmle/python/web/flask/General.qll create mode 100644 python/ql/lib/semmle/python/web/flask/Request.qll create mode 100644 python/ql/lib/semmle/python/web/flask/Response.qll create mode 100644 python/ql/lib/semmle/python/web/pyramid/Request.qll create mode 100644 python/ql/lib/semmle/python/web/pyramid/View.qll create mode 100644 python/ql/lib/semmle/python/web/stdlib/Request.qll create mode 100644 python/ql/lib/semmle/python/web/tornado/Request.qll create mode 100644 python/ql/lib/semmle/python/web/tornado/Tornado.qll create mode 100644 python/ql/lib/semmle/python/web/turbogears/Request.qll create mode 100644 python/ql/lib/semmle/python/web/turbogears/TurboGears.qll create mode 100644 python/ql/lib/semmle/python/web/twisted/Request.qll create mode 100644 python/ql/lib/semmle/python/web/twisted/Twisted.qll create mode 100644 python/ql/lib/semmle/python/web/webob/Request.qll create mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp create mode 100644 python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql create mode 100644 python/ql/src/experimental/Security/CWE-091/Xslt.qhelp create mode 100644 python/ql/src/experimental/Security/CWE-091/Xslt.ql create mode 100644 python/ql/src/experimental/Security/CWE-091/xslt.py create mode 100644 python/ql/src/experimental/semmle/python/templates/Airspeed.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/Bottle.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/Chameleon.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/Cheetah.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/Chevron.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/DjangoTemplate.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/FlaskTemplate.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/Genshi.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/Jinja.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/Mako.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/SSTISink.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/Ssti.qll create mode 100644 python/ql/src/experimental/semmle/python/templates/TRender.qll create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.expected create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.qlref create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.expected create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.qlref create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-091/xslt.py diff --git a/python/ql/lib/semmle/python/security/Paths.qll b/python/ql/lib/semmle/python/security/Paths.qll new file mode 100644 index 00000000000..9288a1eff61 --- /dev/null +++ b/python/ql/lib/semmle/python/security/Paths.qll @@ -0,0 +1,16 @@ +import semmle.python.dataflow.Implementation + +deprecated module TaintTrackingPaths { + predicate edge(TaintTrackingNode src, TaintTrackingNode dest, string label) { + exists(TaintTrackingNode source, TaintTrackingNode sink | + source.getConfiguration().hasFlowPath(source, sink) and + source.getASuccessor*() = src and + src.getASuccessor(label) = dest and + dest.getASuccessor*() = sink + ) + } +} + +deprecated query predicate edges(TaintTrackingNode fromnode, TaintTrackingNode tonode) { + TaintTrackingPaths::edge(fromnode, tonode, _) +} diff --git a/python/ql/lib/semmle/python/security/strings/Basic.qll b/python/ql/lib/semmle/python/security/strings/Basic.qll new file mode 100644 index 00000000000..6bbae862c32 --- /dev/null +++ b/python/ql/lib/semmle/python/security/strings/Basic.qll @@ -0,0 +1,124 @@ +import python +private import Common +import semmle.python.dataflow.TaintTracking + +/** An extensible kind of taint representing any kind of string. */ +abstract deprecated class StringKind extends TaintKind { + bindingset[this] + StringKind() { this = this } + + override TaintKind getTaintOfMethodResult(string name) { + name in [ + "capitalize", "casefold", "center", "expandtabs", "format", "format_map", "ljust", "lstrip", + "lower", "replace", "rjust", "rstrip", "strip", "swapcase", "title", "upper", "zfill", + /* encode/decode is technically not correct, but close enough */ + "encode", "decode" + ] and + result = this + or + name in ["partition", "rpartition", "rsplit", "split", "splitlines"] and + result.(SequenceKind).getItem() = this + } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + result = this and + ( + slice(fromnode, tonode) or + tonode.(BinaryExprNode).getAnOperand() = fromnode or + os_path_join(fromnode, tonode) or + str_format(fromnode, tonode) or + encode_decode(fromnode, tonode) or + to_str(fromnode, tonode) or + f_string(fromnode, tonode) + ) + or + result = this and copy_call(fromnode, tonode) + } + + override ClassValue getType() { + result = Value::named("bytes") or + result = Value::named("str") or + result = Value::named("unicode") + } +} + +deprecated private class StringEqualitySanitizer extends Sanitizer { + StringEqualitySanitizer() { this = "string equality sanitizer" } + + /* The test `if untrusted == "KNOWN_VALUE":` sanitizes `untrusted` on its `true` edge. */ + override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { + taint instanceof StringKind and + exists(ControlFlowNode const, Cmpop op | const.getNode() instanceof StrConst | + ( + test.getTest().(CompareNode).operands(const, op, _) + or + test.getTest().(CompareNode).operands(_, op, const) + ) and + ( + op instanceof Eq and test.getSense() = true + or + op instanceof NotEq and test.getSense() = false + ) + ) + } +} + +/** tonode = ....format(fromnode) */ +deprecated private predicate str_format(ControlFlowNode fromnode, CallNode tonode) { + tonode.getFunction().(AttrNode).getName() = "format" and + tonode.getAnArg() = fromnode +} + +/** tonode = codec.[en|de]code(fromnode) */ +deprecated private predicate encode_decode(ControlFlowNode fromnode, CallNode tonode) { + exists(FunctionObject func, string name | + not func.getFunction().isMethod() and + func.getACall() = tonode and + tonode.getAnArg() = fromnode and + func.getName() = name + | + name = "encode" or + name = "decode" or + name = "decodestring" + ) +} + +/** tonode = str(fromnode) */ +deprecated private predicate to_str(ControlFlowNode fromnode, CallNode tonode) { + tonode.getAnArg() = fromnode and + ( + tonode = ClassValue::bytes().getACall() + or + tonode = ClassValue::unicode().getACall() + ) +} + +/** tonode = fromnode[:] */ +deprecated private predicate slice(ControlFlowNode fromnode, SubscriptNode tonode) { + exists(Slice all | + all = tonode.getIndex().getNode() and + not exists(all.getStart()) and + not exists(all.getStop()) and + tonode.getObject() = fromnode + ) +} + +/** tonode = os.path.join(..., fromnode, ...) */ +deprecated private predicate os_path_join(ControlFlowNode fromnode, CallNode tonode) { + tonode = Value::named("os.path.join").getACall() and + tonode.getAnArg() = fromnode +} + +/** tonode = f"... {fromnode} ..." */ +deprecated private predicate f_string(ControlFlowNode fromnode, ControlFlowNode tonode) { + tonode.getNode().(Fstring).getAValue() = fromnode.getNode() +} + +/** + * A kind of "taint", representing a dictionary mapping str->"taint" + * + * DEPRECATED: Use `ExternalStringDictKind` instead. + */ +deprecated class StringDictKind extends DictKind { + StringDictKind() { this.getValue() instanceof StringKind } +} diff --git a/python/ql/lib/semmle/python/security/strings/Common.qll b/python/ql/lib/semmle/python/security/strings/Common.qll new file mode 100644 index 00000000000..cb19fdd5461 --- /dev/null +++ b/python/ql/lib/semmle/python/security/strings/Common.qll @@ -0,0 +1,14 @@ +import python + +/** A call that returns a copy (or similar) of the argument */ +deprecated predicate copy_call(ControlFlowNode fromnode, CallNode tonode) { + tonode.getFunction().(AttrNode).getObject("copy") = fromnode + or + exists(ModuleValue copy, string name | name = "copy" or name = "deepcopy" | + copy.attr(name).(FunctionValue).getACall() = tonode and + tonode.getArg(0) = fromnode + ) + or + tonode.getFunction().pointsTo(Value::named("reversed")) and + tonode.getArg(0) = fromnode +} diff --git a/python/ql/lib/semmle/python/security/strings/External.qll b/python/ql/lib/semmle/python/security/strings/External.qll new file mode 100644 index 00000000000..a5116e42e4e --- /dev/null +++ b/python/ql/lib/semmle/python/security/strings/External.qll @@ -0,0 +1,318 @@ +import python +import Basic +private import Common + +/** + * An extensible kind of taint representing an externally controlled string. + */ +abstract deprecated class ExternalStringKind extends StringKind { + bindingset[this] + ExternalStringKind() { this = this } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + result = StringKind.super.getTaintForFlowStep(fromnode, tonode) + or + tonode.(SequenceNode).getElement(_) = fromnode and + result.(ExternalStringSequenceKind).getItem() = this + or + json_load(fromnode, tonode) and result.(ExternalJsonKind).getValue() = this + or + tonode.(DictNode).getAValue() = fromnode and result.(ExternalStringDictKind).getValue() = this + or + urlsplit(fromnode, tonode) and result.(ExternalUrlSplitResult).getItem() = this + or + urlparse(fromnode, tonode) and result.(ExternalUrlParseResult).getItem() = this + or + parse_qs(fromnode, tonode) and result.(ExternalStringDictKind).getValue() = this + or + parse_qsl(fromnode, tonode) and result.(SequenceKind).getItem().(SequenceKind).getItem() = this + } +} + +/** A kind of "taint", representing a sequence, with a "taint" member */ +deprecated class ExternalStringSequenceKind extends SequenceKind { + ExternalStringSequenceKind() { this.getItem() instanceof ExternalStringKind } +} + +/** + * An hierarchical dictionary or list where the entire structure is externally controlled + * This is typically a parsed JSON object. + */ +deprecated class ExternalJsonKind extends TaintKind { + ExternalJsonKind() { this = "json[" + any(ExternalStringKind key) + "]" } + + /** Gets the taint kind for item in this sequence */ + TaintKind getValue() { + this = "json[" + result + "]" + or + result = this + } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + this.taints(fromnode) and + json_subscript_taint(tonode, fromnode, this, result) + or + result = this and copy_call(fromnode, tonode) + } + + override TaintKind getTaintOfMethodResult(string name) { + name = "get" and result = this.getValue() + } +} + +/** A kind of "taint", representing a dictionary mapping keys to tainted strings. */ +deprecated class ExternalStringDictKind extends DictKind { + ExternalStringDictKind() { this.getValue() instanceof ExternalStringKind } +} + +/** + * A kind of "taint", representing a dictionary mapping keys to sequences of + * tainted strings. + */ +deprecated class ExternalStringSequenceDictKind extends DictKind { + ExternalStringSequenceDictKind() { this.getValue() instanceof ExternalStringSequenceKind } +} + +/** TaintKind for the result of `urlsplit(tainted_string)` */ +deprecated class ExternalUrlSplitResult extends ExternalStringSequenceKind { + // https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlsplit + override TaintKind getTaintOfAttribute(string name) { + result = super.getTaintOfAttribute(name) + or + name in [ + // namedtuple field names + "scheme", "netloc", "path", "query", "fragment", + // class methods + "password", "username", "hostname", + ] and + result instanceof ExternalStringKind + } + + override TaintKind getTaintOfMethodResult(string name) { + result = super.getTaintOfMethodResult(name) + or + name = "geturl" and + result instanceof ExternalStringKind + } +} + +/** TaintKind for the result of `urlparse(tainted_string)` */ +deprecated class ExternalUrlParseResult extends ExternalStringSequenceKind { + // https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlparse + override TaintKind getTaintOfAttribute(string name) { + result = super.getTaintOfAttribute(name) + or + name in [ + // namedtuple field names + "scheme", "netloc", "path", "params", "query", "fragment", + // class methods + "username", "password", "hostname", + ] and + result instanceof ExternalStringKind + } + + override TaintKind getTaintOfMethodResult(string name) { + result = super.getTaintOfMethodResult(name) + or + name = "geturl" and + result instanceof ExternalStringKind + } +} + +/* Helper for getTaintForStep() */ +pragma[noinline] +deprecated private predicate json_subscript_taint( + SubscriptNode sub, ControlFlowNode obj, ExternalJsonKind seq, TaintKind key +) { + sub.isLoad() and + sub.getObject() = obj and + key = seq.getValue() +} + +deprecated private predicate json_load(ControlFlowNode fromnode, CallNode tonode) { + tonode = Value::named("json.loads").getACall() and + tonode.getArg(0) = fromnode +} + +deprecated private predicate urlsplit(ControlFlowNode fromnode, CallNode tonode) { + // This could be implemented as `exists(FunctionValue` without the explicit six part, + // but then our tests will need to import +100 modules, so for now this slightly + // altered version gets to live on. + exists(Value urlsplit | + ( + urlsplit = Value::named("six.moves.urllib.parse.urlsplit") + or + // Python 2 + urlsplit = Value::named("urlparse.urlsplit") + or + // Python 3 + urlsplit = Value::named("urllib.parse.urlsplit") + ) and + tonode = urlsplit.getACall() and + tonode.getArg(0) = fromnode + ) +} + +deprecated private predicate urlparse(ControlFlowNode fromnode, CallNode tonode) { + // This could be implemented as `exists(FunctionValue` without the explicit six part, + // but then our tests will need to import +100 modules, so for now this slightly + // altered version gets to live on. + exists(Value urlparse | + ( + urlparse = Value::named("six.moves.urllib.parse.urlparse") + or + // Python 2 + urlparse = Value::named("urlparse.urlparse") + or + // Python 3 + urlparse = Value::named("urllib.parse.urlparse") + ) and + tonode = urlparse.getACall() and + tonode.getArg(0) = fromnode + ) +} + +deprecated private predicate parse_qs(ControlFlowNode fromnode, CallNode tonode) { + // This could be implemented as `exists(FunctionValue` without the explicit six part, + // but then our tests will need to import +100 modules, so for now this slightly + // altered version gets to live on. + exists(Value parse_qs | + ( + parse_qs = Value::named("six.moves.urllib.parse.parse_qs") + or + // Python 2 + parse_qs = Value::named("urlparse.parse_qs") + or + // Python 2 deprecated version of `urlparse.parse_qs` + parse_qs = Value::named("cgi.parse_qs") + or + // Python 3 + parse_qs = Value::named("urllib.parse.parse_qs") + ) and + tonode = parse_qs.getACall() and + ( + tonode.getArg(0) = fromnode + or + tonode.getArgByName("qs") = fromnode + ) + ) +} + +deprecated private predicate parse_qsl(ControlFlowNode fromnode, CallNode tonode) { + // This could be implemented as `exists(FunctionValue` without the explicit six part, + // but then our tests will need to import +100 modules, so for now this slightly + // altered version gets to live on. + exists(Value parse_qsl | + ( + parse_qsl = Value::named("six.moves.urllib.parse.parse_qsl") + or + // Python 2 + parse_qsl = Value::named("urlparse.parse_qsl") + or + // Python 2 deprecated version of `urlparse.parse_qsl` + parse_qsl = Value::named("cgi.parse_qsl") + or + // Python 3 + parse_qsl = Value::named("urllib.parse.parse_qsl") + ) and + tonode = parse_qsl.getACall() and + ( + tonode.getArg(0) = fromnode + or + tonode.getArgByName("qs") = fromnode + ) + ) +} + +/** A kind of "taint", representing an open file-like object from an external source. */ +deprecated class ExternalFileObject extends TaintKind { + ExternalStringKind valueKind; + + ExternalFileObject() { this = "file[" + valueKind + "]" } + + /** Gets the taint kind for the contents of this file */ + TaintKind getValue() { result = valueKind } + + override TaintKind getTaintOfMethodResult(string name) { + name in ["read", "readline"] and result = this.getValue() + or + name = "readlines" and result.(SequenceKind).getItem() = this.getValue() + } + + override TaintKind getTaintForIteration() { result = this.getValue() } +} + +/** + * Temporary sanitizer for the tainted result from `urlsplit` and `urlparse`. Can be used to reduce FPs until + * we have better support for namedtuples. + * + * Will clear **all** taint on a test of the kind. That is, on the true edge of any matching test, + * all fields/indexes will be cleared of taint. + * + * Handles: + * - `if splitres.netloc == "KNOWN_VALUE"` + * - `if splitres[0] == "KNOWN_VALUE"` + */ +deprecated class UrlsplitUrlparseTempSanitizer extends Sanitizer { + // TODO: remove this once we have better support for named tuples + UrlsplitUrlparseTempSanitizer() { this = "UrlsplitUrlparseTempSanitizer" } + + override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { + ( + taint instanceof ExternalUrlSplitResult + or + taint instanceof ExternalUrlParseResult + ) and + exists(ControlFlowNode full_use | + full_use.(SubscriptNode).getObject() = test.getInput().getAUse() + or + full_use.(AttrNode).getObject() = test.getInput().getAUse() + | + this.clears_taint(full_use, test.getTest(), test.getSense()) + ) + } + + private predicate clears_taint(ControlFlowNode tainted, ControlFlowNode test, boolean sense) { + this.test_equality_with_const(test, tainted, sense) + or + this.test_in_const_seq(test, tainted, sense) + or + test.(UnaryExprNode).getNode().getOp() instanceof Not and + exists(ControlFlowNode nested_test | + nested_test = test.(UnaryExprNode).getOperand() and + this.clears_taint(tainted, nested_test, sense.booleanNot()) + ) + } + + /** holds for `== "KNOWN_VALUE"` on `true` edge, and `!= "KNOWN_VALUE"` on `false` edge */ + private predicate test_equality_with_const(CompareNode cmp, ControlFlowNode tainted, boolean sense) { + exists(ControlFlowNode const, Cmpop op | const.getNode() instanceof StrConst | + ( + cmp.operands(const, op, tainted) + or + cmp.operands(tainted, op, const) + ) and + ( + op instanceof Eq and sense = true + or + op instanceof NotEq and sense = false + ) + ) + } + + /** holds for `in ["KNOWN_VALUE", ...]` on `true` edge, and `not in ["KNOWN_VALUE", ...]` on `false` edge */ + private predicate test_in_const_seq(CompareNode cmp, ControlFlowNode tainted, boolean sense) { + exists(SequenceNode const_seq, Cmpop op | + forall(ControlFlowNode elem | elem = const_seq.getAnElement() | + elem.getNode() instanceof StrConst + ) + | + cmp.operands(tainted, op, const_seq) and + ( + op instanceof In and sense = true + or + op instanceof NotIn and sense = false + ) + ) + } +} diff --git a/python/ql/lib/semmle/python/security/strings/Untrusted.qll b/python/ql/lib/semmle/python/security/strings/Untrusted.qll new file mode 100644 index 00000000000..2916b723a8f --- /dev/null +++ b/python/ql/lib/semmle/python/security/strings/Untrusted.qll @@ -0,0 +1,10 @@ +import python +import External + +/** + * A kind of taint representing an externally controlled string. + * This class is a simple sub-class of `ExternalStringKind`. + */ +deprecated class UntrustedStringKind extends ExternalStringKind { + UntrustedStringKind() { this = "externally controlled string" } +} diff --git a/python/ql/lib/semmle/python/web/Http.qll b/python/ql/lib/semmle/python/web/Http.qll new file mode 100644 index 00000000000..85100e6524e --- /dev/null +++ b/python/ql/lib/semmle/python/web/Http.qll @@ -0,0 +1,119 @@ +import python +import semmle.python.dataflow.Implementation +import semmle.python.security.strings.External +import HttpConstants + +/** Generic taint source from a http request */ +abstract deprecated class HttpRequestTaintSource extends TaintSource { } + +/** + * Taint kind representing the WSGI environment. + * As specified in PEP 3333. https://www.python.org/dev/peps/pep-3333/#environ-variables + */ +deprecated class WsgiEnvironment extends TaintKind { + WsgiEnvironment() { this = "wsgi.environment" } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + result = this and Implementation::copyCall(fromnode, tonode) + or + result = this and + tonode.(CallNode).getFunction().pointsTo(ClassValue::dict()) and + tonode.(CallNode).getArg(0) = fromnode + or + exists(Value key, string text | + tonode.(CallNode).getFunction().(AttrNode).getObject("get") = fromnode and + tonode.(CallNode).getArg(0).pointsTo(key) + or + tonode.(SubscriptNode).getObject() = fromnode and + tonode.isLoad() and + tonode.(SubscriptNode).getIndex().pointsTo(key) + | + key = Value::forString(text) and + result instanceof ExternalStringKind and + ( + text = "QUERY_STRING" or + text = "PATH_INFO" or + text.matches("HTTP\\_%") + ) + ) + } +} + +/** + * A standard morsel object from a HTTP request, a value in a cookie, + * typically an instance of `http.cookies.Morsel` + */ +deprecated class UntrustedMorsel extends TaintKind { + UntrustedMorsel() { this = "http.Morsel" } + + override TaintKind getTaintOfAttribute(string name) { + result instanceof ExternalStringKind and + name = "value" + } +} + +/** A standard cookie object from a HTTP request, typically an instance of `http.cookies.SimpleCookie` */ +deprecated class UntrustedCookie extends TaintKind { + UntrustedCookie() { this = "http.Cookie" } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + tonode.(SubscriptNode).getObject() = fromnode and + result instanceof UntrustedMorsel + } +} + +abstract deprecated class CookieOperation extends @py_flow_node { + /** Gets a textual representation of this element. */ + abstract string toString(); + + abstract ControlFlowNode getKey(); + + abstract ControlFlowNode getValue(); +} + +abstract deprecated class CookieGet extends CookieOperation { } + +abstract deprecated class CookieSet extends CookieOperation { } + +/** Generic taint sink in a http response */ +abstract deprecated class HttpResponseTaintSink extends TaintSink { + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} + +abstract deprecated class HttpRedirectTaintSink extends TaintSink { + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} + +deprecated module Client { + // TODO: user-input in other than URL: + // - `data`, `json` for `requests.post` + // - `body` for `HTTPConnection.request` + // - headers? + // TODO: Add more library support + // - urllib3 https://github.com/urllib3/urllib3 + // - httpx https://github.com/encode/httpx + /** + * An outgoing http request + * + * For example: + * conn = HTTPConnection('example.com') + * conn.request('GET', '/path') + */ + abstract class HttpRequest extends ControlFlowNode { + /** + * Get any ControlFlowNode that is used to construct the final URL. + * + * In the HTTPConnection example, there is a result for both `'example.com'` and for `'/path'`. + */ + abstract ControlFlowNode getAUrlPart(); + + abstract string getMethodUpper(); + } + + /** Taint sink for the URL-part of an outgoing http request */ + class HttpRequestUrlTaintSink extends TaintSink { + HttpRequestUrlTaintSink() { this = any(HttpRequest r).getAUrlPart() } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } + } +} diff --git a/python/ql/lib/semmle/python/web/HttpConstants.qll b/python/ql/lib/semmle/python/web/HttpConstants.qll new file mode 100644 index 00000000000..e5cebb57729 --- /dev/null +++ b/python/ql/lib/semmle/python/web/HttpConstants.qll @@ -0,0 +1,7 @@ +/** Gets an HTTP verb, in upper case */ +deprecated string httpVerb() { + result in ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"] +} + +/** Gets an HTTP verb, in lower case */ +deprecated string httpVerbLower() { result = httpVerb().toLowerCase() } diff --git a/python/ql/lib/semmle/python/web/HttpRequest.qll b/python/ql/lib/semmle/python/web/HttpRequest.qll new file mode 100644 index 00000000000..88dd36049b4 --- /dev/null +++ b/python/ql/lib/semmle/python/web/HttpRequest.qll @@ -0,0 +1,10 @@ +import semmle.python.web.django.Request +import semmle.python.web.flask.Request +import semmle.python.web.tornado.Request +import semmle.python.web.pyramid.Request +import semmle.python.web.twisted.Request +import semmle.python.web.bottle.Request +import semmle.python.web.turbogears.Request +import semmle.python.web.falcon.Request +import semmle.python.web.cherrypy.Request +import semmle.python.web.stdlib.Request diff --git a/python/ql/lib/semmle/python/web/bottle/General.qll b/python/ql/lib/semmle/python/web/bottle/General.qll new file mode 100644 index 00000000000..cbb42c97305 --- /dev/null +++ b/python/ql/lib/semmle/python/web/bottle/General.qll @@ -0,0 +1,46 @@ +import python +import semmle.python.web.Http +import semmle.python.types.Extensions + +/** Gets the bottle module */ +deprecated ModuleValue theBottleModule() { result = Module::named("bottle") } + +/** Gets the bottle.Bottle class */ +deprecated ClassValue theBottleClass() { result = theBottleModule().attr("Bottle") } + +/** + * Holds if `route` is routed to `func` + * by decorating `func` with `app.route(route)` or `route(route)` + */ +deprecated predicate bottle_route(CallNode route_call, ControlFlowNode route, Function func) { + exists(CallNode decorator_call, string name | + route_call.getFunction().(AttrNode).getObject(name).pointsTo().getClass() = theBottleClass() or + route_call.getFunction().pointsTo(theBottleModule().attr(name)) + | + (name = "route" or name = httpVerbLower()) and + decorator_call.getFunction() = route_call and + route_call.getArg(0) = route and + decorator_call.getArg(0).getNode().(FunctionExpr).getInnerScope() = func + ) +} + +deprecated class BottleRoute extends ControlFlowNode { + BottleRoute() { bottle_route(this, _, _) } + + string getUrl() { + exists(StrConst url | + bottle_route(this, url.getAFlowNode(), _) and + result = url.getText() + ) + } + + Function getFunction() { bottle_route(this, _, result) } + + Parameter getANamedArgument() { + exists(string name, Function func | + func = this.getFunction() and + func.getArgByName(name) = result and + this.getUrl().matches("%<" + name + ">%") + ) + } +} diff --git a/python/ql/lib/semmle/python/web/bottle/Request.qll b/python/ql/lib/semmle/python/web/bottle/Request.qll new file mode 100644 index 00000000000..3de4748b30e --- /dev/null +++ b/python/ql/lib/semmle/python/web/bottle/Request.qll @@ -0,0 +1,80 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.security.strings.External +import semmle.python.web.Http +import semmle.python.web.bottle.General + +deprecated private Value theBottleRequestObject() { result = theBottleModule().attr("request") } + +deprecated class BottleRequestKind extends TaintKind { + BottleRequestKind() { this = "bottle.request" } + + override TaintKind getTaintOfAttribute(string name) { + result instanceof BottleFormsDict and + (name = "cookies" or name = "query" or name = "form") + or + result instanceof ExternalStringKind and + (name = "query_string" or name = "url_args") + or + result.(DictKind).getValue() instanceof FileUpload and + name = "files" + } +} + +deprecated private class RequestSource extends HttpRequestTaintSource { + RequestSource() { this.(ControlFlowNode).pointsTo(theBottleRequestObject()) } + + override predicate isSourceOf(TaintKind kind) { kind instanceof BottleRequestKind } +} + +deprecated class BottleFormsDict extends TaintKind { + BottleFormsDict() { this = "bottle.FormsDict" } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + /* Cannot use `getTaintOfAttribute(name)` as it wouldn't bind `name` */ + exists(string name | + fromnode = tonode.(AttrNode).getObject(name) and + result instanceof ExternalStringKind + | + name != "get" and name != "getunicode" and name != "getall" + ) + } + + override TaintKind getTaintOfMethodResult(string name) { + (name = "get" or name = "getunicode") and + result instanceof ExternalStringKind + or + name = "getall" and result.(SequenceKind).getItem() instanceof ExternalStringKind + } +} + +deprecated class FileUpload extends TaintKind { + FileUpload() { this = "bottle.FileUpload" } + + override TaintKind getTaintOfAttribute(string name) { + name = "filename" and result instanceof ExternalStringKind + or + name = "raw_filename" and result instanceof ExternalStringKind + or + name = "file" and result instanceof UntrustedFile + } +} + +deprecated class UntrustedFile extends TaintKind { + UntrustedFile() { this = "Untrusted file" } +} + +// +// TO DO.. File uploads -- Should check about file uploads for other frameworks as well. +// Move UntrustedFile to shared location +// +/** A parameter to a bottle request handler function */ +deprecated class BottleRequestParameter extends HttpRequestTaintSource { + BottleRequestParameter() { + exists(BottleRoute route | route.getANamedArgument() = this.(ControlFlowNode).getNode()) + } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } + + override string toString() { result = "bottle handler function argument" } +} diff --git a/python/ql/lib/semmle/python/web/cherrypy/General.qll b/python/ql/lib/semmle/python/web/cherrypy/General.qll new file mode 100644 index 00000000000..40becc70a50 --- /dev/null +++ b/python/ql/lib/semmle/python/web/cherrypy/General.qll @@ -0,0 +1,44 @@ +import python +import semmle.python.web.Http + +deprecated module CherryPy { + FunctionValue expose() { result = Value::named("cherrypy.expose") } +} + +deprecated class CherryPyExposedFunction extends Function { + CherryPyExposedFunction() { + this.getADecorator().pointsTo(CherryPy::expose()) + or + this.getADecorator().(Call).getFunc().pointsTo(CherryPy::expose()) + } +} + +deprecated class CherryPyRoute extends CallNode { + CherryPyRoute() { + /* cherrypy.quickstart(root, script_name, config) */ + Value::named("cherrypy.quickstart").(FunctionValue).getACall() = this + or + /* cherrypy.tree.mount(root, script_name, config) */ + this.getFunction().(AttrNode).getObject("mount").pointsTo(Value::named("cherrypy.tree")) + } + + ClassValue getAppClass() { + this.getArg(0).pointsTo().getClass() = result + or + this.getArgByName("root").pointsTo().getClass() = result + } + + string getPath() { + exists(Value path | path = Value::forString(result) | + this.getArg(1).pointsTo(path) + or + this.getArgByName("script_name").pointsTo(path) + ) + } + + ClassValue getConfig() { + this.getArg(2).pointsTo().getClass() = result + or + this.getArgByName("config").pointsTo().getClass() = result + } +} diff --git a/python/ql/lib/semmle/python/web/cherrypy/Request.qll b/python/ql/lib/semmle/python/web/cherrypy/Request.qll new file mode 100644 index 00000000000..b3c096f8bdd --- /dev/null +++ b/python/ql/lib/semmle/python/web/cherrypy/Request.qll @@ -0,0 +1,41 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.security.strings.Basic +import semmle.python.web.Http +import semmle.python.web.cherrypy.General + +/** The cherrypy.request local-proxy object */ +deprecated class CherryPyRequest extends TaintKind { + CherryPyRequest() { this = "cherrypy.request" } + + override TaintKind getTaintOfAttribute(string name) { + name = "params" and result instanceof ExternalStringDictKind + or + name = "cookie" and result instanceof UntrustedCookie + } + + override TaintKind getTaintOfMethodResult(string name) { + name in ["getHeader", "getCookie", "getUser", "getPassword"] and + result instanceof ExternalStringKind + } +} + +deprecated class CherryPyExposedFunctionParameter extends HttpRequestTaintSource { + CherryPyExposedFunctionParameter() { + exists(Parameter p | + p = any(CherryPyExposedFunction f).getAnArg() and + not p.isSelf() and + p.asName().getAFlowNode() = this + ) + } + + override string toString() { result = "CherryPy handler function parameter" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } +} + +deprecated class CherryPyRequestSource extends HttpRequestTaintSource { + CherryPyRequestSource() { this.(ControlFlowNode).pointsTo(Value::named("cherrypy.request")) } + + override predicate isSourceOf(TaintKind kind) { kind instanceof CherryPyRequest } +} diff --git a/python/ql/lib/semmle/python/web/django/General.qll b/python/ql/lib/semmle/python/web/django/General.qll new file mode 100644 index 00000000000..1b179b35f9a --- /dev/null +++ b/python/ql/lib/semmle/python/web/django/General.qll @@ -0,0 +1,136 @@ +import python +import semmle.python.regex +import semmle.python.web.Http + +// TODO: Since django uses `path = partial(...)`, our analysis doesn't understand this is +// a FunctionValue, so we can't use `FunctionValue.getArgumentForCall` +// https://github.com/django/django/blob/master/django/urls/conf.py#L76 +abstract deprecated class DjangoRoute extends CallNode { + DjangoViewHandler getViewHandler() { + result = view_handler_from_view_arg(this.getArg(1)) + or + result = view_handler_from_view_arg(this.getArgByName("view")) + } + + abstract string getANamedArgument(); + + /** + * Get the number of positional arguments that will be passed to the view. + * Will only return a result if there are no named arguments. + */ + abstract int getNumPositionalArguments(); +} + +/** + * For function based views -- also see `DjangoClassBasedViewHandler` + * https://docs.djangoproject.com/en/1.11/topics/http/views/ + * https://docs.djangoproject.com/en/3.0/topics/http/views/ + */ +deprecated class DjangoViewHandler extends PythonFunctionValue { + /** Gets the index of the 'request' argument */ + int getRequestArgIndex() { result = 0 } +} + +/** + * Class based views + * https://docs.djangoproject.com/en/1.11/topics/class-based-views/ + * https://docs.djangoproject.com/en/3.0/topics/class-based-views/ + */ +deprecated private class DjangoViewClass extends ClassValue { + DjangoViewClass() { + Value::named("django.views.generic.View") = this.getASuperType() + or + Value::named("django.views.View") = this.getASuperType() + } +} + +deprecated class DjangoClassBasedViewHandler extends DjangoViewHandler { + DjangoClassBasedViewHandler() { exists(DjangoViewClass cls | cls.lookup(httpVerbLower()) = this) } + + override int getRequestArgIndex() { + // due to `self` being the first parameter + result = 1 + } +} + +/** + * Gets the function that will handle requests when `view_arg` is used as the view argument to a + * django route. That is, this methods handles Class-based Views and its `as_view()` function. + */ +deprecated private DjangoViewHandler view_handler_from_view_arg(ControlFlowNode view_arg) { + // Function-based view + result = view_arg.pointsTo() + or + // Class-based view + exists(ClassValue cls | + cls = view_arg.(CallNode).getFunction().(AttrNode).getObject("as_view").pointsTo() and + result = cls.lookup(httpVerbLower()) + ) +} + +// We need this "dummy" class, since otherwise the regex argument would not be considered +// a regex (RegexString is abstract) +deprecated class DjangoRouteRegex extends RegexString { + DjangoRouteRegex() { exists(DjangoRegexRoute route | route.getRouteArg() = this.getAFlowNode()) } +} + +deprecated class DjangoRegexRoute extends DjangoRoute { + ControlFlowNode route; + + DjangoRegexRoute() { + exists(FunctionValue route_maker | + // Django 1.x: https://docs.djangoproject.com/en/1.11/ref/urls/#django.conf.urls.url + Value::named("django.conf.urls.url") = route_maker and + route_maker.getArgumentForCall(this, 0) = route + ) + or + // Django 2.x and 3.x: https://docs.djangoproject.com/en/3.0/ref/urls/#re-path + this = Value::named("django.urls.re_path").getACall() and + ( + route = this.getArg(0) + or + route = this.getArgByName("route") + ) + } + + ControlFlowNode getRouteArg() { result = route } + + override string getANamedArgument() { + exists(DjangoRouteRegex regex | regex.getAFlowNode() = route | + result = regex.getGroupName(_, _) + ) + } + + override int getNumPositionalArguments() { + not exists(this.getANamedArgument()) and + exists(DjangoRouteRegex regex | regex.getAFlowNode() = route | + result = count(regex.getGroupNumber(_, _)) + ) + } +} + +deprecated class DjangoPathRoute extends DjangoRoute { + ControlFlowNode route; + + DjangoPathRoute() { + // Django 2.x and 3.x: https://docs.djangoproject.com/en/3.0/ref/urls/#path + this = Value::named("django.urls.path").getACall() and + ( + route = this.getArg(0) + or + route = this.getArgByName("route") + ) + } + + override string getANamedArgument() { + // regexp taken from django: + // https://github.com/django/django/blob/7d1bf29977bb368d7c28e7c6eb146db3b3009ae7/django/urls/resolvers.py#L199 + exists(StrConst route_str, string match | + route_str = route.getNode() and + match = route_str.getText().regexpFind("<(?:(?<converter>[^>:]+):)?(?<parameter>\\w+)>", _, _) and + result = match.regexpCapture("<(?:(?<converter>[^>:]+):)?(?<parameter>\\w+)>", 2) + ) + } + + override int getNumPositionalArguments() { none() } +} diff --git a/python/ql/lib/semmle/python/web/django/Request.qll b/python/ql/lib/semmle/python/web/django/Request.qll new file mode 100644 index 00000000000..7e7358595e5 --- /dev/null +++ b/python/ql/lib/semmle/python/web/django/Request.qll @@ -0,0 +1,78 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http +import semmle.python.web.django.General + +/** A django.request.HttpRequest object */ +deprecated class DjangoRequest extends TaintKind { + DjangoRequest() { this = "django.request.HttpRequest" } + + override TaintKind getTaintOfAttribute(string name) { + (name = "GET" or name = "POST") and + result instanceof DjangoQueryDict + } + + override TaintKind getTaintOfMethodResult(string name) { + (name = "body" or name = "path") and + result instanceof ExternalStringKind + } +} + +/* Helper for getTaintForStep() */ +pragma[noinline] +deprecated private predicate subscript_taint(SubscriptNode sub, ControlFlowNode obj, TaintKind kind) { + sub.getObject() = obj and + kind instanceof ExternalStringKind +} + +/** A django.request.QueryDict object */ +deprecated class DjangoQueryDict extends TaintKind { + DjangoQueryDict() { this = "django.http.request.QueryDict" } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + this.taints(fromnode) and + subscript_taint(tonode, fromnode, result) + } + + override TaintKind getTaintOfMethodResult(string name) { + name = "get" and result instanceof ExternalStringKind + } +} + +/** A Django request parameter */ +deprecated class DjangoRequestSource extends HttpRequestTaintSource { + DjangoRequestSource() { + exists(DjangoRoute route, DjangoViewHandler view, int request_arg_index | + route.getViewHandler() = view and + request_arg_index = view.getRequestArgIndex() and + this = view.getScope().getArg(request_arg_index).asName().getAFlowNode() + ) + } + + override string toString() { result = "Django request source" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoRequest } +} + +/** An argument specified in a url routing table */ +deprecated class DjangoRequestParameter extends HttpRequestTaintSource { + DjangoRequestParameter() { + exists(DjangoRoute route, Function f, DjangoViewHandler view, int request_arg_index | + route.getViewHandler() = view and + request_arg_index = view.getRequestArgIndex() and + f = view.getScope() + | + this.(ControlFlowNode).getNode() = f.getArgByName(route.getANamedArgument()) + or + exists(int i | i >= 0 | + i < route.getNumPositionalArguments() and + // +1 because first argument is always the request + this.(ControlFlowNode).getNode() = f.getArg(request_arg_index + 1 + i) + ) + ) + } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } + + override string toString() { result = "django.http.request.parameter" } +} diff --git a/python/ql/lib/semmle/python/web/falcon/General.qll b/python/ql/lib/semmle/python/web/falcon/General.qll new file mode 100644 index 00000000000..5f9cce57611 --- /dev/null +++ b/python/ql/lib/semmle/python/web/falcon/General.qll @@ -0,0 +1,46 @@ +import python +import semmle.python.web.Http + +/** Gets the falcon API class */ +deprecated ClassValue theFalconAPIClass() { result = Value::named("falcon.API") } + +/** Holds if `route` is routed to `resource` */ +deprecated private predicate api_route( + CallNode route_call, ControlFlowNode route, ClassValue resource +) { + route_call.getFunction().(AttrNode).getObject("add_route").pointsTo().getClass() = + theFalconAPIClass() and + route_call.getArg(0) = route and + route_call.getArg(1).pointsTo().getClass() = resource +} + +deprecated private predicate route(FalconRoute route, Function target, string funcname) { + route.getResourceClass().lookup("on_" + funcname).(FunctionValue).getScope() = target +} + +deprecated class FalconRoute extends ControlFlowNode { + FalconRoute() { api_route(this, _, _) } + + string getUrl() { + exists(StrConst url | + api_route(this, url.getAFlowNode(), _) and + result = url.getText() + ) + } + + ClassValue getResourceClass() { api_route(this, _, result) } + + FalconHandlerFunction getHandlerFunction(string method) { route(this, result, method) } +} + +deprecated class FalconHandlerFunction extends Function { + FalconHandlerFunction() { route(_, this, _) } + + private string methodName() { route(_, this, result) } + + string getMethod() { result = this.methodName().toUpperCase() } + + Parameter getRequest() { result = this.getArg(1) } + + Parameter getResponse() { result = this.getArg(2) } +} diff --git a/python/ql/lib/semmle/python/web/falcon/Request.qll b/python/ql/lib/semmle/python/web/falcon/Request.qll new file mode 100644 index 00000000000..ac4c92f3ad0 --- /dev/null +++ b/python/ql/lib/semmle/python/web/falcon/Request.qll @@ -0,0 +1,37 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http +import semmle.python.web.falcon.General + +/** https://falcon.readthedocs.io/en/stable/api/request_and_response.html */ +deprecated class FalconRequest extends TaintKind { + FalconRequest() { this = "falcon.request" } + + override TaintKind getTaintOfAttribute(string name) { + name = "env" and result instanceof WsgiEnvironment + or + result instanceof ExternalStringKind and + name in ["uri", "url", "forwarded_uri", "relative_uri", "query_string"] + or + result instanceof ExternalStringDictKind and + (name = "cookies" or name = "params") + or + name = "stream" and result instanceof ExternalFileObject + } + + override TaintKind getTaintOfMethodResult(string name) { + name = "get_param" and result instanceof ExternalStringKind + or + name = "get_param_as_json" and result instanceof ExternalJsonKind + or + name = "get_param_as_list" and result instanceof ExternalStringSequenceKind + } +} + +deprecated class FalconRequestParameter extends HttpRequestTaintSource { + FalconRequestParameter() { + exists(FalconHandlerFunction f | f.getRequest() = this.(ControlFlowNode).getNode()) + } + + override predicate isSourceOf(TaintKind k) { k instanceof FalconRequest } +} diff --git a/python/ql/lib/semmle/python/web/flask/General.qll b/python/ql/lib/semmle/python/web/flask/General.qll new file mode 100644 index 00000000000..cc4d992f9ff --- /dev/null +++ b/python/ql/lib/semmle/python/web/flask/General.qll @@ -0,0 +1,104 @@ +import python +import semmle.python.web.Http +import semmle.python.web.flask.Response + +/** Gets the flask app class */ +deprecated ClassValue theFlaskClass() { result = Value::named("flask.Flask") } + +/** Gets the flask MethodView class */ +deprecated ClassValue theFlaskMethodViewClass() { result = Value::named("flask.views.MethodView") } + +deprecated ClassValue theFlaskReponseClass() { result = Value::named("flask.Response") } + +/** + * Holds if `route` is routed to `func` + * by decorating `func` with `app.route(route)` + */ +deprecated predicate app_route(ControlFlowNode route, Function func) { + exists(CallNode route_call, CallNode decorator_call | + route_call.getFunction().(AttrNode).getObject("route").pointsTo().getClass() = theFlaskClass() and + decorator_call.getFunction() = route_call and + route_call.getArg(0) = route and + decorator_call.getArg(0).getNode().(FunctionExpr).getInnerScope() = func + ) +} + +/* Helper for add_url_rule */ +deprecated private predicate add_url_rule_call(ControlFlowNode regex, ControlFlowNode callable) { + exists(CallNode call | + call.getFunction().(AttrNode).getObject("add_url_rule").pointsTo().getClass() = theFlaskClass() and + regex = call.getArg(0) + | + callable = call.getArg(2) or + callable = call.getArgByName("view_func") + ) +} + +/** Holds if urls matching `regex` are routed to `func` */ +deprecated predicate add_url_rule(ControlFlowNode regex, Function func) { + exists(ControlFlowNode callable | add_url_rule_call(regex, callable) | + exists(PythonFunctionValue f | f.getScope() = func and callable.pointsTo(f)) + or + /* MethodView.as_view() */ + exists(MethodViewClass view_cls | view_cls.asTaint().taints(callable) | + func = view_cls.lookup(httpVerbLower()).(FunctionValue).getScope() + ) + /* TODO: -- Handle Views that aren't MethodViews */ + ) +} + +/** + * Holds if urls matching `regex` are routed to `func` using + * any of flask's routing mechanisms. + */ +deprecated predicate flask_routing(ControlFlowNode regex, Function func) { + app_route(regex, func) + or + add_url_rule(regex, func) +} + +/** A class that extends flask.views.MethodView */ +deprecated private class MethodViewClass extends ClassValue { + MethodViewClass() { this.getASuperType() = theFlaskMethodViewClass() } + + /* As we are restricted to strings for taint kinds, we need to map these classes to strings. */ + string taintString() { result = "flask/" + this.getQualifiedName() + ".as.view" } + + /* As we are restricted to strings for taint kinds, we need to map these classes to strings. */ + TaintKind asTaint() { result = this.taintString() } +} + +deprecated private class MethodViewTaint extends TaintKind { + MethodViewTaint() { any(MethodViewClass cls).taintString() = this } +} + +/** A source of method view "taint"s. */ +deprecated private class AsView extends TaintSource { + AsView() { + exists(ClassValue view_class | + view_class.getASuperType() = theFlaskMethodViewClass() and + this.(CallNode).getFunction().(AttrNode).getObject("as_view").pointsTo(view_class) + ) + } + + override string toString() { result = "flask.MethodView.as_view()" } + + override predicate isSourceOf(TaintKind kind) { + exists(MethodViewClass view_class | + kind = view_class.asTaint() and + this.(CallNode).getFunction().(AttrNode).getObject("as_view").pointsTo(view_class) + ) + } +} + +deprecated class FlaskCookieSet extends CookieSet, CallNode { + FlaskCookieSet() { + any(FlaskResponseTaintKind t).taints(this.getFunction().(AttrNode).getObject("set_cookie")) + } + + override string toString() { result = CallNode.super.toString() } + + override ControlFlowNode getKey() { result = this.getArg(0) } + + override ControlFlowNode getValue() { result = this.getArg(1) } +} diff --git a/python/ql/lib/semmle/python/web/flask/Request.qll b/python/ql/lib/semmle/python/web/flask/Request.qll new file mode 100644 index 00000000000..ea9a59dc45e --- /dev/null +++ b/python/ql/lib/semmle/python/web/flask/Request.qll @@ -0,0 +1,80 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http +import semmle.python.web.flask.General + +deprecated private Value theFlaskRequestObject() { result = Value::named("flask.request") } + +/** Holds if `attr` is an access of attribute `name` of the flask request object */ +deprecated private predicate flask_request_attr(AttrNode attr, string name) { + attr.isLoad() and + attr.getObject(name).pointsTo(theFlaskRequestObject()) +} + +/** Source of external data from a flask request */ +deprecated class FlaskRequestData extends HttpRequestTaintSource { + FlaskRequestData() { + not this instanceof FlaskRequestArgs and + exists(string name | flask_request_attr(this, name) | + name in ["path", "full_path", "base_url", "url"] + ) + } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } + + override string toString() { result = "flask.request" } +} + +/** Source of dictionary whose values are externally controlled */ +deprecated class FlaskRequestArgs extends HttpRequestTaintSource { + FlaskRequestArgs() { + exists(string attr | flask_request_attr(this, attr) | + attr in ["args", "form", "values", "files", "headers", "json"] + ) + } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind } + + override string toString() { result = "flask.request.args" } +} + +/** Source of dictionary whose values are externally controlled */ +deprecated class FlaskRequestJson extends HttpRequestTaintSource { + FlaskRequestJson() { flask_request_attr(this, "json") } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalJsonKind } + + override string toString() { result = "flask.request.json" } +} + +/** + * A parameter to a flask request handler, that can capture a part of the URL (as specified in + * the url-pattern of a route). + * + * For example, the `name` parameter in: + * ``` + * @app.route('/hello/<name>') + * def hello(name): + * ``` + */ +deprecated class FlaskRoutedParameter extends HttpRequestTaintSource { + FlaskRoutedParameter() { + exists(string name, Function func, StrConst url_pattern | + this.(ControlFlowNode).getNode() = func.getArgByName(name) and + flask_routing(url_pattern.getAFlowNode(), func) and + exists(string match | + match = url_pattern.getS().regexpFind(werkzeug_rule_re(), _, _) and + name = match.regexpCapture(werkzeug_rule_re(), 4) + ) + ) + } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } +} + +deprecated private string werkzeug_rule_re() { + // since flask uses werkzeug internally, we are using its routing rules from + // https://github.com/pallets/werkzeug/blob/4dc8d6ab840d4b78cbd5789cef91b01e3bde01d5/src/werkzeug/routing.py#L138-L151 + result = + "(?<static>[^<]*)<(?:(?<converter>[a-zA-Z_][a-zA-Z0-9_]*)(?:\\((?<args>.*?)\\))?\\:)?(?<variable>[a-zA-Z_][a-zA-Z0-9_]*)>" +} diff --git a/python/ql/lib/semmle/python/web/flask/Response.qll b/python/ql/lib/semmle/python/web/flask/Response.qll new file mode 100644 index 00000000000..1e489c56b46 --- /dev/null +++ b/python/ql/lib/semmle/python/web/flask/Response.qll @@ -0,0 +1,55 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.security.strings.Basic +import semmle.python.web.flask.General + +/** + * A flask response, which is vulnerable to any sort of + * http response malice. + */ +deprecated class FlaskRoutedResponse extends HttpResponseTaintSink { + FlaskRoutedResponse() { + exists(PythonFunctionValue response | + flask_routing(_, response.getScope()) and + this = response.getAReturnedNode() + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof StringKind } + + override string toString() { result = "flask.routed.response" } +} + +deprecated class FlaskResponseArgument extends HttpResponseTaintSink { + FlaskResponseArgument() { + exists(CallNode call | + ( + call.getFunction().pointsTo(theFlaskReponseClass()) + or + call.getFunction().pointsTo(Value::named("flask.make_response")) + ) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof StringKind } + + override string toString() { result = "flask.response.argument" } +} + +deprecated class FlaskResponseTaintKind extends TaintKind { + FlaskResponseTaintKind() { this = "flask.Response" } +} + +deprecated class FlaskResponseConfiguration extends TaintTracking::Configuration { + FlaskResponseConfiguration() { this = "Flask response configuration" } + + override predicate isSource(DataFlow::Node node, TaintKind kind) { + kind instanceof FlaskResponseTaintKind and + ( + node.asCfgNode().(CallNode).getFunction().pointsTo(theFlaskReponseClass()) + or + node.asCfgNode().(CallNode).getFunction().pointsTo(Value::named("flask.make_response")) + ) + } +} diff --git a/python/ql/lib/semmle/python/web/pyramid/Request.qll b/python/ql/lib/semmle/python/web/pyramid/Request.qll new file mode 100644 index 00000000000..df84cc84440 --- /dev/null +++ b/python/ql/lib/semmle/python/web/pyramid/Request.qll @@ -0,0 +1,25 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http +private import semmle.python.web.webob.Request +private import semmle.python.web.pyramid.View + +deprecated class PyramidRequest extends BaseWebobRequest { + PyramidRequest() { this = "pyramid.request" } + + override ClassValue getType() { result = Value::named("pyramid.request.Request") } +} + +/** Source of pyramid request objects */ +deprecated class PyramidViewArgument extends HttpRequestTaintSource { + PyramidViewArgument() { + exists(Function view_func | + is_pyramid_view_function(view_func) and + this.(ControlFlowNode).getNode() = view_func.getArg(0) + ) + } + + override predicate isSourceOf(TaintKind kind) { kind instanceof PyramidRequest } + + override string toString() { result = "pyramid.view.argument" } +} diff --git a/python/ql/lib/semmle/python/web/pyramid/View.qll b/python/ql/lib/semmle/python/web/pyramid/View.qll new file mode 100644 index 00000000000..37d9334cb07 --- /dev/null +++ b/python/ql/lib/semmle/python/web/pyramid/View.qll @@ -0,0 +1,9 @@ +import python + +deprecated ModuleValue thePyramidViewModule() { result.getName() = "pyramid.view" } + +deprecated Value thePyramidViewConfig() { result = thePyramidViewModule().attr("view_config") } + +deprecated predicate is_pyramid_view_function(Function func) { + func.getADecorator().pointsTo().getClass() = thePyramidViewConfig() +} diff --git a/python/ql/lib/semmle/python/web/stdlib/Request.qll b/python/ql/lib/semmle/python/web/stdlib/Request.qll new file mode 100644 index 00000000000..ff850233616 --- /dev/null +++ b/python/ql/lib/semmle/python/web/stdlib/Request.qll @@ -0,0 +1,126 @@ +/** + * Provides the sources and taint-flow for HTTP servers defined using the standard library (stdlib). + * Specifically, we model `HttpRequestTaintSource`s from instances of `BaseHTTPRequestHandler` + * (or subclasses) and form parsing using `cgi.FieldStorage`. + */ + +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http + +/** Source of BaseHttpRequestHandler instances. */ +deprecated class StdLibRequestSource extends HttpRequestTaintSource { + StdLibRequestSource() { + exists(ClassValue cls | + cls.getABaseType+() = Value::named("BaseHTTPServer.BaseHTTPRequestHandler") + or + cls.getABaseType+() = Value::named("http.server.BaseHTTPRequestHandler") + | + this.(ControlFlowNode).pointsTo().getClass() = cls + ) + } + + override predicate isSourceOf(TaintKind kind) { kind instanceof BaseHTTPRequestHandlerKind } +} + +/** TaintKind for an instance of BaseHttpRequestHandler. */ +deprecated class BaseHTTPRequestHandlerKind extends TaintKind { + BaseHTTPRequestHandlerKind() { this = "BaseHTTPRequestHandlerKind" } + + override TaintKind getTaintOfAttribute(string name) { + name in ["requestline", "path"] and + result instanceof ExternalStringKind + or + name = "headers" and + result instanceof HTTPMessageKind + or + name = "rfile" and + result instanceof ExternalFileObject + } +} + +/** TaintKind for headers (instance of HttpMessage). */ +deprecated class HTTPMessageKind extends ExternalStringDictKind { + override TaintKind getTaintOfMethodResult(string name) { + result = super.getTaintOfMethodResult(name) + or + name = "get_all" and + result.(SequenceKind).getItem() = this.getValue() + or + name in ["as_bytes", "as_string"] and + result instanceof ExternalStringKind + } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + result = super.getTaintForFlowStep(fromnode, tonode) + or + exists(ClassValue cls | cls = ClassValue::unicode() or cls = ClassValue::bytes() | + tonode = cls.getACall() and + tonode.(CallNode).getArg(0) = fromnode and + result instanceof ExternalStringKind + ) + } +} + +/** Source of parsed HTTP forms (by using the `cgi` module). */ +deprecated class CgiFieldStorageSource extends HttpRequestTaintSource { + CgiFieldStorageSource() { this = Value::named("cgi.FieldStorage").getACall() } + + override predicate isSourceOf(TaintKind kind) { kind instanceof CgiFieldStorageFormKind } +} + +/** TaintKind for a parsed HTTP form. */ +deprecated class CgiFieldStorageFormKind extends TaintKind { + /* + * There is a slight difference between how we model form/fields and how it is handled by the code. + * In the code + * ``` + * form = cgi.FieldStorage() + * field = form['myfield'] + * ``` + * both `form` and `field` have the type `cgi.FieldStorage`. This allows the code to represent + * nested forms as `form['nested_form']['myfield']`. However, since HTML forms can't be nested + * we ignore that detail since it allows for a more clean modeling. + */ + + CgiFieldStorageFormKind() { this = "CgiFieldStorageFormKind" } + + override TaintKind getTaintOfAttribute(string name) { + name = "value" and result.(SequenceKind).getItem() instanceof CgiFieldStorageFieldKind + } + + override TaintKind getTaintOfMethodResult(string name) { + name = "getvalue" and + ( + result instanceof ExternalStringKind + or + result.(SequenceKind).getItem() instanceof ExternalStringKind + ) + or + name = "getfirst" and + result instanceof ExternalStringKind + or + name = "getlist" and + result.(SequenceKind).getItem() instanceof ExternalStringKind + } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + tonode.(SubscriptNode).getObject() = fromnode and + ( + result instanceof CgiFieldStorageFieldKind + or + result.(SequenceKind).getItem() instanceof CgiFieldStorageFieldKind + ) + } +} + +/** TaintKind for the field of a parsed HTTP form. */ +deprecated class CgiFieldStorageFieldKind extends TaintKind { + CgiFieldStorageFieldKind() { this = "CgiFieldStorageFieldKind" } + + override TaintKind getTaintOfAttribute(string name) { + name in ["filename", "value"] and result instanceof ExternalStringKind + or + name = "file" and result instanceof ExternalFileObject + } +} diff --git a/python/ql/lib/semmle/python/web/tornado/Request.qll b/python/ql/lib/semmle/python/web/tornado/Request.qll new file mode 100644 index 00000000000..77a02c230ae --- /dev/null +++ b/python/ql/lib/semmle/python/web/tornado/Request.qll @@ -0,0 +1,69 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http +import Tornado + +/** A tornado.request.HttpRequest object */ +deprecated class TornadoRequest extends TaintKind { + TornadoRequest() { this = "tornado.request.HttpRequest" } + + override TaintKind getTaintOfAttribute(string name) { + result instanceof ExternalStringDictKind and + ( + name = "headers" or + name = "cookies" + ) + or + result instanceof ExternalStringKind and + ( + name = "uri" or + name = "query" or + name = "body" + ) + or + result instanceof ExternalStringSequenceDictKind and + ( + name = "arguments" or + name = "query_arguments" or + name = "body_arguments" + ) + } +} + +deprecated class TornadoRequestSource extends HttpRequestTaintSource { + TornadoRequestSource() { isTornadoRequestHandlerInstance(this.(AttrNode).getObject("request")) } + + override string toString() { result = "Tornado request source" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoRequest } +} + +deprecated class TornadoExternalInputSource extends HttpRequestTaintSource { + TornadoExternalInputSource() { + exists(string name | + name in ["get_argument", "get_query_argument", "get_body_argument", "decode_argument"] + | + this = callToNamedTornadoRequestHandlerMethod(name) + ) + } + + override string toString() { result = "Tornado request method" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } +} + +deprecated class TornadoExternalInputListSource extends HttpRequestTaintSource { + TornadoExternalInputListSource() { + exists(string name | + name = "get_arguments" or + name = "get_query_arguments" or + name = "get_body_arguments" + | + this = callToNamedTornadoRequestHandlerMethod(name) + ) + } + + override string toString() { result = "Tornado request method" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind } +} diff --git a/python/ql/lib/semmle/python/web/tornado/Tornado.qll b/python/ql/lib/semmle/python/web/tornado/Tornado.qll new file mode 100644 index 00000000000..798ecff43ff --- /dev/null +++ b/python/ql/lib/semmle/python/web/tornado/Tornado.qll @@ -0,0 +1,50 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http + +deprecated private ClassValue theTornadoRequestHandlerClass() { + result = Value::named("tornado.web.RequestHandler") +} + +deprecated ClassValue aTornadoRequestHandlerClass() { + result.getABaseType+() = theTornadoRequestHandlerClass() +} + +/** + * Holds if `node` is likely to refer to an instance of a tornado + * `RequestHandler` class. + */ +deprecated predicate isTornadoRequestHandlerInstance(ControlFlowNode node) { + node.pointsTo().getClass() = aTornadoRequestHandlerClass() + or + /* + * In some cases, the points-to analysis won't capture all instances we care + * about. For these, we use the following syntactic check. First, that + * `node` appears inside a method of a subclass of + * `tornado.web.RequestHandler`: + */ + + node.getScope().getEnclosingScope() = aTornadoRequestHandlerClass().getScope() and + /* Secondly, that `node` refers to the `self` argument: */ + node.isLoad() and + node.(NameNode).isSelf() +} + +deprecated CallNode callToNamedTornadoRequestHandlerMethod(string name) { + isTornadoRequestHandlerInstance(result.getFunction().(AttrNode).getObject(name)) +} + +deprecated class TornadoCookieSet extends CookieSet, CallNode { + TornadoCookieSet() { + exists(ControlFlowNode f | + f = this.getFunction().(AttrNode).getObject("set_cookie") and + isTornadoRequestHandlerInstance(f) + ) + } + + override string toString() { result = CallNode.super.toString() } + + override ControlFlowNode getKey() { result = this.getArg(0) } + + override ControlFlowNode getValue() { result = this.getArg(1) } +} diff --git a/python/ql/lib/semmle/python/web/turbogears/Request.qll b/python/ql/lib/semmle/python/web/turbogears/Request.qll new file mode 100644 index 00000000000..48e063d0f99 --- /dev/null +++ b/python/ql/lib/semmle/python/web/turbogears/Request.qll @@ -0,0 +1,26 @@ +import python +import semmle.python.security.strings.External +import semmle.python.web.Http +import TurboGears + +deprecated private class ValidatedMethodParameter extends Parameter { + ValidatedMethodParameter() { + exists(string name, TurboGearsControllerMethod method | + method.getArgByName(name) = this and + method.getValidationDict().getItem(_).(KeyValuePair).getKey().(StrConst).getText() = name + ) + } +} + +deprecated class UnvalidatedControllerMethodParameter extends HttpRequestTaintSource { + UnvalidatedControllerMethodParameter() { + exists(Parameter p | + any(TurboGearsControllerMethod m | not m.getName() = "onerror").getAnArg() = p and + not p instanceof ValidatedMethodParameter and + not p.isSelf() and + p.(Name).getAFlowNode() = this + ) + } + + override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/lib/semmle/python/web/turbogears/TurboGears.qll b/python/ql/lib/semmle/python/web/turbogears/TurboGears.qll new file mode 100644 index 00000000000..87006afe03a --- /dev/null +++ b/python/ql/lib/semmle/python/web/turbogears/TurboGears.qll @@ -0,0 +1,37 @@ +import python +import semmle.python.dataflow.TaintTracking + +deprecated private ClassValue theTurboGearsControllerClass() { + result = Value::named("tg.TGController") +} + +deprecated ClassValue aTurboGearsControllerClass() { + result.getABaseType+() = theTurboGearsControllerClass() +} + +deprecated class TurboGearsControllerMethod extends Function { + ControlFlowNode decorator; + + TurboGearsControllerMethod() { + aTurboGearsControllerClass().getScope() = this.getScope() and + decorator = this.getADecorator().getAFlowNode() and + /* Is decorated with @expose() or @expose(path) */ + ( + decorator.(CallNode).getFunction().(NameNode).getId() = "expose" + or + decorator.pointsTo().getClass() = Value::named("tg.expose") + ) + } + + private ControlFlowNode templateName() { result = decorator.(CallNode).getArg(0) } + + predicate isTemplated() { exists(this.templateName()) } + + Dict getValidationDict() { + exists(Call call | + call = this.getADecorator() and + call.getFunc().(Name).getId() = "validate" and + call.getArg(0).pointsTo(_, result) + ) + } +} diff --git a/python/ql/lib/semmle/python/web/twisted/Request.qll b/python/ql/lib/semmle/python/web/twisted/Request.qll new file mode 100644 index 00000000000..d1bcf879f0f --- /dev/null +++ b/python/ql/lib/semmle/python/web/twisted/Request.qll @@ -0,0 +1,30 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http +import Twisted + +/** A twisted.web.http.Request object */ +deprecated class TwistedRequest extends TaintKind { + TwistedRequest() { this = "twisted.request.http.Request" } + + override TaintKind getTaintOfAttribute(string name) { + result instanceof ExternalStringSequenceDictKind and + name = "args" + or + result instanceof ExternalStringKind and + name = "uri" + } + + override TaintKind getTaintOfMethodResult(string name) { + name in ["getHeader", "getCookie", "getUser", "getPassword"] and + result instanceof ExternalStringKind + } +} + +deprecated class TwistedRequestSource extends HttpRequestTaintSource { + TwistedRequestSource() { isTwistedRequestInstance(this) } + + override string toString() { result = "Twisted request source" } + + override predicate isSourceOf(TaintKind kind) { kind instanceof TwistedRequest } +} diff --git a/python/ql/lib/semmle/python/web/twisted/Twisted.qll b/python/ql/lib/semmle/python/web/twisted/Twisted.qll new file mode 100644 index 00000000000..54dd1d959e8 --- /dev/null +++ b/python/ql/lib/semmle/python/web/twisted/Twisted.qll @@ -0,0 +1,52 @@ +import python +import semmle.python.dataflow.TaintTracking + +deprecated private ClassValue theTwistedHttpRequestClass() { + result = Value::named("twisted.web.http.Request") +} + +deprecated private ClassValue theTwistedHttpResourceClass() { + result = Value::named("twisted.web.resource.Resource") +} + +deprecated ClassValue aTwistedRequestHandlerClass() { + result.getABaseType+() = theTwistedHttpResourceClass() +} + +deprecated FunctionValue getTwistedRequestHandlerMethod(string name) { + result = aTwistedRequestHandlerClass().declaredAttribute(name) +} + +bindingset[name] +deprecated predicate isKnownRequestHandlerMethodName(string name) { + name = "render" or + name.matches("render_%") +} + +/** + * Holds if `node` is likely to refer to an instance of the twisted + * `Request` class. + */ +deprecated predicate isTwistedRequestInstance(NameNode node) { + node.pointsTo().getClass() = theTwistedHttpRequestClass() + or + /* + * In points-to analysis cannot infer that a given object is an instance of + * the `twisted.web.http.Request` class, we also include any parameter + * called `request` that appears inside a subclass of a request handler + * class, and the appropriate arguments of known request handler methods. + */ + + exists(Function func | + func = node.getScope() and + func.getEnclosingScope() = aTwistedRequestHandlerClass().getScope() + | + /* Any parameter called `request` */ + node.getId() = "request" and + node.isParameter() + or + /* Any request parameter of a known request handler method */ + isKnownRequestHandlerMethodName(func.getName()) and + node.getNode() = func.getArg(1) + ) +} diff --git a/python/ql/lib/semmle/python/web/webob/Request.qll b/python/ql/lib/semmle/python/web/webob/Request.qll new file mode 100644 index 00000000000..3c085b1d02d --- /dev/null +++ b/python/ql/lib/semmle/python/web/webob/Request.qll @@ -0,0 +1,38 @@ +import python +import semmle.python.dataflow.TaintTracking +import semmle.python.web.Http + +abstract deprecated class BaseWebobRequest extends TaintKind { + bindingset[this] + BaseWebobRequest() { any() } + + override TaintKind getTaintOfAttribute(string name) { + result instanceof ExternalStringDictKind and + ( + name = "GET" or + name = "POST" or + name = "headers" + ) + or + result instanceof ExternalStringKind and + name = "body" + } + + override TaintKind getTaintOfMethodResult(string name) { + result = this and + ( + name = "copy" or + name = "copy_get" or + name = "copy_body" + ) + or + result instanceof ExternalStringKind and + name = "as_bytes" + } +} + +deprecated class WebobRequest extends BaseWebobRequest { + WebobRequest() { this = "webob.Request" } + + override ClassValue getType() { result = Value::named("webob.request.Request") } +} diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp b/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp new file mode 100644 index 00000000000..b044243fc8e --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-074/TemplateInjection.qhelp @@ -0,0 +1,24 @@ +<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> +<qhelp> + <overview> + <p> + Template Injection occurs when user input is embedded in a template in an unsafe manner. + When an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side is results in Server Side Template Injection. + </p> + </overview> + <recommendation> + <p> + To fix this, ensure that an untrusted value is not used as a template. If the application requirements do not alow this, use a sandboxed environment where access to unsafe attributes and methods is prohibited. + </p> + </recommendation> + <example> + <p>Consider the example given below, an untrusted HTTP parameter `template` is used to generate a Jinja2 template string. This can lead to remote code execution. </p> + <sample src="JinjaBad.py" /> + + <p>Here we have fixed the problem by using the Jinja sandbox environment for evaluating untrusted code.</p> + <sample src="JinjaGood.py" /> + </example> + <references> + <li>Portswigger : [Server Side Template Injection](https://portswigger.net/web-security/server-side-template-injection)</li> + </references> +</qhelp> diff --git a/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql b/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql new file mode 100644 index 00000000000..cbc3536ad7d --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-074/TemplateInjection.ql @@ -0,0 +1,35 @@ +/** + * @name Server Side Template Injection + * @description Using user-controlled data to create a template can cause security issues. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/template-injection + * @tags security + * experimental + * external/cwe/cwe-074 + */ + +import python +import semmle.python.security.Paths +/* Sources */ +import semmle.python.web.HttpRequest +/* Sinks */ +import experimental.semmle.python.templates.Ssti +/* Flow */ +import semmle.python.security.strings.Untrusted + +class TemplateInjectionConfiguration extends TaintTracking::Configuration { + TemplateInjectionConfiguration() { this = "Template injection configuration" } + + deprecated override predicate isSource(TaintTracking::Source source) { + source instanceof HttpRequestTaintSource + } + + deprecated override predicate isSink(TaintTracking::Sink sink) { sink instanceof SSTISink } +} + +from TemplateInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink +where config.hasFlowPath(src, sink) +select sink.getSink(), src, sink, "This Template depends on $@.", src.getSource(), + "a user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-091/Xslt.qhelp b/python/ql/src/experimental/Security/CWE-091/Xslt.qhelp new file mode 100644 index 00000000000..307314f00df --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-091/Xslt.qhelp @@ -0,0 +1,18 @@ +<!DOCTYPE qhelp SYSTEM "qhelp.dtd"> +<qhelp> + <overview> + <p> + Processing an unvalidated XSL stylesheet can allow an attacker to change the structure and contents of the resultant XML, include arbitrary files from the file system, or execute arbitrary code. + </p> + </overview> + <recommendation> + <p> + This vulnerability can be prevented by not allowing untrusted user input to be passed as an XSL stylesheet. + If the application logic necessitates processing untrusted XSL stylesheets, the input should be properly filtered and sanitized before use. + </p> + </recommendation> + <example> + <p>In the example below, the XSL stylesheet is controlled by the user and hence leads to a vulnerability.</p> + <sample src="xslt.py" /> + </example> +</qhelp> diff --git a/python/ql/src/experimental/Security/CWE-091/Xslt.ql b/python/ql/src/experimental/Security/CWE-091/Xslt.ql new file mode 100644 index 00000000000..77f405f5f5a --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-091/Xslt.ql @@ -0,0 +1,36 @@ +/** + * @name XSLT query built from user-controlled sources + * @description Building a XSLT query from user-controlled sources is vulnerable to insertion of + * malicious XSLT code by the user. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/xslt-injection + * @tags security + * experimental + * external/cwe/cwe-643 + */ + +import python +import semmle.python.security.Paths +/* Sources */ +import semmle.python.web.HttpRequest +/* Sinks */ +import experimental.semmle.python.security.injection.XSLT + +class XsltInjectionConfiguration extends TaintTracking::Configuration { + XsltInjectionConfiguration() { this = "XSLT injection configuration" } + + deprecated override predicate isSource(TaintTracking::Source source) { + source instanceof HttpRequestTaintSource + } + + deprecated override predicate isSink(TaintTracking::Sink sink) { + sink instanceof XSLTInjection::XSLTInjectionSink + } +} + +from XsltInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink +where config.hasFlowPath(src, sink) +select sink.getSink(), src, sink, "This XSLT query depends on $@.", src.getSource(), + "a user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-091/xslt.py b/python/ql/src/experimental/Security/CWE-091/xslt.py new file mode 100644 index 00000000000..1655916c7e0 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-091/xslt.py @@ -0,0 +1,14 @@ +from lxml import etree +from io import StringIO +from flask import Flask, request + +app = Flask(__name__) + + +@app.route("/xslt") +def bad(): + xsltQuery = request.args.get('xml', '') + xslt_root = etree.XML(xsltQuery) + f = StringIO('<foo><bar></bar></foo>') + tree = etree.parse(f) + result_tree = tree.xslt(xslt_root) # Not OK diff --git a/python/ql/src/experimental/semmle/python/security/injection/XSLT.qll b/python/ql/src/experimental/semmle/python/security/injection/XSLT.qll index ff3f7189b18..4d0057f8dc1 100644 --- a/python/ql/src/experimental/semmle/python/security/injection/XSLT.qll +++ b/python/ql/src/experimental/semmle/python/security/injection/XSLT.qll @@ -8,6 +8,7 @@ import python import semmle.python.dataflow.TaintTracking +import semmle.python.web.HttpRequest /** Models XSLT Injection related classes and functions */ module XsltInjection { @@ -20,6 +21,21 @@ module XsltInjection { /** DEPRECATED: Alias for XsltInjectionSink */ deprecated class XSLTInjectionSink = XsltInjectionSink; + /** + * A kind of "taint", representing an untrusted XML string + */ + deprecated private class ExternalXmlStringKind extends ExternalStringKind { + ExternalXmlStringKind() { this = "etree.XML string" } + + override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) { + etreeXml(fromnode, tonode) and result instanceof ExternalXmlKind + or + etreeFromStringList(fromnode, tonode) and result instanceof ExternalXmlKind + or + etreeFromString(fromnode, tonode) and result instanceof ExternalXmlKind + } + } + /** * A kind of "taint", representing a XML encoded string */ @@ -27,6 +43,32 @@ module XsltInjection { ExternalXmlKind() { this = "lxml etree xml" } } + private predicate etreeXml(ControlFlowNode fromnode, CallNode tonode) { + // etree.XML("<xmlContent>") + exists(CallNode call | call.getFunction().(AttrNode).getObject("XML").pointsTo(etree()) | + call.getArg(0) = fromnode and + call = tonode + ) + } + + private predicate etreeFromString(ControlFlowNode fromnode, CallNode tonode) { + // etree.fromstring(text, parser=None) + exists(CallNode call | call.getFunction().(AttrNode).getObject("fromstring").pointsTo(etree()) | + call.getArg(0) = fromnode and + call = tonode + ) + } + + private predicate etreeFromStringList(ControlFlowNode fromnode, CallNode tonode) { + // etree.fromstringlist(strings, parser=None) + exists(CallNode call | + call.getFunction().(AttrNode).getObject("fromstringlist").pointsTo(etree()) + | + call.getArg(0) = fromnode and + call = tonode + ) + } + /** * A Sink representing an argument to the `etree.XSLT` call. * diff --git a/python/ql/src/experimental/semmle/python/templates/Airspeed.qll b/python/ql/src/experimental/semmle/python/templates/Airspeed.qll new file mode 100644 index 00000000000..dc266ac0f82 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Airspeed.qll @@ -0,0 +1,27 @@ +/** Provides classes which model the `airspeed` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the ClassValue representing `airspeed.Template` */ +deprecated ClassValue theAirspeedTemplateClass() { result = Value::named("airspeed.Template") } + +/** + * A sink representing the `airspeed.Template` class instantiation argument. + * + * import airspeed + * temp = airspeed.Template(`"sink"`) + */ +deprecated class AirspeedTemplateSink extends SSTISink { + override string toString() { result = "argument to airspeed.Template()" } + + AirspeedTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theAirspeedTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/Bottle.qll b/python/ql/src/experimental/semmle/python/templates/Bottle.qll new file mode 100644 index 00000000000..1f5bd2bba85 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Bottle.qll @@ -0,0 +1,48 @@ +/** Provides classes which model the `bottle` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the ClassValue representing `bottle.SimpleTemplate` */ +deprecated ClassValue theBottleSimpleTemplateClass() { + result = Value::named("bottle.SimpleTemplate") +} + +/** + * A sink representing the `bottle.SimpleTemplate` class instantiation argument. + * + * from bottle import SimpleTemplate + * template = SimpleTemplate(`sink`) + */ +deprecated class BottleSimpleTemplateSink extends SSTISink { + override string toString() { result = "argument to bottle.SimpleTemplate()" } + + BottleSimpleTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theBottleSimpleTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} + +/** + * A sink representing the `bottle.template` function call argument. + * + * from bottle import template + * tmp = template(`sink`) + */ +deprecated class BottleTemplateSink extends SSTISink { + override string toString() { result = "argument to bottle.template()" } + + BottleTemplateSink() { + exists(CallNode call | + call.getFunction() = theBottleModule().attr("template").getAReference() and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/Chameleon.qll b/python/ql/src/experimental/semmle/python/templates/Chameleon.qll new file mode 100644 index 00000000000..f094dda97b5 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Chameleon.qll @@ -0,0 +1,29 @@ +/** Provides classes which model the `Chameleon` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the ClassValue representing `chameleon.PageTemplate` */ +deprecated ClassValue theChameleonPageTemplateClass() { + result = Value::named("chameleon.PageTemplate") +} + +/** + * A sink representing the `chameleon.PageTemplate` class instantiation argument. + * + * from chameleon import PageTemplate + * template = PageTemplate(`sink`) + */ +deprecated class ChameleonTemplateSink extends SSTISink { + override string toString() { result = "argument to Chameleon.PageTemplate()" } + + ChameleonTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theChameleonPageTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/Cheetah.qll b/python/ql/src/experimental/semmle/python/templates/Cheetah.qll new file mode 100644 index 00000000000..9812fdb7c88 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Cheetah.qll @@ -0,0 +1,39 @@ +/** Provides classes which model the `Cheetah3` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the ClassValue representing `Cheetah.Template.Template` */ +deprecated ClassValue theCheetahTemplateClass() { + result = Value::named("Cheetah.Template.Template") +} + +/** + * A sink representing the instantiation argument of any class which derives from + * the `Cheetah.Template.Template` class . + * + * from Cheetah.Template import Template + * class Template3(Template): + * title = 'Hello World Example!' + * contents = 'Hello World!' + * t3 = Template3("sink") + * + * This will also detect cases of the following type : + * + * from Cheetah.Template import Template + * t3 = Template("sink") + */ +deprecated class CheetahTemplateInstantiationSink extends SSTISink { + override string toString() { result = "argument to Cheetah.Template.Template()" } + + CheetahTemplateInstantiationSink() { + exists(CallNode call, ClassValue cv | + cv.getASuperType() = theCheetahTemplateClass() and + call.getFunction().pointsTo(cv) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/Chevron.qll b/python/ql/src/experimental/semmle/python/templates/Chevron.qll new file mode 100644 index 00000000000..cc93016891c --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Chevron.qll @@ -0,0 +1,36 @@ +/** Provides classes which model the `chevron` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the Value representing `chevron.render` function */ +deprecated Value theChevronRenderFunc() { result = Value::named("chevron.render") } + +/** + * A sink representing the `chevron.render` function call argument. + * + * import chevron + * tmp = chevron.render(`sink`,{ 'key' : 'value' }) + */ +deprecated class ChevronRenderSink extends SSTISink { + override string toString() { result = "argument to chevron.render()" } + + ChevronRenderSink() { + exists(CallNode call | + call.getFunction() = theChevronRenderFunc().getAReference() and + call.getArg(0) = this + ) + // TODO: this should also detect : + // import chevron + // args = { + // 'template': 'sink', + // 'data': { + // 'mustache': 'World' + // } + // } + // chevron.render(**args) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/DjangoTemplate.qll b/python/ql/src/experimental/semmle/python/templates/DjangoTemplate.qll new file mode 100644 index 00000000000..1089ab872ec --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/DjangoTemplate.qll @@ -0,0 +1,35 @@ +/** Provides classes which model the `DjangoTemplate` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +deprecated ClassValue theDjangoTemplateClass() { result = Value::named("django.template.Template") } + +/** + * A sink representing `django.template.Template` class instantiation argument. + * + * from django.template import Template + * template = Template(`sink`) + */ +deprecated class DjangoTemplateTemplateSink extends SSTISink { + override string toString() { result = "argument to Django.template()" } + + DjangoTemplateTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theDjangoTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} +// TODO (intentionally commented out QLDoc, since qlformat will delete those lines otherwise) +// /** +// * Sinks representing the django.template.Template class instantiation. +// * +// * from django.template import engines +// * +// * django_engine = engines["django"] +// * template = django_engine.from_string(`sink`) +// */ diff --git a/python/ql/src/experimental/semmle/python/templates/FlaskTemplate.qll b/python/ql/src/experimental/semmle/python/templates/FlaskTemplate.qll new file mode 100644 index 00000000000..c0f3c90235d --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/FlaskTemplate.qll @@ -0,0 +1,28 @@ +/** Provides classes which model templates in the`flask` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +deprecated Value theFlaskRenderTemplateClass() { + result = Value::named("flask.render_template_string") +} + +/** + * A sink representing `flask.render_template_string` function call argument. + * + * from flask import render_template_string + * render_template_string(`sink`) + */ +deprecated class FlaskTemplateSink extends SSTISink { + override string toString() { result = "argument to flask.render_template_string()" } + + FlaskTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theFlaskRenderTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/Genshi.qll b/python/ql/src/experimental/semmle/python/templates/Genshi.qll new file mode 100644 index 00000000000..c808d7c60f8 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Genshi.qll @@ -0,0 +1,53 @@ +/** Provides classes which model the `Genshi` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the ClassValue representing `Genshi.template.TextTemplate` */ +deprecated ClassValue theGenshiTextTemplateClass() { + result = Value::named("genshi.template.TextTemplate") +} + +/** returns the ClassValue representing `Genshi.template.MarkupTemplate` */ +deprecated ClassValue theGenshiMarkupTemplateClass() { + result = Value::named("genshi.template.MarkupTemplate") +} + +/** + * A sink representing the `genshi.template.TextTemplate` class instantiation argument. + * + * from genshi.template import TextTemplate + * tmpl = TextTemplate('sink') + */ +deprecated class GenshiTextTemplateSink extends SSTISink { + override string toString() { result = "argument to genshi.template.TextTemplate()" } + + GenshiTextTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theGenshiTextTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} + +/** + * A sink representing the `genshi.template.MarkupTemplate` class instantiation argument. + * + * from genshi.template import MarkupTemplate + * tmpl = MarkupTemplate('sink') + */ +deprecated class GenshiMarkupTemplateSink extends SSTISink { + override string toString() { result = "argument to genshi.template.MarkupTemplate()" } + + GenshiMarkupTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theGenshiMarkupTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/Jinja.qll b/python/ql/src/experimental/semmle/python/templates/Jinja.qll new file mode 100644 index 00000000000..44bc103cf04 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Jinja.qll @@ -0,0 +1,49 @@ +/** Provides classes which model the `Jinja2` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the ClassValue representing `jinja2.Template` */ +deprecated ClassValue theJinja2TemplateClass() { result = Value::named("jinja2.Template") } + +/** returns the ClassValue representing `jinja2.Template` */ +deprecated Value theJinja2FromStringValue() { result = Value::named("jinja2.from_string") } + +/** + * A sink representing the `jinja2.Template` class instantiation argument. + * + * from jinja2 import Template + * template = Template(`sink`) + */ +deprecated class Jinja2TemplateSink extends SSTISink { + override string toString() { result = "argument to jinja2.Template()" } + + Jinja2TemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theJinja2TemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} + +/** + * A sink representing the `jinja2.from_string` function call argument. + * + * from jinja2 import from_string + * template = from_string(`sink`) + */ +deprecated class Jinja2FromStringSink extends SSTISink { + override string toString() { result = "argument to jinja2.from_string()" } + + Jinja2FromStringSink() { + exists(CallNode call | + call.getFunction().pointsTo(theJinja2FromStringValue()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/Mako.qll b/python/ql/src/experimental/semmle/python/templates/Mako.qll new file mode 100644 index 00000000000..b8634b3001a --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Mako.qll @@ -0,0 +1,27 @@ +/** Provides classes which model the `Mako` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the ClassValue representing `mako.template.Template` */ +deprecated ClassValue theMakoTemplateClass() { result = Value::named("mako.template.Template") } + +/** + * A sink representing the `mako.template.Template` class instantiation argument. + * + * from mako.template import Template + * mytemplate = Template("hello world!") + */ +deprecated class MakoTemplateSink extends SSTISink { + override string toString() { result = "argument to mako.template.Template()" } + + MakoTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theMakoTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/src/experimental/semmle/python/templates/SSTISink.qll b/python/ql/src/experimental/semmle/python/templates/SSTISink.qll new file mode 100644 index 00000000000..1a68fe17b68 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/SSTISink.qll @@ -0,0 +1,7 @@ +import semmle.python.dataflow.TaintTracking + +/** + * A generic taint sink that is vulnerable to template inclusions. + * The `temp` in `jinja2.Template(temp)` and similar. + */ +abstract deprecated class SSTISink extends TaintSink { } diff --git a/python/ql/src/experimental/semmle/python/templates/Ssti.qll b/python/ql/src/experimental/semmle/python/templates/Ssti.qll new file mode 100644 index 00000000000..eb4f8d0ec2f --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/Ssti.qll @@ -0,0 +1,13 @@ +/** Imports all files which model potential SSTI sinks */ + +import experimental.semmle.python.templates.Airspeed +import experimental.semmle.python.templates.Bottle +import experimental.semmle.python.templates.Chameleon +import experimental.semmle.python.templates.Cheetah +import experimental.semmle.python.templates.Chevron +import experimental.semmle.python.templates.DjangoTemplate +import experimental.semmle.python.templates.FlaskTemplate +import experimental.semmle.python.templates.Genshi +import experimental.semmle.python.templates.Jinja +import experimental.semmle.python.templates.Mako +import experimental.semmle.python.templates.TRender diff --git a/python/ql/src/experimental/semmle/python/templates/TRender.qll b/python/ql/src/experimental/semmle/python/templates/TRender.qll new file mode 100644 index 00000000000..8d5431ad9e0 --- /dev/null +++ b/python/ql/src/experimental/semmle/python/templates/TRender.qll @@ -0,0 +1,27 @@ +/** Provides classes which model the `TRender` package. */ + +import python +import semmle.python.web.HttpRequest +import experimental.semmle.python.templates.SSTISink + +/** returns the ClassValue representing `trender.TRender` */ +deprecated ClassValue theTRenderTemplateClass() { result = Value::named("trender.TRender") } + +/** + * A sink representing the `trender.TRender` class instantiation argument. + * + * from trender import TRender + * template = TRender(`sink`) + */ +deprecated class TRenderTemplateSink extends SSTISink { + override string toString() { result = "argument to trender.TRender()" } + + TRenderTemplateSink() { + exists(CallNode call | + call.getFunction().pointsTo(theTRenderTemplateClass()) and + call.getArg(0) = this + ) + } + + override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } +} diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.expected new file mode 100644 index 00000000000..058a53bdf91 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.expected @@ -0,0 +1,60 @@ +edges +| AirspeedSsti.py:10:16:10:27 | dict of externally controlled string | AirspeedSsti.py:10:16:10:43 | externally controlled string | +| AirspeedSsti.py:10:16:10:27 | dict of externally controlled string | AirspeedSsti.py:10:16:10:43 | externally controlled string | +| AirspeedSsti.py:10:16:10:43 | externally controlled string | AirspeedSsti.py:11:30:11:37 | externally controlled string | +| AirspeedSsti.py:10:16:10:43 | externally controlled string | AirspeedSsti.py:11:30:11:37 | externally controlled string | +| ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:10:16:10:43 | externally controlled string | +| ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:10:16:10:43 | externally controlled string | +| ChevronSsti.py:10:16:10:43 | externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string | +| ChevronSsti.py:10:16:10:43 | externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string | +| DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | +| DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | +| DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | +| DjangoTemplates.py:8:16:8:22 | django.request.HttpRequest | DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | +| DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | DjangoTemplates.py:8:16:8:38 | externally controlled string | +| DjangoTemplates.py:8:16:8:26 | django.http.request.QueryDict | DjangoTemplates.py:8:16:8:38 | externally controlled string | +| DjangoTemplates.py:8:16:8:38 | externally controlled string | DjangoTemplates.py:9:18:9:25 | externally controlled string | +| DjangoTemplates.py:8:16:8:38 | externally controlled string | DjangoTemplates.py:9:18:9:25 | externally controlled string | +| FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string | +| FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string | +| JinjaSsti.py:7:7:7:13 | django.request.HttpRequest | JinjaSsti.py:9:16:9:22 | django.request.HttpRequest | +| JinjaSsti.py:7:7:7:13 | django.request.HttpRequest | JinjaSsti.py:9:16:9:22 | django.request.HttpRequest | +| JinjaSsti.py:9:16:9:22 | django.request.HttpRequest | JinjaSsti.py:9:16:9:26 | django.http.request.QueryDict | +| JinjaSsti.py:9:16:9:22 | django.request.HttpRequest | JinjaSsti.py:9:16:9:26 | django.http.request.QueryDict | +| JinjaSsti.py:9:16:9:26 | django.http.request.QueryDict | JinjaSsti.py:9:16:9:38 | externally controlled string | +| JinjaSsti.py:9:16:9:26 | django.http.request.QueryDict | JinjaSsti.py:9:16:9:38 | externally controlled string | +| JinjaSsti.py:9:16:9:38 | externally controlled string | JinjaSsti.py:10:25:10:32 | externally controlled string | +| JinjaSsti.py:9:16:9:38 | externally controlled string | JinjaSsti.py:10:25:10:32 | externally controlled string | +| JinjaSsti.py:16:7:16:13 | django.request.HttpRequest | JinjaSsti.py:19:16:19:22 | django.request.HttpRequest | +| JinjaSsti.py:16:7:16:13 | django.request.HttpRequest | JinjaSsti.py:19:16:19:22 | django.request.HttpRequest | +| JinjaSsti.py:19:16:19:22 | django.request.HttpRequest | JinjaSsti.py:19:16:19:26 | django.http.request.QueryDict | +| JinjaSsti.py:19:16:19:22 | django.request.HttpRequest | JinjaSsti.py:19:16:19:26 | django.http.request.QueryDict | +| JinjaSsti.py:19:16:19:26 | django.http.request.QueryDict | JinjaSsti.py:19:16:19:38 | externally controlled string | +| JinjaSsti.py:19:16:19:26 | django.http.request.QueryDict | JinjaSsti.py:19:16:19:38 | externally controlled string | +| JinjaSsti.py:19:16:19:38 | externally controlled string | JinjaSsti.py:20:28:20:35 | externally controlled string | +| JinjaSsti.py:19:16:19:38 | externally controlled string | JinjaSsti.py:20:28:20:35 | externally controlled string | +| MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:8:16:8:22 | django.request.HttpRequest | +| MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:8:16:8:22 | django.request.HttpRequest | +| MakoSsti.py:8:16:8:22 | django.request.HttpRequest | MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | +| MakoSsti.py:8:16:8:22 | django.request.HttpRequest | MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | +| MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | MakoSsti.py:8:16:8:38 | externally controlled string | +| MakoSsti.py:8:16:8:26 | django.http.request.QueryDict | MakoSsti.py:8:16:8:38 | externally controlled string | +| MakoSsti.py:8:16:8:38 | externally controlled string | MakoSsti.py:9:27:9:34 | externally controlled string | +| MakoSsti.py:8:16:8:38 | externally controlled string | MakoSsti.py:9:27:9:34 | externally controlled string | +| TRender.py:5:13:5:19 | django.request.HttpRequest | TRender.py:6:16:6:22 | django.request.HttpRequest | +| TRender.py:5:13:5:19 | django.request.HttpRequest | TRender.py:6:16:6:22 | django.request.HttpRequest | +| TRender.py:6:16:6:22 | django.request.HttpRequest | TRender.py:6:16:6:26 | django.http.request.QueryDict | +| TRender.py:6:16:6:22 | django.request.HttpRequest | TRender.py:6:16:6:26 | django.http.request.QueryDict | +| TRender.py:6:16:6:26 | django.http.request.QueryDict | TRender.py:6:16:6:38 | externally controlled string | +| TRender.py:6:16:6:26 | django.http.request.QueryDict | TRender.py:6:16:6:38 | externally controlled string | +| TRender.py:6:16:6:38 | externally controlled string | TRender.py:7:24:7:31 | externally controlled string | +| TRender.py:6:16:6:38 | externally controlled string | TRender.py:7:24:7:31 | externally controlled string | +#select +| AirspeedSsti.py:11:30:11:37 | template | AirspeedSsti.py:10:16:10:27 | dict of externally controlled string | AirspeedSsti.py:11:30:11:37 | externally controlled string | This Template depends on $@. | AirspeedSsti.py:10:16:10:27 | Attribute | a user-provided value | +| ChevronSsti.py:11:27:11:34 | template | ChevronSsti.py:10:16:10:27 | dict of externally controlled string | ChevronSsti.py:11:27:11:34 | externally controlled string | This Template depends on $@. | ChevronSsti.py:10:16:10:27 | Attribute | a user-provided value | +| DjangoTemplates.py:9:18:9:25 | template | DjangoTemplates.py:6:8:6:14 | django.request.HttpRequest | DjangoTemplates.py:9:18:9:25 | externally controlled string | This Template depends on $@. | DjangoTemplates.py:6:8:6:14 | request | a user-provided value | +| FlaskTemplate.py:17:41:17:68 | Attribute() | FlaskTemplate.py:17:41:17:52 | dict of externally controlled string | FlaskTemplate.py:17:41:17:68 | externally controlled string | This Template depends on $@. | FlaskTemplate.py:17:41:17:52 | Attribute | a user-provided value | +| JinjaSsti.py:10:25:10:32 | template | JinjaSsti.py:7:7:7:13 | django.request.HttpRequest | JinjaSsti.py:10:25:10:32 | externally controlled string | This Template depends on $@. | JinjaSsti.py:7:7:7:13 | request | a user-provided value | +| JinjaSsti.py:20:28:20:35 | template | JinjaSsti.py:16:7:16:13 | django.request.HttpRequest | JinjaSsti.py:20:28:20:35 | externally controlled string | This Template depends on $@. | JinjaSsti.py:16:7:16:13 | request | a user-provided value | +| MakoSsti.py:9:27:9:34 | template | MakoSsti.py:6:10:6:16 | django.request.HttpRequest | MakoSsti.py:9:27:9:34 | externally controlled string | This Template depends on $@. | MakoSsti.py:6:10:6:16 | request | a user-provided value | +| TRender.py:7:24:7:31 | template | TRender.py:5:13:5:19 | django.request.HttpRequest | TRender.py:7:24:7:31 | externally controlled string | This Template depends on $@. | TRender.py:5:13:5:19 | request | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.qlref b/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.qlref new file mode 100644 index 00000000000..90efec9f636 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-074/TemplateInjection.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-074/TemplateInjection.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.expected b/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.expected new file mode 100644 index 00000000000..89f19160f69 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.expected @@ -0,0 +1,47 @@ +edges +| xslt.py:10:17:10:28 | dict of etree.XML string | xslt.py:10:17:10:43 | etree.XML string | +| xslt.py:10:17:10:28 | dict of etree.XML string | xslt.py:10:17:10:43 | etree.XML string | +| xslt.py:10:17:10:43 | etree.XML string | xslt.py:11:27:11:35 | etree.XML string | +| xslt.py:10:17:10:43 | etree.XML string | xslt.py:11:27:11:35 | etree.XML string | +| xslt.py:11:17:11:36 | lxml etree xml | xslt.py:14:29:14:37 | lxml etree xml | +| xslt.py:11:17:11:36 | lxml etree xml | xslt.py:14:29:14:37 | lxml etree xml | +| xslt.py:11:27:11:35 | etree.XML string | xslt.py:11:17:11:36 | lxml etree xml | +| xslt.py:11:27:11:35 | etree.XML string | xslt.py:11:17:11:36 | lxml etree xml | +| xsltInjection.py:10:17:10:28 | dict of etree.XML string | xsltInjection.py:10:17:10:43 | etree.XML string | +| xsltInjection.py:10:17:10:28 | dict of etree.XML string | xsltInjection.py:10:17:10:43 | etree.XML string | +| xsltInjection.py:10:17:10:43 | etree.XML string | xsltInjection.py:11:27:11:35 | etree.XML string | +| xsltInjection.py:10:17:10:43 | etree.XML string | xsltInjection.py:11:27:11:35 | etree.XML string | +| xsltInjection.py:11:17:11:36 | lxml etree xml | xsltInjection.py:12:28:12:36 | lxml etree xml | +| xsltInjection.py:11:17:11:36 | lxml etree xml | xsltInjection.py:12:28:12:36 | lxml etree xml | +| xsltInjection.py:11:27:11:35 | etree.XML string | xsltInjection.py:11:17:11:36 | lxml etree xml | +| xsltInjection.py:11:27:11:35 | etree.XML string | xsltInjection.py:11:17:11:36 | lxml etree xml | +| xsltInjection.py:17:17:17:28 | dict of etree.XML string | xsltInjection.py:17:17:17:43 | etree.XML string | +| xsltInjection.py:17:17:17:28 | dict of etree.XML string | xsltInjection.py:17:17:17:43 | etree.XML string | +| xsltInjection.py:17:17:17:43 | etree.XML string | xsltInjection.py:18:27:18:35 | etree.XML string | +| xsltInjection.py:17:17:17:43 | etree.XML string | xsltInjection.py:18:27:18:35 | etree.XML string | +| xsltInjection.py:18:17:18:36 | lxml etree xml | xsltInjection.py:21:29:21:37 | lxml etree xml | +| xsltInjection.py:18:17:18:36 | lxml etree xml | xsltInjection.py:21:29:21:37 | lxml etree xml | +| xsltInjection.py:18:27:18:35 | etree.XML string | xsltInjection.py:18:17:18:36 | lxml etree xml | +| xsltInjection.py:18:27:18:35 | etree.XML string | xsltInjection.py:18:17:18:36 | lxml etree xml | +| xsltInjection.py:26:17:26:28 | dict of etree.XML string | xsltInjection.py:26:17:26:43 | etree.XML string | +| xsltInjection.py:26:17:26:28 | dict of etree.XML string | xsltInjection.py:26:17:26:43 | etree.XML string | +| xsltInjection.py:26:17:26:43 | etree.XML string | xsltInjection.py:27:27:27:35 | etree.XML string | +| xsltInjection.py:26:17:26:43 | etree.XML string | xsltInjection.py:27:27:27:35 | etree.XML string | +| xsltInjection.py:27:17:27:36 | lxml etree xml | xsltInjection.py:31:24:31:32 | lxml etree xml | +| xsltInjection.py:27:17:27:36 | lxml etree xml | xsltInjection.py:31:24:31:32 | lxml etree xml | +| xsltInjection.py:27:27:27:35 | etree.XML string | xsltInjection.py:27:17:27:36 | lxml etree xml | +| xsltInjection.py:27:27:27:35 | etree.XML string | xsltInjection.py:27:17:27:36 | lxml etree xml | +| xsltInjection.py:35:17:35:28 | dict of etree.XML string | xsltInjection.py:35:17:35:43 | etree.XML string | +| xsltInjection.py:35:17:35:28 | dict of etree.XML string | xsltInjection.py:35:17:35:43 | etree.XML string | +| xsltInjection.py:35:17:35:43 | etree.XML string | xsltInjection.py:36:34:36:42 | etree.XML string | +| xsltInjection.py:35:17:35:43 | etree.XML string | xsltInjection.py:36:34:36:42 | etree.XML string | +| xsltInjection.py:36:17:36:43 | lxml etree xml | xsltInjection.py:40:24:40:32 | lxml etree xml | +| xsltInjection.py:36:17:36:43 | lxml etree xml | xsltInjection.py:40:24:40:32 | lxml etree xml | +| xsltInjection.py:36:34:36:42 | etree.XML string | xsltInjection.py:36:17:36:43 | lxml etree xml | +| xsltInjection.py:36:34:36:42 | etree.XML string | xsltInjection.py:36:17:36:43 | lxml etree xml | +#select +| xslt.py:14:29:14:37 | xslt_root | xslt.py:10:17:10:28 | dict of etree.XML string | xslt.py:14:29:14:37 | lxml etree xml | This XSLT query depends on $@. | xslt.py:10:17:10:28 | Attribute | a user-provided value | +| xsltInjection.py:12:28:12:36 | xslt_root | xsltInjection.py:10:17:10:28 | dict of etree.XML string | xsltInjection.py:12:28:12:36 | lxml etree xml | This XSLT query depends on $@. | xsltInjection.py:10:17:10:28 | Attribute | a user-provided value | +| xsltInjection.py:21:29:21:37 | xslt_root | xsltInjection.py:17:17:17:28 | dict of etree.XML string | xsltInjection.py:21:29:21:37 | lxml etree xml | This XSLT query depends on $@. | xsltInjection.py:17:17:17:28 | Attribute | a user-provided value | +| xsltInjection.py:31:24:31:32 | xslt_root | xsltInjection.py:26:17:26:28 | dict of etree.XML string | xsltInjection.py:31:24:31:32 | lxml etree xml | This XSLT query depends on $@. | xsltInjection.py:26:17:26:28 | Attribute | a user-provided value | +| xsltInjection.py:40:24:40:32 | xslt_root | xsltInjection.py:35:17:35:28 | dict of etree.XML string | xsltInjection.py:40:24:40:32 | lxml etree xml | This XSLT query depends on $@. | xsltInjection.py:35:17:35:28 | Attribute | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.qlref b/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.qlref new file mode 100644 index 00000000000..988d13e98a6 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-091/Xslt.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-091/Xslt.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091/XsltSinks.expected b/python/ql/test/experimental/query-tests/Security/CWE-091/XsltSinks.expected index dec055bc8e0..7150b3046e2 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-091/XsltSinks.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-091/XsltSinks.expected @@ -1,3 +1,4 @@ +| xslt.py:14:29:14:37 | lxml.etree.parse.xslt | lxml etree xml | | xsltInjection.py:12:28:12:36 | lxml.etree.XSLT | lxml etree xml | | xsltInjection.py:21:29:21:37 | lxml.etree.parse.xslt | lxml etree xml | | xsltInjection.py:31:24:31:32 | lxml.etree.parse.xslt | lxml etree xml | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091/xslt.py b/python/ql/test/experimental/query-tests/Security/CWE-091/xslt.py new file mode 100644 index 00000000000..1655916c7e0 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-091/xslt.py @@ -0,0 +1,14 @@ +from lxml import etree +from io import StringIO +from flask import Flask, request + +app = Flask(__name__) + + +@app.route("/xslt") +def bad(): + xsltQuery = request.args.get('xml', '') + xslt_root = etree.XML(xsltQuery) + f = StringIO('<foo><bar></bar></foo>') + tree = etree.parse(f) + result_tree = tree.xslt(xslt_root) # Not OK From 8663a8ba1c6db3e633a2e305d4563494bd15f906 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 14 Jun 2023 08:24:39 +0200 Subject: [PATCH 543/739] add change-note --- python/ql/lib/change-notes/2023-06-14-delete-deps.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/lib/change-notes/2023-06-14-delete-deps.md diff --git a/python/ql/lib/change-notes/2023-06-14-delete-deps.md b/python/ql/lib/change-notes/2023-06-14-delete-deps.md new file mode 100644 index 00000000000..16946163f5e --- /dev/null +++ b/python/ql/lib/change-notes/2023-06-14-delete-deps.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted many models that used the old dataflow library, the new models can be found in the `python/ql/lib/semmle/python/frameworks` folder. \ No newline at end of file From 686c35e210185a63c625ae27c546355f86777ba0 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Fri, 19 May 2023 17:18:07 +0200 Subject: [PATCH 544/739] Add autogenerated models --- .../ext/generated/jenkins-json-lib.model.yml | 602 ++ java/ql/lib/ext/generated/jenkins.model.yml | 8330 +++++++++++++++++ java/ql/lib/ext/generated/stapler.model.yml | 679 ++ 3 files changed, 9611 insertions(+) create mode 100644 java/ql/lib/ext/generated/jenkins-json-lib.model.yml create mode 100644 java/ql/lib/ext/generated/jenkins.model.yml create mode 100644 java/ql/lib/ext/generated/stapler.model.yml diff --git a/java/ql/lib/ext/generated/jenkins-json-lib.model.yml b/java/ql/lib/ext/generated/jenkins-json-lib.model.yml new file mode 100644 index 00000000000..61b41de6068 --- /dev/null +++ b/java/ql/lib/ext/generated/jenkins-json-lib.model.yml @@ -0,0 +1,602 @@ +# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. +# Definitions of models for the Jenkins JSON Lib framework. +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["net.sf.json.groovy", "JsonSlurper", true, "parse", "(String)", "", "Argument[0]", "open-url", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", true, "parse", "(URL)", "", "Argument[0]", "open-url", "df-generated"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["net.sf.json.filters", "AndPropertyFilter", true, "AndPropertyFilter", "(PropertyFilter,PropertyFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "AndPropertyFilter", true, "AndPropertyFilter", "(PropertyFilter,PropertyFilter)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "CompositePropertyFilter", true, "CompositePropertyFilter", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "CompositePropertyFilter", true, "addPropertyFilter", "(PropertyFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "MappingPropertyFilter", true, "MappingPropertyFilter", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "MappingPropertyFilter", true, "addPropertyFilter", "(Object,PropertyFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "MappingPropertyFilter", true, "addPropertyFilter", "(Object,PropertyFilter)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "NotPropertyFilter", true, "NotPropertyFilter", "(PropertyFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "OrPropertyFilter", true, "OrPropertyFilter", "(PropertyFilter,PropertyFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.filters", "OrPropertyFilter", true, "OrPropertyFilter", "(PropertyFilter,PropertyFilter)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.groovy", "JsonGroovyBuilder", true, "getJsonConfig", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.groovy", "JsonGroovyBuilder", true, "setJsonConfig", "(JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", true, "JsonSlurper", "(JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", true, "parse", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", true, "parse", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", true, "parseText", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.regexp", "RegexpMatcher", true, "getGroupIfMatches", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "JSONBuilder", "(Writer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "array", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "endArray", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "endObject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "key", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "object", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "value", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "value", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "value", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "value", "(boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "value", "(double)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONBuilder", true, "value", "(long)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONTokener", true, "JSONTokener", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.util", "JSONTokener", true, "next", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONTokener", true, "nextValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONTokener", true, "nextValue", "(JsonConfig)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONTokener", true, "nextValue", "(JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONTokener", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "convertToJavaIdentifier", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "convertToJavaIdentifier", "(String,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "getFunctionBody", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "getFunctionParams", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "getProperties", "(JSONObject)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "stripQuotes", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "valueToCanonicalString", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "valueToString", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JSONUtils", false, "valueToString", "(Object,int,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "JavaIdentifierTransformer", true, "transformToJavaIdentifier", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "PropertySetStrategy", true, "setProperty", "(Object,String,Object)", "", "Argument[1]", "Argument[0]", "taint", "df-generated"] + - ["net.sf.json.util", "PropertySetStrategy", true, "setProperty", "(Object,String,Object)", "", "Argument[2]", "Argument[0]", "taint", "df-generated"] + - ["net.sf.json.util", "PropertySetStrategy", true, "setProperty", "(Object,String,Object,JsonConfig)", "", "Argument[1]", "Argument[0]", "taint", "df-generated"] + - ["net.sf.json.util", "PropertySetStrategy", true, "setProperty", "(Object,String,Object,JsonConfig)", "", "Argument[2]", "Argument[0]", "taint", "df-generated"] + - ["net.sf.json.util", "WebHijackPreventionStrategy", true, "protect", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "WebUtils", true, "protect", "(JSON)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "WebUtils", true, "protect", "(JSON,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.util", "WebUtils", true, "toString", "(JSON)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "addNamespace", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "addNamespace", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "addNamespace", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "addNamespace", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "addNamespace", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "getArrayName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "getElementName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "getExpandableProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "getObjectName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "getRootName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setArrayName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setElementName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setExpandableProperties", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setNamespace", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setNamespace", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setNamespace", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setNamespace", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setNamespace", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setObjectName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", true, "setRootName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSON", true, "toString", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSON", true, "toString", "(int,int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSON", true, "write", "(Writer)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSON", true, "writeCanonical", "(Writer)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "add", "(Object,JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "add", "(int,Object,JsonConfig)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "addAll", "(Collection,JsonConfig)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "addAll", "(int,Collection,JsonConfig)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "discard", "(Object)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "discard", "(int)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Collection)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Collection,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Collection,JsonConfig)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(JSONNull)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(JSONNull)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(JSONObject)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(JSONObject)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Map)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Map,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Map,JsonConfig)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Object,JsonConfig)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Object,JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(Object,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(String,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(String,JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(double)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Collection)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Collection)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Collection,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Collection,JsonConfig)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Map)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Map)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Map,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Map,JsonConfig)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Object,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,Object,JsonConfig)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,String,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,String,JsonConfig)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,double)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(int,long)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "element", "(long)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "fromObject", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "fromObject", "(Object,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "getJSONArray", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "getJSONObject", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "getString", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "join", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "join", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "join", "(String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "join", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "opt", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "optJSONArray", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "optJSONObject", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "optString", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "optString", "(int,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "optString", "(int,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "set", "(int,Object,JsonConfig)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "set", "(int,Object,JsonConfig)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toCollection", "(JSONArray)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toCollection", "(JSONArray,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toCollection", "(JSONArray,JsonConfig)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toCollection", "(JSONArray,JsonConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toJSONObject", "(JSONArray)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toJSONObject", "(JSONArray)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toList", "(JSONArray)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toList", "(JSONArray,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toList", "(JSONArray,Class,Map)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toList", "(JSONArray,JsonConfig)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toList", "(JSONArray,JsonConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toList", "(JSONArray,Object,JsonConfig)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toList", "(JSONArray,Object,JsonConfig)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONArray", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONFunction", true, "JSONFunction", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONFunction", true, "JSONFunction", "(String[],String)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONFunction", true, "JSONFunction", "(String[],String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONFunction", true, "getParams", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONFunction", true, "getText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONFunction", true, "parse", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONFunction", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object,JsonConfig)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object,JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object,JsonConfig)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,Object,JsonConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,double)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,double)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,double)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,long)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,long)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulate", "(String,long)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulateAll", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "accumulateAll", "(Map,JsonConfig)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "discard", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection,JsonConfig)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection,JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection,JsonConfig)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Collection,JsonConfig)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map,JsonConfig)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map,JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map,JsonConfig)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Map,JsonConfig)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Object,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Object,JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,Object,JsonConfig)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,double)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,double)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,double)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,long)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,long)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "element", "(String,long)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "elementOpt", "(String,Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "elementOpt", "(String,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "elementOpt", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "elementOpt", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "elementOpt", "(String,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "elementOpt", "(String,Object,JsonConfig)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["net.sf.json", "JSONObject", false, "elementOpt", "(String,Object,JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "elementOpt", "(String,Object,JsonConfig)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "fromObject", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "fromObject", "(Object,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "fromObject", "(Object,JsonConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "get", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "getJSONArray", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "getJSONObject", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "getString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "keys", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "names", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "names", "(JsonConfig)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "opt", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "optJSONArray", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "optJSONObject", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "optString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "optString", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "optString", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "putAll", "(Map,JsonConfig)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "remove", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,Class,Map)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,JsonConfig)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,JsonConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,Object,JsonConfig)", "", "Argument[0].Element", "Argument[1]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,Object,JsonConfig)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,Object,JsonConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,Object,JsonConfig)", "", "Argument[2]", "Argument[1]", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toBean", "(JSONObject,Object,JsonConfig)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toJSONArray", "(JSONArray)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONObject", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONSerializer", true, "toJSON", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONSerializer", true, "toJSON", "(Object,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONSerializer", true, "toJSON", "(Object,JsonConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONSerializer", true, "toJava", "(JSON)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONSerializer", true, "toJava", "(JSON,JsonConfig)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JSONSerializer", true, "toJava", "(JSON,JsonConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "addIgnoreFieldAnnotation", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "addJsonEventListener", "(JsonEventListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "copy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "findDefaultValueProcessor", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "findJavaPropertyNameProcessor", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "findJsonBeanProcessor", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "findJsonPropertyNameProcessor", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "findJsonValueProcessor", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "findJsonValueProcessor", "(Class,Class,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "findJsonValueProcessor", "(Class,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "findPropertyNameProcessor", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getClassMap", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getCycleDetectionStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getDefaultValueProcessorMatcher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getExcludes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getIgnoreFieldAnnotations", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getJavaIdentifierTransformer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getJavaPropertyFilter", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getJavaPropertyNameProcessorMatcher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getJsonBeanProcessorMatcher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getJsonEventListeners", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getJsonPropertyFilter", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getJsonPropertyNameProcessorMatcher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getJsonValueProcessorMatcher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getMergedExcludes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getMergedExcludes", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getNewBeanInstanceStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getPropertyExclusionClassMatcher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getPropertyNameProcessorMatcher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "getPropertySetStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerDefaultValueProcessor", "(Class,DefaultValueProcessor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerJavaPropertyNameProcessor", "(Class,PropertyNameProcessor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerJsonBeanProcessor", "(Class,JsonBeanProcessor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerJsonPropertyNameProcessor", "(Class,PropertyNameProcessor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerJsonValueProcessor", "(Class,Class,JsonValueProcessor)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerJsonValueProcessor", "(Class,JsonValueProcessor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerJsonValueProcessor", "(Class,String,JsonValueProcessor)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerJsonValueProcessor", "(String,JsonValueProcessor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerJsonValueProcessor", "(String,JsonValueProcessor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "registerPropertyNameProcessor", "(Class,PropertyNameProcessor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setClassMap", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setCycleDetectionStrategy", "(CycleDetectionStrategy)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setDefaultValueProcessorMatcher", "(DefaultValueProcessorMatcher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setExcludes", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setJavaIdentifierTransformer", "(JavaIdentifierTransformer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setJavaPropertyFilter", "(PropertyFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setJavaPropertyNameProcessorMatcher", "(PropertyNameProcessorMatcher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setJsonBeanProcessorMatcher", "(JsonBeanProcessorMatcher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setJsonPropertyFilter", "(PropertyFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setJsonPropertyNameProcessorMatcher", "(PropertyNameProcessorMatcher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setJsonValueProcessorMatcher", "(JsonValueProcessorMatcher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setNewBeanInstanceStrategy", "(NewBeanInstanceStrategy)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setPropertyExclusionClassMatcher", "(PropertyExclusionClassMatcher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setPropertyNameProcessorMatcher", "(PropertyNameProcessorMatcher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["net.sf.json", "JsonConfig", true, "setPropertySetStrategy", "(PropertySetStrategy)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.util", "Collection<Object>", "isEmpty", "()", "summary", "df-generated"] + - ["java.util", "Collection<Object>", "size", "()", "summary", "df-generated"] + - ["java.util", "Map<String,Object>", "isEmpty", "()", "summary", "df-generated"] + - ["java.util", "Map<String,Object>", "size", "()", "summary", "df-generated"] + - ["net.sf.json.filters", "CompositePropertyFilter", "removePropertyFilter", "(PropertyFilter)", "summary", "df-generated"] + - ["net.sf.json.filters", "MappingPropertyFilter", "removePropertyFilter", "(Object)", "summary", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", "parse", "(File)", "summary", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", "parse", "(String)", "summary", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", "parse", "(URL)", "summary", "df-generated"] + - ["net.sf.json.processors", "DefaultValueProcessor", "getDefaultValue", "(Class)", "summary", "df-generated"] + - ["net.sf.json.processors", "DefaultValueProcessorMatcher", "getMatch", "(Class,Set)", "summary", "df-generated"] + - ["net.sf.json.processors", "JsonBeanProcessor", "processBean", "(Object,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json.processors", "JsonBeanProcessorMatcher", "getMatch", "(Class,Set)", "summary", "df-generated"] + - ["net.sf.json.processors", "JsonValueProcessor", "processArrayValue", "(Object,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json.processors", "JsonValueProcessor", "processObjectValue", "(String,Object,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json.processors", "JsonValueProcessorMatcher", "getMatch", "(Class,Set)", "summary", "df-generated"] + - ["net.sf.json.processors", "JsonVerifier", "isValidJsonValue", "(Object)", "summary", "df-generated"] + - ["net.sf.json.processors", "PropertyNameProcessorMatcher", "getMatch", "(Class,Set)", "summary", "df-generated"] + - ["net.sf.json.regexp", "JdkRegexpMatcher", "JdkRegexpMatcher", "(String)", "summary", "df-generated"] + - ["net.sf.json.regexp", "JdkRegexpMatcher", "JdkRegexpMatcher", "(String,boolean)", "summary", "df-generated"] + - ["net.sf.json.regexp", "Perl5RegexpMatcher", "Perl5RegexpMatcher", "(String)", "summary", "df-generated"] + - ["net.sf.json.regexp", "Perl5RegexpMatcher", "Perl5RegexpMatcher", "(String,boolean)", "summary", "df-generated"] + - ["net.sf.json.regexp", "RegexpMatcher", "getGroupIfMatches", "(String,int)", "summary", "df-generated"] + - ["net.sf.json.regexp", "RegexpMatcher", "matches", "(String)", "summary", "df-generated"] + - ["net.sf.json.regexp", "RegexpUtils", "getMatcher", "(String)", "summary", "df-generated"] + - ["net.sf.json.regexp", "RegexpUtils", "getMatcher", "(String,boolean)", "summary", "df-generated"] + - ["net.sf.json.regexp", "RegexpUtils", "isJDK13", "()", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(JSON,JSON)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(JSONArray,JSONArray)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(JSONArray,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(JSONFunction,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(JSONNull,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(JSONObject,JSONObject)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(JSONObject,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSON,JSON)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONArray)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONArray,JSONArray)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONArray,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONFunction)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONFunction,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONNull)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONNull,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONObject)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONObject,JSONObject)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,JSONObject,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,String,JSONArray)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,String,JSONFunction)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,String,JSONNull)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertEquals", "(String,String,JSONObject)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertJsonEquals", "(String,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertJsonEquals", "(String,String,String)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertNotNull", "(JSON)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertNotNull", "(String,JSON)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertNull", "(JSON)", "summary", "df-generated"] + - ["net.sf.json.test", "JSONAssert", "assertNull", "(String,JSON)", "summary", "df-generated"] + - ["net.sf.json.util", "CycleDetectionStrategy", "handleRepeatedReferenceAsArray", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "CycleDetectionStrategy", "handleRepeatedReferenceAsObject", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "EnumMorpher", "EnumMorpher", "(Class)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONStringer", "toString", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "back", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "dehexchar", "(char)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "length", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "matches", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "more", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "next", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "next", "(char)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "nextClean", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "nextString", "(char)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "nextTo", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "nextTo", "(char)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "peek", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "reset", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "skipPast", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "skipTo", "(char)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONTokener", "syntaxError", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "doubleToString", "(double)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "getInnerComponentType", "(Class)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "getMorpherRegistry", "()", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "getTypeClass", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "hasQuotes", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "hashCode", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isArray", "(Class)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isArray", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isBoolean", "(Class)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isBoolean", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isDouble", "(Class)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isFunction", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isFunctionHeader", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isJavaIdentifier", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isJsonKeyword", "(String,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isNull", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isNumber", "(Class)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isNumber", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isObject", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isString", "(Class)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "isString", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "mayBeJSON", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "newDynaBean", "(JSONObject)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "newDynaBean", "(JSONObject,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "numberToString", "(Number)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "quote", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "quoteCanonical", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "testValidity", "(Object)", "summary", "df-generated"] + - ["net.sf.json.util", "JSONUtils", "transformNumber", "(Number)", "summary", "df-generated"] + - ["net.sf.json.util", "JavaIdentifierTransformer", "transformToJavaIdentifier", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "NewBeanInstanceStrategy", "newInstance", "(Class,JSONObject)", "summary", "df-generated"] + - ["net.sf.json.util", "PropertyExclusionClassMatcher", "getMatch", "(Class,Set)", "summary", "df-generated"] + - ["net.sf.json.util", "PropertyFilter", "apply", "(Object,String,Object)", "summary", "df-generated"] + - ["net.sf.json.util", "PropertySetStrategy", "setProperty", "(Object,String,Object)", "summary", "df-generated"] + - ["net.sf.json.util", "WebHijackPreventionStrategy", "protect", "(String)", "summary", "df-generated"] + - ["net.sf.json.util", "WebUtils", "getWebHijackPreventionStrategy", "()", "summary", "df-generated"] + - ["net.sf.json.util", "WebUtils", "setWebHijackPreventionStrategy", "(WebHijackPreventionStrategy)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "clearNamespaces", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "clearNamespaces", "(String)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "isForceTopLevelObject", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "isNamespaceLenient", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "isRemoveNamespacePrefixFromElements", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "isSkipNamespaces", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "isSkipWhitespace", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "isTrimSpaces", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "isTypeHintsCompatibility", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "isTypeHintsEnabled", "()", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "read", "(String)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "readFromFile", "(File)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "readFromFile", "(String)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "readFromStream", "(InputStream)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "removeNamespace", "(String)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "removeNamespace", "(String,String)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "setForceTopLevelObject", "(boolean)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "setNamespaceLenient", "(boolean)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "setRemoveNamespacePrefixFromElements", "(boolean)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "setSkipNamespaces", "(boolean)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "setSkipWhitespace", "(boolean)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "setTrimSpaces", "(boolean)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "setTypeHintsCompatibility", "(boolean)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "setTypeHintsEnabled", "(boolean)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "write", "(JSON)", "summary", "df-generated"] + - ["net.sf.json.xml", "XMLSerializer", "write", "(JSON,String)", "summary", "df-generated"] + - ["net.sf.json", "JSON", "isArray", "()", "summary", "df-generated"] + - ["net.sf.json", "JSON", "isEmpty", "()", "summary", "df-generated"] + - ["net.sf.json", "JSON", "size", "()", "summary", "df-generated"] + - ["net.sf.json", "JSON", "toString", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSON", "toString", "(int,int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "contains", "(Object,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "containsAll", "(Collection,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "getBoolean", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "getCollectionType", "(PropertyDescriptor,boolean)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "getDimensions", "(JSONArray)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "getDouble", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "getInt", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "getLong", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "isExpandElements", "()", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "optBoolean", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "optBoolean", "(int,boolean)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "optDouble", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "optDouble", "(int,double)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "optInt", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "optInt", "(int,int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "optLong", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "optLong", "(int,long)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "removeAll", "(Collection,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "retainAll", "(Collection,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "setExpandElements", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "toArray", "(JSONArray)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "toArray", "(JSONArray,Class)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "toArray", "(JSONArray,Class,Map)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "toArray", "(JSONArray,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json", "JSONArray", "toArray", "(JSONArray,Object,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json", "JSONException", "JSONException", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONException", "JSONException", "(String,Throwable)", "summary", "df-generated"] + - ["net.sf.json", "JSONException", "JSONException", "(Throwable)", "summary", "df-generated"] + - ["net.sf.json", "JSONNull", "getInstance", "()", "summary", "df-generated"] + - ["net.sf.json", "JSONNull", "toString", "()", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "JSONObject", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "containsValue", "(Object,JsonConfig)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "getBoolean", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "getDouble", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "getInt", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "getLong", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "has", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "isNullObject", "()", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "optBoolean", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "optBoolean", "(String,boolean)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "optDouble", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "optDouble", "(String,double)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "optInt", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "optInt", "(String,int)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "optLong", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "optLong", "(String,long)", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "toBean", "()", "summary", "df-generated"] + - ["net.sf.json", "JSONObject", "toBean", "(JSONObject)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "addIgnoreFieldAnnotation", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "clearJavaPropertyNameProcessors", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "clearJsonBeanProcessors", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "clearJsonEventListeners", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "clearJsonPropertyNameProcessors", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "clearJsonValueProcessors", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "clearPropertyExclusions", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "clearPropertyNameProcessors", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "disableEventTriggering", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "enableEventTriggering", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "getArrayMode", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "getCollectionType", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "getEnclosedType", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "getRootClass", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isAllowNonStringKeys", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isEventTriggeringEnabled", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isHandleJettisonEmptyElement", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isHandleJettisonSingleElementArray", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isIgnoreDefaultExcludes", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isIgnoreJPATransient", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isIgnorePublicFields", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isIgnoreTransientFields", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isIgnoreUnreadableProperty", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isJavascriptCompliant", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "isSkipJavaIdentifierTransformationInMapKeys", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "registerPropertyExclusion", "(Class,String)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "registerPropertyExclusions", "(Class,String[])", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "removeIgnoreFieldAnnotation", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "removeIgnoreFieldAnnotation", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "removeJsonEventListener", "(JsonEventListener)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "reset", "()", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setAllowNonStringKeys", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setArrayMode", "(int)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setCollectionType", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setEnclosedType", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setHandleJettisonEmptyElement", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setHandleJettisonSingleElementArray", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setIgnoreDefaultExcludes", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setIgnoreJPATransient", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setIgnorePublicFields", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setIgnoreTransientFields", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setIgnoreUnreadableProperty", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setJavascriptCompliant", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setRootClass", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "setSkipJavaIdentifierTransformationInMapKeys", "(boolean)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterDefaultValueProcessor", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterJavaPropertyNameProcessor", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterJsonBeanProcessor", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterJsonPropertyNameProcessor", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterJsonValueProcessor", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterJsonValueProcessor", "(Class,Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterJsonValueProcessor", "(Class,String)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterJsonValueProcessor", "(String)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterPropertyExclusion", "(Class,String)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterPropertyExclusions", "(Class)", "summary", "df-generated"] + - ["net.sf.json", "JsonConfig", "unregisterPropertyNameProcessor", "(Class)", "summary", "df-generated"] diff --git a/java/ql/lib/ext/generated/jenkins.model.yml b/java/ql/lib/ext/generated/jenkins.model.yml new file mode 100644 index 00000000000..82202559350 --- /dev/null +++ b/java/ql/lib/ext/generated/jenkins.model.yml @@ -0,0 +1,8330 @@ +# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. +# Definitions of models for the Jenkins framework. +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["antlr", "ANTLRException", true, "ANTLRException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "BuildCommand$CLICause", true, "CLICause", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLICommand", true, "getTransportAuthentication2", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "CLICommand", true, "getTransportAuthentication", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "CLICommand", true, "main", "(List,Locale,InputStream,PrintStream,PrintStream)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLICommand", true, "main", "(List,Locale,InputStream,PrintStream,PrintStream)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLICommand", true, "main", "(List,Locale,InputStream,PrintStream,PrintStream)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLICommand", true, "main", "(List,Locale,InputStream,PrintStream,PrintStream)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLICommand", true, "setTransportAuth2", "(Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLICommand", true, "setTransportAuth", "(Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "authorization", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "authorization", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "basicAuth", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "basicAuth", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "basicAuth", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "basicAuth", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "basicAuth", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "basicAuth", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "basicAuth", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "basicAuth", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "bearerAuth", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "bearerAuth", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "CLIConnectionFactory", true, "bearerAuth", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "Connection", true, "Connection", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "Connection", true, "Connection", "(InputStream,OutputStream)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "Connection", true, "readByteArray", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "Connection", true, "readUTF", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "Connection", true, "writeByteArray", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "FullDuplexHttpStream", true, "FullDuplexHttpStream", "(URL,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.cli", "FullDuplexHttpStream", true, "getInputStream", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "FullDuplexHttpStream", true, "getOutputStream", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.cli", "PrivateKeyProvider", true, "getKeys", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "AnnotatedLargeText", true, "AnnotatedLargeText", "(ByteBuffer,Charset,boolean,Object)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "AnnotatedLargeText", true, "AnnotatedLargeText", "(File,Charset,boolean,Object)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "ConsoleAnnotationOutputStream", true, "ConsoleAnnotationOutputStream", "(Writer,ConsoleAnnotator,Object,Charset)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "ConsoleAnnotationOutputStream", true, "ConsoleAnnotationOutputStream", "(Writer,ConsoleAnnotator,Object,Charset)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "ConsoleAnnotationOutputStream", true, "ConsoleAnnotationOutputStream", "(Writer,ConsoleAnnotator,Object,Charset)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "ConsoleAnnotationOutputStream", true, "getConsoleAnnotator", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ConsoleAnnotator", true, "cast", "(ConsoleAnnotator)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ConsoleAnnotator", true, "combine", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ConsoleLogFilter", true, "decorateLogger", "(AbstractBuild,OutputStream)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ConsoleLogFilter", true, "decorateLogger", "(Computer,OutputStream)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ConsoleLogFilter", true, "decorateLogger", "(Run,OutputStream)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ConsoleNote", true, "removeNotes", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ConsoleNote", true, "removeNotes", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ExpandableDetailsNote", true, "ExpandableDetailsNote", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "ExpandableDetailsNote", true, "ExpandableDetailsNote", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "HyperlinkNote", true, "HyperlinkNote", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "HyperlinkNote", true, "encodeTo", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "ModelHyperlinkNote", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "encodeTo", "(Item)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "encodeTo", "(Item,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "encodeTo", "(Label)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "encodeTo", "(Node)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "encodeTo", "(Run)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "encodeTo", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "encodeTo", "(User)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "ModelHyperlinkNote", true, "encodeTo", "(User,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.console", "PlainTextConsoleOutputStream", true, "PlainTextConsoleOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.diagnosis", "HudsonHomeDiskUsageMonitor$Solution", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.diagnosis", "MemoryUsageMonitor$MemoryGroup", false, "doGraph", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.diagnosis", "NullIdDescriptorMonitor", true, "getProblems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor$VersionRange", true, "VersionRange", "(VersionRange,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor$VersionRange", true, "VersionRange", "(VersionRange,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor$VersionRange", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", true, "getData", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", true, "getVersionList", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.diagnosis", "ReverseProxySetupMonitor", true, "doTest", "(StaplerRequest,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.init", "InitializerFinder", true, "InitializerFinder", "(ClassLoader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.init", "TaskMethodFinder$TaskImpl", true, "getAnnotation", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.init", "TaskMethodFinder$TaskImpl", true, "getMethod", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.init", "TerminatorFinder", true, "TerminatorFinder", "(ClassLoader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.lifecycle", "RestartNotSupportedException", true, "RestartNotSupportedException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.lifecycle", "WindowsInstallerLink", true, "doDoInstall", "(StaplerRequest,StaplerResponse,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", false, "Target", "(String,Level)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", false, "Target", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", false, "Target", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", false, "getLogger", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder", true, "LogRecorder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder", true, "getAutoCompletionCandidates", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder", true, "getLoggers", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.logging", "LogRecorder", true, "setLoggers", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.logging", "LogRecorderManager", true, "getDynamic", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.logging", "LogRecorderManager", true, "getLogRecorder", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.logging", "LogRecorderManager", true, "getRecorders", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.logging", "LogRecorderManager", true, "setRecorders", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.logging", "WeakLogHandler", false, "WeakLogHandler", "(Handler,Logger)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelAtom", true, "LabelAtom", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelAtom", true, "get", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.labels", "LabelAtom", true, "getProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.labels", "LabelAtom", true, "setDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$And", false, "And", "(Label,Label)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$And", false, "And", "(Label,Label)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$Iff", false, "Iff", "(Label,Label)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$Iff", false, "Iff", "(Label,Label)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$Implies", false, "Implies", "(Label,Label)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$Implies", false, "Implies", "(Label,Label)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$Not", true, "Not", "(Label)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$Or", false, "Or", "(Label,Label)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$Or", false, "Or", "(Label,Label)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.labels", "LabelExpression$Paren", true, "Paren", "(Label)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage$BecauseLabelIsBusy", false, "BecauseLabelIsBusy", "(Label)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage$BecauseLabelIsOffline", false, "BecauseLabelIsOffline", "(Label)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage$BecauseNodeIsBusy", false, "BecauseNodeIsBusy", "(Node)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage$BecauseNodeIsNotAcceptingTasks", false, "BecauseNodeIsNotAcceptingTasks", "(Node)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage$BecauseNodeIsOffline", false, "BecauseNodeIsOffline", "(Node)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage", true, "createNeedsMoreExecutor", "(Localizable)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage", true, "getShortDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "Executables", true, "getParentOf", "(Executable)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "FutureImpl", false, "FutureImpl", "(Task)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$ExecutorChunk", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$ExecutorSlot", true, "getExecutor", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", false, "assign", "(int,ExecutorChunk)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", false, "assign", "(int,ExecutorChunk)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", false, "assigned", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", false, "toMap", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet", true, "MappingWorksheet", "(BuildableItem,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet", true, "MappingWorksheet", "(BuildableItem,List,Collection)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet", true, "executors", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet", true, "works", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", true, "created", "(WaitingItem)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", true, "existing", "(Item)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", true, "getCreateItem", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", true, "getItem", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "SubTask", true, "getAssignedLabel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "SubTask", true, "getOwnerTask", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "SubTask", true, "getSameNodeConstraint", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "SubTask", true, "getSameNodeConstraint", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model.queue", "Tasks", true, "getItemOf", "(SubTask)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "Tasks", true, "getOwnerTaskOf", "(SubTask)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "Tasks", true, "getSameNodeConstraintOf", "(SubTask)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "Tasks", true, "getSubTasksOf", "(Task)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnit", false, "getExecutable", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnit", false, "getExecutor", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnit", false, "setExecutable", "(Executable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnit", false, "setExecutor", "(Executor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnit", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", false, "WorkUnitContext", "(BuildableItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", false, "abort", "(Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", false, "createWorkUnit", "(SubTask)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", false, "createWorkUnit", "(SubTask)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", false, "getPrimaryWorkUnit", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", false, "getWorkUnits", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild$AbstractBuildExecution", true, "getLauncher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild$AbstractBuildExecution", true, "getListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild$DependencyChange", false, "DependencyChange", "(AbstractProject,int,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getBuiltOnStr", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getChangeSet", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getEnvironments", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getHudsonVersion", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getModuleRoot", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getModuleRoots", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getPersistentActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getProject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getRootBuild", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "AbstractBuild", true, "getWorkspace", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractCIBase", true, "getDisabledAdministrativeMonitors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractCIBase", true, "getNodes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractCIBase", true, "getQueue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractCIBase", true, "setDisabledAdministrativeMonitors", "(Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "doConfirmRename", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "doConfirmRename", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "getConfigFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "getDisplayNameOrNull", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "getRelativeDisplayNameFrom", "(ItemGroup)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "getRelativeNameFromGroup", "(ItemGroup)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "movedTo", "(DirectlyModifiableTopLevelItemGroup,AbstractItem,File)", "", "Argument[this]", "Argument[1]", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "movedTo", "(DirectlyModifiableTopLevelItemGroup,AbstractItem,File)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "renameTo", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "setDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "setDisplayName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "setDisplayNameOrNull", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractItem", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractProject$BecauseOfBuildInProgress", true, "BecauseOfBuildInProgress", "(AbstractBuild)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractProject$BecauseOfDownstreamBuildInProgress", true, "BecauseOfDownstreamBuildInProgress", "(AbstractProject)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractProject$BecauseOfUpstreamBuildInProgress", true, "BecauseOfUpstreamBuildInProgress", "(AbstractProject)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "addTrigger", "(Trigger)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "doWs", "(StaplerRequest,StaplerResponse)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "getAssignedLabelString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "getCustomWorkspace", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "getRelevantLabels", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "getRootProject", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "AbstractProject", true, "getScm", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "getScmCheckoutStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "getWorkspaceResource", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "setCustomWorkspace", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "setJDK", "(JDK)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "setScm", "(SCM)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AbstractProject", true, "setScmCheckoutStrategy", "(SCMCheckoutStrategy)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "addAction", "(Action)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "addAction", "(Action)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "addOrReplaceAction", "(Action)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "addOrReplaceAction", "(Action)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "getAction", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "getActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "getAllActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "getDynamic", "(String,StaplerRequest,StaplerResponse)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "replaceAction", "(Action)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.model", "Actionable", true, "replaceAction", "(Action)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AdministrativeMonitor", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "AllView", true, "AllView", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AllView", true, "AllView", "(String,ViewGroup)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AllView", true, "AllView", "(String,ViewGroup)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AllView", true, "migrateLegacyPrimaryAllViewLocalizedName", "(List,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Api", true, "Api", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AutoCompletionCandidates", true, "add", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "AutoCompletionCandidates", true, "add", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AutoCompletionCandidates", true, "add", "(String[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "AutoCompletionCandidates", true, "add", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "AutoCompletionCandidates", true, "getValues", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "BallColor", false, "anime", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "BallColor", false, "noAnime", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "BooleanParameterDefinition", true, "BooleanParameterDefinition", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "BooleanParameterDefinition", true, "BooleanParameterDefinition", "(String,boolean,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "BooleanParameterDefinition", true, "BooleanParameterDefinition", "(String,boolean,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "BooleanParameterValue", true, "BooleanParameterValue", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "BooleanParameterValue", true, "BooleanParameterValue", "(String,boolean,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "BooleanParameterValue", true, "BooleanParameterValue", "(String,boolean,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "BooleanParameterValue", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "BuildAuthorizationToken", false, "BuildAuthorizationToken", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "BuildAuthorizationToken", false, "getToken", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "BuildTimelineWidget", true, "BuildTimelineWidget", "(RunList)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "BuildTimelineWidget", true, "getFirstBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "BuildTimelineWidget", true, "getLastBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "BuildableItemWithBuildWrappers", true, "asProject", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "BuildableItemWithBuildWrappers", true, "getBuildWrappersList", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$RemoteCause", true, "RemoteCause", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause$RemoteCause", true, "RemoteCause", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause$RemoteCause", true, "getAddr", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$RemoteCause", true, "getNote", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause$ConverterImpl", true, "ConverterImpl", "(XStream2)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", true, "UpstreamCause", "(AbstractBuild)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", true, "UpstreamCause", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", true, "getUpstreamCauses", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", true, "getUpstreamProject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", true, "getUpstreamUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$UserCause", true, "getUserName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$UserIdCause", true, "UserIdCause", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause$UserIdCause", true, "getUserId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$UserIdCause", true, "getUserName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause$UserIdCause", true, "getUserUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Cause", true, "onAddedTo", "(AbstractBuild)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause", true, "onAddedTo", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause", true, "onLoad", "(AbstractBuild)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Cause", true, "onLoad", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CauseAction$ConverterImpl", true, "ConverterImpl", "(XStream2)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CauseAction", true, "CauseAction", "(Cause)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CauseAction", true, "CauseAction", "(CauseAction)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CauseAction", true, "CauseAction", "(Cause[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CauseAction", true, "CauseAction", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CauseAction", true, "getCauseCounts", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "CauseAction", true, "getCauses", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "CheckPoint", false, "CheckPoint", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CheckPoint", false, "CheckPoint", "(String,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CheckPoint", false, "CheckPoint", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "CheckPoint", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "ChoiceParameterDefinition", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "ChoiceParameterDefinition", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "ChoiceParameterDefinition", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "ChoiceParameterDefinition", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "ChoiceParameterDefinition", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "ChoiceParameterDefinition", "(String,String[],String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "ChoiceParameterDefinition", "(String,String[],String)", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "ChoiceParameterDefinition", "(String,String[],String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "getChoices", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "getChoicesText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", true, "setChoices", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Computer$DisplayExecutor", true, "DisplayExecutor", "(String,String,Executor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Computer$DisplayExecutor", true, "DisplayExecutor", "(String,String,Executor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Computer$DisplayExecutor", true, "DisplayExecutor", "(String,String,Executor)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Computer$DisplayExecutor", true, "getExecutor", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer$DisplayExecutor", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer$DisplayExecutor", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer$TerminationRequest", true, "TerminationRequest", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "cliDisconnect", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "cliOffline", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "connect", "(boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "disconnect", "(OfflineCause)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getAllExecutors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getChannel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getComputerPanelBoxs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getDisplayExecutors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getEnvVars", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getEnvironment", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getExecutors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getHeapDump", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getHostName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getLogFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getLogText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getOfflineCause", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getOneOffExecutors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getTerminatedBy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "getWorkspaceList", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Computer", true, "setTemporarilyOffline", "(boolean,OfflineCause)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ComputerPanelBox", true, "all", "(Computer)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ComputerPanelBox", true, "getComputer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ComputerPanelBox", true, "setComputer", "(Computer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ComputerSet", false, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph$Dependency", true, "Dependency", "(AbstractProject,AbstractProject)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph$Dependency", true, "Dependency", "(AbstractProject,AbstractProject)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph$Dependency", true, "getDownstreamProject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph$Dependency", true, "getUpstreamProject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph$Dependency", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "getComputationalData", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "getDownstream", "(AbstractProject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "getDownstreamDependencies", "(AbstractProject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "getTopologicallySorted", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "getTransitiveDownstream", "(AbstractProject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "getTransitiveUpstream", "(AbstractProject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "getUpstream", "(AbstractProject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "getUpstreamDependencies", "(AbstractProject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DependencyGraph", true, "putComputationalData", "(Class,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Descriptor$FormException", false, "FormException", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Descriptor$FormException", false, "FormException", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Descriptor$FormException", false, "FormException", "(String,Throwable,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Descriptor$FormException", false, "FormException", "(Throwable,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Descriptor$FormException", false, "getFormField", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "find", "(Collection,String)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "findByDescribableClassName", "(Collection,String)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "findById", "(Collection,String)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getCheckMethod", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getCheckMethod", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getCheckUrl", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getCheckUrl", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getGlobalPropertyType", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getHelpFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getHelpFile", "(Klass,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getHelpFile", "(Klass,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getHelpFile", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getHelpFile", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getPropertyType", "(Object,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getPropertyType", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "getPropertyTypeOrDie", "(Object,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "toArray", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "toList", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Descriptor", true, "toMap", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DescriptorVisibilityFilter", true, "apply", "(Object,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DescriptorVisibilityFilter", true, "applyType", "(Class,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DirectlyModifiableView", true, "add", "(TopLevelItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", false, "Path", "(String,String,boolean,long,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", false, "Path", "(String,String,boolean,long,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", false, "Path", "(String,String,boolean,long,boolean,long)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", false, "Path", "(String,String,boolean,long,boolean,long)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", false, "createNotReadableVersionOf", "(Path)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", false, "getHref", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", false, "getTitle", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,VirtualFile,String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,VirtualFile,String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,VirtualFile,String,String,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "DirectoryBrowserSupport", "(ModelObject,VirtualFile,String,String,boolean)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", false, "setIndexFileName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "Downloadable", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "Downloadable", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "Downloadable", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "Downloadable", "(String,String,long)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "Downloadable", "(String,String,long)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "getDataFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "getUrls", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", true, "reduce", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Environment", true, "buildEnvVars", "(Map)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.model", "EnvironmentContributingAction", true, "buildEnvVars", "(AbstractBuild,EnvVars)", "", "Argument[this]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.model", "EnvironmentContributingAction", true, "buildEnvironment", "(Run,EnvVars)", "", "Argument[this]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.model", "EnvironmentContributor", true, "buildEnvironmentFor", "(Job,EnvVars,TaskListener)", "", "Argument[0]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.model", "EnvironmentContributor", true, "buildEnvironmentFor", "(Run,EnvVars,TaskListener)", "", "Argument[0]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.model", "EnvironmentList", false, "EnvironmentList", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "Executor", "(Computer,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "abortResult", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "getAsynchronousExecution", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "getCausesOfInterruption", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "getCurrentExecutable", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "getCurrentExecutableForApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "getCurrentWorkUnit", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "getCurrentWorkspace", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "getOwner", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "interrupt", "(Result)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "interrupt", "(Result,CauseOfInterruption[])", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Executor", true, "interrupt", "(Result,CauseOfInterruption[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Failure", true, "Failure", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Failure", true, "Failure", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterDefinition", true, "FileParameterDefinition", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterDefinition", true, "FileParameterDefinition", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterDefinition", true, "FileParameterDefinition", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue$FileItemImpl", false, "FileItemImpl", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "FileParameterValue", "(String,File,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "FileParameterValue", "(String,File,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "FileParameterValue", "(String,File,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "FileParameterValue", "(String,FileItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "FileParameterValue", "(String,FileItem)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "doDynamic", "(StaplerRequest,StaplerResponse)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "getFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "getLocation", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "getOriginalFileName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FileParameterValue", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", true, "BuildPtr", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", true, "BuildPtr", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$RangeItem", false, "RangeItem", "(String,RangeSet)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$RangeItem", false, "RangeItem", "(String,RangeSet)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet$ConverterImpl", false, "ConverterImpl", "(Converter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", false, "add", "(RangeSet)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", false, "getRanges", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "Fingerprint", "(Run,String,byte[])", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "Fingerprint", "(Run,String,byte[])", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "Fingerprint", "(Run,String,byte[])", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "_getUsages", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "add", "(AbstractBuild)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "add", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "addFor", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getFacetBlockingDeletion", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getFileName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getHashString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getJobs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getOriginal", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getPersistedFacets", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getRangeSet", "(Job)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getRangeSet", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getTimestamp", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "getUsages", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "rename", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Fingerprint", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,byte[])", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,byte[])", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,byte[])", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,byte[])", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(AbstractBuild,String,byte[])", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(Run,String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(Run,String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(Run,String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(Run,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FingerprintMap", false, "getOrCreate", "(Run,String,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "FreeStyleBuild", true, "FreeStyleBuild", "(FreeStyleProject)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FreeStyleBuild", true, "FreeStyleBuild", "(FreeStyleProject,File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FreeStyleProject", true, "FreeStyleProject", "(ItemGroup,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FreeStyleProject", true, "FreeStyleProject", "(ItemGroup,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FreeStyleProject", true, "FreeStyleProject", "(Jenkins,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FreeStyleProject", true, "FreeStyleProject", "(Jenkins,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "FullDuplexHttpChannel", true, "getChannel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport$ConverterImpl", true, "ConverterImpl", "(XStream2)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "HealthReport", "(int,Localizable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "HealthReport", "(int,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "HealthReport", "(int,String,Localizable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "HealthReport", "(int,String,Localizable)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "HealthReport", "(int,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "HealthReport", "(int,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "getIconClassName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "getIconUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "getIconUrl", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "getIconUrl", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "getLocalizableDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "max", "(HealthReport,HealthReport)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "max", "(HealthReport,HealthReport)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "min", "(HealthReport,HealthReport)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "min", "(HealthReport,HealthReport)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "setDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "setIconUrl", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "HealthReport", true, "setLocalizibleDescription", "(Localizable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Hudson$CloudList", true, "CloudList", "(Jenkins)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "Hudson", "(File,ServletContext)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "Hudson", "(File,ServletContext)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "Hudson", "(File,ServletContext,PluginManager)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "Hudson", "(File,ServletContext,PluginManager)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "Hudson", "(File,ServletContext,PluginManager)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "getComputerListeners", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "getJob", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "getJobCaseInsensitive", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "getJobListeners", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "getSlave", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Hudson", true, "getSlaves", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getAbsoluteUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getAllJobs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getFullDisplayName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getFullName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getParent", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getRelativeNameFrom", "(Item)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getRelativeNameFrom", "(ItemGroup)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getShortUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Item", true, "onLoad", "(ItemGroup,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Item", true, "onLoad", "(ItemGroup,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ItemGroup", true, "allItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroup", true, "allItems", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroup", true, "allItems", "(Class,Predicate)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroup", true, "allItems", "(Class,Predicate)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroup", true, "getItems", "(Predicate)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroup", true, "getItemsStream", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroup", true, "getItemsStream", "(Predicate)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroupMixIn", true, "createProject", "(TopLevelItemDescriptor,String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroupMixIn", true, "createTopLevelItem", "(StaplerRequest,StaplerResponse)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemGroupMixIn", true, "loadChildren", "(ItemGroup,File,Function1)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ItemVisitor", true, "onItem", "(Item)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ItemVisitor", true, "onItemGroup", "(ItemGroup)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems2", "(Authentication,ItemGroup,Class)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems2", "(Authentication,ItemGroup,Class)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems2", "(Authentication,ItemGroup,Class,Predicate)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems2", "(Authentication,ItemGroup,Class,Predicate)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems2", "(Authentication,ItemGroup,Class,Predicate)", "", "Argument[3]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems", "(Authentication,ItemGroup,Class)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems", "(Authentication,ItemGroup,Class)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems", "(Authentication,ItemGroup,Class,Predicate)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems", "(Authentication,ItemGroup,Class,Predicate)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems", "(Authentication,ItemGroup,Class,Predicate)", "", "Argument[3]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems", "(ItemGroup,Class)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems", "(ItemGroup,Class,Predicate)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "allItems", "(ItemGroup,Class,Predicate)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "computeRelativeNamesAfterRenaming", "(String,String,String,ItemGroup)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "computeRelativeNamesAfterRenaming", "(String,String,String,ItemGroup)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "getCanonicalName", "(ItemGroup,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "getConfigFile", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "getConfigFile", "(Item)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "load", "(ItemGroup,File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "load", "(ItemGroup,File)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "move", "(AbstractItem,DirectlyModifiableTopLevelItemGroup)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.model", "Items", true, "move", "(AbstractItem,DirectlyModifiableTopLevelItemGroup)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "move", "(AbstractItem,DirectlyModifiableTopLevelItemGroup)", "", "Argument[1]", "Argument[0]", "taint", "df-generated"] + - ["hudson.model", "Items", true, "move", "(AbstractItem,DirectlyModifiableTopLevelItemGroup)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Items", true, "toNameList", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "JDK$ConverterImpl", true, "ConverterImpl", "(XStream2)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "JDK", false, "JDK", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "JDK", false, "JDK", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "JDK", false, "JDK", "(String,String,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "JDK", false, "JDK", "(String,String,List)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "JDK", false, "buildEnvVars", "(Map)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.model", "JDK", false, "getBinDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "JDK", false, "getJavaHome", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "addProperty", "(JobProperty)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getAllProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuild", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuildByNumber", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuildDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuildDiscarder", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuildForCLI", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuildHealth", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuildHealthReports", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuilds", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuilds", "(RangeSet)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuildsAsMap", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getBuildsByTimestamp", "(long,long)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getCharacteristicEnvVars", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getEnvironment", "(Node,TaskListener)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getFirstBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLastBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLastBuildsOverThreshold", "(int,Result)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLastCompletedBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLastFailedBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLastStableBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLastSuccessfulBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLastUnstableBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLastUnsuccessfulBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getLogRotator", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getNearestBuild", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getNearestOldBuild", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getNewBuilds", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getProperty", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getTimeline", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Job", true, "getWidgets", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "accept", "(LabelVisitor,Object)", "", "Argument[this]", "Argument[1]", "taint", "df-generated"] + - ["hudson.model", "Label", true, "and", "(Label)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "and", "(Label)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "get", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "getClouds", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "getExpression", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "getNodes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "getSortedNodes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "iff", "(Label)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "iff", "(Label)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "implies", "(Label)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "implies", "(Label)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "listAtoms", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "not", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "or", "(Label)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "or", "(Label)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "paren", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Label", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ListView", true, "ListView", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ListView", true, "ListView", "(String,ViewGroup)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ListView", true, "ListView", "(String,ViewGroup)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ListView", true, "getIncludeRegex", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ListView", true, "getJobFilters", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ListView", true, "getJobNames", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ListView", true, "setIncludeRegex", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ListView", true, "setJobNames", "(Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot$Builder", true, "with", "(Computer)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot$Builder", true, "with", "(Node)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot$Builder", true, "withQueueLength", "(int)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "LoadStatistics", true, "createTrendChart", "(TimeScale)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "LoadStatistics", true, "doGraph", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "LoadStatistics", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ModelObject", true, "getDisplayName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ModifiableViewGroup", true, "addView", "(View)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries$TrendChart", true, "TrendChart", "(TimeScale,MultiStageTimeSeries[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries", true, "MultiStageTimeSeries", "(Localizable,Color,float,float)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries", true, "MultiStageTimeSeries", "(Localizable,Color,float,float)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries", true, "createTrendChart", "(TimeScale,MultiStageTimeSeries[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries", true, "pick", "(TimeScale)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "MyView", true, "MyView", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "MyView", true, "MyView", "(String,ViewGroup)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "MyView", true, "MyView", "(String,ViewGroup)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "MyViewsProperty", true, "MyViewsProperty", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "MyViewsProperty", true, "getPrimaryViewName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "MyViewsProperty", true, "getUser", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "MyViewsProperty", true, "readResolve", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "MyViewsProperty", true, "setPrimaryViewName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "NoFingerprintMatch", true, "NoFingerprintMatch", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Node", true, "canTake", "(BuildableItem)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "createComputer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "createLauncher", "(TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "createPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getAssignedLabels", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getLabelString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getNodeDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getNodeName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getNodeProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getNodeProperty", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getSelfLabel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getTemporaryOfflineCause", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "getWorkspaceFor", "(TopLevelItem)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Node", true, "setLabelString", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Node", true, "setNodeName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "OneOffExecutor", true, "OneOffExecutor", "(Computer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PaneStatusProperties", true, "toggleCollapsed", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "copyWithDefaultValue", "(ParameterValue)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "createValue", "(CLICommand,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "createValue", "(CLICommand,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "createValue", "(StaplerRequest)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "createValue", "(StaplerRequest)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "createValue", "(StaplerRequest,JSONObject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "getDefaultParameterValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterDefinition", true, "setDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParameterValue", true, "buildEnvVars", "(AbstractBuild,EnvVars)", "", "Argument[this]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.model", "ParameterValue", true, "buildEnvVars", "(AbstractBuild,Map)", "", "Argument[this]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.model", "ParameterValue", true, "buildEnvironment", "(Run,EnvVars)", "", "Argument[this]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.model", "ParameterValue", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterValue", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterValue", true, "getShortDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterValue", true, "getValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParameterValue", true, "setDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "ParametersAction", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "ParametersAction", "(List,Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "ParametersAction", "(List,Collection)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "ParametersAction", "(ParameterValue[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "createUpdated", "(Collection)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "createUpdated", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "getAllParameters", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "getParameter", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "getParameters", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "merge", "(ParametersAction)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "merge", "(ParametersAction)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersAction", true, "substitute", "(AbstractBuild,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "ParametersDefinitionProperty", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "ParametersDefinitionProperty", "(ParameterDefinition[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "getJob", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "getJobActions", "(AbstractProject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "getOwner", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "getParameterDefinition", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "getParameterDefinitionNames", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "getParameterDefinitions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", true, "getProject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "PasswordParameterDefinition", "(String,Secret,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "PasswordParameterDefinition", "(String,Secret,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "PasswordParameterDefinition", "(String,Secret,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "PasswordParameterDefinition", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "PasswordParameterDefinition", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "PasswordParameterDefinition", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "getDefaultValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "getDefaultValueAsSecret", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterDefinition", true, "setDefaultValue", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterValue", true, "PasswordParameterValue", "(String,Secret,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterValue", true, "PasswordParameterValue", "(String,Secret,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterValue", true, "PasswordParameterValue", "(String,Secret,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterValue", true, "PasswordParameterValue", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterValue", true, "PasswordParameterValue", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterValue", true, "PasswordParameterValue", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterValue", true, "PasswordParameterValue", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PasswordParameterValue", true, "PasswordParameterValue", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "PermalinkProjectAction$Permalink", true, "resolve", "(Job)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "PersistenceRoot", true, "getRootDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Project", true, "addPublisher", "(Publisher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Project", true, "getBuildWrappers", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Project", true, "getBuildersList", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Project", true, "getPublisher", "(Descriptor)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Project", true, "getPublishers", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ProxyView", true, "ProxyView", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ProxyView", true, "getProxiedViewName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ProxyView", true, "setProxiedViewName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$BlockedItem", false, "BlockedItem", "(NotWaitingItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$BlockedItem", false, "BlockedItem", "(WaitingItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$BuildableItem", false, "BuildableItem", "(NotWaitingItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$BuildableItem", false, "BuildableItem", "(WaitingItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$Executable", true, "getParentExecutable", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Item", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Item", true, "getAssignedLabel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Item", true, "getAssignedLabelFor", "(SubTask)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Item", true, "getCauseOfBlockage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Item", true, "getFuture", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Item", true, "getWhy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Item", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$LeftItem", false, "LeftItem", "(Item)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$LeftItem", false, "LeftItem", "(WorkUnitContext)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$StubItem", true, "StubItem", "(StubTask)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$StubTask", true, "StubTask", "(Task)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$StubTask", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Task", true, "getAffinityKey", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Task", true, "getFullDisplayName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Task", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Task", true, "getSubTasks", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$Task", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue$WaitingItem", false, "WaitingItem", "(Calendar,Task,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$WaitingItem", false, "WaitingItem", "(Calendar,Task,List)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue$WaitingItem", false, "WaitingItem", "(Calendar,Task,List)", "", "Argument[2].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getBuildableItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getBuildableItems", "(Computer)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getItem", "(Task)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getItem", "(long)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getItems", "(Task)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getLeftItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getLoadBalancer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getPendingItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getSorter", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "getUnblockedItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule2", "(Task,int,Action[])", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule2", "(Task,int,Action[])", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule2", "(Task,int,List)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule2", "(Task,int,List)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule", "(AbstractProject)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule", "(Task,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule", "(Task,int,Action[])", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule", "(Task,int,Action[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule", "(Task,int,List)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "schedule", "(Task,int,List)", "", "Argument[2].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "scheduleMaintenance", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "setSorter", "(QueueSorter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "wrapWithLock", "(Callable)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Queue", true, "wrapWithLock", "(Runnable)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Resource", false, "Resource", "(Resource,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Resource", false, "Resource", "(Resource,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Resource", false, "Resource", "(Resource,String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Resource", false, "Resource", "(Resource,String,int)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Resource", false, "Resource", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Resource", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ResourceActivity", true, "getDisplayName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ResourceController", true, "getBlockingActivity", "(ResourceActivity)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ResourceList", false, "getConflict", "(ResourceList)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ResourceList", false, "getConflict", "(ResourceList)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ResourceList", false, "r", "(Resource)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "ResourceList", false, "r", "(Resource)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "ResourceList", false, "union", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ResourceList", false, "union", "(ResourceList[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ResourceList", false, "w", "(Resource)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "ResourceList", false, "w", "(Resource)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Result", false, "combine", "(Result)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "Result", false, "combine", "(Result,Result)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Result", false, "combine", "(Result,Result)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Result", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$Artifact", true, "getDisplayPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$Artifact", true, "getFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$Artifact", true, "getFileName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$Artifact", true, "getHref", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$Artifact", true, "getLength", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$Artifact", true, "getTreeNodeId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$Artifact", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$ArtifactList", false, "getTree", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$RunExecution", true, "getAttributes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run$Summary", true, "Summary", "(boolean,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Run", true, "doArtifact", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getArtifactManager", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getArtifactsDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getCharacteristicEnvVars", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getEnvVars", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getEnvironment", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getEnvironment", "(TaskListener)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getExternalizableId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getFullDisplayName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getLogFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getLogInputStream", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getLogReader", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getLogText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getNextBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getParent", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getPreviousBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getPreviousBuildInProgress", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getPreviousBuildsOverThreshold", "(int,Result)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getPreviousBuiltBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getPreviousCompletedBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getPreviousFailedBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getPreviousNotFailedBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getPreviousSuccessfulBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getResult", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getTruncatedDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "pickArtifactManager", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Run", true, "setDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Run", true, "setDisplayName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Run", true, "setResult", "(Result)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Run", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "RunMap", false, "RunMap", "(File,Constructor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunMap", false, "RunMap", "(File,Constructor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunMap", false, "getView", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "RunMap", false, "load", "(Job,Constructor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunMap", false, "load", "(Job,Constructor)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterDefinition", true, "RunParameterDefinition", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterDefinition", true, "RunParameterDefinition", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterDefinition", true, "RunParameterDefinition", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterDefinition", true, "RunParameterDefinition", "(String,String,String,RunParameterFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterDefinition", true, "RunParameterDefinition", "(String,String,String,RunParameterFilter)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterDefinition", true, "RunParameterDefinition", "(String,String,String,RunParameterFilter)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterDefinition", true, "getProjectName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "RunParameterValue", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "RunParameterValue", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "RunParameterValue", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "RunParameterValue", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "RunParameterValue", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "getJobName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "getNumber", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "getRunId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "RunParameterValue", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "SimpleParameterDefinition", true, "createValue", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "SimpleParameterDefinition", true, "createValue", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Slave$JnlpJar", false, "JnlpJar", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Slave", true, "getLauncher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Slave", true, "getRemoteFS", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Slave", true, "getRetentionStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Slave", true, "getUserId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "Slave", true, "setLauncher", "(ComputerLauncher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Slave", true, "setNodeDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Slave", true, "setRetentionStrategy", "(RetentionStrategy)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "Slave", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "StatusIcon", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "StatusIcon", true, "getImageOf", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "StatusIcon", true, "getImageOf", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "StockStatusIcon", false, "StockStatusIcon", "(String,Localizable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StockStatusIcon", false, "StockStatusIcon", "(String,Localizable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StreamBuildListener", true, "StreamBuildListener", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StreamBuildListener", true, "StreamBuildListener", "(OutputStream,Charset)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StreamBuildListener", true, "StreamBuildListener", "(PrintStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StreamBuildListener", true, "StreamBuildListener", "(PrintStream,Charset)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String,String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String,String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "StringParameterDefinition", "(String,String,String,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "getDefaultValue4Build", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "getDefaultValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "StringParameterDefinition", true, "setDefaultValue", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterValue", true, "StringParameterValue", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterValue", true, "StringParameterValue", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterValue", true, "StringParameterValue", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterValue", true, "StringParameterValue", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterValue", true, "StringParameterValue", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "StringParameterValue", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TaskAction", true, "getWorkerThread", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TaskListener", true, "getLogger", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TaskThread$ListenerAndText", false, "ListenerAndText", "(TaskListener,AnnotatedLargeText)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TaskThread$ListenerAndText", false, "ListenerAndText", "(TaskListener,AnnotatedLargeText)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TaskThread$ListenerAndText", false, "forFile", "(File,TaskAction)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TaskThread$ListenerAndText", false, "forMemory", "(TaskAction)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TextParameterDefinition", true, "TextParameterDefinition", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterDefinition", true, "TextParameterDefinition", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterDefinition", true, "TextParameterDefinition", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterDefinition", true, "TextParameterDefinition", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterValue", true, "TextParameterValue", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterValue", true, "TextParameterValue", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterValue", true, "TextParameterValue", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterValue", true, "TextParameterValue", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterValue", true, "TextParameterValue", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TextParameterValue", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TimeZoneProperty", true, "TimeZoneProperty", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TimeZoneProperty", true, "getTimeZoneName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TimeZoneProperty", true, "setTimeZoneName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", true, "getIconFilePath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", true, "newInstance", "(ItemGroup,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", true, "newInstance", "(ItemGroup,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", true, "newInstance", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$CompleteBatchJob", false, "CompleteBatchJob", "(List,long,UUID)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$CompleteBatchJob", false, "CompleteBatchJob", "(List,long,UUID)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$ConnectionCheckJob", false, "ConnectionCheckJob", "(UpdateSite)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$ConnectionCheckJob", false, "getStatuses", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob$Failure", true, "Failure", "(Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob$Failure", true, "getProblemStackTrace", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob$SuccessButRequiresRestart", true, "SuccessButRequiresRestart", "(Localizable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob", true, "getDisplayName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob", true, "getUser", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$EnableJob", true, "EnableJob", "(UpdateSite,Authentication,Plugin,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$EnableJob", true, "EnableJob", "(UpdateSite,Authentication,Plugin,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$EnableJob", true, "EnableJob", "(UpdateSite,Authentication,Plugin,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$EnableJob", true, "getPlugin", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$HudsonDowngradeJob", false, "HudsonDowngradeJob", "(UpdateSite,Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$HudsonDowngradeJob", false, "HudsonDowngradeJob", "(UpdateSite,Authentication)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$HudsonUpgradeJob", false, "HudsonUpgradeJob", "(UpdateSite,Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$HudsonUpgradeJob", false, "HudsonUpgradeJob", "(UpdateSite,Authentication)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$InstallationJob", true, "InstallationJob", "(Plugin,UpdateSite,Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$InstallationJob", true, "InstallationJob", "(Plugin,UpdateSite,Authentication)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$InstallationJob", true, "InstallationJob", "(Plugin,UpdateSite,Authentication)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$InstallationJob", true, "InstallationJob", "(Plugin,UpdateSite,Authentication,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$InstallationJob", true, "InstallationJob", "(Plugin,UpdateSite,Authentication,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$InstallationJob", true, "InstallationJob", "(Plugin,UpdateSite,Authentication,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$InstallationJob", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$NoOpJob", true, "NoOpJob", "(UpdateSite,Authentication,Plugin)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$NoOpJob", true, "NoOpJob", "(UpdateSite,Authentication,Plugin)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$NoOpJob", true, "NoOpJob", "(UpdateSite,Authentication,Plugin)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$PluginDowngradeJob", false, "PluginDowngradeJob", "(Plugin,UpdateSite,Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$PluginDowngradeJob", false, "PluginDowngradeJob", "(Plugin,UpdateSite,Authentication)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$PluginDowngradeJob", false, "PluginDowngradeJob", "(Plugin,UpdateSite,Authentication)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$PluginDowngradeJob", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$RestartJenkinsJob", true, "RestartJenkinsJob", "(UpdateSite)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterJob", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterJob", true, "getCorrelationId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterJob", true, "getError", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterJob", true, "getErrorMessage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterJob", true, "setCorrelationId", "(UUID)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$WithComputedChecksums", true, "getComputedSHA1", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$WithComputedChecksums", true, "getComputedSHA256", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter$WithComputedChecksums", true, "getComputedSHA512", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "addJob", "(UpdateCenterJob)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "configure", "(UpdateCenterConfiguration)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "createUpdateCenter", "(UpdateCenterConfiguration)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getById", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getCategoryDisplayName", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getCoreSource", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getHudsonJob", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getJob", "(Plugin)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getJob", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getJobs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getSite", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateCenter", true, "getSites", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Data", false, "getDeprecations", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Data", false, "getWarnings", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Deprecation", false, "Deprecation", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Entry", true, "Entry", "(String,JSONObject)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Entry", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Entry", true, "getSha1", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Entry", true, "getSha256", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Entry", true, "getSha512", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$IssueTracker", false, "IssueTracker", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$IssueTracker", false, "IssueTracker", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$IssueTracker", false, "IssueTracker", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", false, "Plugin", "(String,JSONObject)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", false, "getCategoriesStream", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", false, "getIncompatibleParentPlugins", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", false, "setIncompatibleParentPlugins", "(Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "UpdateSite", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "UpdateSite", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getAvailables", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getConnectionCheckUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getData", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getDownloadUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getMetadataUrlForDownloadable", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getMetadataUrlForDownloadable", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getPlugin", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UpdateSite", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UsageStatistics$CombinedCipherOutputStream", false, "CombinedCipherOutputStream", "(OutputStream,Cipher,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UsageStatistics$CombinedCipherOutputStream", false, "CombinedCipherOutputStream", "(OutputStream,RSAKey,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "UsageStatistics", true, "UsageStatistics", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "User$CanonicalIdResolver", true, "resolve", "(String,Map)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User$CanonicalIdResolver", true, "resolveCanonicalId", "(String,Map)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "addProperty", "(UserProperty)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.model", "User", true, "addProperty", "(UserProperty)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "User", true, "get", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "get", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "get", "(String,boolean,Map)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getAbsoluteUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getAllProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getById", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getDynamic", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getFullName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getOrCreateByIdOrFullName", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getPropertyActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "getUserDetailsForImpersonation2", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "User", true, "setDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "User", true, "setFullName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "User", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "UserIdMapper", true, "init", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View$AsynchPeople$People", false, "getUsers", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View$AsynchPeople", false, "AsynchPeople", "(Jenkins)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "View$AsynchPeople", false, "AsynchPeople", "(View)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "View$People", false, "People", "(Jenkins)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "View$People", false, "People", "(View)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "View$People", false, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View$PropertyList", true, "getOwner", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View$UserInfo", false, "getJob", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View$UserInfo", false, "getLastChange", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View$UserInfo", false, "getProject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View$UserInfo", false, "getUser", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "create", "(StaplerRequest,StaplerResponse,ViewGroup)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "createViewFromXML", "(String,InputStream)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getAbsoluteUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getAsynchPeople", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getColumns", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getDynamic", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getItem", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getJob", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getOwner", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getOwnerItemGroup", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getOwnerViewActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getPeople", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getViewName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "getViewUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "View", true, "setDescription", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.model", "View", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ViewGroup", true, "getItemGroup", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.model", "ViewGroup", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ViewGroup", true, "getViewActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ViewGroup", true, "getViewsTabBar", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.model", "ViewGroupMixIn", true, "addView", "(View)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.node_monitors", "AbstractNodeMonitorDescriptor", true, "get", "(Computer)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitor", true, "DiskSpaceMonitor", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitorDescriptor$DiskSpace", false, "DiskSpace", "(String,long)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitorDescriptor$DiskSpace", false, "getPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.node_monitors", "TemporarySpaceMonitor", true, "TemporarySpaceMonitor", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.os", "PosixException", true, "PosixException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.os", "PosixException", true, "PosixException", "(String,Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.os", "PosixException", true, "PosixException", "(String,Throwable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.os", "WindowsUtil", true, "createJunction", "(File,File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.os", "WindowsUtil", true, "quoteArgument", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.os", "WindowsUtil", true, "quoteArgumentForCmd", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "CronTab", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "CronTab", "(String,Hash)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "CronTab", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "CronTab", "(String,int,Hash)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "CronTab", "(String,int,Hash,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "CronTab", "(String,int,Hash,String)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "ceil", "(Calendar)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "floor", "(Calendar)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scheduler", "CronTab", false, "hashify", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scheduler", "CronTabList", false, "CronTabList", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.scheduler", "CronTabList", false, "getValidTimezone", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", true, "StartRuleContext", "(ParserRuleContext,int,CronTab)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scheduler", "CrontabParser", true, "startRule", "(CronTab)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm.browsers", "QueryBuilder", false, "QueryBuilder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scm.browsers", "QueryBuilder", false, "add", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.scm.browsers", "QueryBuilder", false, "add", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scm.browsers", "QueryBuilder", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "AbstractScmTagAction", true, "getBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "AbstractScmTagAction", true, "getRun", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "ChangeLogParser", true, "parse", "(AbstractBuild,File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "ChangeLogParser", true, "parse", "(Run,RepositoryBrowser,File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", true, "getParent", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "ChangeLogSet", true, "createEmpty", "(AbstractBuild)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "ChangeLogSet", true, "createEmpty", "(Run)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "ChangeLogSet", true, "getBrowser", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "ChangeLogSet", true, "getItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "ChangeLogSet", true, "getRun", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "EditType", false, "EditType", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scm", "EditType", false, "EditType", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scm", "EditType", false, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "EditType", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "PollingResult", false, "PollingResult", "(SCMRevisionState,SCMRevisionState,Change)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scm", "PollingResult", false, "PollingResult", "(SCMRevisionState,SCMRevisionState,Change)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.scm", "SCM", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "SCM", true, "getEffectiveBrowser", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "SCM", true, "getModuleRoot", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "SCM", true, "getModuleRoot", "(FilePath,AbstractBuild)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "SCM", true, "getModuleRoots", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.scm", "SCM", true, "getModuleRoots", "(FilePath,AbstractBuild)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "FixedSet", true, "FixedSet", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "FixedSet", true, "FixedSet", "(SearchItem[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "Search$Item", true, "Item", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "Search", true, "find", "(SearchIndex,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "Search", true, "find", "(SearchIndex,String,SearchableModelObject)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "SearchIndex", true, "find", "(String,List)", "", "Argument[this]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.search", "SearchIndex", true, "find", "(String,List)", "", "Argument[0]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.search", "SearchIndex", true, "suggest", "(String,List)", "", "Argument[this]", "Argument[1].Element", "taint", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(SearchIndex)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(SearchIndex)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(SearchIndexBuilder)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(SearchItem)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(SearchItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(String,SearchableModelObject,String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(String,SearchableModelObject,String[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(String,String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "add", "(String,String[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "addAllAnnotations", "(SearchableModelObject)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.search", "SearchIndexBuilder", false, "make", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "SearchItem", true, "getSearchName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "SearchItem", true, "getSearchUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "SuggestedItem", true, "SuggestedItem", "(SearchItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "SuggestedItem", true, "SuggestedItem", "(SuggestedItem,SearchItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "SuggestedItem", true, "SuggestedItem", "(SuggestedItem,SearchItem)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "SuggestedItem", true, "build", "(SearchableModelObject,SearchItem)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "SuggestedItem", true, "getPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "SuggestedItem", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.search", "UnionSearchIndex", true, "UnionSearchIndex", "(SearchIndex,SearchIndex)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "UnionSearchIndex", true, "UnionSearchIndex", "(SearchIndex,SearchIndex)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.search", "UnionSearchIndex", true, "combine", "(SearchIndex[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuerDescriptor", true, "getCrumbRequestField", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuerDescriptor", true, "getCrumbSalt", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuerDescriptor", true, "setCrumbRequestField", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuerDescriptor", true, "setCrumbSalt", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "ACLContext", true, "getPreviousContext2", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "AccessDeniedException2", true, "AccessDeniedException2", "(Authentication,Permission)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AccessDeniedException2", true, "AccessDeniedException2", "(Authentication,Permission)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AccessDeniedException2", true, "AccessDeniedException2", "(Throwable,Authentication,Permission)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AccessDeniedException2", true, "AccessDeniedException2", "(Throwable,Authentication,Permission)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AccessDeniedException3", true, "AccessDeniedException3", "(Authentication,Permission)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AccessDeniedException3", true, "AccessDeniedException3", "(Authentication,Permission)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AccessDeniedException3", true, "AccessDeniedException3", "(Throwable,Authentication,Permission)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AccessDeniedException3", true, "AccessDeniedException3", "(Throwable,Authentication,Permission)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AccountCreationFailedException", true, "AccountCreationFailedException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "AuthenticationManagerProxy", true, "setDelegate", "(AuthenticationManager)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "ChainedServletFilter", true, "ChainedServletFilter", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "ChainedServletFilter", true, "ChainedServletFilter", "(Filter[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "ChainedServletFilter", true, "setFilters", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "FederatedLoginService$UnclaimedIdentityException", true, "UnclaimedIdentityException", "(FederatedIdentity)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "FederatedLoginServiceUserProperty", true, "addIdentifier", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "FederatedLoginServiceUserProperty", true, "getIdentifiers", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "HudsonAuthenticationEntryPoint", true, "HudsonAuthenticationEntryPoint", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details$ConverterImpl", true, "ConverterImpl", "(XStream2)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", false, "getPassword", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", false, "getUsername", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", true, "HudsonPrivateSecurityRealm", "(boolean,boolean,CaptchaSupport)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", true, "createAccount", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", true, "createAccountWithHashedPassword", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", true, "getUser", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,PermissionScope)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,PermissionScope)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,PermissionScope)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,PermissionScope)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,PermissionScope)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,PermissionScope)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean,PermissionScope[])", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean,PermissionScope[])", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean,PermissionScope[])", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean,PermissionScope[])", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean,PermissionScope[])", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Localizable,Permission,boolean,PermissionScope[])", "", "Argument[5].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Permission)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Permission)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Permission)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "Permission", "(PermissionGroup,String,Permission)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "Permission", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "PermissionGroup", false, "PermissionGroup", "(Class,Localizable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "PermissionGroup", false, "PermissionGroup", "(String,Class,Localizable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "PermissionGroup", false, "PermissionGroup", "(String,Class,Localizable)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "PermissionGroup", false, "find", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "PermissionGroup", false, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "PermissionGroup", false, "getPermissions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "PermissionScope", false, "PermissionScope", "(Class,PermissionScope[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "RememberMeServicesProxy", true, "setDelegate", "(RememberMeServices)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm$SecurityComponents", false, "SecurityComponents", "(AuthenticationManager)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm$SecurityComponents", false, "SecurityComponents", "(AuthenticationManager,UserDetailsService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm$SecurityComponents", false, "SecurityComponents", "(AuthenticationManager,UserDetailsService)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm$SecurityComponents", false, "SecurityComponents", "(AuthenticationManager,UserDetailsService,RememberMeServices)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm$SecurityComponents", false, "SecurityComponents", "(AuthenticationManager,UserDetailsService,RememberMeServices)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm$SecurityComponents", false, "SecurityComponents", "(AuthenticationManager,UserDetailsService,RememberMeServices)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm", true, "createSecurityComponents", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm", true, "getCaptchaSupport", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm", true, "getSecurityComponents", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm", true, "loadUserByUsername2", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.security", "SecurityRealm", true, "setCaptchaSupport", "(CaptchaSupport)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SparseACL$Entry", false, "Entry", "(Sid,Permission,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SparseACL$Entry", false, "Entry", "(Sid,Permission,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SparseACL", true, "SparseACL", "(ACL)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "SparseACL", true, "add", "(Entry)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "UserDetailsServiceProxy", true, "setDelegate", "(UserDetailsService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "UserMayOrMayNotExistException", true, "UserMayOrMayNotExistException", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.security", "WhoAmI", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "AbstractCloudComputer", true, "AbstractCloudComputer", "(AbstractCloudSlave)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.slaves", "AbstractCloudComputer", true, "AbstractCloudComputer", "(AbstractCloudSlave)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "Cloud$CloudState", false, "CloudState", "(Label,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "Cloud$CloudState", false, "getLabel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "Cloud", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "ComputerLauncherFilter", true, "getCore", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "DelegatingComputerLauncher", true, "getLauncher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,ComputerLauncher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,ComputerLauncher)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,ComputerLauncher)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy)", "", "Argument[5]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy)", "", "Argument[6]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy)", "", "Argument[7]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy,List)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy,List)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy,List)", "", "Argument[5]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy,List)", "", "Argument[6]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "DumbSlave", false, "DumbSlave", "(String,String,String,String,Mode,String,ComputerLauncher,RetentionStrategy,List)", "", "Argument[7]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "EnvironmentVariablesNodeProperty$Entry", true, "Entry", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "EnvironmentVariablesNodeProperty$Entry", true, "Entry", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "EnvironmentVariablesNodeProperty", true, "EnvironmentVariablesNodeProperty", "(Entry[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "EnvironmentVariablesNodeProperty", true, "EnvironmentVariablesNodeProperty", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "EnvironmentVariablesNodeProperty", true, "getEnv", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "EnvironmentVariablesNodeProperty", true, "getEnvVars", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", true, "JNLPLauncher", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", true, "JNLPLauncher", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", true, "JNLPLauncher", "(String,String,RemotingWorkDirSettings)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", true, "JNLPLauncher", "(String,String,RemotingWorkDirSettings)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", true, "getWorkDirOptions", "(Computer)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", true, "getWorkDirSettings", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", true, "setWorkDirSettings", "(RemotingWorkDirSettings)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "NodeList", false, "NodeList", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "NodeList", false, "NodeList", "(Node[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "NodeList", false, "getNode", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$PlannedNode", true, "PlannedNode", "(String,Future,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$PlannedNode", true, "PlannedNode", "(String,Future,int)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", false, "getLabel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", false, "getSnapshot", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "NodeProvisioner", true, "NodeProvisioner", "(Label,LoadStatistics)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "NodeProvisioner", true, "NodeProvisioner", "(Label,LoadStatistics)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "NodeProvisioner", true, "getPendingLaunches", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "OfflineCause$ByCLI", true, "ByCLI", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "OfflineCause$ChannelTermination", true, "ChannelTermination", "(Exception)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "OfflineCause$SimpleOfflineCause", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "OfflineCause$UserCause", true, "UserCause", "(User,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "OfflineCause$UserCause", true, "getUser", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "OfflineCause", true, "create", "(Localizable)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SimpleScheduledRetentionStrategy", true, "SimpleScheduledRetentionStrategy", "(String,int,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "SimpleScheduledRetentionStrategy", true, "getStartTimeSpec", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "SlaveComputer", "(Slave)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "SlaveComputer", "(Slave)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "doJenkinsAgentJnlp", "(StaplerRequest,StaplerResponse)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "doSlaveAgentJnlp", "(StaplerRequest,StaplerResponse)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "getAbsoluteRemoteFs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "getAbsoluteRemotePath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "getDelegatedLauncher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "getJnlpJars", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "getLauncher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "getListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "openLogFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "SlaveComputer", true, "setChannel", "(Channel,OutputStream,Listener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList$Entry", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList$Lease", true, "createDummyLease", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList$Lease", true, "createLinkedDummyLease", "(FilePath,Lease)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "acquire", "(FilePath)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "acquire", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "acquire", "(FilePath,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "acquire", "(FilePath,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "acquire", "(FilePath,boolean,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "acquire", "(FilePath,boolean,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "allocate", "(FilePath)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "allocate", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "allocate", "(FilePath,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "allocate", "(FilePath,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "record", "(FilePath)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "record", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.slaves", "WorkspaceList", false, "tempDir", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks._maven", "MavenConsoleAnnotator", true, "MavenConsoleAnnotator", "(OutputStream,Charset)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String,String,boolean,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String,String,boolean,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String,String,boolean,boolean,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String,String,boolean,boolean,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String,String,boolean,boolean,boolean,Boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "ArtifactArchiver", "(String,String,boolean,boolean,boolean,Boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "getArtifacts", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "getExcludes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", true, "setExcludes", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BatchFile", true, "BatchFile", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BatchFile", true, "setConfiguredLocalRules", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildStep$PublisherList", false, "addNotifier", "(Descriptor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildStep$PublisherList", false, "addRecorder", "(Descriptor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildStep", true, "getProjectActions", "(AbstractProject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "BuildStepDescriptor", true, "filter", "(List,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "BuildTrigger", "(Collection,Result)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "BuildTrigger", "(Collection,Result)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "BuildTrigger", "(List,Result)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "BuildTrigger", "(List,Result)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "BuildTrigger", "(String,Result)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "BuildTrigger", "(String,Result)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "BuildTrigger", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "BuildTrigger", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "getChildProjectsValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "getThreshold", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "BuildTrigger", true, "onJobRenamed", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "BuildWrapper", true, "decorateLauncher", "(AbstractBuild,Launcher,BuildListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "BuildWrapper", true, "decorateLogger", "(AbstractBuild,OutputStream)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "BuildWrapper", true, "setUp", "(AbstractBuild,Launcher,BuildListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "BuildWrapper", true, "setUp", "(Build,Launcher,BuildListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "CommandInterpreter", true, "buildCommandLine", "(FilePath)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "CommandInterpreter", true, "buildCommandLine", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "CommandInterpreter", true, "createScriptFile", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "CommandInterpreter", true, "getCommand", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "CommandInterpreter", true, "getConfiguredLocalRules", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", false, "FingerprintAction", "(AbstractBuild,Map)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", false, "FingerprintAction", "(Run,Map)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", false, "getBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", false, "getFingerprints", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", false, "getRecords", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", false, "getRun", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter", true, "Fingerprinter", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter", true, "Fingerprinter", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter", true, "getExcludes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter", true, "getTargets", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Fingerprinter", true, "setExcludes", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "LogRotator$CollatedLogRotatorException", true, "CollatedLogRotatorException", "(String,Collection)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "LogRotator$CollatedLogRotatorException", true, "CollatedLogRotatorException", "(String,Collection)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "LogRotator$CollatedLogRotatorException", true, "CollatedLogRotatorException", "(String,Exception[])", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "LogRotator$CollatedLogRotatorException", true, "CollatedLogRotatorException", "(String,Exception[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven$DescriptorImpl", false, "getInstallations", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation$ConverterImpl", true, "ConverterImpl", "(XStream2)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", false, "MavenInstallation", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", false, "MavenInstallation", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", false, "MavenInstallation", "(String,String,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", false, "MavenInstallation", "(String,String,List)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", false, "getHomeDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", false, "getMavenHome", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstaller", true, "MavenInstaller", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider)", "", "Argument[6]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider)", "", "Argument[7]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider,boolean)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider,boolean)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider,boolean)", "", "Argument[6]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "Maven", "(String,String,String,String,String,boolean,SettingsProvider,GlobalSettingsProvider,boolean)", "", "Argument[7]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "getGlobalSettings", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "getSettings", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Maven", true, "getTargets", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Publisher$DescriptorExtensionListImpl", false, "DescriptorExtensionListImpl", "(Jenkins)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Shell$DescriptorImpl", true, "getShell", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Shell$DescriptorImpl", true, "getShellOrDefault", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Shell$DescriptorImpl", true, "getShellOrDefault", "(VirtualChannel)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tasks", "Shell$DescriptorImpl", true, "setShell", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Shell", true, "Shell", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tasks", "Shell", true, "setConfiguredLocalRules", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "AbstractCommandInstaller", true, "getCommand", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "AbstractCommandInstaller", true, "getCommandCall", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "AbstractCommandInstaller", true, "getToolHome", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "BatchCommandInstaller", true, "BatchCommandInstaller", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "BatchCommandInstaller", true, "BatchCommandInstaller", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "BatchCommandInstaller", true, "BatchCommandInstaller", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "CommandInstaller", true, "CommandInstaller", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "CommandInstaller", true, "CommandInstaller", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "CommandInstaller", true, "CommandInstaller", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "PropertyDescriptor", true, "for_", "(List,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "PropertyDescriptor", true, "for_", "(List,Object)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolDescriptor", true, "getInstallations", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolDescriptor", true, "setInstallations", "(ToolInstallation[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "buildEnvVars", "(EnvVars)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "getHome", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "getProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "translate", "(AbstractBuild,TaskListener)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "translate", "(AbstractBuild,TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "translate", "(Node,EnvVars,TaskListener)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstallation", true, "translate", "(Node,EnvVars,TaskListener)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstaller$ToolInstallerEntry", false, "ToolInstallerEntry", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolInstaller$ToolInstallerEntry", false, "ToolInstallerEntry", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolInstaller$ToolInstallerEntry", false, "ToolInstallerEntry", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolInstaller", true, "getLabel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstaller", true, "performInstallation", "(ToolInstallation,Node,TaskListener)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolInstaller", true, "performInstallation", "(ToolInstallation,Node,TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$DescriptorImpl", true, "getKey", "(ToolInstallation)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "ToolLocation", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "ToolLocation", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "ToolLocation", "(ToolDescriptor,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "ToolLocation", "(ToolDescriptor,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "ToolLocation", "(ToolDescriptor,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "getHome", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "getKey", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$ToolLocation", false, "getType", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty", true, "ToolLocationNodeProperty", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty", true, "ToolLocationNodeProperty", "(ToolLocation[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty", true, "getHome", "(ToolInstallation)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty", true, "getLocations", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty", true, "getToolHome", "(Node,ToolInstallation,TaskListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ToolLocationTranslator", true, "getToolHome", "(Node,ToolInstallation,TaskListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ZipExtractionInstaller", true, "ZipExtractionInstaller", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ZipExtractionInstaller", true, "ZipExtractionInstaller", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ZipExtractionInstaller", true, "ZipExtractionInstaller", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.tools", "ZipExtractionInstaller", true, "getSubdir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.tools", "ZipExtractionInstaller", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger$BuildAction", true, "BuildAction", "(AbstractBuild)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger$BuildAction", true, "BuildAction", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger$BuildAction", true, "getPollingLogText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger$BuildAction", true, "getRun", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", true, "getExecutor", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger$Runner", true, "Runner", "(Action[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger$SCMTriggerCause", true, "SCMTriggerCause", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger$SCMTriggerCause", true, "getRun", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger", true, "SCMTrigger", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger", true, "SCMTrigger", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger", true, "getLogFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "SCMTrigger", true, "getScmpoll_spec", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor$Value", true, "getFullJobName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor", true, "getErrors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "TimerTrigger", true, "TimerTrigger", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.triggers", "Trigger", true, "getSpec", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.triggers", "Trigger", true, "start", "(Item,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util.io", "ArchiverFactory", true, "create", "(OutputStream)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util.io", "ArchiverFactory", true, "createZipWithoutSymlink", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util.io", "ReopenableFileOutputStream", true, "ReopenableFileOutputStream", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util.io", "ReopenableRotatingFileOutputStream", true, "ReopenableRotatingFileOutputStream", "(File,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util.io", "RewindableFileOutputStream", true, "RewindableFileOutputStream", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util.io", "RewindableRotatingFileOutputStream", true, "RewindableRotatingFileOutputStream", "(File,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util.jna", "RegistryKey", true, "open", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util.jna", "RegistryKey", true, "open", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util.jna", "RegistryKey", true, "open", "(String,int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util.jna", "RegistryKey", true, "open", "(String,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util.jna", "RegistryKey", true, "openReadonly", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util.jna", "RegistryKey", true, "openReadonly", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util.jna", "SHELLEXECUTEINFO$DUMMYUNIONNAME_union", true, "DUMMYUNIONNAME_union", "(Pointer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util.jna", "WinIOException", true, "WinIOException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util.jna", "WinIOException", true, "WinIOException", "(String,Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util.xstream", "MapperDelegate", true, "MapperDelegate", "(Mapper)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AWTProblem", true, "AWTProblem", "(Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AdministrativeError", true, "AdministrativeError", "(String,String,String,Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AdministrativeError", true, "AdministrativeError", "(String,String,String,Throwable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AdministrativeError", true, "AdministrativeError", "(String,String,String,Throwable)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AdministrativeError", true, "AdministrativeError", "(String,String,String,Throwable)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AlternativeUiTextProvider$Message", false, "cast", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "AlternativeUiTextProvider", true, "get", "(Message,Object,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "ArgumentListBuilder", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(File)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(Iterable)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(Iterable)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(Object,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(String,boolean)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(String[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "add", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePair", "(String,String,String,boolean)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePair", "(String,String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePair", "(String,String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePair", "(String,String,String,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairs", "(String,Map)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairs", "(String,Map)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairs", "(String,Map)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairs", "(String,Map,Set)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairs", "(String,Map,Set)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairs", "(String,Map,Set)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairsFromPropertyString", "(String,String,VariableResolver)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairsFromPropertyString", "(String,String,VariableResolver)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairsFromPropertyString", "(String,String,VariableResolver)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairsFromPropertyString", "(String,String,VariableResolver,Set)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addKeyValuePairsFromPropertyString", "(String,String,VariableResolver,Set)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addMasked", "(Secret)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addMasked", "(Secret)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addMasked", "(Secret)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addMasked", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addQuoted", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addQuoted", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addQuoted", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addQuoted", "(String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addQuoted", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addQuoted", "(String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addTokenized", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "addTokenized", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "prepend", "(String[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "prepend", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "toCommandArray", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "toList", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", true, "toStringWithQuote", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "AtomicFileWriter", true, "AtomicFileWriter", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AtomicFileWriter", true, "AtomicFileWriter", "(File,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AtomicFileWriter", true, "AtomicFileWriter", "(Path,Charset)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AtomicFileWriter", true, "AtomicFileWriter", "(Path,Charset,boolean,boolean)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "AtomicFileWriter", true, "getTemporaryFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "AtomicFileWriter", true, "getTemporaryPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "BootFailure", true, "getBootFailureFile", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ByteArrayOutputStream2", true, "getBuffer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ByteArrayOutputStream2", true, "readFrom", "(InputStream)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson.util", "ByteArrayOutputStream2", true, "readFrom", "(InputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ChartUtil$NumberOnlyBuildLabel", false, "NumberOnlyBuildLabel", "(AbstractBuild)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ChartUtil$NumberOnlyBuildLabel", false, "NumberOnlyBuildLabel", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ChartUtil$NumberOnlyBuildLabel", false, "getRun", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ChartUtil$NumberOnlyBuildLabel", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ChunkedInputStream", true, "ChunkedInputStream", "(InputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ChunkedOutputStream", true, "ChunkedOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ChunkedOutputStream", true, "ChunkedOutputStream", "(OutputStream,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ClassLoaderSanityThreadFactory", true, "ClassLoaderSanityThreadFactory", "(ThreadFactory)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "add", "(File)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "add", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "add", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "add", "(FilePath)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "add", "(FilePath)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "add", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "add", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "add", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "addAll", "(FilePath,String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "addJarOf", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ClasspathBuilder", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ComboBoxModel", true, "ComboBoxModel", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ComboBoxModel", true, "ComboBoxModel", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CompoundEnumeration", true, "CompoundEnumeration", "(Enumeration[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CompoundEnumeration", true, "CompoundEnumeration", "(Iterable)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CompressedFile", true, "CompressedFile", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "ConsistentHash", "(Hash)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "ConsistentHash", "(Hash,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "add", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "add", "(Object,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "addAll", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "addAll", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "addAll", "(Object[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "lookup", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "lookup", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ConsistentHash", true, "remove", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "CopyOnWriteList", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "add", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "addAll", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "addAllTo", "(Collection)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "get", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "getView", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "replaceBy", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "replaceBy", "(CopyOnWriteList)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "replaceBy", "(Object[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "toArray", "(Object[])", "", "Argument[this]", "Argument[0].ArrayElement", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteList", true, "toArray", "(Object[])", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteMap$Hash", false, "Hash", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteMap$Tree", false, "Tree", "(Comparator)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteMap$Tree", false, "Tree", "(Map,Comparator)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteMap$Tree", false, "Tree", "(Map,Comparator)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CopyOnWriteMap", true, "replaceBy", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CyclicGraphDetector$CycleDetectedException", false, "CycleDetectedException", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "CyclicGraphDetector", true, "getSorted", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "CyclicGraphDetector", true, "run", "(Iterable)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DaemonThreadFactory", true, "DaemonThreadFactory", "(ThreadFactory)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DataSetBuilder", false, "add", "(Number,Comparable,Comparable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DataSetBuilder", false, "add", "(Number,Comparable,Comparable)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DecodingStream", true, "DecodingStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "DescribableList", "(Owner)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "DescribableList", "(Saveable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "DescribableList", "(Saveable,Collection)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "get", "(Descriptor)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "getDynamic", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "setOwner", "(Owner)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "toArray", "(Describable[])", "", "Argument[this]", "Argument[0].ArrayElement", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "toArray", "(Describable[])", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "DescribableList", true, "toMap", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "DescriptorList", false, "find", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "DescriptorList", false, "findByName", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "DirScanner$Filter", true, "Filter", "(FileFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DirScanner$Glob", true, "Glob", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DirScanner$Glob", true, "Glob", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DirScanner$Glob", true, "Glob", "(String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DirScanner$Glob", true, "Glob", "(String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DirScanner$Glob", true, "Glob", "(String,String,boolean,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DirScanner$Glob", true, "Glob", "(String,String,boolean,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DoubleLaunchChecker", true, "getCollidingId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "DualOutputStream", true, "DualOutputStream", "(OutputStream,OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "DualOutputStream", true, "DualOutputStream", "(OutputStream,OutputStream)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "EditDistance", true, "findNearest", "(String,Collection)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "EditDistance", true, "findNearest", "(String,String[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "EncodingStream", true, "EncodingStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ErrorObject", true, "getStackTraceString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ExceptionCatchingThreadFactory", true, "ExceptionCatchingThreadFactory", "(ThreadFactory)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FileVisitor", true, "with", "(FileFilter)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "FlushProofOutputStream", true, "FlushProofOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ForkOutputStream", true, "ForkOutputStream", "(OutputStream,OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ForkOutputStream", true, "ForkOutputStream", "(OutputStream,OutputStream)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$Base64", true, "Base64", "(StaplerRequest,StaplerResponse,boolean,boolean,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$Base64", true, "Base64", "(StaplerRequest,StaplerResponse,boolean,boolean,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$Base64", true, "Base64", "(StaplerRequest,StaplerResponse,boolean,boolean,String)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$Executable", true, "Executable", "(StaplerRequest,StaplerResponse)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$Executable", true, "Executable", "(StaplerRequest,StaplerResponse)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$HudsonURL", true, "HudsonURL", "(StaplerRequest,StaplerResponse)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$HudsonURL", true, "HudsonURL", "(StaplerRequest,StaplerResponse)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceDirectory", true, "WorkspaceDirectory", "(StaplerRequest,StaplerResponse)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceDirectory", true, "WorkspaceDirectory", "(StaplerRequest,StaplerResponse)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceDirectory", true, "WorkspaceDirectory", "(StaplerRequest,StaplerResponse,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceDirectory", true, "WorkspaceDirectory", "(StaplerRequest,StaplerResponse,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceFileMask", true, "WorkspaceFileMask", "(StaplerRequest,StaplerResponse)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceFileMask", true, "WorkspaceFileMask", "(StaplerRequest,StaplerResponse)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceFileMask", true, "WorkspaceFileMask", "(StaplerRequest,StaplerResponse,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceFileMask", true, "WorkspaceFileMask", "(StaplerRequest,StaplerResponse,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceFilePath", true, "WorkspaceFilePath", "(StaplerRequest,StaplerResponse,boolean,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFieldValidator$WorkspaceFilePath", true, "WorkspaceFilePath", "(StaplerRequest,StaplerResponse,boolean,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormFillFailure", true, "errorWithMarkup", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "FormFillFailure", true, "warningWithMarkup", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "FormFillFailure", true, "withSelectionCleared", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "FormValidation$CheckMethod", true, "CheckMethod", "(Descriptor,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "FormValidation$CheckMethod", true, "getDependsOn", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "FormValidation$CheckMethod", true, "toCheckUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "FormValidation$CheckMethod", true, "toStemUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "FormValidation", true, "aggregate", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "FormValidation", true, "errorWithMarkup", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "FormValidation", true, "okWithMarkup", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "FormValidation", true, "warningWithMarkup", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HeadBufferingStream", true, "getSideBuffer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HttpResponses", true, "errorJSON", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HttpResponses", true, "errorJSON", "(String,JSONArray)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HttpResponses", true, "errorJSON", "(String,JSONArray)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HttpResponses", true, "errorJSON", "(String,JSONObject)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HttpResponses", true, "errorJSON", "(String,JSONObject)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HttpResponses", true, "errorJSON", "(String,Map)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HttpResponses", true, "okJSON", "(JSONArray)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HttpResponses", true, "okJSON", "(JSONObject)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "HudsonFailedToLoad", true, "HudsonFailedToLoad", "(Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "absolutize", "(File,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "absolutize", "(File,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "copy", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "copy", "(InputStream,Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "copy", "(InputStream,Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "copy", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "copyLarge", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "copyLarge", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "lineIterator", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "lineIterator", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "readFirstLine", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "readLines", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "readLines", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "readLines", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "skip", "(InputStream,long)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toByteArray", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toByteArray", "(Reader,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toByteArray", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toCharArray", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toCharArray", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toCharArray", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toInputStream", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toInputStream", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toString", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toString", "(InputStream,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toString", "(Reader)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toString", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "toString", "(byte[],String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "write", "(String,Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "write", "(StringBuffer,Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "write", "(byte[],OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "write", "(byte[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "write", "(byte[],Writer,String)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "write", "(char[],Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "writeLines", "(Collection,String,OutputStream)", "", "Argument[1]", "Argument[2]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "writeLines", "(Collection,String,OutputStream,String)", "", "Argument[1]", "Argument[2]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "writeLines", "(Collection,String,Writer)", "", "Argument[0].Element", "Argument[2]", "taint", "df-generated"] + - ["hudson.util", "IOUtils", true, "writeLines", "(Collection,String,Writer)", "", "Argument[1]", "Argument[2]", "taint", "df-generated"] + - ["hudson.util", "InsufficientPermissionDetected", true, "InsufficientPermissionDetected", "(SecurityException)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "Iterators$DuplicateFilterIterator", false, "DuplicateFilterIterator", "(Iterable)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "Iterators$DuplicateFilterIterator", false, "DuplicateFilterIterator", "(Iterator)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "Iterators", true, "cast", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Iterators", true, "cast", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Iterators", true, "removeDups", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Iterators", true, "removeNull", "(Iterator)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Iterators", true, "sequence", "(Iterator[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Iterators", true, "subType", "(Iterator,Class)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "args", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "classpath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "debug", "(int)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "launch", "(Launcher)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "mainClass", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "mainClass", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "mainClass", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "pwd", "(File)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "pwd", "(FilePath)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "pwd", "(FilePath)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "systemProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "systemProperties", "(Map)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "systemProperties", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "systemProperty", "(String,String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "systemProperty", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "systemProperty", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "toFullArguments", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JVMBuilder", true, "vmopts", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "JenkinsReloadFailed", true, "JenkinsReloadFailed", "(Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "KeyedDataStorage", true, "get", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "KeyedDataStorage", true, "get", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "KeyedDataStorage", true, "get", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "KeyedDataStorage", true, "getOrCreate", "(String,Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "KeyedDataStorage", true, "getOrCreate", "(String,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "KeyedDataStorage", true, "getOrCreate", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "KeyedDataStorage", true, "getOrCreate", "(String,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "LineEndingConversion", true, "convertEOL", "(String,EOLType)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel$Option", false, "Option", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel$Option", false, "Option", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel$Option", false, "Option", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel$Option", false, "Option", "(String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel$Option", false, "Option", "(String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel$Option", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "ListBoxModel", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "ListBoxModel", "(Option[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "add", "(ModelObject,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "add", "(ModelObject,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "add", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "add", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "add", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "add", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ListBoxModel", true, "values", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "MaskingClassLoader", true, "MaskingClassLoader", "(ClassLoader,Collection)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "MaskingClassLoader", true, "MaskingClassLoader", "(ClassLoader,String[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "MaskingClassLoader", true, "add", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "MultipartFormDataParser", true, "getFileItem", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "NamingThreadFactory", false, "NamingThreadFactory", "(ThreadFactory,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "NamingThreadFactory", false, "NamingThreadFactory", "(ThreadFactory,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "NoHomeDir", true, "NoHomeDir", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "NoTempDir", true, "NoTempDir", "(IOException)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "OneShotEvent", false, "OneShotEvent", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "PackedMap", false, "of", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "PersistedList", true, "PersistedList", "(Saveable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "PersistedList", true, "addAllTo", "(Collection)", "", "Argument[this]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson.util", "PersistedList", true, "setOwner", "(Saveable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "PersistedList", true, "toList", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ProcessKillingVeto$VetoCause", true, "VetoCause", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ProcessKillingVeto$VetoCause", true, "getMessage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ProcessTree", true, "get", "(Process)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ProcessTree", true, "get", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", true, "getArguments", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", true, "getEnvironmentVariables", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "QueryParameterMap", true, "get", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "QueryParameterMap", true, "getAll", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "QuotedStringTokenizer", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "QuotedStringTokenizer", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "QuotedStringTokenizer", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "QuotedStringTokenizer", "(String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "QuotedStringTokenizer", "(String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "QuotedStringTokenizer", "(String,String,boolean,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "QuotedStringTokenizer", "(String,String,boolean,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "quote", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "toArray", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", true, "unquote", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ReflectionUtils$Parameter", false, "Parameter", "(MethodInfo,int)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "ReflectionUtils$Parameter", false, "annotations", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ReflectionUtils$Parameter", false, "genericType", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ReflectionUtils$Parameter", false, "name", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "ReflectionUtils", true, "getParameters", "(Method)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RemotingDiagnostics$HeapDump", true, "HeapDump", "(AccessControlled,VirtualChannel)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "RemotingDiagnostics$HeapDump", true, "HeapDump", "(AccessControlled,VirtualChannel)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "Builder", "(Callable,BiPredicate,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "Builder", "(Callable,BiPredicate,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "Builder", "(Callable,BiPredicate,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "build", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "withAttempts", "(int)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "withDelay", "(long)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "withDuringActionExceptionListener", "(BiFunction)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "withDuringActionExceptionListener", "(BiFunction)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "withDuringActionExceptions", "(Class[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "Retrier$Builder", true, "withDuringActionExceptions", "(Class[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "RobustReflectionConverter", true, "RobustReflectionConverter", "(Mapper,ReflectionProvider)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "RobustReflectionConverter", true, "RobustReflectionConverter", "(Mapper,ReflectionProvider)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "RobustReflectionConverter", true, "doUnmarshal", "(Object,HierarchicalStreamReader,UnmarshallingContext)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "RunList", "(Job)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "byTimestamp", "(long,long)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "completedOnly", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "failureOnly", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "filter", "(Predicate)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "filter", "(Predicate)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson.util", "RunList", true, "fromRuns", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "getFirstBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "getLastBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "limit", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "newBuilds", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "node", "(Node)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "overThresholdOnly", "(Result)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "RunList", true, "regressionOnly", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Scrambler", true, "descramble", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Scrambler", true, "scramble", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Secret", false, "decrypt", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Secret", false, "fromString", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Secret", false, "getEncryptedValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Secret", false, "getPlainText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Secret", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "Secret", false, "toString", "(Secret)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "SecretRewriter", true, "rewriteRecursive", "(File,TaskListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "SequentialExecutionQueue", true, "SequentialExecutionQueue", "(ExecutorService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "SequentialExecutionQueue", true, "getExecutors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "SequentialExecutionQueue", true, "getInProgress", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "SequentialExecutionQueue", true, "setExecutors", "(ExecutorService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "StreamCopyThread", true, "StreamCopyThread", "(String,InputStream,OutputStream)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "StreamCopyThread", true, "StreamCopyThread", "(String,InputStream,OutputStream)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "StreamCopyThread", true, "StreamCopyThread", "(String,InputStream,OutputStream,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "StreamCopyThread", true, "StreamCopyThread", "(String,InputStream,OutputStream,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "StreamResource", true, "StreamResource", "(String,InputStream)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "StreamTaskListener", true, "StreamTaskListener", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "StreamTaskListener", true, "StreamTaskListener", "(OutputStream,Charset)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "StreamTaskListener", true, "StreamTaskListener", "(PrintStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "TagCloud$Entry", false, "Entry", "(Object,float)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "TextFile", true, "TextFile", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "TextFile", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "VariableResolver$ByMap", false, "ByMap", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "VariableResolver$Union", false, "Union", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "VariableResolver$Union", false, "Union", "(VariableResolver[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "XStream2", true, "addCompatibilityAlias", "(String,Class)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.util", "XStream2", true, "getMapperInjectionPoint", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.util", "XStream2", true, "setMapper", "(Mapper)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.views", "MyViewsTabBar", true, "sort", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.views", "ViewJobFilter", true, "filter", "(List,List,View)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.views", "ViewsTabBar", true, "sort", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson.widgets", "BuildHistoryWidget", true, "BuildHistoryWidget", "(Task,Iterable,Adapter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.widgets", "BuildHistoryWidget", true, "BuildHistoryWidget", "(Task,Iterable,Adapter)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.widgets", "BuildHistoryWidget", true, "BuildHistoryWidget", "(Task,Iterable,Adapter)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "HistoryWidget", "(ModelObject,Iterable,Adapter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "HistoryWidget", "(ModelObject,Iterable,Adapter)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "HistoryWidget", "(ModelObject,Iterable,Adapter)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "doAjax", "(StaplerRequest,StaplerResponse,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "getFirstTransientBuildKey", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "getHistoryPageFilter", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "getNextBuildNumberToFetch", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "getRenderList", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson.widgets", "HistoryWidget", true, "setNextBuildNumberToFetch", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "AbortException", true, "AbortException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "AbstractMarkupText", true, "getText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "BulkChange", true, "BulkChange", "(Saveable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ClassicPluginStrategy", true, "ClassicPluginStrategy", "(PluginManager)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "CloseProofOutputStream", true, "CloseProofOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "DependencyRunner", true, "DependencyRunner", "(ProjectRunnable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "DescriptorExtensionList", true, "createDescriptorList", "(Hudson,Class)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "DescriptorExtensionList", true, "createDescriptorList", "(Jenkins,Class)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "DescriptorExtensionList", true, "find", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "DescriptorExtensionList", true, "find", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "DescriptorExtensionList", true, "findByName", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "EnvVars", "(EnvVars)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "EnvVars", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "EnvVars", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "addLine", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "expand", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "expand", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "get", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "get", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "override", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "override", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "overrideAll", "(Map)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "EnvVars", true, "overrideAll", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "overrideExpandingAll", "(Map)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "EnvVars", true, "overrideExpandingAll", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "putIfNotNull", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "EnvVars", true, "putIfNotNull", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ExtensionComponent", true, "ExtensionComponent", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ExtensionComponent", true, "ExtensionComponent", "(Object,Extension)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ExtensionComponent", true, "ExtensionComponent", "(Object,double)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ExtensionComponent", true, "getInstance", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ExtensionFinder$GuiceFinder", true, "getContainer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ExtensionList", true, "addListener", "(ExtensionListListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ExtensionList", true, "create", "(Hudson,Class)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ExtensionList", true, "create", "(Jenkins,Class)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ExtensionList", true, "getComponents", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ExtensionList", true, "getDynamic", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath$ExplicitlySpecifiedDirScanner", false, "ExplicitlySpecifiedDirScanner", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "FilePath$TarCompression", true, "extract", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "FilePath", "(FilePath,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "FilePath", false, "FilePath", "(FilePath,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "FilePath", false, "FilePath", "(VirtualChannel,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "FilePath", false, "FilePath", "(VirtualChannel,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "FilePath", false, "absolutize", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "act", "(FileCallable)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "asCallableWith", "(FileCallable)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "child", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "child", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "createLauncher", "(TaskListener)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "createLauncher", "(TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "createTempDir", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "createTempFile", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "createTextTempFile", "(String,String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "createTextTempFile", "(String,String,String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "digest", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "getBaseName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "getChannel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "getParent", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "getRemote", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "ignoringSymlinks", "(FileVisitor,String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "normalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "readLink", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "readToString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "sibling", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "sibling", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "toURI", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "toVirtualFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "validateAntFileMask", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "validateAntFileMask", "(String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "validateAntFileMask", "(String,int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "validateAntFileMask", "(String,int,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "withSuffix", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "FilePath", false, "withSuffix", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions$RunUrl", false, "RunUrl", "(Run,String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Functions$RunUrl", false, "RunUrl", "(Run,String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Functions$RunUrl", false, "RunUrl", "(Run,String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Functions$RunUrl", false, "RunUrl", "(Run,String,String,String)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Functions$RunUrl", false, "getBaseUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions$RunUrl", false, "getNextBuildUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions$RunUrl", false, "getPreviousBuildUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions$ThreadGroupMap", true, "getThreadGroup", "(ThreadInfo)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "addSuffix", "(int,String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "addSuffix", "(int,String,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "appendIfNotNull", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "appendIfNotNull", "(String,String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "appendIfNotNull", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "appendSpaceIfNotNull", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "breakableString", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "calcCheckUrl", "(Map,String,Object,String)", "", "Argument[2]", "Argument[0].Element", "taint", "df-generated"] + - ["hudson", "Functions", true, "calcCheckUrl", "(Map,String,Object,String)", "", "Argument[3]", "Argument[2]", "taint", "df-generated"] + - ["hudson", "Functions", true, "capitalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "decompose", "(StaplerRequest)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "defaulted", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "defaulted", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "dumpThreadInfo", "(ThreadInfo,ThreadGroupMap)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "encode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "extractPluginNameFromIconSrc", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "filter", "(SortedMap,String,String)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "filterDescriptors", "(Object,Iterable)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "filterExcludingFrom", "(SortedMap,String,String)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getActionUrl", "(String,Action)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getCheckUrl", "(String,Object,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getCheckUrl", "(String,Object,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getCheckUrl", "(String,Object,String)", "", "Argument[2]", "Argument[1]", "taint", "df-generated"] + - ["hudson", "Functions", true, "getCookie", "(HttpServletRequest,String,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getDiffString2", "(String,int,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getDiffString2", "(String,int,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getNearestAncestorUrl", "(StaplerRequest,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getPasswordValue", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getProjectListString", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getRelativeDisplayNameFrom", "(Item,ItemGroup)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getRelativeNameFrom", "(Item,ItemGroup)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getRelativeNameFrom", "(Item,ItemGroup,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "getViewResource", "(Object,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "ifThenElse", "(boolean,Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "ifThenElse", "(boolean,Object,Object)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "joinPath", "(String[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "prepend", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "prepend", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "printThrowable", "(Throwable)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "rawHtml", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "reverse", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "singletonList", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "subList", "(List,int)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "tryGetIconPath", "(String,JellyContext)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "validateIconSize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Functions", true, "xmlUnescape", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$DecoratedLauncher", true, "DecoratedLauncher", "(Launcher)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$DecoratedLauncher", true, "getInner", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$DecoratedLauncher", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$DummyLauncher", true, "DummyLauncher", "(TaskListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$LocalLauncher", true, "LocalLauncher", "(TaskListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$LocalLauncher", true, "LocalLauncher", "(TaskListener,VirtualChannel)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$LocalLauncher", true, "LocalLauncher", "(TaskListener,VirtualChannel)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "buildStep", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "buildStep", "(EnvVarsFilterableBuilder)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "buildStep", "(EnvVarsFilterableBuilder)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmdAsSingleString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(ArgumentListBuilder)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(ArgumentListBuilder)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(File,String[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(File,String[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(List)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(String[])", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "cmds", "(String[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "copy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "envs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "envs", "(Map)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "envs", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "envs", "(String[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "envs", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "masks", "(boolean[])", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "pwd", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "pwd", "(File)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "pwd", "(FilePath)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "pwd", "(FilePath)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "pwd", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "quiet", "(boolean)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "readStderr", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "readStdout", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "start", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stderr", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stderr", "(OutputStream)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stderr", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stdin", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stdin", "(InputStream)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stdin", "(InputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stdout", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stdout", "(OutputStream)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stdout", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stdout", "(TaskListener)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "stdout", "(TaskListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$ProcStarter", false, "writeStdin", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["hudson", "Launcher$RemoteLauncher$ProcImpl", false, "ProcImpl", "(RemoteProcess)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$RemoteLauncher", true, "RemoteLauncher", "(TaskListener,VirtualChannel,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$RemoteLauncher", true, "RemoteLauncher", "(TaskListener,VirtualChannel,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Launcher$RemoteLauncher", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "decorateByEnv", "(EnvVars)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "decorateByPrefix", "(String[])", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "decorateFor", "(Node)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "getChannel", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "getListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(ProcStarter)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String,Map,OutputStream,FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String,Map,OutputStream,FilePath)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String,Map,OutputStream,FilePath)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String,String[],OutputStream,FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String,String[],OutputStream,FilePath)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String,String[],OutputStream,FilePath)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],Map,InputStream,OutputStream)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],Map,InputStream,OutputStream)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],Map,InputStream,OutputStream)", "", "Argument[3]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],Map,OutputStream,FilePath)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],Map,OutputStream,FilePath)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],Map,OutputStream,FilePath)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],InputStream,OutputStream)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],InputStream,OutputStream)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],InputStream,OutputStream)", "", "Argument[3]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],InputStream,OutputStream,FilePath)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],InputStream,OutputStream,FilePath)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],InputStream,OutputStream,FilePath)", "", "Argument[3]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],OutputStream,FilePath)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],OutputStream,FilePath)", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],String[],OutputStream,FilePath)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],Map,InputStream,OutputStream)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],Map,InputStream,OutputStream)", "", "Argument[2].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],Map,InputStream,OutputStream)", "", "Argument[4]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],Map,OutputStream,FilePath)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],Map,OutputStream,FilePath)", "", "Argument[2].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],Map,OutputStream,FilePath)", "", "Argument[3]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],InputStream,OutputStream)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],InputStream,OutputStream)", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],InputStream,OutputStream)", "", "Argument[4]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],InputStream,OutputStream,FilePath)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],InputStream,OutputStream,FilePath)", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],InputStream,OutputStream,FilePath)", "", "Argument[4]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],OutputStream,FilePath)", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],OutputStream,FilePath)", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Launcher", true, "launch", "(String[],boolean[],String[],OutputStream,FilePath)", "", "Argument[3]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "LocalPluginManager", true, "LocalPluginManager", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "LocalPluginManager", true, "LocalPluginManager", "(Jenkins)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "LocalPluginManager", true, "LocalPluginManager", "(ServletContext,File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "LocalPluginManager", true, "LocalPluginManager", "(ServletContext,File)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Lookup", true, "set", "(Class,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Lookup", true, "setIfNull", "(Class,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Lookup", true, "setIfNull", "(Class,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "MarkupText", true, "MarkupText", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "MarkupText", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "MarkupText", true, "toString", "(boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PermalinkList", false, "PermalinkList", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PermalinkList", false, "findNearest", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PermalinkList", false, "get", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Plugin", true, "getWrapper", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginFirstClassLoader", true, "getURLs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager$FailedPlugin", false, "FailedPlugin", "(PluginWrapper,Exception)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginManager$FailedPlugin", false, "FailedPlugin", "(PluginWrapper,Exception)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginManager$FailedPlugin", false, "FailedPlugin", "(String,Exception)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginManager$FailedPlugin", false, "FailedPlugin", "(String,Exception)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginManager$FailedPlugin", false, "getExceptionString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager$PluginCycleDependenciesMonitor", false, "getPluginsWithCycle", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager$PluginUpdateMonitor", false, "addPluginToUpdate", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginManager$PluginUpdateMonitor", false, "getPluginsToBeUpdated", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager$PluginUpdateMonitor", false, "ifPluginOlderThenReport", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginManager$UberClassLoader", false, "UberClassLoader", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "createDefault", "(Jenkins)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "disablePlugins", "(PluginDisableStrategy,List)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "disablePlugins", "(PluginDisableStrategy,List)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "dynamicLoad", "(File,boolean,List)", "", "Argument[this]", "Argument[2].Element", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "dynamicLoad", "(File,boolean,List)", "", "Argument[0]", "Argument[2].Element", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getFailedPlugins", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getLastErrorCheckUpdateCenters", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getPlugin", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getPlugin", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getPluginStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getPlugins", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getPlugins", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "getWorkDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginManager", true, "whichPlugin", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginStrategy", true, "createPluginWrapper", "(File)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginStrategy", true, "createPluginWrapper", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginStrategy", true, "getShortName", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper$Dependency", false, "Dependency", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper$Dependency", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", true, "PluginDisableResult", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", true, "PluginDisableResult", "(String,PluginDisableStatus,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", true, "PluginDisableResult", "(String,PluginDisableStatus,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", true, "addDependentDisableStatus", "(PluginDisableResult)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", true, "getDependentsDisableStatus", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", true, "getMessage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", true, "getPlugin", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", true, "setMessage", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginWrapperAdministrativeMonitor", false, "getPlugin", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper$PluginWrapperAdministrativeMonitor", false, "getPlugins", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "PluginWrapper", "(PluginManager,File,Manifest,URL,ClassLoader,File,List,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "PluginWrapper", "(PluginManager,File,Manifest,URL,ClassLoader,File,List,List)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "PluginWrapper", "(PluginManager,File,Manifest,URL,ClassLoader,File,List,List)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "PluginWrapper", "(PluginManager,File,Manifest,URL,ClassLoader,File,List,List)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "PluginWrapper", "(PluginManager,File,Manifest,URL,ClassLoader,File,List,List)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "PluginWrapper", "(PluginManager,File,Manifest,URL,ClassLoader,File,List,List)", "", "Argument[5]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "PluginWrapper", "(PluginManager,File,Manifest,URL,ClassLoader,File,List,List)", "", "Argument[6].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "PluginWrapper", "(PluginManager,File,Manifest,URL,ClassLoader,File,List,List)", "", "Argument[7].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "disable", "(PluginDisableStrategy)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getBackupFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getDependants", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getDependencies", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getDependencyErrors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getDependents", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getDerivedDependencyErrors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getLongName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getMandatoryDependencies", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getMandatoryDependents", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getManifest", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getOptionalDependants", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getOptionalDependencies", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getOptionalDependents", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getOriginalDependencyErrors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "getShortName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "setDependants", "(Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "setDependents", "(Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "setOptionalDependents", "(Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "setPlugin", "(Plugin)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["hudson", "PluginWrapper", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String,Map,OutputStream,File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String,Map,OutputStream,File)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String,String[],OutputStream,File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String,String[],OutputStream,File)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],Map,InputStream,OutputStream)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],Map,InputStream,OutputStream)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],InputStream,OutputStream)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],InputStream,OutputStream)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],InputStream,OutputStream,File)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],InputStream,OutputStream,File)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],InputStream,OutputStream,OutputStream,File)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],InputStream,OutputStream,OutputStream,File)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],InputStream,OutputStream,OutputStream,File)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],OutputStream,File)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$LocalProc", false, "LocalProc", "(String[],String[],OutputStream,File)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc$RemoteProc", false, "RemoteProc", "(Future)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "Proc", true, "getStderr", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Proc", true, "getStdin", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Proc", true, "getStdout", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String,String)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String,String)", "", "Argument[4]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "ProxyConfiguration", "(String,int,String,String,String,String)", "", "Argument[5]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "getEncryptedPassword", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "getNoProxyHost", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "getPassword", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "getSecretPassword", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "getTestUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "getUserName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "setNoProxyHost", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "setSecretPassword", "(Secret)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "setTestUrl", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "ProxyConfiguration", false, "setUserName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "StructuredForm", true, "get", "(StaplerRequest)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "changeExtension", "(File,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "combine", "(long,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "copyStream", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson", "Util", true, "copyStream", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson", "Util", true, "copyStreamAndClose", "(InputStream,OutputStream)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson", "Util", true, "copyStreamAndClose", "(Reader,Writer)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson", "Util", true, "createDirectories", "(Path,FileAttribute[])", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "encode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "encodeRFC2396", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "ensureEndsWith", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "ensureEndsWith", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fileToPath", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixEmpty", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixEmptyAndTrim", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixNull", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixNull", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixNull", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixNull", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixNull", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixNull", "(Set)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fixNull", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "fullEncode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "getFileName", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "intern", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "join", "(Collection,String)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "join", "(Collection,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "join", "(Collection[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "mapToEnv", "(Map)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "nullify", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "rawEncode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "removeTrailingSlash", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "replaceMacro", "(String,Map)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "replaceMacro", "(String,Map)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "replaceMacro", "(String,VariableResolver)", "", "Argument[0]", "Argument[1]", "taint", "df-generated"] + - ["hudson", "Util", true, "replaceMacro", "(String,VariableResolver)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "replaceMacro", "(String,VariableResolver)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "singleQuote", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "toHexString", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "tokenize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "Util", true, "wrapToErrorSpan", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "WebAppMain$FileAndDescription", true, "FileAndDescription", "(File,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "WebAppMain$FileAndDescription", true, "FileAndDescription", "(File,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "XmlFile", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "XmlFile", "(XStream,File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "XmlFile", "(XStream,File)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "XmlFile", "(XStream,File,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "XmlFile", "(XStream,File,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "getFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "getXStream", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "replaceIfNotAtTopLevel", "(Object,Supplier)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["hudson", "XmlFile", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", true, "HsErrPidFile", "(HsErrPidList,File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", true, "HsErrPidFile", "(HsErrPidList,File)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidList", true, "getFiles", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.fingerprints", "GlobalFingerprintConfiguration", true, "getStorage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.fingerprints", "GlobalFingerprintConfiguration", true, "setStorage", "(FingerprintStorage)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.install", "InstallState", true, "InstallState", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.install", "InstallState", true, "name", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.install", "InstallState", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsApiData", true, "getMonitorsList", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsDecorator", true, "filterNonSecurityAdministrativeMonitors", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsDecorator", true, "filterSecurityAdministrativeMonitors", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["jenkins.management", "AsynchronousAdministrativeMonitor", true, "getLogText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.management", "Badge", true, "Badge", "(String,String,Severity)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.management", "Badge", true, "Badge", "(String,String,Severity)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.management", "Badge", true, "getText", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.management", "Badge", true, "getTooltip", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.item_category", "Categories", true, "getItem", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.item_category", "Categories", true, "getItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.item_category", "Category", true, "Category", "(String,String,String,int,int,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.item_category", "Category", true, "Category", "(String,String,String,int,int,List)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.item_category", "Category", true, "Category", "(String,String,String,int,int,List)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.item_category", "Category", true, "Category", "(String,String,String,int,int,List)", "", "Argument[5].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.item_category", "Category", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.item_category", "Category", true, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.item_category", "Category", true, "getItems", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.item_category", "Category", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.labels", "LabelAutoCompleteSeeder", true, "LabelAutoCompleteSeeder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.labels", "LabelAutoCompleteSeeder", true, "getSeeds", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", true, "getLoadedBuilds", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", true, "put", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", true, "put", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", true, "updateBaseDir", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.lazy", "BuildReference$HolderFactory", true, "make", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "BuildReference", false, "BuildReference", "(String,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.lazy", "BuildReference", false, "BuildReference", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.lazy", "BuildReference", false, "get", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "BuildReference", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn$RunMixIn", true, "createReference", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn$RunMixIn", true, "getNextBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn$RunMixIn", true, "getPreviousBuild", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", true, "_getRuns", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", true, "createHistoryWidget", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", true, "getRunMap", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.queue", "AsynchronousExecution", true, "completed", "(Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.queue", "AsynchronousExecution", true, "getExecutor", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model.queue", "AsynchronousExecution", true, "setExecutorWithoutCompleting", "(Executor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model.queue", "CompositeCauseOfBlockage", true, "CompositeCauseOfBlockage", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ArtifactManager", true, "onLoad", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ArtifactManagerConfiguration", true, "getArtifactManagerFactories", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "BlockedBecauseOfBuildInProgress", true, "BlockedBecauseOfBuildInProgress", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "BuildDiscarder$ConverterImpl", true, "ConverterImpl", "(Mapper)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "BuildDiscarderProperty", true, "BuildDiscarderProperty", "(BuildDiscarder)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "BuildDiscarderProperty", true, "getStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "CauseOfInterruption$UserInterruption", false, "UserInterruption", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "CauseOfInterruption$UserInterruption", false, "UserInterruption", "(User)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "CauseOfInterruption$UserInterruption", false, "getUser", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "CauseOfInterruption$UserInterruption", false, "getUserId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "CauseOfInterruption$UserInterruption", false, "getUserOrNull", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Configuration", true, "getStringConfigParameter", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "DirectlyModifiableTopLevelItemGroup", true, "add", "(TopLevelItem,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "DirectlyModifiableTopLevelItemGroup", true, "add", "(TopLevelItem,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "DirectlyModifiableTopLevelItemGroup", true, "add", "(TopLevelItem,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "FingerprintFacet", true, "_setOwner", "(Fingerprint)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "FingerprintFacet", true, "getFingerprint", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "GlobalBuildDiscarderConfiguration", true, "getConfiguredBuildDiscarders", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "IdStrategy", true, "idFromFilename", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "IdStrategy", true, "keyFor", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "InterruptedBuildAction", true, "InterruptedBuildAction", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "InterruptedBuildAction", true, "getCauses", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "InvalidBuildsDir", true, "InvalidBuildsDir", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins$CloudList", true, "CloudList", "(Jenkins)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins$CloudList", true, "getByName", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "_getFingerprint", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "createProject", "(TopLevelItemDescriptor,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "doJnlpJars", "(StaplerRequest)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "doQuietDown", "(boolean,int,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "doUserContent", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "expandVariablesForDirectory", "(String,String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "expandVariablesForDirectory", "(String,String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "expandVariablesForDirectory", "(String,String,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getActiveAdministrativeMonitors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getAdjuncts", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getAdministrativeMonitor", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getAgentProtocols", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getAllThreadDumps", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getApi", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getAsynchPeople", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getAuthorizationStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getBuildDirFor", "(Job)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getBuildDirFor", "(Job)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getCloud", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getComputer", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getComputers", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getCrumbIssuer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getDependencyGraph", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getDescriptor", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getDescriptorList", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getDescriptorOrDie", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getDynamic", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getExtensionList", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getExtensionList", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getFingerprint", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getFingerprintMap", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getFutureDependencyGraph", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getGlobalNodeProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getHeapDump", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getItem", "(String,Item)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getItem", "(String,Item)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getItem", "(String,ItemGroup)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getItem", "(String,ItemGroup)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getItemMap", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getJDK", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getJDKs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getJnlpJars", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLabel", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLabel", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLabel", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLabelAtom", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLabelAtom", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLabelAtom", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLabelAtoms", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLabels", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getLog", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getMarkupFormatter", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getMyViewsTabBar", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getNode", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getNodesObject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getPeople", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getPluginManager", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getProjectNamingStrategy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getProxy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getQuietDownReason", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getRawBuildsDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getRawWorkspaceDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getSCMListeners", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getSecretKey", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getSecurityRealm", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getSetupWizard", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getSystemMessage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getTcpSlaveAgentListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getTopLevelItemNames", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getUpdateCenter", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getUser", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "getWidgets", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "putItem", "(TopLevelItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "rebuildDependencyGraphAsync", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setAuthorizationStrategy", "(AuthorizationStrategy)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setCrumbIssuer", "(CrumbIssuer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setInstallState", "(InstallState)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setJDKs", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setLog", "(LogRecorderManager)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setMarkupFormatter", "(MarkupFormatter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setMyViewsTabBar", "(MyViewsTabBar)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setPrimaryView", "(View)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setProjectNamingStrategy", "(ProjectNamingStrategy)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setProxy", "(ProxyConfiguration)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setRawBuildsDir", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setSecurityRealm", "(SecurityRealm)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setSystemMessage", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Jenkins", true, "setViewsTabBar", "(ViewsTabBar)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "JenkinsLocationConfiguration", true, "getAdminAddress", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "JenkinsLocationConfiguration", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "JenkinsLocationConfiguration", true, "setAdminAddress", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "JenkinsLocationConfiguration", true, "setUrl", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(Action)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(Computer)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(Job)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(MenuItem)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(MenuItem)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(Node)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(String,String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(String,String,String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(String,String,String,String,boolean,boolean)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(String,String,String,boolean)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "add", "(String,String,String,boolean,boolean)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "addAll", "(Collection)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "addHeader", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "addSeparator", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "from", "(ModelObjectWithContextMenu,StaplerRequest,StaplerResponse)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$ContextMenu", true, "from", "(ModelObjectWithContextMenu,StaplerRequest,StaplerResponse,String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "MenuItem", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "getIconXml", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withContextRelativeUrl", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withContextRelativeUrl", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withDisplayName", "(ModelObject)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withDisplayName", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withIcon", "(BallColor)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withIcon", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withIcon", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withIconClass", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withStockIcon", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withStockIcon", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu$MenuItem", true, "withUrl", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.model", "ModifiableTopLevelItemGroup", true, "createProject", "(TopLevelItemDescriptor,String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Nodes", true, "addNode", "(Node)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "Nodes", true, "getNode", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "Nodes", true, "getNodes", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", true, "extendSearchIndex", "(SearchIndexBuilder)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", true, "scheduleBuild2", "(Job,int,Action[])", "", "Argument[2].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy$PatternProjectNamingStrategy", false, "PatternProjectNamingStrategy", "(String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy$PatternProjectNamingStrategy", false, "PatternProjectNamingStrategy", "(String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy$PatternProjectNamingStrategy", false, "PatternProjectNamingStrategy", "(String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy$PatternProjectNamingStrategy", false, "getDescription", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy$PatternProjectNamingStrategy", false, "getNamePattern", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "RunAction2", true, "onAttached", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "RunAction2", true, "onLoad", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "SimpleGlobalBuildDiscarderStrategy", true, "SimpleGlobalBuildDiscarderStrategy", "(BuildDiscarder)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.model", "SimpleGlobalBuildDiscarderStrategy", true, "getDiscarder", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.model", "StandardArtifactManager", true, "StandardArtifactManager", "(Run)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.mvn", "FilePathGlobalSettingsProvider", true, "FilePathGlobalSettingsProvider", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.mvn", "FilePathGlobalSettingsProvider", true, "getPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "FilePathSettingsProvider", true, "FilePathSettingsProvider", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.mvn", "FilePathSettingsProvider", true, "getPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalMavenConfig", true, "getGlobalSettingsProvider", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalMavenConfig", true, "getSettingsProvider", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalMavenConfig", true, "setGlobalSettingsProvider", "(GlobalSettingsProvider)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalMavenConfig", true, "setSettingsProvider", "(SettingsProvider)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProvider", true, "getSettingsFilePath", "(GlobalSettingsProvider,AbstractBuild,TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProvider", true, "getSettingsFilePath", "(GlobalSettingsProvider,AbstractBuild,TaskListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProvider", true, "getSettingsRemotePath", "(GlobalSettingsProvider,AbstractBuild,TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProvider", true, "getSettingsRemotePath", "(GlobalSettingsProvider,AbstractBuild,TaskListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProvider", true, "supplySettings", "(AbstractBuild,TaskListener)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProvider", true, "supplySettings", "(AbstractBuild,TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "SettingsProvider", true, "getSettingsFilePath", "(SettingsProvider,AbstractBuild,TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "SettingsProvider", true, "getSettingsFilePath", "(SettingsProvider,AbstractBuild,TaskListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "SettingsProvider", true, "getSettingsRemotePath", "(SettingsProvider,AbstractBuild,TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "SettingsProvider", true, "getSettingsRemotePath", "(SettingsProvider,AbstractBuild,TaskListener)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "SettingsProvider", true, "supplySettings", "(AbstractBuild,TaskListener)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.mvn", "SettingsProvider", true, "supplySettings", "(AbstractBuild,TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator$Item", true, "Item", "(ArrayType,String[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", true, "getInstance", "(boolean,List)", "", "Argument[1].Element", "ReturnValue", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", true, "getOverrides", "(ArrayType)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "RegexValidator", true, "match", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "RegexValidator", true, "validate", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", true, "UrlValidator", "(RegexValidator,long)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", true, "UrlValidator", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", true, "UrlValidator", "(String[],RegexValidator,long)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", true, "UrlValidator", "(String[],RegexValidator,long)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", true, "UrlValidator", "(String[],RegexValidator,long,DomainValidator)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", true, "UrlValidator", "(String[],RegexValidator,long,DomainValidator)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", true, "UrlValidator", "(String[],RegexValidator,long,DomainValidator)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", true, "UrlValidator", "(String[],long)", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil$DetachedPlugin", false, "getShortName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil$DetachedPlugin", false, "getSplitWhen", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil$DetachedPlugin", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil", true, "configLines", "(InputStream)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats$SingleTokenStats", true, "getLastUseDate", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats$SingleTokenStats", true, "getTokenUuid", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", true, "findTokenStatsById", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", true, "findTokenStatsById", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", true, "load", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", true, "load", "(User)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", true, "updateUsageForId", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", true, "updateUsageForId", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", true, "buildNew", "(String,HashValue)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", true, "buildNew", "(String,HashValue)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", true, "buildNewFromLegacy", "(HashValue,boolean)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", true, "getCreationDate", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", true, "getUuid", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", true, "rename", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", true, "setName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", true, "findMatchingToken", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", true, "getLegacyToken", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", true, "getTokenListSortedByName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", true, "revokeToken", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "LegacyApiTokenAdministrativeMonitor", true, "getLegacyStatsOf", "(User,HashedToken)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.apitoken", "TokenUuidAndPlainValue", true, "TokenUuidAndPlainValue", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security.apitoken", "TokenUuidAndPlainValue", true, "TokenUuidAndPlainValue", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security.seed", "UserSeedProperty", true, "getSeed", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security.stapler", "StaticRoutingDecisionProvider", true, "add", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.security.stapler", "StaticRoutingDecisionProvider", true, "add", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security.stapler", "StaticRoutingDecisionProvider", true, "addBlacklistSignature", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.security.stapler", "StaticRoutingDecisionProvider", true, "addBlacklistSignature", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security.stapler", "StaticRoutingDecisionProvider", true, "remove", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.security.stapler", "StaticRoutingDecisionProvider", true, "removeBlacklistSignature", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$TokenInfoAndStats", true, "TokenInfoAndStats", "(HashedToken,SingleTokenStats)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$TokenInfoAndStats", true, "TokenInfoAndStats", "(HashedToken,SingleTokenStats)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", true, "getTokenStats", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", true, "getTokenStore", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "BasicApiTokenHelper", true, "isConnectingUsingApiToken", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "BasicHeaderProcessor", true, "setAuthenticationEntryPoint", "(AuthenticationEntryPoint)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "BasicHeaderProcessor", true, "setRememberMeServices", "(RememberMeServices)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ConfidentialKey", true, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "CryptoConfidentialKey", true, "CryptoConfidentialKey", "(Class,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "CryptoConfidentialKey", true, "CryptoConfidentialKey", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "DefaultConfidentialStore", true, "DefaultConfidentialStore", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", true, "HMACConfidentialKey", "(Class,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", true, "HMACConfidentialKey", "(Class,String,int)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", true, "HMACConfidentialKey", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", true, "HMACConfidentialKey", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "HexStringConfidentialKey", true, "HexStringConfidentialKey", "(Class,String,int)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "HexStringConfidentialKey", true, "HexStringConfidentialKey", "(String,int)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "HexStringConfidentialKey", true, "get", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "ImpersonatingExecutorService", false, "ImpersonatingExecutorService", "(ExecutorService,Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ImpersonatingExecutorService", false, "ImpersonatingExecutorService", "(ExecutorService,Authentication)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ImpersonatingScheduledExecutorService", false, "ImpersonatingScheduledExecutorService", "(ScheduledExecutorService,Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ImpersonatingScheduledExecutorService", false, "ImpersonatingScheduledExecutorService", "(ScheduledExecutorService,Authentication)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ImpersonatingUserDetailsService2", true, "ImpersonatingUserDetailsService2", "(UserDetailsService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ImpersonatingUserDetailsService", true, "ImpersonatingUserDetailsService", "(UserDetailsService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "NonSerializableSecurityContext", true, "NonSerializableSecurityContext", "(Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "NonSerializableSecurityContext", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticatorConfiguration", true, "getAuthenticators", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "RSAConfidentialKey", true, "getPublicKey", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "RSADigitalSignatureConfidentialKey", true, "RSADigitalSignatureConfidentialKey", "(Class,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "RSADigitalSignatureConfidentialKey", true, "RSADigitalSignatureConfidentialKey", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ResourceDomainConfiguration", false, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "ResourceDomainConfiguration", false, "setUrl", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "ResourceDomainRootAction", true, "getDynamic", "(String,StaplerRequest,StaplerResponse)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "ResourceDomainRootAction", true, "getRedirectUrl", "(Token,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "ResourceDomainRootAction", true, "getToken", "(DirectoryBrowserSupport,StaplerRequest)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "SecurityContextExecutorService", true, "SecurityContextExecutorService", "(ExecutorService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsConfiguration", true, "getIgnoredWarnings", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsConfiguration", true, "setIgnoredWarnings", "(Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.security", "UserDetailsCache", false, "getCached", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.security", "UserDetailsCache", false, "loadUserByUsername", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.slaves", "EncryptedSlaveAgentJnlpFile", true, "EncryptedSlaveAgentJnlpFile", "(AccessControlled,String,String,Permission)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.slaves", "EncryptedSlaveAgentJnlpFile", true, "EncryptedSlaveAgentJnlpFile", "(AccessControlled,String,String,Permission)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.slaves", "EncryptedSlaveAgentJnlpFile", true, "EncryptedSlaveAgentJnlpFile", "(AccessControlled,String,String,Permission)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.slaves", "EncryptedSlaveAgentJnlpFile", true, "EncryptedSlaveAgentJnlpFile", "(AccessControlled,String,String,Permission)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.slaves", "IOHubProvider", true, "getHub", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.slaves", "NioChannelSelector", true, "getHub", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", true, "RemotingWorkDirSettings", "(boolean,String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", true, "RemotingWorkDirSettings", "(boolean,String,String,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", true, "getInternalDir", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", true, "getWorkDirPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", true, "toCommandLineArgs", "(SlaveComputer)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", true, "toCommandLineString", "(SlaveComputer)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks.filters.impl", "RetainVariablesLocalRule", true, "getVariables", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks.filters.impl", "RetainVariablesLocalRule", true, "setVariables", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterException", true, "EnvVarsFilterException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterException", true, "getRule", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterException", true, "withRule", "(EnvVarsFilterRule)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterException", true, "withRule", "(EnvVarsFilterRule)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterException", true, "withVariable", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterException", true, "withVariable", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRuleContext", true, "EnvVarsFilterRuleContext", "(Launcher,TaskListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRuleContext", true, "EnvVarsFilterRuleContext", "(Launcher,TaskListener)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRuleContext", true, "getLauncher", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRuleContext", true, "getTaskListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRuleWrapper", true, "EnvVarsFilterRuleWrapper", "(List)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRuleWrapper", true, "createRuleWrapper", "(Run,Object,Launcher,List)", "", "Argument[3].Element", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterableBuilder", true, "buildEnvVarsFilterRules", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper$Context", false, "env", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper$Context", false, "env", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper$Context", false, "getDisposer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper$Context", false, "getEnv", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper$Context", false, "setDisposer", "(Disposer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.telemetry", "Correlator", true, "getCorrelationId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.triggers", "ReverseBuildTrigger", false, "ReverseBuildTrigger", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.triggers", "ReverseBuildTrigger", false, "ReverseBuildTrigger", "(String,Result)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.triggers", "ReverseBuildTrigger", false, "ReverseBuildTrigger", "(String,Result)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.triggers", "ReverseBuildTrigger", false, "getThreshold", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.triggers", "ReverseBuildTrigger", false, "getUpstreamProjects", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.triggers", "ReverseBuildTrigger", false, "setThreshold", "(Result)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem$SCMTriggerItems", true, "asSCMTriggerItem", "(Item)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem$SCMTriggerItems", true, "resolveMultiScmIfConfigured", "(SCM)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", true, "asItem", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", true, "getSCMs", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.triggers", "TriggeredItem", true, "getTriggers", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.antlr", "JenkinsANTLRErrorListener", true, "JenkinsANTLRErrorListener", "(Supplier)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.groovy", "GroovyHookScript", true, "GroovyHookScript", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.groovy", "GroovyHookScript", true, "GroovyHookScript", "(String,ServletContext,File,ClassLoader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.groovy", "GroovyHookScript", true, "GroovyHookScript", "(String,ServletContext,File,ClassLoader)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.groovy", "GroovyHookScript", true, "GroovyHookScript", "(String,ServletContext,File,ClassLoader)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.groovy", "GroovyHookScript", true, "GroovyHookScript", "(String,ServletContext,File,ClassLoader)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.groovy", "GroovyHookScript", true, "bind", "(String,Object)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["jenkins.util.groovy", "GroovyHookScript", true, "getBindings", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.io", "CompositeIOException", true, "CompositeIOException", "(String,IOException[])", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.io", "CompositeIOException", true, "CompositeIOException", "(String,IOException[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.io", "CompositeIOException", true, "CompositeIOException", "(String,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.io", "CompositeIOException", true, "CompositeIOException", "(String,List)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.io", "CompositeIOException", true, "getExceptions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.io", "FileBoolean", true, "FileBoolean", "(Class,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.io", "FileBoolean", true, "FileBoolean", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.io", "PathRemover$RetryStrategy", true, "failureMessage", "(Path,int)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.io", "PathRemover", true, "newFilteredRobustRemover", "(PathChecker,int,boolean,long)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.io", "PathRemover", true, "newRemoverWithStrategy", "(RetryStrategy)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xml", "FilteredFunctionContext", true, "FilteredFunctionContext", "(Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM$WriterImpl", true, "getOutput", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "XStreamDOM", "(String,Map,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "XStreamDOM", "(String,Map,List)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "XStreamDOM", "(String,Map,List)", "", "Argument[2].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "XStreamDOM", "(String,Map,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "XStreamDOM", "(String,Map,String)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "XStreamDOM", "(String,Map,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "expandMacro", "(VariableResolver)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "expandMacro", "(VariableResolver)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "expandMacro", "(VariableResolver)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "getAttribute", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "getAttribute", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "getAttributeMap", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "getChildren", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "getTagName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", true, "getValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "AntClassLoader", true, "addPathFiles", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "AtmostOneTaskExecutor", true, "AtmostOneTaskExecutor", "(Callable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "AtmostOneTaskExecutor", true, "AtmostOneTaskExecutor", "(ExecutorService,Callable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "AtmostOneTaskExecutor", true, "AtmostOneTaskExecutor", "(ExecutorService,Callable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "AtmostOneTaskExecutor", true, "submit", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "BuildListenerAdapter", false, "BuildListenerAdapter", "(TaskListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "BuildListenerAdapter", false, "wrap", "(TaskListener)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "ContextResettingExecutorService", true, "ContextResettingExecutorService", "(ExecutorService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "ErrorLoggingExecutorService", true, "ErrorLoggingExecutorService", "(ExecutorService)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "JSONSignatureValidator", true, "JSONSignatureValidator", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "MemoryReductionUtil", true, "internInPlace", "(String[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "NonLocalizable", true, "NonLocalizable", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "NonLocalizable", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "ServerTcpPort", true, "ServerTcpPort", "(int,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.util", "SystemProperties", true, "getString", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "SystemProperties", true, "getString", "(String,String,Level)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "TreeString", false, "of", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "TreeString", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "TreeString", false, "toString", "(TreeString)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "TreeStringBuilder", true, "intern", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "TreeStringBuilder", true, "intern", "(TreeString)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "child", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "child", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "forFile", "(File)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "forFilePath", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "getParent", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "list", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "list", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "list", "(String,String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "list", "(String,String,boolean,boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "list", "(boolean)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "listOnlyDescendants", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "readLink", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.util", "VirtualFile", true, "toURI", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.websocket", "Provider$Listener", true, "getProviderSession", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.websocket", "Provider$Listener", true, "onWebSocketConnect", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.widgets", "HistoryPageEntry", true, "HistoryPageEntry", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.widgets", "HistoryPageEntry", true, "getEntry", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins.widgets", "HistoryPageFilter", true, "setSearchString", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins.widgets", "RunListProgressiveRendering", true, "setBuilds", "(Iterable)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins", "ExtensionRefreshException", true, "ExtensionRefreshException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins", "MissingDependencyException", true, "MissingDependencyException", "(String,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins", "MissingDependencyException", true, "MissingDependencyException", "(String,List)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["jenkins", "MissingDependencyException", true, "getMissingDependencies", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins", "MissingDependencyException", true, "getPluginShortName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["jenkins", "RestartRequiredException", true, "RestartRequiredException", "(Localizable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["jenkins", "RestartRequiredException", true, "RestartRequiredException", "(Localizable,Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.acls.sid", "GrantedAuthoritySid", true, "GrantedAuthoritySid", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.acls.sid", "GrantedAuthoritySid", true, "getGrantedAuthority", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.acls.sid", "GrantedAuthoritySid", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.acls.sid", "PrincipalSid", true, "PrincipalSid", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.acls.sid", "PrincipalSid", true, "getPrincipal", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.acls.sid", "PrincipalSid", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.context", "SecurityContext", true, "getAuthentication", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.context", "SecurityContext", true, "setAuthentication", "(Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.providers.anonymous", "AnonymousAuthenticationToken", true, "AnonymousAuthenticationToken", "(AnonymousAuthenticationToken)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.providers", "AbstractAuthenticationToken", true, "setDetails", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.providers", "UsernamePasswordAuthenticationToken", true, "UsernamePasswordAuthenticationToken", "(UsernamePasswordAuthenticationToken)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.ui.rememberme", "RememberMeServices", true, "fromSpring", "(RememberMeServices)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.ui.rememberme", "RememberMeServices", true, "toSpring", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,GrantedAuthority[])", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,GrantedAuthority[])", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,GrantedAuthority[])", "", "Argument[3].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,boolean,boolean,GrantedAuthority[])", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,boolean,boolean,GrantedAuthority[])", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,boolean,boolean,GrantedAuthority[])", "", "Argument[5].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,boolean,boolean,boolean,GrantedAuthority[])", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,boolean,boolean,boolean,GrantedAuthority[])", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "User", "(String,String,boolean,boolean,boolean,boolean,GrantedAuthority[])", "", "Argument[6].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "User", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", true, "fromSpring", "(UserDetails)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", true, "fromSpringPrincipal", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", true, "getAuthorities", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", true, "getPassword", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", true, "getUsername", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", true, "toSpring", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", true, "toSpringPrincipal", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetailsService", true, "loadUserByUsername", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity.userdetails", "UsernameNotFoundException", true, "UsernameNotFoundException", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity", "AccountExpiredException", true, "AccountExpiredException", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity", "AcegiSecurityException", true, "toSpring", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "Authentication", true, "fromSpring", "(Authentication)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "Authentication", true, "getAuthorities", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "Authentication", true, "getDetails", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "Authentication", true, "toSpring", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "AuthenticationException", true, "fromSpring", "(AuthenticationException)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "AuthenticationException", true, "getAuthentication", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "AuthenticationException", true, "getExtraInformation", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "AuthenticationException", true, "setAuthentication", "(Authentication)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity", "BadCredentialsException", true, "BadCredentialsException", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity", "CredentialsExpiredException", true, "CredentialsExpiredException", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity", "DisabledException", true, "DisabledException", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity", "GrantedAuthority", true, "getAuthority", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "GrantedAuthorityImpl", true, "GrantedAuthorityImpl", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.acegisecurity", "GrantedAuthorityImpl", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.acegisecurity", "LockedException", true, "LockedException", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "BuildStatusIcon", true, "BuildStatusIcon", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "BuildStatusIcon", true, "BuildStatusIcon", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "BuildStatusIcon", true, "BuildStatusIcon", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "BuildStatusIcon", true, "BuildStatusIcon", "(String,String,String,boolean)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "BuildStatusIcon", true, "BuildStatusIcon", "(String,String,String,boolean)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "BuildStatusIcon", true, "BuildStatusIcon", "(String,String,String,boolean)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconFormat)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconFormat)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconFormat)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconType)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconType)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconType)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconType,IconFormat)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconType,IconFormat)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "Icon", "(String,String,String,IconType,IconFormat)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "getClassSpec", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "getNormalizedSelector", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "getQualifiedUrl", "(JellyContext)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "getQualifiedUrl", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "getQualifiedUrl", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "getStyle", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "toNormalizedCSSSelector", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "toNormalizedIconName", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "toNormalizedIconNameClass", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "toNormalizedIconSizeClass", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", true, "toNormalizedIconUrl", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", true, "addIcon", "(Icon)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", true, "addIcon", "(Icon)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", true, "getCoreIcons", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", true, "getIconByClassSpec", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", true, "getIconByNormalizedCSSSelector", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", true, "getIconByUrl", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "IconType", false, "toQualifiedUrl", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "IconType", false, "toQualifiedUrl", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "WeatherIcon", true, "WeatherIcon", "(String,String,Status)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.icon", "WeatherIcon", true, "WeatherIcon", "(String,String,Status)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "build", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "getClasses", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "getHtmlTooltip", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "getPluginName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "getRaw", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "getTitle", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "getTooltip", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withClasses", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withClasses", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withHtmlTooltip", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withHtmlTooltip", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withId", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withId", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withName", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withPluginName", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withPluginName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withRaw", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withRaw", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withTitle", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withTitle", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withTooltip", "(String)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest$Builder", true, "withTooltip", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest", false, "getClasses", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest", false, "getHtmlTooltip", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest", false, "getId", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest", false, "getPluginName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest", false, "getTitle", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.jenkins.ui.symbol", "SymbolRequest", false, "getTooltip", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["antlr", "ANTLRException", "ANTLRException", "(String,Throwable)", "summary", "df-generated"] + - ["antlr", "ANTLRException", "ANTLRException", "(Throwable)", "summary", "df-generated"] + - ["executable", "Main", "whoAmI", "(File)", "summary", "df-generated"] + - ["hudson.cli.client", "Messages", "CLI_BadAuth", "()", "summary", "df-generated"] + - ["hudson.cli.client", "Messages", "CLI_NoSuchFileExists", "(Object)", "summary", "df-generated"] + - ["hudson.cli.client", "Messages", "CLI_NoURL", "()", "summary", "df-generated"] + - ["hudson.cli.client", "Messages", "CLI_Usage", "()", "summary", "df-generated"] + - ["hudson.cli.client", "Messages", "_CLI_BadAuth", "()", "summary", "df-generated"] + - ["hudson.cli.client", "Messages", "_CLI_NoSuchFileExists", "(Object)", "summary", "df-generated"] + - ["hudson.cli.client", "Messages", "_CLI_NoURL", "()", "summary", "df-generated"] + - ["hudson.cli.client", "Messages", "_CLI_Usage", "()", "summary", "df-generated"] + - ["hudson.cli.handlers", "AbstractItemOptionHandler", "AbstractItemOptionHandler", "(CmdLineParser,OptionDef,Setter)", "summary", "df-generated"] + - ["hudson.cli.handlers", "AbstractProjectOptionHandler", "AbstractProjectOptionHandler", "(CmdLineParser,OptionDef,Setter)", "summary", "df-generated"] + - ["hudson.cli.handlers", "JobOptionHandler", "JobOptionHandler", "(CmdLineParser,OptionDef,Setter)", "summary", "df-generated"] + - ["hudson.cli.handlers", "NodeOptionHandler", "NodeOptionHandler", "(CmdLineParser,OptionDef,Setter)", "summary", "df-generated"] + - ["hudson.cli.handlers", "ParameterizedJobOptionHandler", "ParameterizedJobOptionHandler", "(CmdLineParser,OptionDef,Setter)", "summary", "df-generated"] + - ["hudson.cli.handlers", "TopLevelItemOptionHandler", "TopLevelItemOptionHandler", "(CmdLineParser,OptionDef,Setter)", "summary", "df-generated"] + - ["hudson.cli.handlers", "ViewOptionHandler", "ViewOptionHandler", "(CmdLineParser,OptionDef,Setter)", "summary", "df-generated"] + - ["hudson.cli.handlers", "ViewOptionHandler", "getView", "(String)", "summary", "df-generated"] + - ["hudson.cli", "CLI", "_main", "(String[])", "summary", "df-generated"] + - ["hudson.cli", "CLI", "loadKey", "(File)", "summary", "df-generated"] + - ["hudson.cli", "CLI", "loadKey", "(File,String)", "summary", "df-generated"] + - ["hudson.cli", "CLI", "loadKey", "(String)", "summary", "df-generated"] + - ["hudson.cli", "CLI", "loadKey", "(String,String)", "summary", "df-generated"] + - ["hudson.cli", "CLIAction", "doCommand", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.cli", "CLIAction", "doWs", "()", "summary", "df-generated"] + - ["hudson.cli", "CLIAction", "isWebSocketSupported", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "all", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "checkChannel", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "clone", "(String)", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "getCurrent", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "getLongDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "getName", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "getShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "getSingleLineSummary", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "getUsage", "()", "summary", "df-generated"] + - ["hudson.cli", "CLICommand", "setClientCharset", "(Charset)", "summary", "df-generated"] + - ["hudson.cli", "CliTransportAuthenticator", "all", "()", "summary", "df-generated"] + - ["hudson.cli", "CliTransportAuthenticator", "authenticate", "(String,Channel,Connection)", "summary", "df-generated"] + - ["hudson.cli", "CliTransportAuthenticator", "supportsProtocol", "(String)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "Connection", "(Socket)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "close", "()", "summary", "df-generated"] + - ["hudson.cli", "Connection", "diffieHellman", "(boolean)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "diffieHellman", "(boolean,int)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "encryptConnection", "(SecretKey,String)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "fold", "(byte[],int)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "proveIdentity", "(byte[],KeyPair)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "readBoolean", "()", "summary", "df-generated"] + - ["hudson.cli", "Connection", "readKey", "()", "summary", "df-generated"] + - ["hudson.cli", "Connection", "readObject", "()", "summary", "df-generated"] + - ["hudson.cli", "Connection", "verifyIdentity", "(byte[])", "summary", "df-generated"] + - ["hudson.cli", "Connection", "writeBoolean", "(boolean)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "writeKey", "(Key)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "writeObject", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Connection", "writeUTF", "(String)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "AddJobToViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "BuildCommand_CLICause_CannotBuildConfigNotSaved", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "BuildCommand_CLICause_CannotBuildDisabled", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "BuildCommand_CLICause_CannotBuildUnknownReasons", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "BuildCommand_CLICause_ShortDescription", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "BuildCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "CancelQuietDownCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "ClearQueueCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "CliProtocol2_displayName", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "CliProtocol_displayName", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "ConnectNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "ConsoleCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "CopyJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "CreateJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "CreateNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "CreateViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DeleteBuildsCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DeleteJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DeleteNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DeleteViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DisablePluginCommand_NoSuchStrategy", "(Object,Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DisablePluginCommand_PrintUsageSummary", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DisablePluginCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DisablePluginCommand_StatusMessage", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "DisconnectNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "EnablePluginCommand_MissingDependencies", "(Object,Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "EnablePluginCommand_NoSuchPlugin", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "EnablePluginCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "GetJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "GetNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "GetViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "GroovyCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "GroovyshCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "HelpCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_DidYouMean", "(Object,Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_InstallingFromUpdateCenter", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_InstallingPluginFromLocalFile", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_InstallingPluginFromStdin", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_InstallingPluginFromUrl", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_NoUpdateCenterDefined", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_NoUpdateDataRetrieved", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_NotAValidSourceName", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "InstallPluginCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "ListChangesCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "ListJobsCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "ListPluginsCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "OfflineNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "OnlineNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "QuietDownCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "ReloadConfigurationCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "ReloadJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "RemoveJobFromViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "SessionIdCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "SetBuildDescriptionCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "SetBuildDisplayNameCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "UpdateJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "UpdateNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "UpdateViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "VersionCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "WaitNodeOfflineCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "WaitNodeOnlineCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "WhoAmICommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_AddJobToViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_BuildCommand_CLICause_CannotBuildConfigNotSaved", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_BuildCommand_CLICause_CannotBuildDisabled", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_BuildCommand_CLICause_CannotBuildUnknownReasons", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_BuildCommand_CLICause_ShortDescription", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_BuildCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_CancelQuietDownCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_ClearQueueCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_CliProtocol2_displayName", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_CliProtocol_displayName", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_ConnectNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_ConsoleCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_CopyJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_CreateJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_CreateNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_CreateViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DeleteBuildsCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DeleteJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DeleteNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DeleteViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DisablePluginCommand_NoSuchStrategy", "(Object,Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DisablePluginCommand_PrintUsageSummary", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DisablePluginCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DisablePluginCommand_StatusMessage", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_DisconnectNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_EnablePluginCommand_MissingDependencies", "(Object,Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_EnablePluginCommand_NoSuchPlugin", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_EnablePluginCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_GetJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_GetNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_GetViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_GroovyCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_GroovyshCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_HelpCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_DidYouMean", "(Object,Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_InstallingFromUpdateCenter", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_InstallingPluginFromLocalFile", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_InstallingPluginFromStdin", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_InstallingPluginFromUrl", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_NoUpdateCenterDefined", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_NoUpdateDataRetrieved", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_NotAValidSourceName", "(Object)", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_InstallPluginCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_ListChangesCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_ListJobsCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_ListPluginsCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_OfflineNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_OnlineNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_QuietDownCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_ReloadConfigurationCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_ReloadJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_RemoveJobFromViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_SessionIdCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_SetBuildDescriptionCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_SetBuildDisplayNameCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_UpdateJobCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_UpdateNodeCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_UpdateViewCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_VersionCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_WaitNodeOfflineCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_WaitNodeOnlineCommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "Messages", "_WhoAmICommand_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.cli", "PrivateKeyProvider", "hasKeys", "()", "summary", "df-generated"] + - ["hudson.cli", "PrivateKeyProvider", "loadKey", "(File,String)", "summary", "df-generated"] + - ["hudson.cli", "PrivateKeyProvider", "loadKey", "(String,String)", "summary", "df-generated"] + - ["hudson.cli", "PrivateKeyProvider", "readFrom", "(File)", "summary", "df-generated"] + - ["hudson.cli", "PrivateKeyProvider", "readFromDefaultLocations", "()", "summary", "df-generated"] + - ["hudson.console", "AnnotatedLargeText", "doProgressiveHtml", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.console", "AnnotatedLargeText", "doProgressiveText", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.console", "AnnotatedLargeText", "writeHtmlTo", "(long,Writer)", "summary", "df-generated"] + - ["hudson.console", "AnnotatedLargeText", "writeRawLogTo", "(long,OutputStream)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotationDescriptor", "all", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotationDescriptor", "doScriptJs", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotationDescriptor", "doStyleCss", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotationDescriptor", "hasScript", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotationDescriptor", "hasStylesheet", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotator", "_for", "(Object)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotator", "annotate", "(Object,MarkupText)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotator", "initial", "(Object)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotatorFactory", "all", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotatorFactory", "doScriptJs", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotatorFactory", "doStyleCss", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotatorFactory", "hasScript", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotatorFactory", "hasStylesheet", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotatorFactory", "newInstance", "(Object)", "summary", "df-generated"] + - ["hudson.console", "ConsoleAnnotatorFactory", "type", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleLogFilter", "all", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleNote", "annotate", "(Object,MarkupText,int)", "summary", "df-generated"] + - ["hudson.console", "ConsoleNote", "encode", "()", "summary", "df-generated"] + - ["hudson.console", "ConsoleNote", "encodeTo", "(OutputStream)", "summary", "df-generated"] + - ["hudson.console", "ConsoleNote", "encodeTo", "(Writer)", "summary", "df-generated"] + - ["hudson.console", "ConsoleNote", "findPreamble", "(byte[],int,int)", "summary", "df-generated"] + - ["hudson.console", "ConsoleNote", "readFrom", "(DataInputStream)", "summary", "df-generated"] + - ["hudson.console", "ConsoleNote", "skip", "(DataInputStream)", "summary", "df-generated"] + - ["hudson.console", "ExpandableDetailsNote", "encodeTo", "(String,String)", "summary", "df-generated"] + - ["hudson.console", "LineTransformationOutputStream", "forceEol", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "HudsonHomeDiskUsageMonitor$Solution", "all", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "HudsonHomeDiskUsageMonitor", "doAct", "(String)", "summary", "df-generated"] + - ["hudson.diagnosis", "HudsonHomeDiskUsageMonitor", "get", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "HudsonHomeDiskUsageMonitor", "getSolution", "(String)", "summary", "df-generated"] + - ["hudson.diagnosis", "HudsonHomeDiskUsageMonitor", "getSolutions", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "HsErrPidList_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "HudsonHomeDiskUsageMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "MemoryUsageMonitor_TOTAL", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "MemoryUsageMonitor_USED", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "NullIdDescriptorMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "OldDataMonitor_Description", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "OldDataMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "OldDataMonitor_OldDataTooltip", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "ReverseProxySetupMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "TooManyJobsButNoView_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_HsErrPidList_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_HudsonHomeDiskUsageMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_MemoryUsageMonitor_TOTAL", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_MemoryUsageMonitor_USED", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_NullIdDescriptorMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_OldDataMonitor_Description", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_OldDataMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_OldDataMonitor_OldDataTooltip", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_ReverseProxySetupMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "Messages", "_TooManyJobsButNoView_DisplayName", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "NullIdDescriptorMonitor", "verify", "()", "summary", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor$VersionRange", "isOld", "(int)", "summary", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", "doAct", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", "doDiscard", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", "doIndex", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", "doUpgrade", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", "report", "(Saveable,Collection)", "summary", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", "report", "(Saveable,String)", "summary", "df-generated"] + - ["hudson.diagnosis", "OldDataMonitor", "report", "(UnmarshallingContext,String)", "summary", "df-generated"] + - ["hudson.diagnosis", "ReverseProxySetupMonitor", "doAct", "(String)", "summary", "df-generated"] + - ["hudson.diagnosis", "ReverseProxySetupMonitor", "getTestForReverseProxySetup", "(String)", "summary", "df-generated"] + - ["hudson.diagnosis", "TooManyJobsButNoView", "doAct", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "WorkspaceSnapshotSCM_IncorrectJobType", "(Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "WorkspaceSnapshotSCM_NoBuild", "(Object,Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "WorkspaceSnapshotSCM_NoSuchJob", "(Object,Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "WorkspaceSnapshotSCM_NoSuchPermalink", "(Object,Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "WorkspaceSnapshotSCM_NoWorkspace", "(Object,Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "_WorkspaceSnapshotSCM_IncorrectJobType", "(Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "_WorkspaceSnapshotSCM_NoBuild", "(Object,Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "_WorkspaceSnapshotSCM_NoSuchJob", "(Object,Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "_WorkspaceSnapshotSCM_NoSuchPermalink", "(Object,Object)", "summary", "df-generated"] + - ["hudson.fsp", "Messages", "_WorkspaceSnapshotSCM_NoWorkspace", "(Object,Object)", "summary", "df-generated"] + - ["hudson.init.impl", "GroovyInitScript", "init", "(Jenkins)", "summary", "df-generated"] + - ["hudson.init.impl", "InitialUserContent", "init", "(Jenkins)", "summary", "df-generated"] + - ["hudson.init.impl", "InstallUncaughtExceptionHandler", "init", "(Jenkins)", "summary", "df-generated"] + - ["hudson.init.impl", "Messages", "GroovyInitScript_init", "()", "summary", "df-generated"] + - ["hudson.init.impl", "Messages", "InitialUserContent_init", "()", "summary", "df-generated"] + - ["hudson.init.impl", "Messages", "_GroovyInitScript_init", "()", "summary", "df-generated"] + - ["hudson.init.impl", "Messages", "_InitialUserContent_init", "()", "summary", "df-generated"] + - ["hudson.init", "InitMilestone", "ordering", "()", "summary", "df-generated"] + - ["hudson.init", "InitMilestone", "toString", "()", "summary", "df-generated"] + - ["hudson.init", "InitStrategy", "get", "(ClassLoader)", "summary", "df-generated"] + - ["hudson.init", "InitStrategy", "listPluginArchives", "(PluginManager)", "summary", "df-generated"] + - ["hudson.init", "InitStrategy", "skipInitTask", "(Task)", "summary", "df-generated"] + - ["hudson.init", "TaskMethodFinder$TaskImpl", "toString", "()", "summary", "df-generated"] + - ["hudson.init", "TermMilestone", "ordering", "()", "summary", "df-generated"] + - ["hudson.init", "TermMilestone", "toString", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "canRestart", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "canRewriteHudsonWar", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "get", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "getHudsonWar", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "onExtendTimeout", "(long,TimeUnit)", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "onReady", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "onReload", "(String,String)", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "onStatusUpdate", "(String)", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "onStop", "(String,String)", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "restart", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "rewriteHudsonWar", "(File)", "summary", "df-generated"] + - ["hudson.lifecycle", "Lifecycle", "verifyRestartable", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "WindowsInstallerLink_Description", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "WindowsInstallerLink_DisplayName", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "WindowsSlaveInstaller_ConfirmInstallation", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "WindowsSlaveInstaller_DotNetRequired", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "WindowsSlaveInstaller_InstallationSuccessful", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "WindowsSlaveInstaller_RootFsDoesntExist", "(Object)", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "_WindowsInstallerLink_Description", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "_WindowsInstallerLink_DisplayName", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "_WindowsSlaveInstaller_ConfirmInstallation", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "_WindowsSlaveInstaller_DotNetRequired", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "_WindowsSlaveInstaller_InstallationSuccessful", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "Messages", "_WindowsSlaveInstaller_RootFsDoesntExist", "(Object)", "summary", "df-generated"] + - ["hudson.lifecycle", "RestartNotSupportedException", "RestartNotSupportedException", "(String,Throwable)", "summary", "df-generated"] + - ["hudson.lifecycle", "WindowsInstallerLink", "doRestart", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.lifecycle", "WindowsInstallerLink", "isInstalled", "()", "summary", "df-generated"] + - ["hudson.lifecycle", "WindowsInstallerLink", "registerIfApplicable", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", "disable", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", "enable", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", "getLevel", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", "includes", "(LogRecord)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder$Target", "matches", "(LogRecord)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "doAutoCompleteLoggerName", "(String)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "doCheckName", "(String,String)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "doClear", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "doConfigSubmit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "doDoDelete", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "doRss", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "getLogRecords", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "getParent", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "getSlaveLogRecords", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorder", "load", "()", "summary", "df-generated"] + - ["hudson.logging", "LogRecorderManager", "doCheckNewName", "(String)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorderManager", "doConfigLogger", "(String,String)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorderManager", "doNewLogRecorder", "(String)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorderManager", "doRss", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorderManager", "init", "(Jenkins)", "summary", "df-generated"] + - ["hudson.logging", "LogRecorderManager", "load", "()", "summary", "df-generated"] + - ["hudson.logging", "Messages", "LogRecorderManager_DisplayName", "()", "summary", "df-generated"] + - ["hudson.logging", "Messages", "LogRecorderManager_LoggerNotFound", "(Object)", "summary", "df-generated"] + - ["hudson.logging", "Messages", "LogRecorderManager_init", "()", "summary", "df-generated"] + - ["hudson.logging", "Messages", "LogRecorder_Target_Empty_Warning", "()", "summary", "df-generated"] + - ["hudson.logging", "Messages", "_LogRecorderManager_DisplayName", "()", "summary", "df-generated"] + - ["hudson.logging", "Messages", "_LogRecorderManager_LoggerNotFound", "(Object)", "summary", "df-generated"] + - ["hudson.logging", "Messages", "_LogRecorderManager_init", "()", "summary", "df-generated"] + - ["hudson.logging", "Messages", "_LogRecorder_Target_Empty_Warning", "()", "summary", "df-generated"] + - ["hudson.markup", "MarkupFormatter", "doPreviewDescription", "(String)", "summary", "df-generated"] + - ["hudson.markup", "MarkupFormatter", "getHelpUrl", "()", "summary", "df-generated"] + - ["hudson.markup", "MarkupFormatter", "previewsNowNeedPostForSecurity2153", "(String,StaplerRequest)", "summary", "df-generated"] + - ["hudson.markup", "MarkupFormatter", "translate", "(String)", "summary", "df-generated"] + - ["hudson.markup", "MarkupFormatter", "translate", "(String,Writer)", "summary", "df-generated"] + - ["hudson.markup", "MarkupFormatterDescriptor", "all", "()", "summary", "df-generated"] + - ["hudson.markup", "Messages", "EscapedMarkupFormatter_DisplayName", "()", "summary", "df-generated"] + - ["hudson.markup", "Messages", "_EscapedMarkupFormatter_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAssignmentAction", "getAssignedLabel", "(SubTask)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtom", "doConfigSubmit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtom", "doSubmitDescription", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtom", "escape", "(String)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtom", "findNearest", "(String)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtom", "getApplicablePropertyDescriptors", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtom", "getPropertiesList", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtom", "load", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtom", "needsEscape", "(String)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtomProperty", "all", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelAtomProperty", "getActions", "(LabelAtom)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpression", "autoComplete", "(String)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpression", "validate", "(String)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpression", "validate", "(String,Item)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionLexer", "LabelExpressionLexer", "(CharStream)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$ExprContext", "EOF", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$ExprContext", "ExprContext", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$ExprContext", "term1", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term1Context", "IFF", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term1Context", "IFF", "(int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term1Context", "Term1Context", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term1Context", "term2", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term1Context", "term2", "(int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term2Context", "IMPLIES", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term2Context", "Term2Context", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term2Context", "term3", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term2Context", "term3", "(int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term3Context", "OR", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term3Context", "OR", "(int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term3Context", "Term3Context", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term3Context", "term4", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term3Context", "term4", "(int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term4Context", "AND", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term4Context", "AND", "(int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term4Context", "Term4Context", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term4Context", "term5", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term4Context", "term5", "(int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term5Context", "NOT", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term5Context", "Term5Context", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term5Context", "term6", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term6Context", "ATOM", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term6Context", "LPAREN", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term6Context", "RPAREN", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term6Context", "STRINGLITERAL", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term6Context", "Term6Context", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser$Term6Context", "term1", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser", "LabelExpressionParser", "(TokenStream)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser", "expr", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser", "term1", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser", "term2", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser", "term3", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser", "term4", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser", "term5", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParser", "term6", "()", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "enterExpr", "(ExprContext)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "enterTerm1", "(Term1Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "enterTerm2", "(Term2Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "enterTerm3", "(Term3Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "enterTerm4", "(Term4Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "enterTerm5", "(Term5Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "enterTerm6", "(Term6Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "exitExpr", "(ExprContext)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "exitTerm1", "(Term1Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "exitTerm2", "(Term2Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "exitTerm3", "(Term3Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "exitTerm4", "(Term4Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "exitTerm5", "(Term5Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelExpressionParserListener", "exitTerm6", "(Term6Context)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelVisitor", "onAnd", "(And,Object)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelVisitor", "onAtom", "(LabelAtom,Object)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelVisitor", "onIff", "(Iff,Object)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelVisitor", "onImplies", "(Implies,Object)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelVisitor", "onNot", "(Not,Object)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelVisitor", "onOr", "(Or,Object)", "summary", "df-generated"] + - ["hudson.model.labels", "LabelVisitor", "onParen", "(Paren,Object)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "all", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "checkBeforeCopy", "(Item,ItemGroup)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "fireLocationChange", "(Item,String)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "fireOnCopied", "(Item,Item)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "fireOnCreated", "(Item)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "fireOnDeleted", "(Item)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "fireOnUpdated", "(Item)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onBeforeShutdown", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onCheckCopy", "(Item,ItemGroup)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onCopied", "(Item,Item)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onCreated", "(Item)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onDeleted", "(Item)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onLoaded", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onLocationChanged", "(Item,String,String)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onRenamed", "(Item,String,String)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "onUpdated", "(Item)", "summary", "df-generated"] + - ["hudson.model.listeners", "ItemListener", "register", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "all", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "fireCompleted", "(Run,TaskListener)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "fireDeleted", "(Run)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "fireFinalized", "(Run)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "fireInitialize", "(Run)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "fireStarted", "(Run,TaskListener)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "onCompleted", "(Run,TaskListener)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "onDeleted", "(Run)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "onFinalized", "(Run)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "onInitialize", "(Run)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "onStarted", "(Run,TaskListener)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "register", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "setUpEnvironment", "(AbstractBuild,Launcher,BuildListener)", "summary", "df-generated"] + - ["hudson.model.listeners", "RunListener", "unregister", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMListener", "all", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMListener", "onChangeLogParsed", "(AbstractBuild,BuildListener,ChangeLogSet)", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMListener", "onChangeLogParsed", "(Run,SCM,TaskListener,ChangeLogSet)", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMListener", "onCheckout", "(Run,SCM,FilePath,TaskListener,File,SCMRevisionState)", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMListener", "register", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMListener", "unregister", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMPollListener", "all", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMPollListener", "fireBeforePolling", "(AbstractProject,TaskListener)", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMPollListener", "firePollingFailed", "(AbstractProject,TaskListener,Throwable)", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMPollListener", "firePollingSuccess", "(AbstractProject,TaskListener,PollingResult)", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMPollListener", "onBeforePolling", "(AbstractProject,TaskListener)", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMPollListener", "onPollingFailed", "(AbstractProject,TaskListener,Throwable)", "summary", "df-generated"] + - ["hudson.model.listeners", "SCMPollListener", "onPollingSuccess", "(AbstractProject,TaskListener,PollingResult)", "summary", "df-generated"] + - ["hudson.model.listeners", "SaveableListener", "all", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "SaveableListener", "fireOnChange", "(Saveable,XmlFile)", "summary", "df-generated"] + - ["hudson.model.listeners", "SaveableListener", "onChange", "(Saveable,XmlFile)", "summary", "df-generated"] + - ["hudson.model.listeners", "SaveableListener", "register", "()", "summary", "df-generated"] + - ["hudson.model.listeners", "SaveableListener", "unregister", "()", "summary", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage", "fromMessage", "(Localizable)", "summary", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage", "getShortDescription", "()", "summary", "df-generated"] + - ["hudson.model.queue", "CauseOfBlockage", "print", "(TaskListener)", "summary", "df-generated"] + - ["hudson.model.queue", "Executables", "getEstimatedDurationFor", "(Executable)", "summary", "df-generated"] + - ["hudson.model.queue", "FoldableAction", "foldIntoExisting", "(Item,Task,List)", "summary", "df-generated"] + - ["hudson.model.queue", "FutureLoad", "FutureLoad", "(long,long,int)", "summary", "df-generated"] + - ["hudson.model.queue", "FutureLoad", "toString", "()", "summary", "df-generated"] + - ["hudson.model.queue", "LoadPredictor", "all", "()", "summary", "df-generated"] + - ["hudson.model.queue", "LoadPredictor", "predict", "(Computer,long,long)", "summary", "df-generated"] + - ["hudson.model.queue", "LoadPredictor", "predict", "(MappingWorksheet,Computer,long,long)", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$ExecutorChunk", "canAccept", "(WorkChunk)", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$ExecutorChunk", "capacity", "()", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$ExecutorSlot", "getExecutor", "()", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$ExecutorSlot", "isAvailable", "()", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", "execute", "(WorkUnitContext)", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", "get", "(int)", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", "isCompletelyValid", "()", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", "isPartiallyValid", "()", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$Mapping", "size", "()", "summary", "df-generated"] + - ["hudson.model.queue", "MappingWorksheet$WorkChunk", "applicableExecutorChunks", "()", "summary", "df-generated"] + - ["hudson.model.queue", "Messages", "QueueSorter_installDefaultQueueSorter", "()", "summary", "df-generated"] + - ["hudson.model.queue", "Messages", "_QueueSorter_installDefaultQueueSorter", "()", "summary", "df-generated"] + - ["hudson.model.queue", "QueueListener", "all", "()", "summary", "df-generated"] + - ["hudson.model.queue", "QueueListener", "onEnterBlocked", "(BlockedItem)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueListener", "onEnterBuildable", "(BuildableItem)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueListener", "onEnterWaiting", "(WaitingItem)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueListener", "onLeaveBlocked", "(BlockedItem)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueListener", "onLeaveBuildable", "(BuildableItem)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueListener", "onLeaveWaiting", "(WaitingItem)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueListener", "onLeft", "(LeftItem)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueSorter", "all", "()", "summary", "df-generated"] + - ["hudson.model.queue", "QueueSorter", "installDefaultQueueSorter", "()", "summary", "df-generated"] + - ["hudson.model.queue", "QueueSorter", "sortBlockedItems", "(List)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueSorter", "sortBuildableItems", "(List)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueTaskDispatcher", "all", "()", "summary", "df-generated"] + - ["hudson.model.queue", "QueueTaskDispatcher", "canRun", "(Item)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueTaskDispatcher", "canTake", "(Node,BuildableItem)", "summary", "df-generated"] + - ["hudson.model.queue", "QueueTaskDispatcher", "canTake", "(Node,Task)", "summary", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", "getCreateItem", "()", "summary", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", "getItem", "()", "summary", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", "isAccepted", "()", "summary", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", "isCreated", "()", "summary", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", "isRefused", "()", "summary", "df-generated"] + - ["hudson.model.queue", "ScheduleResult", "refused", "()", "summary", "df-generated"] + - ["hudson.model.queue", "SubTask", "createExecutable", "()", "summary", "df-generated"] + - ["hudson.model.queue", "SubTask", "getAssignedLabel", "()", "summary", "df-generated"] + - ["hudson.model.queue", "SubTask", "getEstimatedDuration", "()", "summary", "df-generated"] + - ["hudson.model.queue", "SubTask", "getLastBuiltOn", "()", "summary", "df-generated"] + - ["hudson.model.queue", "SubTask", "getOwnerExecutable", "()", "summary", "df-generated"] + - ["hudson.model.queue", "SubTask", "getSameNodeConstraint", "()", "summary", "df-generated"] + - ["hudson.model.queue", "SubTaskContributor", "all", "()", "summary", "df-generated"] + - ["hudson.model.queue", "SubTaskContributor", "forProject", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model.queue", "Tasks", "getAuthenticationOf2", "(Task)", "summary", "df-generated"] + - ["hudson.model.queue", "Tasks", "getAuthenticationOf", "(Task)", "summary", "df-generated"] + - ["hudson.model.queue", "Tasks", "getDefaultAuthenticationOf", "(Task)", "summary", "df-generated"] + - ["hudson.model.queue", "Tasks", "getDefaultAuthenticationOf", "(Task,Item)", "summary", "df-generated"] + - ["hudson.model.queue", "WorkUnit", "isMainWork", "()", "summary", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", "synchronizeEnd", "(Executable,Throwable,long)", "summary", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", "synchronizeEnd", "(Executor,Executable,Throwable,long)", "summary", "df-generated"] + - ["hudson.model.queue", "WorkUnitContext", "synchronizeStart", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild$AbstractBuildExecution", "defaultCheckout", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild$DependencyChange", "getBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "doStop", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "doStop", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "due", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getAggregatedTestResultAction", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getBuildVariableResolver", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getBuildVariables", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getBuiltOn", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getDependencyChanges", "(AbstractBuild)", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getDownstreamBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getDownstreamBuilds", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getDownstreamRelationship", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getSensitiveBuildVariables", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getTestResultAction", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getTransitiveUpstreamBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getUpUrl", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getUpstreamBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getUpstreamRelationship", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "getUpstreamRelationshipBuild", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "AbstractBuild", "hasChangeSetComputed", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractCIBase", "getNodes", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractCIBase", "getQueue", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "doCheckNewName", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "doConfigDotXml", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "doDoDelete", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "doReload", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "doSubmitDescription", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "getPronoun", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "getTaskNoun", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "isNameEditable", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "resolveForCLI", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "updateByXml", "(Source)", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "updateByXml", "(StreamSource)", "summary", "df-generated"] + - ["hudson.model", "AbstractItem", "writeConfigDotXml", "(OutputStream)", "summary", "df-generated"] + - ["hudson.model", "AbstractModelObject", "makeSearchIndex", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$AbstractProjectDescriptor", "doAutoCompleteAssignedLabelString", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$AbstractProjectDescriptor", "doAutoCompleteLabel", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$AbstractProjectDescriptor", "doAutoCompleteUpstreamProjects", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$AbstractProjectDescriptor", "doCheckAssignedLabelString", "(AbstractProject,String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$AbstractProjectDescriptor", "doCheckCustomWorkspace", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$AbstractProjectDescriptor", "doCheckLabel", "(AbstractProject,String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$AbstractProjectDescriptor", "getApplicableSCMCheckoutStrategyDescriptors", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$AbstractProjectDescriptor", "validateLabelExpression", "(String,AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$LabelValidator", "check", "(AbstractProject,Label)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject$LabelValidator", "checkItem", "(Item,Label)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "blockBuildWhenDownstreamBuilding", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "blockBuildWhenUpstreamBuilding", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "checkout", "(AbstractBuild,Launcher,BuildListener,File)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "disable", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "doBuild", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "doBuildWithParameters", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "doCheckRetryCount", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "doDoWipeOutWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "enable", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "findNearest", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "findNearest", "(String,ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getBuildTriggerUpstreamProjects", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getBuildingDownstream", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getBuildingUpstream", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getDelay", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getDownstreamProjects", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getDownstreamProjectsForApi", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getHasCustomQuietPeriod", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getJDK", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getModuleRoot", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getModuleRoots", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getProminentActions", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getPublishersList", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getRelationship", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getScmCheckoutRetryCount", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getSomeBuildWithWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getSomeWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getTransitiveDownstreamProjects", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getTransitiveUpstreamProjects", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getTrigger", "(Class)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getUpstreamProjects", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getUpstreamProjectsForApi", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "getWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "hasCustomScmCheckoutRetryCount", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "hasParticipant", "(User)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "isConfigurable", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "isFingerprintConfigured", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "poll", "(TaskListener)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "pollSCMChanges", "(TaskListener)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "removeTrigger", "(TriggerDescriptor)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "resolveForCLI", "(String)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "scheduleBuild2", "(int)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "scheduleBuild2", "(int,Cause)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "scheduleBuild2", "(int,Cause,Action[])", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "scheduleBuild2", "(int,Cause,Collection)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "scheduleBuild", "(int,Cause,Action[])", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "schedulePolling", "()", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "setAssignedLabel", "(Label)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "setAssignedNode", "(Node)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "setBlockBuildWhenDownstreamBuilding", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "setBlockBuildWhenUpstreamBuilding", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "setConcurrentBuild", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "AbstractProject", "setQuietPeriod", "(Integer)", "summary", "df-generated"] + - ["hudson.model", "Action", "getIconFileName", "()", "summary", "df-generated"] + - ["hudson.model", "Action", "getUrlName", "()", "summary", "df-generated"] + - ["hudson.model", "Actionable", "getAction", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Actionable", "getActions", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Actionable", "removeAction", "(Action)", "summary", "df-generated"] + - ["hudson.model", "Actionable", "removeActions", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Actionable", "replaceActions", "(Class,Action)", "summary", "df-generated"] + - ["hudson.model", "AdministrativeMonitor", "all", "()", "summary", "df-generated"] + - ["hudson.model", "AdministrativeMonitor", "disable", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "AdministrativeMonitor", "doDisable", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "AdministrativeMonitor", "getRequiredPermission", "()", "summary", "df-generated"] + - ["hudson.model", "AdministrativeMonitor", "isActivated", "()", "summary", "df-generated"] + - ["hudson.model", "AdministrativeMonitor", "isEnabled", "()", "summary", "df-generated"] + - ["hudson.model", "AdministrativeMonitor", "isSecurity", "()", "summary", "df-generated"] + - ["hudson.model", "AperiodicWork", "all", "()", "summary", "df-generated"] + - ["hudson.model", "AperiodicWork", "doAperiodicRun", "()", "summary", "df-generated"] + - ["hudson.model", "AperiodicWork", "getInitialDelay", "()", "summary", "df-generated"] + - ["hudson.model", "AperiodicWork", "getNewInstance", "()", "summary", "df-generated"] + - ["hudson.model", "AperiodicWork", "getRecurrencePeriod", "()", "summary", "df-generated"] + - ["hudson.model", "AperiodicWork", "init", "()", "summary", "df-generated"] + - ["hudson.model", "Api", "doJson", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Api", "doPython", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Api", "doSchema", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Api", "doXml", "(StaplerRequest,StaplerResponse,String,String,String,int)", "summary", "df-generated"] + - ["hudson.model", "AsyncPeriodicWork", "execute", "(TaskListener)", "summary", "df-generated"] + - ["hudson.model", "AutoCompletionCandidates", "ofJobNames", "(Class,String,Item,ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "AutoCompletionCandidates", "ofJobNames", "(Class,String,ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "BallColor", "getBaseColor", "()", "summary", "df-generated"] + - ["hudson.model", "BallColor", "getHtmlBaseColor", "()", "summary", "df-generated"] + - ["hudson.model", "BallColor", "getIconClassName", "()", "summary", "df-generated"] + - ["hudson.model", "BallColor", "getIconName", "()", "summary", "df-generated"] + - ["hudson.model", "BallColor", "getImage", "()", "summary", "df-generated"] + - ["hudson.model", "BallColor", "isAnimated", "()", "summary", "df-generated"] + - ["hudson.model", "BallColor", "toString", "()", "summary", "df-generated"] + - ["hudson.model", "BooleanParameterDefinition", "isDefaultValue", "()", "summary", "df-generated"] + - ["hudson.model", "BooleanParameterDefinition", "setDefaultValue", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "BuildAuthorizationToken", "checkPermission", "(AbstractProject,BuildAuthorizationToken,StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "BuildAuthorizationToken", "checkPermission", "(Job,BuildAuthorizationToken,StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "BuildAuthorizationToken", "create", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "BuildListener", "finished", "(Result)", "summary", "df-generated"] + - ["hudson.model", "BuildListener", "started", "(List)", "summary", "df-generated"] + - ["hudson.model", "BuildStepListener", "all", "()", "summary", "df-generated"] + - ["hudson.model", "BuildStepListener", "finished", "(AbstractBuild,BuildStep,BuildListener,boolean)", "summary", "df-generated"] + - ["hudson.model", "BuildStepListener", "started", "(AbstractBuild,BuildStep,BuildListener)", "summary", "df-generated"] + - ["hudson.model", "BuildTimelineWidget", "doData", "(StaplerRequest,long,long)", "summary", "df-generated"] + - ["hudson.model", "BuildVariableContributor", "all", "()", "summary", "df-generated"] + - ["hudson.model", "BuildVariableContributor", "buildVariablesFor", "(AbstractBuild,Map)", "summary", "df-generated"] + - ["hudson.model", "BuildableItem", "scheduleBuild", "()", "summary", "df-generated"] + - ["hudson.model", "BuildableItem", "scheduleBuild", "(Cause)", "summary", "df-generated"] + - ["hudson.model", "BuildableItem", "scheduleBuild", "(int)", "summary", "df-generated"] + - ["hudson.model", "BuildableItem", "scheduleBuild", "(int,Cause)", "summary", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause$DeeplyNestedUpstreamCause", "toString", "()", "summary", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", "getUpstreamBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", "getUpstreamRun", "()", "summary", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", "pointsTo", "(Job)", "summary", "df-generated"] + - ["hudson.model", "Cause$UpstreamCause", "pointsTo", "(Run)", "summary", "df-generated"] + - ["hudson.model", "Cause", "getShortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Cause", "onLoad", "(Job,int)", "summary", "df-generated"] + - ["hudson.model", "Cause", "print", "(TaskListener)", "summary", "df-generated"] + - ["hudson.model", "CauseAction", "findCause", "(Class)", "summary", "df-generated"] + - ["hudson.model", "CauseAction", "getShortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "CheckPoint", "block", "()", "summary", "df-generated"] + - ["hudson.model", "CheckPoint", "block", "(BuildListener,String)", "summary", "df-generated"] + - ["hudson.model", "CheckPoint", "report", "()", "summary", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition$DescriptorImpl", "doCheckChoices", "(String)", "summary", "df-generated"] + - ["hudson.model", "ChoiceParameterDefinition", "areValidChoices", "(String)", "summary", "df-generated"] + - ["hudson.model", "Computer$TerminationRequest", "getWhen", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "buildEnvironment", "(TaskListener)", "summary", "df-generated"] + - ["hudson.model", "Computer", "cliConnect", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "Computer", "cliOnline", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "countBusy", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "countExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "countIdle", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "currentComputer", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "disconnect", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "doChangeOfflineCause", "(String)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doConfigDotXml", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doConfigSubmit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doDoDelete", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "doDumpExportTable", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doLaunchSlaveAgent", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doProgressiveLog", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doRssAll", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doRssFailed", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doRssLatest", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doScript", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doScriptText", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Computer", "doToggleOffline", "(String)", "summary", "df-generated"] + - ["hudson.model", "Computer", "getAssignedLabels", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getCaption", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getChannel", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getConnectTime", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getDefaultCharset", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getDemandStartMilliseconds", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getIcon", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getIconAltText", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getIconClassName", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getIdleStartMilliseconds", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getLoadStatistics", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getLog", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getLogRecords", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getMonitorData", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getName", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getNode", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getNumExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getOfflineCauseReason", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getRetentionStrategy", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getSystemProperties", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getThreadDump", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getTiedJobs", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getTimeline", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "getUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "interrupt", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isAcceptingTasks", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isConnecting", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isIdle", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isJnlpAgent", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isLaunchSupported", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isManualLaunchAllowed", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isOffline", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isOnline", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isPartiallyIdle", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isTemporarilyOffline", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "isUnix", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "launch", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "recordTermination", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "relocateOldLogs", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "resolveForCLI", "(String)", "summary", "df-generated"] + - ["hudson.model", "Computer", "setTemporarilyOffline", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "Computer", "updateByXml", "(InputStream)", "summary", "df-generated"] + - ["hudson.model", "Computer", "waitUntilOffline", "()", "summary", "df-generated"] + - ["hudson.model", "Computer", "waitUntilOnline", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerPinger", "all", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerPinger", "checkIsReachable", "(InetAddress,int)", "summary", "df-generated"] + - ["hudson.model", "ComputerPinger", "isReachable", "(InetAddress,int)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet$DescriptorImpl", "doAutoCompleteCopyNewItemFrom", "(String)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "checkName", "(String)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "doCheckName", "(String)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "doConfigSubmit", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "doCreateItem", "(StaplerRequest,StaplerResponse,String,String,String)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "doDoCreateItem", "(StaplerRequest,StaplerResponse,String,String)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "doUpdateNow", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "do_launchAll", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "getBusyExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "getComputerNames", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "getDynamic", "(String,StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "getIdleExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "getMonitors", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "getNodeMonitorDescriptors", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "getNonIgnoredMonitors", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "getTotalExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "get_all", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "get_monitors", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "get_slaveNames", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "init", "()", "summary", "df-generated"] + - ["hudson.model", "ComputerSet", "initialize", "()", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph$Dependency", "pointsItself", "()", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph$Dependency", "shouldTriggerBuild", "(AbstractBuild,TaskListener,List)", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph", "addDependency", "(AbstractProject,AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph", "addDependency", "(AbstractProject,Collection)", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph", "addDependency", "(Collection,AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph", "addDependency", "(Dependency)", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph", "addDependencyDeclarers", "(AbstractProject,Collection)", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph", "build", "()", "summary", "df-generated"] + - ["hudson.model", "DependencyGraph", "hasIndirectDependencies", "(AbstractProject,AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "Descriptor$PropertyType", "getApplicableDescriptors", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor$PropertyType", "getApplicableItemDescriptors", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor$PropertyType", "getEnumConstants", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor$PropertyType", "getItemType", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor$PropertyType", "getItemTypeDescriptor", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor$PropertyType", "getItemTypeDescriptorOrDie", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "bindJSON", "(StaplerRequest,Class,JSONObject)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "calcAutoCompleteSettings", "(String,Map)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "calcFillSettings", "(String,Map)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "configure", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "configure", "(StaplerRequest,JSONObject)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "doHelp", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "find", "(String)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getCategory", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getConfigPage", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getCurrentDescriptorByNameUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getDescriptorFullUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getDescriptorUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getDisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getGlobalConfigPage", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getId", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getJsonSafeClassName", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getKlass", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getRequiredGlobalConfigPagePermission", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "getT", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "isInstance", "(Describable)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "isSubTypeOf", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "load", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "newInstance", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "newInstance", "(StaplerRequest,JSONObject)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "newInstancesFromHeteroList", "(StaplerRequest,JSONObject,String,Collection)", "summary", "df-generated"] + - ["hudson.model", "Descriptor", "newInstancesFromHeteroList", "(StaplerRequest,Object,Collection)", "summary", "df-generated"] + - ["hudson.model", "Descriptor<CrumbIssuer>", "getDisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Descriptor<GlobalConfiguration>", "load", "()", "summary", "df-generated"] + - ["hudson.model", "DescriptorByNameOwner", "getDescriptorByName", "(String)", "summary", "df-generated"] + - ["hudson.model", "DescriptorVisibilityFilter", "all", "()", "summary", "df-generated"] + - ["hudson.model", "DescriptorVisibilityFilter", "filter", "(Object,Descriptor)", "summary", "df-generated"] + - ["hudson.model", "DescriptorVisibilityFilter", "filterType", "(Class,Descriptor)", "summary", "df-generated"] + - ["hudson.model", "DirectlyModifiableView", "doAddJobToView", "(String)", "summary", "df-generated"] + - ["hudson.model", "DirectlyModifiableView", "doRemoveJobFromView", "(String)", "summary", "df-generated"] + - ["hudson.model", "DirectlyModifiableView", "remove", "(TopLevelItem)", "summary", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", "getIconClassName", "()", "summary", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", "getIconName", "()", "summary", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", "getLastModified", "()", "summary", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", "getLastModifiedAsCalendar", "()", "summary", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", "getSize", "()", "summary", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", "isFolder", "()", "summary", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport$Path", "isReadable", "()", "summary", "df-generated"] + - ["hudson.model", "DirectoryBrowserSupport", "serveFile", "(StaplerRequest,StaplerResponse,FilePath,String,boolean)", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "Downloadable", "(Class)", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "all", "()", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "get", "(Class)", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "get", "(String)", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "getData", "()", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "getDue", "()", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "getInterval", "()", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "hasDuplicates", "(List,String)", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "idFor", "(Class)", "summary", "df-generated"] + - ["hudson.model", "DownloadService$Downloadable", "updateNow", "()", "summary", "df-generated"] + - ["hudson.model", "DownloadService$DownloadableListener", "installListener", "()", "summary", "df-generated"] + - ["hudson.model", "DownloadService", "generateFragment", "()", "summary", "df-generated"] + - ["hudson.model", "DownloadService", "getById", "(String)", "summary", "df-generated"] + - ["hudson.model", "DownloadService", "loadJSON", "(URL)", "summary", "df-generated"] + - ["hudson.model", "DownloadService", "loadJSONHTML", "(URL)", "summary", "df-generated"] + - ["hudson.model", "Environment", "buildEnvVars", "(Map)", "summary", "df-generated"] + - ["hudson.model", "Environment", "create", "(EnvVars)", "summary", "df-generated"] + - ["hudson.model", "Environment", "tearDown", "(AbstractBuild,BuildListener)", "summary", "df-generated"] + - ["hudson.model", "EnvironmentContributor", "all", "()", "summary", "df-generated"] + - ["hudson.model", "EnvironmentContributor", "buildEnvironmentFor", "(Job,EnvVars,TaskListener)", "summary", "df-generated"] + - ["hudson.model", "EnvironmentContributor", "buildEnvironmentFor", "(Run,EnvVars,TaskListener)", "summary", "df-generated"] + - ["hudson.model", "EnvironmentList", "get", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Executor", "completedAsynchronous", "(Throwable)", "summary", "df-generated"] + - ["hudson.model", "Executor", "currentExecutor", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "doStop", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "doStop", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Executor", "doStopBuild", "(String)", "summary", "df-generated"] + - ["hudson.model", "Executor", "doYank", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getCauseOfDeath", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getElapsedTime", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getEstimatedDurationFor", "(Executable)", "summary", "df-generated"] + - ["hudson.model", "Executor", "getEstimatedRemainingTime", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getEstimatedRemainingTimeMillis", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getIdleStartMilliseconds", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getProgress", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getTimeSpentInQueue", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "getTimestampString", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "hasStopPermission", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "isActive", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "isBusy", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "isDisplayCell", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "isIdle", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "isLikelyStuck", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "isParking", "()", "summary", "df-generated"] + - ["hudson.model", "Executor", "newImpersonatingProxy", "(Class,Object)", "summary", "df-generated"] + - ["hudson.model", "Executor", "of", "(Executable)", "summary", "df-generated"] + - ["hudson.model", "Executor", "recordCauseOfInterruption", "(Run,TaskListener)", "summary", "df-generated"] + - ["hudson.model", "ExecutorListener", "taskAccepted", "(Executor,Task)", "summary", "df-generated"] + - ["hudson.model", "ExecutorListener", "taskCompleted", "(Executor,Task,long)", "summary", "df-generated"] + - ["hudson.model", "ExecutorListener", "taskCompletedWithProblems", "(Executor,Task,long,Throwable)", "summary", "df-generated"] + - ["hudson.model", "ExecutorListener", "taskStarted", "(Executor,Task)", "summary", "df-generated"] + - ["hudson.model", "Failure", "generateResponse", "(StaplerRequest,StaplerResponse,Object,Throwable)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", "belongsTo", "(Job)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", "getJob", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", "getNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", "getRun", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", "is", "(Job)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$BuildPtr", "is", "(Run)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "Range", "(int,int)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "combine", "(Range)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "contains", "(Range)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "expandLeft", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "expandRight", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "getEnd", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "getStart", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "includes", "(int)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "intersect", "(Range)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "isAdjacentTo", "(Range)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "isBiggerThan", "(int)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "isDisjoint", "(Range)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "isIndependent", "(Range)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "isSingle", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "isSmallerThan", "(int)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$Range", "toString", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet$ConverterImpl", "serialize", "(RangeSet)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "add", "(int)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "addAll", "(int[])", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "fromString", "(String,boolean)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "includes", "(int)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "isEmpty", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "isSmallerThan", "(int)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "listNumbers", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "listNumbersReverse", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "max", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "min", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "removeAll", "(RangeSet)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint$RangeSet", "retainAll", "(RangeSet)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "delete", "(String)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "getActions", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "getFacet", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "getFacets", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "getSortedFacets", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "getTimestampString", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "getXStream", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "isAlive", "()", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "load", "(String)", "summary", "df-generated"] + - ["hudson.model", "Fingerprint", "trim", "()", "summary", "df-generated"] + - ["hudson.model", "FingerprintCleanupThread", "invoke", "()", "summary", "df-generated"] + - ["hudson.model", "FingerprintMap", "isReady", "()", "summary", "df-generated"] + - ["hudson.model", "HealthReport", "getAggregatedReports", "()", "summary", "df-generated"] + - ["hudson.model", "HealthReport", "getScore", "()", "summary", "df-generated"] + - ["hudson.model", "HealthReport", "isAggregateReport", "()", "summary", "df-generated"] + - ["hudson.model", "HealthReport", "setScore", "(int)", "summary", "df-generated"] + - ["hudson.model", "Hudson", "adminCheck", "()", "summary", "df-generated"] + - ["hudson.model", "Hudson", "adminCheck", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Hudson", "doFieldCheck", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Hudson", "doFieldCheck", "(String,String,String,String)", "summary", "df-generated"] + - ["hudson.model", "Hudson", "doLogRss", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Hudson", "doQuietDown", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Hudson", "getInstance", "()", "summary", "df-generated"] + - ["hudson.model", "Hudson", "isAdmin", "()", "summary", "df-generated"] + - ["hudson.model", "Hudson", "isAdmin", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "Hudson", "isDarwin", "()", "summary", "df-generated"] + - ["hudson.model", "Hudson", "isWindows", "()", "summary", "df-generated"] + - ["hudson.model", "Hudson", "setSlaves", "(List)", "summary", "df-generated"] + - ["hudson.model", "Item", "delete", "()", "summary", "df-generated"] + - ["hudson.model", "Item", "getAbsoluteUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Item", "getAllJobs", "()", "summary", "df-generated"] + - ["hudson.model", "Item", "onCopiedFrom", "(Item)", "summary", "df-generated"] + - ["hudson.model", "Item", "onCreatedFromScratch", "()", "summary", "df-generated"] + - ["hudson.model", "ItemGroup", "getAllItems", "()", "summary", "df-generated"] + - ["hudson.model", "ItemGroup", "getAllItems", "(Class)", "summary", "df-generated"] + - ["hudson.model", "ItemGroup", "getAllItems", "(Class,Predicate)", "summary", "df-generated"] + - ["hudson.model", "ItemGroup", "onRenamed", "(Item,String,String)", "summary", "df-generated"] + - ["hudson.model", "ItemGroup<TopLevelItem>", "getUrl", "()", "summary", "df-generated"] + - ["hudson.model", "ItemGroupMixIn", "copy", "(TopLevelItem,String)", "summary", "df-generated"] + - ["hudson.model", "ItemGroupMixIn", "createProjectFromXML", "(String,InputStream)", "summary", "df-generated"] + - ["hudson.model", "ItemVisitor", "onItem", "(Item)", "summary", "df-generated"] + - ["hudson.model", "ItemVisitor", "walk", "()", "summary", "df-generated"] + - ["hudson.model", "Items", "all2", "(Authentication,ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "Items", "all", "()", "summary", "df-generated"] + - ["hudson.model", "Items", "all", "(Authentication,ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "Items", "all", "(ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "Items", "currentlyUpdatingByXml", "()", "summary", "df-generated"] + - ["hudson.model", "Items", "findNearest", "(Class,String,ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "Items", "fromNameList", "(ItemGroup,String,Class)", "summary", "df-generated"] + - ["hudson.model", "Items", "fromNameList", "(String,Class)", "summary", "df-generated"] + - ["hudson.model", "Items", "getAllItems", "(ItemGroup,Class)", "summary", "df-generated"] + - ["hudson.model", "Items", "getAllItems", "(ItemGroup,Class,Predicate)", "summary", "df-generated"] + - ["hudson.model", "Items", "getDescriptor", "(String)", "summary", "df-generated"] + - ["hudson.model", "Items", "whileUpdatingByXml", "(Callable)", "summary", "df-generated"] + - ["hudson.model", "JDK", "getExists", "()", "summary", "df-generated"] + - ["hudson.model", "JDK", "isDefaultJDKValid", "(Node)", "summary", "df-generated"] + - ["hudson.model", "JDK", "isDefaultName", "(String)", "summary", "df-generated"] + - ["hudson.model", "Job", "assignBuildNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "doBuildStatus", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Job", "doConfigSubmit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Job", "doDescription", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Job", "doDoRename", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Job", "doRssAll", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Job", "doRssChangelog", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Job", "doRssFailed", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Job", "getBuildStatusIconClassName", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "getBuildStatusUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "getBuildTimeGraph", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "getEstimatedDuration", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "getIconColor", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "getNextBuildNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "getPermalinks", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "getProperty", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Job", "getQueueItem", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "isBuildable", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "isBuilding", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "isHoldOffBuildUntilSave", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "isInQueue", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "isKeepDependencies", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "isLogUpdated", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "logRotate", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "removeProperty", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Job", "removeProperty", "(JobProperty)", "summary", "df-generated"] + - ["hudson.model", "Job", "setBuildDiscarder", "(BuildDiscarder)", "summary", "df-generated"] + - ["hudson.model", "Job", "setLogRotator", "(LogRotator)", "summary", "df-generated"] + - ["hudson.model", "Job", "supportsLogRotator", "()", "summary", "df-generated"] + - ["hudson.model", "Job", "updateNextBuildNumber", "(int)", "summary", "df-generated"] + - ["hudson.model", "JobProperty", "getJobAction", "(Job)", "summary", "df-generated"] + - ["hudson.model", "JobProperty", "getJobActions", "(Job)", "summary", "df-generated"] + - ["hudson.model", "JobProperty", "getJobOverrides", "()", "summary", "df-generated"] + - ["hudson.model", "JobProperty", "getSubTasks", "()", "summary", "df-generated"] + - ["hudson.model", "JobPropertyDescriptor", "all", "()", "summary", "df-generated"] + - ["hudson.model", "JobPropertyDescriptor", "getPropertyDescriptors", "(Class)", "summary", "df-generated"] + - ["hudson.model", "JobPropertyDescriptor", "isApplicable", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Label", "accept", "(LabelVisitor,Object)", "summary", "df-generated"] + - ["hudson.model", "Label", "contains", "(Node)", "summary", "df-generated"] + - ["hudson.model", "Label", "getBusyExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "getExpression", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "getIdleExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "getTiedJobCount", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "getTiedJobs", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "getTotalConfiguredExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "getTotalExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "isAssignable", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "isAtom", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "isEmpty", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "isOffline", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "isSelfLabel", "()", "summary", "df-generated"] + - ["hudson.model", "Label", "matches", "(Collection)", "summary", "df-generated"] + - ["hudson.model", "Label", "matches", "(Node)", "summary", "df-generated"] + - ["hudson.model", "Label", "matches", "(VariableResolver)", "summary", "df-generated"] + - ["hudson.model", "Label", "parse", "(String)", "summary", "df-generated"] + - ["hudson.model", "Label", "parseExpression", "(String)", "summary", "df-generated"] + - ["hudson.model", "Label", "precedence", "()", "summary", "df-generated"] + - ["hudson.model", "LabelFinder", "all", "()", "summary", "df-generated"] + - ["hudson.model", "LabelFinder", "findLabels", "(Node)", "summary", "df-generated"] + - ["hudson.model", "ListView$DescriptorImpl", "doCheckIncludeRegex", "(String)", "summary", "df-generated"] + - ["hudson.model", "ListView", "getDefaultColumns", "()", "summary", "df-generated"] + - ["hudson.model", "ListView", "getStatusFilter", "()", "summary", "df-generated"] + - ["hudson.model", "ListView", "hasJobFilterExtensions", "()", "summary", "df-generated"] + - ["hudson.model", "ListView", "isAddToCurrentView", "()", "summary", "df-generated"] + - ["hudson.model", "ListView", "isRecurse", "()", "summary", "df-generated"] + - ["hudson.model", "ListView", "jobNamesContains", "(TopLevelItem)", "summary", "df-generated"] + - ["hudson.model", "ListView", "setColumns", "(List)", "summary", "df-generated"] + - ["hudson.model", "ListView", "setJobFilters", "(List)", "summary", "df-generated"] + - ["hudson.model", "ListView", "setRecurse", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "ListView", "setStatusFilter", "(Boolean)", "summary", "df-generated"] + - ["hudson.model", "LoadBalancer", "map", "(Task,MappingWorksheet)", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot$Builder", "build", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "builder", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "getAvailableExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "getBusyExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "getConnectingExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "getDefinedExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "getIdleExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "getOnlineExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "getQueueLength", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics$LoadStatisticsSnapshot", "toString", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics", "computeIdleExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics", "computeQueueLength", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics", "computeSnapshot", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics", "computeTotalExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics", "createChart", "(CategoryDataset)", "summary", "df-generated"] + - ["hudson.model", "LoadStatistics", "getLatestIdleExecutors", "(TimeScale)", "summary", "df-generated"] + - ["hudson.model", "ManageJenkinsAction", "addContextMenuItem", "(ContextMenu,String,String,String,String,boolean,boolean)", "summary", "df-generated"] + - ["hudson.model", "ManagementLink$Category", "getLabel", "()", "summary", "df-generated"] + - ["hudson.model", "ManagementLink", "all", "()", "summary", "df-generated"] + - ["hudson.model", "ManagementLink", "getBadge", "()", "summary", "df-generated"] + - ["hudson.model", "ManagementLink", "getCategory", "()", "summary", "df-generated"] + - ["hudson.model", "ManagementLink", "getDescription", "()", "summary", "df-generated"] + - ["hudson.model", "ManagementLink", "getRequiredPermission", "()", "summary", "df-generated"] + - ["hudson.model", "ManagementLink", "getRequiresConfirmation", "()", "summary", "df-generated"] + - ["hudson.model", "ManagementLink", "getRequiresPOST", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractBuild_Building", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractBuild_BuildingInWorkspace", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractBuild_BuildingOnMaster", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractBuild_BuildingRemotely", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractBuild_KeptBecause", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractItem_BeingDeleted", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractItem_FailureToStopBuilds", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractItem_NewNameInUse", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractItem_NewNameUnchanged", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractItem_NoSuchJobExists", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractItem_NoSuchJobExistsWithoutSuggestion", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractItem_Pronoun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractItem_TaskNoun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_Aborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_AwaitingBuildForWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_AwaitingWorkspaceToComeOnline", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_BuildPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_CancelPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_CustomWorkspaceEmpty", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_Disabled", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_DiscoverPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_DownstreamBuildInProgress", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_ExtendedReadPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_NewBuildForWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_NoBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_NoSCM", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_NoWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_PollingABorted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_PollingVetoed", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_Pronoun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_ScmAborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_UpstreamBuildInProgress", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_WipeOutPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_WorkspaceOffline", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_WorkspacePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_WorkspaceTitle", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "AbstractProject_WorkspaceTitleOnComputer", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Api_MultipleMatch", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Api_NoXPathMatch", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Api_WrapperParamInvalid", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BallColor_Aborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BallColor_Disabled", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BallColor_Failed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BallColor_InProgress", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BallColor_NotBuilt", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BallColor_Pending", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BallColor_Success", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BallColor_Unstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BooleanParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "BuildAuthorizationToken_InvalidTokenProvided", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Build_post_build_steps_failed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "CLI_clear_queue_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "CLI_keep_build_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "CLI_online_node_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "CLI_restart_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "CLI_safe_restart_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Cause_LegacyCodeCause_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Cause_RemoteCause_ShortDescription", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Cause_RemoteCause_ShortDescriptionWithNote", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Cause_UpstreamCause_CausedBy", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Cause_UpstreamCause_ShortDescription", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Cause_UserCause_ShortDescription", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Cause_UserIdCause_ShortDescription", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "ChoiceParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ChoiceParameterDefinition_MissingChoices", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ComputerSet_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ComputerSet_NoSuchSlave", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "ComputerSet_SlaveAlreadyExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "ComputerSet_SpecifySlaveToCopy", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_BadChannel", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_BuildPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_Caption", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_ConfigurePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_ConnectPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_CreatePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_DeletePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_DisconnectPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_ExtendedReadPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_NoSuchSlaveExists", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_NoSuchSlaveExistsWithoutAdvice", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Computer_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Descriptor_From", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Executor_NotAvailable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "FileParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "FileParameterValue_IndexTitle", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "FreeStyleProject_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "FreeStyleProject_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "HealthReport_EmptyString", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_AdministerPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_BadPortNumber", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_Computer_Caption", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_Computer_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_ControlCodeNotAllowed", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_JobAlreadyExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_MustBeAtLeast", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_MustBeAtMost", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NoJavaInPath", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NoName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NoSuchDirectory", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NodeBeingRemoved", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NodeDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NotANegativeNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NotANonNegativeNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NotANumber", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NotAPlugin", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NotAPositiveNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NotJDKDir", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_NotUsesUTF8ToDecodeURL", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_ReadPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_RunScriptsPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_TrailingDot", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_USER_CONTENT_README", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_UnsafeChar", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_ViewAlreadyExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Hudson_ViewName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ItemGroupMixIn_may_not_copy_as_it_contains_secrets_and_", "(Object,Object,Object,Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Item_CONFIGURE_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Item_CREATE_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Item_DELETE_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Item_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Item_READ_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Item_RENAME_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "JDK_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Jenkins_CheckDisplayName_DisplayNameNotUniqueWarning", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Jenkins_CheckDisplayName_NameNotUniqueWarning", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Jenkins_IsRestarting", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Jenkins_Manage_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Jenkins_NotAllowedName", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Jenkins_SystemRead_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Job_AllRecentBuildFailed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Job_BuildStability", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Job_NOfMFailed", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Job_NoRecentBuildFailed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Job_NoRenameWhileBuilding", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Job_Pronoun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Job_minutes", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Job_you_must_use_the_save_button_if_you_wish", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LabelExpression_InvalidBooleanExpression", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "LabelExpression_LabelLink", "(Object,Object,Object,Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "LabelExpression_NoMatch", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LabelExpression_NoMatch_DidYouMean", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "LabelExpression_ObsoleteMasterLabel", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Label_GroupOf", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Label_InvalidLabel", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Label_ProvisionedFrom", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "ListView_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LoadStatistics_Legends_AvailableExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LoadStatistics_Legends_BusyExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LoadStatistics_Legends_ConnectingExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LoadStatistics_Legends_DefinedExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LoadStatistics_Legends_IdleExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LoadStatistics_Legends_OnlineExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LoadStatistics_Legends_QueueLength", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "LoadStatistics_Legends_TotalExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ManageJenkinsAction_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ManagementLink_Category_CONFIGURATION", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ManagementLink_Category_MISC", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ManagementLink_Category_SECURITY", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ManagementLink_Category_STATUS", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ManagementLink_Category_TOOLS", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ManagementLink_Category_TROUBLESHOOTING", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ManagementLink_Category_UNCATEGORIZED", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "MultiStageTimeSeries_EMPTY_STRING", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "MyView_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "MyViewsProperty_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "MyViewsProperty_GlobalAction_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "MyViewsProperty_ViewExistsCheck_AlreadyExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "MyViewsProperty_ViewExistsCheck_NotExist", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Node_BecauseNodeIsNotAcceptingTasks", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Node_BecauseNodeIsReserved", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Node_LabelMissing", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Node_LackingBuildPermission", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Node_Mode_EXCLUSIVE", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Node_Mode_NORMAL", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ParameterAction_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ParametersDefinitionProperty_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "PasswordParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Permalink_LastBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Permalink_LastCompletedBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Permalink_LastFailedBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Permalink_LastStableBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Permalink_LastSuccessfulBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Permalink_LastUnstableBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Permalink_LastUnsuccessfulBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ProxyView_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ProxyView_NoSuchViewExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_AllNodesOffline", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_BlockedBy", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_ExceptionCanRun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_ExceptionCanTake", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_FinishedWaiting", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_HudsonIsAboutToShutDown", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_InProgress", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_InQuietPeriod", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_LabelHasNoNodes", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_NodeOffline", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_Unknown", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_WaitingForNextAvailableExecutor", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_WaitingForNextAvailableExecutorOn", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_executor_slot_already_in_use", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_init", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Queue_node_has_been_removed_from_configuration", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_Aborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_Failure", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_Fixed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_NotBuilt", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_NowUnstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_StillFailing", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_StillUnstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_Success", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "ResultTrend_Unstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "RunParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_ArtifactsBrowserTitle", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_ArtifactsPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_BuildAborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_DeletePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_InProgressDuration", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_MarkedExplicitly", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_NotStartedYet", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_Aborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_BackToNormal", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_BrokenForALongTime", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_BrokenSince", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_BrokenSinceThisBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_NotBuilt", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_Stable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_Unknown", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_Summary_Unstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_UnableToDelete", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_UpdatePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run__is_waiting_for_a_checkpoint_on_", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_running_as_", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Run_running_as_SYSTEM", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Slave_InvalidConfig_Executors", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Slave_InvalidConfig_NoName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Slave_Network_Mounted_File_System_Warning", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Slave_Remote_Director_Mandatory", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Slave_Remote_Relative_Path_Warning", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Slave_Terminated", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "Slave_UnixSlave", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "Slave_WindowsSlave", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "StringParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "TextParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "TimeZoneProperty_DisplayDefaultTimeZone", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "TimeZoneProperty_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "TimeZoneProperty_current_time_in_", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "TimeZoneProperty_current_time_on_server_in_in_proposed_di", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "TopLevelItemDescriptor_NotApplicableIn", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_CoreUpdateMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_DownloadButNotActivated", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_agent", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_android", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_api_plugin", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_builder", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_buildwrapper", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_cli", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_cloud", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_cluster", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_database", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_deployment", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_devops", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_devsecops", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_dotnet", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_external", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_groovy_related", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_ios", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_listview_column", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_maven", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_misc", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_must_be_labeled", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_notifier", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_orchestration", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_page_decorator", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_parameter", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_post_build", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_python", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_report", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_ruby", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_runcondition", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_scala", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_scm", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_scm_related", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_security", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_test", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_theme", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_trigger", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_ui", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_unrecognized", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_upload", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_user", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_PluginCategory_view", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_Status_CheckingInternet", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_Status_CheckingJavaNet", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_Status_ConnectionFailed", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_Status_Success", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_Status_UnknownHostException", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_init", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "UpdateCenter_n_a", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "User_IllegalFullname", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "User_IllegalUsername", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "View_ConfigurePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "View_CreatePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "View_DeletePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "View_DisplayNameNotUniqueWarning", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "View_MissingMode", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "View_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "View_ReadPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractBuild_Building", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractBuild_BuildingInWorkspace", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractBuild_BuildingOnMaster", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractBuild_BuildingRemotely", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractBuild_KeptBecause", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractItem_BeingDeleted", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractItem_FailureToStopBuilds", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractItem_NewNameInUse", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractItem_NewNameUnchanged", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractItem_NoSuchJobExists", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractItem_NoSuchJobExistsWithoutSuggestion", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractItem_Pronoun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractItem_TaskNoun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_Aborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_AwaitingBuildForWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_AwaitingWorkspaceToComeOnline", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_BuildPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_CancelPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_CustomWorkspaceEmpty", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_Disabled", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_DiscoverPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_DownstreamBuildInProgress", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_ExtendedReadPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_NewBuildForWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_NoBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_NoSCM", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_NoWorkspace", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_PollingABorted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_PollingVetoed", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_Pronoun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_ScmAborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_UpstreamBuildInProgress", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_WipeOutPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_WorkspaceOffline", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_WorkspacePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_WorkspaceTitle", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_AbstractProject_WorkspaceTitleOnComputer", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Api_MultipleMatch", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Api_NoXPathMatch", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Api_WrapperParamInvalid", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BallColor_Aborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BallColor_Disabled", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BallColor_Failed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BallColor_InProgress", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BallColor_NotBuilt", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BallColor_Pending", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BallColor_Success", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BallColor_Unstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BooleanParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_BuildAuthorizationToken_InvalidTokenProvided", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Build_post_build_steps_failed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_CLI_clear_queue_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_CLI_keep_build_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_CLI_online_node_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_CLI_restart_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_CLI_safe_restart_shortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Cause_LegacyCodeCause_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Cause_RemoteCause_ShortDescription", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Cause_RemoteCause_ShortDescriptionWithNote", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Cause_UpstreamCause_CausedBy", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Cause_UpstreamCause_ShortDescription", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Cause_UserCause_ShortDescription", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Cause_UserIdCause_ShortDescription", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ChoiceParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ChoiceParameterDefinition_MissingChoices", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ComputerSet_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ComputerSet_NoSuchSlave", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ComputerSet_SlaveAlreadyExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ComputerSet_SpecifySlaveToCopy", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_BadChannel", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_BuildPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_Caption", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_ConfigurePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_ConnectPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_CreatePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_DeletePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_DisconnectPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_ExtendedReadPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_NoSuchSlaveExists", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_NoSuchSlaveExistsWithoutAdvice", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Computer_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Descriptor_From", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Executor_NotAvailable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_FileParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_FileParameterValue_IndexTitle", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_FreeStyleProject_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_FreeStyleProject_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_HealthReport_EmptyString", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_AdministerPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_BadPortNumber", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_Computer_Caption", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_Computer_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_ControlCodeNotAllowed", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_JobAlreadyExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_MustBeAtLeast", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_MustBeAtMost", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NoJavaInPath", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NoName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NoSuchDirectory", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NodeBeingRemoved", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NodeDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NotANegativeNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NotANonNegativeNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NotANumber", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NotAPlugin", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NotAPositiveNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NotJDKDir", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_NotUsesUTF8ToDecodeURL", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_ReadPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_RunScriptsPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_TrailingDot", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_USER_CONTENT_README", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_UnsafeChar", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_ViewAlreadyExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Hudson_ViewName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ItemGroupMixIn_may_not_copy_as_it_contains_secrets_and_", "(Object,Object,Object,Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Item_CONFIGURE_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Item_CREATE_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Item_DELETE_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Item_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Item_READ_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Item_RENAME_description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_JDK_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Jenkins_CheckDisplayName_DisplayNameNotUniqueWarning", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Jenkins_CheckDisplayName_NameNotUniqueWarning", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Jenkins_IsRestarting", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Jenkins_Manage_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Jenkins_NotAllowedName", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Jenkins_SystemRead_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Job_AllRecentBuildFailed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Job_BuildStability", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Job_NOfMFailed", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Job_NoRecentBuildFailed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Job_NoRenameWhileBuilding", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Job_Pronoun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Job_minutes", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Job_you_must_use_the_save_button_if_you_wish", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LabelExpression_InvalidBooleanExpression", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LabelExpression_LabelLink", "(Object,Object,Object,Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LabelExpression_NoMatch", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LabelExpression_NoMatch_DidYouMean", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LabelExpression_ObsoleteMasterLabel", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Label_GroupOf", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Label_InvalidLabel", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Label_ProvisionedFrom", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ListView_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LoadStatistics_Legends_AvailableExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LoadStatistics_Legends_BusyExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LoadStatistics_Legends_ConnectingExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LoadStatistics_Legends_DefinedExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LoadStatistics_Legends_IdleExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LoadStatistics_Legends_OnlineExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LoadStatistics_Legends_QueueLength", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_LoadStatistics_Legends_TotalExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ManageJenkinsAction_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ManagementLink_Category_CONFIGURATION", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ManagementLink_Category_MISC", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ManagementLink_Category_SECURITY", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ManagementLink_Category_STATUS", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ManagementLink_Category_TOOLS", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ManagementLink_Category_TROUBLESHOOTING", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ManagementLink_Category_UNCATEGORIZED", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_MultiStageTimeSeries_EMPTY_STRING", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_MyView_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_MyViewsProperty_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_MyViewsProperty_GlobalAction_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_MyViewsProperty_ViewExistsCheck_AlreadyExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_MyViewsProperty_ViewExistsCheck_NotExist", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Node_BecauseNodeIsNotAcceptingTasks", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Node_BecauseNodeIsReserved", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Node_LabelMissing", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Node_LackingBuildPermission", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Node_Mode_EXCLUSIVE", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Node_Mode_NORMAL", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ParameterAction_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ParametersDefinitionProperty_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_PasswordParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Permalink_LastBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Permalink_LastCompletedBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Permalink_LastFailedBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Permalink_LastStableBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Permalink_LastSuccessfulBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Permalink_LastUnstableBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Permalink_LastUnsuccessfulBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ProxyView_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ProxyView_NoSuchViewExists", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_AllNodesOffline", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_BlockedBy", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_ExceptionCanRun", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_ExceptionCanTake", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_FinishedWaiting", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_HudsonIsAboutToShutDown", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_InProgress", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_InQuietPeriod", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_LabelHasNoNodes", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_NodeOffline", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_Unknown", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_WaitingForNextAvailableExecutor", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_WaitingForNextAvailableExecutorOn", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_executor_slot_already_in_use", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_init", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Queue_node_has_been_removed_from_configuration", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_Aborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_Failure", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_Fixed", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_NotBuilt", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_NowUnstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_StillFailing", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_StillUnstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_Success", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_ResultTrend_Unstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_RunParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_ArtifactsBrowserTitle", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_ArtifactsPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_BuildAborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_DeletePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_InProgressDuration", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_MarkedExplicitly", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_NotStartedYet", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_Aborted", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_BackToNormal", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_BrokenForALongTime", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_BrokenSince", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_BrokenSinceThisBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_NotBuilt", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_Stable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_Unknown", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_Summary_Unstable", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_UnableToDelete", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_UpdatePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run__is_waiting_for_a_checkpoint_on_", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_running_as_", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Run_running_as_SYSTEM", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Slave_InvalidConfig_Executors", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Slave_InvalidConfig_NoName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Slave_Network_Mounted_File_System_Warning", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Slave_Remote_Director_Mandatory", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Slave_Remote_Relative_Path_Warning", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Slave_Terminated", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Slave_UnixSlave", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_Slave_WindowsSlave", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_StringParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_TextParameterDefinition_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_TimeZoneProperty_DisplayDefaultTimeZone", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_TimeZoneProperty_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_TimeZoneProperty_current_time_in_", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_TimeZoneProperty_current_time_on_server_in_in_proposed_di", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_TopLevelItemDescriptor_NotApplicableIn", "(Object,Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_CoreUpdateMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_DisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_DownloadButNotActivated", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_agent", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_android", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_api_plugin", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_builder", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_buildwrapper", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_cli", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_cloud", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_cluster", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_database", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_deployment", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_devops", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_devsecops", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_dotnet", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_external", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_groovy_related", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_ios", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_listview_column", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_maven", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_misc", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_must_be_labeled", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_notifier", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_orchestration", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_page_decorator", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_parameter", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_post_build", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_python", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_report", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_ruby", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_runcondition", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_scala", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_scm", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_scm_related", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_security", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_test", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_theme", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_trigger", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_ui", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_unrecognized", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_upload", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_user", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_PluginCategory_view", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_Status_CheckingInternet", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_Status_CheckingJavaNet", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_Status_ConnectionFailed", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_Status_Success", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_Status_UnknownHostException", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_init", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_UpdateCenter_n_a", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_User_IllegalFullname", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_User_IllegalUsername", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_View_ConfigurePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_View_CreatePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_View_DeletePermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_View_DisplayNameNotUniqueWarning", "(Object)", "summary", "df-generated"] + - ["hudson.model", "Messages", "_View_MissingMode", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_View_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.model", "Messages", "_View_ReadPermission_Description", "()", "summary", "df-generated"] + - ["hudson.model", "ModelObject", "getDisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries$TimeScale", "createDateFormat", "()", "summary", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries$TimeScale", "parse", "(String)", "summary", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries$TrendChart", "createChart", "()", "summary", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries", "MultiStageTimeSeries", "(float,float)", "summary", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries", "getLatest", "(TimeScale)", "summary", "df-generated"] + - ["hudson.model", "MultiStageTimeSeries", "update", "(float)", "summary", "df-generated"] + - ["hudson.model", "MyViewsProperty", "doCreateView", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "MyViewsProperty", "doIndex", "()", "summary", "df-generated"] + - ["hudson.model", "MyViewsProperty", "doViewExistsCheck", "(String,boolean)", "summary", "df-generated"] + - ["hudson.model", "MyViewsProperty", "getMyViewsTabBar", "()", "summary", "df-generated"] + - ["hudson.model", "Node$Mode", "getDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Node$Mode", "getName", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "canTake", "(Task)", "summary", "df-generated"] + - ["hudson.model", "Node", "createComputer", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "createLauncher", "(TaskListener)", "summary", "df-generated"] + - ["hudson.model", "Node", "getChannel", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getClockDifference", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getClockDifferenceCallable", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getFileSystemProvisioner", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getLabelCloud", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getLabelString", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getMode", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getNodeDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getNodeName", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getNodeProperties", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getNodeProperty", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Node", "getNodePropertyDescriptors", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getNumExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getRootPath", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "getWorkspaceFor", "(TopLevelItem)", "summary", "df-generated"] + - ["hudson.model", "Node", "isAcceptingTasks", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "isHoldOffLaunchUntilSave", "()", "summary", "df-generated"] + - ["hudson.model", "Node", "setLabelString", "(String)", "summary", "df-generated"] + - ["hudson.model", "Node", "setNodeName", "(String)", "summary", "df-generated"] + - ["hudson.model", "Node", "toComputer", "()", "summary", "df-generated"] + - ["hudson.model", "PageDecorator", "all", "()", "summary", "df-generated"] + - ["hudson.model", "PageDecorator", "getUrl", "()", "summary", "df-generated"] + - ["hudson.model", "PaneStatusProperties", "forCurrentUser", "()", "summary", "df-generated"] + - ["hudson.model", "PaneStatusProperties", "isCollapsed", "(String)", "summary", "df-generated"] + - ["hudson.model", "PaneStatusProperties", "toggleCollapsed", "(String)", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition$ParameterDescriptor", "getValuePage", "()", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition", "all", "()", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition", "createValue", "(CLICommand,String)", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition", "createValue", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition", "createValue", "(StaplerRequest,JSONObject)", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition", "getDefaultParameterValue", "()", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition", "getFormattedDescription", "()", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition", "getType", "()", "summary", "df-generated"] + - ["hudson.model", "ParameterDefinition", "isValid", "(ParameterValue)", "summary", "df-generated"] + - ["hudson.model", "ParameterValue", "createBuildWrapper", "(AbstractBuild)", "summary", "df-generated"] + - ["hudson.model", "ParameterValue", "createVariableResolver", "(AbstractBuild)", "summary", "df-generated"] + - ["hudson.model", "ParameterValue", "getAssignedLabel", "(SubTask)", "summary", "df-generated"] + - ["hudson.model", "ParameterValue", "getDefinition", "()", "summary", "df-generated"] + - ["hudson.model", "ParameterValue", "getFormattedDescription", "()", "summary", "df-generated"] + - ["hudson.model", "ParameterValue", "getValue", "()", "summary", "df-generated"] + - ["hudson.model", "ParameterValue", "isSensitive", "()", "summary", "df-generated"] + - ["hudson.model", "ParametersAction", "createBuildWrappers", "(AbstractBuild,Collection)", "summary", "df-generated"] + - ["hudson.model", "ParametersAction", "createVariableResolver", "(AbstractBuild)", "summary", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", "_doBuild", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", "_doBuild", "(StaplerRequest,StaplerResponse,TimeDuration)", "summary", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", "buildWithParameters", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "ParametersDefinitionProperty", "buildWithParameters", "(StaplerRequest,StaplerResponse,TimeDuration)", "summary", "df-generated"] + - ["hudson.model", "PeriodicWork", "all", "()", "summary", "df-generated"] + - ["hudson.model", "PeriodicWork", "getInitialDelay", "()", "summary", "df-generated"] + - ["hudson.model", "PeriodicWork", "getRecurrencePeriod", "()", "summary", "df-generated"] + - ["hudson.model", "PeriodicWork", "init", "()", "summary", "df-generated"] + - ["hudson.model", "PermalinkProjectAction$Permalink", "getDisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "PermalinkProjectAction$Permalink", "getId", "()", "summary", "df-generated"] + - ["hudson.model", "PermalinkProjectAction$Permalink", "resolve", "(Job)", "summary", "df-generated"] + - ["hudson.model", "PersistentDescriptor", "load", "()", "summary", "df-generated"] + - ["hudson.model", "Project", "getBuilders", "()", "summary", "df-generated"] + - ["hudson.model", "Project", "removePublisher", "(Descriptor)", "summary", "df-generated"] + - ["hudson.model", "ProxyView", "doViewExistsCheck", "(String)", "summary", "df-generated"] + - ["hudson.model", "ProxyView", "getProxiedView", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$BlockedItem", "isCauseOfBlockageNull", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$BuildableItem", "isPending", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Executable", "getEstimatedDuration", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Executable", "getParentExecutable", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "authenticate2", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "authenticate", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "doCancelQueue", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getCauseOfBlockage", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getCauses", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getCausesDescription", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getId", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getIdLegacy", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getInQueueForString", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getInQueueSince", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getParams", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "getUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "hasCancelPermission", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "isBlocked", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "isBuildable", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Item", "isStuck", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$JobOffer", "canTake", "(BuildableItem)", "summary", "df-generated"] + - ["hudson.model", "Queue$JobOffer", "getCauseOfBlockage", "(BuildableItem)", "summary", "df-generated"] + - ["hudson.model", "Queue$JobOffer", "getNode", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$JobOffer", "isNotExclusive", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$JobOffer", "toString", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$LeftItem", "getExecutable", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$LeftItem", "isCancelled", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$QueueAction", "shouldSchedule", "(List)", "summary", "df-generated"] + - ["hudson.model", "Queue$QueueDecisionHandler", "all", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$QueueDecisionHandler", "shouldSchedule", "(Task,List)", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "checkAbortPermission", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "getCauseOfBlockage", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "getDefaultAuthentication2", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "getDefaultAuthentication2", "(Item)", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "getDefaultAuthentication", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "getDefaultAuthentication", "(Item)", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "getWhyBlocked", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "hasAbortPermission", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "isBuildBlocked", "()", "summary", "df-generated"] + - ["hudson.model", "Queue$Task", "isConcurrentBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "Queue", "(LoadBalancer)", "summary", "df-generated"] + - ["hudson.model", "Queue", "add", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "Queue", "add", "(AbstractProject,int)", "summary", "df-generated"] + - ["hudson.model", "Queue", "add", "(Task,int)", "summary", "df-generated"] + - ["hudson.model", "Queue", "add", "(Task,int,Action[])", "summary", "df-generated"] + - ["hudson.model", "Queue", "cancel", "(Item)", "summary", "df-generated"] + - ["hudson.model", "Queue", "cancel", "(Task)", "summary", "df-generated"] + - ["hudson.model", "Queue", "clear", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "clearLeftItems", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "contains", "(Task)", "summary", "df-generated"] + - ["hudson.model", "Queue", "countBuildableItems", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "countBuildableItemsFor", "(Label)", "summary", "df-generated"] + - ["hudson.model", "Queue", "doCancelItem", "(long)", "summary", "df-generated"] + - ["hudson.model", "Queue", "getApproximateItemsQuickly", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "getDiscoverableItems", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "getInstance", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "getItems", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "getUnblockedTasks", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "ifBlockedByHudsonShutdown", "(Task)", "summary", "df-generated"] + - ["hudson.model", "Queue", "init", "(Jenkins)", "summary", "df-generated"] + - ["hudson.model", "Queue", "isBlockedByShutdown", "(Task)", "summary", "df-generated"] + - ["hudson.model", "Queue", "isEmpty", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "isPending", "(Task)", "summary", "df-generated"] + - ["hudson.model", "Queue", "load", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "maintain", "()", "summary", "df-generated"] + - ["hudson.model", "Queue", "setLoadBalancer", "(LoadBalancer)", "summary", "df-generated"] + - ["hudson.model", "Queue", "strictCountBuildableItemsFor", "(Label)", "summary", "df-generated"] + - ["hudson.model", "Queue", "tryWithLock", "(Runnable)", "summary", "df-generated"] + - ["hudson.model", "Queue", "withLock", "(Callable)", "summary", "df-generated"] + - ["hudson.model", "Queue", "withLock", "(Runnable)", "summary", "df-generated"] + - ["hudson.model", "RSS", "forwardToRss", "(String,String,Collection,FeedAdapter,StaplerRequest,HttpServletResponse)", "summary", "df-generated"] + - ["hudson.model", "RSS", "rss", "(StaplerRequest,StaplerResponse,String,String,RunList)", "summary", "df-generated"] + - ["hudson.model", "RSS", "rss", "(StaplerRequest,StaplerResponse,String,String,RunList,FeedAdapter)", "summary", "df-generated"] + - ["hudson.model", "Resource", "isCollidingWith", "(Resource,int)", "summary", "df-generated"] + - ["hudson.model", "ResourceActivity", "getResourceList", "()", "summary", "df-generated"] + - ["hudson.model", "ResourceController", "canRun", "(ResourceList)", "summary", "df-generated"] + - ["hudson.model", "ResourceController", "execute", "(Runnable,ResourceActivity)", "summary", "df-generated"] + - ["hudson.model", "ResourceController", "getMissingResource", "(ResourceList)", "summary", "df-generated"] + - ["hudson.model", "ResourceList", "isCollidingWith", "(ResourceList)", "summary", "df-generated"] + - ["hudson.model", "ResourceList", "toString", "()", "summary", "df-generated"] + - ["hudson.model", "RestartListener", "all", "()", "summary", "df-generated"] + - ["hudson.model", "RestartListener", "isAllReady", "()", "summary", "df-generated"] + - ["hudson.model", "RestartListener", "isReadyToRestart", "()", "summary", "df-generated"] + - ["hudson.model", "RestartListener", "onRestart", "()", "summary", "df-generated"] + - ["hudson.model", "Result$OptionHandlerImpl", "OptionHandlerImpl", "(CmdLineParser,OptionDef,Setter)", "summary", "df-generated"] + - ["hudson.model", "Result", "fromString", "(String)", "summary", "df-generated"] + - ["hudson.model", "Result", "init", "()", "summary", "df-generated"] + - ["hudson.model", "Result", "isBetterOrEqualTo", "(Result)", "summary", "df-generated"] + - ["hudson.model", "Result", "isBetterThan", "(Result)", "summary", "df-generated"] + - ["hudson.model", "Result", "isCompleteBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Result", "isWorseOrEqualTo", "(Result)", "summary", "df-generated"] + - ["hudson.model", "Result", "isWorseThan", "(Result)", "summary", "df-generated"] + - ["hudson.model", "ResultTrend", "getDescription", "()", "summary", "df-generated"] + - ["hudson.model", "ResultTrend", "getID", "()", "summary", "df-generated"] + - ["hudson.model", "ResultTrend", "getResultTrend", "(AbstractBuild)", "summary", "df-generated"] + - ["hudson.model", "ResultTrend", "getResultTrend", "(Run)", "summary", "df-generated"] + - ["hudson.model", "Run$Artifact", "getFileSize", "()", "summary", "df-generated"] + - ["hudson.model", "Run$ArtifactList", "computeDisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Run$KeepLogBuildBadge", "getWhyKeepLog", "()", "summary", "df-generated"] + - ["hudson.model", "Run$RedirectUp", "doDynamic", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Run$RunExecution", "cleanUp", "(BuildListener)", "summary", "df-generated"] + - ["hudson.model", "Run$RunExecution", "getBuild", "()", "summary", "df-generated"] + - ["hudson.model", "Run$RunExecution", "getProject", "()", "summary", "df-generated"] + - ["hudson.model", "Run$RunExecution", "post", "(BuildListener)", "summary", "df-generated"] + - ["hudson.model", "Run$RunExecution", "run", "(BuildListener)", "summary", "df-generated"] + - ["hudson.model", "Run$StatusSummarizer", "summarize", "(Run,ResultTrend)", "summary", "df-generated"] + - ["hudson.model", "Run", "canToggleLogKeep", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "delete", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "deleteArtifacts", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "doBuildNumber", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Run", "doBuildStatus", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Run", "doBuildTimestamp", "(StaplerRequest,StaplerResponse,String)", "summary", "df-generated"] + - ["hudson.model", "Run", "doConfigSubmit", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "Run", "doConsoleText", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Run", "doDoDelete", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Run", "doProgressiveLog", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Run", "doSubmitDescription", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Run", "doToggleLogKeep", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Run", "fromExternalizableId", "(String)", "summary", "df-generated"] + - ["hudson.model", "Run", "getAbsoluteUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getArtifacts", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getArtifactsUpTo", "(int)", "summary", "df-generated"] + - ["hudson.model", "Run", "getBadgeActions", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getBuildFingerprints", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getBuildStatusIconClassName", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getBuildStatusSummary", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getBuildStatusUrl", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getCause", "(Class)", "summary", "df-generated"] + - ["hudson.model", "Run", "getCauses", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getCharset", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getDuration", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getDurationString", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getEstimatedDuration", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getExecutor", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getHasArtifacts", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getIconColor", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getLog", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getLog", "(int)", "summary", "df-generated"] + - ["hudson.model", "Run", "getNumber", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getOneOffExecutor", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getQueueId", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getStartTimeInMillis", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getTime", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getTimeInMillis", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getTimestamp", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getTimestampString2", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getTimestampString", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getTransientActions", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "getWhyKeepLog", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "hasCustomDisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "hasntStartedYet", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "isBuilding", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "isInProgress", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "isKeepLog", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "isLogUpdated", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "keepLog", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "keepLog", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "Run", "reload", "()", "summary", "df-generated"] + - ["hudson.model", "Run", "setQueueId", "(long)", "summary", "df-generated"] + - ["hudson.model", "Run", "updateSymlinks", "(TaskListener)", "summary", "df-generated"] + - ["hudson.model", "Run", "writeLogTo", "(long,XMLOutput)", "summary", "df-generated"] + - ["hudson.model", "Run", "writeWholeLogTo", "(OutputStream)", "summary", "df-generated"] + - ["hudson.model", "RunMap", "newestValue", "()", "summary", "df-generated"] + - ["hudson.model", "RunMap", "oldestValue", "()", "summary", "df-generated"] + - ["hudson.model", "RunMap", "remove", "(Run)", "summary", "df-generated"] + - ["hudson.model", "RunParameterDefinition$DescriptorImpl", "doAutoCompleteProjectName", "(String)", "summary", "df-generated"] + - ["hudson.model", "RunParameterDefinition$RunParameterFilter", "getName", "()", "summary", "df-generated"] + - ["hudson.model", "RunParameterDefinition", "getBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "RunParameterDefinition", "getFilter", "()", "summary", "df-generated"] + - ["hudson.model", "RunParameterDefinition", "getProject", "()", "summary", "df-generated"] + - ["hudson.model", "RunParameterValue", "getRun", "()", "summary", "df-generated"] + - ["hudson.model", "Saveable", "save", "()", "summary", "df-generated"] + - ["hudson.model", "SimpleParameterDefinition", "createValue", "(String)", "summary", "df-generated"] + - ["hudson.model", "Slave$JnlpJar", "doIndex", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "Slave$JnlpJar", "getURL", "()", "summary", "df-generated"] + - ["hudson.model", "Slave$JnlpJar", "readFully", "()", "summary", "df-generated"] + - ["hudson.model", "Slave$SlaveDescriptor", "computerLauncherDescriptors", "(Slave)", "summary", "df-generated"] + - ["hudson.model", "Slave$SlaveDescriptor", "doCheckNumExecutors", "(String)", "summary", "df-generated"] + - ["hudson.model", "Slave$SlaveDescriptor", "doCheckRemoteFS", "(String)", "summary", "df-generated"] + - ["hudson.model", "Slave$SlaveDescriptor", "nodePropertyDescriptors", "(Slave)", "summary", "df-generated"] + - ["hudson.model", "Slave$SlaveDescriptor", "retentionStrategyDescriptors", "(Slave)", "summary", "df-generated"] + - ["hudson.model", "Slave", "getComputer", "()", "summary", "df-generated"] + - ["hudson.model", "Slave", "getWorkspaceRoot", "()", "summary", "df-generated"] + - ["hudson.model", "Slave", "setMode", "(Mode)", "summary", "df-generated"] + - ["hudson.model", "Slave", "setNodeProperties", "(List)", "summary", "df-generated"] + - ["hudson.model", "Slave", "setNumExecutors", "(int)", "summary", "df-generated"] + - ["hudson.model", "Slave", "setUserId", "(String)", "summary", "df-generated"] + - ["hudson.model", "StatusIcon", "getDescription", "()", "summary", "df-generated"] + - ["hudson.model", "StreamBuildListener", "StreamBuildListener", "(File,Charset)", "summary", "df-generated"] + - ["hudson.model", "StringParameterDefinition", "isTrim", "()", "summary", "df-generated"] + - ["hudson.model", "StringParameterDefinition", "setTrim", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "StringParameterValue", "doTrim", "()", "summary", "df-generated"] + - ["hudson.model", "TaskAction", "doClearError", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "TaskAction", "doProgressiveHtml", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "TaskAction", "doProgressiveLog", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "TaskAction", "getLog", "()", "summary", "df-generated"] + - ["hudson.model", "TaskAction", "obtainLog", "()", "summary", "df-generated"] + - ["hudson.model", "TaskListener", "annotate", "(ConsoleNote)", "summary", "df-generated"] + - ["hudson.model", "TaskListener", "error", "(String)", "summary", "df-generated"] + - ["hudson.model", "TaskListener", "error", "(String,Object[])", "summary", "df-generated"] + - ["hudson.model", "TaskListener", "fatalError", "(String)", "summary", "df-generated"] + - ["hudson.model", "TaskListener", "fatalError", "(String,Object[])", "summary", "df-generated"] + - ["hudson.model", "TaskListener", "getCharset", "()", "summary", "df-generated"] + - ["hudson.model", "TaskListener", "getLogger", "()", "summary", "df-generated"] + - ["hudson.model", "TaskListener", "hyperlink", "(String,String)", "summary", "df-generated"] + - ["hudson.model", "TaskThread$ListenerAndText", "forFile", "(File)", "summary", "df-generated"] + - ["hudson.model", "TaskThread$ListenerAndText", "forMemory", "()", "summary", "df-generated"] + - ["hudson.model", "TaskThread", "isRunning", "()", "summary", "df-generated"] + - ["hudson.model", "TaskThread", "readAll", "()", "summary", "df-generated"] + - ["hudson.model", "TimeSeries", "TimeSeries", "(float,float,int)", "summary", "df-generated"] + - ["hudson.model", "TimeSeries", "getHistory", "()", "summary", "df-generated"] + - ["hudson.model", "TimeSeries", "getLatest", "()", "summary", "df-generated"] + - ["hudson.model", "TimeSeries", "toString", "()", "summary", "df-generated"] + - ["hudson.model", "TimeSeries", "update", "(float)", "summary", "df-generated"] + - ["hudson.model", "TimeZoneProperty$DescriptorImpl", "doCheckTimeZoneName", "(String)", "summary", "df-generated"] + - ["hudson.model", "TimeZoneProperty$DescriptorImpl", "doFillTimeZoneNameItems", "(User)", "summary", "df-generated"] + - ["hudson.model", "TimeZoneProperty", "forCurrentUser", "()", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "all", "()", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "checkApplicableIn", "(ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "getCategoryId", "()", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "getDescription", "()", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "getIconFilePathPattern", "()", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "isApplicable", "(Descriptor)", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "isApplicableIn", "(ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "newInstance", "(ItemGroup,String)", "summary", "df-generated"] + - ["hudson.model", "TopLevelItemDescriptor", "testInstance", "(TopLevelItem)", "summary", "df-generated"] + - ["hudson.model", "TransientBuildActionFactory", "all", "()", "summary", "df-generated"] + - ["hudson.model", "TransientBuildActionFactory", "createFor", "(AbstractBuild)", "summary", "df-generated"] + - ["hudson.model", "TransientBuildActionFactory", "createFor", "(Run)", "summary", "df-generated"] + - ["hudson.model", "TransientComputerActionFactory", "all", "()", "summary", "df-generated"] + - ["hudson.model", "TransientComputerActionFactory", "createAllFor", "(Computer)", "summary", "df-generated"] + - ["hudson.model", "TransientComputerActionFactory", "createFor", "(Computer)", "summary", "df-generated"] + - ["hudson.model", "TransientProjectActionFactory", "all", "()", "summary", "df-generated"] + - ["hudson.model", "TransientProjectActionFactory", "createFor", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "TransientUserActionFactory", "all", "()", "summary", "df-generated"] + - ["hudson.model", "TransientUserActionFactory", "createFor", "(User)", "summary", "df-generated"] + - ["hudson.model", "TransientViewActionFactory", "all", "()", "summary", "df-generated"] + - ["hudson.model", "TransientViewActionFactory", "createAllFor", "(View)", "summary", "df-generated"] + - ["hudson.model", "TransientViewActionFactory", "createFor", "(View)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$CoreUpdateMonitor", "getData", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob$InstallationStatus", "getType", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob$InstallationStatus", "isSuccess", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob$InstallationStatus", "requiresRestart", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob$Installing", "Installing", "(int)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob", "_run", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob", "getContentLength", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob", "getDisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$DownloadJob", "getName", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$RestartJenkinsJob$Pending", "getType", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$RestartJenkinsJob", "cancel", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "checkConnection", "(ConnectionCheckJob,String)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "checkUpdateCenter", "(ConnectionCheckJob,String)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "download", "(DownloadJob,URL)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "getConnectionCheckUrl", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "getPluginRepositoryBaseUrl", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "getUpdateCenterUrl", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "install", "(DownloadJob,File,File)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "postValidate", "(DownloadJob,File)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "preValidate", "(DownloadJob,URL)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", "upgrade", "(DownloadJob,File,File)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterJob", "getType", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterJob", "schedule", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter$UpdateCenterJob", "submit", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doCancelRestart", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doConnectionStatus", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doDowngrade", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doIncompleteInstallStatus", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doInstallStatus", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doInvalidateData", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doRestart", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doSafeRestart", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "doUpgrade", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getAvailables", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getBackupVersion", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getCategorizedAvailables", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getDefaultBaseUrl", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getLastUpdatedString", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getPlugin", "(String)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getPlugin", "(String,VersionNumber)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getPluginFromAllSites", "(String,VersionNumber)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getSiteList", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "getUpdates", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "hasIncompatibleUpdates", "(MetadataCache)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "init", "(Jenkins)", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "isDowngradable", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "isRestartRequiredForCompletion", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "isRestartScheduled", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "isSiteDataReady", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "load", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "persistInstallStatus", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "updateAllSites", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "updateAllSitesNow", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateCenter", "updateDefaultSite", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Data", "canUpgrade", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Data", "hasCoreUpdates", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Entry", "getFileSize", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Entry", "isNewerThan", "(String)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "deploy", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "deploy", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "deploy", "(boolean,UUID,List,boolean)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "deployBackup", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "doDowngrade", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "doInstall", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "doInstallNow", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "fixesSecurityVulnerabilities", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "getDependenciesIncompatibleWithInstalledVersion", "(MetadataCache)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "getDeprecation", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "getDisplayName", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "getInstalled", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "getNeededDependencies", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "getNeededDependenciesRequiredCore", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "getWarnings", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "hasCategory", "(String)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "hasIncompatibleParentPlugins", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "hasWarnings", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "install", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isCompatible", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isCompatible", "(MetadataCache)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isCompatibleWithInstalledVersion", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isDeprecated", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isForNewerHudson", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isNeededDependenciesCompatibleWithInstalledVersion", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isNeededDependenciesCompatibleWithInstalledVersion", "(MetadataCache)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isNeededDependenciesForNewerJenkins", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Plugin", "isNeededDependenciesForNewerJenkins", "(MetadataCache)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Warning", "Warning", "(JSONObject)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Warning", "isFixable", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Warning", "isPluginWarning", "(String)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Warning", "isRelevant", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$Warning", "isRelevantToVersion", "(VersionNumber)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$WarningVersionRange", "WarningVersionRange", "(JSONObject)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite$WarningVersionRange", "includes", "(VersionNumber)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "doInvalidateData", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "doVerifySignature", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "getDataTimestamp", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "getJSONObject", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "getUpdates", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "hasUpdates", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "isDue", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "isLegacyDefault", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "updateDirectly", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "updateDirectly", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "updateDirectlyNow", "()", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "updateDirectlyNow", "(boolean)", "summary", "df-generated"] + - ["hudson.model", "UpdateSite", "verifySignatureInternal", "(JSONObject)", "summary", "df-generated"] + - ["hudson.model", "UsageStatistics$CombinedCipherInputStream", "CombinedCipherInputStream", "(InputStream,Cipher,String,int)", "summary", "df-generated"] + - ["hudson.model", "UsageStatistics$CombinedCipherInputStream", "CombinedCipherInputStream", "(InputStream,RSAKey,String)", "summary", "df-generated"] + - ["hudson.model", "UsageStatistics", "getStatData", "()", "summary", "df-generated"] + - ["hudson.model", "UsageStatistics", "isDue", "()", "summary", "df-generated"] + - ["hudson.model", "User$AllUsers", "scanAll", "()", "summary", "df-generated"] + - ["hudson.model", "User$CanonicalIdResolver", "all", "()", "summary", "df-generated"] + - ["hudson.model", "User$CanonicalIdResolver", "getPriority", "()", "summary", "df-generated"] + - ["hudson.model", "User$CanonicalIdResolver", "resolveCanonicalId", "(String,Map)", "summary", "df-generated"] + - ["hudson.model", "User", "canDelete", "()", "summary", "df-generated"] + - ["hudson.model", "User", "clear", "()", "summary", "df-generated"] + - ["hudson.model", "User", "current", "()", "summary", "df-generated"] + - ["hudson.model", "User", "delete", "()", "summary", "df-generated"] + - ["hudson.model", "User", "doConfigSubmit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "User", "doDoDelete", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "User", "doRssAll", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "User", "doRssFailed", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "User", "doRssLatest", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "User", "doSubmitDescription", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "User", "get2", "(Authentication)", "summary", "df-generated"] + - ["hudson.model", "User", "get", "(Authentication)", "summary", "df-generated"] + - ["hudson.model", "User", "getAll", "()", "summary", "df-generated"] + - ["hudson.model", "User", "getAuthorities", "()", "summary", "df-generated"] + - ["hudson.model", "User", "getBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "User", "getProjects", "()", "summary", "df-generated"] + - ["hudson.model", "User", "getProperty", "(Class)", "summary", "df-generated"] + - ["hudson.model", "User", "getTransientActions", "()", "summary", "df-generated"] + - ["hudson.model", "User", "getUnknown", "()", "summary", "df-generated"] + - ["hudson.model", "User", "getUserDetailsForImpersonation", "()", "summary", "df-generated"] + - ["hudson.model", "User", "getUserFolder", "()", "summary", "df-generated"] + - ["hudson.model", "User", "idStrategy", "()", "summary", "df-generated"] + - ["hudson.model", "User", "impersonate2", "()", "summary", "df-generated"] + - ["hudson.model", "User", "impersonate", "()", "summary", "df-generated"] + - ["hudson.model", "User", "impersonate", "(UserDetails)", "summary", "df-generated"] + - ["hudson.model", "User", "isIdOrFullnameAllowed", "(String)", "summary", "df-generated"] + - ["hudson.model", "User", "rekey", "()", "summary", "df-generated"] + - ["hudson.model", "User", "reload", "()", "summary", "df-generated"] + - ["hudson.model", "UserProperty", "all", "()", "summary", "df-generated"] + - ["hudson.model", "UserPropertyDescriptor", "isEnabled", "()", "summary", "df-generated"] + - ["hudson.model", "UserPropertyDescriptor", "newInstance", "(User)", "summary", "df-generated"] + - ["hudson.model", "View$AsynchPeople", "getApi", "()", "summary", "df-generated"] + - ["hudson.model", "View$People", "isApplicable", "(Collection)", "summary", "df-generated"] + - ["hudson.model", "View$UserInfo", "getLastChangeTimeString", "()", "summary", "df-generated"] + - ["hudson.model", "View$UserInfo", "getTimeSortKey", "()", "summary", "df-generated"] + - ["hudson.model", "View", "all", "()", "summary", "df-generated"] + - ["hudson.model", "View", "allInstantiable", "()", "summary", "df-generated"] + - ["hudson.model", "View", "contains", "(TopLevelItem)", "summary", "df-generated"] + - ["hudson.model", "View", "doCheckJobName", "(String)", "summary", "df-generated"] + - ["hudson.model", "View", "doConfigDotXml", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.model", "View", "doConfigSubmit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "View", "doCreateItem", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "View", "doDoDelete", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "View", "doItemCategories", "(StaplerRequest,StaplerResponse,String)", "summary", "df-generated"] + - ["hudson.model", "View", "doRssAll", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "View", "doRssFailed", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "View", "doRssLatest", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "View", "doSubmitDescription", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.model", "View", "getAllItems", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getAllProperties", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getApplicablePropertyDescriptors", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getApproximateQueueItemsQuickly", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getBuilds", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getColumns", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getComputers", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getIndenter", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getItem", "(String)", "summary", "df-generated"] + - ["hudson.model", "View", "getItemCreatePermission", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getItems", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getNewPronoun", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getOwnerPrimaryView", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getPostConstructLandingPage", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getQueueItems", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getTimeline", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getVisiblePropertyDescriptors", "()", "summary", "df-generated"] + - ["hudson.model", "View", "getWidgets", "()", "summary", "df-generated"] + - ["hudson.model", "View", "hasPeople", "()", "summary", "df-generated"] + - ["hudson.model", "View", "isAutomaticRefreshEnabled", "()", "summary", "df-generated"] + - ["hudson.model", "View", "isDefault", "()", "summary", "df-generated"] + - ["hudson.model", "View", "isEditable", "()", "summary", "df-generated"] + - ["hudson.model", "View", "isFilterExecutors", "()", "summary", "df-generated"] + - ["hudson.model", "View", "isFilterQueue", "()", "summary", "df-generated"] + - ["hudson.model", "View", "onJobRenamed", "(Item,String,String)", "summary", "df-generated"] + - ["hudson.model", "View", "registerPermissions", "()", "summary", "df-generated"] + - ["hudson.model", "View", "rename", "(String)", "summary", "df-generated"] + - ["hudson.model", "View", "updateByXml", "(Source)", "summary", "df-generated"] + - ["hudson.model", "View", "updateTransientActions", "()", "summary", "df-generated"] + - ["hudson.model", "View", "writeXml", "(OutputStream)", "summary", "df-generated"] + - ["hudson.model", "ViewDescriptor", "doAutoCompleteCopyNewItemFrom", "(String,ItemGroup)", "summary", "df-generated"] + - ["hudson.model", "ViewDescriptor", "getColumnsDescriptors", "()", "summary", "df-generated"] + - ["hudson.model", "ViewDescriptor", "getJobFiltersDescriptors", "()", "summary", "df-generated"] + - ["hudson.model", "ViewDescriptor", "getNewViewDetailPage", "()", "summary", "df-generated"] + - ["hudson.model", "ViewDescriptor", "isApplicable", "(Class)", "summary", "df-generated"] + - ["hudson.model", "ViewDescriptor", "isApplicableIn", "(ViewGroup)", "summary", "df-generated"] + - ["hudson.model", "ViewDescriptor", "isInstantiable", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "canDelete", "(View)", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "deleteView", "(View)", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "getAllViews", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "getItemGroup", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "getPrimaryView", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "getUrl", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "getView", "(String)", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "getViewActions", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "getViews", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "getViewsTabBar", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroup", "onViewRenamed", "(View,String,String)", "summary", "df-generated"] + - ["hudson.model", "ViewGroupMixIn", "canDelete", "(View)", "summary", "df-generated"] + - ["hudson.model", "ViewGroupMixIn", "deleteView", "(View)", "summary", "df-generated"] + - ["hudson.model", "ViewGroupMixIn", "getPrimaryView", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroupMixIn", "getView", "(String)", "summary", "df-generated"] + - ["hudson.model", "ViewGroupMixIn", "getViews", "()", "summary", "df-generated"] + - ["hudson.model", "ViewGroupMixIn", "onViewRenamed", "(View,String,String)", "summary", "df-generated"] + - ["hudson.model", "ViewProperty", "all", "()", "summary", "df-generated"] + - ["hudson.model", "ViewPropertyDescriptor", "isEnabledFor", "(View)", "summary", "df-generated"] + - ["hudson.model", "ViewPropertyDescriptor", "newInstance", "(View)", "summary", "df-generated"] + - ["hudson.model", "WorkspaceBrowser", "getWorkspace", "(Job)", "summary", "df-generated"] + - ["hudson.model", "WorkspaceCleanupThread", "invoke", "()", "summary", "df-generated"] + - ["hudson.model", "WorkspaceListener", "afterDelete", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.model", "WorkspaceListener", "all", "()", "summary", "df-generated"] + - ["hudson.model", "WorkspaceListener", "beforeUse", "(AbstractBuild,FilePath,BuildListener)", "summary", "df-generated"] + - ["hudson.node_monitors", "AbstractDiskSpaceMonitor", "getThresholdBytes", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "AbstractDiskSpaceMonitor", "markNodeOfflineIfDiskspaceIsTooLow", "(Computer)", "summary", "df-generated"] + - ["hudson.node_monitors", "AbstractNodeMonitorDescriptor", "getTimestamp", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "AbstractNodeMonitorDescriptor", "getTimestampString", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "AbstractNodeMonitorDescriptor", "isIgnored", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "ClockMonitor", "getDifferenceFor", "(Computer)", "summary", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitor", "getFreeSpace", "(Computer)", "summary", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitor", "install", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitorDescriptor$DiskSpace", "getFreeSize", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitorDescriptor$DiskSpace", "getGbLeft", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitorDescriptor$DiskSpace", "parse", "(String)", "summary", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitorDescriptor$DiskSpace", "toHtml", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "DiskSpaceMonitorDescriptor$DiskSpace", "toString", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "AbstractNodeMonitorDescriptor_NoDataYet", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "ArchitectureMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "ClockMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "DiskSpaceMonitorDescriptor_DiskSpace_FreeSpace", "(Object,Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "DiskSpaceMonitorDescriptor_DiskSpace_FreeSpaceTooLow", "(Object,Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "DiskSpaceMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "DiskSpaceMonitor_MarkedOffline", "(Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "DiskSpaceMonitor_MarkedOnline", "(Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "MonitorMarkedNodeOffline_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "ResponseTimeMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "ResponseTimeMonitor_MarkedOffline", "(Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "ResponseTimeMonitor_TimeOut", "(Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "SwapSpaceMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "TemporarySpaceMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_AbstractNodeMonitorDescriptor_NoDataYet", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_ArchitectureMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_ClockMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_DiskSpaceMonitorDescriptor_DiskSpace_FreeSpace", "(Object,Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_DiskSpaceMonitorDescriptor_DiskSpace_FreeSpaceTooLow", "(Object,Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_DiskSpaceMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_DiskSpaceMonitor_MarkedOffline", "(Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_DiskSpaceMonitor_MarkedOnline", "(Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_MonitorMarkedNodeOffline_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_ResponseTimeMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_ResponseTimeMonitor_MarkedOffline", "(Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_ResponseTimeMonitor_TimeOut", "(Object)", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_SwapSpaceMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "Messages", "_TemporarySpaceMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "MonitorOfflineCause", "getTrigger", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "NodeMonitor", "all", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "NodeMonitor", "data", "(Computer)", "summary", "df-generated"] + - ["hudson.node_monitors", "NodeMonitor", "getAll", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "NodeMonitor", "getColumnCaption", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "NodeMonitor", "isIgnored", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "NodeMonitor", "setIgnored", "(boolean)", "summary", "df-generated"] + - ["hudson.node_monitors", "NodeMonitor", "triggerUpdate", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "ResponseTimeMonitor$Data", "getAverage", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "ResponseTimeMonitor$Data", "hasTooManyTimeouts", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "ResponseTimeMonitor$Data", "toString", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "SwapSpaceMonitor$MemoryUsage2", "MemoryUsage2", "(MemoryUsage)", "summary", "df-generated"] + - ["hudson.node_monitors", "SwapSpaceMonitor$MemoryUsage2", "getAvailablePhysicalMemory", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "SwapSpaceMonitor$MemoryUsage2", "getAvailableSwapSpace", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "SwapSpaceMonitor$MemoryUsage2", "getTotalPhysicalMemory", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "SwapSpaceMonitor$MemoryUsage2", "getTotalSwapSpace", "()", "summary", "df-generated"] + - ["hudson.node_monitors", "SwapSpaceMonitor", "toHtml", "(MemoryUsage)", "summary", "df-generated"] + - ["hudson.node_monitors", "SwapSpaceMonitor", "toMB", "(MemoryUsage)", "summary", "df-generated"] + - ["hudson.node_monitors", "TemporarySpaceMonitor", "getFreeSpace", "(Computer)", "summary", "df-generated"] + - ["hudson.node_monitors", "TemporarySpaceMonitor", "install", "()", "summary", "df-generated"] + - ["hudson.os", "SU", "execute", "(TaskListener,String,String,Callable)", "summary", "df-generated"] + - ["hudson.os", "SU", "start", "(TaskListener,String,String)", "summary", "df-generated"] + - ["hudson.os", "WindowsUtil", "execCmd", "(String[])", "summary", "df-generated"] + - ["hudson.scheduler", "CronTab", "ceil", "(long)", "summary", "df-generated"] + - ["hudson.scheduler", "CronTab", "checkSanity", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CronTab", "floor", "(long)", "summary", "df-generated"] + - ["hudson.scheduler", "CronTab", "getTimeZone", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CronTab", "toString", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CronTabList", "check", "(Calendar)", "summary", "df-generated"] + - ["hudson.scheduler", "CronTabList", "checkSanity", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CronTabList", "create", "(String)", "summary", "df-generated"] + - ["hudson.scheduler", "CronTabList", "create", "(String,Hash)", "summary", "df-generated"] + - ["hudson.scheduler", "CronTabList", "next", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CronTabList", "previous", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabLexer", "CrontabLexer", "(CharStream)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$ExprContext", "ExprContext", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$ExprContext", "ExprContext", "(ParserRuleContext,int,int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$ExprContext", "OR", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$ExprContext", "expr", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$ExprContext", "term", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "ANNUALLY", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "AT", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "DAILY", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "EOF", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "HOURLY", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "MIDNIGHT", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "MONTHLY", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "StartRuleContext", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "WEEKLY", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "WS", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "WS", "(int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "YEARLY", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "expr", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$StartRuleContext", "expr", "(int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "DIV", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "H", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "LPAREN", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "MINUS", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "RPAREN", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "STAR", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "TermContext", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "TermContext", "(ParserRuleContext,int,int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "token", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TermContext", "token", "(int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TokenContext", "TOKEN", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser$TokenContext", "TokenContext", "(ParserRuleContext,int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser", "CrontabParser", "(TokenStream)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser", "expr", "(int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser", "term", "(int)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParser", "token", "()", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParserListener", "enterExpr", "(ExprContext)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParserListener", "enterStartRule", "(StartRuleContext)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParserListener", "enterTerm", "(TermContext)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParserListener", "enterToken", "(TokenContext)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParserListener", "exitExpr", "(ExprContext)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParserListener", "exitStartRule", "(StartRuleContext)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParserListener", "exitTerm", "(TermContext)", "summary", "df-generated"] + - ["hudson.scheduler", "CrontabParserListener", "exitToken", "(TokenContext)", "summary", "df-generated"] + - ["hudson.scheduler", "Hash", "from", "(String)", "summary", "df-generated"] + - ["hudson.scheduler", "Hash", "next", "(int)", "summary", "df-generated"] + - ["hudson.scheduler", "Hash", "zero", "()", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "BaseParser_MustBePositive", "(Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "BaseParser_OutOfRange", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "BaseParser_StartEndReversed", "(Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "CronTabList_InvalidInput", "(Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "CronTab_do_you_really_mean_every_minute_when_you", "(Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "CronTab_short_cycles_in_the_day_of_month_field_w", "()", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "CronTab_spread_load_evenly_by_using_rather_than_", "(Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "_BaseParser_MustBePositive", "(Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "_BaseParser_OutOfRange", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "_BaseParser_StartEndReversed", "(Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "_CronTabList_InvalidInput", "(Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "_CronTab_do_you_really_mean_every_minute_when_you", "(Object,Object)", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "_CronTab_short_cycles_in_the_day_of_month_field_w", "()", "summary", "df-generated"] + - ["hudson.scheduler", "Messages", "_CronTab_spread_load_evenly_by_using_rather_than_", "(Object,Object)", "summary", "df-generated"] + - ["hudson.scm", "AbstractScmTagAction", "doIndex", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.scm", "AbstractScmTagAction", "getTooltip", "()", "summary", "df-generated"] + - ["hudson.scm", "AbstractScmTagAction", "isTagged", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogAnnotator", "all", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogAnnotator", "annotate", "(AbstractBuild,Entry,MarkupText)", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogAnnotator", "annotate", "(Run,Entry,MarkupText)", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogAnnotator", "register", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogAnnotator", "unregister", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", "getAffectedFiles", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", "getAffectedPaths", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", "getAuthor", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", "getCommitId", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", "getMsg", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", "getMsgAnnotated", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", "getMsgEscaped", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet$Entry", "getTimestamp", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet", "getKind", "()", "summary", "df-generated"] + - ["hudson.scm", "ChangeLogSet", "isEmptySet", "()", "summary", "df-generated"] + - ["hudson.scm", "Messages", "NullSCM_DisplayName", "()", "summary", "df-generated"] + - ["hudson.scm", "Messages", "SCM_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.scm", "Messages", "SCM_TagPermission_Description", "()", "summary", "df-generated"] + - ["hudson.scm", "Messages", "_NullSCM_DisplayName", "()", "summary", "df-generated"] + - ["hudson.scm", "Messages", "_SCM_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.scm", "Messages", "_SCM_TagPermission_Description", "()", "summary", "df-generated"] + - ["hudson.scm", "PollingResult", "PollingResult", "(Change)", "summary", "df-generated"] + - ["hudson.scm", "PollingResult", "hasChanges", "()", "summary", "df-generated"] + - ["hudson.scm", "RepositoryBrowser", "all", "()", "summary", "df-generated"] + - ["hudson.scm", "RepositoryBrowser", "getChangeSetLink", "(Entry)", "summary", "df-generated"] + - ["hudson.scm", "RepositoryBrowsers", "createInstance", "(Class,StaplerRequest,JSONObject,String)", "summary", "df-generated"] + - ["hudson.scm", "RepositoryBrowsers", "createInstance", "(Class,StaplerRequest,String)", "summary", "df-generated"] + - ["hudson.scm", "RepositoryBrowsers", "filter", "(Class)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "_calcRevisionsFromBuild", "(AbstractBuild,Launcher,TaskListener)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "_for", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "_for", "(Job)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "all", "()", "summary", "df-generated"] + - ["hudson.scm", "SCM", "buildEnvVars", "(AbstractBuild,Map)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "buildEnvironment", "(Run,Map)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "calcRevisionsFromBuild", "(AbstractBuild,Launcher,TaskListener)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "calcRevisionsFromBuild", "(Run,FilePath,Launcher,TaskListener)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "checkout", "(AbstractBuild,Launcher,FilePath,BuildListener,File)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "checkout", "(Run,Launcher,FilePath,TaskListener,File,SCMRevisionState)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "compareRemoteRevisionWith", "(Job,Launcher,FilePath,TaskListener,SCMRevisionState)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "createChangeLogParser", "()", "summary", "df-generated"] + - ["hudson.scm", "SCM", "getBrowser", "()", "summary", "df-generated"] + - ["hudson.scm", "SCM", "getKey", "()", "summary", "df-generated"] + - ["hudson.scm", "SCM", "getType", "()", "summary", "df-generated"] + - ["hudson.scm", "SCM", "guessBrowser", "()", "summary", "df-generated"] + - ["hudson.scm", "SCM", "poll", "(AbstractProject,Launcher,FilePath,TaskListener,SCMRevisionState)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "pollChanges", "(AbstractProject,Launcher,FilePath,TaskListener)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "postCheckout", "(AbstractBuild,Launcher,FilePath,BuildListener)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "postCheckout", "(Run,Launcher,FilePath,TaskListener)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "processWorkspaceBeforeDeletion", "(AbstractProject,FilePath,Node)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "processWorkspaceBeforeDeletion", "(Job,FilePath,Node)", "summary", "df-generated"] + - ["hudson.scm", "SCM", "requiresWorkspaceForPolling", "()", "summary", "df-generated"] + - ["hudson.scm", "SCM", "supportsPolling", "()", "summary", "df-generated"] + - ["hudson.scm", "SCMDescriptor", "getBrowserDescriptors", "()", "summary", "df-generated"] + - ["hudson.scm", "SCMDescriptor", "getGeneration", "()", "summary", "df-generated"] + - ["hudson.scm", "SCMDescriptor", "incrementGeneration", "()", "summary", "df-generated"] + - ["hudson.scm", "SCMDescriptor", "isApplicable", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.scm", "SCMDescriptor", "isApplicable", "(Job)", "summary", "df-generated"] + - ["hudson.scm", "SCMDescriptor", "isBrowserReusable", "(SCM,SCM)", "summary", "df-generated"] + - ["hudson.scm", "SCMS", "parseSCM", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.scm", "SCMS", "parseSCM", "(StaplerRequest,AbstractProject)", "summary", "df-generated"] + - ["hudson.search", "Messages", "UserSearchProperty_DisplayName", "()", "summary", "df-generated"] + - ["hudson.search", "Messages", "_UserSearchProperty_DisplayName", "()", "summary", "df-generated"] + - ["hudson.search", "Search", "doIndex", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.search", "Search", "doSuggest", "(StaplerRequest,StaplerResponse,String)", "summary", "df-generated"] + - ["hudson.search", "Search", "doSuggestOpenSearch", "(StaplerRequest,StaplerResponse,String)", "summary", "df-generated"] + - ["hudson.search", "Search", "getSuggestions", "(StaplerRequest,String)", "summary", "df-generated"] + - ["hudson.search", "Search", "suggest", "(SearchIndex,String)", "summary", "df-generated"] + - ["hudson.search", "Search", "suggest", "(SearchIndex,String,SearchableModelObject)", "summary", "df-generated"] + - ["hudson.search", "SearchFactory", "all", "()", "summary", "df-generated"] + - ["hudson.search", "SearchFactory", "createFor", "(SearchableModelObject)", "summary", "df-generated"] + - ["hudson.search", "SearchIndex", "find", "(String,List)", "summary", "df-generated"] + - ["hudson.search", "SearchIndex", "suggest", "(String,List)", "summary", "df-generated"] + - ["hudson.search", "SearchItem", "getSearchIndex", "()", "summary", "df-generated"] + - ["hudson.search", "SearchItem", "getSearchName", "()", "summary", "df-generated"] + - ["hudson.search", "SearchItem", "getSearchUrl", "()", "summary", "df-generated"] + - ["hudson.search", "SearchItems", "create", "(String,String)", "summary", "df-generated"] + - ["hudson.search", "SearchItems", "create", "(String,String,SearchIndex)", "summary", "df-generated"] + - ["hudson.search", "SearchItems", "create", "(String,String,SearchableModelObject)", "summary", "df-generated"] + - ["hudson.search", "SearchResult", "hasMoreResults", "()", "summary", "df-generated"] + - ["hudson.search", "SearchableModelObject", "getSearch", "()", "summary", "df-generated"] + - ["hudson.search", "UserSearchProperty", "UserSearchProperty", "(boolean)", "summary", "df-generated"] + - ["hudson.search", "UserSearchProperty", "getInsensitiveSearch", "()", "summary", "df-generated"] + - ["hudson.search", "UserSearchProperty", "isCaseInsensitive", "()", "summary", "df-generated"] + - ["hudson.security.captcha", "CaptchaSupport", "all", "()", "summary", "df-generated"] + - ["hudson.security.captcha", "CaptchaSupport", "generateImage", "(String,OutputStream)", "summary", "df-generated"] + - ["hudson.security.captcha", "CaptchaSupport", "validateCaptcha", "(String,String)", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbExclusion", "all", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbExclusion", "process", "(HttpServletRequest,HttpServletResponse,FilterChain)", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbFilter", "getCrumbIssuer", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", "all", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", "getCrumb", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", "getCrumb", "(ServletRequest)", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", "getCrumbRequestField", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", "initStaplerCrumbIssuer", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", "validateCrumb", "(ServletRequest)", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", "validateCrumb", "(ServletRequest,MultipartFormDataParser)", "summary", "df-generated"] + - ["hudson.security.csrf", "CrumbIssuer", "validateCrumb", "(ServletRequest,String,String)", "summary", "df-generated"] + - ["hudson.security.csrf", "DefaultCrumbIssuer", "DefaultCrumbIssuer", "(boolean)", "summary", "df-generated"] + - ["hudson.security.csrf", "DefaultCrumbIssuer", "isExcludeClientIPFromCrumb", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "GlobalCrumbIssuerConfiguration", "createDefaultCrumbIssuer", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "GlobalCrumbIssuerConfiguration", "getCrumbIssuer", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "Messages", "DefaultCrumbIssuer_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security.csrf", "Messages", "_DefaultCrumbIssuer_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "ACL", "as2", "(Authentication)", "summary", "df-generated"] + - ["hudson.security", "ACL", "as", "(Authentication)", "summary", "df-generated"] + - ["hudson.security", "ACL", "as", "(User)", "summary", "df-generated"] + - ["hudson.security", "ACL", "checkAnyPermission", "(Permission[])", "summary", "df-generated"] + - ["hudson.security", "ACL", "checkCreatePermission", "(ItemGroup,TopLevelItemDescriptor)", "summary", "df-generated"] + - ["hudson.security", "ACL", "checkCreatePermission", "(ViewGroup,ViewDescriptor)", "summary", "df-generated"] + - ["hudson.security", "ACL", "checkPermission", "(Permission)", "summary", "df-generated"] + - ["hudson.security", "ACL", "hasAnyPermission", "(Permission[])", "summary", "df-generated"] + - ["hudson.security", "ACL", "hasCreatePermission2", "(Authentication,ItemGroup,TopLevelItemDescriptor)", "summary", "df-generated"] + - ["hudson.security", "ACL", "hasCreatePermission2", "(Authentication,ViewGroup,ViewDescriptor)", "summary", "df-generated"] + - ["hudson.security", "ACL", "hasCreatePermission", "(Authentication,ItemGroup,TopLevelItemDescriptor)", "summary", "df-generated"] + - ["hudson.security", "ACL", "hasCreatePermission", "(Authentication,ViewGroup,ViewDescriptor)", "summary", "df-generated"] + - ["hudson.security", "ACL", "hasPermission2", "(Authentication,Permission)", "summary", "df-generated"] + - ["hudson.security", "ACL", "hasPermission", "(Authentication,Permission)", "summary", "df-generated"] + - ["hudson.security", "ACL", "hasPermission", "(Permission)", "summary", "df-generated"] + - ["hudson.security", "ACL", "impersonate2", "(Authentication)", "summary", "df-generated"] + - ["hudson.security", "ACL", "impersonate2", "(Authentication,Callable)", "summary", "df-generated"] + - ["hudson.security", "ACL", "impersonate2", "(Authentication,Runnable)", "summary", "df-generated"] + - ["hudson.security", "ACL", "impersonate", "(Authentication)", "summary", "df-generated"] + - ["hudson.security", "ACL", "impersonate", "(Authentication,Callable)", "summary", "df-generated"] + - ["hudson.security", "ACL", "impersonate", "(Authentication,Runnable)", "summary", "df-generated"] + - ["hudson.security", "ACL", "isAnonymous2", "(Authentication)", "summary", "df-generated"] + - ["hudson.security", "ACL", "isAnonymous", "(Authentication)", "summary", "df-generated"] + - ["hudson.security", "ACL", "lambda2", "(BiFunction)", "summary", "df-generated"] + - ["hudson.security", "ACL", "lambda", "(BiFunction)", "summary", "df-generated"] + - ["hudson.security", "ACLContext", "getPreviousContext", "()", "summary", "df-generated"] + - ["hudson.security", "AccessControlled", "checkAnyPermission", "(Permission[])", "summary", "df-generated"] + - ["hudson.security", "AccessControlled", "checkPermission", "(Permission)", "summary", "df-generated"] + - ["hudson.security", "AccessControlled", "getACL", "()", "summary", "df-generated"] + - ["hudson.security", "AccessControlled", "hasAnyPermission", "(Permission[])", "summary", "df-generated"] + - ["hudson.security", "AccessControlled", "hasPermission2", "(Authentication,Permission)", "summary", "df-generated"] + - ["hudson.security", "AccessControlled", "hasPermission", "(Authentication,Permission)", "summary", "df-generated"] + - ["hudson.security", "AccessControlled", "hasPermission", "(Permission)", "summary", "df-generated"] + - ["hudson.security", "AccessDeniedException2", "report", "(PrintWriter)", "summary", "df-generated"] + - ["hudson.security", "AccessDeniedException2", "reportAsHeaders", "(HttpServletResponse)", "summary", "df-generated"] + - ["hudson.security", "AccessDeniedException3", "report", "(PrintWriter)", "summary", "df-generated"] + - ["hudson.security", "AccessDeniedException3", "reportAsHeaders", "(HttpServletResponse)", "summary", "df-generated"] + - ["hudson.security", "AuthenticationProcessingFilter2", "AuthenticationProcessingFilter2", "(String)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "all", "()", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getACL", "(AbstractItem)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getACL", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getACL", "(Cloud)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getACL", "(Computer)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getACL", "(Job)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getACL", "(Node)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getACL", "(User)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getACL", "(View)", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getGroups", "()", "summary", "df-generated"] + - ["hudson.security", "AuthorizationStrategy", "getRootACL", "()", "summary", "df-generated"] + - ["hudson.security", "CliAuthenticator", "authenticate", "()", "summary", "df-generated"] + - ["hudson.security", "ContainerAuthentication", "ContainerAuthentication", "(HttpServletRequest)", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "addTo", "(User)", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "addToCurrentUser", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "getEmailAddress", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "getFullName", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "getIdentifier", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "getNickname", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "getPronoun", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "locateUser", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "signin", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService$FederatedIdentity", "toString", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService", "all", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService", "getUrlName", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginService", "getUserPropertyClass", "()", "summary", "df-generated"] + - ["hudson.security", "FederatedLoginServiceUserProperty", "has", "(String)", "summary", "df-generated"] + - ["hudson.security", "FullControlOnceLoggedInAuthorizationStrategy", "isAllowAnonymousRead", "()", "summary", "df-generated"] + - ["hudson.security", "FullControlOnceLoggedInAuthorizationStrategy", "setAllowAnonymousRead", "(boolean)", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "configure", "(StaplerRequest,JSONObject)", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "doConfigure", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "getAgentProtocols", "()", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "getAuthorizationStrategy", "()", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "getMarkupFormatter", "()", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "getSecurityRealm", "()", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "getSlaveAgentPort", "()", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "isDisableRememberMe", "()", "summary", "df-generated"] + - ["hudson.security", "GlobalSecurityConfiguration", "isSlaveAgentPortEnforced", "()", "summary", "df-generated"] + - ["hudson.security", "GroupDetails", "getDisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "GroupDetails", "getMembers", "()", "summary", "df-generated"] + - ["hudson.security", "GroupDetails", "getName", "()", "summary", "df-generated"] + - ["hudson.security", "HttpSessionContextIntegrationFilter2", "HttpSessionContextIntegrationFilter2", "(SecurityContextRepository)", "summary", "df-generated"] + - ["hudson.security", "HudsonFilter", "get", "(ServletContext)", "summary", "df-generated"] + - ["hudson.security", "HudsonFilter", "reset", "(SecurityRealm)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$DescriptorImpl", "doCheckAllowsSignup", "(boolean)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", "getAuthorities2", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", "getAuthorities", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", "getProtectedPassword", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", "isAccountNonExpired", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", "isAccountNonLocked", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", "isCredentialsNonExpired", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", "isEnabled", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$Details", "isPasswordCorrect", "(String)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$SignupInfo", "SignupInfo", "(FederatedIdentity)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm$SignupInfo", "SignupInfo", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "HudsonPrivateSecurityRealm", "(boolean)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "createAccountByAdmin", "(StaplerRequest,StaplerResponse,String,String)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "createAccountFromSetupWizard", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "doCreateAccount", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "doCreateAccountByAdmin", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "doCreateAccountWithFederatedIdentity", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "doCreateFirstAccount", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "getAllUsers", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "getAllowsSignup", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "isEnableCaptcha", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "isMailerPluginPresent", "()", "summary", "df-generated"] + - ["hudson.security", "HudsonPrivateSecurityRealm", "load", "(String)", "summary", "df-generated"] + - ["hudson.security", "Messages", "AccessDeniedException2_MissingPermission", "(Object,Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "AccessDeniedException_MissingPermissions", "(Object,Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "AuthorizationStrategy_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "FullControlOnceLoggedInAuthorizationStrategy_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "GlobalSecurityConfiguration_Description", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "GlobalSecurityConfiguration_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_CreateAccount_InvalidEmailAddress", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_CreateAccount_PasswordNotMatch", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_CreateAccount_PasswordRequired", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_CreateAccount_TextNotMatchWordInImage", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_CreateAccount_UserNameAlreadyTaken", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_CreateAccount_UserNameInvalidCharacters", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_CreateAccount_UserNameInvalidCharactersCustom", "(Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_CreateAccount_UserNameRequired", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_Details_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_Details_PasswordError", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_ManageUserLinks_Description", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_ManageUserLinks_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_SignupWarning", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "HudsonPrivateSecurityRealm_WouldYouLikeToSignUp", "(Object,Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "LegacyAuthorizationStrategy_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "LegacySecurityRealm_Displayname", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "NoneSecurityRealm_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "Permission_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "UserDetailsServiceProxy_UnableToQuery", "(Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "_AccessDeniedException2_MissingPermission", "(Object,Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "_AccessDeniedException_MissingPermissions", "(Object,Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "_AuthorizationStrategy_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_FullControlOnceLoggedInAuthorizationStrategy_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_GlobalSecurityConfiguration_Description", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_GlobalSecurityConfiguration_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_CreateAccount_InvalidEmailAddress", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_CreateAccount_PasswordNotMatch", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_CreateAccount_PasswordRequired", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_CreateAccount_TextNotMatchWordInImage", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_CreateAccount_UserNameAlreadyTaken", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_CreateAccount_UserNameInvalidCharacters", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_CreateAccount_UserNameInvalidCharactersCustom", "(Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_CreateAccount_UserNameRequired", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_Details_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_Details_PasswordError", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_ManageUserLinks_Description", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_ManageUserLinks_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_SignupWarning", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_HudsonPrivateSecurityRealm_WouldYouLikeToSignUp", "(Object,Object)", "summary", "df-generated"] + - ["hudson.security", "Messages", "_LegacyAuthorizationStrategy_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_LegacySecurityRealm_Displayname", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_NoneSecurityRealm_DisplayName", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_Permission_Permissions_Title", "()", "summary", "df-generated"] + - ["hudson.security", "Messages", "_UserDetailsServiceProxy_UnableToQuery", "(Object)", "summary", "df-generated"] + - ["hudson.security", "Permission", "fromId", "(String)", "summary", "df-generated"] + - ["hudson.security", "Permission", "getAll", "()", "summary", "df-generated"] + - ["hudson.security", "Permission", "getEnabled", "()", "summary", "df-generated"] + - ["hudson.security", "Permission", "isContainedBy", "(PermissionScope)", "summary", "df-generated"] + - ["hudson.security", "Permission", "setEnabled", "(boolean)", "summary", "df-generated"] + - ["hudson.security", "PermissionAdder", "add", "(AuthorizationStrategy,User,Permission)", "summary", "df-generated"] + - ["hudson.security", "PermissionGroup", "get", "(Class)", "summary", "df-generated"] + - ["hudson.security", "PermissionGroup", "getAll", "()", "summary", "df-generated"] + - ["hudson.security", "PermissionGroup", "getOwnerClassName", "()", "summary", "df-generated"] + - ["hudson.security", "PermissionGroup", "hasPermissionContainedBy", "(PermissionScope)", "summary", "df-generated"] + - ["hudson.security", "PermissionGroup", "size", "()", "summary", "df-generated"] + - ["hudson.security", "PermissionGroup", "toString", "()", "summary", "df-generated"] + - ["hudson.security", "PermissionScope", "isContainedBy", "(PermissionScope)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm$SecurityComponents", "SecurityComponents", "(AuthenticationManager)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm$SecurityComponents", "SecurityComponents", "(AuthenticationManager,UserDetailsService)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "all", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "allowsSignup", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "canLogOut", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "commenceSignup", "(FederatedIdentity)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "createCliAuthenticator", "(CLICommand)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "createFilter", "(FilterConfig)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "createSecurityComponents", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "doCaptcha", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "doLogout", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "getAuthenticationGatewayUrl", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "getCaptchaSupportDescriptors", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "getFrom", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "getGroupIdStrategy", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "getLoginUrl", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "getUserIdStrategy", "()", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "loadGroupByGroupname2", "(String,boolean)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "loadGroupByGroupname", "(String)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "loadGroupByGroupname", "(String,boolean)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "loadUserByUsername2", "(String)", "summary", "df-generated"] + - ["hudson.security", "SecurityRealm", "loadUserByUsername", "(String)", "summary", "df-generated"] + - ["hudson.security", "SidACL", "newInheritingACL", "(SidACL)", "summary", "df-generated"] + - ["hudson.security", "SparseACL", "add", "(Sid,Permission,boolean)", "summary", "df-generated"] + - ["hudson.security", "TokenBasedRememberMeServices2", "TokenBasedRememberMeServices2", "(UserDetailsService)", "summary", "df-generated"] + - ["hudson.security", "UserMayOrMayNotExistException2", "UserMayOrMayNotExistException2", "(String)", "summary", "df-generated"] + - ["hudson.security", "UserMayOrMayNotExistException2", "UserMayOrMayNotExistException2", "(String,Throwable)", "summary", "df-generated"] + - ["hudson.security", "UserMayOrMayNotExistException", "UserMayOrMayNotExistException", "(String)", "summary", "df-generated"] + - ["hudson.security", "UserMayOrMayNotExistException", "UserMayOrMayNotExistException", "(String,Throwable)", "summary", "df-generated"] + - ["hudson.security", "UserMayOrMayNotExistException", "fromSpring", "(UserMayOrMayNotExistException2)", "summary", "df-generated"] + - ["hudson.security", "WhoAmI", "getAuthorities", "()", "summary", "df-generated"] + - ["hudson.security", "WhoAmI", "getDetails", "()", "summary", "df-generated"] + - ["hudson.security", "WhoAmI", "getName", "()", "summary", "df-generated"] + - ["hudson.security", "WhoAmI", "getToString", "()", "summary", "df-generated"] + - ["hudson.security", "WhoAmI", "isAnonymous", "()", "summary", "df-generated"] + - ["hudson.security", "WhoAmI", "isAuthenticated", "()", "summary", "df-generated"] + - ["hudson.security", "WhoAmI", "isHeaderDangerous", "(String)", "summary", "df-generated"] + - ["hudson.slaves", "AbstractCloudImpl", "getInstanceCap", "()", "summary", "df-generated"] + - ["hudson.slaves", "AbstractCloudImpl", "getInstanceCapStr", "()", "summary", "df-generated"] + - ["hudson.slaves", "AbstractCloudSlave", "terminate", "()", "summary", "df-generated"] + - ["hudson.slaves", "ChannelPinger$SetUpRemotePing", "SetUpRemotePing", "(int,int)", "summary", "df-generated"] + - ["hudson.slaves", "ChannelPinger", "install", "(Channel)", "summary", "df-generated"] + - ["hudson.slaves", "ChannelPinger", "setUpPingForChannel", "(Channel,SlaveComputer,int,int,boolean)", "summary", "df-generated"] + - ["hudson.slaves", "Channels", "forProcess", "(String,ExecutorService,InputStream,OutputStream,OutputStream,Proc)", "summary", "df-generated"] + - ["hudson.slaves", "Channels", "forProcess", "(String,ExecutorService,InputStream,OutputStream,Proc)", "summary", "df-generated"] + - ["hudson.slaves", "Channels", "forProcess", "(String,ExecutorService,Process,OutputStream)", "summary", "df-generated"] + - ["hudson.slaves", "Channels", "newJVM", "(String,TaskListener,FilePath,ClasspathBuilder,Map)", "summary", "df-generated"] + - ["hudson.slaves", "Channels", "newJVM", "(String,TaskListener,JVMBuilder,FilePath,ClasspathBuilder)", "summary", "df-generated"] + - ["hudson.slaves", "Cloud$CloudState", "getAdditionalPlannedCapacity", "()", "summary", "df-generated"] + - ["hudson.slaves", "Cloud", "all", "()", "summary", "df-generated"] + - ["hudson.slaves", "Cloud", "canProvision", "(CloudState)", "summary", "df-generated"] + - ["hudson.slaves", "Cloud", "canProvision", "(Label)", "summary", "df-generated"] + - ["hudson.slaves", "Cloud", "provision", "(CloudState,int)", "summary", "df-generated"] + - ["hudson.slaves", "Cloud", "provision", "(Label,int)", "summary", "df-generated"] + - ["hudson.slaves", "Cloud", "registerPermissions", "()", "summary", "df-generated"] + - ["hudson.slaves", "CloudProvisioningListener", "all", "()", "summary", "df-generated"] + - ["hudson.slaves", "CloudProvisioningListener", "canProvision", "(Cloud,CloudState,int)", "summary", "df-generated"] + - ["hudson.slaves", "CloudProvisioningListener", "canProvision", "(Cloud,Label,int)", "summary", "df-generated"] + - ["hudson.slaves", "CloudProvisioningListener", "onCommit", "(PlannedNode,Node)", "summary", "df-generated"] + - ["hudson.slaves", "CloudProvisioningListener", "onComplete", "(PlannedNode,Node)", "summary", "df-generated"] + - ["hudson.slaves", "CloudProvisioningListener", "onFailure", "(PlannedNode,Throwable)", "summary", "df-generated"] + - ["hudson.slaves", "CloudProvisioningListener", "onRollback", "(PlannedNode,Node,Throwable)", "summary", "df-generated"] + - ["hudson.slaves", "CloudProvisioningListener", "onStarted", "(Cloud,Label,Collection)", "summary", "df-generated"] + - ["hudson.slaves", "CloudRetentionStrategy", "CloudRetentionStrategy", "(int)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerConnector", "launch", "(String,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerConnectorDescriptor", "all", "()", "summary", "df-generated"] + - ["hudson.slaves", "ComputerLauncher", "afterDisconnect", "(SlaveComputer,StreamTaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerLauncher", "afterDisconnect", "(SlaveComputer,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerLauncher", "beforeDisconnect", "(SlaveComputer,StreamTaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerLauncher", "beforeDisconnect", "(SlaveComputer,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerLauncher", "isLaunchSupported", "()", "summary", "df-generated"] + - ["hudson.slaves", "ComputerLauncher", "launch", "(SlaveComputer,StreamTaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerLauncher", "launch", "(SlaveComputer,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "all", "()", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "onConfigurationChange", "()", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "onLaunchFailure", "(Computer,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "onOffline", "(Computer)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "onOffline", "(Computer,OfflineCause)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "onOnline", "(Computer)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "onOnline", "(Computer,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "onTemporarilyOffline", "(Computer,OfflineCause)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "onTemporarilyOnline", "(Computer)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "preLaunch", "(Computer,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "preOnline", "(Computer,Channel,FilePath,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "register", "()", "summary", "df-generated"] + - ["hudson.slaves", "ComputerListener", "unregister", "()", "summary", "df-generated"] + - ["hudson.slaves", "DelegatingComputerLauncher$DescriptorImpl", "applicableDescriptors", "(Slave,SlaveDescriptor)", "summary", "df-generated"] + - ["hudson.slaves", "DelegatingComputerLauncher$DescriptorImpl", "getApplicableDescriptors", "()", "summary", "df-generated"] + - ["hudson.slaves", "EnvironmentVariablesNodeProperty$DescriptorImpl", "getHelpPage", "()", "summary", "df-generated"] + - ["hudson.slaves", "JNLPLauncher$DescriptorImpl", "doCheckWebSocket", "(boolean,String)", "summary", "df-generated"] + - ["hudson.slaves", "JNLPLauncher$DescriptorImpl", "isWorkDirSupported", "()", "summary", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", "JNLPLauncher", "(boolean)", "summary", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", "getInboundAgentUrl", "()", "summary", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", "isWebSocket", "()", "summary", "df-generated"] + - ["hudson.slaves", "JNLPLauncher", "setWebSocket", "(boolean)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "Cloud_ProvisionPermission_Description", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "ComputerLauncher_JavaVersionResult", "(Object,Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "ComputerLauncher_NoJavaFound", "(Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "ComputerLauncher_UnknownJavaVersion", "(Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "ComputerLauncher_abortedLaunch", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "ComputerLauncher_unexpectedError", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "ConnectionActivityMonitor_OfflineCause", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "DumbSlave_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "EnvironmentVariablesNodeProperty_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "JNLPLauncher_InstanceIdentityRequired", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "JNLPLauncher_TCPPortDisabled", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "JNLPLauncher_TunnelingNotSupported", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "JNLPLauncher_WebsocketNotEnabled", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "JNLPLauncher_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "NodeDescriptor_CheckName_Mandatory", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "NodeProvisioner_EmptyString", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "OfflineCause_LaunchFailed", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "OfflineCause_connection_was_broken_", "(Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "RetentionStrategy_Always_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "RetentionStrategy_Demand_OfflineIdle", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "RetentionStrategy_Demand_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "SimpleScheduledRetentionStrategy_FinishedUpTime", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "SimpleScheduledRetentionStrategy_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "SlaveComputer_DisconnectedBy", "(Object,Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_Cloud_ProvisionPermission_Description", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_ComputerLauncher_JavaVersionResult", "(Object,Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_ComputerLauncher_NoJavaFound", "(Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_ComputerLauncher_UnknownJavaVersion", "(Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_ComputerLauncher_abortedLaunch", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_ComputerLauncher_unexpectedError", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_ConnectionActivityMonitor_OfflineCause", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_DumbSlave_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_EnvironmentVariablesNodeProperty_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_JNLPLauncher_InstanceIdentityRequired", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_JNLPLauncher_TCPPortDisabled", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_JNLPLauncher_TunnelingNotSupported", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_JNLPLauncher_WebsocketNotEnabled", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_JNLPLauncher_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_NodeDescriptor_CheckName_Mandatory", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_NodeProvisioner_EmptyString", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_OfflineCause_LaunchFailed", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_OfflineCause_connection_was_broken_", "(Object)", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_RetentionStrategy_Always_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_RetentionStrategy_Demand_OfflineIdle", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_RetentionStrategy_Demand_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_SimpleScheduledRetentionStrategy_FinishedUpTime", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_SimpleScheduledRetentionStrategy_displayName", "()", "summary", "df-generated"] + - ["hudson.slaves", "Messages", "_SlaveComputer_DisconnectedBy", "(Object,Object)", "summary", "df-generated"] + - ["hudson.slaves", "NodeDescriptor", "all", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeDescriptor", "allInstantiable", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeDescriptor", "doCheckName", "(String)", "summary", "df-generated"] + - ["hudson.slaves", "NodeDescriptor", "handleNewNodePage", "(ComputerSet,String,StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.slaves", "NodeDescriptor", "isInstantiable", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeDescriptor", "newInstanceDetailPage", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeList$ConverterImpl", "ConverterImpl", "(XStream)", "summary", "df-generated"] + - ["hudson.slaves", "NodeProperty", "all", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProperty", "buildEnvVars", "(EnvVars,TaskListener)", "summary", "df-generated"] + - ["hudson.slaves", "NodeProperty", "canTake", "(BuildableItem)", "summary", "df-generated"] + - ["hudson.slaves", "NodeProperty", "canTake", "(Task)", "summary", "df-generated"] + - ["hudson.slaves", "NodeProperty", "for_", "(Node)", "summary", "df-generated"] + - ["hudson.slaves", "NodeProperty", "setUp", "(AbstractBuild,Launcher,BuildListener)", "summary", "df-generated"] + - ["hudson.slaves", "NodePropertyDescriptor", "isApplicableAsGlobal", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$PlannedNode", "spent", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$Strategy", "apply", "(StrategyState)", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getAdditionalPlannedCapacity", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getAvailableExecutorsLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getBusyExecutorsLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getConnectingExecutorsLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getDefinedExecutorsLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getIdleExecutorsLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getIdleLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getIdleSnapshot", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getOnlineExecutorsLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getPlannedCapacityLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getPlannedCapacitySnapshot", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getQueueLengthLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getQueueLengthSnapshot", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getTotalLatest", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "getTotalSnapshot", "()", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "recordPendingLaunches", "(Collection)", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner$StrategyState", "recordPendingLaunches", "(PlannedNode[])", "summary", "df-generated"] + - ["hudson.slaves", "NodeProvisioner", "suggestReviewNow", "()", "summary", "df-generated"] + - ["hudson.slaves", "OfflineCause$ChannelTermination", "getShortDescription", "()", "summary", "df-generated"] + - ["hudson.slaves", "OfflineCause$ChannelTermination", "toString", "()", "summary", "df-generated"] + - ["hudson.slaves", "OfflineCause$LaunchFailed", "toString", "()", "summary", "df-generated"] + - ["hudson.slaves", "OfflineCause", "getTime", "()", "summary", "df-generated"] + - ["hudson.slaves", "OfflineCause", "getTimestamp", "()", "summary", "df-generated"] + - ["hudson.slaves", "RetentionStrategy$Demand", "Demand", "(long,long)", "summary", "df-generated"] + - ["hudson.slaves", "RetentionStrategy$Demand", "getIdleDelay", "()", "summary", "df-generated"] + - ["hudson.slaves", "RetentionStrategy$Demand", "getInDemandDelay", "()", "summary", "df-generated"] + - ["hudson.slaves", "RetentionStrategy", "all", "()", "summary", "df-generated"] + - ["hudson.slaves", "RetentionStrategy", "check", "(Computer)", "summary", "df-generated"] + - ["hudson.slaves", "RetentionStrategy", "isAcceptingTasks", "(Computer)", "summary", "df-generated"] + - ["hudson.slaves", "RetentionStrategy", "isManualLaunchAllowed", "(Computer)", "summary", "df-generated"] + - ["hudson.slaves", "RetentionStrategy", "start", "(Computer)", "summary", "df-generated"] + - ["hudson.slaves", "SimpleScheduledRetentionStrategy$DescriptorImpl", "doCheck", "(String)", "summary", "df-generated"] + - ["hudson.slaves", "SimpleScheduledRetentionStrategy", "getUpTimeMins", "()", "summary", "df-generated"] + - ["hudson.slaves", "SimpleScheduledRetentionStrategy", "isKeepUpWhenActive", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "doDoDisconnect", "(String)", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "doSubmitDescription", "(StaplerResponse,String)", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getChannelToMaster", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getClassLoadingCount", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getClassLoadingPrefetchCacheCount", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getClassLoadingTime", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getEnvVarsFull", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getJnlpMac", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getOSDescription", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getResourceLoadingCount", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getResourceLoadingTime", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getSlaveVersion", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "getSystemInfoExtensions", "()", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "setAcceptingTasks", "(boolean)", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "setChannel", "(ChannelBuilder,CommandTransport,Listener)", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "setChannel", "(InputStream,OutputStream,OutputStream,Listener)", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "setChannel", "(InputStream,OutputStream,TaskListener,Listener)", "summary", "df-generated"] + - ["hudson.slaves", "SlaveComputer", "tryReconnect", "()", "summary", "df-generated"] + - ["hudson.slaves", "WorkspaceList$Lease", "release", "()", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver$DescriptorImpl", "doCheckArtifacts", "(AbstractProject,String,String)", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "getAllowEmptyArchive", "()", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "isCaseSensitive", "()", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "isDefaultExcludes", "()", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "isFingerprint", "()", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "isFollowSymlinks", "()", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "isLatestOnly", "()", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "isOnlyIfSuccessful", "()", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "setAllowEmptyArchive", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "setCaseSensitive", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "setDefaultExcludes", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "setFingerprint", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "setFollowSymlinks", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "ArtifactArchiver", "setOnlyIfSuccessful", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "BatchFile$DescriptorImpl", "doCheckUnstableReturn", "(String)", "summary", "df-generated"] + - ["hudson.tasks", "BatchFile$DescriptorImpl", "getApplicableLocalRules", "()", "summary", "df-generated"] + - ["hudson.tasks", "BatchFile", "getUnstableReturn", "()", "summary", "df-generated"] + - ["hudson.tasks", "BatchFile", "setUnstableReturn", "(Integer)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStep", "getProjectAction", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStep", "getProjectActions", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStep", "getRequiredMonitorService", "()", "summary", "df-generated"] + - ["hudson.tasks", "BuildStep", "perform", "(AbstractBuild,Launcher,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStep", "prebuild", "(AbstractBuild,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStepCompatibilityLayer", "getProjectAction", "(Project)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStepCompatibilityLayer", "perform", "(Build,Launcher,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStepCompatibilityLayer", "prebuild", "(Build,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStepDescriptor", "isApplicable", "(Class)", "summary", "df-generated"] + - ["hudson.tasks", "BuildStepMonitor", "perform", "(BuildStep,AbstractBuild,Launcher,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger$DescriptorImpl", "doAutoCompleteChildProjects", "(String,Item,ItemGroup)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger$DescriptorImpl", "doCheck", "(AbstractProject,String)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger$DescriptorImpl", "showEvenIfUnstableOption", "(Class)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger", "execute", "(AbstractBuild,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger", "execute", "(AbstractBuild,BuildListener,BuildTrigger)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger", "getChildJobs", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger", "getChildProjects", "()", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger", "getChildProjects", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger", "getChildProjects", "(ItemGroup)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger", "hasSame", "(AbstractProject,Collection)", "summary", "df-generated"] + - ["hudson.tasks", "BuildTrigger", "hasSame", "(Collection)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapper$Environment", "tearDown", "(Build,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapper", "all", "()", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapper", "getProjectAction", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapper", "getProjectActions", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapper", "makeBuildVariables", "(AbstractBuild,Map)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapper", "makeSensitiveBuildVariables", "(AbstractBuild,Set)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapper", "preCheckout", "(AbstractBuild,Launcher,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapper", "setUp", "(AbstractBuild,Launcher,BuildListener)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrapperDescriptor", "isApplicable", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.tasks", "BuildWrappers", "getFor", "(AbstractProject)", "summary", "df-generated"] + - ["hudson.tasks", "Builder", "all", "()", "summary", "df-generated"] + - ["hudson.tasks", "CommandInterpreter", "buildCommandLine", "(FilePath)", "summary", "df-generated"] + - ["hudson.tasks", "CommandInterpreter", "perform", "(AbstractBuild,Launcher,TaskListener)", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter$DescriptorImpl", "doCheck", "(AbstractProject,String)", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter$DescriptorImpl", "doCheckTargets", "(AbstractProject,String)", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", "add", "(Map)", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", "getDependencies", "()", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter$FingerprintAction", "getDependencies", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter", "getCaseSensitive", "()", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter", "getDefaultExcludes", "()", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter", "getRecordBuildArtifacts", "()", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter", "setCaseSensitive", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "Fingerprinter", "setDefaultExcludes", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "LogRotator", "(String,String,String,String)", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "LogRotator", "(int,int)", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "LogRotator", "(int,int,int,int)", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "getArtifactDaysToKeep", "()", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "getArtifactDaysToKeepStr", "()", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "getArtifactNumToKeep", "()", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "getArtifactNumToKeepStr", "()", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "getDaysToKeep", "()", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "getDaysToKeepStr", "()", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "getNumToKeep", "()", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "getNumToKeepStr", "()", "summary", "df-generated"] + - ["hudson.tasks", "LogRotator", "parse", "(String)", "summary", "df-generated"] + - ["hudson.tasks", "Maven$DescriptorImpl", "getDefaultGlobalSettingsProvider", "()", "summary", "df-generated"] + - ["hudson.tasks", "Maven$DescriptorImpl", "getDefaultSettingsProvider", "()", "summary", "df-generated"] + - ["hudson.tasks", "Maven$DescriptorImpl", "setInstallations", "(MavenInstallation[])", "summary", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", "getExecutable", "(Launcher)", "summary", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", "getExists", "()", "summary", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", "isMaven2_1", "(Launcher)", "summary", "df-generated"] + - ["hudson.tasks", "Maven$MavenInstallation", "meetsMavenReqVersion", "(Launcher,int)", "summary", "df-generated"] + - ["hudson.tasks", "Maven$ProjectWithMaven", "inferMavenInstallation", "()", "summary", "df-generated"] + - ["hudson.tasks", "Maven", "getMaven", "()", "summary", "df-generated"] + - ["hudson.tasks", "Maven", "isInjectBuildVariables", "()", "summary", "df-generated"] + - ["hudson.tasks", "Maven", "setUsePrivateRepository", "(boolean)", "summary", "df-generated"] + - ["hudson.tasks", "Maven", "usesPrivateRepository", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Ant_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Ant_ExecFailed", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Ant_ExecutableNotFound", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Ant_GlobalConfigNeeded", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Ant_NotADirectory", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Ant_NotAntDirectory", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Ant_ProjectConfigNeeded", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "ArtifactArchiver_ARCHIVING_ARTIFACTS", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "ArtifactArchiver_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "ArtifactArchiver_NoIncludes", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "ArtifactArchiver_NoMatchFound", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "ArtifactArchiver_SkipBecauseOnlyIfSuccessful", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BatchFile_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BatchFile_invalid_exit_code_range", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BatchFile_invalid_exit_code_zero", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_Disabled", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_InQueue", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_NoProjectSpecified", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_NoSuchProject", "(Object,Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_NotBuildable", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_Triggering", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_ok_ancestor_is_null", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "BuildTrigger_you_have_no_permission_to_build_", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "CommandInterpreter_CommandFailed", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "CommandInterpreter_UnableToDelete", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "CommandInterpreter_UnableToProduceScript", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Fingerprinter_Aborted", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Fingerprinter_Action_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Fingerprinter_DigestFailed", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Fingerprinter_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Fingerprinter_Failed", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Fingerprinter_FailedFor", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Fingerprinter_Recording", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "InstallFromApache", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "JavadocArchiver_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "JavadocArchiver_DisplayName_Generic", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "JavadocArchiver_DisplayName_Javadoc", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "JavadocArchiver_NoMatchFound", "(Object,Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "JavadocArchiver_Publishing", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "JavadocArchiver_UnableToCopy", "(Object,Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Maven_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Maven_ExecFailed", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Maven_NoExecutable", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Maven_NotMavenDirectory", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Shell_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Shell_invalid_exit_code_range", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "Shell_invalid_exit_code_zero", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "TestJavadocArchiver_DisplayName_Javadoc", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Ant_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Ant_ExecFailed", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Ant_ExecutableNotFound", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Ant_GlobalConfigNeeded", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Ant_NotADirectory", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Ant_NotAntDirectory", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Ant_ProjectConfigNeeded", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_ArtifactArchiver_ARCHIVING_ARTIFACTS", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_ArtifactArchiver_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_ArtifactArchiver_NoIncludes", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_ArtifactArchiver_NoMatchFound", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_ArtifactArchiver_SkipBecauseOnlyIfSuccessful", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BatchFile_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BatchFile_invalid_exit_code_range", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BatchFile_invalid_exit_code_zero", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_Disabled", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_InQueue", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_NoProjectSpecified", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_NoSuchProject", "(Object,Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_NotBuildable", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_Triggering", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_ok_ancestor_is_null", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_BuildTrigger_you_have_no_permission_to_build_", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_CommandInterpreter_CommandFailed", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_CommandInterpreter_UnableToDelete", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_CommandInterpreter_UnableToProduceScript", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Fingerprinter_Aborted", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Fingerprinter_Action_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Fingerprinter_DigestFailed", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Fingerprinter_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Fingerprinter_Failed", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Fingerprinter_FailedFor", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Fingerprinter_Recording", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_InstallFromApache", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_JavadocArchiver_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_JavadocArchiver_DisplayName_Generic", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_JavadocArchiver_DisplayName_Javadoc", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_JavadocArchiver_NoMatchFound", "(Object,Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_JavadocArchiver_Publishing", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_JavadocArchiver_UnableToCopy", "(Object,Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Maven_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Maven_ExecFailed", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Maven_NoExecutable", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Maven_NotMavenDirectory", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Shell_DisplayName", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Shell_invalid_exit_code_range", "(Object)", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_Shell_invalid_exit_code_zero", "()", "summary", "df-generated"] + - ["hudson.tasks", "Messages", "_TestJavadocArchiver_DisplayName_Javadoc", "()", "summary", "df-generated"] + - ["hudson.tasks", "Publisher", "all", "()", "summary", "df-generated"] + - ["hudson.tasks", "Publisher", "needsToRunAfterFinalized", "()", "summary", "df-generated"] + - ["hudson.tasks", "Shell$DescriptorImpl", "doCheckShell", "(String)", "summary", "df-generated"] + - ["hudson.tasks", "Shell$DescriptorImpl", "doCheckUnstableReturn", "(String)", "summary", "df-generated"] + - ["hudson.tasks", "Shell$DescriptorImpl", "getApplicableLocalRules", "()", "summary", "df-generated"] + - ["hudson.tasks", "Shell", "getUnstableReturn", "()", "summary", "df-generated"] + - ["hudson.tasks", "Shell", "setUnstableReturn", "(Integer)", "summary", "df-generated"] + - ["hudson.tasks", "UserAvatarResolver", "all", "()", "summary", "df-generated"] + - ["hudson.tasks", "UserAvatarResolver", "findAvatarFor", "(User,int,int)", "summary", "df-generated"] + - ["hudson.tasks", "UserAvatarResolver", "resolve", "(User,String)", "summary", "df-generated"] + - ["hudson.tasks", "UserAvatarResolver", "resolveOrNull", "(User,String)", "summary", "df-generated"] + - ["hudson.tasks", "UserNameResolver", "all", "()", "summary", "df-generated"] + - ["hudson.tasks", "UserNameResolver", "findNameFor", "(User)", "summary", "df-generated"] + - ["hudson.tasks", "UserNameResolver", "resolve", "(User)", "summary", "df-generated"] + - ["hudson.tools", "AbstractCommandInstaller$Descriptor", "doCheckCommand", "(String)", "summary", "df-generated"] + - ["hudson.tools", "AbstractCommandInstaller$Descriptor", "doCheckToolHome", "(String)", "summary", "df-generated"] + - ["hudson.tools", "AbstractCommandInstaller", "getCommandCall", "(FilePath)", "summary", "df-generated"] + - ["hudson.tools", "AbstractCommandInstaller", "getCommandFileExtension", "()", "summary", "df-generated"] + - ["hudson.tools", "DownloadFromUrlInstaller$DescriptorImpl", "createDownloadable", "()", "summary", "df-generated"] + - ["hudson.tools", "DownloadFromUrlInstaller$DescriptorImpl", "getInstallables", "()", "summary", "df-generated"] + - ["hudson.tools", "DownloadFromUrlInstaller", "getInstallable", "()", "summary", "df-generated"] + - ["hudson.tools", "InstallSourceProperty", "InstallSourceProperty", "(List)", "summary", "df-generated"] + - ["hudson.tools", "Messages", "BatchCommandInstaller_DescriptorImpl_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "CannotBeInstalled", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.tools", "Messages", "CommandInstaller_DescriptorImpl_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "CommandInstaller_no_command", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "CommandInstaller_no_toolHome", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "InstallSourceProperty_DescriptorImpl_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "ToolDescriptor_NotADirectory", "(Object)", "summary", "df-generated"] + - ["hudson.tools", "Messages", "ToolLocationNodeProperty_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "ZipExtractionInstaller_DescriptorImpl_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "ZipExtractionInstaller_bad_connection", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "ZipExtractionInstaller_could_not_connect", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "ZipExtractionInstaller_malformed_url", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_BatchCommandInstaller_DescriptorImpl_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_CannotBeInstalled", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_CommandInstaller_DescriptorImpl_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_CommandInstaller_no_command", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_CommandInstaller_no_toolHome", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_InstallSourceProperty_DescriptorImpl_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_ToolDescriptor_NotADirectory", "(Object)", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_ToolLocationNodeProperty_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_ZipExtractionInstaller_DescriptorImpl_displayName", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_ZipExtractionInstaller_bad_connection", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_ZipExtractionInstaller_could_not_connect", "()", "summary", "df-generated"] + - ["hudson.tools", "Messages", "_ZipExtractionInstaller_malformed_url", "()", "summary", "df-generated"] + - ["hudson.tools", "PropertyDescriptor", "isApplicable", "(Class)", "summary", "df-generated"] + - ["hudson.tools", "ToolDescriptor", "doCheckHome", "(File)", "summary", "df-generated"] + - ["hudson.tools", "ToolDescriptor", "doCheckName", "(String)", "summary", "df-generated"] + - ["hudson.tools", "ToolDescriptor", "getDefaultInstallers", "()", "summary", "df-generated"] + - ["hudson.tools", "ToolDescriptor", "getDefaultProperties", "()", "summary", "df-generated"] + - ["hudson.tools", "ToolDescriptor", "getPropertyDescriptors", "()", "summary", "df-generated"] + - ["hudson.tools", "ToolInstallation", "all", "()", "summary", "df-generated"] + - ["hudson.tools", "ToolInstallation", "buildEnvVars", "(EnvVars)", "summary", "df-generated"] + - ["hudson.tools", "ToolInstaller", "appliesTo", "(Node)", "summary", "df-generated"] + - ["hudson.tools", "ToolInstaller", "performInstallation", "(ToolInstallation,Node,TaskListener)", "summary", "df-generated"] + - ["hudson.tools", "ToolInstallerDescriptor", "all", "()", "summary", "df-generated"] + - ["hudson.tools", "ToolInstallerDescriptor", "doAutoCompleteLabel", "(String)", "summary", "df-generated"] + - ["hudson.tools", "ToolInstallerDescriptor", "doCheckLabel", "(String)", "summary", "df-generated"] + - ["hudson.tools", "ToolInstallerDescriptor", "for_", "(Class)", "summary", "df-generated"] + - ["hudson.tools", "ToolInstallerDescriptor", "isApplicable", "(Class)", "summary", "df-generated"] + - ["hudson.tools", "ToolLocationNodeProperty$DescriptorImpl", "getToolDescriptors", "()", "summary", "df-generated"] + - ["hudson.tools", "ToolLocationTranslator", "all", "()", "summary", "df-generated"] + - ["hudson.tools", "ToolLocationTranslator", "getToolHome", "(Node,ToolInstallation,TaskListener)", "summary", "df-generated"] + - ["hudson.tools", "ToolProperty", "all", "()", "summary", "df-generated"] + - ["hudson.tools", "ToolProperty", "type", "()", "summary", "df-generated"] + - ["hudson.tools", "ZipExtractionInstaller$DescriptorImpl", "doCheckUrl", "(String)", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "SCMTrigger_AdministrativeMonitorImpl_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "SCMTrigger_BuildAction_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "SCMTrigger_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "SCMTrigger_SCMTriggerCause_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "SCMTrigger_getDisplayName", "(Object)", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "SCMTrigger_no_schedules_hooks", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "SCMTrigger_no_schedules_no_hooks", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "SlowTriggerAdminMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "TimerTrigger_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "TimerTrigger_MissingWhitespace", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "TimerTrigger_TimerTriggerCause_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "TimerTrigger_no_schedules_so_will_never_run", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "TimerTrigger_the_specified_cron_tab_is_rare_or_impossible", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "TimerTrigger_would_last_have_run_at_would_next_run_at", "(Object,Object)", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "Trigger_init", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_SCMTrigger_AdministrativeMonitorImpl_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_SCMTrigger_BuildAction_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_SCMTrigger_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_SCMTrigger_SCMTriggerCause_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_SCMTrigger_getDisplayName", "(Object)", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_SCMTrigger_no_schedules_hooks", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_SCMTrigger_no_schedules_no_hooks", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_SlowTriggerAdminMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_TimerTrigger_DisplayName", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_TimerTrigger_MissingWhitespace", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_TimerTrigger_TimerTriggerCause_ShortDescription", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_TimerTrigger_no_schedules_so_will_never_run", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_TimerTrigger_the_specified_cron_tab_is_rare_or_impossible", "()", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_TimerTrigger_would_last_have_run_at_would_next_run_at", "(Object,Object)", "summary", "df-generated"] + - ["hudson.triggers", "Messages", "_Trigger_init", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$BuildAction", "doPollingLog", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$BuildAction", "getPollingLogFile", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$BuildAction", "writePollingLogTo", "(long,XMLOutput)", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "clogCheck", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "doCheckPollingThreadCount", "(String)", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "doCheckScmpoll_spec", "(String,boolean,Item)", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "getItemsBeingPolled", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "getPollingThreadCount", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "getRunners", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "isClogged", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "isPollingThreadCountOptionVisible", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$DescriptorImpl", "setPollingThreadCount", "(int)", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$Runner", "getDuration", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$Runner", "getLogFile", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$Runner", "getStartTime", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$Runner", "getTarget", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$SCMAction", "getItem", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$SCMAction", "getLog", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$SCMAction", "getOwner", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$SCMAction", "writeLogTo", "(XMLOutput)", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger$SCMTriggerCause", "SCMTriggerCause", "(File)", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger", "isIgnorePostCommitHooks", "()", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger", "run", "(Action[])", "summary", "df-generated"] + - ["hudson.triggers", "SCMTrigger", "setIgnorePostCommitHooks", "(boolean)", "summary", "df-generated"] + - ["hudson.triggers", "SafeTimerTask", "doRun", "()", "summary", "df-generated"] + - ["hudson.triggers", "SafeTimerTask", "getLogsRoot", "()", "summary", "df-generated"] + - ["hudson.triggers", "SafeTimerTask", "of", "(ExceptionRunnable)", "summary", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor$Value", "getDuration", "()", "summary", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor$Value", "getTimeString", "()", "summary", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor$Value", "getTrigger", "()", "summary", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor", "clear", "()", "summary", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor", "doClear", "()", "summary", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor", "getInstance", "()", "summary", "df-generated"] + - ["hudson.triggers", "SlowTriggerAdminMonitor", "report", "(Class,String,long)", "summary", "df-generated"] + - ["hudson.triggers", "TimerTrigger$DescriptorImpl", "doCheck", "(String,Item)", "summary", "df-generated"] + - ["hudson.triggers", "TimerTrigger$DescriptorImpl", "doCheckSpec", "(String,Item)", "summary", "df-generated"] + - ["hudson.triggers", "Trigger", "all", "()", "summary", "df-generated"] + - ["hudson.triggers", "Trigger", "checkTriggers", "(Calendar)", "summary", "df-generated"] + - ["hudson.triggers", "Trigger", "for_", "(Item)", "summary", "df-generated"] + - ["hudson.triggers", "Trigger", "getProjectAction", "()", "summary", "df-generated"] + - ["hudson.triggers", "Trigger", "getProjectActions", "()", "summary", "df-generated"] + - ["hudson.triggers", "Trigger", "run", "()", "summary", "df-generated"] + - ["hudson.triggers", "Trigger", "stop", "()", "summary", "df-generated"] + - ["hudson.triggers", "TriggerDescriptor", "isApplicable", "(Item)", "summary", "df-generated"] + - ["hudson.triggers", "Triggers", "getApplicableTriggers", "(Item)", "summary", "df-generated"] + - ["hudson.util.io", "Archiver", "countEntries", "()", "summary", "df-generated"] + - ["hudson.util.io", "ArchiverFactory", "create", "(OutputStream)", "summary", "df-generated"] + - ["hudson.util.io", "ParserConfigurator", "all", "()", "summary", "df-generated"] + - ["hudson.util.io", "ParserConfigurator", "applyConfiguration", "(SAXReader,Object)", "summary", "df-generated"] + - ["hudson.util.io", "ParserConfigurator", "configure", "(SAXReader,Object)", "summary", "df-generated"] + - ["hudson.util.io", "ReopenableFileOutputStream", "rewind", "()", "summary", "df-generated"] + - ["hudson.util.io", "ReopenableRotatingFileOutputStream", "deleteAll", "()", "summary", "df-generated"] + - ["hudson.util.io", "RewindableFileOutputStream", "rewind", "()", "summary", "df-generated"] + - ["hudson.util.io", "RewindableRotatingFileOutputStream", "deleteAll", "()", "summary", "df-generated"] + - ["hudson.util.jna", "DotNet", "isInstalled", "(int,int)", "summary", "df-generated"] + - ["hudson.util.jna", "DotNet", "isInstalled", "(int,int,String,IJIAuthInfo)", "summary", "df-generated"] + - ["hudson.util.jna", "InitializationErrorInvocationHandler", "create", "(Class,Throwable)", "summary", "df-generated"] + - ["hudson.util.jna", "JnaException", "JnaException", "(int)", "summary", "df-generated"] + - ["hudson.util.jna", "JnaException", "getErrorCode", "()", "summary", "df-generated"] + - ["hudson.util.jna", "Kernel32Utils", "createSymbolicLink", "(File,String,boolean)", "summary", "df-generated"] + - ["hudson.util.jna", "Kernel32Utils", "getTempDir", "()", "summary", "df-generated"] + - ["hudson.util.jna", "Kernel32Utils", "getWin32FileAttributes", "(File)", "summary", "df-generated"] + - ["hudson.util.jna", "Kernel32Utils", "isJunctionOrSymlink", "(File)", "summary", "df-generated"] + - ["hudson.util.jna", "Kernel32Utils", "waitForExitProcess", "(Pointer)", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "delete", "()", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "deleteValue", "(String)", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "dispose", "()", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "getIntValue", "(String)", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "getStringValue", "(String)", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "getSubKeys", "()", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "getValues", "()", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "setValue", "(String,String)", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "setValue", "(String,int)", "summary", "df-generated"] + - ["hudson.util.jna", "RegistryKey", "valueExists", "(String)", "summary", "df-generated"] + - ["hudson.util.jna", "WinIOException", "WinIOException", "(Throwable)", "summary", "df-generated"] + - ["hudson.util.jna", "WinIOException", "getErrorCode", "()", "summary", "df-generated"] + - ["hudson.util.xstream", "ImmutableListConverter", "ImmutableListConverter", "(Mapper,ReflectionProvider)", "summary", "df-generated"] + - ["hudson.util.xstream", "ImmutableListConverter", "ImmutableListConverter", "(XStream)", "summary", "df-generated"] + - ["hudson.util.xstream", "ImmutableMapConverter", "ImmutableMapConverter", "(Mapper,ReflectionProvider)", "summary", "df-generated"] + - ["hudson.util.xstream", "ImmutableMapConverter", "ImmutableMapConverter", "(XStream)", "summary", "df-generated"] + - ["hudson.util.xstream", "ImmutableSetConverter", "ImmutableSetConverter", "(Mapper,ReflectionProvider)", "summary", "df-generated"] + - ["hudson.util.xstream", "ImmutableSetConverter", "ImmutableSetConverter", "(XStream)", "summary", "df-generated"] + - ["hudson.util.xstream", "ImmutableSortedSetConverter", "ImmutableSortedSetConverter", "(Mapper,ReflectionProvider)", "summary", "df-generated"] + - ["hudson.util.xstream", "ImmutableSortedSetConverter", "ImmutableSortedSetConverter", "(XStream)", "summary", "df-generated"] + - ["hudson.util", "AlternativeUiTextProvider", "all", "()", "summary", "df-generated"] + - ["hudson.util", "AlternativeUiTextProvider", "get", "(Message,Object)", "summary", "df-generated"] + - ["hudson.util", "AlternativeUiTextProvider", "getText", "(Message,Object)", "summary", "df-generated"] + - ["hudson.util", "Area", "Area", "(int,int)", "summary", "df-generated"] + - ["hudson.util", "Area", "area", "()", "summary", "df-generated"] + - ["hudson.util", "Area", "parse", "(String)", "summary", "df-generated"] + - ["hudson.util", "Area", "toString", "()", "summary", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", "clear", "()", "summary", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", "hasMaskedArguments", "()", "summary", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", "toMaskArray", "()", "summary", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", "toWindowsCommand", "()", "summary", "df-generated"] + - ["hudson.util", "ArgumentListBuilder", "toWindowsCommand", "(boolean)", "summary", "df-generated"] + - ["hudson.util", "AtomicFileWriter", "abort", "()", "summary", "df-generated"] + - ["hudson.util", "AtomicFileWriter", "commit", "()", "summary", "df-generated"] + - ["hudson.util", "BootFailure", "publish", "(ServletContext,File)", "summary", "df-generated"] + - ["hudson.util", "ByteArrayOutputStream2", "ByteArrayOutputStream2", "(int)", "summary", "df-generated"] + - ["hudson.util", "ChartUtil", "adjustChebyshev", "(CategoryDataset,NumberAxis)", "summary", "df-generated"] + - ["hudson.util", "ChartUtil", "generateClickableMap", "(StaplerRequest,StaplerResponse,JFreeChart,Area)", "summary", "df-generated"] + - ["hudson.util", "ChartUtil", "generateClickableMap", "(StaplerRequest,StaplerResponse,JFreeChart,int,int)", "summary", "df-generated"] + - ["hudson.util", "ChartUtil", "generateGraph", "(StaplerRequest,StaplerResponse,JFreeChart,Area)", "summary", "df-generated"] + - ["hudson.util", "ChartUtil", "generateGraph", "(StaplerRequest,StaplerResponse,JFreeChart,int,int)", "summary", "df-generated"] + - ["hudson.util", "ChunkedOutputStream", "finish", "()", "summary", "df-generated"] + - ["hudson.util", "ClockDifference", "ClockDifference", "(long)", "summary", "df-generated"] + - ["hudson.util", "ClockDifference", "abs", "()", "summary", "df-generated"] + - ["hudson.util", "ClockDifference", "isDangerous", "()", "summary", "df-generated"] + - ["hudson.util", "ClockDifference", "toHtml", "()", "summary", "df-generated"] + - ["hudson.util", "ClockDifference", "toHtml", "(ClockDifference)", "summary", "df-generated"] + - ["hudson.util", "ClockDifference", "toHtml", "(Node)", "summary", "df-generated"] + - ["hudson.util", "ClockDifference", "toString", "()", "summary", "df-generated"] + - ["hudson.util", "ColorPalette", "apply", "(LineAndShapeRenderer)", "summary", "df-generated"] + - ["hudson.util", "ComboBoxModel", "ComboBoxModel", "(int)", "summary", "df-generated"] + - ["hudson.util", "CompressedFile", "compress", "()", "summary", "df-generated"] + - ["hudson.util", "CompressedFile", "loadAsString", "()", "summary", "df-generated"] + - ["hudson.util", "CompressedFile", "read", "()", "summary", "df-generated"] + - ["hudson.util", "CompressedFile", "write", "()", "summary", "df-generated"] + - ["hudson.util", "ConsistentHash", "ConsistentHash", "(int)", "summary", "df-generated"] + - ["hudson.util", "ConsistentHash", "countAllPoints", "()", "summary", "df-generated"] + - ["hudson.util", "ConsistentHash", "list", "(String)", "summary", "df-generated"] + - ["hudson.util", "ConsistentHash", "list", "(int)", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteList$ConverterImpl", "ConverterImpl", "(Mapper)", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteList", "clear", "()", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteList", "contains", "(Object)", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteList", "isEmpty", "()", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteList", "remove", "(Object)", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteList", "size", "()", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteList", "toString", "()", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteMap$Hash$ConverterImpl", "ConverterImpl", "(Mapper)", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteMap$Tree$ConverterImpl", "ConverterImpl", "(Mapper)", "summary", "df-generated"] + - ["hudson.util", "CopyOnWriteMap", "toString", "()", "summary", "df-generated"] + - ["hudson.util", "DataSetBuilder", "build", "()", "summary", "df-generated"] + - ["hudson.util", "DescribableList$ConverterImpl", "ConverterImpl", "(Mapper)", "summary", "df-generated"] + - ["hudson.util", "DescribableList", "buildDependencyGraph", "(AbstractProject,DependencyGraph)", "summary", "df-generated"] + - ["hudson.util", "DescribableList", "contains", "(Descriptor)", "summary", "df-generated"] + - ["hudson.util", "DescribableList", "rebuild", "(StaplerRequest,JSONObject,List)", "summary", "df-generated"] + - ["hudson.util", "DescribableList", "rebuild", "(StaplerRequest,JSONObject,List,String)", "summary", "df-generated"] + - ["hudson.util", "DescribableList", "rebuildHetero", "(StaplerRequest,JSONObject,Collection,String)", "summary", "df-generated"] + - ["hudson.util", "DescribableList", "remove", "(Descriptor)", "summary", "df-generated"] + - ["hudson.util", "DescribableList", "replace", "(Describable)", "summary", "df-generated"] + - ["hudson.util", "DescriptorList", "DescriptorList", "(Class)", "summary", "df-generated"] + - ["hudson.util", "DescriptorList", "DescriptorList", "(Descriptor[])", "summary", "df-generated"] + - ["hudson.util", "DescriptorList", "load", "(Class)", "summary", "df-generated"] + - ["hudson.util", "DescriptorList", "newInstanceFromRadioList", "(JSONObject)", "summary", "df-generated"] + - ["hudson.util", "DescriptorList", "newInstanceFromRadioList", "(JSONObject,String)", "summary", "df-generated"] + - ["hudson.util", "DirScanner", "scan", "(File,FileVisitor)", "summary", "df-generated"] + - ["hudson.util", "DoubleLaunchChecker", "doDynamic", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "DoubleLaunchChecker", "doIgnore", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "DoubleLaunchChecker", "getId", "()", "summary", "df-generated"] + - ["hudson.util", "DoubleLaunchChecker", "init", "()", "summary", "df-generated"] + - ["hudson.util", "DoubleLaunchChecker", "schedule", "()", "summary", "df-generated"] + - ["hudson.util", "EditDistance", "editDistance", "(String,String)", "summary", "df-generated"] + - ["hudson.util", "ErrorObject", "doDynamic", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "FileVisitor", "understandsSymlink", "()", "summary", "df-generated"] + - ["hudson.util", "FileVisitor", "visit", "(File,String)", "summary", "df-generated"] + - ["hudson.util", "FileVisitor", "visitSymlink", "(File,String,String)", "summary", "df-generated"] + - ["hudson.util", "FormApply", "applyResponse", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormApply", "isApply", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson.util", "FormApply", "success", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "error", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "error", "(String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "errorWithMarkup", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "ok", "()", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "ok", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "ok", "(String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "okWithMarkup", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "process", "()", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "respond", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "warning", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "warning", "(String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormFieldValidator", "warningWithMarkup", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "error", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "error", "(String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "error", "(Throwable,String)", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "error", "(Throwable,String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "getKind", "()", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "isSelectionCleared", "()", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "renderHtml", "()", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "respond", "(Kind,String)", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "warning", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "warning", "(String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "warning", "(Throwable,String)", "summary", "df-generated"] + - ["hudson.util", "FormFillFailure", "warning", "(Throwable,String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormValidation$FileValidator", "validate", "(File)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "error", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "error", "(String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "error", "(Throwable,String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "error", "(Throwable,String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "ok", "()", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "ok", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "ok", "(String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "renderHtml", "()", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "respond", "(Kind,String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "validateBase64", "(String,boolean,boolean,String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "validateExecutable", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "validateExecutable", "(String,FileValidator)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "validateIntegerInRange", "(String,int,int)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "validateNonNegativeInteger", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "validatePositiveInteger", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "validateRequired", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "warning", "(String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "warning", "(String,Object[])", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "warning", "(Throwable,String)", "summary", "df-generated"] + - ["hudson.util", "FormValidation", "warning", "(Throwable,String,Object[])", "summary", "df-generated"] + - ["hudson.util", "Futures", "precomputed", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Graph", "doMap", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "Graph", "doPng", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "Graph", "safeDimension", "(int,int,int,int)", "summary", "df-generated"] + - ["hudson.util", "HeadBufferingStream", "HeadBufferingStream", "(InputStream,int)", "summary", "df-generated"] + - ["hudson.util", "HeadBufferingStream", "fillSide", "()", "summary", "df-generated"] + - ["hudson.util", "HttpResponses", "okJSON", "()", "summary", "df-generated"] + - ["hudson.util", "HttpResponses", "okJSON", "(Map)", "summary", "df-generated"] + - ["hudson.util", "HttpResponses", "staticResource", "(File)", "summary", "df-generated"] + - ["hudson.util", "HudsonIsLoading", "doDynamic", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "HudsonIsRestarting", "doDynamic", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "IOException2", "IOException2", "(String,Throwable)", "summary", "df-generated"] + - ["hudson.util", "IOException2", "IOException2", "(Throwable)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "closeQuietly", "(InputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "closeQuietly", "(OutputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "closeQuietly", "(Reader)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "closeQuietly", "(Writer)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "contentEquals", "(InputStream,InputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "contentEquals", "(Reader,Reader)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "copy", "(File,OutputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "copy", "(InputStream,File)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "copy", "(Reader,OutputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "copy", "(Reader,OutputStream,String)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "drain", "(InputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "isAbsolute", "(String)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "mkdirs", "(File)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "mode", "(File)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "toByteArray", "(InputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "write", "(String,OutputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "write", "(String,OutputStream,String)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "write", "(StringBuffer,OutputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "write", "(StringBuffer,OutputStream,String)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "write", "(char[],OutputStream)", "summary", "df-generated"] + - ["hudson.util", "IOUtils", "write", "(char[],OutputStream,String)", "summary", "df-generated"] + - ["hudson.util", "IncompatibleAntVersionDetected", "IncompatibleAntVersionDetected", "(Class)", "summary", "df-generated"] + - ["hudson.util", "IncompatibleAntVersionDetected", "getWhereAntIsLoaded", "()", "summary", "df-generated"] + - ["hudson.util", "IncompatibleServletVersionDetected", "IncompatibleServletVersionDetected", "(Class)", "summary", "df-generated"] + - ["hudson.util", "IncompatibleServletVersionDetected", "getWhereServletIsLoaded", "()", "summary", "df-generated"] + - ["hudson.util", "IncompatibleVMDetected", "getSystemProperties", "()", "summary", "df-generated"] + - ["hudson.util", "InterceptingProxy", "wrap", "(Class,Object)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "empty", "()", "summary", "df-generated"] + - ["hudson.util", "Iterators", "limit", "(Iterator,CountingPredicate)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "readOnly", "(Iterator)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "removeDups", "(Iterable)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "reverse", "(List)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "reverseSequence", "(int,int)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "reverseSequence", "(int,int,int)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "sequence", "(Iterable[])", "summary", "df-generated"] + - ["hudson.util", "Iterators", "sequence", "(int,int)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "sequence", "(int,int,int)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "skip", "(Iterator,int)", "summary", "df-generated"] + - ["hudson.util", "Iterators", "wrap", "(Iterable)", "summary", "df-generated"] + - ["hudson.util", "KeyedDataStorage", "getPerformanceStats", "()", "summary", "df-generated"] + - ["hudson.util", "KeyedDataStorage", "resetPerformanceStats", "()", "summary", "df-generated"] + - ["hudson.util", "LRUStringConverter", "LRUStringConverter", "(int)", "summary", "df-generated"] + - ["hudson.util", "ListBoxModel", "ListBoxModel", "(int)", "summary", "df-generated"] + - ["hudson.util", "ListBoxModel", "writeTo", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "LogTaskListener", "LogTaskListener", "(Logger,Level)", "summary", "df-generated"] + - ["hudson.util", "Messages", "ClockDifference_Ahead", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "ClockDifference_Behind", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "ClockDifference_Failed", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "ClockDifference_InSync", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "FormFieldValidator_did_not_manage_to_validate_may_be_too_sl", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "FormValidation_Error_Details", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "FormValidation_ValidateRequired", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "HttpResponses_Saved", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_Attempt", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_AttemptFailed", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_CallingListener", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_ExceptionFailed", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_ExceptionThrown", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_Interruption", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_NoSuccess", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_Sleeping", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "Retrier_Success", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_ClockDifference_Ahead", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_ClockDifference_Behind", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_ClockDifference_Failed", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "_ClockDifference_InSync", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "_FormFieldValidator_did_not_manage_to_validate_may_be_too_sl", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_FormValidation_Error_Details", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "_FormValidation_ValidateRequired", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "_HttpResponses_Saved", "()", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_Attempt", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_AttemptFailed", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_CallingListener", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_ExceptionFailed", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_ExceptionThrown", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_Interruption", "(Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_NoSuccess", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_Sleeping", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "Messages", "_Retrier_Success", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "MultipartFormDataParser", "MultipartFormDataParser", "(HttpServletRequest)", "summary", "df-generated"] + - ["hudson.util", "MultipartFormDataParser", "cleanUp", "()", "summary", "df-generated"] + - ["hudson.util", "MultipartFormDataParser", "get", "(String)", "summary", "df-generated"] + - ["hudson.util", "MultipartFormDataParser", "isMultiPartForm", "(String)", "summary", "df-generated"] + - ["hudson.util", "NoOverlapCategoryAxis", "NoOverlapCategoryAxis", "(String)", "summary", "df-generated"] + - ["hudson.util", "NoTempDir", "getTempDir", "()", "summary", "df-generated"] + - ["hudson.util", "OneShotEvent", "block", "()", "summary", "df-generated"] + - ["hudson.util", "OneShotEvent", "block", "(long)", "summary", "df-generated"] + - ["hudson.util", "OneShotEvent", "isSignaled", "()", "summary", "df-generated"] + - ["hudson.util", "OneShotEvent", "signal", "()", "summary", "df-generated"] + - ["hudson.util", "PackedMap$ConverterImpl", "ConverterImpl", "(Mapper)", "summary", "df-generated"] + - ["hudson.util", "PersistedList$ConverterImpl", "ConverterImpl", "(Mapper)", "summary", "df-generated"] + - ["hudson.util", "PersistedList", "get", "(Class)", "summary", "df-generated"] + - ["hudson.util", "PersistedList", "getAll", "(Class)", "summary", "df-generated"] + - ["hudson.util", "PersistedList", "remove", "(Class)", "summary", "df-generated"] + - ["hudson.util", "PersistedList", "removeAll", "(Class)", "summary", "df-generated"] + - ["hudson.util", "PersistedList", "replace", "(Object,Object)", "summary", "df-generated"] + - ["hudson.util", "PersistedList", "replaceBy", "(Collection)", "summary", "df-generated"] + - ["hudson.util", "PersistedList", "toString", "()", "summary", "df-generated"] + - ["hudson.util", "PluginServletFilter", "addFilter", "(Filter)", "summary", "df-generated"] + - ["hudson.util", "PluginServletFilter", "cleanUp", "()", "summary", "df-generated"] + - ["hudson.util", "PluginServletFilter", "hasFilter", "(Filter)", "summary", "df-generated"] + - ["hudson.util", "PluginServletFilter", "removeFilter", "(Filter)", "summary", "df-generated"] + - ["hudson.util", "ProcessKiller", "all", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessKiller", "kill", "(OSProcess)", "summary", "df-generated"] + - ["hudson.util", "ProcessKillingVeto", "all", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessKillingVeto", "vetoProcessKilling", "(IOSProcess)", "summary", "df-generated"] + - ["hudson.util", "ProcessTree$OSProcess", "getChildren", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessTree$OSProcess", "hasMatchingEnvVars", "(Map)", "summary", "df-generated"] + - ["hudson.util", "ProcessTree$Remote", "Remote", "(ProcessTree,Channel)", "summary", "df-generated"] + - ["hudson.util", "ProcessTree$Remote", "Remote", "(ProcessTree,Channel,boolean)", "summary", "df-generated"] + - ["hudson.util", "ProcessTree", "get", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessTree", "get", "(Process)", "summary", "df-generated"] + - ["hudson.util", "ProcessTree", "killAll", "(Process,Map)", "summary", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", "act", "(ProcessCallable)", "summary", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", "getArguments", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", "getEnvironmentVariables", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", "getParent", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", "getPid", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", "kill", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IOSProcess", "killRecursively", "()", "summary", "df-generated"] + - ["hudson.util", "ProcessTreeRemoting$IProcessTree", "killAll", "(Map)", "summary", "df-generated"] + - ["hudson.util", "Protector", "protect", "(String)", "summary", "df-generated"] + - ["hudson.util", "Protector", "unprotect", "(String)", "summary", "df-generated"] + - ["hudson.util", "QueryParameterMap", "QueryParameterMap", "(HttpServletRequest)", "summary", "df-generated"] + - ["hudson.util", "QueryParameterMap", "QueryParameterMap", "(String)", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "convertHexDigit", "(byte)", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "getDouble", "()", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "getSingle", "()", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "quote", "(String)", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "quote", "(StringBuffer,String)", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "setDouble", "(boolean)", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "setSingle", "(boolean)", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "tokenize", "(String)", "summary", "df-generated"] + - ["hudson.util", "QuotedStringTokenizer", "tokenize", "(String,String)", "summary", "df-generated"] + - ["hudson.util", "ReflectionUtils$Parameter", "annotation", "(Class)", "summary", "df-generated"] + - ["hudson.util", "ReflectionUtils$Parameter", "index", "()", "summary", "df-generated"] + - ["hudson.util", "ReflectionUtils$Parameter", "type", "()", "summary", "df-generated"] + - ["hudson.util", "ReflectionUtils", "getPublicMethodNamed", "(Class,String)", "summary", "df-generated"] + - ["hudson.util", "ReflectionUtils", "getPublicProperty", "(Object,String)", "summary", "df-generated"] + - ["hudson.util", "ReflectionUtils", "getVmDefaultValueForPrimitiveType", "(Class)", "summary", "df-generated"] + - ["hudson.util", "RemotingDiagnostics$HeapDump", "doHeapDump", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "RemotingDiagnostics$HeapDump", "doIndex", "(StaplerResponse)", "summary", "df-generated"] + - ["hudson.util", "RemotingDiagnostics$HeapDump", "obtain", "()", "summary", "df-generated"] + - ["hudson.util", "RemotingDiagnostics", "executeGroovy", "(String,VirtualChannel)", "summary", "df-generated"] + - ["hudson.util", "RemotingDiagnostics", "getHeapDump", "(VirtualChannel)", "summary", "df-generated"] + - ["hudson.util", "RemotingDiagnostics", "getSystemProperties", "(VirtualChannel)", "summary", "df-generated"] + - ["hudson.util", "RemotingDiagnostics", "getThreadDump", "(VirtualChannel)", "summary", "df-generated"] + - ["hudson.util", "RemotingDiagnostics", "getThreadDumpAsync", "(VirtualChannel)", "summary", "df-generated"] + - ["hudson.util", "Retrier", "start", "()", "summary", "df-generated"] + - ["hudson.util", "RingBufferLogHandler", "RingBufferLogHandler", "(int)", "summary", "df-generated"] + - ["hudson.util", "RingBufferLogHandler", "clear", "()", "summary", "df-generated"] + - ["hudson.util", "RingBufferLogHandler", "getDefaultRingBufferSize", "()", "summary", "df-generated"] + - ["hudson.util", "RingBufferLogHandler", "getView", "()", "summary", "df-generated"] + - ["hudson.util", "RobustCollectionConverter", "RobustCollectionConverter", "(Mapper,ReflectionProvider)", "summary", "df-generated"] + - ["hudson.util", "RobustCollectionConverter", "RobustCollectionConverter", "(XStream)", "summary", "df-generated"] + - ["hudson.util", "RobustReflectionConverter$DuplicateFieldException", "DuplicateFieldException", "(String)", "summary", "df-generated"] + - ["hudson.util", "RobustReflectionConverter", "addErrorInContext", "(UnmarshallingContext,Throwable)", "summary", "df-generated"] + - ["hudson.util", "RunList", "RunList", "(Collection)", "summary", "df-generated"] + - ["hudson.util", "RunList", "RunList", "(View)", "summary", "df-generated"] + - ["hudson.util", "RunList", "fromJobs", "(Iterable)", "summary", "df-generated"] + - ["hudson.util", "Secret", "getCipher", "(String)", "summary", "df-generated"] + - ["hudson.util", "SecretRewriter", "SecretRewriter", "(File)", "summary", "df-generated"] + - ["hudson.util", "SecretRewriter", "rewrite", "(File)", "summary", "df-generated"] + - ["hudson.util", "SecretRewriter", "rewrite", "(File,File)", "summary", "df-generated"] + - ["hudson.util", "SequentialExecutionQueue", "isStarving", "(long)", "summary", "df-generated"] + - ["hudson.util", "Service", "load", "(Class,ClassLoader,Collection)", "summary", "df-generated"] + - ["hudson.util", "Service", "loadInstances", "(ClassLoader,Class)", "summary", "df-generated"] + - ["hudson.util", "ShiftedCategoryAxis", "ShiftedCategoryAxis", "(String)", "summary", "df-generated"] + - ["hudson.util", "StreamTaskListener", "StreamTaskListener", "(File)", "summary", "df-generated"] + - ["hudson.util", "StreamTaskListener", "StreamTaskListener", "(File,Charset)", "summary", "df-generated"] + - ["hudson.util", "StreamTaskListener", "StreamTaskListener", "(File,boolean,Charset)", "summary", "df-generated"] + - ["hudson.util", "StreamTaskListener", "StreamTaskListener", "(Writer)", "summary", "df-generated"] + - ["hudson.util", "StreamTaskListener", "closeQuietly", "()", "summary", "df-generated"] + - ["hudson.util", "StreamTaskListener", "fromStderr", "()", "summary", "df-generated"] + - ["hudson.util", "StreamTaskListener", "fromStdout", "()", "summary", "df-generated"] + - ["hudson.util", "TableNestChecker", "TableNestChecker", "(ContentHandler)", "summary", "df-generated"] + - ["hudson.util", "TableNestChecker", "applyTo", "(XMLOutput)", "summary", "df-generated"] + - ["hudson.util", "TagCloud$Entry", "getClassName", "()", "summary", "df-generated"] + - ["hudson.util", "TagCloud$Entry", "scale", "()", "summary", "df-generated"] + - ["hudson.util", "TagCloud", "TagCloud", "(Iterable,WeightFunction)", "summary", "df-generated"] + - ["hudson.util", "TextFile", "delete", "()", "summary", "df-generated"] + - ["hudson.util", "TextFile", "exists", "()", "summary", "df-generated"] + - ["hudson.util", "TextFile", "fastTail", "(int)", "summary", "df-generated"] + - ["hudson.util", "TextFile", "fastTail", "(int,Charset)", "summary", "df-generated"] + - ["hudson.util", "TextFile", "head", "(int)", "summary", "df-generated"] + - ["hudson.util", "TextFile", "lines", "()", "summary", "df-generated"] + - ["hudson.util", "TextFile", "read", "()", "summary", "df-generated"] + - ["hudson.util", "TextFile", "readTrim", "()", "summary", "df-generated"] + - ["hudson.util", "TextFile", "write", "(String)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "convert", "(long,TimeUnit)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "convert", "(long,TimeUnit2)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "sleep", "(long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "timedJoin", "(Thread,long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "timedWait", "(Object,long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "toDays", "(long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "toHours", "(long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "toMicros", "(long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "toMillis", "(long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "toMinutes", "(long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "toNanos", "(long)", "summary", "df-generated"] + - ["hudson.util", "TimeUnit2", "toSeconds", "(long)", "summary", "df-generated"] + - ["hudson.util", "XStream2", "XStream2", "(HierarchicalStreamDriver)", "summary", "df-generated"] + - ["hudson.util", "XStream2", "XStream2", "(ReflectionProvider,HierarchicalStreamDriver,ClassLoaderReference,Mapper,ConverterLookup,ConverterRegistry)", "summary", "df-generated"] + - ["hudson.util", "XStream2", "addCriticalField", "(Class,String)", "summary", "df-generated"] + - ["hudson.util", "XStream2", "getDefaultDriver", "()", "summary", "df-generated"] + - ["hudson.util", "XStream2", "toXMLUTF8", "(Object,OutputStream)", "summary", "df-generated"] + - ["hudson.util", "XStream2", "unmarshal", "(HierarchicalStreamReader,Object,DataHolder,boolean)", "summary", "df-generated"] + - ["hudson.util", "XStream2SecurityUtils", "checkForCollectionDoSAttack", "(UnmarshallingContext,long)", "summary", "df-generated"] + - ["hudson.views", "BuildButtonColumn", "taskNoun", "(Object)", "summary", "df-generated"] + - ["hudson.views", "ListViewColumn", "all", "()", "summary", "df-generated"] + - ["hudson.views", "ListViewColumn", "createDefaultInitialColumnList", "()", "summary", "df-generated"] + - ["hudson.views", "ListViewColumn", "createDefaultInitialColumnList", "(Class)", "summary", "df-generated"] + - ["hudson.views", "ListViewColumn", "createDefaultInitialColumnList", "(View)", "summary", "df-generated"] + - ["hudson.views", "ListViewColumn", "getColumnCaption", "()", "summary", "df-generated"] + - ["hudson.views", "ListViewColumn", "shownByDefault", "()", "summary", "df-generated"] + - ["hudson.views", "ListViewColumnDescriptor", "shownByDefault", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "BuildButtonColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "DefaultMyViewsTabsBar_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "DefaultViewsTabsBar_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "GlobalDefaultViewConfiguration_ViewDoesNotExist", "(Object)", "summary", "df-generated"] + - ["hudson.views", "Messages", "JobColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "LastDurationColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "LastFailureColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "LastStableColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "LastSuccessColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "StatusColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "StatusFilter_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "WeatherColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_BuildButtonColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_DefaultMyViewsTabsBar_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_DefaultViewsTabsBar_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_GlobalDefaultViewConfiguration_ViewDoesNotExist", "(Object)", "summary", "df-generated"] + - ["hudson.views", "Messages", "_JobColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_LastDurationColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_LastFailureColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_LastStableColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_LastSuccessColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_StatusColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_StatusFilter_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "Messages", "_WeatherColumn_DisplayName", "()", "summary", "df-generated"] + - ["hudson.views", "MyViewsTabBar$GlobalConfigurationImpl", "getMyViewsTabBar", "()", "summary", "df-generated"] + - ["hudson.views", "MyViewsTabBar", "all", "()", "summary", "df-generated"] + - ["hudson.views", "StatusFilter", "StatusFilter", "(boolean)", "summary", "df-generated"] + - ["hudson.views", "StatusFilter", "getStatusFilter", "()", "summary", "df-generated"] + - ["hudson.views", "ViewJobFilter", "all", "()", "summary", "df-generated"] + - ["hudson.views", "ViewJobFilter", "filter", "(List,List,View)", "summary", "df-generated"] + - ["hudson.views", "ViewsTabBar$GlobalConfigurationImpl", "getViewsTabBar", "()", "summary", "df-generated"] + - ["hudson.views", "ViewsTabBar", "all", "()", "summary", "df-generated"] + - ["hudson.widgets", "BuildHistoryWidget", "getQueuedItem", "()", "summary", "df-generated"] + - ["hudson.widgets", "BuildHistoryWidget", "getQueuedItems", "()", "summary", "df-generated"] + - ["hudson.widgets", "HistoryWidget", "getDisplayName", "()", "summary", "df-generated"] + - ["hudson.widgets", "HistoryWidget", "isTrimmed", "()", "summary", "df-generated"] + - ["hudson.widgets", "HistoryWidget", "setTrimmed", "(boolean)", "summary", "df-generated"] + - ["hudson.widgets", "Messages", "BuildHistoryWidget_DisplayName", "()", "summary", "df-generated"] + - ["hudson.widgets", "Messages", "_BuildHistoryWidget_DisplayName", "()", "summary", "df-generated"] + - ["hudson.widgets", "RenderOnDemandClosure", "RenderOnDemandClosure", "(JellyContext,String)", "summary", "df-generated"] + - ["hudson.widgets", "RenderOnDemandClosure", "render", "()", "summary", "df-generated"] + - ["hudson.widgets", "Widget", "getUrlName", "()", "summary", "df-generated"] + - ["hudson", "AboutJenkins", "getLicensesURL", "()", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "addHyperlink", "(int,int,String)", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "addHyperlinkLowKey", "(int,int,String)", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "addMarkup", "(int,int,String,String)", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "charAt", "(int)", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "findToken", "(Pattern)", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "findTokens", "(Pattern)", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "getText", "()", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "hide", "(int,int)", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "length", "()", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "subText", "(int,int)", "summary", "df-generated"] + - ["hudson", "AbstractMarkupText", "wrapBy", "(String,String)", "summary", "df-generated"] + - ["hudson", "BulkChange", "abort", "()", "summary", "df-generated"] + - ["hudson", "BulkChange", "commit", "()", "summary", "df-generated"] + - ["hudson", "BulkChange", "contains", "(Saveable)", "summary", "df-generated"] + - ["hudson", "BulkChange", "current", "()", "summary", "df-generated"] + - ["hudson", "ClassicPluginStrategy", "getImpliedDependencies", "(String,String)", "summary", "df-generated"] + - ["hudson", "ClassicPluginStrategy", "startPlugin", "(PluginWrapper)", "summary", "df-generated"] + - ["hudson", "DependencyRunner$ProjectRunnable", "run", "(AbstractProject)", "summary", "df-generated"] + - ["hudson", "DescriptorExtensionList", "clearLegacyInstances", "()", "summary", "df-generated"] + - ["hudson", "DescriptorExtensionList", "listLegacyInstances", "()", "summary", "df-generated"] + - ["hudson", "DescriptorExtensionList", "newInstanceFromRadioList", "(JSONObject)", "summary", "df-generated"] + - ["hudson", "DescriptorExtensionList", "newInstanceFromRadioList", "(JSONObject,String)", "summary", "df-generated"] + - ["hudson", "EnvVars", "createCookie", "()", "summary", "df-generated"] + - ["hudson", "EnvVars", "getPlatform", "()", "summary", "df-generated"] + - ["hudson", "EnvVars", "getRemote", "(VirtualChannel)", "summary", "df-generated"] + - ["hudson", "EnvVars", "putAllNonNull", "(Map)", "summary", "df-generated"] + - ["hudson", "EnvVars", "resolve", "(Map)", "summary", "df-generated"] + - ["hudson", "EnvVars", "setPlatform", "(Platform)", "summary", "df-generated"] + - ["hudson", "ExtensionComponent", "isDescriptorOf", "(Class)", "summary", "df-generated"] + - ["hudson", "ExtensionComponent", "ordinal", "()", "summary", "df-generated"] + - ["hudson", "ExtensionFinder", "_find", "(Class,Hudson)", "summary", "df-generated"] + - ["hudson", "ExtensionFinder", "find", "(Class,Hudson)", "summary", "df-generated"] + - ["hudson", "ExtensionFinder", "findExtensions", "(Class,Hudson)", "summary", "df-generated"] + - ["hudson", "ExtensionFinder", "isRefreshable", "()", "summary", "df-generated"] + - ["hudson", "ExtensionFinder", "refresh", "()", "summary", "df-generated"] + - ["hudson", "ExtensionFinder", "scout", "(Class,Hudson)", "summary", "df-generated"] + - ["hudson", "ExtensionList", "clearLegacyInstances", "()", "summary", "df-generated"] + - ["hudson", "ExtensionList", "get", "(Class)", "summary", "df-generated"] + - ["hudson", "ExtensionList", "getInstance", "(Class)", "summary", "df-generated"] + - ["hudson", "ExtensionList", "lookup", "(Class)", "summary", "df-generated"] + - ["hudson", "ExtensionList", "lookupSingleton", "(Class)", "summary", "df-generated"] + - ["hudson", "ExtensionList", "refresh", "(ExtensionComponentSet)", "summary", "df-generated"] + - ["hudson", "ExtensionList", "reverseView", "()", "summary", "df-generated"] + - ["hudson", "ExtensionListListener", "onChange", "()", "summary", "df-generated"] + - ["hudson", "ExtensionListView", "createCopyOnWriteList", "(Class)", "summary", "df-generated"] + - ["hudson", "ExtensionListView", "createList", "(Class)", "summary", "df-generated"] + - ["hudson", "FilePath$FileCallableWrapperFactory", "wrap", "(DelegatingCallable)", "summary", "df-generated"] + - ["hudson", "FilePath$TarCompression", "compress", "(OutputStream)", "summary", "df-generated"] + - ["hudson", "FilePath$TarCompression", "extract", "(InputStream)", "summary", "df-generated"] + - ["hudson", "FilePath", "FilePath", "(File)", "summary", "df-generated"] + - ["hudson", "FilePath", "act", "(Callable)", "summary", "df-generated"] + - ["hudson", "FilePath", "actAsync", "(FileCallable)", "summary", "df-generated"] + - ["hudson", "FilePath", "archive", "(ArchiverFactory,OutputStream,DirScanner)", "summary", "df-generated"] + - ["hudson", "FilePath", "archive", "(ArchiverFactory,OutputStream,DirScanner,String,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "archive", "(ArchiverFactory,OutputStream,FileFilter)", "summary", "df-generated"] + - ["hudson", "FilePath", "archive", "(ArchiverFactory,OutputStream,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "chmod", "(int)", "summary", "df-generated"] + - ["hudson", "FilePath", "containsSymlink", "(FilePath,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyFrom", "(FileItem)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyFrom", "(FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyFrom", "(InputStream)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyFrom", "(URL)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyRecursiveTo", "(DirScanner,FilePath,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyRecursiveTo", "(DirScanner,FilePath,String,TarCompression)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyRecursiveTo", "(FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyRecursiveTo", "(String,FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyRecursiveTo", "(String,String,FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyTo", "(FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyTo", "(OutputStream)", "summary", "df-generated"] + - ["hudson", "FilePath", "copyToWithPermission", "(FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "createZipArchive", "(OutputStream)", "summary", "df-generated"] + - ["hudson", "FilePath", "createZipArchive", "(OutputStream,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "delete", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "deleteContents", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "deleteRecursive", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "deleteSuffixesRecursive", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "exists", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "getFreeDiskSpace", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "getHomeDirectory", "(VirtualChannel)", "summary", "df-generated"] + - ["hudson", "FilePath", "getTotalDiskSpace", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "getUsableDiskSpace", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "hasSymlink", "(FilePath,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "installIfNecessaryFrom", "(URL,TaskListener,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "isDescendant", "(String)", "summary", "df-generated"] + - ["hudson", "FilePath", "isDirectory", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "isRemote", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "isSymlink", "(File,String,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "lastModified", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "length", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "list", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "list", "(FileFilter)", "summary", "df-generated"] + - ["hudson", "FilePath", "list", "(FilePath,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "list", "(String)", "summary", "df-generated"] + - ["hudson", "FilePath", "list", "(String,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "list", "(String,String,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "listDirectories", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "mkdirs", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "mode", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "moveAllChildrenTo", "(FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "read", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "read", "(FilePath,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "readFromOffset", "(long)", "summary", "df-generated"] + - ["hudson", "FilePath", "renameTo", "(FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "symlinkTo", "(String,TaskListener)", "summary", "df-generated"] + - ["hudson", "FilePath", "tar", "(OutputStream,DirScanner)", "summary", "df-generated"] + - ["hudson", "FilePath", "tar", "(OutputStream,FileFilter)", "summary", "df-generated"] + - ["hudson", "FilePath", "tar", "(OutputStream,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "toComputer", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "touch", "(long)", "summary", "df-generated"] + - ["hudson", "FilePath", "untar", "(FilePath,TarCompression)", "summary", "df-generated"] + - ["hudson", "FilePath", "untarFrom", "(InputStream,TarCompression)", "summary", "df-generated"] + - ["hudson", "FilePath", "unzip", "(FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "unzipFrom", "(InputStream)", "summary", "df-generated"] + - ["hudson", "FilePath", "validateFileMask", "(FilePath,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "validateFileMask", "(FilePath,String,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "validateFileMask", "(String)", "summary", "df-generated"] + - ["hudson", "FilePath", "validateFileMask", "(String,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "validateFileMask", "(String,boolean,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "validateRelativeDirectory", "(String)", "summary", "df-generated"] + - ["hudson", "FilePath", "validateRelativeDirectory", "(String,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "validateRelativePath", "(String,boolean,boolean)", "summary", "df-generated"] + - ["hudson", "FilePath", "write", "()", "summary", "df-generated"] + - ["hudson", "FilePath", "write", "(String,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "zip", "(FilePath)", "summary", "df-generated"] + - ["hudson", "FilePath", "zip", "(OutputStream)", "summary", "df-generated"] + - ["hudson", "FilePath", "zip", "(OutputStream,DirScanner)", "summary", "df-generated"] + - ["hudson", "FilePath", "zip", "(OutputStream,DirScanner,String,boolean,String)", "summary", "df-generated"] + - ["hudson", "FilePath", "zip", "(OutputStream,FileFilter)", "summary", "df-generated"] + - ["hudson", "FilePath", "zip", "(OutputStream,String)", "summary", "df-generated"] + - ["hudson", "FileSystemProvisioner", "discardWorkspace", "(AbstractProject,FilePath)", "summary", "df-generated"] + - ["hudson", "FileSystemProvisioner", "prepareWorkspace", "(AbstractBuild,FilePath,TaskListener)", "summary", "df-generated"] + - ["hudson", "FileSystemProvisioner", "snapshot", "(AbstractBuild,FilePath,String,TaskListener)", "summary", "df-generated"] + - ["hudson", "Functions", "adminCheck", "(StaplerRequest,StaplerResponse,Object,Permission)", "summary", "df-generated"] + - ["hudson", "Functions", "advertiseHeaders", "(HttpServletResponse)", "summary", "df-generated"] + - ["hudson", "Functions", "checkAnyPermission", "(AccessControlled,Permission[])", "summary", "df-generated"] + - ["hudson", "Functions", "checkAnyPermission", "(Object,Permission[])", "summary", "df-generated"] + - ["hudson", "Functions", "checkPermission", "(AccessControlled,Permission)", "summary", "df-generated"] + - ["hudson", "Functions", "checkPermission", "(Object,Permission)", "summary", "df-generated"] + - ["hudson", "Functions", "checkPermission", "(Permission)", "summary", "df-generated"] + - ["hudson", "Functions", "configureAutoRefresh", "(HttpServletRequest,HttpServletResponse,boolean)", "summary", "df-generated"] + - ["hudson", "Functions", "createRenderOnDemandProxy", "(JellyContext,String)", "summary", "df-generated"] + - ["hudson", "Functions", "defaultToTrue", "(Boolean)", "summary", "df-generated"] + - ["hudson", "Functions", "determineRows", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "dumpAllThreads", "()", "summary", "df-generated"] + - ["hudson", "Functions", "emptyList", "()", "summary", "df-generated"] + - ["hudson", "Functions", "escape", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "generateConsoleAnnotationScriptAndStylesheet", "()", "summary", "df-generated"] + - ["hudson", "Functions", "generateId", "()", "summary", "df-generated"] + - ["hudson", "Functions", "generateItemId", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getAllTopLevelItems", "(ItemGroup)", "summary", "df-generated"] + - ["hudson", "Functions", "getAuthorizationStrategyDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getAvatar", "(User,String)", "summary", "df-generated"] + - ["hudson", "Functions", "getBuildWrapperDescriptors", "(AbstractProject)", "summary", "df-generated"] + - ["hudson", "Functions", "getBuilderDescriptors", "(AbstractProject)", "summary", "df-generated"] + - ["hudson", "Functions", "getCLICommands", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getCaptchaSupportDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getCloudDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getComputerLauncherDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getCookie", "(HttpServletRequest,String)", "summary", "df-generated"] + - ["hudson", "Functions", "getCrumb", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson", "Functions", "getCrumbIssuerDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getCrumbRequestField", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getCurrentDescriptorByNameUrl", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getCurrentJellyContext", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getCurrentLocale", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getCurrentTime", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getDiffString2", "(int)", "summary", "df-generated"] + - ["hudson", "Functions", "getDiffString", "(int)", "summary", "df-generated"] + - ["hudson", "Functions", "getEnvVars", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getFooterURL", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getGlobalNodePropertyDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getHourLocalTimezone", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getIconFilePath", "(Action)", "summary", "df-generated"] + - ["hudson", "Functions", "getIsUnitTest", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getJDKDescriptor", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getJobPropertyDescriptors", "(Class)", "summary", "df-generated"] + - ["hudson", "Functions", "getJobPropertyDescriptors", "(Job)", "summary", "df-generated"] + - ["hudson", "Functions", "getLogRecords", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getLoggerNames", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getMyViewsTabBarDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getNodeModes", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getNodePropertyDescriptors", "(Class)", "summary", "df-generated"] + - ["hudson", "Functions", "getPageDecorators", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getParameterDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getPublisherDescriptors", "(AbstractProject)", "summary", "df-generated"] + - ["hudson", "Functions", "getRelativeLinkTo", "(Item)", "summary", "df-generated"] + - ["hudson", "Functions", "getRequestHeaders", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "getResourcePath", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getRetentionStrategyDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSCMDescriptors", "(AbstractProject)", "summary", "df-generated"] + - ["hudson", "Functions", "getScreenResolution", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSearchURL", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSecurityRealmDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getServerName", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSimplePageDecorator", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSimplePageDecorators", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSortedDescriptorsForGlobalConfig", "(Predicate)", "summary", "df-generated"] + - ["hudson", "Functions", "getSortedDescriptorsForGlobalConfigByDescriptor", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSortedDescriptorsForGlobalConfigByDescriptor", "(Predicate)", "summary", "df-generated"] + - ["hudson", "Functions", "getSortedDescriptorsForGlobalConfigNoSecurity", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSortedDescriptorsForGlobalConfigUnclassified", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSortedDescriptorsForGlobalConfigUnclassifiedReadable", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSystemProperties", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getSystemProperty", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "getThreadInfos", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getTimeSpanString", "(Date)", "summary", "df-generated"] + - ["hudson", "Functions", "getTypeParameter", "(Class,Class,int)", "summary", "df-generated"] + - ["hudson", "Functions", "getUserAvatar", "(User,String)", "summary", "df-generated"] + - ["hudson", "Functions", "getUserTimeZone", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getUserTimeZonePostfix", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getVersion", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getViewsTabBarDescriptors", "()", "summary", "df-generated"] + - ["hudson", "Functions", "getWin32ErrorMessage", "(IOException)", "summary", "df-generated"] + - ["hudson", "Functions", "getYuiSuffix", "()", "summary", "df-generated"] + - ["hudson", "Functions", "hasAnyPermission", "(AccessControlled,Permission[])", "summary", "df-generated"] + - ["hudson", "Functions", "hasAnyPermission", "(Object,Permission[])", "summary", "df-generated"] + - ["hudson", "Functions", "hasPermission", "(Object,Permission)", "summary", "df-generated"] + - ["hudson", "Functions", "hasPermission", "(Permission)", "summary", "df-generated"] + - ["hudson", "Functions", "hasView", "(Object,String)", "summary", "df-generated"] + - ["hudson", "Functions", "htmlAttributeEscape", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "humanReadableByteSize", "(long)", "summary", "df-generated"] + - ["hudson", "Functions", "hyperlinkMatchesCurrentPage", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "inferHudsonURL", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson", "Functions", "initPageVariables", "(JellyContext)", "summary", "df-generated"] + - ["hudson", "Functions", "isAnonymous", "()", "summary", "df-generated"] + - ["hudson", "Functions", "isArtifactsPermissionEnabled", "()", "summary", "df-generated"] + - ["hudson", "Functions", "isAutoRefresh", "(HttpServletRequest)", "summary", "df-generated"] + - ["hudson", "Functions", "isCollapsed", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "isContextMenuVisible", "(Action)", "summary", "df-generated"] + - ["hudson", "Functions", "isExtensionsAvailable", "()", "summary", "df-generated"] + - ["hudson", "Functions", "isGlibcSupported", "()", "summary", "df-generated"] + - ["hudson", "Functions", "isMatrixProject", "(Object)", "summary", "df-generated"] + - ["hudson", "Functions", "isModel", "(Object)", "summary", "df-generated"] + - ["hudson", "Functions", "isModelWithChildren", "(Object)", "summary", "df-generated"] + - ["hudson", "Functions", "isModelWithContextMenu", "(Object)", "summary", "df-generated"] + - ["hudson", "Functions", "isMultiline", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "isMustangOrAbove", "()", "summary", "df-generated"] + - ["hudson", "Functions", "isUserTimeZoneOverride", "()", "summary", "df-generated"] + - ["hudson", "Functions", "isWindows", "()", "summary", "df-generated"] + - ["hudson", "Functions", "isWipeOutPermissionEnabled", "()", "summary", "df-generated"] + - ["hudson", "Functions", "iso8601DateTime", "(Date)", "summary", "df-generated"] + - ["hudson", "Functions", "jsStringEscape", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "localDate", "(Date)", "summary", "df-generated"] + - ["hudson", "Functions", "nbspIndent", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "printLogRecord", "(LogRecord)", "summary", "df-generated"] + - ["hudson", "Functions", "printLogRecordHtml", "(LogRecord,LogRecord)", "summary", "df-generated"] + - ["hudson", "Functions", "printStackTrace", "(Throwable,PrintStream)", "summary", "df-generated"] + - ["hudson", "Functions", "printStackTrace", "(Throwable,PrintWriter)", "summary", "df-generated"] + - ["hudson", "Functions", "restoreCurrentDescriptorByNameUrl", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "rfc822Date", "(Calendar)", "summary", "df-generated"] + - ["hudson", "Functions", "runScript", "(Script)", "summary", "df-generated"] + - ["hudson", "Functions", "setCurrentDescriptorByNameUrl", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "size2", "(Object)", "summary", "df-generated"] + - ["hudson", "Functions", "sortThreadsAndGetGroupMap", "(ThreadInfo[])", "summary", "df-generated"] + - ["hudson", "Functions", "toCCStatus", "(Item)", "summary", "df-generated"] + - ["hudson", "Functions", "toEmailSafeString", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "tryGetIcon", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "urlEncode", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "useHidingPasswordFields", "()", "summary", "df-generated"] + - ["hudson", "Functions", "xmlEscape", "(String)", "summary", "df-generated"] + - ["hudson", "Functions", "xsDate", "(Calendar)", "summary", "df-generated"] + - ["hudson", "Indenter", "getCss", "(Job)", "summary", "df-generated"] + - ["hudson", "Indenter", "getRelativeShift", "(Job)", "summary", "df-generated"] + - ["hudson", "Launcher$LocalLauncher", "launchChannel", "(OutputStream,ProcessBuilder)", "summary", "df-generated"] + - ["hudson", "Launcher$ProcStarter", "join", "()", "summary", "df-generated"] + - ["hudson", "Launcher$ProcStarter", "masks", "()", "summary", "df-generated"] + - ["hudson", "Launcher$ProcStarter", "quiet", "()", "summary", "df-generated"] + - ["hudson", "Launcher$RemoteProcess", "getIOtriplet", "()", "summary", "df-generated"] + - ["hudson", "Launcher$RemoteProcess", "isAlive", "()", "summary", "df-generated"] + - ["hudson", "Launcher$RemoteProcess", "join", "()", "summary", "df-generated"] + - ["hudson", "Launcher$RemoteProcess", "kill", "()", "summary", "df-generated"] + - ["hudson", "Launcher", "getComputer", "()", "summary", "df-generated"] + - ["hudson", "Launcher", "isUnix", "()", "summary", "df-generated"] + - ["hudson", "Launcher", "kill", "(Map)", "summary", "df-generated"] + - ["hudson", "Launcher", "launch", "()", "summary", "df-generated"] + - ["hudson", "Launcher", "launch", "(ProcStarter)", "summary", "df-generated"] + - ["hudson", "Launcher", "launchChannel", "(String[],OutputStream,FilePath,Map)", "summary", "df-generated"] + - ["hudson", "Launcher", "prepareFilterRules", "(Run,EnvVarsFilterableBuilder)", "summary", "df-generated"] + - ["hudson", "LauncherDecorator", "all", "()", "summary", "df-generated"] + - ["hudson", "LauncherDecorator", "decorate", "(Launcher,Node)", "summary", "df-generated"] + - ["hudson", "Lookup", "get", "(Class)", "summary", "df-generated"] + - ["hudson", "Main", "remotePost", "(String[])", "summary", "df-generated"] + - ["hudson", "Main", "run", "(String[])", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "SubText", "(Matcher,int)", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "SubText", "(int,int)", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "end", "()", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "end", "(int)", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "group", "(int)", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "groupCount", "()", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "href", "(String)", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "replace", "(String)", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "start", "()", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "start", "(int)", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "surroundWith", "(String,String)", "summary", "df-generated"] + - ["hudson", "MarkupText$SubText", "surroundWithLiteral", "(String,String)", "summary", "df-generated"] + - ["hudson", "MarkupText", "addMarkup", "(int,String)", "summary", "df-generated"] + - ["hudson", "Messages", "AboutJenkins_Description", "()", "summary", "df-generated"] + - ["hudson", "Messages", "AboutJenkins_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_TildaDoesntWork", "()", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_did_not_manage_to_validate_may_be_too_sl", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateAntFileMask_doesntMatchAndSuggest", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateAntFileMask_doesntMatchAnything", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateAntFileMask_doesntMatchAnythingAndSuggest", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateAntFileMask_matchWithCaseInsensitive", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateAntFileMask_portionMatchAndSuggest", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateAntFileMask_portionMatchButPreviousNotMatchAndSuggest", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateAntFileMask_whitespaceSeparator", "()", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateRelativePath_noSuchDirectory", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateRelativePath_noSuchFile", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateRelativePath_notDirectory", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateRelativePath_notFile", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "FilePath_validateRelativePath_wildcardNotAllowed", "()", "summary", "df-generated"] + - ["hudson", "Messages", "Functions_NoExceptionDetails", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_CheckUpdateServerError", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_ConfigureUpdateCenterPermission_Description", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_PluginCycleDependenciesMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_PluginDeprecationMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_PluginDoesntSupportDynamicLoad_RestartRequired", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_PluginIsAlreadyInstalled_RestartRequired", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_PluginUpdateMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_PortNotANumber", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_PortNotInRange", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_UnexpectedException", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_UpdateSiteChangeLogLevel", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_UpdateSiteError", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_UploadPluginsPermission_Description", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_adoptThisPlugin", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_ago", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_compatWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_connectionFailed", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_coreWarning", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_depCompatWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_depCoreWarning", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_deprecationWarning", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_emptyUpdateSiteUrl", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_insecureUrl", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_invalidUrl", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_parentCompatWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_parentDepCompatWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginManager_securityWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_Already_Disabled", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_Error_Disabling", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_NoSuchPlugin", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_PluginWrapperAdministrativeMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_Plugin_Disabled", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_Plugin_Has_Dependent", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_disabled_2", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_failed_to_load_dependency_2", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_failed_to_load_plugin_2", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_missing", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_obsoleteCore", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "PluginWrapper_obsolete_2", "(Object,Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "ProxyConfiguration_FailedToConnect", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "ProxyConfiguration_FailedToConnectViaProxy", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "ProxyConfiguration_MalformedTestUrl", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "ProxyConfiguration_Success", "()", "summary", "df-generated"] + - ["hudson", "Messages", "ProxyConfiguration_TestUrlRequired", "()", "summary", "df-generated"] + - ["hudson", "Messages", "TcpSlaveAgentListener_PingAgentProtocol_displayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "Util_day", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "Util_hour", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "Util_millisecond", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "Util_minute", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "Util_month", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "Util_second", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "Util_year", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_AboutJenkins_Description", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_AboutJenkins_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_TildaDoesntWork", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_did_not_manage_to_validate_may_be_too_sl", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateAntFileMask_doesntMatchAndSuggest", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateAntFileMask_doesntMatchAnything", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateAntFileMask_doesntMatchAnythingAndSuggest", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateAntFileMask_matchWithCaseInsensitive", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateAntFileMask_portionMatchAndSuggest", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateAntFileMask_portionMatchButPreviousNotMatchAndSuggest", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateAntFileMask_whitespaceSeparator", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateRelativePath_noSuchDirectory", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateRelativePath_noSuchFile", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateRelativePath_notDirectory", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateRelativePath_notFile", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_FilePath_validateRelativePath_wildcardNotAllowed", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_Functions_NoExceptionDetails", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_CheckUpdateServerError", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_ConfigureUpdateCenterPermission_Description", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_PluginCycleDependenciesMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_PluginDeprecationMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_PluginDoesntSupportDynamicLoad_RestartRequired", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_PluginIsAlreadyInstalled_RestartRequired", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_PluginUpdateMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_PortNotANumber", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_PortNotInRange", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_UnexpectedException", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_UpdateSiteChangeLogLevel", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_UpdateSiteError", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_UploadPluginsPermission_Description", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_adoptThisPlugin", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_ago", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_compatWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_connectionFailed", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_coreWarning", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_depCompatWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_depCoreWarning", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_deprecationWarning", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_emptyUpdateSiteUrl", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_insecureUrl", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_invalidUrl", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_parentCompatWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_parentDepCompatWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginManager_securityWarning", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_Already_Disabled", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_Error_Disabling", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_NoSuchPlugin", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_PluginWrapperAdministrativeMonitor_DisplayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_Plugin_Disabled", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_Plugin_Has_Dependent", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_disabled_2", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_failed_to_load_dependency_2", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_failed_to_load_plugin_2", "(Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_missing", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_obsoleteCore", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_PluginWrapper_obsolete_2", "(Object,Object,Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_ProxyConfiguration_FailedToConnect", "(Object,Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_ProxyConfiguration_FailedToConnectViaProxy", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_ProxyConfiguration_MalformedTestUrl", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_ProxyConfiguration_Success", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_ProxyConfiguration_TestUrlRequired", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_TcpSlaveAgentListener_PingAgentProtocol_displayName", "()", "summary", "df-generated"] + - ["hudson", "Messages", "_Util_day", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_Util_hour", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_Util_millisecond", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_Util_minute", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_Util_month", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_Util_second", "(Object)", "summary", "df-generated"] + - ["hudson", "Messages", "_Util_year", "(Object)", "summary", "df-generated"] + - ["hudson", "Platform", "current", "()", "summary", "df-generated"] + - ["hudson", "Platform", "isDarwin", "()", "summary", "df-generated"] + - ["hudson", "Platform", "isSnowLeopardOrLater", "()", "summary", "df-generated"] + - ["hudson", "Plugin", "configure", "(JSONObject)", "summary", "df-generated"] + - ["hudson", "Plugin", "configure", "(StaplerRequest,JSONObject)", "summary", "df-generated"] + - ["hudson", "Plugin", "doDynamic", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson", "Plugin", "postInitialize", "()", "summary", "df-generated"] + - ["hudson", "Plugin", "setServletContext", "(ServletContext)", "summary", "df-generated"] + - ["hudson", "Plugin", "start", "()", "summary", "df-generated"] + - ["hudson", "Plugin", "stop", "()", "summary", "df-generated"] + - ["hudson", "PluginFirstClassLoader2", "PluginFirstClassLoader2", "(URL[],ClassLoader)", "summary", "df-generated"] + - ["hudson", "PluginManager$MetadataCache", "of", "(String,Class,Supplier)", "summary", "df-generated"] + - ["hudson", "PluginManager$PluginDeprecationMonitor", "getDeprecatedPlugins", "()", "summary", "df-generated"] + - ["hudson", "PluginManager$PluginUpdateMonitor", "getInstance", "()", "summary", "df-generated"] + - ["hudson", "PluginManager$UberClassLoader", "toString", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "createCache", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "discover", "(Class)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doCheckPluginUrl", "(StaplerRequest,String)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doCheckUpdateSiteUrl", "(StaplerRequest,String)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doCheckUpdatesServer", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "doInstall", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doInstallNecessaryPlugins", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doInstallPlugins", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doInstallPluginsDone", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "doPlugins", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "doPluginsSearch", "(String,Integer)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doPrevalidateConfig", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doProxyConfigure", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doSiteConfigure", "(String)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doUpdateSources", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson", "PluginManager", "doUploadPlugin", "(StaplerRequest)", "summary", "df-generated"] + - ["hudson", "PluginManager", "dynamicLoad", "(File)", "summary", "df-generated"] + - ["hudson", "PluginManager", "getBundledPluginManifest", "(String)", "summary", "df-generated"] + - ["hudson", "PluginManager", "getProxyDescriptor", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "getUpdates", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "hasAdoptThisPluginLabel", "(Plugin)", "summary", "df-generated"] + - ["hudson", "PluginManager", "hasAdoptThisPluginLabel", "(PluginWrapper)", "summary", "df-generated"] + - ["hudson", "PluginManager", "initTasks", "(InitStrategy)", "summary", "df-generated"] + - ["hudson", "PluginManager", "install", "(Collection,boolean)", "summary", "df-generated"] + - ["hudson", "PluginManager", "isMetaLabel", "(String)", "summary", "df-generated"] + - ["hudson", "PluginManager", "isNonMetaLabel", "(String)", "summary", "df-generated"] + - ["hudson", "PluginManager", "isPluginUploaded", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "parseRequestedPlugins", "(InputStream)", "summary", "df-generated"] + - ["hudson", "PluginManager", "prevalidateConfig", "(InputStream)", "summary", "df-generated"] + - ["hudson", "PluginManager", "resolveDependentPlugins", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "start", "(List)", "summary", "df-generated"] + - ["hudson", "PluginManager", "stop", "()", "summary", "df-generated"] + - ["hudson", "PluginManager", "unscientific", "(double)", "summary", "df-generated"] + - ["hudson", "PluginManagerStaplerOverride", "all", "()", "summary", "df-generated"] + - ["hudson", "PluginStrategy", "findComponents", "(Class,Hudson)", "summary", "df-generated"] + - ["hudson", "PluginStrategy", "initializeComponents", "(PluginWrapper)", "summary", "df-generated"] + - ["hudson", "PluginStrategy", "load", "(PluginWrapper)", "summary", "df-generated"] + - ["hudson", "PluginStrategy", "updateDependency", "(PluginWrapper,PluginWrapper)", "summary", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", "getStatus", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableResult", "setStatus", "(PluginDisableStatus)", "summary", "df-generated"] + - ["hudson", "PluginWrapper$PluginDisableStrategy", "toString", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper$PluginWrapperAdministrativeMonitor", "doAct", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["hudson", "PluginWrapper$PluginWrapperAdministrativeMonitor", "get", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper$PluginWrapperAdministrativeMonitor", "hasAnyDerivedDependencyErrors", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "disable", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "doDoUninstall", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "doMakeDisabled", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "doMakeEnabled", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "doPin", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "doUnpin", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "enable", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getActiveWarnings", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getBackupVersion", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getDeprecations", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getImpliedDependents", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getIndexPage", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getInfo", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getIssueTrackerReportUrl", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getPlugin", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getPluginClass", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getPluginOrFail", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getRequiredCoreVersion", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getUpdateInfo", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getUrl", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getVersion", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "getVersionNumber", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasCycleDependency", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasDependants", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasDependencies", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasDependents", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasDerivedDependencyErrors", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasImpliedDependents", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasLicensesXml", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasMandatoryDependencies", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasMandatoryDependents", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasOptionalDependants", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasOptionalDependents", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasOriginalDependencyErrors", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "hasUpdate", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "injectJarsToClasspath", "(File[])", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isActive", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isBundled", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isDeleted", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isDeprecated", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isDetached", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isDowngradable", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isEnabled", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isOlderThan", "(VersionNumber)", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isPinned", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "isPinningForcingOldVersion", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "releaseClassLoader", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "setHasCycleDependency", "(boolean)", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "setOptionalDependants", "(Set)", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "stop", "()", "summary", "df-generated"] + - ["hudson", "PluginWrapper", "supportsDynamicLoad", "()", "summary", "df-generated"] + - ["hudson", "Proc", "getStderr", "()", "summary", "df-generated"] + - ["hudson", "Proc", "getStdin", "()", "summary", "df-generated"] + - ["hudson", "Proc", "getStdout", "()", "summary", "df-generated"] + - ["hudson", "Proc", "isAlive", "()", "summary", "df-generated"] + - ["hudson", "Proc", "join", "()", "summary", "df-generated"] + - ["hudson", "Proc", "joinWithTimeout", "(long,TimeUnit,TaskListener)", "summary", "df-generated"] + - ["hudson", "Proc", "kill", "()", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration$DescriptorImpl", "doCheckPort", "(String)", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration$DescriptorImpl", "doValidateProxy", "(String,String,int,String,Secret,String)", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "createProxy", "()", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "createProxy", "(String)", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "createProxy", "(String,String,int,String)", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "getInputStream", "(URL)", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "getNoProxyHostPatterns", "()", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "getNoProxyHostPatterns", "(String)", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "getPort", "()", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "getXmlFile", "()", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "load", "()", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "newHttpClient", "()", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "newHttpClientBuilder", "()", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "newHttpRequestBuilder", "(URI)", "summary", "df-generated"] + - ["hudson", "ProxyConfiguration", "open", "(URL)", "summary", "df-generated"] + - ["hudson", "StructuredForm", "toList", "(JSONObject,String)", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener$ConnectionFromCurrentPeer", "toString", "()", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener$PingAgentProtocol", "connect", "(Socket)", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener", "TcpSlaveAgentListener", "(int)", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener", "getAdvertisedHost", "()", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener", "getAdvertisedPort", "()", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener", "getAgentProtocolNames", "()", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener", "getIdentityPublicKey", "()", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener", "getPort", "()", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener", "getRemotingMinimumVersion", "()", "summary", "df-generated"] + - ["hudson", "TcpSlaveAgentListener", "shutdown", "()", "summary", "df-generated"] + - ["hudson", "URLConnectionDecorator", "all", "()", "summary", "df-generated"] + - ["hudson", "URLConnectionDecorator", "decorate", "(URLConnection)", "summary", "df-generated"] + - ["hudson", "Util", "closeAndLogFailures", "(Closeable,Logger,String,String)", "summary", "df-generated"] + - ["hudson", "Util", "copyFile", "(File,File)", "summary", "df-generated"] + - ["hudson", "Util", "createFileSet", "(File,String)", "summary", "df-generated"] + - ["hudson", "Util", "createFileSet", "(File,String,String)", "summary", "df-generated"] + - ["hudson", "Util", "createSubList", "(Collection,Class)", "summary", "df-generated"] + - ["hudson", "Util", "createSymlink", "(File,String,String,TaskListener)", "summary", "df-generated"] + - ["hudson", "Util", "createTempDir", "()", "summary", "df-generated"] + - ["hudson", "Util", "daysBetween", "(Date,Date)", "summary", "df-generated"] + - ["hudson", "Util", "daysElapsedSince", "(Date)", "summary", "df-generated"] + - ["hudson", "Util", "deleteContentsRecursive", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "deleteContentsRecursive", "(Path,PathChecker)", "summary", "df-generated"] + - ["hudson", "Util", "deleteFile", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "deleteRecursive", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "deleteRecursive", "(Path,PathChecker)", "summary", "df-generated"] + - ["hudson", "Util", "displayIOException", "(IOException,TaskListener)", "summary", "df-generated"] + - ["hudson", "Util", "escape", "(String)", "summary", "df-generated"] + - ["hudson", "Util", "filter", "(Iterable,Class)", "summary", "df-generated"] + - ["hudson", "Util", "filter", "(List,Class)", "summary", "df-generated"] + - ["hudson", "Util", "fromHexString", "(String)", "summary", "df-generated"] + - ["hudson", "Util", "getDigestOf", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "getDigestOf", "(InputStream)", "summary", "df-generated"] + - ["hudson", "Util", "getDigestOf", "(String)", "summary", "df-generated"] + - ["hudson", "Util", "getHostName", "()", "summary", "df-generated"] + - ["hudson", "Util", "getNearestAncestorOfTypeOrThrow", "(StaplerRequest,Class)", "summary", "df-generated"] + - ["hudson", "Util", "getPastTimeString", "(long)", "summary", "df-generated"] + - ["hudson", "Util", "getTimeSpanString", "(long)", "summary", "df-generated"] + - ["hudson", "Util", "getWin32ErrorMessage", "(IOException)", "summary", "df-generated"] + - ["hudson", "Util", "getWin32ErrorMessage", "(Throwable)", "summary", "df-generated"] + - ["hudson", "Util", "getWin32ErrorMessage", "(int)", "summary", "df-generated"] + - ["hudson", "Util", "ifOverridden", "(Supplier,Class,Class,String,Class[])", "summary", "df-generated"] + - ["hudson", "Util", "isAbsoluteUri", "(String)", "summary", "df-generated"] + - ["hudson", "Util", "isDescendant", "(File,File)", "summary", "df-generated"] + - ["hudson", "Util", "isOverridden", "(Class,Class,String,Class[])", "summary", "df-generated"] + - ["hudson", "Util", "isRelativePath", "(String)", "summary", "df-generated"] + - ["hudson", "Util", "isSafeToRedirectTo", "(String)", "summary", "df-generated"] + - ["hudson", "Util", "isSymlink", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "isSymlink", "(Path)", "summary", "df-generated"] + - ["hudson", "Util", "loadFile", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "loadFile", "(File,Charset)", "summary", "df-generated"] + - ["hudson", "Util", "loadProperties", "(String)", "summary", "df-generated"] + - ["hudson", "Util", "min", "(int,int[])", "summary", "df-generated"] + - ["hudson", "Util", "modeToPermissions", "(int)", "summary", "df-generated"] + - ["hudson", "Util", "permissionsToMode", "(Set)", "summary", "df-generated"] + - ["hudson", "Util", "resolveSymlink", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "resolveSymlink", "(File,TaskListener)", "summary", "df-generated"] + - ["hudson", "Util", "resolveSymlinkToFile", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "toAes128Key", "(String)", "summary", "df-generated"] + - ["hudson", "Util", "toHexString", "(byte[],int,int)", "summary", "df-generated"] + - ["hudson", "Util", "tokenize", "(String,String)", "summary", "df-generated"] + - ["hudson", "Util", "touch", "(File)", "summary", "df-generated"] + - ["hudson", "Util", "tryParseNumber", "(String,Number)", "summary", "df-generated"] + - ["hudson", "Util", "xmlEscape", "(String)", "summary", "df-generated"] + - ["hudson", "WebAppMain", "getDefaultRingBufferSize", "()", "summary", "df-generated"] + - ["hudson", "WebAppMain", "getHomeDir", "(ServletContextEvent)", "summary", "df-generated"] + - ["hudson", "WebAppMain", "installExpressionFactory", "(ServletContextEvent)", "summary", "df-generated"] + - ["hudson", "WebAppMain", "joinInit", "()", "summary", "df-generated"] + - ["hudson", "WorkspaceSnapshot", "restoreTo", "(AbstractBuild,FilePath,TaskListener)", "summary", "df-generated"] + - ["hudson", "XmlFile", "asString", "()", "summary", "df-generated"] + - ["hudson", "XmlFile", "delete", "()", "summary", "df-generated"] + - ["hudson", "XmlFile", "exists", "()", "summary", "df-generated"] + - ["hudson", "XmlFile", "mkdirs", "()", "summary", "df-generated"] + - ["hudson", "XmlFile", "read", "()", "summary", "df-generated"] + - ["hudson", "XmlFile", "readRaw", "()", "summary", "df-generated"] + - ["hudson", "XmlFile", "sniffEncoding", "()", "summary", "df-generated"] + - ["hudson", "XmlFile", "unmarshal", "(Object)", "summary", "df-generated"] + - ["hudson", "XmlFile", "unmarshalNullingOut", "(Object)", "summary", "df-generated"] + - ["hudson", "XmlFile", "write", "(Object)", "summary", "df-generated"] + - ["hudson", "XmlFile", "writeRawTo", "(Writer)", "summary", "df-generated"] + - ["java.lang", "ClassLoader", "findClass", "(String)", "summary", "df-generated"] + - ["java.lang", "ClassLoader", "findResource", "(String)", "summary", "df-generated"] + - ["java.lang", "ClassLoader", "findResources", "(String)", "summary", "df-generated"] + - ["java.lang", "ClassLoader", "getClassLoadingLock", "(String)", "summary", "df-generated"] + - ["jenkins.agents", "AgentComputerUtil", "getChannelToController", "()", "summary", "df-generated"] + - ["jenkins.agents", "AgentComputerUtil", "getChannelToMaster", "()", "summary", "df-generated"] + - ["jenkins.agents", "WebSocketAgents", "doIndex", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", "doDelete", "()", "summary", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", "doDownload", "()", "summary", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", "getLastModified", "()", "summary", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", "getLastModifiedDate", "()", "summary", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", "getPath", "()", "summary", "df-generated"] + - ["jenkins.diagnosis", "HsErrPidFile", "getTimeSpanString", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "ControllerExecutorsAgents", "doAct", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.diagnostics", "ControllerExecutorsNoAgents", "doAct", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "CompletedInitializationMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "ControllerExecutorsAgents_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "ControllerExecutorsNoAgents_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "RootUrlNotSetMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "SecurityIsOffMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "URICheckEncodingMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "_CompletedInitializationMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "_ControllerExecutorsAgents_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "_ControllerExecutorsNoAgents_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "_RootUrlNotSetMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "_SecurityIsOffMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "Messages", "_URICheckEncodingMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "RootUrlNotSetMonitor", "isUrlNull", "()", "summary", "df-generated"] + - ["jenkins.diagnostics", "SecurityIsOffMonitor", "doAct", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.diagnostics", "URICheckEncodingMonitor", "doCheckURIEncoding", "(StaplerRequest)", "summary", "df-generated"] + - ["jenkins.diagnostics", "URICheckEncodingMonitor", "isCheckEnabled", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "FileFingerprintStorage", "load", "(File)", "summary", "df-generated"] + - ["jenkins.fingerprints", "FileFingerprintStorage", "save", "(Fingerprint,File)", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorage", "cleanFingerprint", "(Fingerprint,TaskListener)", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorage", "delete", "(String)", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorage", "get", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorage", "getFileFingerprintStorage", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorage", "isReady", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorage", "iterateAndCleanupFingerprints", "(TaskListener)", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorage", "load", "(String)", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorage", "save", "(Fingerprint)", "summary", "df-generated"] + - ["jenkins.fingerprints", "FingerprintStorageDescriptor", "all", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "GlobalFingerprintConfiguration", "get", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "GlobalFingerprintConfiguration", "getFingerprintStorageDescriptors", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "GlobalFingerprintConfiguration", "isFingerprintCleanupDisabled", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "GlobalFingerprintConfiguration", "setFingerprintCleanupDisabled", "(boolean)", "summary", "df-generated"] + - ["jenkins.fingerprints", "Messages", "FileFingerprintStorage_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.fingerprints", "Messages", "_FileFingerprintStorage_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.formelementpath", "FormElementPathPageDecorator", "isEnabled", "()", "summary", "df-generated"] + - ["jenkins.install", "InstallState", "initializeState", "()", "summary", "df-generated"] + - ["jenkins.install", "InstallState", "isSetupComplete", "()", "summary", "df-generated"] + - ["jenkins.install", "InstallState", "valueOf", "(String)", "summary", "df-generated"] + - ["jenkins.install", "InstallStateFilter", "all", "()", "summary", "df-generated"] + - ["jenkins.install", "InstallStateFilter", "getNextInstallState", "(InstallState,Provider)", "summary", "df-generated"] + - ["jenkins.install", "InstallUtil", "clearInstallStatus", "()", "summary", "df-generated"] + - ["jenkins.install", "InstallUtil", "getLastExecVersion", "()", "summary", "df-generated"] + - ["jenkins.install", "InstallUtil", "getPersistedInstallStatus", "()", "summary", "df-generated"] + - ["jenkins.install", "InstallUtil", "persistInstallStatus", "(List)", "summary", "df-generated"] + - ["jenkins.install", "InstallUtil", "proceedToNextStateFrom", "(InstallState)", "summary", "df-generated"] + - ["jenkins.install", "InstallUtil", "saveLastExecVersion", "()", "summary", "df-generated"] + - ["jenkins.install", "Messages", "SetupWizard_ConfigureInstance_RootUrl_Empty", "()", "summary", "df-generated"] + - ["jenkins.install", "Messages", "SetupWizard_ConfigureInstance_RootUrl_Invalid", "()", "summary", "df-generated"] + - ["jenkins.install", "Messages", "SetupWizard_ConfigureInstance_ValidationErrors", "()", "summary", "df-generated"] + - ["jenkins.install", "Messages", "SetupWizard_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.install", "Messages", "_SetupWizard_ConfigureInstance_RootUrl_Empty", "()", "summary", "df-generated"] + - ["jenkins.install", "Messages", "_SetupWizard_ConfigureInstance_RootUrl_Invalid", "()", "summary", "df-generated"] + - ["jenkins.install", "Messages", "_SetupWizard_ConfigureInstance_ValidationErrors", "()", "summary", "df-generated"] + - ["jenkins.install", "Messages", "_SetupWizard_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "doCompleteInstall", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "doConfigureInstance", "(StaplerRequest,String)", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "doCreateAdminUser", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "doPlatformPluginList", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "doRestartStatus", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "getCurrentLevel", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "getInitialAdminApiTokenFile", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "getInitialAdminPasswordFile", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "getInstallState", "(String)", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "getInstallStates", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "getPlatformPluginUpdates", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "hasSetupWizardFilter", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "isUsingSecurityToken", "()", "summary", "df-generated"] + - ["jenkins.install", "SetupWizard", "onInstallStateUpdate", "(InstallState)", "summary", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsApi", "doNonSecurityPopupContent", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsApi", "doSecurityPopupContent", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsApiData", "hasActiveMonitors", "()", "summary", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsDecorator", "getMonitorsToDisplay", "()", "summary", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsDecorator", "getNonSecurityAdministrativeMonitors", "()", "summary", "df-generated"] + - ["jenkins.management", "AdministrativeMonitorsDecorator", "getSecurityAdministrativeMonitors", "()", "summary", "df-generated"] + - ["jenkins.management", "AsynchronousAdministrativeMonitor", "isFixingActive", "()", "summary", "df-generated"] + - ["jenkins.management", "Badge", "getSeverity", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "AdministrativeMonitorsDecorator_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "CliLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "CliLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ConfigureLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ConfigureLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ConfigureTools_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ConfigureTools_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ConsoleLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ConsoleLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "NodesLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "NodesLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "PluginsLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "PluginsLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "PluginsLink_incompatibleUpdateAvailable", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "PluginsLink_incompatibleUpdatesAvailable", "(Object)", "summary", "df-generated"] + - ["jenkins.management", "Messages", "PluginsLink_securityUpdateAvailable", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "PluginsLink_securityUpdatesAvailable", "(Object)", "summary", "df-generated"] + - ["jenkins.management", "Messages", "PluginsLink_updateAvailable", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "PluginsLink_updatesAvailable", "(Object)", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ReloadLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ReloadLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ShutdownLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ShutdownLink_DisplayName_cancel", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ShutdownLink_DisplayName_prepare", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ShutdownLink_DisplayName_update", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ShutdownLink_ShutDownReason_title", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ShutdownLink_ShutDownReason_update", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "ShutdownLink_ShuttingDownInProgressDescription", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "StatisticsLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "StatisticsLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "SystemInfoLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "SystemInfoLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "SystemLogLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "SystemLogLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_AdministrativeMonitorsDecorator_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_CliLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_CliLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ConfigureLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ConfigureLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ConfigureTools_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ConfigureTools_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ConsoleLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ConsoleLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_NodesLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_NodesLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_PluginsLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_PluginsLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_PluginsLink_incompatibleUpdateAvailable", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_PluginsLink_incompatibleUpdatesAvailable", "(Object)", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_PluginsLink_securityUpdateAvailable", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_PluginsLink_securityUpdatesAvailable", "(Object)", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_PluginsLink_updateAvailable", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_PluginsLink_updatesAvailable", "(Object)", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ReloadLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ReloadLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ShutdownLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ShutdownLink_DisplayName_cancel", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ShutdownLink_DisplayName_prepare", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ShutdownLink_DisplayName_update", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ShutdownLink_ShutDownReason_title", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ShutdownLink_ShutDownReason_update", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_ShutdownLink_ShuttingDownInProgressDescription", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_StatisticsLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_StatisticsLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_SystemInfoLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_SystemInfoLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_SystemLogLink_Description", "()", "summary", "df-generated"] + - ["jenkins.management", "Messages", "_SystemLogLink_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.management", "ShutdownLink", "doCancel", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.management", "ShutdownLink", "doPrepare", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model.identity", "IdentityRootAction", "getFingerprint", "()", "summary", "df-generated"] + - ["jenkins.model.identity", "IdentityRootAction", "getPublicKey", "()", "summary", "df-generated"] + - ["jenkins.model.identity", "InstanceIdentityProvider$KeyTypes", "getCertificate", "()", "summary", "df-generated"] + - ["jenkins.model.identity", "InstanceIdentityProvider$KeyTypes", "getKeyPair", "()", "summary", "df-generated"] + - ["jenkins.model.identity", "InstanceIdentityProvider$KeyTypes", "getPrivateKey", "()", "summary", "df-generated"] + - ["jenkins.model.identity", "InstanceIdentityProvider$KeyTypes", "getPrivateKeyClass", "()", "summary", "df-generated"] + - ["jenkins.model.identity", "InstanceIdentityProvider$KeyTypes", "getPublicKey", "()", "summary", "df-generated"] + - ["jenkins.model.identity", "InstanceIdentityProvider$KeyTypes", "getPublicKeyClass", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Category", "getMinToShow", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Category", "getOrder", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "ItemCategory", "getCategory", "(TopLevelItemDescriptor)", "summary", "df-generated"] + - ["jenkins.model.item_category", "ItemCategory", "getDescription", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "ItemCategory", "getDisplayName", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "ItemCategory", "getId", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "ItemCategory", "getMinToShow", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "ItemCategory", "getOrder", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "NestedProjects_Description", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "NestedProjects_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "StandaloneProjects_Description", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "StandaloneProjects_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "Uncategorized_Description", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "Uncategorized_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "_NestedProjects_Description", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "_NestedProjects_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "_StandaloneProjects_Description", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "_StandaloneProjects_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "_Uncategorized_Description", "()", "summary", "df-generated"] + - ["jenkins.model.item_category", "Messages", "_Uncategorized_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "baseDirInitialized", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "get", "(int)", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "getById", "(String)", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "getByNumber", "(int)", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "maxNumberOnDisk", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "newestBuild", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "oldestBuild", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "purgeCache", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "removeValue", "(Object)", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "reset", "(TreeMap)", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "runExists", "(int)", "summary", "df-generated"] + - ["jenkins.model.lazy", "AbstractLazyLoadRunMap", "search", "(int,Direction)", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn$RunMixIn", "dropLinks", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "getBuild", "(String)", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "getBuildByNumber", "(int)", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "getFirstBuild", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "getLastBuild", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "getNearestBuild", "(int)", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "getNearestOldBuild", "(int)", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "loadBuild", "(File)", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "newBuild", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "onCreatedFromScratch", "()", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "onLoad", "(ItemGroup,String)", "summary", "df-generated"] + - ["jenkins.model.lazy", "LazyBuildMixIn", "removeRun", "(Run)", "summary", "df-generated"] + - ["jenkins.model.queue", "AsynchronousExecution", "blocksRestart", "()", "summary", "df-generated"] + - ["jenkins.model.queue", "AsynchronousExecution", "displayCell", "()", "summary", "df-generated"] + - ["jenkins.model.queue", "AsynchronousExecution", "interrupt", "(boolean)", "summary", "df-generated"] + - ["jenkins.model.queue", "AsynchronousExecution", "maybeComplete", "()", "summary", "df-generated"] + - ["jenkins.model.queue", "ItemDeletion", "contains", "(Item)", "summary", "df-generated"] + - ["jenkins.model.queue", "ItemDeletion", "deregister", "(Item)", "summary", "df-generated"] + - ["jenkins.model.queue", "ItemDeletion", "isRegistered", "(Item)", "summary", "df-generated"] + - ["jenkins.model.queue", "ItemDeletion", "register", "(Item)", "summary", "df-generated"] + - ["jenkins.model", "ArtifactManager", "archive", "(FilePath,Launcher,BuildListener,Map)", "summary", "df-generated"] + - ["jenkins.model", "ArtifactManager", "delete", "()", "summary", "df-generated"] + - ["jenkins.model", "ArtifactManager", "onLoad", "(Run)", "summary", "df-generated"] + - ["jenkins.model", "ArtifactManager", "root", "()", "summary", "df-generated"] + - ["jenkins.model", "ArtifactManagerConfiguration", "get", "()", "summary", "df-generated"] + - ["jenkins.model", "ArtifactManagerFactory", "managerFor", "(Run)", "summary", "df-generated"] + - ["jenkins.model", "ArtifactManagerFactoryDescriptor", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "AssetManager", "doDynamic", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "BackgroundGlobalBuildDiscarder", "processJob", "(TaskListener,Job)", "summary", "df-generated"] + - ["jenkins.model", "BuildDiscarder", "perform", "(Job)", "summary", "df-generated"] + - ["jenkins.model", "BuildDiscarderDescriptor", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "BuiltInNodeMigration", "doAct", "(StaplerRequest,StaplerResponse,String,String)", "summary", "df-generated"] + - ["jenkins.model", "CauseOfInterruption", "getShortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "CauseOfInterruption", "print", "(TaskListener)", "summary", "df-generated"] + - ["jenkins.model", "Configuration", "getBooleanConfigParameter", "(String,boolean)", "summary", "df-generated"] + - ["jenkins.model", "DependencyDeclarer", "buildDependencyGraph", "(AbstractProject,DependencyGraph)", "summary", "df-generated"] + - ["jenkins.model", "DirectlyModifiableTopLevelItemGroup", "canAdd", "(TopLevelItem)", "summary", "df-generated"] + - ["jenkins.model", "DirectlyModifiableTopLevelItemGroup", "remove", "(TopLevelItem)", "summary", "df-generated"] + - ["jenkins.model", "FingerprintFacet", "createActions", "(List)", "summary", "df-generated"] + - ["jenkins.model", "FingerprintFacet", "getTimestamp", "()", "summary", "df-generated"] + - ["jenkins.model", "FingerprintFacet", "isFingerprintDeletionBlocked", "()", "summary", "df-generated"] + - ["jenkins.model", "GlobalBuildDiscarderConfiguration", "get", "()", "summary", "df-generated"] + - ["jenkins.model", "GlobalBuildDiscarderStrategy", "apply", "(Job)", "summary", "df-generated"] + - ["jenkins.model", "GlobalBuildDiscarderStrategy", "apply", "(Run)", "summary", "df-generated"] + - ["jenkins.model", "GlobalBuildDiscarderStrategy", "isApplicable", "(Job)", "summary", "df-generated"] + - ["jenkins.model", "GlobalBuildDiscarderStrategyDescriptor", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "GlobalCloudConfiguration", "doConfigure", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "GlobalConfiguration", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "GlobalConfigurationCategory", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "GlobalConfigurationCategory", "get", "(Class)", "summary", "df-generated"] + - ["jenkins.model", "GlobalConfigurationCategory", "getShortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "GlobalQuietPeriodConfiguration", "getQuietPeriod", "()", "summary", "df-generated"] + - ["jenkins.model", "GlobalSCMRetryCountConfiguration", "getScmCheckoutRetryCount", "()", "summary", "df-generated"] + - ["jenkins.model", "IdStrategy", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "IdStrategy", "equals", "(String,String)", "summary", "df-generated"] + - ["jenkins.model", "IdStrategy", "filenameOf", "(String)", "summary", "df-generated"] + - ["jenkins.model", "IdStrategy", "legacyFilenameOf", "(String)", "summary", "df-generated"] + - ["jenkins.model", "IdStrategy", "toString", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins$DescriptorImpl", "doCheckNumExecutors", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins$DescriptorImpl", "getDynamic", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins$EnforceSlaveAgentPortAdministrativeMonitor", "doAct", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins$EnforceSlaveAgentPortAdministrativeMonitor", "getExpectedPort", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins$EnforceSlaveAgentPortAdministrativeMonitor", "getSystemPropertyName", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins$JenkinsHolder", "getInstance", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "_doScript", "(StaplerRequest,StaplerResponse,RequestDispatcher,VirtualChannel,ACL)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "addNode", "(Node)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "checkGoodName", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "cleanUp", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "copy", "(AbstractProject,String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "createProject", "(Class,String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "disableSecurity", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doCancelQuietDown", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doCheckDisplayName", "(String,String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doCheckURIEncoding", "(StaplerRequest)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doCheckViewName", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doClassicThreadDump", "(StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doConfigExecutorsSubmit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doConfigSubmit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doCreateView", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doDefaultJDKCheck", "(StaplerRequest,String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doDoFingerprintCheck", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doEval", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doException", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doExit", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doFingerprintCleanup", "(StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doGc", "(StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doIconSize", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doLoginEntry", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doLogout", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doQuietDown", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doQuietDown", "(boolean,int)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doReload", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doResources", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doRestart", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doSafeExit", "(StaplerRequest)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doSafeRestart", "(StaplerRequest)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doScript", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doScriptText", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doSecured", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doSignup", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doSimulateOutOfMemory", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doSubmitDescription", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doTestPost", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doToggleCollapse", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doViewExistsCheck", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "doWorkspaceCleanup", "(StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "get", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getActiveInstance", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getAuthentication2", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getAuthentication", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getBuildWrapper", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getBuilder", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getCategorizedManagementLinks", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getComputer", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getConfiguredRootUrl", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getDescriptor", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getDescriptorByType", "(Class)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getFederatedLoginService", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getFederatedLoginServices", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getInitLevel", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getInjector", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getInstallState", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getInstance", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getInstanceOrNull", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getItem", "(String,Item,Class)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getItem", "(String,ItemGroup,Class)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getItemByFullName", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getItemByFullName", "(String,Class)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getItems", "(Class)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getJobNames", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getJobProperty", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getLegacyInstanceId", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getLifecycle", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getManagementLinks", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getMe", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getPlugin", "(Class)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getPlugin", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getPlugins", "(Class)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getProjects", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getPublisher", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getQuietPeriod", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getRepositoryBrowser", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getRetentionStrategy", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getRootUrl", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getRootUrlFromRequest", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getScm", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getScmCheckoutRetryCount", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getSecretKeyAsAES128", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getSecurity", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getSecurityRealms", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getSlaveAgentPort", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getStoredVersion", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getTrigger", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getUnprotectedRootActions", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "getVersion", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "hasPeople", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isCheckURIEncodingEnabled", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isDefaultBuildDir", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isDisableRememberMe", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isNoUsageStatistics", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isQuietingDown", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isRootUrlSecure", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isSlaveAgentPortEnforced", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isSubjectToMandatoryReadPermissionCheck", "(String)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isTerminating", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isUpgradedFromBefore", "(VersionNumber)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isUsageStatisticsCollected", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isUseCrumbs", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isUseProjectNamingStrategy", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "isUseSecurity", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "lookup", "(Class)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "rebuildDependencyGraph", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "refreshExtensions", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "reload", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "removeNode", "(Node)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "restart", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "safeRestart", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setAgentProtocols", "(Set)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setDisableRememberMe", "(boolean)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setMode", "(Mode)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setNoUsageStatistics", "(Boolean)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setNodes", "(List)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setNumExecutors", "(int)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setQuietPeriod", "(Integer)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setScmCheckoutRetryCount", "(int)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setSlaveAgentPort", "(int)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "setViews", "(Collection)", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "shouldShowStackTrace", "()", "summary", "df-generated"] + - ["jenkins.model", "Jenkins", "updateNode", "(Node)", "summary", "df-generated"] + - ["jenkins.model", "JenkinsLocationConfiguration", "doCheckAdminAddress", "(String)", "summary", "df-generated"] + - ["jenkins.model", "JenkinsLocationConfiguration", "doCheckUrl", "(String)", "summary", "df-generated"] + - ["jenkins.model", "JenkinsLocationConfiguration", "get", "()", "summary", "df-generated"] + - ["jenkins.model", "JenkinsLocationConfiguration", "getOrDie", "()", "summary", "df-generated"] + - ["jenkins.model", "MasterBuildConfiguration", "getLabelString", "()", "summary", "df-generated"] + - ["jenkins.model", "MasterBuildConfiguration", "getNumExecutors", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "BlockedBecauseOfBuildInProgress_ETA", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "BlockedBecauseOfBuildInProgress_shortDescription", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "BuildDiscarderProperty_displayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "BuiltInNodeMigration_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "CLI_disable_job_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "CLI_enable_job_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "CLI_keep_build_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "CLI_restart_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "CLI_safe_restart_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "CLI_safe_shutdown_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "CLI_shutdown_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "CauseOfInterruption_ShortDescription", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "DefaultProjectNamingStrategy_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "EnforceSlaveAgentPortAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "GlobalCloudConfiguration_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_BadPortNumber", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_Computer_Caption", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_Computer_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_Computer_IncorrectNumberOfExecutors", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_ControlCodeNotAllowed", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_JobAlreadyExists", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_JobNameConventionNotApplyed", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_NoJavaInPath", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_NoName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_NodeBeingRemoved", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_NodeDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_NotUsesUTF8ToDecodeURL", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_UnsafeChar", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_ViewAlreadyExists", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Hudson_ViewName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "IdStrategy_CaseInsensitive_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "IdStrategy_CaseSensitiveEmailAddress_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "IdStrategy_CaseSensitive_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "JenkinsLocationConfiguration_does_not_look_like_an_email_address", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "JobGlobalBuildDiscarderStrategy_displayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Mailer_Address_Not_Configured", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Mailer_Localhost_Error", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "Mailer_NotHttp_Error", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "ParameterizedJobMixIn_build_now", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "ParameterizedJobMixIn_build_with_parameters", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "PatternProjectNamingStrategy_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "PatternProjectNamingStrategy_NamePatternInvalidSyntax", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "PatternProjectNamingStrategy_NamePatternRequired", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "SimpleGlobalBuildDiscarderStrategy_displayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_BlockedBecauseOfBuildInProgress_ETA", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_BlockedBecauseOfBuildInProgress_shortDescription", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_BuildDiscarderProperty_displayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_BuiltInNodeMigration_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_CLI_disable_job_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_CLI_enable_job_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_CLI_keep_build_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_CLI_restart_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_CLI_safe_restart_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_CLI_safe_shutdown_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_CLI_shutdown_shortDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_CauseOfInterruption_ShortDescription", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_DefaultProjectNamingStrategy_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_EnforceSlaveAgentPortAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_GlobalCloudConfiguration_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_BadPortNumber", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_Computer_Caption", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_Computer_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_Computer_IncorrectNumberOfExecutors", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_ControlCodeNotAllowed", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_JobAlreadyExists", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_JobNameConventionNotApplyed", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_NoJavaInPath", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_NoName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_NodeBeingRemoved", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_NodeDescription", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_NotUsesUTF8ToDecodeURL", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_UnsafeChar", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_ViewAlreadyExists", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Hudson_ViewName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_IdStrategy_CaseInsensitive_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_IdStrategy_CaseSensitiveEmailAddress_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_IdStrategy_CaseSensitive_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_JenkinsLocationConfiguration_does_not_look_like_an_email_address", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_JobGlobalBuildDiscarderStrategy_displayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Mailer_Address_Not_Configured", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Mailer_Localhost_Error", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_Mailer_NotHttp_Error", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_ParameterizedJobMixIn_build_now", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_ParameterizedJobMixIn_build_with_parameters", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_PatternProjectNamingStrategy_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_PatternProjectNamingStrategy_NamePatternInvalidSyntax", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_PatternProjectNamingStrategy_NamePatternRequired", "()", "summary", "df-generated"] + - ["jenkins.model", "Messages", "_SimpleGlobalBuildDiscarderStrategy_displayName", "()", "summary", "df-generated"] + - ["jenkins.model", "ModelObjectWithChildren", "doChildrenContextMenu", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "ModelObjectWithContextMenu", "doContextMenu", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "ModifiableTopLevelItemGroup", "copy", "(TopLevelItem,String)", "summary", "df-generated"] + - ["jenkins.model", "ModifiableTopLevelItemGroup", "createProjectFromXML", "(String,InputStream)", "summary", "df-generated"] + - ["jenkins.model", "NodeListener", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "NodeListener", "fireOnCreated", "(Node)", "summary", "df-generated"] + - ["jenkins.model", "NodeListener", "fireOnDeleted", "(Node)", "summary", "df-generated"] + - ["jenkins.model", "NodeListener", "fireOnUpdated", "(Node,Node)", "summary", "df-generated"] + - ["jenkins.model", "Nodes", "isLegacy", "()", "summary", "df-generated"] + - ["jenkins.model", "Nodes", "load", "()", "summary", "df-generated"] + - ["jenkins.model", "Nodes", "removeNode", "(Node)", "summary", "df-generated"] + - ["jenkins.model", "Nodes", "replaceNode", "(Node,Node)", "summary", "df-generated"] + - ["jenkins.model", "Nodes", "setNodes", "(Collection)", "summary", "df-generated"] + - ["jenkins.model", "Nodes", "updateNode", "(Node)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "doBuild", "(StaplerRequest,StaplerResponse,TimeDuration)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "doBuildWithParameters", "(StaplerRequest,StaplerResponse,TimeDuration)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "doCancelQueue", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "doDisable", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "doEnable", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "doPolling", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "getBuildNowText", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "getParameterizedJobMixIn", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "getQuietPeriod", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "isBuildable", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "isDisabled", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "isParameterized", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "makeDisabled", "(boolean)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "resolveForCLI", "(String)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "scheduleBuild2", "(int,Action[])", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "setDisabled", "(boolean)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn$ParameterizedJob", "supportsMakeDisabled", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "doBuild", "(StaplerRequest,StaplerResponse,TimeDuration)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "doBuildWithParameters", "(StaplerRequest,StaplerResponse,TimeDuration)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "doCancelQueue", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "getBuildCause", "(ParameterizedJob,StaplerRequest)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "getBuildNowText", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "getTrigger", "(Job,Class)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "isParameterized", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "scheduleBuild2", "(int,Action[])", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "scheduleBuild", "()", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "scheduleBuild", "(Cause)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "scheduleBuild", "(int)", "summary", "df-generated"] + - ["jenkins.model", "ParameterizedJobMixIn", "scheduleBuild", "(int,Cause)", "summary", "df-generated"] + - ["jenkins.model", "PeepholePermalink", "apply", "(Run)", "summary", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy$PatternProjectNamingStrategy$DescriptorImpl", "doCheckNamePattern", "(String)", "summary", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy", "checkName", "(String)", "summary", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy", "checkName", "(String,String)", "summary", "df-generated"] + - ["jenkins.model", "ProjectNamingStrategy", "isForceExistingJobs", "()", "summary", "df-generated"] + - ["jenkins.model", "RunAction2", "onAttached", "(Run)", "summary", "df-generated"] + - ["jenkins.model", "RunAction2", "onLoad", "(Run)", "summary", "df-generated"] + - ["jenkins.model", "RunIdMigrator$UnmigrationInstruction", "getCommand", "()", "summary", "df-generated"] + - ["jenkins.model", "RunIdMigrator", "created", "(File)", "summary", "df-generated"] + - ["jenkins.model", "RunIdMigrator", "delete", "(File,String)", "summary", "df-generated"] + - ["jenkins.model", "RunIdMigrator", "findNumber", "(String)", "summary", "df-generated"] + - ["jenkins.model", "RunIdMigrator", "migrate", "(File,File)", "summary", "df-generated"] + - ["jenkins.model", "SimplePageDecorator", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "SimplePageDecorator", "first", "()", "summary", "df-generated"] + - ["jenkins.model", "SimplePageDecorator", "getUrl", "()", "summary", "df-generated"] + - ["jenkins.model", "TransientActionFactory", "actionType", "()", "summary", "df-generated"] + - ["jenkins.model", "TransientActionFactory", "createFor", "(Object)", "summary", "df-generated"] + - ["jenkins.model", "TransientActionFactory", "factoriesFor", "(Class,Class)", "summary", "df-generated"] + - ["jenkins.model", "TransientActionFactory", "type", "()", "summary", "df-generated"] + - ["jenkins.model", "TransientFingerprintFacetFactory", "all", "()", "summary", "df-generated"] + - ["jenkins.model", "TransientFingerprintFacetFactory", "createFor", "(Fingerprint,List)", "summary", "df-generated"] + - ["jenkins.model", "Uptime", "getStartTime", "()", "summary", "df-generated"] + - ["jenkins.model", "Uptime", "getUptime", "()", "summary", "df-generated"] + - ["jenkins.model", "Uptime", "init", "()", "summary", "df-generated"] + - ["jenkins.monitor", "JavaVersionRecommendationAdminMonitor", "doAct", "(String)", "summary", "df-generated"] + - ["jenkins.monitor", "Messages", "JavaLevelAdminMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.monitor", "Messages", "_JavaLevelAdminMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "GlobalMavenConfig", "get", "()", "summary", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProvider", "parseSettingsProvider", "(StaplerRequest)", "summary", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProvider", "supplySettings", "(AbstractBuild,TaskListener)", "summary", "df-generated"] + - ["jenkins.mvn", "GlobalSettingsProviderDescriptor", "all", "()", "summary", "df-generated"] + - ["jenkins.mvn", "Messages", "DefaultGlobalSettingsProvider_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "Messages", "DefaultSettingsProvider_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "Messages", "FilePathGlobalSettingsProvider_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "Messages", "FilePathSettingsProvider_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "Messages", "_DefaultGlobalSettingsProvider_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "Messages", "_DefaultSettingsProvider_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "Messages", "_FilePathGlobalSettingsProvider_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "Messages", "_FilePathSettingsProvider_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.mvn", "SettingsProvider", "parseSettingsProvider", "(StaplerRequest)", "summary", "df-generated"] + - ["jenkins.mvn", "SettingsProvider", "supplySettings", "(AbstractBuild,TaskListener)", "summary", "df-generated"] + - ["jenkins.mvn", "SettingsProviderDescriptor", "all", "()", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "getInstance", "()", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "getInstance", "(boolean)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "getTLDEntries", "(ArrayType)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "isAllowLocal", "()", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "isValid", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "isValidCountryCodeTld", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "isValidGenericTld", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "isValidInfrastructureTld", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "isValidLocalTld", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "isValidTld", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "unicodeToASCII", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "DomainValidator", "updateTLDOverride", "(ArrayType,String[])", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "InetAddressValidator", "getInstance", "()", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "InetAddressValidator", "isValid", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "InetAddressValidator", "isValidInet4Address", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "InetAddressValidator", "isValidInet6Address", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "RegexValidator", "RegexValidator", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "RegexValidator", "RegexValidator", "(String,boolean)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "RegexValidator", "RegexValidator", "(String[])", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "RegexValidator", "RegexValidator", "(String[],boolean)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "RegexValidator", "isValid", "(String)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "RegexValidator", "toString", "()", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", "UrlValidator", "(long)", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", "getInstance", "()", "summary", "df-generated"] + - ["jenkins.org.apache.commons.validator.routines", "UrlValidator", "isValid", "(String)", "summary", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil$DetachedPlugin", "getRequiredVersion", "()", "summary", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil", "getDetachedPlugins", "()", "summary", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil", "getDetachedPlugins", "(VersionNumber)", "summary", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil", "getImpliedDependencies", "(String,String)", "summary", "df-generated"] + - ["jenkins.plugins", "DetachedPluginsUtil", "isDetachedPlugin", "(String)", "summary", "df-generated"] + - ["jenkins.scm", "RunWithSCM", "calculateCulprits", "()", "summary", "df-generated"] + - ["jenkins.scm", "RunWithSCM", "getCulprits", "()", "summary", "df-generated"] + - ["jenkins.scm", "RunWithSCM", "hasParticipant", "(User)", "summary", "df-generated"] + - ["jenkins.scm", "SCMCheckoutStrategy", "checkout", "(AbstractBuildExecution)", "summary", "df-generated"] + - ["jenkins.scm", "SCMCheckoutStrategy", "preCheckout", "(AbstractBuild,Launcher,BuildListener)", "summary", "df-generated"] + - ["jenkins.scm", "SCMCheckoutStrategyDescriptor", "_for", "(AbstractProject)", "summary", "df-generated"] + - ["jenkins.scm", "SCMCheckoutStrategyDescriptor", "all", "()", "summary", "df-generated"] + - ["jenkins.scm", "SCMCheckoutStrategyDescriptor", "isApplicable", "(AbstractProject)", "summary", "df-generated"] + - ["jenkins.scm", "SCMDecisionHandler", "all", "()", "summary", "df-generated"] + - ["jenkins.scm", "SCMDecisionHandler", "firstShouldPollVeto", "(Item)", "summary", "df-generated"] + - ["jenkins.scm", "SCMDecisionHandler", "listShouldPollVetos", "(Item)", "summary", "df-generated"] + - ["jenkins.scm", "SCMDecisionHandler", "shouldPoll", "(Item)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyConfiguration", "get", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyConfiguration", "hasExistingConfigFile", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyConfiguration", "isCreationOfLegacyTokenEnabled", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyConfiguration", "isTokenGenerationOnCreationEnabled", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyConfiguration", "isUsageStatisticsEnabled", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyConfiguration", "setCreationOfLegacyTokenEnabled", "(boolean)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyConfiguration", "setTokenGenerationOnCreationEnabled", "(boolean)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyConfiguration", "setUsageStatisticsEnabled", "(boolean)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyDisabledDefaultAdministrativeMonitor", "doAct", "(String)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor", "doAct", "(String)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats$SingleTokenStats", "getNumDaysUse", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats$SingleTokenStats", "getUseCounter", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", "removeAll", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", "removeAllExcept", "(String)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStats", "removeId", "(String)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", "getNumDaysCreation", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", "isLegacy", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore$HashedToken", "match", "(byte[])", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", "addFixedNewToken", "(String,String)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", "generateNewToken", "(String)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", "reconfigure", "(Map)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", "regenerateTokenFromLegacy", "(Secret)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", "regenerateTokenFromLegacyIfRequired", "(Secret)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", "renameToken", "(String,String)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", "revokeAllTokens", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "ApiTokenStore", "revokeAllTokensExcept", "(String)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "LegacyApiTokenAdministrativeMonitor", "doIndex", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "LegacyApiTokenAdministrativeMonitor", "doRevokeAllSelected", "(RevokeAllSelectedModel)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "LegacyApiTokenAdministrativeMonitor", "getImpactedUserList", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "LegacyApiTokenAdministrativeMonitor", "getLegacyTokenOf", "(User)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "LegacyApiTokenAdministrativeMonitor", "hasFreshToken", "(User,TokenInfoAndStats)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "LegacyApiTokenAdministrativeMonitor", "hasMoreRecentlyUsedToken", "(User,TokenInfoAndStats)", "summary", "df-generated"] + - ["jenkins.security.apitoken", "Messages", "ApiTokenPropertyDisabledDefaultAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "Messages", "ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "Messages", "LegacyApiTokenAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "Messages", "_ApiTokenPropertyDisabledDefaultAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "Messages", "_ApiTokenPropertyEnabledNewLegacyAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.security.apitoken", "Messages", "_LegacyApiTokenAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.security.csrf", "Messages", "CSRFAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.security.csrf", "Messages", "_CSRFAdministrativeMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.security.s2m", "AdminWhitelistRule", "getMasterKillSwitch", "()", "summary", "df-generated"] + - ["jenkins.security.s2m", "AdminWhitelistRule", "setMasterKillSwitch", "(boolean)", "summary", "df-generated"] + - ["jenkins.security.seed", "Messages", "UserSeedProperty_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security.seed", "Messages", "_UserSeedProperty_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security.seed", "UserSeedChangeListener", "fireUserSeedRenewed", "(User)", "summary", "df-generated"] + - ["jenkins.security.seed", "UserSeedChangeListener", "onUserSeedRenewed", "(User)", "summary", "df-generated"] + - ["jenkins.security.seed", "UserSeedProperty$DescriptorImpl", "doRenewSessionSeed", "(User)", "summary", "df-generated"] + - ["jenkins.security.seed", "UserSeedProperty$DescriptorImpl", "isCurrentUser", "(User)", "summary", "df-generated"] + - ["jenkins.security.seed", "UserSeedProperty", "renewSeed", "()", "summary", "df-generated"] + - ["jenkins.security.stapler", "RoutingDecisionProvider", "decide", "(String)", "summary", "df-generated"] + - ["jenkins.security.stapler", "StaticRoutingDecisionProvider", "get", "()", "summary", "df-generated"] + - ["jenkins.security.stapler", "StaticRoutingDecisionProvider", "reload", "()", "summary", "df-generated"] + - ["jenkins.security.stapler", "TypedFilter", "isStaplerRelevant", "(Class)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "doAddFixedToken", "(User,String,String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "doChangeToken", "(User,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "doGenerateNewToken", "(User,String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "doRename", "(User,String,String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "doRevoke", "(User,String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "doRevokeAll", "(User)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "doRevokeAllExcept", "(User,String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "getNoLegacyToken", "()", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "hasCurrentUserRightToGenerateNewToken", "(User)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "isStatisticsEnabled", "()", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty$DescriptorImpl", "mustDisplayLegacyApiToken", "(User)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "addFixedNewToken", "(String,String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "changeApiToken", "()", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "deleteApiToken", "()", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "generateNewToken", "(String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "getApiToken", "()", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "getTokenList", "()", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "hasLegacyToken", "()", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "matchesPassword", "(String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "revokeAllTokens", "()", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "revokeAllTokensExceptOne", "(String)", "summary", "df-generated"] + - ["jenkins.security", "ApiTokenProperty", "revokeToken", "(String)", "summary", "df-generated"] + - ["jenkins.security", "BasicHeaderAuthenticator", "all", "()", "summary", "df-generated"] + - ["jenkins.security", "BasicHeaderAuthenticator", "authenticate2", "(HttpServletRequest,HttpServletResponse,String,String)", "summary", "df-generated"] + - ["jenkins.security", "BasicHeaderAuthenticator", "authenticate", "(HttpServletRequest,HttpServletResponse,String,String)", "summary", "df-generated"] + - ["jenkins.security", "ChannelConfigurator", "all", "()", "summary", "df-generated"] + - ["jenkins.security", "ChannelConfigurator", "onChannelBuilding", "(ChannelBuilder,Object)", "summary", "df-generated"] + - ["jenkins.security", "ClassFilterImpl", "register", "()", "summary", "df-generated"] + - ["jenkins.security", "ClassFilterImpl", "unregister", "()", "summary", "df-generated"] + - ["jenkins.security", "ConfidentialStore", "get", "()", "summary", "df-generated"] + - ["jenkins.security", "ConfidentialStore", "randomBytes", "(int)", "summary", "df-generated"] + - ["jenkins.security", "CryptoConfidentialKey", "decrypt", "()", "summary", "df-generated"] + - ["jenkins.security", "CryptoConfidentialKey", "decrypt", "(byte[])", "summary", "df-generated"] + - ["jenkins.security", "CryptoConfidentialKey", "encrypt", "()", "summary", "df-generated"] + - ["jenkins.security", "CryptoConfidentialKey", "encrypt", "(byte[])", "summary", "df-generated"] + - ["jenkins.security", "CryptoConfidentialKey", "newIv", "()", "summary", "df-generated"] + - ["jenkins.security", "CryptoConfidentialKey", "newIv", "(int)", "summary", "df-generated"] + - ["jenkins.security", "CustomClassFilter$Contributed", "load", "()", "summary", "df-generated"] + - ["jenkins.security", "CustomClassFilter", "permits", "(Class)", "summary", "df-generated"] + - ["jenkins.security", "CustomClassFilter", "permits", "(String)", "summary", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", "checkMac", "(String,String)", "summary", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", "checkMac", "(byte[],byte[])", "summary", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", "createMac", "()", "summary", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", "mac", "(String)", "summary", "df-generated"] + - ["jenkins.security", "HMACConfidentialKey", "mac", "(byte[])", "summary", "df-generated"] + - ["jenkins.security", "LastGrantedAuthoritiesProperty", "getAuthorities2", "()", "summary", "df-generated"] + - ["jenkins.security", "LastGrantedAuthoritiesProperty", "getAuthorities", "()", "summary", "df-generated"] + - ["jenkins.security", "LastGrantedAuthoritiesProperty", "invalidate", "()", "summary", "df-generated"] + - ["jenkins.security", "LastGrantedAuthoritiesProperty", "update", "(Authentication)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ApiTokenProperty_ChangeToken_CapabilityNotAllowed", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ApiTokenProperty_ChangeToken_Success", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ApiTokenProperty_ChangeToken_SuccessHidden", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ApiTokenProperty_ChangeToken_TokenIsHidden", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ApiTokenProperty_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ApiTokenProperty_LegacyTokenName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ApiTokenProperty_NoLegacyToken", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "RekeySecretAdminMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_Empty", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_Exception", "(Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_FailedIdentityCheck", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_IOException", "(Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_Invalid", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_InvalidRootURL", "(Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_NeedsRootURL", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_NotJenkins", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_OtherJenkins", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_ResourceResponse", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_SameAsCurrent", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_SameAsJenkinsRoot", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_SomeJenkins", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "ResourceDomainConfiguration_ThisJenkins", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "Token_Created_on", "(Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "UpdateSiteWarningsMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ApiTokenProperty_ChangeToken_CapabilityNotAllowed", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ApiTokenProperty_ChangeToken_Success", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ApiTokenProperty_ChangeToken_SuccessHidden", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ApiTokenProperty_ChangeToken_TokenIsHidden", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ApiTokenProperty_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ApiTokenProperty_LegacyTokenName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ApiTokenProperty_NoLegacyToken", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_RekeySecretAdminMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_Empty", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_Exception", "(Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_FailedIdentityCheck", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_IOException", "(Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_Invalid", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_InvalidRootURL", "(Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_NeedsRootURL", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_NotJenkins", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_OtherJenkins", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_ResourceResponse", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_SameAsCurrent", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_SameAsJenkinsRoot", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_SomeJenkins", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_ResourceDomainConfiguration_ThisJenkins", "()", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_Token_Created_on", "(Object)", "summary", "df-generated"] + - ["jenkins.security", "Messages", "_UpdateSiteWarningsMonitor_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticator", "authenticate2", "(Item)", "summary", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticator", "authenticate2", "(Task)", "summary", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticator", "authenticate", "(Item)", "summary", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticator", "authenticate", "(Task)", "summary", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticatorConfiguration", "get", "()", "summary", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticatorDescriptor", "all", "()", "summary", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticatorProvider", "authenticators", "()", "summary", "df-generated"] + - ["jenkins.security", "QueueItemAuthenticatorProvider", "getAuthenticators", "()", "summary", "df-generated"] + - ["jenkins.security", "RSAConfidentialKey", "getEncodedPublicKey", "()", "summary", "df-generated"] + - ["jenkins.security", "RSADigitalSignatureConfidentialKey", "sign", "(String)", "summary", "df-generated"] + - ["jenkins.security", "RekeySecretAdminMonitor", "doScan", "(StaplerRequest)", "summary", "df-generated"] + - ["jenkins.security", "RekeySecretAdminMonitor", "isDone", "()", "summary", "df-generated"] + - ["jenkins.security", "RekeySecretAdminMonitor", "isScanOnBoot", "()", "summary", "df-generated"] + - ["jenkins.security", "RekeySecretAdminMonitor", "scanOnReboot", "()", "summary", "df-generated"] + - ["jenkins.security", "RekeySecretAdminMonitor", "setNeeded", "()", "summary", "df-generated"] + - ["jenkins.security", "ResourceDomainConfiguration", "doCheckUrl", "(String)", "summary", "df-generated"] + - ["jenkins.security", "ResourceDomainConfiguration", "get", "()", "summary", "df-generated"] + - ["jenkins.security", "ResourceDomainConfiguration", "isResourceDomainConfigured", "()", "summary", "df-generated"] + - ["jenkins.security", "ResourceDomainConfiguration", "isResourceRequest", "(HttpServletRequest)", "summary", "df-generated"] + - ["jenkins.security", "ResourceDomainFilter", "init", "()", "summary", "df-generated"] + - ["jenkins.security", "ResourceDomainRecommendation", "doAct", "(String,String)", "summary", "df-generated"] + - ["jenkins.security", "ResourceDomainRootAction", "doIndex", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.security", "ResourceDomainRootAction", "get", "()", "summary", "df-generated"] + - ["jenkins.security", "SecureRequester", "permit", "(StaplerRequest,Object)", "summary", "df-generated"] + - ["jenkins.security", "SecurityListener", "fireAuthenticated2", "(UserDetails)", "summary", "df-generated"] + - ["jenkins.security", "SecurityListener", "fireAuthenticated", "(UserDetails)", "summary", "df-generated"] + - ["jenkins.security", "SecurityListener", "fireFailedToAuthenticate", "(String)", "summary", "df-generated"] + - ["jenkins.security", "SecurityListener", "fireFailedToLogIn", "(String)", "summary", "df-generated"] + - ["jenkins.security", "SecurityListener", "fireLoggedIn", "(String)", "summary", "df-generated"] + - ["jenkins.security", "SecurityListener", "fireLoggedOut", "(String)", "summary", "df-generated"] + - ["jenkins.security", "SecurityListener", "fireUserCreated", "(String)", "summary", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsConfiguration", "getAllWarnings", "()", "summary", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsConfiguration", "getApplicableWarnings", "()", "summary", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsConfiguration", "getPlugin", "(Warning)", "summary", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsConfiguration", "isIgnored", "(Warning)", "summary", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsMonitor", "doForward", "(String,String)", "summary", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsMonitor", "getActiveCoreWarnings", "()", "summary", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsMonitor", "getActivePluginWarningsByPlugin", "()", "summary", "df-generated"] + - ["jenkins.security", "UpdateSiteWarningsMonitor", "hasApplicableHiddenWarnings", "()", "summary", "df-generated"] + - ["jenkins.security", "UserDetailsCache", "get", "()", "summary", "df-generated"] + - ["jenkins.security", "UserDetailsCache", "invalidate", "(String)", "summary", "df-generated"] + - ["jenkins.security", "UserDetailsCache", "invalidateAll", "()", "summary", "df-generated"] + - ["jenkins.slaves.restarter", "SlaveRestarter", "all", "()", "summary", "df-generated"] + - ["jenkins.slaves.restarter", "SlaveRestarter", "canWork", "()", "summary", "df-generated"] + - ["jenkins.slaves.restarter", "SlaveRestarter", "restart", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "Messages", "ClassLoaderStatisticsSlaveInfo_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "Messages", "EnvVarsSlaveInfo_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "Messages", "SystemPropertySlaveInfo_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "Messages", "ThreadDumpSlaveInfo_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "Messages", "_ClassLoaderStatisticsSlaveInfo_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "Messages", "_EnvVarsSlaveInfo_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "Messages", "_SystemPropertySlaveInfo_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "Messages", "_ThreadDumpSlaveInfo_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "SlaveSystemInfo", "all", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "SlaveSystemInfo", "getDisplayName", "()", "summary", "df-generated"] + - ["jenkins.slaves.systemInfo", "SlaveSystemInfo", "getRequiredPermission", "()", "summary", "df-generated"] + - ["jenkins.slaves", "IOHubProvider", "cleanUp", "()", "summary", "df-generated"] + - ["jenkins.slaves", "JnlpAgentReceiver", "all", "()", "summary", "df-generated"] + - ["jenkins.slaves", "JnlpAgentReceiver", "exists", "(String)", "summary", "df-generated"] + - ["jenkins.slaves", "JnlpAgentReceiver", "generateCookie", "()", "summary", "df-generated"] + - ["jenkins.slaves", "JnlpAgentReceiver", "owns", "(String)", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "DeprecatedAgentProtocolMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "JnlpSlaveAgentProtocol2_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "JnlpSlaveAgentProtocol3_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "JnlpSlaveAgentProtocol4_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "JnlpSlaveAgentProtocol_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "_DeprecatedAgentProtocolMonitor_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "_JnlpSlaveAgentProtocol2_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "_JnlpSlaveAgentProtocol3_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "_JnlpSlaveAgentProtocol4_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "Messages", "_JnlpSlaveAgentProtocol_displayName", "()", "summary", "df-generated"] + - ["jenkins.slaves", "NioChannelSelector", "cleanUp", "()", "summary", "df-generated"] + - ["jenkins.slaves", "PingFailureAnalyzer", "all", "()", "summary", "df-generated"] + - ["jenkins.slaves", "PingFailureAnalyzer", "onPingFailure", "(Channel,Throwable)", "summary", "df-generated"] + - ["jenkins.slaves", "RemotingVersionInfo", "getEmbeddedVersion", "()", "summary", "df-generated"] + - ["jenkins.slaves", "RemotingVersionInfo", "getMinimumSupportedVersion", "()", "summary", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", "getDisabledDefaults", "()", "summary", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", "getEnabledDefaults", "()", "summary", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", "isDisabled", "()", "summary", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", "isFailIfWorkDirIsMissing", "()", "summary", "df-generated"] + - ["jenkins.slaves", "RemotingWorkDirSettings", "isUseAgentRootDir", "()", "summary", "df-generated"] + - ["jenkins.slaves", "WorkspaceLocator", "all", "()", "summary", "df-generated"] + - ["jenkins.slaves", "WorkspaceLocator", "locate", "(TopLevelItem,Node)", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "RetainVariablesLocalRule_CharacteristicEnvVarsFormValidationOK", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "RetainVariablesLocalRule_CharacteristicEnvVarsFormValidationWarning", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "RetainVariablesLocalRule_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "RetainVariablesLocalRule_REMOVE_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "RetainVariablesLocalRule_RESET_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "RetainVariablesLocalRule_RemovalMessage", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "RetainVariablesLocalRule_ResetMessage", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "_RetainVariablesLocalRule_CharacteristicEnvVarsFormValidationOK", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "_RetainVariablesLocalRule_CharacteristicEnvVarsFormValidationWarning", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "_RetainVariablesLocalRule_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "_RetainVariablesLocalRule_REMOVE_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "_RetainVariablesLocalRule_RESET_DisplayName", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "_RetainVariablesLocalRule_RemovalMessage", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "Messages", "_RetainVariablesLocalRule_ResetMessage", "(Object,Object)", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "RetainVariablesLocalRule$DescriptorImpl", "doCheckRetainCharacteristicEnvVars", "(boolean)", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "RetainVariablesLocalRule$ProcessVariablesHandling", "getDisplayName", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "RetainVariablesLocalRule", "getProcessVariablesHandling", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "RetainVariablesLocalRule", "isRetainCharacteristicEnvVars", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "RetainVariablesLocalRule", "setProcessVariablesHandling", "(ProcessVariablesHandling)", "summary", "df-generated"] + - ["jenkins.tasks.filters.impl", "RetainVariablesLocalRule", "setRetainCharacteristicEnvVars", "(boolean)", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterGlobalConfiguration", "get", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterGlobalConfiguration", "getAllActivatedGlobalRules", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterGlobalConfiguration", "getAllGlobalRules", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterLocalRuleDescriptor", "allApplicableFor", "(Class)", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterLocalRuleDescriptor", "isApplicable", "(Class)", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRule", "filter", "(EnvVars,EnvVarsFilterRuleContext)", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRule", "getDisplayName", "()", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterRuleWrapper", "filter", "(EnvVars,Launcher,TaskListener)", "summary", "df-generated"] + - ["jenkins.tasks.filters", "EnvVarsFilterableBuilder", "buildEnvVarsFilterRules", "()", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildStep", "perform", "(Run,EnvVars,TaskListener)", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildStep", "perform", "(Run,FilePath,EnvVars,Launcher,TaskListener)", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildStep", "perform", "(Run,FilePath,Launcher,TaskListener)", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildStep", "requiresWorkspace", "()", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper$Disposer", "requiresWorkspace", "()", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper$Disposer", "tearDown", "(Run,FilePath,Launcher,TaskListener)", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper$Disposer", "tearDown", "(Run,TaskListener)", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper", "createContext", "()", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper", "createLoggerDecorator", "(Run)", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper", "requiresWorkspace", "()", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper", "setUp", "(Context,Run,FilePath,Launcher,TaskListener,EnvVars)", "summary", "df-generated"] + - ["jenkins.tasks", "SimpleBuildWrapper", "setUp", "(Context,Run,TaskListener,EnvVars)", "summary", "df-generated"] + - ["jenkins.telemetry.impl", "UserLanguages", "setUpFilter", "()", "summary", "df-generated"] + - ["jenkins.telemetry", "Telemetry", "all", "()", "summary", "df-generated"] + - ["jenkins.telemetry", "Telemetry", "createContent", "()", "summary", "df-generated"] + - ["jenkins.telemetry", "Telemetry", "getDisplayName", "()", "summary", "df-generated"] + - ["jenkins.telemetry", "Telemetry", "getEnd", "()", "summary", "df-generated"] + - ["jenkins.telemetry", "Telemetry", "getId", "()", "summary", "df-generated"] + - ["jenkins.telemetry", "Telemetry", "getStart", "()", "summary", "df-generated"] + - ["jenkins.telemetry", "Telemetry", "isActivePeriod", "()", "summary", "df-generated"] + - ["jenkins.telemetry", "Telemetry", "isDisabled", "()", "summary", "df-generated"] + - ["jenkins.tools", "GlobalToolConfiguration", "doConfigure", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.triggers", "Messages", "ReverseBuildTrigger_build_after_other_projects_are_built", "()", "summary", "df-generated"] + - ["jenkins.triggers", "Messages", "ReverseBuildTrigger_running_as_cannot_even_see_for_trigger_f", "(Object,Object,Object)", "summary", "df-generated"] + - ["jenkins.triggers", "Messages", "SCMTriggerItem_PollingVetoed", "(Object)", "summary", "df-generated"] + - ["jenkins.triggers", "Messages", "_ReverseBuildTrigger_build_after_other_projects_are_built", "()", "summary", "df-generated"] + - ["jenkins.triggers", "Messages", "_ReverseBuildTrigger_running_as_cannot_even_see_for_trigger_f", "(Object,Object,Object)", "summary", "df-generated"] + - ["jenkins.triggers", "Messages", "_SCMTriggerItem_PollingVetoed", "(Object)", "summary", "df-generated"] + - ["jenkins.triggers", "ReverseBuildTrigger$DescriptorImpl", "doAutoCompleteUpstreamProjects", "(String,Item,ItemGroup)", "summary", "df-generated"] + - ["jenkins.triggers", "ReverseBuildTrigger$DescriptorImpl", "doCheckUpstreamProjects", "(Job,String)", "summary", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", "asItem", "()", "summary", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", "getNextBuildNumber", "()", "summary", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", "getQuietPeriod", "()", "summary", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", "getSCMTrigger", "()", "summary", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", "getSCMs", "()", "summary", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", "poll", "(TaskListener)", "summary", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", "scheduleBuild2", "(int,Action[])", "summary", "df-generated"] + - ["jenkins.triggers", "SCMTriggerItem", "schedulePolling", "()", "summary", "df-generated"] + - ["jenkins.util.groovy", "AbstractGroovyViewModule", "methodMissing", "(String,Object)", "summary", "df-generated"] + - ["jenkins.util.groovy", "AbstractGroovyViewModule", "propertyMissing", "(String)", "summary", "df-generated"] + - ["jenkins.util.groovy", "AbstractGroovyViewModule", "propertyMissing", "(String,Object)", "summary", "df-generated"] + - ["jenkins.util.groovy", "GroovyHookScript", "run", "()", "summary", "df-generated"] + - ["jenkins.util.io", "CompositeIOException", "asUncheckedIOException", "()", "summary", "df-generated"] + - ["jenkins.util.io", "FileBoolean", "fastGet", "()", "summary", "df-generated"] + - ["jenkins.util.io", "FileBoolean", "get", "()", "summary", "df-generated"] + - ["jenkins.util.io", "FileBoolean", "isOff", "()", "summary", "df-generated"] + - ["jenkins.util.io", "FileBoolean", "isOn", "()", "summary", "df-generated"] + - ["jenkins.util.io", "FileBoolean", "off", "()", "summary", "df-generated"] + - ["jenkins.util.io", "FileBoolean", "on", "()", "summary", "df-generated"] + - ["jenkins.util.io", "FileBoolean", "set", "(boolean)", "summary", "df-generated"] + - ["jenkins.util.io", "PathRemover$RetryStrategy", "shouldRetry", "(int)", "summary", "df-generated"] + - ["jenkins.util.io", "PathRemover", "forceRemoveDirectoryContents", "(Path)", "summary", "df-generated"] + - ["jenkins.util.io", "PathRemover", "forceRemoveFile", "(Path)", "summary", "df-generated"] + - ["jenkins.util.io", "PathRemover", "forceRemoveRecursive", "(Path)", "summary", "df-generated"] + - ["jenkins.util.io", "PathRemover", "newSimpleRemover", "()", "summary", "df-generated"] + - ["jenkins.util.java", "JavaUtils", "getCurrentJavaRuntimeVersionNumber", "()", "summary", "df-generated"] + - ["jenkins.util.java", "JavaUtils", "getCurrentRuntimeJavaVersion", "()", "summary", "df-generated"] + - ["jenkins.util.java", "JavaUtils", "isRunningWithJava8OrBelow", "()", "summary", "df-generated"] + - ["jenkins.util.java", "JavaUtils", "isRunningWithPostJava8", "()", "summary", "df-generated"] + - ["jenkins.util.xml", "XMLUtils", "getValue", "(String,Document)", "summary", "df-generated"] + - ["jenkins.util.xml", "XMLUtils", "getValue", "(String,File)", "summary", "df-generated"] + - ["jenkins.util.xml", "XMLUtils", "getValue", "(String,File,String)", "summary", "df-generated"] + - ["jenkins.util.xml", "XMLUtils", "parse", "(File)", "summary", "df-generated"] + - ["jenkins.util.xml", "XMLUtils", "parse", "(File,String)", "summary", "df-generated"] + - ["jenkins.util.xml", "XMLUtils", "parse", "(InputStream)", "summary", "df-generated"] + - ["jenkins.util.xml", "XMLUtils", "parse", "(Reader)", "summary", "df-generated"] + - ["jenkins.util.xml", "XMLUtils", "safeTransform", "(Source,Result)", "summary", "df-generated"] + - ["jenkins.util.xstream", "CriticalXStreamException", "CriticalXStreamException", "(XStreamException)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM$ConverterImpl", "unmarshalElement", "(HierarchicalStreamReader,UnmarshallingContext)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "from", "(HierarchicalStreamReader)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "from", "(InputStream)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "from", "(Reader)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "from", "(XStream,Object)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "getAttributeCount", "()", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "newReader", "()", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "newWriter", "()", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "unmarshal", "(XStream)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "unmarshal", "(XStream,Object)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "writeTo", "(HierarchicalStreamWriter)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "writeTo", "(OutputStream)", "summary", "df-generated"] + - ["jenkins.util.xstream", "XStreamDOM", "writeTo", "(Writer)", "summary", "df-generated"] + - ["jenkins.util", "AntClassLoader", "AntClassLoader", "(ClassLoader,Project,Path)", "summary", "df-generated"] + - ["jenkins.util", "AntClassLoader", "AntClassLoader", "(ClassLoader,Project,Path,boolean)", "summary", "df-generated"] + - ["jenkins.util", "AntClassLoader", "AntClassLoader", "(ClassLoader,boolean)", "summary", "df-generated"] + - ["jenkins.util", "AntClassLoader", "AntClassLoader", "(Project,Path)", "summary", "df-generated"] + - ["jenkins.util", "AntClassLoader", "AntClassLoader", "(Project,Path,boolean)", "summary", "df-generated"] + - ["jenkins.util", "AntClassLoader", "addPathFiles", "(Collection)", "summary", "df-generated"] + - ["jenkins.util", "DirectedGraph$SCC", "SCC", "(int)", "summary", "df-generated"] + - ["jenkins.util", "DirectedGraph", "getStronglyConnectedComponents", "()", "summary", "df-generated"] + - ["jenkins.util", "FullDuplexHttpService", "download", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.util", "FullDuplexHttpService", "upload", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["jenkins.util", "HttpSessionListener", "all", "()", "summary", "df-generated"] + - ["jenkins.util", "InterceptingExecutorService", "toString", "()", "summary", "df-generated"] + - ["jenkins.util", "JSONSignatureValidator", "verifySignature", "(JSONObject)", "summary", "df-generated"] + - ["jenkins.util", "JavaVMArguments", "current", "()", "summary", "df-generated"] + - ["jenkins.util", "JenkinsClassLoader", "findClass", "(String)", "summary", "df-generated"] + - ["jenkins.util", "JenkinsClassLoader", "findLoadedClass2", "(String)", "summary", "df-generated"] + - ["jenkins.util", "JenkinsClassLoader", "findResource", "(String)", "summary", "df-generated"] + - ["jenkins.util", "JenkinsClassLoader", "findResources", "(String)", "summary", "df-generated"] + - ["jenkins.util", "JenkinsClassLoader", "getClassLoadingLock", "(String)", "summary", "df-generated"] + - ["jenkins.util", "JenkinsJVM", "checkJenkinsJVM", "()", "summary", "df-generated"] + - ["jenkins.util", "JenkinsJVM", "checkNotJenkinsJVM", "()", "summary", "df-generated"] + - ["jenkins.util", "JenkinsJVM", "isJenkinsJVM", "()", "summary", "df-generated"] + - ["jenkins.util", "Listeners", "notify", "(Class,boolean,Consumer)", "summary", "df-generated"] + - ["jenkins.util", "MemoryReductionUtil", "getPresizedMutableMap", "(int)", "summary", "df-generated"] + - ["jenkins.util", "MemoryReductionUtil", "preallocatedHashmapCapacity", "(int)", "summary", "df-generated"] + - ["jenkins.util", "PluginLabelUtil", "canonicalLabels", "(JSONArray)", "summary", "df-generated"] + - ["jenkins.util", "ProgressiveRendering", "news", "()", "summary", "df-generated"] + - ["jenkins.util", "ProgressiveRendering", "start", "()", "summary", "df-generated"] + - ["jenkins.util", "ResourceBundleUtil", "getBundle", "(String)", "summary", "df-generated"] + - ["jenkins.util", "ResourceBundleUtil", "getBundle", "(String,Locale)", "summary", "df-generated"] + - ["jenkins.util", "ServerTcpPort", "ServerTcpPort", "(JSONObject)", "summary", "df-generated"] + - ["jenkins.util", "ServerTcpPort", "getPort", "()", "summary", "df-generated"] + - ["jenkins.util", "SetContextClassLoader", "SetContextClassLoader", "(Class)", "summary", "df-generated"] + - ["jenkins.util", "SetContextClassLoader", "SetContextClassLoader", "(ClassLoader)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "allowOnAgent", "(String)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getBoolean", "(String)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getBoolean", "(String,boolean)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getInteger", "(String)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getInteger", "(String,Integer)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getInteger", "(String,Integer,Level)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getLong", "(String)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getLong", "(String,Long)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getLong", "(String,Long,Level)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "getString", "(String)", "summary", "df-generated"] + - ["jenkins.util", "SystemProperties", "optBoolean", "(String)", "summary", "df-generated"] + - ["jenkins.util", "TimeDuration", "TimeDuration", "(long)", "summary", "df-generated"] + - ["jenkins.util", "TimeDuration", "as", "(TimeUnit)", "summary", "df-generated"] + - ["jenkins.util", "TimeDuration", "fromString", "(String)", "summary", "df-generated"] + - ["jenkins.util", "TimeDuration", "getTime", "()", "summary", "df-generated"] + - ["jenkins.util", "TimeDuration", "getTimeInMillis", "()", "summary", "df-generated"] + - ["jenkins.util", "TimeDuration", "getTimeInSeconds", "()", "summary", "df-generated"] + - ["jenkins.util", "Timer", "get", "()", "summary", "df-generated"] + - ["jenkins.util", "Timer", "shutdown", "()", "summary", "df-generated"] + - ["jenkins.util", "TreeString$ConverterImpl", "ConverterImpl", "(XStream)", "summary", "df-generated"] + - ["jenkins.util", "TreeString", "isBlank", "()", "summary", "df-generated"] + - ["jenkins.util", "TreeStringBuilder", "dedup", "()", "summary", "df-generated"] + - ["jenkins.util", "URLClassLoader2", "URLClassLoader2", "(URL[])", "summary", "df-generated"] + - ["jenkins.util", "URLClassLoader2", "URLClassLoader2", "(URL[],ClassLoader)", "summary", "df-generated"] + - ["jenkins.util", "UrlHelper", "isValidRootUrl", "(String)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "canRead", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "child", "(String)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "containsSymLinkChild", "(boolean)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "exists", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "getName", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "getParent", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "hasSymlink", "(boolean)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "isDescendant", "(String)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "isDirectory", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "isFile", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "lastModified", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "length", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "list", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "list", "(String,String,boolean)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "list", "(String,String,boolean,boolean)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "listOnlyDescendants", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "mode", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "open", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "open", "(boolean)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "readLink", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "run", "(Callable)", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "supportIsDescendant", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "supportsQuickRecursiveListing", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "toExternalURL", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "toString", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "toURI", "()", "summary", "df-generated"] + - ["jenkins.util", "VirtualFile", "zip", "(OutputStream,String,String,boolean,boolean,String)", "summary", "df-generated"] + - ["jenkins.views", "Header", "get", "()", "summary", "df-generated"] + - ["jenkins.views", "Header", "isAvailable", "()", "summary", "df-generated"] + - ["jenkins.views", "Header", "isCompatible", "()", "summary", "df-generated"] + - ["jenkins.views", "Header", "isEnabled", "()", "summary", "df-generated"] + - ["jenkins.views", "PartialHeader", "getSupportedHeaderVersion", "()", "summary", "df-generated"] + - ["jenkins.views", "PartialHeader", "incompatibleHeaders", "()", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Handler", "close", "()", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Handler", "sendBinary", "(ByteBuffer)", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Handler", "sendBinary", "(ByteBuffer,boolean)", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Handler", "sendPing", "(ByteBuffer)", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Handler", "sendText", "(String)", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Listener", "onWebSocketBinary", "(byte[],int,int)", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Listener", "onWebSocketClose", "(int,String)", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Listener", "onWebSocketError", "(Throwable)", "summary", "df-generated"] + - ["jenkins.websocket", "Provider$Listener", "onWebSocketText", "(String)", "summary", "df-generated"] + - ["jenkins.websocket", "Provider", "handle", "(HttpServletRequest,HttpServletResponse,Listener)", "summary", "df-generated"] + - ["jenkins.websocket", "WebSocketEcho", "doIndex", "()", "summary", "df-generated"] + - ["jenkins.websocket", "WebSockets", "isSupported", "()", "summary", "df-generated"] + - ["jenkins.websocket", "WebSockets", "upgrade", "(WebSocketSession)", "summary", "df-generated"] + - ["jenkins.widgets", "HistoryPageEntry", "getEntryId", "()", "summary", "df-generated"] + - ["jenkins.widgets", "HistoryPageFilter", "HistoryPageFilter", "(int)", "summary", "df-generated"] + - ["jenkins.widgets", "HistoryPageFilter", "add", "(Iterable)", "summary", "df-generated"] + - ["jenkins.widgets", "HistoryPageFilter", "add", "(Iterable,List)", "summary", "df-generated"] + - ["jenkins.widgets", "HistoryPageFilter", "setNewerThan", "(Long)", "summary", "df-generated"] + - ["jenkins.widgets", "HistoryPageFilter", "setOlderThan", "(Long)", "summary", "df-generated"] + - ["jenkins.widgets", "HistoryPageFilter", "size", "()", "summary", "df-generated"] + - ["jenkins", "AgentProtocol", "all", "()", "summary", "df-generated"] + - ["jenkins", "AgentProtocol", "getDisplayName", "()", "summary", "df-generated"] + - ["jenkins", "AgentProtocol", "getName", "()", "summary", "df-generated"] + - ["jenkins", "AgentProtocol", "handle", "(Socket)", "summary", "df-generated"] + - ["jenkins", "AgentProtocol", "isDeprecated", "()", "summary", "df-generated"] + - ["jenkins", "AgentProtocol", "isOptIn", "()", "summary", "df-generated"] + - ["jenkins", "AgentProtocol", "isRequired", "()", "summary", "df-generated"] + - ["jenkins", "AgentProtocol", "of", "(String)", "summary", "df-generated"] + - ["jenkins", "ClassLoaderReflectionToolkit", "_findResource", "(ClassLoader,String)", "summary", "df-generated"] + - ["jenkins", "ClassLoaderReflectionToolkit", "_findResources", "(ClassLoader,String)", "summary", "df-generated"] + - ["jenkins", "ClassLoaderReflectionToolkit", "loadClass", "(ClassLoader,String)", "summary", "df-generated"] + - ["jenkins", "ExtensionComponentSet", "allOf", "(ExtensionFinder)", "summary", "df-generated"] + - ["jenkins", "ExtensionComponentSet", "filtered", "()", "summary", "df-generated"] + - ["jenkins", "ExtensionComponentSet", "find", "(Class)", "summary", "df-generated"] + - ["jenkins", "ExtensionComponentSet", "union", "(Collection)", "summary", "df-generated"] + - ["jenkins", "ExtensionComponentSet", "union", "(ExtensionComponentSet[])", "summary", "df-generated"] + - ["jenkins", "ExtensionFilter", "all", "()", "summary", "df-generated"] + - ["jenkins", "ExtensionFilter", "allows", "(Class,ExtensionComponent)", "summary", "df-generated"] + - ["jenkins", "ExtensionFilter", "isAllowed", "(Class,ExtensionComponent)", "summary", "df-generated"] + - ["jenkins", "ExtensionRefreshException", "ExtensionRefreshException", "(String,Throwable)", "summary", "df-generated"] + - ["jenkins", "ExtensionRefreshException", "ExtensionRefreshException", "(Throwable)", "summary", "df-generated"] + - ["jenkins", "I18n", "doResourceBundle", "(StaplerRequest)", "summary", "df-generated"] + - ["jenkins", "InitReactorRunner", "getDisplayName", "(Task)", "summary", "df-generated"] + - ["jenkins", "InitReactorRunner", "run", "(Reactor)", "summary", "df-generated"] + - ["jenkins", "UserAgentURLConnectionDecorator", "getUserAgent", "()", "summary", "df-generated"] + - ["jenkins", "YesNoMaybe", "toBool", "()", "summary", "df-generated"] + - ["jenkins", "YesNoMaybe", "toBoolean", "(YesNoMaybe)", "summary", "df-generated"] + - ["org.acegisecurity.acls.sid", "GrantedAuthoritySid", "GrantedAuthoritySid", "(GrantedAuthority)", "summary", "df-generated"] + - ["org.acegisecurity.acls.sid", "PrincipalSid", "PrincipalSid", "(Authentication)", "summary", "df-generated"] + - ["org.acegisecurity.context", "SecurityContext", "fromSpring", "(SecurityContext)", "summary", "df-generated"] + - ["org.acegisecurity.context", "SecurityContext", "getAuthentication", "()", "summary", "df-generated"] + - ["org.acegisecurity.context", "SecurityContext", "setAuthentication", "(Authentication)", "summary", "df-generated"] + - ["org.acegisecurity.context", "SecurityContext", "toSpring", "()", "summary", "df-generated"] + - ["org.acegisecurity.context", "SecurityContextHolder", "clearContext", "()", "summary", "df-generated"] + - ["org.acegisecurity.context", "SecurityContextHolder", "getContext", "()", "summary", "df-generated"] + - ["org.acegisecurity.context", "SecurityContextHolder", "setContext", "(SecurityContext)", "summary", "df-generated"] + - ["org.acegisecurity.providers.anonymous", "AnonymousAuthenticationToken", "AnonymousAuthenticationToken", "(String,Object,GrantedAuthority[])", "summary", "df-generated"] + - ["org.acegisecurity.providers.anonymous", "AnonymousAuthenticationToken", "setDetails", "(Object)", "summary", "df-generated"] + - ["org.acegisecurity.providers.anonymous", "AnonymousAuthenticationToken", "toString", "()", "summary", "df-generated"] + - ["org.acegisecurity.providers", "AbstractAuthenticationToken", "toString", "()", "summary", "df-generated"] + - ["org.acegisecurity.providers", "AuthenticationProvider", "authenticate", "(Authentication)", "summary", "df-generated"] + - ["org.acegisecurity.providers", "AuthenticationProvider", "supports", "(Class)", "summary", "df-generated"] + - ["org.acegisecurity.providers", "ProviderNotFoundException", "ProviderNotFoundException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity.providers", "ProviderNotFoundException", "ProviderNotFoundException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity.providers", "ProviderNotFoundException", "fromSpring", "(ProviderNotFoundException)", "summary", "df-generated"] + - ["org.acegisecurity.providers", "UsernamePasswordAuthenticationToken", "UsernamePasswordAuthenticationToken", "(Object,Object)", "summary", "df-generated"] + - ["org.acegisecurity.providers", "UsernamePasswordAuthenticationToken", "UsernamePasswordAuthenticationToken", "(Object,Object,GrantedAuthority[])", "summary", "df-generated"] + - ["org.acegisecurity.providers", "UsernamePasswordAuthenticationToken", "setDetails", "(Object)", "summary", "df-generated"] + - ["org.acegisecurity.providers", "UsernamePasswordAuthenticationToken", "toString", "()", "summary", "df-generated"] + - ["org.acegisecurity.ui.rememberme", "RememberMeServices", "autoLogin", "(HttpServletRequest,HttpServletResponse)", "summary", "df-generated"] + - ["org.acegisecurity.ui.rememberme", "RememberMeServices", "loginFail", "(HttpServletRequest,HttpServletResponse)", "summary", "df-generated"] + - ["org.acegisecurity.ui.rememberme", "RememberMeServices", "loginSuccess", "(HttpServletRequest,HttpServletResponse,Authentication)", "summary", "df-generated"] + - ["org.acegisecurity.ui", "WebAuthenticationDetails", "WebAuthenticationDetails", "(HttpServletRequest)", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", "getAuthorities", "()", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", "getPassword", "()", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", "getUsername", "()", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", "isAccountNonExpired", "()", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", "isAccountNonLocked", "()", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", "isCredentialsNonExpired", "()", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetails", "isEnabled", "()", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetailsService", "fromSpring", "(UserDetailsService)", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UserDetailsService", "toSpring", "()", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UsernameNotFoundException", "UsernameNotFoundException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UsernameNotFoundException", "UsernameNotFoundException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity.userdetails", "UsernameNotFoundException", "fromSpring", "(UsernameNotFoundException)", "summary", "df-generated"] + - ["org.acegisecurity.util", "FieldUtils", "getProtectedFieldValue", "(String,Object)", "summary", "df-generated"] + - ["org.acegisecurity.util", "FieldUtils", "setProtectedFieldValue", "(String,Object,Object)", "summary", "df-generated"] + - ["org.acegisecurity", "AccessDeniedException", "AccessDeniedException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity", "AccessDeniedException", "AccessDeniedException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity", "AccountExpiredException", "AccountExpiredException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity", "AccountExpiredException", "AccountExpiredException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity", "AccountExpiredException", "fromSpring", "(AccountExpiredException)", "summary", "df-generated"] + - ["org.acegisecurity", "AcegiSecurityException", "toSpring", "()", "summary", "df-generated"] + - ["org.acegisecurity", "Authentication", "getAuthorities", "()", "summary", "df-generated"] + - ["org.acegisecurity", "Authentication", "getCredentials", "()", "summary", "df-generated"] + - ["org.acegisecurity", "Authentication", "getDetails", "()", "summary", "df-generated"] + - ["org.acegisecurity", "Authentication", "getPrincipal", "()", "summary", "df-generated"] + - ["org.acegisecurity", "Authentication", "isAuthenticated", "()", "summary", "df-generated"] + - ["org.acegisecurity", "Authentication", "setAuthenticated", "(boolean)", "summary", "df-generated"] + - ["org.acegisecurity", "AuthenticationException", "clearExtraInformation", "()", "summary", "df-generated"] + - ["org.acegisecurity", "AuthenticationManager", "fromSpring", "(AuthenticationManager)", "summary", "df-generated"] + - ["org.acegisecurity", "AuthenticationManager", "toSpring", "()", "summary", "df-generated"] + - ["org.acegisecurity", "AuthenticationServiceException", "AuthenticationServiceException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity", "AuthenticationServiceException", "AuthenticationServiceException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity", "AuthenticationServiceException", "fromSpring", "(AuthenticationServiceException)", "summary", "df-generated"] + - ["org.acegisecurity", "BadCredentialsException", "BadCredentialsException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity", "BadCredentialsException", "BadCredentialsException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity", "BadCredentialsException", "fromSpring", "(AuthenticationException)", "summary", "df-generated"] + - ["org.acegisecurity", "CredentialsExpiredException", "CredentialsExpiredException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity", "CredentialsExpiredException", "CredentialsExpiredException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity", "CredentialsExpiredException", "fromSpring", "(CredentialsExpiredException)", "summary", "df-generated"] + - ["org.acegisecurity", "DisabledException", "DisabledException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity", "DisabledException", "DisabledException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity", "DisabledException", "fromSpring", "(DisabledException)", "summary", "df-generated"] + - ["org.acegisecurity", "GrantedAuthority", "fromSpring", "(Collection)", "summary", "df-generated"] + - ["org.acegisecurity", "GrantedAuthority", "fromSpring", "(GrantedAuthority)", "summary", "df-generated"] + - ["org.acegisecurity", "GrantedAuthority", "toSpring", "()", "summary", "df-generated"] + - ["org.acegisecurity", "GrantedAuthority", "toSpring", "(GrantedAuthority[])", "summary", "df-generated"] + - ["org.acegisecurity", "InsufficientAuthenticationException", "InsufficientAuthenticationException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity", "InsufficientAuthenticationException", "InsufficientAuthenticationException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity", "InsufficientAuthenticationException", "fromSpring", "(InsufficientAuthenticationException)", "summary", "df-generated"] + - ["org.acegisecurity", "LockedException", "LockedException", "(String)", "summary", "df-generated"] + - ["org.acegisecurity", "LockedException", "LockedException", "(String,Throwable)", "summary", "df-generated"] + - ["org.acegisecurity", "LockedException", "fromSpring", "(LockedException)", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "BuildStatusIcon", "isBuildStatus", "()", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "BuildStatusIcon", "isInProgress", "()", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "Icon", "isSvgSprite", "()", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", "getSymbol", "(String,String,String,String,String,String,String)", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", "initPageVariables", "(JellyContext)", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", "toNormalizedIconNameClass", "(Object)", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", "toNormalizedIconSizeClass", "(Object)", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", "toNormalizedIconUrl", "(Object)", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", "tryTranslateTangoIconToSymbol", "(String)", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "IconSet", "tryTranslateTangoIconToSymbol", "(String,Supplier)", "summary", "df-generated"] + - ["org.jenkins.ui.icon", "IconSpec", "getIconClassName", "()", "summary", "df-generated"] + - ["org.jenkins.ui.symbol", "Symbol", "get", "(SymbolRequest)", "summary", "df-generated"] + - ["org.springframework.dao", "DataAccessException", "DataAccessException", "(String)", "summary", "df-generated"] + - ["org.springframework.dao", "DataAccessException", "DataAccessException", "(String,Throwable)", "summary", "df-generated"] + - ["org.springframework.dao", "DataAccessException", "toSpring", "()", "summary", "df-generated"] + - ["org.springframework.dao", "DataAccessResourceFailureException", "DataAccessResourceFailureException", "(String)", "summary", "df-generated"] + - ["org.springframework.dao", "DataAccessResourceFailureException", "DataAccessResourceFailureException", "(String,Throwable)", "summary", "df-generated"] + - ["org.springframework.dao", "DataRetrievalFailureException", "DataRetrievalFailureException", "(String)", "summary", "df-generated"] + - ["org.springframework.dao", "DataRetrievalFailureException", "DataRetrievalFailureException", "(String,Throwable)", "summary", "df-generated"] diff --git a/java/ql/lib/ext/generated/stapler.model.yml b/java/ql/lib/ext/generated/stapler.model.yml new file mode 100644 index 00000000000..a82d01328d6 --- /dev/null +++ b/java/ql/lib/ext/generated/stapler.model.yml @@ -0,0 +1,679 @@ +# THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. +# Definitions of models for the Stapler framework. +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.kohsuke.stapler.bind", "Bound", true, "getProxyScript", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.bind", "Bound", true, "getTarget", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.bind", "Bound", true, "getURL", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.bind", "BoundObjectTable$Table", true, "getDynamic", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.bind", "BoundObjectTable", true, "bind", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.compression", "FilterServletOutputStream", true, "FilterServletOutputStream", "(OutputStream,ServletOutputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.compression", "FilterServletOutputStream", true, "FilterServletOutputStream", "(OutputStream,ServletOutputStream)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ClassAttributeBehaviour", true, "simple", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ClassAttributeBehaviour", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", true, "getExportConfig", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", true, "name", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", true, "value", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "getClassAttribute", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "getExportInterceptor", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "withClassAttribute", "(ClassAttributeBehaviour)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "withClassAttribute", "(ClassAttributeBehaviour)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "withExportInterceptor", "(ExportInterceptor)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "withExportInterceptor", "(ExportInterceptor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "withFlavor", "(Flavor)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "withPrettyPrint", "(boolean)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", true, "withSkipIfFail", "(boolean)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler.export", "Flavor", true, "createDataWriter", "(Object,StaplerResponse)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Flavor", true, "createDataWriter", "(Object,Writer)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Flavor", true, "createDataWriter", "(Object,Writer,ExportConfig)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Flavor", true, "createDataWriter", "(Object,Writer,ExportConfig)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Model", true, "getProperties", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Model", true, "writeTo", "(Object,DataWriter)", "", "Argument[this]", "Argument[1]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Model", true, "writeTo", "(Object,TreePruner,DataWriter)", "", "Argument[this]", "Argument[2]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Model", true, "writeTo", "(Object,int,DataWriter)", "", "Argument[this]", "Argument[2]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ModelBuilder", true, "get", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ModelBuilder", true, "get", "(Class,Class,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "ModelBuilder", true, "getOrNull", "(Class,Class,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "NotExportableException", true, "NotExportableException", "(Class,Class,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "NotExportableException", true, "NotExportableException", "(String,Class)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Property", true, "getJavadoc", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Property", true, "writeTo", "(Object,TreePruner,DataWriter)", "", "Argument[this]", "Argument[2]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Property", true, "writeTo", "(Object,int,DataWriter)", "", "Argument[this]", "Argument[2]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Range", true, "apply", "(Collection)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Range", true, "apply", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Range", true, "apply", "(List)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "Range", true, "apply", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "SchemaGenerator", true, "SchemaGenerator", "(Model)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "TreePruner", true, "accept", "(Object,Property)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "TreePruner", true, "accept", "(Object,Property)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler.export", "TreePruner", true, "getRange", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "TypeUtil", true, "getBaseClass", "(Type,Class)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.export", "TypeUtil", true, "getTypeArgument", "(Type,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "Adjunct", true, "Adjunct", "(AdjunctManager,String,ClassLoader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "Adjunct", true, "Adjunct", "(AdjunctManager,String,ClassLoader)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "Adjunct", true, "getPackageUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "AdjunctManager", "(ServletContext,ClassLoader,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "AdjunctManager", "(ServletContext,ClassLoader,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "AdjunctManager", "(ServletContext,ClassLoader,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "AdjunctManager", "(ServletContext,ClassLoader,String,long)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "AdjunctManager", "(ServletContext,ClassLoader,String,long)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "AdjunctManager", "(ServletContext,ClassLoader,String,long)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "doDynamic", "(StaplerRequest,StaplerResponse)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "get", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "get", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", true, "get", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", true, "assumeIncluded", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", true, "assumeIncluded", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", true, "generate", "(XMLOutput,String[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", true, "get", "(StaplerRequest)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", true, "getIncluded", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", true, "spool", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "NoSuchAdjunctException", true, "NoSuchAdjunctException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "NoSuchAdjunctException", true, "NoSuchAdjunctException", "(String,Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.errors", "ErrorObject", true, "getMessage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.errors", "NoHomeDirError", true, "NoHomeDirError", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "AtomicFileWriter", true, "AtomicFileWriter", "(File)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "AtomicFileWriter", true, "getTemporaryFile", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "ByteBuffer", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "ByteBuffer", true, "writeTo", "(OutputStream)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "CharSpool", false, "writeTo", "(Writer)", "", "Argument[this]", "Argument[0]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "IOException2", true, "IOException2", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "IOException2", true, "IOException2", "(String,Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "WriterOutputStream", true, "WriterOutputStream", "(Writer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "WriterOutputStream", true, "WriterOutputStream", "(Writer,Charset)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.framework", "AbstractWebAppMain", true, "getInitializer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.interceptor", "Interceptor", true, "setTarget", "(Function)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.interceptor", "JsonOutputFilter$FilterPropertyFilter", true, "FilterPropertyFilter", "(Set,Set)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.interceptor", "JsonOutputFilter$FilterPropertyFilter", true, "FilterPropertyFilter", "(Set,Set)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.interceptor", "JsonOutputFilter$FilterPropertyFilter", true, "FilterPropertyFilter", "(String[],String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.interceptor", "JsonOutputFilter$FilterPropertyFilter", true, "FilterPropertyFilter", "(String[],String[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovierJellyScript", true, "GroovierJellyScript", "(Class,URL)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyClassLoaderTearOff", true, "GroovyClassLoaderTearOff", "(MetaClassLoader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyClassLoaderTearOff", true, "parse", "(URL)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyClassLoaderTearOff", true, "parseGSP", "(URL)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyClassTearOff", false, "GroovyClassTearOff", "(MetaClass)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyClassTearOff", false, "createDispatcher", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyClassTearOff", false, "createDispatcher", "(Object,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyClosureScript", true, "getDelegate", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyClosureScript", true, "setDelegate", "(GroovyObject)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyServerPageScript", true, "getOut", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyServerPageTearOff", true, "GroovyServerPageTearOff", "(MetaClass)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyServerPageTearOff", true, "createDispatcher", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovyServerPageTearOff", true, "createDispatcher", "(Object,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "JellyBuilder", "(JellyContext,XMLOutput)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "JellyBuilder", "(JellyContext,XMLOutput)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "getBuilder", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "getContext", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "getOutput", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "getRequest", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "getResponse", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "getRootURL", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "jelly", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "namespace", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "namespace", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "namespace", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "namespace", "(String,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "namespace", "(String,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "res", "(Object,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "res", "(Object,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "setOutput", "(XMLOutput)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "setOutput", "(XMLOutput)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", false, "with", "(XMLOutput,Closure)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "StaplerClosureScript", true, "gettext", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "StaplerClosureScript", true, "gettext", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "AdjunctTag", true, "setAssumes", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "AdjunctTag", true, "setIncludes", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "BindTag", true, "setValue", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "BindTag", true, "setVar", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ContentTypeTag", true, "setValue", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "CopyStreamTag", true, "setInputStream", "(InputStream)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "CopyStreamTag", true, "setReader", "(Reader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "CustomTagLibrary", false, "CustomTagLibrary", "(JellyContext,ClassLoader,String,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "CustomTagLibrary", false, "CustomTagLibrary", "(JellyContext,ClassLoader,String,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "CustomTagLibrary", false, "CustomTagLibrary", "(JellyContext,ClassLoader,String,String)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "CustomTagLibrary", false, "CustomTagLibrary", "(JellyContext,ClassLoader,String,String)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "DoctypeTag", true, "setPublicId", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "DoctypeTag", true, "setSystemId", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "FindAncestorTag", true, "setTag", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "FindAncestorTag", true, "setVar", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "HeaderTag", true, "setName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "HeaderTag", true, "setValue", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "IncludeTag", true, "setFrom", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "IncludeTag", true, "setIt", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "IncludeTag", true, "setPage", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "InternationalizedStringExpression$RawHtmlArgument", false, "RawHtmlArgument", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "InternationalizedStringExpression", true, "InternationalizedStringExpression", "(ResourceBundle,String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "InternationalizedStringExpression", true, "InternationalizedStringExpression", "(ResourceBundle,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "InternationalizedStringExpression", true, "getArguments", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "IsUserInRoleTag", true, "setRole", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyClassLoaderTearOff", true, "JellyClassLoaderTearOff", "(MetaClassLoader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyClassTearOff", true, "JellyClassTearOff", "(MetaClass)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyClassTearOff", true, "createDispatcher", "(Object,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyClassTearOff", true, "createDispatcher", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyClassTearOff", true, "createDispatcher", "(Object,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyRequestDispatcher", false, "JellyRequestDispatcher", "(Object,Script)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyRequestDispatcher", false, "JellyRequestDispatcher", "(Object,Script)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyViewScript", false, "JellyViewScript", "(Class,URL,Script)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyViewScript", false, "JellyViewScript", "(Class,URL,Script)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyViewScript", false, "JellyViewScript", "(Klass,URL,Script)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyViewScript", false, "JellyViewScript", "(Klass,URL,Script)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyViewScript", false, "JellyViewScript", "(Klass,URL,Script)", "", "Argument[2]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyViewScript", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "OutTag", true, "setValue", "(Expression)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "RedirectTag", true, "setUrl", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ResourceBundle", true, "ResourceBundle", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ResourceBundle", true, "format", "(Locale,String,Object[])", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ResourceBundle", true, "getBaseName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ResourceBundle", true, "getFormatString", "(Locale,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ResourceBundle", true, "getFormatStringWithoutDefaulting", "(Locale,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ResourceBundle", true, "load", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ResourceBundle", true, "load", "(URL)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ResourceBundleFactory", true, "create", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "SetHeaderTag", true, "setName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "SetHeaderTag", true, "setValue", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "StructuredMessageFormatTag", true, "addArgument", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "StructuredMessageFormatTag", true, "setKey", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ThisTagLibrary", true, "ThisTagLibrary", "(Expression)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.json", "JsonHttpResponse", true, "JsonHttpResponse", "(JSONObject)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.json", "JsonHttpResponse", true, "JsonHttpResponse", "(JSONObject,int)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", false, "Klass", "(Object,KlassNavigator)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", false, "Klass", "(Object,KlassNavigator)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", false, "getArrayElement", "(Object,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", false, "getMapElement", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", true, "getArrayElement", "(Object,int)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", true, "getMapElement", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler.tags", "Include", true, "setIt", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.tags", "Include", true, "setPage", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler.util", "IllegalReflectiveAccessLogHandler", true, "get", "(IllegalAccessException)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "AbstractTearOff", true, "resolveScript", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "AcceptHeader", false, "AcceptHeader", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "AcceptHeader", false, "select", "(Iterable)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "AcceptHeader", false, "select", "(String[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "AcceptHeader", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Ancestor", true, "getFullUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Ancestor", true, "getNext", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Ancestor", true, "getNextToken", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Ancestor", true, "getObject", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Ancestor", true, "getPrev", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Ancestor", true, "getRestOfUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Ancestor", true, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", true, "AttributeKey", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "CachingScriptLoader", true, "findScript", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "CachingScriptLoader", true, "findScript", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "EvaluationTrace", true, "trace", "(StaplerResponse,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Facet", true, "buildIndexDispatchers", "(MetaClass,List)", "", "Argument[this]", "Argument[1].Element", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Facet", true, "buildIndexDispatchers", "(MetaClass,List)", "", "Argument[0]", "Argument[1].Element", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Facet", true, "buildViewDispatchers", "(MetaClass,List)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Facet", true, "createRequestDispatcher", "(RequestImpl,Class,Object,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Facet", true, "createRequestDispatcher", "(RequestImpl,Klass,Object,String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Facet", true, "createRequestDispatcher", "(RequestImpl,Klass,Object,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Facet", true, "createRequestDispatcher", "(RequestImpl,Klass,Object,String)", "", "Argument[3]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", true, "optional", "()", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", true, "with", "(Map)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", true, "with", "(Map)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", true, "with", "(String,Object)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", true, "with", "(String,Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", true, "with", "(String,Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ForwardingFunction", true, "ForwardingFunction", "(Function)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Function$InstanceFunction", true, "InstanceFunction", "(Method)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Function", true, "contextualize", "(Object)", "", "Argument[this]", "ReturnValue", "value", "df-generated"] + - ["org.kohsuke.stapler", "Function", true, "getParameterNames", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "FunctionList", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "FunctionList", "(Function[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "annotated", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "name", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "prefix", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "signature", "(Class[])", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "signatureStartsWith", "(Class[])", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "union", "(FunctionList)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "union", "(FunctionList)", "", "Argument[0].Element", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList", false, "webMethodsLegacy", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpRedirect", false, "HttpRedirect", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpRedirect", false, "HttpRedirect", "(int,String)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses$HttpResponseException", true, "HttpResponseException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses$HttpResponseException", true, "HttpResponseException", "(String,Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses$HttpResponseException", true, "HttpResponseException", "(String,Throwable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses$HttpResponseException", true, "HttpResponseException", "(Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", true, "error", "(Throwable)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", true, "error", "(int,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", true, "error", "(int,Throwable)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", true, "redirectTo", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", true, "redirectTo", "(int,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "JavaScriptMethodContext", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "MetaClass", true, "getPostConstructMethods", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "MetaClass", true, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "MetaClassLoader", true, "MetaClassLoader", "(ClassLoader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "MetaClassLoader", true, "get", "(ClassLoader)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "NoStaplerConstructorException", true, "NoStaplerConstructorException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "RawHtmlArgument", true, "RawHtmlArgument", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "RawHtmlArgument", true, "getValue", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ReflectionUtils", true, "union", "(Annotation[],Annotation[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ReflectionUtils", true, "union", "(Annotation[],Annotation[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "RequestImpl", true, "RequestImpl", "(Stapler,HttpServletRequest,List,TokenList)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "RequestImpl", true, "RequestImpl", "(Stapler,HttpServletRequest,List,TokenList)", "", "Argument[2].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "RequestImpl", true, "RequestImpl", "(Stapler,HttpServletRequest,List,TokenList)", "", "Argument[3]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "RequestImpl", true, "getView", "(Klass,Object,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "RequestImpl", true, "getView", "(Klass,Object,String)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ResponseImpl", true, "ResponseImpl", "(Stapler,HttpServletResponse)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ResponseImpl", true, "ResponseImpl", "(Stapler,HttpServletResponse)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ResponseImpl", true, "encode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ScriptLoadException", true, "ScriptLoadException", "(String,Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ScriptLoadException", true, "ScriptLoadException", "(String,Throwable)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "ScriptLoadException", true, "ScriptLoadException", "(Throwable)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "SingleLinkedList", true, "SingleLinkedList", "(Object,SingleLinkedList)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "SingleLinkedList", true, "SingleLinkedList", "(Object,SingleLinkedList)", "", "Argument[1].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "SingleLinkedList", true, "grow", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "SingleLinkedList", true, "grow", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", true, "escape", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", true, "getClassLoader", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", true, "getViewURL", "(Class,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", true, "getWebApp", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", true, "htmlSafeArgument", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", true, "htmlSafeArguments", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "bindJSON", "(Type,Class,Object)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "findAncestor", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "findAncestor", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getAncestors", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getBindInterceptor", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getFileItem", "(String)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getOriginalRequestURI", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getOriginalRestOfPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getRestOfPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getStapler", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getSubmittedForm", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getView", "(Class,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getView", "(Klass,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getView", "(Object,String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getView", "(Object,String)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "getWebApp", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "setBindInterceptor", "(BindInterceptor)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "setBindInterceptor", "(BindInterceptor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "setBindInterceptpr", "(BindInterceptor)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "setBindInterceptpr", "(BindInterceptor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "setBindListener", "(BindInterceptor)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", true, "setBindListener", "(BindInterceptor)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", true, "getCompressedOutputStream", "(HttpServletRequest)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", true, "getCompressedWriter", "(HttpServletRequest)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", true, "getJsonConfig", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", true, "setJsonConfig", "(JsonConfig)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponseWrapper", true, "StaplerResponseWrapper", "(StaplerResponse)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponseWrapper", true, "getWrapped", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaticViewFacet", true, "StaticViewFacet", "(Collection)", "", "Argument[0].Element", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaticViewFacet", true, "StaticViewFacet", "(String[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "StaticViewFacet", true, "addExtension", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", false, "assembleOriginalRestOfPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", false, "assembleRestOfPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", false, "decode", "(String)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", false, "get", "(int)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", false, "next", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", false, "peek", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", false, "prev", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", false, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "TraversalMethodContext", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "WebApp", "(ServletContext)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "get", "(ServletContext)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getClassLoader", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getCrumbIssuer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getDispatchValidator", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getDispatchersFilter", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getFilterForDoActions", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getFilterForFields", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getFilterForGetMethods", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getFilteredDispatchTriggerListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getFilteredDoActionTriggerListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getFilteredFieldTriggerListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getFilteredGetterTriggerListener", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getJsonInErrorMessageSanitizer", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getMetaClass", "(Class)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getMetaClass", "(Klass)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getMetaClass", "(Klass)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getMetaClass", "(Object)", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getResponseRenderers", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "getSomeStapler", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setClassLoader", "(ClassLoader)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setCrumbIssuer", "(CrumbIssuer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setDispatchValidator", "(DispatchValidator)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setDispatchersFilter", "(DispatchersFilter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setFilterForDoActions", "(Filter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setFilterForFields", "(Filter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setFilterForGetMethods", "(Filter)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setFilteredDispatchTriggerListener", "(FilteredDispatchTriggerListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setFilteredDoActionTriggerListener", "(FilteredDoActionTriggerListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setFilteredFieldTriggerListener", "(FilteredFieldTriggerListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setFilteredGetterTriggerListener", "(FilteredGetterTriggerListener)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", true, "setJsonInErrorMessageSanitizer", "(JsonInErrorMessageSanitizer)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WebMethodContext", false, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] + - ["org.kohsuke.stapler", "WrongTypeException", true, "WrongTypeException", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["org.kohsuke.stapler.bind", "Bound", "getTarget", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.bind", "Bound", "getURL", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.bind", "Bound", "release", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.bind", "BoundObjectTable$Table", "doEnableLogging", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.bind", "BoundObjectTable", "bindWeak", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.bind", "BoundObjectTable", "getTable", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.bind", "BoundObjectTable", "releaseMe", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.compression", "CompressionFilter", "activate", "(ServletRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler.compression", "CompressionFilter", "getUncaughtExceptionHandler", "(ServletContext)", "summary", "df-generated"] + - ["org.kohsuke.stapler.compression", "CompressionFilter", "has", "(ServletRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler.compression", "CompressionFilter", "setUncaughtExceptionHandler", "(ServletContext,UncaughtExceptionHandler)", "summary", "df-generated"] + - ["org.kohsuke.stapler.compression", "CompressionServletResponse", "CompressionServletResponse", "(HttpServletResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler.compression", "CompressionServletResponse", "activate", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.compression", "CompressionServletResponse", "close", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.compression", "UncaughtExceptionHandler", "reportException", "(Throwable,ServletContext,HttpServletRequest,HttpServletResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler.config", "ConfigurationLoader", "as", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.config", "ConfigurationLoader", "from", "(File)", "summary", "df-generated"] + - ["org.kohsuke.stapler.config", "ConfigurationLoader", "from", "(Map)", "summary", "df-generated"] + - ["org.kohsuke.stapler.config", "ConfigurationLoader", "from", "(Properties)", "summary", "df-generated"] + - ["org.kohsuke.stapler.config", "ConfigurationLoader", "fromEnvironmentVariables", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.config", "ConfigurationLoader", "fromSystemProperties", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.event", "FilteredDispatchTriggerListener", "onDispatchTrigger", "(StaplerRequest,StaplerResponse,Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.event", "FilteredDoActionTriggerListener", "onDoActionTrigger", "(Function,StaplerRequest,StaplerResponse,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.event", "FilteredFieldTriggerListener", "onFieldTrigger", "(FieldRef,StaplerRequest,StaplerResponse,Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.event", "FilteredGetterTriggerListener", "onGetterTrigger", "(Function,StaplerRequest,StaplerResponse,Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "endArray", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "endObject", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "getExportConfig", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "name", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "startArray", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "startObject", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "type", "(Type,Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "value", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "valueNull", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "DataWriter", "valuePrimitive", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", "getFlavor", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", "isPrettyPrint", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportConfig", "isSkipIfFail", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "ExportInterceptor", "getValue", "(Property,Object,ExportConfig)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "Flavor", "createDataWriter", "(Object,Writer,ExportConfig)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "NamedPathPruner", "NamedPathPruner", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "NotExportableException", "NotExportableException", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "NotExportableException", "NotExportableException", "(String,Throwable,Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "NotExportableException", "NotExportableException", "(Throwable,Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "NotExportableException", "getType", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "Property", "getGenericType", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "Property", "getJavadoc", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "Property", "getType", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "Property", "getValue", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "Range", "Range", "(int,int)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "SchemaGenerator", "add", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "SchemaGenerator", "generateSchema", "(Result)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "SchemaGenerator", "getXmlTypeName", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "TreePruner$ByDepth", "ByDepth", "(int)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "TreePruner", "accept", "(Object,Property)", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "TreePruner", "getRange", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.export", "TypeUtil", "erasure", "(Type)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "Adjunct", "has", "(Kind)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "Adjunct", "write", "(StaplerRequest,XMLOutput)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctManager", "get", "(ServletContext)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", "get", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", "isIncluded", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "AdjunctsInPage", "writeSpooled", "(XMLOutput)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.adjunct", "NoSuchAdjunctException", "NoSuchAdjunctException", "(Throwable)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.errors", "ErrorObject", "getMessage", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "AtomicFileWriter", "commit", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "ByteBuffer", "length", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "ByteBuffer", "newInputStream", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "IOException2", "IOException2", "(Throwable)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "LargeText", "(ByteBuffer,Charset,boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "LargeText", "(ByteBuffer,boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "LargeText", "(File,Charset,boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "LargeText", "(File,Charset,boolean,boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "LargeText", "(File,boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "LargeText", "(File,boolean,boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "doProgressText", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "isComplete", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "length", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "markAsComplete", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "readAll", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "writeLogTo", "(long,OutputStream)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LargeText", "writeLogTo", "(long,Writer)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework.io", "LineEndNormalizingWriter", "LineEndNormalizingWriter", "(Writer)", "summary", "df-generated"] + - ["org.kohsuke.stapler.framework", "AbstractWebAppMain", "getApplication", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.interceptor", "Interceptor", "invoke", "(StaplerRequest,StaplerResponse,Object,Object[])", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "GroovierJellyScript", "run", "(JellyBuilder)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "adjunct", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "getMy", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "getServletContext", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "img", "(Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "include", "(Class,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "include", "(Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "methodMissing", "(String,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "namespace", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "raw", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "redirectToDom", "(Closure)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "set", "(String,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "taglib", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "JellyBuilder", "text", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "Namespace", "createInvoker", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "Namespace", "endPrefixMapping", "(XMLOutput)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly.groovy", "Namespace", "startPrefixMapping", "(XMLOutput)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "AttributeConstraintsTag", "setExpr", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "AttributeTag", "setDeprecated", "(boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "AttributeTag", "setName", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "AttributeTag", "setSince", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "AttributeTag", "setType", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "AttributeTag", "setUse", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "CopyStreamTag", "setFile", "(File)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "CopyStreamTag", "setUrl", "(URL)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "HTMLWriterOutput", "create", "(OutputStream)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "HTMLWriterOutput", "create", "(Writer,boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "HTMLWriterOutput", "useHTML", "(boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "IncludeTag", "setClass", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "IncludeTag", "setClazz", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "IncludeTag", "setOptional", "(boolean)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "InternationalizedStringExpression", "makeEscapingExpression", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyClassLoaderTearOff", "createContext", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyClassLoaderTearOff", "getTagLibrary", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyClassTearOff", "serveIndexJelly", "(StaplerRequest,StaplerResponse,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyCompatibleFacet", "getClassTearOffTypes", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyCompatibleFacet", "getScriptExtensions", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyFacet", "setExpressionFactory", "(ServletContextEvent,ExpressionFactory)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyTagFileLoader", "discover", "(ClassLoader)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "JellyTagFileLoader", "load", "(CustomTagLibrary,String,ClassLoader)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ReallyStaticTagLibrary", "createTagScript", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ScriptInvoker", "invokeScript", "(StaplerRequest,StaplerResponse,Script,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "ScriptInvoker", "invokeScript", "(StaplerRequest,StaplerResponse,Script,Object,XMLOutput)", "summary", "df-generated"] + - ["org.kohsuke.stapler.jelly", "StatusCodeTag", "setValue", "(int)", "summary", "df-generated"] + - ["org.kohsuke.stapler.json", "JsonHttpResponse", "JsonHttpResponse", "(Throwable,int)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang.util", "FieldRefFilter", "wrap", "(Field)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang.util", "MethodRefFilter", "wrap", "(Method)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "AnnotatedRef", "getAnnotation", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "AnnotatedRef", "hasAnnotation", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef$Filter", "keep", "(FieldRef)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef", "get", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef", "getName", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef", "getQualifiedName", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef", "getReturnType", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef", "getSignature", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef", "isRoutable", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef", "isStatic", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "FieldRef", "wrap", "(Field)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "getAncestors", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "getDeclaredFields", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "getDeclaredMethods", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "getFields", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "getFunctions", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "getResource", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "getSuperClass", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "isArray", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "isMap", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "java", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "toJavaClass", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "Klass", "toString", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "getAncestors", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "getDeclaredFields", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "getDeclaredMethods", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "getFunctions", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "getResource", "(Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "getSuperClass", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "isArray", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "isMap", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "KlassNavigator", "toJavaClass", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "MethodRef", "getName", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "MethodRef", "invoke", "(Object,Object[])", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "MethodRef", "isRoutable", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler.lang", "MethodRef", "wrap", "(Method)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Ancestor", "getRelativePath", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AnnotationHandler", "parse", "(StaplerRequest,Annotation,Class,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "appScoped", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "get", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "get", "(HttpServletRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "remove", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "remove", "(HttpServletRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "requestScoped", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "sessionScoped", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "set", "(HttpServletRequest,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "AttributeKey", "set", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "BindInterceptor", "instantiate", "(Class,JSONObject)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "BindInterceptor", "onConvert", "(Type,Class,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "CachingScriptLoader", "clearScripts", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "ClassDescriptor", "ClassDescriptor", "(Class,Class[])", "summary", "df-generated"] + - ["org.kohsuke.stapler", "ClassDescriptor", "loadConstructorParamNames", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "ClassDescriptor", "loadParameterNames", "(Constructor)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "ClassDescriptor", "loadParameterNames", "(Method)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "CrumbIssuer", "doCrumb", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "CrumbIssuer", "issueCrumb", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "CrumbIssuer", "issueCrumb", "(StaplerRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "CrumbIssuer", "validateCrumb", "(StaplerRequest,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "DispatchValidator", "allowDispatch", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "DispatchValidator", "isDispatchAllowed", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "DispatchValidator", "isDispatchAllowed", "(StaplerRequest,StaplerResponse,String,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "DispatchValidator", "requireDispatchAllowed", "(StaplerRequest,StaplerResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "anonymizedTraceEval", "(StaplerRequest,StaplerResponse,Object,String,String[])", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "dispatch", "(RequestImpl,ResponseImpl,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "isTraceEnabled", "(StaplerRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "toString", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "trace", "(StaplerRequest,StaplerResponse,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "trace", "(StaplerRequest,StaplerResponse,String,Object[])", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "traceEval", "(StaplerRequest,StaplerResponse,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "traceEval", "(StaplerRequest,StaplerResponse,Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "traceEval", "(StaplerRequest,StaplerResponse,Object,String,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Dispatcher", "traceable", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "EvaluationTrace$ApplicationTracer", "trace", "(StaplerRequest,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "EvaluationTrace", "get", "(StaplerRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "EvaluationTrace", "printHtml", "(PrintWriter)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Facet", "buildFallbackDispatchers", "(MetaClass,List)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Facet", "buildIndexDispatchers", "(MetaClass,List)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Facet", "buildViewDispatchers", "(MetaClass,List)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Facet", "createRequestDispatcher", "(RequestImpl,Klass,Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Facet", "discover", "(ClassLoader)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Facet", "discoverExtensions", "(Class,ClassLoader[])", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Facet", "getKlass", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Facet", "handleIndexRequest", "(RequestImpl,ResponseImpl,Object,MetaClass)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", "ForwardToView", "(Class,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", "ForwardToView", "(Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "ForwardToView", "ForwardToView", "(RequestDispatcher)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getAnnotation", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getAnnotations", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getCheckedExceptionTypes", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getDeclaringClass", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getDisplayName", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getGenericParameterTypes", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getName", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getParameterAnnotations", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getParameterNames", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getParameterTypes", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getQualifiedName", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getReturnType", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "getSignature", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "invoke", "(StaplerRequest,StaplerResponse,Object,Object[])", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "isStatic", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Function", "returnNull", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "FunctionList$Filter", "keep", "(Function)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpRedirect", "fromContextPath", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponse", "generateResponse", "(StaplerRequest,StaplerResponse,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponseRenderer", "generateResponse", "(StaplerRequest,StaplerResponse,Object,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "errorWithoutStack", "(int,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "forbidden", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "forwardToPreviousPage", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "forwardToView", "(Class,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "forwardToView", "(Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "html", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "literalHtml", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "notFound", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "ok", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "plainText", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "redirectToContextRoot", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "redirectToDot", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "redirectViaContextPath", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "redirectViaContextPath", "(int,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "staticResource", "(URL)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "staticResource", "(URL,long)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "status", "(int)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "HttpResponses", "text", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "LocaleDrivenResourceProvider", "lookup", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "MethodHandleFactory", "get", "(Method)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "NoStaplerConstructorException", "NoStaplerConstructorException", "(String,Throwable)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "NoStaplerConstructorException", "NoStaplerConstructorException", "(Throwable)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "RawHtmlArgument", "toString", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "ReflectionUtils", "getVmDefaultValueFor", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "SingleLinkedList", "empty", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "buildResourcePaths", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "forward", "(RequestDispatcher,StaplerRequest,HttpServletResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "getClassLoader", "(ServletContext)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "getCurrent", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "getCurrentRequest", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "getCurrentResponse", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "invoke", "(HttpServletRequest,HttpServletResponse,Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "isSocketException", "(Throwable)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "lookupConverter", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "setClassLoader", "(ServletContext,ClassLoader)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "Stapler", "setRoot", "(ServletContextEvent,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerFallback", "getStaplerFallback", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "bindJSON", "(Class,JSONObject)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "bindJSON", "(Object,JSONObject)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "bindJSONToList", "(Class,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "bindParameters", "(Class,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "bindParameters", "(Class,String,int)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "bindParameters", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "bindParameters", "(Object,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "bindParametersToList", "(Class,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "checkIfModified", "(Calendar,StaplerResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "checkIfModified", "(Date,StaplerResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "checkIfModified", "(long,StaplerResponse)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "checkIfModified", "(long,StaplerResponse,long)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "createJavaScriptProxy", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "findAncestorObject", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "getBoundObjectTable", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "getReferer", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "getRequestURIWithQueryString", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "getRequestURLWithQueryString", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "getRootPath", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "hasParameter", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerRequest", "isJavaScriptProxyCall", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "forward", "(Object,String,StaplerRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "forwardToPreviousPage", "(StaplerRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "reverseProxyTo", "(URL,StaplerRequest)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "sendRedirect2", "(String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "sendRedirect", "(int,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveExposedBean", "(StaplerRequest,Object,ExportConfig)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveExposedBean", "(StaplerRequest,Object,Flavor)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveFile", "(StaplerRequest,InputStream,long,int,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveFile", "(StaplerRequest,InputStream,long,long,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveFile", "(StaplerRequest,InputStream,long,long,int,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveFile", "(StaplerRequest,InputStream,long,long,long,String)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveFile", "(StaplerRequest,URL)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveFile", "(StaplerRequest,URL,long)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveLocalizedFile", "(StaplerRequest,URL)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "StaplerResponse", "serveLocalizedFile", "(StaplerRequest,URL,long)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "TearOffSupport", "getTearOff", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "TearOffSupport", "loadTearOff", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "TearOffSupport", "setTearOff", "(Class,Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", "countRemainingTokens", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", "hasMore", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", "length", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", "nextAsInt", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "TokenList", "nextAsLong", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", "clearMetaClassCache", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", "clearScripts", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", "getApp", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", "getCurrent", "()", "summary", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", "getFacet", "(Class)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", "getKlass", "(Object)", "summary", "df-generated"] + - ["org.kohsuke.stapler", "WebApp", "setApp", "(Object)", "summary", "df-generated"] From 73d2ab7d66f89d03f390deec07c8787c5bf8d932 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 14 Jun 2023 09:54:55 +0200 Subject: [PATCH 545/739] Add change note --- .../2023-06-14-jenkins-autogenerated-models.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-06-14-jenkins-autogenerated-models.md diff --git a/java/ql/lib/change-notes/2023-06-14-jenkins-autogenerated-models.md b/java/ql/lib/change-notes/2023-06-14-jenkins-autogenerated-models.md new file mode 100644 index 00000000000..da2f90c2326 --- /dev/null +++ b/java/ql/lib/change-notes/2023-06-14-jenkins-autogenerated-models.md @@ -0,0 +1,8 @@ +--- +category: minorAnalysis +--- +* Added automatically-generated dataflow models for the following frameworks and libraries: + * `hudson` + * `jenkins` + * `net.sf.json` + * `stapler` From 8bafc22add704888542fb52ec6c300e3cc62382f Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 14 Jun 2023 09:59:59 +0200 Subject: [PATCH 546/739] Replace open-url sink kinds with request-forgery --- java/ql/lib/ext/generated/jenkins-json-lib.model.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/ext/generated/jenkins-json-lib.model.yml b/java/ql/lib/ext/generated/jenkins-json-lib.model.yml index 61b41de6068..1726e603857 100644 --- a/java/ql/lib/ext/generated/jenkins-json-lib.model.yml +++ b/java/ql/lib/ext/generated/jenkins-json-lib.model.yml @@ -5,8 +5,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["net.sf.json.groovy", "JsonSlurper", true, "parse", "(String)", "", "Argument[0]", "open-url", "df-generated"] - - ["net.sf.json.groovy", "JsonSlurper", true, "parse", "(URL)", "", "Argument[0]", "open-url", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", true, "parse", "(String)", "", "Argument[0]", "request-forgery", "df-generated"] + - ["net.sf.json.groovy", "JsonSlurper", true, "parse", "(URL)", "", "Argument[0]", "request-forgery", "df-generated"] - addsTo: pack: codeql/java-all extensible: summaryModel From 21831516f4000da4effafd3959b97650652bb3d8 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Wed, 14 Jun 2023 10:38:33 +0200 Subject: [PATCH 547/739] JS: use test-local data extensions --- .../test/library-tests/DataExtensions/Test.expected | 8 -------- .../ql/test/library-tests/DataExtensions/Test.ql | 11 ----------- .../library-tests/DataExtensions/connection.expected | 2 ++ .../{connection.model.yml => connection.ext.yml} | 0 .../test/library-tests/DataExtensions/connection.ql | 4 ++++ .../test/library-tests/DataExtensions/execa.expected | 1 + .../test/library-tests/DataExtensions/execa.ext.yml | 6 ++++++ .../test/library-tests/DataExtensions/execa.model.yml | 10 ---------- .../ql/test/library-tests/DataExtensions/execa.ql | 6 ++++++ .../library-tests/DataExtensions/message.expected | 2 ++ .../{message.model.yml => message.ext.yml} | 0 .../ql/test/library-tests/DataExtensions/message.ql | 3 +++ 12 files changed, 24 insertions(+), 29 deletions(-) delete mode 100644 javascript/ql/test/library-tests/DataExtensions/Test.expected delete mode 100644 javascript/ql/test/library-tests/DataExtensions/Test.ql create mode 100644 javascript/ql/test/library-tests/DataExtensions/connection.expected rename javascript/ql/test/library-tests/DataExtensions/{connection.model.yml => connection.ext.yml} (100%) create mode 100644 javascript/ql/test/library-tests/DataExtensions/connection.ql create mode 100644 javascript/ql/test/library-tests/DataExtensions/execa.expected create mode 100644 javascript/ql/test/library-tests/DataExtensions/execa.ext.yml delete mode 100644 javascript/ql/test/library-tests/DataExtensions/execa.model.yml create mode 100644 javascript/ql/test/library-tests/DataExtensions/execa.ql create mode 100644 javascript/ql/test/library-tests/DataExtensions/message.expected rename javascript/ql/test/library-tests/DataExtensions/{message.model.yml => message.ext.yml} (100%) create mode 100644 javascript/ql/test/library-tests/DataExtensions/message.ql diff --git a/javascript/ql/test/library-tests/DataExtensions/Test.expected b/javascript/ql/test/library-tests/DataExtensions/Test.expected deleted file mode 100644 index 6c82916b357..00000000000 --- a/javascript/ql/test/library-tests/DataExtensions/Test.expected +++ /dev/null @@ -1,8 +0,0 @@ -commandInjectionSinks -| execa.example.js:2:7:2:9 | cmd | -sqlInjectionSinks -| connection.example.ts:4:20:4:20 | q | -| connection.example.ts:9:18:9:18 | q | -remoteFlowSources -| message.example.js:1:46:1:50 | event | -| message.example.js:2:16:2:25 | event.data | diff --git a/javascript/ql/test/library-tests/DataExtensions/Test.ql b/javascript/ql/test/library-tests/DataExtensions/Test.ql deleted file mode 100644 index 38eda6b4f78..00000000000 --- a/javascript/ql/test/library-tests/DataExtensions/Test.ql +++ /dev/null @@ -1,11 +0,0 @@ -import javascript -private import semmle.javascript.security.dataflow.CommandInjectionCustomizations -private import semmle.javascript.security.dataflow.SqlInjectionCustomizations - -query predicate commandInjectionSinks(DataFlow::Node node) { - node instanceof CommandInjection::Sink -} - -query predicate sqlInjectionSinks(DataFlow::Node node) { node instanceof SqlInjection::Sink } - -query predicate remoteFlowSources(RemoteFlowSource node) { any() } diff --git a/javascript/ql/test/library-tests/DataExtensions/connection.expected b/javascript/ql/test/library-tests/DataExtensions/connection.expected new file mode 100644 index 00000000000..3c48d0b5e43 --- /dev/null +++ b/javascript/ql/test/library-tests/DataExtensions/connection.expected @@ -0,0 +1,2 @@ +| connection.example.ts:4:20:4:20 | q | +| connection.example.ts:9:18:9:18 | q | diff --git a/javascript/ql/test/library-tests/DataExtensions/connection.model.yml b/javascript/ql/test/library-tests/DataExtensions/connection.ext.yml similarity index 100% rename from javascript/ql/test/library-tests/DataExtensions/connection.model.yml rename to javascript/ql/test/library-tests/DataExtensions/connection.ext.yml diff --git a/javascript/ql/test/library-tests/DataExtensions/connection.ql b/javascript/ql/test/library-tests/DataExtensions/connection.ql new file mode 100644 index 00000000000..be05bcd4036 --- /dev/null +++ b/javascript/ql/test/library-tests/DataExtensions/connection.ql @@ -0,0 +1,4 @@ +import javascript +private import semmle.javascript.security.dataflow.SqlInjectionCustomizations + +query predicate sqlInjectionSinks(DataFlow::Node node) { node instanceof SqlInjection::Sink } diff --git a/javascript/ql/test/library-tests/DataExtensions/execa.expected b/javascript/ql/test/library-tests/DataExtensions/execa.expected new file mode 100644 index 00000000000..e69a5072709 --- /dev/null +++ b/javascript/ql/test/library-tests/DataExtensions/execa.expected @@ -0,0 +1 @@ +| execa.example.js:2:7:2:9 | cmd | diff --git a/javascript/ql/test/library-tests/DataExtensions/execa.ext.yml b/javascript/ql/test/library-tests/DataExtensions/execa.ext.yml new file mode 100644 index 00000000000..d1e4adb96cb --- /dev/null +++ b/javascript/ql/test/library-tests/DataExtensions/execa.ext.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sinkModel + data: + - ["@example/execa", "Member[shell].Argument[0]", "command-injection"] diff --git a/javascript/ql/test/library-tests/DataExtensions/execa.model.yml b/javascript/ql/test/library-tests/DataExtensions/execa.model.yml deleted file mode 100644 index f7e0f70c0bc..00000000000 --- a/javascript/ql/test/library-tests/DataExtensions/execa.model.yml +++ /dev/null @@ -1,10 +0,0 @@ -extensions: - - addsTo: - pack: codeql/javascript-all - extensible: sinkModel - data: - - [ - "@example/execa", - "Member[shell].Argument[0]", - "command-injection", - ] diff --git a/javascript/ql/test/library-tests/DataExtensions/execa.ql b/javascript/ql/test/library-tests/DataExtensions/execa.ql new file mode 100644 index 00000000000..3e6191d3dfb --- /dev/null +++ b/javascript/ql/test/library-tests/DataExtensions/execa.ql @@ -0,0 +1,6 @@ +import javascript +private import semmle.javascript.security.dataflow.CommandInjectionCustomizations + +query predicate commandInjectionSinks(DataFlow::Node node) { + node instanceof CommandInjection::Sink +} diff --git a/javascript/ql/test/library-tests/DataExtensions/message.expected b/javascript/ql/test/library-tests/DataExtensions/message.expected new file mode 100644 index 00000000000..e8457f74bf6 --- /dev/null +++ b/javascript/ql/test/library-tests/DataExtensions/message.expected @@ -0,0 +1,2 @@ +| message.example.js:1:46:1:50 | event | +| message.example.js:2:16:2:25 | event.data | diff --git a/javascript/ql/test/library-tests/DataExtensions/message.model.yml b/javascript/ql/test/library-tests/DataExtensions/message.ext.yml similarity index 100% rename from javascript/ql/test/library-tests/DataExtensions/message.model.yml rename to javascript/ql/test/library-tests/DataExtensions/message.ext.yml diff --git a/javascript/ql/test/library-tests/DataExtensions/message.ql b/javascript/ql/test/library-tests/DataExtensions/message.ql new file mode 100644 index 00000000000..cf0637a04ef --- /dev/null +++ b/javascript/ql/test/library-tests/DataExtensions/message.ql @@ -0,0 +1,3 @@ +import javascript + +query predicate remoteFlowSources(RemoteFlowSource node) { any() } From 5aea6fc16c23559630b24f4a0c3a0bda64d7f607 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Wed, 14 Jun 2023 10:42:31 +0200 Subject: [PATCH 548/739] JS: Remove dataExtensions clause from test qlpack --- javascript/ql/test/qlpack.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/javascript/ql/test/qlpack.yml b/javascript/ql/test/qlpack.yml index 566916b499f..8976782483a 100644 --- a/javascript/ql/test/qlpack.yml +++ b/javascript/ql/test/qlpack.yml @@ -5,6 +5,4 @@ dependencies: codeql/javascript-queries: ${workspace} extractor: javascript tests: . -dataExtensions: - - library-tests/DataExtensions/*.model.yml warnOnImplicitThis: true From 2200a2ae793450755251660fca2919f8756da049 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 11:25:31 +0200 Subject: [PATCH 549/739] C#: Address review comments. --- .../ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 83bdcdcc04e..14590895b14 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -388,7 +388,9 @@ module EntityFramework { * for property `mapped` for this. */ pragma[noinline] - predicate output(SummaryComponentStack output, Property mapped, DbContextClassSetProperty dbSet) { + private predicate output( + SummaryComponentStack output, Property mapped, DbContextClassSetProperty dbSet + ) { exists(PropertyContent head, SummaryComponentStack tail | this.requiresComponentStackOut(head, _, tail, _, dbSet) and head.getProperty() = mapped and From 5e3d9d8136eb2e846aa2ee00ca3ea01fd194adda Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 23 May 2023 15:21:50 +0200 Subject: [PATCH 550/739] Java: Model the Stapler framework --- .../change-notes/2023-05-22-stapler-models.md | 4 + .../ext/org.kohsuke.stapler.bind.model.yml | 6 + .../ext/org.kohsuke.stapler.json.model.yml | 7 + java/ql/lib/ext/org.kohsuke.stapler.model.yml | 42 ++++++ .../semmle/code/java/dataflow/FlowSources.qll | 1 + .../semmle/code/java/dataflow/FlowSteps.qll | 1 + .../code/java/frameworks/hudson/Hudson.qll | 9 ++ .../code/java/frameworks/stapler/Stapler.qll | 124 ++++++++++++++++++ .../dataflow/taintsources/Stapler.java | 14 ++ .../dataflow/taintsources/options | 2 +- .../stapler/DataBoundPostConstructTest.java | 42 ++++++ .../frameworks/stapler/HttpResponseTest.java | 26 ++++ .../library-tests/frameworks/stapler/options | 2 +- .../javax/annotation/PostConstruct.java | 13 ++ .../jenkins/hudson/model/Descriptor.java | 5 + .../kohsuke/stapler/DataBoundConstructor.java | 13 ++ .../kohsuke/stapler/DataBoundResolvable.java | 4 + .../org/kohsuke/stapler/DataBoundSetter.java | 14 ++ .../kohsuke/stapler/InjectedParameter.java | 13 ++ 19 files changed, 340 insertions(+), 2 deletions(-) create mode 100644 java/ql/lib/change-notes/2023-05-22-stapler-models.md create mode 100644 java/ql/lib/ext/org.kohsuke.stapler.bind.model.yml create mode 100644 java/ql/lib/ext/org.kohsuke.stapler.json.model.yml create mode 100644 java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll create mode 100644 java/ql/test/library-tests/dataflow/taintsources/Stapler.java create mode 100644 java/ql/test/library-tests/frameworks/stapler/DataBoundPostConstructTest.java create mode 100644 java/ql/test/library-tests/frameworks/stapler/HttpResponseTest.java create mode 100644 java/ql/test/stubs/javax-annotation-api-1.3.2/javax/annotation/PostConstruct.java create mode 100644 java/ql/test/stubs/jenkins/hudson/model/Descriptor.java create mode 100644 java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundConstructor.java create mode 100644 java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundResolvable.java create mode 100644 java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundSetter.java create mode 100644 java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/InjectedParameter.java diff --git a/java/ql/lib/change-notes/2023-05-22-stapler-models.md b/java/ql/lib/change-notes/2023-05-22-stapler-models.md new file mode 100644 index 00000000000..37c7250b953 --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-22-stapler-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added more models for the Stapler framework. diff --git a/java/ql/lib/ext/org.kohsuke.stapler.bind.model.yml b/java/ql/lib/ext/org.kohsuke.stapler.bind.model.yml new file mode 100644 index 00000000000..9152eb7b55b --- /dev/null +++ b/java/ql/lib/ext/org.kohsuke.stapler.bind.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.kohsuke.stapler.bind", "JavaScriptMethod", True, "", "", "Annotated", "Parameter", "remote", "manual"] diff --git a/java/ql/lib/ext/org.kohsuke.stapler.json.model.yml b/java/ql/lib/ext/org.kohsuke.stapler.json.model.yml new file mode 100644 index 00000000000..a06683144e0 --- /dev/null +++ b/java/ql/lib/ext/org.kohsuke.stapler.json.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.kohsuke.stapler.json", "SubmittedForm", True, "", "", "Annotated", "Parameter", "remote", "manual"] + - ["org.kohsuke.stapler.json", "JsonBody", True, "", "", "Annotated", "Parameter", "remote", "manual"] diff --git a/java/ql/lib/ext/org.kohsuke.stapler.model.yml b/java/ql/lib/ext/org.kohsuke.stapler.model.yml index 7a242051485..63bbdbfd52a 100644 --- a/java/ql/lib/ext/org.kohsuke.stapler.model.yml +++ b/java/ql/lib/ext/org.kohsuke.stapler.model.yml @@ -4,4 +4,46 @@ extensions: extensible: sinkModel data: - ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(String)", "", "Argument[0]", "url-redirection", "ai-manual"] + - ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(int,String)", "", "Argument[1]", "url-redirection", "manual"] - ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL,long)", "", "Argument[0]", "request-forgery", "manual"] + - ["org.kohsuke.stapler", "HttpResponses", True, "html", "(String)", "", "Argument[0]", "html-injection", "manual"] + - ["org.kohsuke.stapler", "HttpResponses", True, "literalHtml", "(String)", "", "Argument[0]", "html-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "forward", "(Object,String,StaplerRequest)", "", "Argument[1]", "request-forgery", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect2", "(String)", "", "Argument[0]", "url-redirection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect", "(int,String)", "", "Argument[1]", "url-redirection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect", "(String)", "", "Argument[0]", "url-redirection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,URL)", "", "Argument[1]", "path-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,URL,long)", "", "Argument[1]", "path-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "serveLocalizedFile", "(StaplerRequest,URL)", "", "Argument[1]", "path-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "serveLocalizedFile", "(StaplerRequest,URL,long)", "", "Argument[1]", "path-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,long,String)", "", "Argument[1]", "path-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,int,String)", "", "Argument[1]", "path-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,String)", "", "Argument[1]", "path-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,int,String)", "", "Argument[1]", "path-injection", "manual"] + - ["org.kohsuke.stapler", "StaplerResponse", True, "reverseProxyTo", "(URL,StaplerRequest)", "", "Argument[0]", "request-forgery", "manual"] + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["org.kohsuke.stapler", "StaplerRequest", True, "getRequestURIWithQueryString", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getRequestURLWithQueryString", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getReferer", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getOriginalRequestURI", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getSubmittedForm", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getFileItem", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "bindParametersToList", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "bindParameters", "", "", "Argument[0]", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "bindParameters", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSON", "", "", "Argument[0]", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSON", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSONToList", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getParameter", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterMap", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterNames", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterValues", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "StaplerRequest", True, "getRestOfPath", "", "", "ReturnValue", "remote", "manual"] + - ["org.kohsuke.stapler", "QueryParameter", True, "", "", "Annotated", "Parameter", "remote", "manual"] + - ["org.kohsuke.stapler", "Header", True, "", "", "Annotated", "Parameter", "remote", "manual"] + - ["org.kohsuke.stapler", "DataBoundConstructor", True, "", "", "Annotated", "Parameter", "remote", "manual"] + - ["org.kohsuke.stapler", "DataBoundSetter", True, "", "", "Annotated", "Parameter", "remote", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index 1a009c1f2e6..f049a0cb37b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -41,6 +41,7 @@ abstract class RemoteFlowSource extends DataFlow::Node { */ private module FlowSources { private import semmle.code.java.frameworks.hudson.Hudson + private import semmle.code.java.frameworks.stapler.Stapler } private class ExternalRemoteFlowSource extends RemoteFlowSource { diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll index 9a187c027ff..1619965f0f0 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll @@ -23,6 +23,7 @@ private module Frameworks { private import semmle.code.java.frameworks.Properties private import semmle.code.java.frameworks.Protobuf private import semmle.code.java.frameworks.ratpack.RatpackExec + private import semmle.code.java.frameworks.stapler.Stapler private import semmle.code.java.JDK } diff --git a/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll b/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll index aab962e65aa..c283c23a046 100644 --- a/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll @@ -2,8 +2,17 @@ import java private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.frameworks.stapler.Stapler private import semmle.code.java.security.XSS +/** A method declared in a subtype of `hudson.model.Descriptor` that returns an `HttpResponse`. */ +class HudsonWebMethod extends Method { + HudsonWebMethod() { + this.getReturnType().(RefType).getASourceSupertype*() instanceof HttpResponse and + this.getDeclaringType().getASourceSupertype*().hasQualifiedName("hudson.model", "Descriptor") + } +} + private class FilePathRead extends LocalUserInput { FilePathRead() { this.asExpr() diff --git a/java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll b/java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll new file mode 100644 index 00000000000..dbccfc99c04 --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll @@ -0,0 +1,124 @@ +/** Provides classes and predicates related to the Stapler framework. */ + +import java +private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.FlowSteps +private import semmle.code.java.dataflow.TypeFlow +private import semmle.code.java.frameworks.hudson.Hudson +private import semmle.code.java.frameworks.JavaxAnnotations + +/** + * A callable annotated with a Stapler `DataBound` annotation, + * or that has the `@stapler-constructor` Javadoc annotation. + */ +class DataBoundAnnotated extends Callable { + DataBoundAnnotated() { + exists(Annotation an | + an.getType() + .hasQualifiedName("org.kohsuke.stapler", ["DataBoundConstructor", "DataBoundSetter"]) + | + this = an.getAnnotatedElement() + ) + or + exists(Javadoc doc | doc.getAChild().getText().matches("%@stapler-constructor%") | + doc.getCommentedElement() = this + ) + } +} + +/** The interface `org.kohsuke.stapler.HttpResponse`. */ +class HttpResponse extends Interface { + HttpResponse() { this.hasQualifiedName("org.kohsuke.stapler", "HttpResponse") } +} + +/** + * A remote flow source for parameters annotated with an annotation + * that is itself annotated with `InjectedParameter`. + * + * Such parameters are populated with user-provided data by Stapler. + */ +private class InjectedParameterSource extends RemoteFlowSource { + InjectedParameterSource() { + this.asParameter().getAnAnnotation().getType() instanceof InjectedParameterAnnotatedType + } + + override string getSourceType() { result = "Stapler injected parameter" } +} + +/** + * A dataflow step from the `HttpResponse` return value of a `HudsonWebMethod` + * to the instance parameter of the `generateResponse` method of the appropriate subtype of `HttpResponse`. + * + * This models the rendering process of an `HttpResponse` by Stapler. + */ +private class HttpResponseGetDescriptionStep extends AdditionalValueStep { + override predicate step(DataFlow::Node n1, DataFlow::Node n2) { + exists(ReturnStmt s, GenerateResponseMethod m | + s.getEnclosingCallable() instanceof HudsonWebMethod and + boundOrStaticType(s.getResult(), m.getDeclaringType().getADescendant()) + | + n1.asExpr() = s.getResult() and + n2.(DataFlow::InstanceParameterNode).getCallable() = m + ) + } +} + +/** + * A dataflow step from the post-update node of an instance access in a `DataBoundAnnotated` method + * to the instance parameter of a `PostConstruct` method of the same type. + * + * This models the construction process of a `DataBound` object in Stapler. + */ +private class PostConstructDataBoundAdditionalStep extends AdditionalValueStep { + override predicate step(DataFlow::Node n1, DataFlow::Node n2) { + exists(PostConstructDataBoundMethod postConstruct, DataBoundAnnotated input | + postConstruct.getDeclaringType() = input.getDeclaringType() + | + n1.(DataFlow::PostUpdateNode) + .getPreUpdateNode() + .(DataFlow::InstanceAccessNode) + .getEnclosingCallable() = input and + n2.(DataFlow::InstanceParameterNode).getCallable() = postConstruct + ) + } +} + +/** An annotation type annotated with the `InjectedParameter` annotation. */ +private class InjectedParameterAnnotatedType extends AnnotationType { + InjectedParameterAnnotatedType() { + this.getAnAnnotation().getType().hasQualifiedName("org.kohsuke.stapler", "InjectedParameter") + } +} + +/** The `generateResponse` method of `org.kohsuke.stapler.HttpResponse` or its subtypes. */ +private class GenerateResponseMethod extends Method { + GenerateResponseMethod() { + this.getDeclaringType().getASourceSupertype*() instanceof HttpResponse and + this.hasName("generateResponse") + } +} + +/** Gets the static type of `e`, or an upper bound of the runtime type of `e`. */ +private predicate boundOrStaticType(Expr e, RefType t) { + exprTypeFlow(e, t, false) + or + t = e.getType() +} + +/** + * A method called after the construction of a `DataBound` object. + * + * That is, either the `bindResolve` method of a subtype of `org.kohsuke.stapler.DataBoundResolvable`, + * or a method annotated with `javax.annotation.PostConstruct`. + */ +private class PostConstructDataBoundMethod extends Method { + PostConstructDataBoundMethod() { + this.getDeclaringType() + .getASourceSupertype*() + .hasQualifiedName("org.kohsuke.stapler", "DataBoundResolvable") and + this.hasName("bindResolve") + or + this.getAnAnnotation() instanceof PostConstructAnnotation + } +} diff --git a/java/ql/test/library-tests/dataflow/taintsources/Stapler.java b/java/ql/test/library-tests/dataflow/taintsources/Stapler.java new file mode 100644 index 00000000000..96be00270ba --- /dev/null +++ b/java/ql/test/library-tests/dataflow/taintsources/Stapler.java @@ -0,0 +1,14 @@ +import org.kohsuke.stapler.InjectedParameter; + +public class Stapler { + + @InjectedParameter + private @interface MyInjectedParameter { + } + + private static void sink(Object o) {} + + public static void test(@MyInjectedParameter String src) { + sink(src); // $ hasRemoteValueFlow + } +} diff --git a/java/ql/test/library-tests/dataflow/taintsources/options b/java/ql/test/library-tests/dataflow/taintsources/options index bd30b3e8c95..c8249b05e38 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/options +++ b/java/ql/test/library-tests/dataflow/taintsources/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/akka-2.6.x:${testdir}/../../../stubs/jwtk-jjwt-0.11.2:${testdir}/../../../stubs/jenkins \ No newline at end of file +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/akka-2.6.x:${testdir}/../../../stubs/jwtk-jjwt-0.11.2:${testdir}/../../../stubs/jenkins:${testdir}/../../../stubs/stapler-1.263 \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/stapler/DataBoundPostConstructTest.java b/java/ql/test/library-tests/frameworks/stapler/DataBoundPostConstructTest.java new file mode 100644 index 00000000000..efab6d956d2 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/stapler/DataBoundPostConstructTest.java @@ -0,0 +1,42 @@ +import javax.annotation.PostConstruct; +import net.sf.json.JSONObject; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundResolvable; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.StaplerRequest; + +public class DataBoundPostConstructTest implements DataBoundResolvable { + + static Object source(String label) { + return null; + } + + static void sink(Object o) {} + + static void test() { + new DataBoundPostConstructTest(source("constructor")); + new DataBoundPostConstructTest(null).setField(source("setter")); + } + + private Object field; + + @DataBoundConstructor + public DataBoundPostConstructTest(Object field) { + this.field = field; + } + + @DataBoundSetter + public void setField(Object field) { + this.field = field; + } + + private Object bindResolve(StaplerRequest request, JSONObject src) { + sink(this.field); // $ hasValueFlow=constructor hasValueFlow=setter + return null; + } + + @PostConstruct + private void post() { + sink(this.field); // $ hasValueFlow=constructor hasValueFlow=setter + } +} diff --git a/java/ql/test/library-tests/frameworks/stapler/HttpResponseTest.java b/java/ql/test/library-tests/frameworks/stapler/HttpResponseTest.java new file mode 100644 index 00000000000..d437d1a7de3 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/stapler/HttpResponseTest.java @@ -0,0 +1,26 @@ +import hudson.model.Descriptor; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +public class HttpResponseTest { + + Object source() { + return null; + } + + void sink(Object o) {} + + private class MyDescriptor extends Descriptor<Object> { + public HttpResponse doTest() { + return (MyHttpResponse) source(); + } + } + + private class MyHttpResponse implements HttpResponse { + @Override + public void generateResponse(StaplerRequest p0, StaplerResponse p1, Object p2) { + sink(this); // $ hasValueFlow + } + } +} diff --git a/java/ql/test/library-tests/frameworks/stapler/options b/java/ql/test/library-tests/frameworks/stapler/options index 5b75976846a..52f4c738a88 100644 --- a/java/ql/test/library-tests/frameworks/stapler/options +++ b/java/ql/test/library-tests/frameworks/stapler/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/jaxen-1.2.0 \ No newline at end of file +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/jenkins:${testdir}/../../../stubs/javax-annotation-api-1.3.2 \ No newline at end of file diff --git a/java/ql/test/stubs/javax-annotation-api-1.3.2/javax/annotation/PostConstruct.java b/java/ql/test/stubs/javax-annotation-api-1.3.2/javax/annotation/PostConstruct.java new file mode 100644 index 00000000000..a7fde6ae23b --- /dev/null +++ b/java/ql/test/stubs/javax-annotation-api-1.3.2/javax/annotation/PostConstruct.java @@ -0,0 +1,13 @@ +package javax.annotation; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Documented +@Retention(RUNTIME) +@Target(METHOD) +public @interface PostConstruct { +} diff --git a/java/ql/test/stubs/jenkins/hudson/model/Descriptor.java b/java/ql/test/stubs/jenkins/hudson/model/Descriptor.java new file mode 100644 index 00000000000..613ed31f665 --- /dev/null +++ b/java/ql/test/stubs/jenkins/hudson/model/Descriptor.java @@ -0,0 +1,5 @@ +package hudson.model; + +public abstract class Descriptor<T> { + +} diff --git a/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundConstructor.java b/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundConstructor.java new file mode 100644 index 00000000000..6909171def8 --- /dev/null +++ b/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundConstructor.java @@ -0,0 +1,13 @@ +package org.kohsuke.stapler; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(CONSTRUCTOR) +@Documented +public @interface DataBoundConstructor { +} diff --git a/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundResolvable.java b/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundResolvable.java new file mode 100644 index 00000000000..0fc9cffd0aa --- /dev/null +++ b/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundResolvable.java @@ -0,0 +1,4 @@ +package org.kohsuke.stapler; + +public interface DataBoundResolvable { +} diff --git a/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundSetter.java b/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundSetter.java new file mode 100644 index 00000000000..ff11084fcbd --- /dev/null +++ b/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/DataBoundSetter.java @@ -0,0 +1,14 @@ +package org.kohsuke.stapler; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({METHOD, FIELD}) +@Documented +public @interface DataBoundSetter { +} diff --git a/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/InjectedParameter.java b/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/InjectedParameter.java new file mode 100644 index 00000000000..1674e667233 --- /dev/null +++ b/java/ql/test/stubs/stapler-1.263/org/kohsuke/stapler/InjectedParameter.java @@ -0,0 +1,13 @@ +package org.kohsuke.stapler; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.ANNOTATION_TYPE;; + +@Retention(RUNTIME) +@Target(ANNOTATION_TYPE) +@Documented +public @interface InjectedParameter { +} From 38cca08a865c5c53af9c6d93c7eef358d07d4b98 Mon Sep 17 00:00:00 2001 From: yoff <lerchedahl@gmail.com> Date: Wed, 14 Jun 2023 13:27:33 +0200 Subject: [PATCH 551/739] Apply suggestions from code review Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com> --- .../ql/lib/change-notes/2023-06-13-container-store-steps.md | 2 +- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/lib/change-notes/2023-06-13-container-store-steps.md b/python/ql/lib/change-notes/2023-06-13-container-store-steps.md index 1edff243128..3e12554a92b 100644 --- a/python/ql/lib/change-notes/2023-06-13-container-store-steps.md +++ b/python/ql/lib/change-notes/2023-06-13-container-store-steps.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* More precise modelling of several container functions and methods. +* More precise modelling of several container functions (such as `sorted`, `reversed`) and methods (such as `set.add`, `list.append`). diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 641dba0779e..ed9d33c16bb 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4349,7 +4349,7 @@ private module StdlibPrivate { output = "Argument[self].ListElement" and preservesValue = true or - // transfer taint from new element to this + // transfer taint from new element to this (TODO: remove in future when taint-handling is more in line with other languages) input = "Argument[0]" and output = "Argument[self]" and preservesValue = false @@ -4391,7 +4391,7 @@ private module StdlibPrivate { output = "Argument[self].SetElement" and preservesValue = true or - // transfer taint from new element to this + // transfer taint from new element to this (TODO: remove in future when taint-handling is more in line with other languages) input = "Argument[0]" and output = "Argument[self]" and preservesValue = false From 3b558a0044b3ba453318c299bf83153df1606dd3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 14 Jun 2023 13:35:37 +0200 Subject: [PATCH 552/739] python: remove spurious return flow --- .../lib/semmle/python/frameworks/Stdlib.qll | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index ed9d33c16bb..309cc80b034 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4339,11 +4339,6 @@ private module StdlibPrivate { output = "ReturnValue.ListElement" and preservesValue = true or - // newly added element returned - input = "Argument[0]" and - output = "ReturnValue.ListElement" and - preservesValue = true - or // newly added element added to this input = "Argument[0]" and output = "Argument[self].ListElement" and @@ -4353,11 +4348,6 @@ private module StdlibPrivate { input = "Argument[0]" and output = "Argument[self]" and preservesValue = false - or - // transfer taint from new element to return value - input = "Argument[0]" and - output = "ReturnValue" and - preservesValue = false } } @@ -4381,11 +4371,6 @@ private module StdlibPrivate { output = "ReturnValue.SetElement" and preservesValue = true or - // newly added element returned - input = "Argument[0]" and - output = "ReturnValue.SetElement" and - preservesValue = true - or // newly added element added to this input = "Argument[0]" and output = "Argument[self].SetElement" and @@ -4395,11 +4380,6 @@ private module StdlibPrivate { input = "Argument[0]" and output = "Argument[self]" and preservesValue = false - or - // transfer taint from new element to return value - input = "Argument[0]" and - output = "ReturnValue" and - preservesValue = false } } } From f26c514426b8d228f50e0b82b81ae66bc64bad96 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 12 May 2023 14:49:06 +0200 Subject: [PATCH 553/739] C#: Remove the JumpReturnKind and the related summary component stack. --- .../code/csharp/dataflow/FlowSummary.qll | 12 ------- .../dataflow/internal/DataFlowDispatch.qll | 33 ------------------- .../dataflow/internal/DataFlowPrivate.qll | 9 +---- .../internal/FlowSummaryImplSpecific.qll | 11 +------ 4 files changed, 2 insertions(+), 63 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll index fc4e68f2448..fef05b35f0b 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll @@ -64,15 +64,6 @@ module SummaryComponent { /** Gets a summary component that represents the return value of a call. */ SummaryComponent return() { result = return(any(DataFlowDispatch::NormalReturnKind rk)) } - /** Gets a summary component that represents a jump to `c`. */ - SummaryComponent jump(Callable c) { - result = - return(any(DataFlowDispatch::JumpReturnKind jrk | - jrk.getTarget() = c.getUnboundDeclaration() and - jrk.getTargetReturnKind() instanceof DataFlowDispatch::NormalReturnKind - )) - } - predicate syntheticGlobal = SummaryComponentInternal::syntheticGlobal/1; class SyntheticGlobal = SummaryComponentInternal::SyntheticGlobal; @@ -114,9 +105,6 @@ module SummaryComponentStack { /** Gets a singleton stack representing the return value of a call. */ SummaryComponentStack return() { result = singleton(SummaryComponent::return()) } - /** Gets a singleton stack representing a jump to `c`. */ - SummaryComponentStack jump(Callable c) { result = singleton(SummaryComponent::jump(c)) } - /** Gets a singleton stack representing a synthetic global with name `name`. */ SummaryComponentStack syntheticGlobal(string synthetic) { result = singleton(SummaryComponent::syntheticGlobal(synthetic)) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index 4e37d14805b..cb26a1c2075 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -74,18 +74,6 @@ newtype TReturnKind = exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowOut(_, _) | v = def.getSourceVariable().getAssignable() ) - } or - TJumpReturnKind(Callable target, ReturnKind rk) { - target.isUnboundDeclaration() and - ( - rk instanceof NormalReturnKind and - ( - target instanceof Constructor or - not target.getReturnType() instanceof VoidType - ) - or - exists(target.getParameter(rk.(OutRefReturnKind).getPosition())) - ) } /** @@ -257,27 +245,6 @@ class ImplicitCapturedReturnKind extends ReturnKind, TImplicitCapturedReturnKind override string toString() { result = "captured " + v } } -/** - * A value returned through the output of another callable. - * - * This is currently only used to model flow summaries where data may flow into - * one API entry point and out of another. - */ -class JumpReturnKind extends ReturnKind, TJumpReturnKind { - private Callable target; - private ReturnKind rk; - - JumpReturnKind() { this = TJumpReturnKind(target, rk) } - - /** Gets the target of the jump. */ - Callable getTarget() { result = target } - - /** Gets the return kind of the target. */ - ReturnKind getTargetReturnKind() { result = rk } - - override string toString() { result = "jump to " + target } -} - /** A callable used for data flow. */ class DataFlowCallable extends TDataFlowCallable { /** Get the underlying source code callable, if any. */ diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index a3aed9f9097..da26fc1de43 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -1457,8 +1457,7 @@ private module ReturnNodes { private ReturnKind rk; SummaryReturnNode() { - FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) and - not rk instanceof JumpReturnKind + FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) or exists(Parameter p, int pos | summaryPostUpdateNodeIsOutOrRef(this, p) and @@ -1708,12 +1707,6 @@ predicate jumpStep(Node pred, Node succ) { flr.hasNonlocalValue() ) or - exists(JumpReturnKind jrk, NonDelegateDataFlowCall call | - FlowSummaryImpl::Private::summaryReturnNode(pred.(FlowSummaryNode).getSummaryNode(), jrk) and - jrk.getTarget() = call.getATarget(_) and - succ = getAnOutNode(call, jrk.getTargetReturnKind()) - ) - or FlowSummaryImpl::Private::Steps::summaryJumpStep(pred.(FlowSummaryNode).getSummaryNode(), succ.(FlowSummaryNode).getSummaryNode()) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index 2a6bed67596..3c0b6329f36 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -61,7 +61,7 @@ DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { ) } -private DataFlowType getReturnTypeBase(DotNet::Callable c, ReturnKind rk) { +DataFlowType getReturnType(DotNet::Callable c, ReturnKind rk) { exists(Type t | result = Gvn::getGlobalValueNumber(t) | rk instanceof NormalReturnKind and ( @@ -75,15 +75,6 @@ private DataFlowType getReturnTypeBase(DotNet::Callable c, ReturnKind rk) { ) } -/** Gets the return type of kind `rk` for callable `c`. */ -bindingset[c] -DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { - result = getReturnTypeBase(c, rk) - or - rk = - any(JumpReturnKind jrk | result = getReturnTypeBase(jrk.getTarget(), jrk.getTargetReturnKind())) -} - /** * Gets the type of the parameter matching arguments at position `pos` in a * synthesized call that targets a callback of type `t`. From 7c4cdbf0d662509f00661d2d757a8c47241ffc17 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Wed, 14 Jun 2023 14:20:16 +0200 Subject: [PATCH 554/739] Remove badly generated models --- java/ql/lib/ext/generated/jenkins-json-lib.model.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/java/ql/lib/ext/generated/jenkins-json-lib.model.yml b/java/ql/lib/ext/generated/jenkins-json-lib.model.yml index 1726e603857..b028104472f 100644 --- a/java/ql/lib/ext/generated/jenkins-json-lib.model.yml +++ b/java/ql/lib/ext/generated/jenkins-json-lib.model.yml @@ -353,10 +353,6 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.util", "Collection<Object>", "isEmpty", "()", "summary", "df-generated"] - - ["java.util", "Collection<Object>", "size", "()", "summary", "df-generated"] - - ["java.util", "Map<String,Object>", "isEmpty", "()", "summary", "df-generated"] - - ["java.util", "Map<String,Object>", "size", "()", "summary", "df-generated"] - ["net.sf.json.filters", "CompositePropertyFilter", "removePropertyFilter", "(PropertyFilter)", "summary", "df-generated"] - ["net.sf.json.filters", "MappingPropertyFilter", "removePropertyFilter", "(Object)", "summary", "df-generated"] - ["net.sf.json.groovy", "JsonSlurper", "parse", "(File)", "summary", "df-generated"] From 9a1e895fdc7a5553c66e43cceb73fca75fa9e720 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 14 Jun 2023 14:51:21 +0200 Subject: [PATCH 555/739] Python: missed removing these `set.add` and `list.append` do not return a value --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 309cc80b034..ec8d808d9ea 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4334,11 +4334,6 @@ private module StdlibPrivate { } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - // existing elements - input = "Argument[self].ListElement" and - output = "ReturnValue.ListElement" and - preservesValue = true - or // newly added element added to this input = "Argument[0]" and output = "Argument[self].ListElement" and @@ -4366,11 +4361,6 @@ private module StdlibPrivate { } override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - // existing elements - input = "Argument[self].SetElement" and - output = "ReturnValue.SetElement" and - preservesValue = true - or // newly added element added to this input = "Argument[0]" and output = "Argument[self].SetElement" and From 77f52e4e01c4507fc7c9a104c3f0c7d9fe44c84f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Wed, 14 Jun 2023 14:52:10 +0200 Subject: [PATCH 556/739] Swift: better join order fix for NamedPattern.getVarDecl This brings it down to 85ms when run from a query, not just from quick-eval: ``` [2023-06-14 14:47:06] Evaluated non-recursive predicate NamedPattern#1696c0d8::NamedPattern::getVarDecl#0#dispred#ff@04392e6o in 85ms (size: 91309). Evaluated relational algebra for predicate NamedPattern#1696c0d8::NamedPattern::getVarDecl#0#dispred#ff@04392e6o with tuple counts: 1310544 ~9% {2} r1 = SCAN var_decls OUTPUT In.0, In.1 1209062 ~0% {2} r2 = STREAM DEDUP r1 1209062 ~0% {2} r3 = JOIN r2 WITH Synth#5f134a93::Synth::convertVarDeclToRaw#1#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 91309 ~0% {3} r4 = JOIN r3 WITH VarDecl#914e0d1e::Generated::VarDecl::getImmediateParentPattern#0#dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0 69599 ~0% {3} r5 = JOIN r4 WITH #Pattern#19b8cf65::Pattern::getImmediateEnclosingPattern#0#dispredPlus#bf_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2 160908 ~1% {3} r6 = r4 UNION r5 94246 ~0% {4} r7 = JOIN r6 WITH Synth#5f134a93::Synth::convertNamedPatternToRaw#1#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.0 91309 ~1% {2} r8 = JOIN r7 WITH named_patterns ON FIRST 2 OUTPUT Lhs.3, Lhs.2 return r8 ``` --- swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll index f55087f0f8e..39b7ade299e 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll @@ -20,8 +20,7 @@ class NamedPattern extends Generated::NamedPattern { */ VarDecl getVarDecl() { this.getImmediateEnclosingPattern*() = result.getImmediateParentPattern() and - pragma[only_bind_out](pragma[only_bind_into](result).getName()) = - pragma[only_bind_out](pragma[only_bind_into](this).getName()) + pragma[only_bind_out](result.getName()) = pragma[only_bind_out](this.getName()) } override string toString() { result = this.getName() } From d071b463a3426af8186dc15c9aa131395e468217 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 14:14:37 +0100 Subject: [PATCH 557/739] Add failing tests for MaD with pointer content --- .../dataflow/ExternalFlow/completetest.ext.yml | 2 ++ .../semmle/go/dataflow/ExternalFlow/test.go | 16 ++++++++++++++++ .../vendor/github.com/nonexistent/test/stub.go | 3 +++ 3 files changed, 21 insertions(+) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ext.yml index 79ca023562c..4ec8602daaf 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ext.yml @@ -22,7 +22,9 @@ extensions: - ["github.com/nonexistent/test", "", False, "GetMapKey", "", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] - ["github.com/nonexistent/test", "", False, "SetElement", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] - ["github.com/nonexistent/test", "C", False, "Get", "", "", "Argument[-1].Field[github.com/nonexistent/test.C.F]", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "C", False, "GetThroughPointer", "", "", "Argument[-1].Field[github.com/nonexistent/test.C.F]", "ReturnValue", "value", "manual"] - ["github.com/nonexistent/test", "C", False, "Set", "", "", "Argument[0]", "Argument[-1].Field[github.com/nonexistent/test.C.F]", "value", "manual"] + - ["github.com/nonexistent/test", "C", False, "SetThroughPointer", "", "", "Argument[0]", "Argument[-1].Field[github.com/nonexistent/test.C.F]", "value", "manual"] - addsTo: pack: codeql/go-all diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/test.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/test.go index a70b2868f58..0d92787b65c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/test.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/test.go @@ -141,6 +141,22 @@ func simpleflow() { c4.Set("") b.Sink1(c4.Get()) // $ SPURIOUS: hasTaintFlow="call to Get" // because we currently don't clear content + cp1 := &test.C{""} + cp1.SetThroughPointer(a.Src1().(string)) + b.Sink1(cp1.F) // $ MISSING: hasTaintFlow="selection of F" + + cp2 := &test.C{a.Src1().(string)} + b.Sink1(cp2.GetThroughPointer()) // $ MISSING: hasTaintFlow="call to GetThroughPointer" + + cp3 := &test.C{""} + cp3.SetThroughPointer(a.Src1().(string)) + b.Sink1(cp3.GetThroughPointer()) // $ hasTaintFlow="call to GetThroughPointer" + + cp4 := &test.C{""} + cp4.SetThroughPointer(a.Src1().(string)) + cp4.SetThroughPointer("") + b.Sink1(cp4.GetThroughPointer()) // $ SPURIOUS: hasTaintFlow="call to GetThroughPointer" // because we currently don't clear content + arg1 := src arg2 := src arg3 := src diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/vendor/github.com/nonexistent/test/stub.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/vendor/github.com/nonexistent/test/stub.go index 2f13fce84e7..746f6ac9a6a 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/vendor/github.com/nonexistent/test/stub.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/vendor/github.com/nonexistent/test/stub.go @@ -67,3 +67,6 @@ type C struct { func (c C) Set(f string) {} func (c C) Get() string { return "" } + +func (c *C) SetThroughPointer(f string) {} +func (c *C) GetThroughPointer() string { return "" } From dd57d9fd550d0351a225d9ae5559d210285cf140 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 14:27:58 +0100 Subject: [PATCH 558/739] Add flowCheckNodeSpecific This allows individual languages to specify `FlowCheckNode`s, which break up the big step relation and make sure that those nodes appear in path summaries. --- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 984c5ae2018..41341c6be5c 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> { FlowCheckNode() { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) + expectsContentCached(this.asNode(), _) or + flowCheckNodeSpecific(this.asNode()) } } From e0f7437d40630621b32b437338f8cd7fb9040202 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 14:29:56 +0100 Subject: [PATCH 559/739] Sync dataflow library --- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 3 ++- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 3 ++- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 3 ++- .../ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 3 ++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll | 3 ++- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll | 3 ++- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll | 3 ++- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 984c5ae2018..41341c6be5c 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> { FlowCheckNode() { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) + expectsContentCached(this.asNode(), _) or + flowCheckNodeSpecific(this.asNode()) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 984c5ae2018..41341c6be5c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> { FlowCheckNode() { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) + expectsContentCached(this.asNode(), _) or + flowCheckNodeSpecific(this.asNode()) } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 984c5ae2018..41341c6be5c 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> { FlowCheckNode() { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) + expectsContentCached(this.asNode(), _) or + flowCheckNodeSpecific(this.asNode()) } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 984c5ae2018..41341c6be5c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> { FlowCheckNode() { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) + expectsContentCached(this.asNode(), _) or + flowCheckNodeSpecific(this.asNode()) } } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 984c5ae2018..41341c6be5c 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> { FlowCheckNode() { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) + expectsContentCached(this.asNode(), _) or + flowCheckNodeSpecific(this.asNode()) } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 984c5ae2018..41341c6be5c 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> { FlowCheckNode() { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) + expectsContentCached(this.asNode(), _) or + flowCheckNodeSpecific(this.asNode()) } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 984c5ae2018..41341c6be5c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> { FlowCheckNode() { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) + expectsContentCached(this.asNode(), _) or + flowCheckNodeSpecific(this.asNode()) } } From 5f72ce093594c5af730e16069d392a0d92d41751 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 14:36:45 +0100 Subject: [PATCH 560/739] Add stub implementations of flowCheckNodeSpecific --- .../semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll | 5 +++++ .../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 5 +++++ .../semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll | 5 +++++ go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 5 +++++ .../semmle/code/java/dataflow/internal/DataFlowPrivate.qll | 5 +++++ .../semmle/python/dataflow/new/internal/DataFlowPrivate.qll | 5 +++++ .../ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll | 5 +++++ .../lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll | 5 +++++ 8 files changed, 40 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index 115989e3dea..9b7b92f6fb8 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -235,6 +235,11 @@ class CastNode extends Node { CastNode() { none() } // stub implementation } +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { none() } + class DataFlowCallable = Function; class DataFlowExpr = Expr; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 33ff6f74775..dfd8fcbaccf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -783,6 +783,11 @@ class CastNode extends Node { CastNode() { none() } // stub implementation } +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { none() } + /** * A function that may contain code or a variable that may contain itself. When * flow crosses from one _enclosing callable_ to another, the interprocedural diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index a3aed9f9097..27d35568e09 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -2147,6 +2147,11 @@ class CastNode extends Node { } } +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { none() } + class DataFlowExpr = DotNet::Expr; /** Holds if `e` is an expression that always has the same Boolean value `val`. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index ee146fc2aba..c014e89e397 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -228,6 +228,11 @@ class CastNode extends ExprNode { override ConversionExpr expr; } +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { none() } + class DataFlowExpr = Expr; private newtype TDataFlowType = diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index ea393dad0bf..eabfa3ecfc5 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -242,6 +242,11 @@ class CastNode extends ExprNode { CastNode() { this.getExpr() instanceof CastingExpr } } +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { none() } + private newtype TDataFlowCallable = TSrcCallable(Callable c) or TSummarizedCallable(SummarizedCallable c) or diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 7f907ca84e8..98c262375e1 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -497,6 +497,11 @@ class CastNode extends Node { CastNode() { readStep(_, _, this) or storeStep(_, _, this) } } +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { none() } + /** * Holds if `t1` and `t2` are compatible, that is, whether data can flow from * a node of type `t1` to a node of type `t2`. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 0fb0bac0462..313c76dfab7 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1296,6 +1296,11 @@ class CastNode extends Node { } } +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { none() } + class DataFlowExpr = CfgNodes::ExprCfgNode; int accessPathLimit() { result = 5 } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 02ae10b83af..b18f38cbb65 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -849,6 +849,11 @@ class CastNode extends Node { CastNode() { none() } } +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { none() } + class DataFlowExpr = Expr; class DataFlowParameter = ParamDecl; From ee185ae204691b78ff58358045717e19ae342912 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 14:41:16 +0100 Subject: [PATCH 561/739] Python: Move hack from CastNode into flowCheckNodeSpecific --- .../dataflow/new/internal/DataFlowPrivate.qll | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 98c262375e1..8df16662e07 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -486,6 +486,13 @@ class DataFlowType extends TDataFlowType { /** A node that performs a type cast. */ class CastNode extends Node { + CastNode() { none() } +} + +/** + * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + */ +predicate flowCheckNodeSpecific(Node n) { // We include read- and store steps here to force them to be // shown in path explanations. // This hack is necessary, because we have included some of these @@ -494,14 +501,9 @@ class CastNode extends Node { // We should revert this once, we can remove this steps from the // default taint steps; this should be possible once we have // implemented flow summaries and recursive content. - CastNode() { readStep(_, _, this) or storeStep(_, _, this) } + readStep(_, _, n) or storeStep(_, _, n) } -/** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. - */ -predicate flowCheckNodeSpecific(Node n) { none() } - /** * Holds if `t1` and `t2` are compatible, that is, whether data can flow from * a node of type `t1` to a node of type `t2`. From e34bcef2bd2527d7ab5c77af534fe3d0ab76bb72 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 14:41:58 +0100 Subject: [PATCH 562/739] Ruby: Move path summary visibility code into flowCheckNodeSpecific --- .../codeql/ruby/dataflow/internal/DataFlowPrivate.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 313c76dfab7..6cabe899d5a 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1290,16 +1290,16 @@ private import PostUpdateNodes /** A node that performs a type cast. */ class CastNode extends Node { - CastNode() { - // ensure that all variable assignments are included in the path graph - this.(SsaDefinitionExtNode).getDefinitionExt() instanceof Ssa::WriteDefinition - } + CastNode() { none() } } /** * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. */ -predicate flowCheckNodeSpecific(Node n) { none() } +predicate flowCheckNodeSpecific(Node n) { + // ensure that all variable assignments are included in the path graph + n.(SsaDefinitionExtNode).getDefinitionExt() instanceof Ssa::WriteDefinition +} class DataFlowExpr = CfgNodes::ExprCfgNode; From 22b98c8959cbbad130c3f56d571ef9780d8ce518 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Wed, 14 Jun 2023 15:48:58 +0200 Subject: [PATCH 563/739] JS: Restrict length of state path in vuex model --- javascript/ql/lib/semmle/javascript/frameworks/Vuex.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Vuex.qll b/javascript/ql/lib/semmle/javascript/frameworks/Vuex.qll index 74e02422876..6e111207790 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Vuex.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Vuex.qll @@ -289,7 +289,8 @@ module Vuex { or exists(string base, string prop | result = stateRefByAccessPath(base).getMember(prop) and - path = appendToNamespace(base, prop) + path = appendToNamespace(base, prop) and + path.length() < 100 ) } From 396b57696cede9a56f44c887b658ce902ce8ccce Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Thu, 6 Apr 2023 17:27:24 +0200 Subject: [PATCH 564/739] Swift: minimal 5.8 compatibility --- .../actions/run-integration-tests/action.yml | 2 +- swift/extractor/infra/SwiftTagTraits.h | 26 ++++++++++++------- .../extractor/translators/ExprTranslator.cpp | 2 +- swift/extractor/translators/ExprTranslator.h | 2 +- swift/ql/.generated.list | 4 +-- swift/ql/lib/codeql/swift/generated/Raw.qll | 2 +- .../swift/generated/expr/CaptureListExpr.qll | 10 +++---- swift/ql/lib/swift.dbscheme | 12 ++++----- .../test/library-tests/ast/PrintAst.expected | 4 +-- swift/schema.py | 2 +- .../BUILD.swift-llvm-support.bazel | 19 ++------------ swift/third_party/load.bzl | 8 +++--- 12 files changed, 43 insertions(+), 50 deletions(-) diff --git a/swift/actions/run-integration-tests/action.yml b/swift/actions/run-integration-tests/action.yml index bf46b22558f..58bd728d7e1 100644 --- a/swift/actions/run-integration-tests/action.yml +++ b/swift/actions/run-integration-tests/action.yml @@ -13,7 +13,7 @@ runs: - uses: actions/setup-python@v4 with: python-version-file: 'swift/.python-version' - - uses: swift-actions/setup-swift@da0e3e04b5e3e15dbc3861bd835ad9f0afe56296 + - uses: swift-actions/setup-swift@65540b95f51493d65f5e59e97dcef9629ddf11bf with: swift-version: "${{steps.get_swift_version.outputs.version}}" - uses: ./.github/actions/fetch-codeql diff --git a/swift/extractor/infra/SwiftTagTraits.h b/swift/extractor/infra/SwiftTagTraits.h index 3ba1b25bfcc..0371a783bb7 100644 --- a/swift/extractor/infra/SwiftTagTraits.h +++ b/swift/extractor/infra/SwiftTagTraits.h @@ -95,6 +95,7 @@ MAP(swift::Expr, ExprTag) MAP(swift::IdentityExpr, IdentityExprTag) MAP(swift::ParenExpr, ParenExprTag) MAP(swift::DotSelfExpr, DotSelfExprTag) + MAP(swift::MoveExpr, void) // TODO (introduced in 5.8) MAP(swift::AwaitExpr, AwaitExprTag) MAP(swift::UnresolvedMemberChainResultExpr, UnresolvedMemberChainResultExprTag) MAP(swift::AnyTryExpr, AnyTryExprTag) @@ -113,6 +114,8 @@ MAP(swift::Expr, ExprTag) MAP(swift::AutoClosureExpr, AutoClosureExprTag) MAP(swift::InOutExpr, InOutExprTag) MAP(swift::VarargExpansionExpr, VarargExpansionExprTag) + MAP(swift::PackExpansionExpr, void) // TODO (introduced in 5.8) + MAP(swift::PackElementExpr, void) // TODO (introduced in 5.8) MAP(swift::DynamicTypeExpr, DynamicTypeExprTag) MAP(swift::RebindSelfInConstructorExpr, RebindSelfInInitializerExprTag) MAP(swift::OpaqueValueExpr, OpaqueValueExprTag) @@ -164,7 +167,6 @@ MAP(swift::Expr, ExprTag) MAP(swift::DifferentiableFunctionExtractOriginalExpr, DifferentiableFunctionExtractOriginalExprTag) MAP(swift::LinearFunctionExtractOriginalExpr, LinearFunctionExtractOriginalExprTag) MAP(swift::LinearToDifferentiableFunctionExpr, LinearToDifferentiableFunctionExprTag) - MAP(swift::ReifyPackExpr, void) // experimental variadic generics MAP(swift::ABISafeConversionExpr, AbiSafeConversionExprTag) // different acronym convention MAP(swift::ExplicitCastExpr, ExplicitCastExprTag) MAP(swift::CheckedCastExpr, CheckedCastExprTag) @@ -173,7 +175,7 @@ MAP(swift::Expr, ExprTag) MAP(swift::IsExpr, IsExprTag) MAP(swift::CoerceExpr, CoerceExprTag) MAP(swift::ArrowExpr, void) // not present after the Sema phase - MAP(swift::IfExpr, IfExprTag) + MAP(swift::TernaryExpr, IfExprTag) MAP(swift::EnumIsCaseExpr, EnumIsCaseExprTag) MAP(swift::AssignExpr, AssignExprTag) MAP(swift::CodeCompletionExpr, void) // only generated for code editing @@ -185,8 +187,8 @@ MAP(swift::Expr, ExprTag) MAP(swift::KeyPathDotExpr, KeyPathDotExprTag) MAP(swift::OneWayExpr, OneWayExprTag) MAP(swift::TapExpr, TapExprTag) - MAP(swift::PackExpr, void) // experimental variadic generics - + MAP(swift::TypeJoinExpr, void) // TODO (introduced in 5.8) + MAP(swift::MacroExpansionExpr, void) // TODO (introduced in 5.8) MAP(swift::Decl, DeclTag) MAP(swift::ValueDecl, ValueDeclTag) MAP(swift::TypeDecl, TypeDeclTag) @@ -196,11 +198,11 @@ MAP(swift::Decl, DeclTag) MAP(swift::StructDecl, StructDeclTag) MAP(swift::ClassDecl, ClassDeclTag) MAP(swift::ProtocolDecl, ProtocolDeclTag) + MAP(swift::BuiltinTupleDecl, void) // TODO (introduced in 5.8) MAP(swift::OpaqueTypeDecl, OpaqueTypeDeclTag) MAP(swift::TypeAliasDecl, TypeAliasDeclTag) - MAP(swift::AbstractTypeParamDecl, AbstractTypeParamDeclTag) - MAP(swift::GenericTypeParamDecl, GenericTypeParamDeclTag) - MAP(swift::AssociatedTypeDecl, AssociatedTypeDeclTag) + MAP(swift::GenericTypeParamDecl, GenericTypeParamDeclTag) + MAP(swift::AssociatedTypeDecl, AssociatedTypeDeclTag) MAP(swift::ModuleDecl, ModuleDeclTag) MAP(swift::AbstractStorageDecl, AbstractStorageDeclTag) MAP(swift::VarDecl, VarDeclTag) @@ -213,6 +215,7 @@ MAP(swift::Decl, DeclTag) MAP(swift::FuncDecl, AccessorOrNamedFunctionTag) MAP_CONCRETE(swift::FuncDecl, NamedFunctionTag) MAP(swift::AccessorDecl, AccessorTag) + MAP(swift::MacroDecl, void) // TODO (introduced in 5.8) MAP(swift::EnumElementDecl, EnumElementDeclTag) MAP(swift::ExtensionDecl, ExtensionDeclTag) MAP(swift::TopLevelCodeDecl, TopLevelCodeDeclTag) @@ -227,6 +230,7 @@ MAP(swift::Decl, DeclTag) MAP(swift::InfixOperatorDecl, InfixOperatorDeclTag) MAP(swift::PrefixOperatorDecl, PrefixOperatorDeclTag) MAP(swift::PostfixOperatorDecl, PostfixOperatorDeclTag) + MAP(swift::MacroExpansionDecl, void) // TODO (introduced in 5.8) MAP(swift::Pattern, PatternTag) MAP(swift::ParenPattern, ParenPatternTag) @@ -274,6 +278,7 @@ MAP(swift::TypeBase, TypeTag) MAP(swift::StructType, StructTypeTag) MAP(swift::ClassType, ClassTypeTag) MAP(swift::ProtocolType, ProtocolTypeTag) + MAP(swift::BuiltinTupleType, void) // TODO (introduced in 5.8) MAP(swift::BoundGenericType, BoundGenericTypeTag) MAP(swift::BoundGenericClassType, BoundGenericClassTypeTag) MAP(swift::BoundGenericEnumType, BoundGenericEnumTypeTag) @@ -288,8 +293,10 @@ MAP(swift::TypeBase, TypeTag) MAP(swift::ArchetypeType, ArchetypeTypeTag) MAP(swift::PrimaryArchetypeType, PrimaryArchetypeTypeTag) MAP(swift::OpaqueTypeArchetypeType, OpaqueTypeArchetypeTypeTag) - MAP(swift::OpenedArchetypeType, OpenedArchetypeTypeTag) - MAP(swift::SequenceArchetypeType, void) // experimental variadic generics + MAP(swift::LocalArchetypeType, OpenedArchetypeTypeTag) // TODO (introduced in 5.8) + MAP(swift::OpenedArchetypeType, OpenedArchetypeTypeTag) + MAP(swift::ElementArchetypeType, void) // TODO (introduced in 5.8) + MAP(swift::PackArchetypeType, void) // TODO (introduced in 5.8) MAP(swift::GenericTypeParamType, GenericTypeParamTypeTag) MAP(swift::DependentMemberType, DependentMemberTypeTag) MAP(swift::AnyFunctionType, AnyFunctionTypeTag) @@ -298,6 +305,7 @@ MAP(swift::TypeBase, TypeTag) MAP(swift::SILFunctionType, void) // SIL types cannot really appear in the frontend run) MAP(swift::SILBlockStorageType, void) // SIL types cannot really appear in the frontend run) MAP(swift::SILBoxType, void) // SIL types cannot really appear in the frontend run) + MAP(swift::SILMoveOnlyWrappedType, void) // SIL types cannot really appear in the frontend run) MAP(swift::SILTokenType, void) // SIL types cannot really appear in the frontend run) MAP(swift::ProtocolCompositionType, ProtocolCompositionTypeTag) MAP(swift::ParameterizedProtocolType, ParameterizedProtocolTypeTag) diff --git a/swift/extractor/translators/ExprTranslator.cpp b/swift/extractor/translators/ExprTranslator.cpp index 6939415913b..22c0c7bf797 100644 --- a/swift/extractor/translators/ExprTranslator.cpp +++ b/swift/extractor/translators/ExprTranslator.cpp @@ -403,7 +403,7 @@ codeql::ForceValueExpr ExprTranslator::translateForceValueExpr(const swift::Forc return entry; } -codeql::IfExpr ExprTranslator::translateIfExpr(const swift::IfExpr& expr) { +codeql::IfExpr ExprTranslator::translateTernaryExpr(const swift::TernaryExpr& expr) { auto entry = createExprEntry(expr); entry.condition = dispatcher.fetchLabel(expr.getCondExpr()); entry.then_expr = dispatcher.fetchLabel(expr.getThenExpr()); diff --git a/swift/extractor/translators/ExprTranslator.h b/swift/extractor/translators/ExprTranslator.h index fe71707ad2e..504f66999cf 100644 --- a/swift/extractor/translators/ExprTranslator.h +++ b/swift/extractor/translators/ExprTranslator.h @@ -90,7 +90,7 @@ class ExprTranslator : public AstTranslatorBase<ExprTranslator> { codeql::LazyInitializationExpr translateLazyInitializerExpr( const swift::LazyInitializerExpr& expr); codeql::ForceValueExpr translateForceValueExpr(const swift::ForceValueExpr& expr); - codeql::IfExpr translateIfExpr(const swift::IfExpr& expr); + codeql::IfExpr translateTernaryExpr(const swift::TernaryExpr& expr); codeql::KeyPathDotExpr translateKeyPathDotExpr(const swift::KeyPathDotExpr& expr); codeql::KeyPathApplicationExpr translateKeyPathApplicationExpr( const swift::KeyPathApplicationExpr& expr); diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 3fac0083642..d05def16c03 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -383,7 +383,7 @@ lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d lib/codeql/swift/generated/ParentChild.qll 5c5ff9812efbed0adf465d1c8b9108c893c77ff946f6feaaec7223ad38664079 94038dcd8a5e98b959ce9f09b7b54b745b0df49b91339b9396017a209abe8bb7 lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -lib/codeql/swift/generated/Raw.qll 991f95f30bde82ba43237bd9c1a68d3f450038ef828edb89219fbf583dd1956a e3e6c41caac09d532453c28167622fae7057d846f35750873eacd48cd128b957 +lib/codeql/swift/generated/Raw.qll 7904614a526f13c336402c38e8632c8ee32e0ee7a6b5a9c2ace22fab0a5927f8 273f958f5052ae025e7361dbfd6a7a505da5fa6b4f418e83aa2a1d5f8602c54d lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814 lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -450,7 +450,7 @@ lib/codeql/swift/generated/expr/BridgeFromObjCExpr.qll b9a6520d01613dfb8c7606177 lib/codeql/swift/generated/expr/BridgeToObjCExpr.qll 31ca13762aee9a6a17746f40ec4e1e929811c81fdadb27c48e0e7ce6a3a6222d 31ca13762aee9a6a17746f40ec4e1e929811c81fdadb27c48e0e7ce6a3a6222d lib/codeql/swift/generated/expr/BuiltinLiteralExpr.qll 052f8d0e9109a0d4496da1ae2b461417951614c88dbc9d80220908734b3f70c6 536fa290bb75deae0517d53528237eab74664958bf7fdbf8041283415dda2142 lib/codeql/swift/generated/expr/CallExpr.qll c7dc105fcb6c0956e20d40f736db35bd7f38f41c3d872858972c2ca120110d36 c7dc105fcb6c0956e20d40f736db35bd7f38f41c3d872858972c2ca120110d36 -lib/codeql/swift/generated/expr/CaptureListExpr.qll 671234408ead93c0d6abc453f774a88f0888956e6ad08d5a1c22aec72b2eec46 601e23e0356341fd6287fb9775f0e86bca6a0de46383e0912854e045e501d42c +lib/codeql/swift/generated/expr/CaptureListExpr.qll 300e3e7b60d49c321c9b6209ace7cd4665dc3db1b3f4227af476c3bdaf7da196 3ccc01074fa7cef8df1f2923fb3837af59360f5bd496ccbb5f0f77d02ac9311a lib/codeql/swift/generated/expr/CheckedCastExpr.qll 146c24e72cda519676321d3bdb89d1953dfe1810d2710f04cfdc4210ace24c40 91093e0ba88ec3621b538d98454573b5eea6d43075a2ab0a08f80f9b9be336d3 lib/codeql/swift/generated/expr/ClassMetatypeToObjectExpr.qll 076c0f7369af3fffc8860429bd8e290962bf7fc8cf53bbba061de534e99cc8bf 076c0f7369af3fffc8860429bd8e290962bf7fc8cf53bbba061de534e99cc8bf lib/codeql/swift/generated/expr/ClosureExpr.qll f194fc8c5f67fcf0219e8e2de93ee2b820c27a609b2986b68d57a54445f66b61 3cae87f6c6eefb32195f06bc4c95ff6634446ecf346d3a3c94dc05c1539f3de2 diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index 38e84cd3093..122cb0291da 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -1096,7 +1096,7 @@ module Raw { /** * Gets the closure body of this capture list expression. */ - ExplicitClosureExpr getClosureBody() { capture_list_exprs(this, result) } + ClosureExpr getClosureBody() { capture_list_exprs(this, result) } } /** diff --git a/swift/ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll index 521eb9f074d..535e477d177 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/CaptureListExpr.qll @@ -1,7 +1,7 @@ // generated by codegen/codegen.py private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw -import codeql.swift.elements.expr.ExplicitClosureExpr +import codeql.swift.elements.expr.ClosureExpr import codeql.swift.elements.expr.Expr import codeql.swift.elements.decl.PatternBindingDecl @@ -35,9 +35,9 @@ module Generated { * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the * behavior of both the `Immediate` and non-`Immediate` versions. */ - ExplicitClosureExpr getImmediateClosureBody() { + ClosureExpr getImmediateClosureBody() { result = - Synth::convertExplicitClosureExprFromRaw(Synth::convertCaptureListExprToRaw(this) + Synth::convertClosureExprFromRaw(Synth::convertCaptureListExprToRaw(this) .(Raw::CaptureListExpr) .getClosureBody()) } @@ -45,8 +45,8 @@ module Generated { /** * Gets the closure body of this capture list expression. */ - final ExplicitClosureExpr getClosureBody() { - exists(ExplicitClosureExpr immediate | + final ClosureExpr getClosureBody() { + exists(ClosureExpr immediate | immediate = this.getImmediateClosureBody() and if exists(this.getResolveStep()) then result = immediate else result = immediate.resolve() ) diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 44e36e15e90..147e087e57e 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -829,7 +829,7 @@ bind_optional_exprs( //dir=expr capture_list_exprs( //dir=expr unique int id: @capture_list_expr, - int closure_body: @explicit_closure_expr_or_none ref + int closure_body: @closure_expr_or_none ref ); #keyset[id, index] @@ -2457,6 +2457,11 @@ variadic_sequence_types( //dir=type | @unspecified_element ; +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + @condition_element_or_none = @condition_element | @unspecified_element @@ -2472,11 +2477,6 @@ variadic_sequence_types( //dir=type | @unspecified_element ; -@explicit_closure_expr_or_none = - @explicit_closure_expr -| @unspecified_element -; - @expr_or_none = @expr | @unspecified_element diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index f1fbb4f1544..2708c13ddfb 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -2476,7 +2476,7 @@ cfg.swift: # 377| Type = Derived #-----| getParam(0): [ParamDecl] n #-----| Type = Int -#-----| getBody(): [BraceStmt] { ... } +# 377| getBody(): [BraceStmt] { ... } # 377| getElement(0): [CallExpr] call to _unimplementedInitializer(className:initName:file:line:column:) # 377| getFunction(): [DeclRefExpr] _unimplementedInitializer(className:initName:file:line:column:) # 377| getArgument(0): [Argument] : cfg.Derived @@ -4769,7 +4769,7 @@ expressions.swift: # 77| Type = Derived #-----| getParam(0): [ParamDecl] x #-----| Type = Int -#-----| getBody(): [BraceStmt] { ... } +# 77| getBody(): [BraceStmt] { ... } # 77| getElement(0): [CallExpr] call to _unimplementedInitializer(className:initName:file:line:column:) # 77| getFunction(): [DeclRefExpr] _unimplementedInitializer(className:initName:file:line:column:) # 77| getArgument(0): [Argument] : expressions.Derived diff --git a/swift/schema.py b/swift/schema.py index 3af02367d8a..bc917a8f6be 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -399,7 +399,7 @@ class CapturedDecl(Decl): class CaptureListExpr(Expr): binding_decls: list[PatternBindingDecl] | child - closure_body: "ExplicitClosureExpr" | child + closure_body: "ClosureExpr" | child class CollectionExpr(Expr): pass diff --git a/swift/third_party/BUILD.swift-llvm-support.bazel b/swift/third_party/BUILD.swift-llvm-support.bazel index 58796aaaacb..21a8d8801b3 100644 --- a/swift/third_party/BUILD.swift-llvm-support.bazel +++ b/swift/third_party/BUILD.swift-llvm-support.bazel @@ -2,22 +2,7 @@ load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") cc_library( name = "swift-llvm-support", - srcs = [ - "libCodeQLSwiftFrontendTool.a", - ] + select({ - "@platforms//os:linux": [ - "libCodeQLSwiftFrontendTool.so", - "libswiftCore.so", - ], - "@platforms//os:macos": [ - "libCodeQLSwiftFrontendTool.dylib", - "libswiftCore.dylib", - "libswiftCompatibility50.a", - "libswiftCompatibility51.a", - "libswiftCompatibilityConcurrency.a", - "libswiftCompatibilityDynamicReplacements.a", - ], - }), + srcs = glob(["*.a", "*.so", "*.dylib"]), hdrs = glob(["include/**/*", "stdlib/**/*" ]), linkopts = [ "-lm", @@ -34,7 +19,7 @@ cc_library( ], "//conditions:default": [], }), - includes = [ "include" ], + includes = ["include", "stdlib/public/SwiftShims"], visibility = ["//visibility:public"], ) diff --git a/swift/third_party/load.bzl b/swift/third_party/load.bzl index b909ff97e21..df21ba1a894 100644 --- a/swift/third_party/load.bzl +++ b/swift/third_party/load.bzl @@ -1,11 +1,11 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") -_swift_prebuilt_version = "swift-5.7.3-RELEASE.142" +_swift_prebuilt_version = "swift-5.8.1-RELEASE.208" _swift_sha_map = { - "Linux-X64": "398d8de54c8775c939dff95ed5bb0e04a9308a1982b4c1900cd4a5d01223f63b", - "macOS-ARM64": "397dd67ea99b9c9455794c6eb0f1664b6179fe542c7c1d3010314a3e8a905ae4", - "macOS-X64": "4b9d8e4e89f16a7c1e7edc7893aa189b37d5b4412be724a86ef59c49d11a6f75", + "Linux-X64": "1d93286d6219e5c5746938ab9287d90efea98039f022cb1433296ccbc1684bc0", + "macOS-ARM64": "a29ce5143cb2c68190e337a35ebb163e961a58b9d8826fe7f8daf4d8381ee75d", + "macOS-X64": "a7e63ea732750c783142083df20a34c8d337b9b9ba210fa6a9e5ada7b7880189", } _swift_arch_map = { From 75684eebe9e3f8fb2d03ec72fada92807befc609 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Fri, 21 Apr 2023 10:42:35 +0200 Subject: [PATCH 565/739] Swift: add 5.8 update QL test --- .../extractor-tests/updates/PrintAst.expected | 256 ++++++++++++++++++ .../extractor-tests/updates/PrintAst.qlref | 1 + .../test/extractor-tests/updates/v5.8.swift | 44 +++ 3 files changed, 301 insertions(+) create mode 100644 swift/ql/test/extractor-tests/updates/PrintAst.expected create mode 100644 swift/ql/test/extractor-tests/updates/PrintAst.qlref create mode 100644 swift/ql/test/extractor-tests/updates/v5.8.swift diff --git a/swift/ql/test/extractor-tests/updates/PrintAst.expected b/swift/ql/test/extractor-tests/updates/PrintAst.expected new file mode 100644 index 00000000000..904eee573f0 --- /dev/null +++ b/swift/ql/test/extractor-tests/updates/PrintAst.expected @@ -0,0 +1,256 @@ +v5.8.swift: +# 1| [Comment] // https://github.com/apple/swift/blob/main/CHANGELOG.md#swift-58 +# 1| +# 4| [StructDecl] Temperature +# 5| getMember(0): [PatternBindingDecl] var ... = ... +# 5| getPattern(0): [TypedPattern] ... as ... +# 5| getSubPattern(): [NamedPattern] degreesCelsius +# 5| getTypeRepr(): [TypeRepr] Double +# 5| getMember(1): [ConcreteVarDecl] degreesCelsius +# 5| Type = Double +# 5| getAccessorDecl(0): [AccessorDecl] get +# 5| InterfaceType = (Temperature) -> () -> Double +# 5| getSelfParam(): [ParamDecl] self +# 5| Type = Temperature +# 5| getBody(): [BraceStmt] { ... } +#-----| getElement(0): [ReturnStmt] return ... +#-----| getResult(): [MemberRefExpr] .degreesCelsius +#-----| getBase(): [DeclRefExpr] self +# 5| getAccessorDecl(1): [AccessorDecl] set +# 5| InterfaceType = (inout Temperature) -> (Double) -> () +# 5| getSelfParam(): [ParamDecl] self +# 5| Type = Temperature +# 5| getParam(0): [ParamDecl] value +# 5| Type = Double +# 5| getBody(): [BraceStmt] { ... } +#-----| getElement(0): [AssignExpr] ... = ... +#-----| getDest(): [MemberRefExpr] .degreesCelsius +#-----| getBase(): [DeclRefExpr] self +#-----| getSource(): [DeclRefExpr] value +# 5| getAccessorDecl(2): [AccessorDecl] _modify +# 5| InterfaceType = (inout Temperature) -> () -> () +# 5| getSelfParam(): [ParamDecl] self +# 5| Type = Temperature +# 5| getBody(): [BraceStmt] { ... } +# 5| getElement(0): [YieldStmt] yield ... +#-----| getResult(0): [InOutExpr] &... +#-----| getSubExpr(): [MemberRefExpr] .degreesCelsius +#-----| getBase(): [DeclRefExpr] self +# 4| getMember(2): [ConstructorDecl] Temperature.init(degreesCelsius:) +# 4| InterfaceType = (Temperature.Type) -> (Double) -> Temperature +# 4| getSelfParam(): [ParamDecl] self +# 4| Type = Temperature +# 4| getParam(0): [ParamDecl] degreesCelsius +# 4| Type = Double +# 7| [Comment] // ... +# 7| +# 10| [ExtensionDecl] extension of Temperature +# 13| getMember(0): [PatternBindingDecl] var ... = ... +# 13| getPattern(0): [TypedPattern] ... as ... +# 13| getSubPattern(): [NamedPattern] degreesFahrenheit +# 13| getTypeRepr(): [TypeRepr] Double +# 13| getMember(1): [ConcreteVarDecl] degreesFahrenheit +# 13| Type = Double +# 13| getAccessorDecl(0): [AccessorDecl] get +# 13| InterfaceType = (Temperature) -> () -> Double +# 13| getSelfParam(): [ParamDecl] self +# 13| Type = Temperature +# 13| getBody(): [BraceStmt] { ... } +# 14| getElement(0): [ReturnStmt] return ... +# 14| getResult(): [BinaryExpr] ... .+(_:_:) ... +# 14| getFunction(): [MethodLookupExpr] .+(_:_:) +# 14| getBase(): [TypeExpr] Double.Type +# 14| getTypeRepr(): [TypeRepr] Double +# 14| getMethodRef(): [DeclRefExpr] +(_:_:) +# 14| getArgument(0): [Argument] : ... ./(_:_:) ... +# 14| getExpr(): [BinaryExpr] ... ./(_:_:) ... +# 14| getFunction(): [MethodLookupExpr] ./(_:_:) +# 14| getBase(): [TypeExpr] Double.Type +# 14| getTypeRepr(): [TypeRepr] Double +# 14| getMethodRef(): [DeclRefExpr] /(_:_:) +# 14| getArgument(0): [Argument] : ... .*(_:_:) ... +# 14| getExpr(): [BinaryExpr] ... .*(_:_:) ... +# 14| getFunction(): [MethodLookupExpr] .*(_:_:) +# 14| getBase(): [TypeExpr] Double.Type +# 14| getTypeRepr(): [TypeRepr] Double +# 14| getMethodRef(): [DeclRefExpr] *(_:_:) +# 14| getArgument(0): [Argument] : .degreesCelsius +# 14| getExpr(): [MemberRefExpr] .degreesCelsius +# 14| getBase(): [DeclRefExpr] self +# 14| getArgument(1): [Argument] : 9 +# 14| getExpr(): [IntegerLiteralExpr] 9 +# 14| getArgument(1): [Argument] : 5 +# 14| getExpr(): [IntegerLiteralExpr] 5 +# 14| getExpr().getFullyConverted(): [ParenExpr] (...) +# 14| getArgument(1): [Argument] : 32 +# 14| getExpr(): [IntegerLiteralExpr] 32 +# 18| [ConcreteFuncDecl] collectionDowncast(_:) +# 18| InterfaceType = ([Any]) -> () +# 18| getParam(0): [ParamDecl] arr +# 18| Type = [Any] +# 18| getBody(): [BraceStmt] { ... } +# 19| getElement(0): [SwitchStmt] switch arr { ... } +# 19| getExpr(): [DeclRefExpr] arr +# 20| getCase(0): [CaseStmt] case ... +# 21| getBody(): [BraceStmt] { ... } +# 21| getElement(0): [IntegerLiteralExpr] 0 +# 20| getLabel(0): [CaseLabelItem] ... is ... +# 20| getPattern(): [IsPattern] ... is ... +# 20| getCastTypeRepr(): [TypeRepr] [Int] +# 20| getSubPattern(): [NamedPattern] ints +# 20| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 22| getCase(1): [CaseStmt] case ... +# 23| getBody(): [BraceStmt] { ... } +# 23| getElement(0): [IntegerLiteralExpr] 1 +# 22| getLabel(0): [CaseLabelItem] ... is ... +# 22| getPattern(): [IsPattern] ... is ... +# 22| getCastTypeRepr(): [TypeRepr] [Bool] +# 24| getCase(2): [CaseStmt] case ... +# 25| getBody(): [BraceStmt] { ... } +# 25| getElement(0): [IntegerLiteralExpr] 2 +# 24| getLabel(0): [CaseLabelItem] _ +# 24| getPattern(): [AnyPattern] _ +# 20| [ConcreteVarDecl] ints +# 20| Type = [Int] +# 29| [StructDecl] Button +# 30| getMember(0): [PatternBindingDecl] var ... = ... +#-----| getInit(0): [NilLiteralExpr] nil +# 30| getPattern(0): [TypedPattern] ... as ... +# 30| getSubPattern(): [NamedPattern] tapHandler +# 30| getTypeRepr(): [TypeRepr] (() -> ())? +# 30| getMember(1): [ConcreteVarDecl] tapHandler +# 30| Type = (() -> ())? +# 30| getAccessorDecl(0): [AccessorDecl] get +# 30| InterfaceType = (Button) -> () -> (() -> ())? +# 30| getSelfParam(): [ParamDecl] self +# 30| Type = Button +# 30| getBody(): [BraceStmt] { ... } +#-----| getElement(0): [ReturnStmt] return ... +#-----| getResult(): [MemberRefExpr] .tapHandler +#-----| getBase(): [DeclRefExpr] self +# 30| getAccessorDecl(1): [AccessorDecl] set +# 30| InterfaceType = (inout Button) -> ((() -> ())?) -> () +# 30| getSelfParam(): [ParamDecl] self +# 30| Type = Button +# 30| getParam(0): [ParamDecl] value +# 30| Type = (() -> ())? +# 30| getBody(): [BraceStmt] { ... } +#-----| getElement(0): [AssignExpr] ... = ... +#-----| getDest(): [MemberRefExpr] .tapHandler +#-----| getBase(): [DeclRefExpr] self +#-----| getSource(): [DeclRefExpr] value +# 30| getAccessorDecl(2): [AccessorDecl] _modify +# 30| InterfaceType = (inout Button) -> () -> () +# 30| getSelfParam(): [ParamDecl] self +# 30| Type = Button +# 30| getBody(): [BraceStmt] { ... } +# 30| getElement(0): [YieldStmt] yield ... +#-----| getResult(0): [InOutExpr] &... +#-----| getSubExpr(): [MemberRefExpr] .tapHandler +#-----| getBase(): [DeclRefExpr] self +# 29| getMember(2): [ConstructorDecl] Button.init() +# 29| InterfaceType = (Button.Type) -> () -> Button +# 29| getSelfParam(): [ParamDecl] self +# 29| Type = Button +# 29| getBody(): [BraceStmt] { ... } +# 29| getElement(0): [ReturnStmt] return +# 29| getMember(3): [ConstructorDecl] Button.init(tapHandler:) +# 29| InterfaceType = (Button.Type) -> ((() -> ())?) -> Button +# 29| getSelfParam(): [ParamDecl] self +# 29| Type = Button +# 29| getParam(0): [ParamDecl] tapHandler +# 29| Type = (() -> ())? +# 33| [ClassDecl] ViewController +# 34| getMember(0): [PatternBindingDecl] var ... = ... +# 34| getInit(0): [CallExpr] call to Button.init() +# 34| getFunction(): [MethodLookupExpr] Button.init() +# 34| getBase(): [TypeExpr] Button.Type +# 34| getTypeRepr(): [TypeRepr] Button +# 34| getMethodRef(): [DeclRefExpr] Button.init() +# 34| getPattern(0): [TypedPattern] ... as ... +# 34| getSubPattern(): [NamedPattern] button +# 34| getTypeRepr(): [TypeRepr] Button +# 34| getMember(1): [ConcreteVarDecl] button +# 34| Type = Button +# 34| getAccessorDecl(0): [AccessorDecl] get +# 34| InterfaceType = (ViewController) -> () -> Button +# 34| getSelfParam(): [ParamDecl] self +# 34| Type = ViewController +# 34| getBody(): [BraceStmt] { ... } +#-----| getElement(0): [ReturnStmt] return ... +#-----| getResult(): [MemberRefExpr] .button +#-----| getBase(): [DeclRefExpr] self +# 34| getAccessorDecl(1): [AccessorDecl] set +# 34| InterfaceType = (ViewController) -> (Button) -> () +# 34| getSelfParam(): [ParamDecl] self +# 34| Type = ViewController +# 34| getParam(0): [ParamDecl] value +# 34| Type = Button +# 34| getBody(): [BraceStmt] { ... } +#-----| getElement(0): [AssignExpr] ... = ... +#-----| getDest(): [MemberRefExpr] .button +#-----| getBase(): [DeclRefExpr] self +#-----| getSource(): [DeclRefExpr] value +# 34| getAccessorDecl(2): [AccessorDecl] _modify +# 34| InterfaceType = (ViewController) -> () -> () +# 34| getSelfParam(): [ParamDecl] self +# 34| Type = ViewController +# 34| getBody(): [BraceStmt] { ... } +# 34| getElement(0): [YieldStmt] yield ... +#-----| getResult(0): [InOutExpr] &... +#-----| getSubExpr(): [MemberRefExpr] .button +#-----| getBase(): [DeclRefExpr] self +# 36| getMember(2): [ConcreteFuncDecl] setup() +# 36| InterfaceType = (ViewController) -> () -> () +# 36| getSelfParam(): [ParamDecl] self +# 36| Type = ViewController +# 36| getBody(): [BraceStmt] { ... } +# 37| getElement(0): [AssignExpr] ... = ... +# 37| getDest(): [MemberRefExpr] .tapHandler +# 37| getBase(): [MemberRefExpr] .button +# 37| getBase(): [DeclRefExpr] self +# 37| getSource(): [CaptureListExpr] { ... } +# 37| getBindingDecl(0): [PatternBindingDecl] var ... = ... +# 37| getInit(0): [DeclRefExpr] self +# 37| getInit(0).getFullyConverted(): [InjectIntoOptionalExpr] (ViewController?) ... +# 37| getPattern(0): [NamedPattern] self +# 37| getClosureBody(): [ClosureExpr] { ... } +# 37| getBody(): [BraceStmt] { ... } +# 38| getElement(0): [GuardStmt] guard ... else { ... } +# 38| getCondition(): [StmtCondition] StmtCondition +# 38| getElement(0): [ConditionElement] let ...? = ... +# 38| getPattern(): [OptionalSomePattern] let ...? +# 38| getSubPattern(): [NamedPattern] self +# 38| getSubPattern().getFullyUnresolved(): [BindingPattern] let ... +# 38| getInitializer(): [DeclRefExpr] self +# 38| getInitializer().getFullyConverted(): [LoadExpr] (ViewController?) ... +# 38| getBody(): [BraceStmt] { ... } +# 38| getElement(0): [ReturnStmt] return +# 39| getElement(1): [CallExpr] call to dismiss() +# 39| getFunction(): [MethodLookupExpr] .dismiss() +# 39| getBase(): [DeclRefExpr] self +# 39| getMethodRef(): [DeclRefExpr] dismiss() +# 38| getCapture(0): [CapturedDecl] self +# 37| getSource().getFullyConverted(): [InjectIntoOptionalExpr] ((() -> ())?) ... +# 43| getMember(3): [ConcreteFuncDecl] dismiss() +# 43| InterfaceType = (ViewController) -> () -> () +# 43| getSelfParam(): [ParamDecl] self +# 43| Type = ViewController +# 43| getBody(): [BraceStmt] { ... } +# 33| getMember(4): [DestructorDecl] ViewController.deinit() +# 33| InterfaceType = (ViewController) -> () -> () +# 33| getSelfParam(): [ParamDecl] self +# 33| Type = ViewController +# 33| getBody(): [BraceStmt] { ... } +# 33| getMember(5): [ConstructorDecl] ViewController.init() +# 33| InterfaceType = (ViewController.Type) -> () -> ViewController +# 33| getSelfParam(): [ParamDecl] self +# 33| Type = ViewController +# 33| getBody(): [BraceStmt] { ... } +# 33| getElement(0): [ReturnStmt] return +# 37| [ConcreteVarDecl] self +# 37| Type = ViewController? +# 38| [ConcreteVarDecl] self +# 38| Type = ViewController +# 39| [Comment] // refers to `self.dismiss()` +# 39| diff --git a/swift/ql/test/extractor-tests/updates/PrintAst.qlref b/swift/ql/test/extractor-tests/updates/PrintAst.qlref new file mode 100644 index 00000000000..f7d7d0c4fcb --- /dev/null +++ b/swift/ql/test/extractor-tests/updates/PrintAst.qlref @@ -0,0 +1 @@ +library-tests/ast/PrintAst.ql diff --git a/swift/ql/test/extractor-tests/updates/v5.8.swift b/swift/ql/test/extractor-tests/updates/v5.8.swift new file mode 100644 index 00000000000..0f037366ed1 --- /dev/null +++ b/swift/ql/test/extractor-tests/updates/v5.8.swift @@ -0,0 +1,44 @@ +// https://github.com/apple/swift/blob/main/CHANGELOG.md#swift-58 + +@available(macOS 12, *) +public struct Temperature { + public var degreesCelsius: Double + + // ... +} + +extension Temperature { + @available(macOS 12, *) + @backDeployed(before: macOS 13) + public var degreesFahrenheit: Double { + return (degreesCelsius * 9 / 5) + 32 + } +} + +func collectionDowncast(_ arr: [Any]) { + switch arr { + case let ints as [Int]: + 0 + case is [Bool]: + 1 + case _: + 2 + } +} + +struct Button { + var tapHandler: (() -> ())? +} + +class ViewController { + var button: Button = Button() + + func setup() { + button.tapHandler = { [weak self] in + guard let self else { return } + dismiss() // refers to `self.dismiss()` + } + } + + func dismiss() {} +} From b9c4adee319d1b3f9fc4208ac55ab818a8ffa245 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Mon, 24 Apr 2023 08:51:24 +0200 Subject: [PATCH 566/739] Swift: print only `toBeTested` errors in `Errors.ql` test --- swift/ql/test/extractor-tests/errors/Errors.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swift/ql/test/extractor-tests/errors/Errors.ql b/swift/ql/test/extractor-tests/errors/Errors.ql index 3738f9a83dd..fd25bc8f5cc 100644 --- a/swift/ql/test/extractor-tests/errors/Errors.ql +++ b/swift/ql/test/extractor-tests/errors/Errors.ql @@ -1,5 +1,6 @@ import swift +import TestUtils from Locatable e -where e instanceof ErrorElement +where e instanceof ErrorElement and toBeTested(e) select e, e.getPrimaryQlClasses() From c945d65b2d6871ee08665c7fe2805fbd51ea8666 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Thu, 27 Apr 2023 10:29:55 +0200 Subject: [PATCH 567/739] Swift: add clang ignored flag --- swift/tools/tracing-config.lua | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/swift/tools/tracing-config.lua b/swift/tools/tracing-config.lua index 0d92688ea45..ba2b34d1281 100644 --- a/swift/tools/tracing-config.lua +++ b/swift/tools/tracing-config.lua @@ -25,11 +25,29 @@ function RegisterExtractorPack(id) end end + -- removes unsupported -Xcc flag, e.g, calling strip_unsupported_xcc_arg('-foo', 2) against + -- swift -Xcc -foo -Xcc -bar main.swift + -- will only leave 'swift main.swift' removing both -Xcc -foo, and also -Xcc -bar + -- removes unsupported CLI arg passed to clang via -Xcc together with the following how_many args + function strip_unsupported_clang_arg(args, arg, how_many) + local index = indexOf(args, arg) + if index and index > 0 and args[index - 1] == '-Xcc' then + index = index - 1 -- start from -Xcc + how_many = 2 * (how_many + 1) -- need to remove initial -Xcc <arg> as well as following -Xcc prefixed flags + while (how_many > 0) + do + table.remove(args, index) + how_many = how_many - 1 + end + end + end + function strip_unsupported_args(args) strip_unsupported_arg(args, '-emit-localized-strings', 0) strip_unsupported_arg(args, '-emit-localized-strings-path', 1) strip_unsupported_arg(args, '-stack-check', 0) strip_unsupported_arg(args, '-experimental-skip-non-inlinable-function-bodies-without-types', 0) + strip_unsupported_clang_arg(args, '-ivfsstatcache', 1) end -- xcodebuild does not always specify the -resource-dir in which case the compiler falls back From 93b9115217de9c0343689438e99a8278abc15cc6 Mon Sep 17 00:00:00 2001 From: Alex Denisov <alexdenisov@github.com> Date: Thu, 1 Jun 2023 12:23:01 +0200 Subject: [PATCH 568/739] Swift: package resource dir from precomiled toolchain --- swift/BUILD.bazel | 8 ++++++++ swift/extractor/main.cpp | 15 +++++++++++++-- swift/third_party/BUILD.swift-llvm-support.bazel | 9 +++++++++ swift/third_party/swift-llvm-support/BUILD.bazel | 2 +- swift/tools/qltest.sh | 4 ++-- swift/tools/test/qltest/utils.py | 2 +- 6 files changed, 34 insertions(+), 6 deletions(-) diff --git a/swift/BUILD.bazel b/swift/BUILD.bazel index 59cafbba609..b5042dc19d8 100644 --- a/swift/BUILD.bazel +++ b/swift/BUILD.bazel @@ -64,6 +64,13 @@ pkg_runfiles( prefix = "tools/" + codeql_platform, ) +pkg_filegroup( + name = "resource-dir-arch", + srcs = ["//swift/third_party/swift-llvm-support:swift-resource-dir"], + prefix = "resource-dir/" + codeql_platform, + visibility = ["//visibility:public"], +) + pkg_files( name = "swift-test-sdk-arch", srcs = ["//swift/third_party/swift-llvm-support:swift-test-sdk"], @@ -76,6 +83,7 @@ pkg_filegroup( srcs = [ ":extractor", ":swift-test-sdk-arch", + ":resource-dir-arch", ] + select({ "@platforms//os:linux": [ ":incompatible-os", diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index de8a0d3f5e5..de7fd703161 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -174,7 +174,9 @@ codeql::TrapDomain invocationTrapDomain(codeql::SwiftExtractorState& state) { return std::move(maybeDomain.value()); } -codeql::SwiftExtractorConfiguration configure(int argc, char** argv) { +codeql::SwiftExtractorConfiguration configure(int argc, + char** argv, + const std::string& resourceDir) { codeql::SwiftExtractorConfiguration configuration{}; configuration.trapDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_TRAP_DIR", "extractor-out/trap/swift"); configuration.sourceArchiveDir = @@ -182,6 +184,13 @@ codeql::SwiftExtractorConfiguration configure(int argc, char** argv) { configuration.scratchDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SCRATCH_DIR", "extractor-out/working"); configuration.frontendOptions.assign(argv + 1, argv + argc); + // TODO: Should be moved to the tracer config + for (int i = 0; i < argc - 1; i++) { + if (std::string("-resource-dir") == configuration.frontendOptions[i]) { + configuration.frontendOptions[i + 1] = resourceDir.c_str(); + break; + } + } return configuration; } @@ -214,7 +223,9 @@ int main(int argc, char** argv, char** envp) { INITIALIZE_LLVM(); initializeSwiftModules(); - const auto configuration = configure(argc, argv); + std::string resourceDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_ROOT", ".") + "/resource-dir/" + + getenv_or("CODEQL_PLATFORM", "."); + const auto configuration = configure(argc, argv, resourceDir); LOG_INFO("calling extractor with arguments \"{}\"", argDump(argc, argv)); LOG_DEBUG("environment:\n{}\n", envDump(envp)); diff --git a/swift/third_party/BUILD.swift-llvm-support.bazel b/swift/third_party/BUILD.swift-llvm-support.bazel index 21a8d8801b3..0a9068c4cf6 100644 --- a/swift/third_party/BUILD.swift-llvm-support.bazel +++ b/swift/third_party/BUILD.swift-llvm-support.bazel @@ -31,3 +31,12 @@ pkg_files( strip_prefix = strip_prefix.from_pkg(), visibility = ["//visibility:public"], ) + +pkg_files( + name = "swift-resource-dir", + srcs = glob([ + "toolchain/lib/swift/**/*", + ]), + strip_prefix = "toolchain/lib/swift", + visibility = ["//visibility:public"], +) diff --git a/swift/third_party/swift-llvm-support/BUILD.bazel b/swift/third_party/swift-llvm-support/BUILD.bazel index db5c09085a4..2f6df03697f 100644 --- a/swift/third_party/swift-llvm-support/BUILD.bazel +++ b/swift/third_party/swift-llvm-support/BUILD.bazel @@ -17,5 +17,5 @@ _arch_override = { for arch in ("linux", "darwin_x86_64", "darwin_arm64") }), ) - for name in ("swift-llvm-support", "swift-test-sdk") + for name in ("swift-llvm-support", "swift-test-sdk", "swift-resource-dir") ] diff --git a/swift/tools/qltest.sh b/swift/tools/qltest.sh index 5b12607ca4f..409bc9a7d15 100755 --- a/swift/tools/qltest.sh +++ b/swift/tools/qltest.sh @@ -6,11 +6,11 @@ QLTEST_LOG="$CODEQL_EXTRACTOR_SWIFT_LOG_DIR"/qltest.log EXTRACTOR="$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor" SDK="$CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk" +RESOURCE_DIR="$CODEQL_EXTRACTOR_SWIFT_ROOT/resource-dir/$CODEQL_PLATFORM" export CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS=${CODEQL_EXTRACTOR_SWIFT_LOG_LEVELS:-out:text:no_logs,out:console:info} - for src in *.swift; do env=() - opts=(-sdk "$SDK" -c -primary-file "$src") + opts=(-sdk "$SDK" -resource-dir "$RESOURCE_DIR" -c -primary-file "$src") opts+=($(sed -n '1 s=//codeql-extractor-options:==p' $src)) expected_status=$(sed -n 's=//codeql-extractor-expected-status:[[:space:]]*==p' $src) expected_status=${expected_status:-0} diff --git a/swift/tools/test/qltest/utils.py b/swift/tools/test/qltest/utils.py index 88924f3f509..6e60223be9f 100644 --- a/swift/tools/test/qltest/utils.py +++ b/swift/tools/test/qltest/utils.py @@ -60,7 +60,7 @@ def assert_extractor_executed_with(*flags): for actual, expected in itertools.zip_longest(execution, flags): if actual: actual = actual.strip() - expected_prefix = f"-sdk {swift_root}/qltest/{platform}/sdk -c -primary-file " + expected_prefix = f"-sdk {swift_root}/qltest/{platform}/sdk -resource-dir {swift_root}/resource-dir/{platform} -c -primary-file " assert actual.startswith(expected_prefix), f"correct sdk option not found in\n{actual}" actual = actual[len(expected_prefix):] assert actual, f"\nnot encountered: {expected}" From 17111c96e41f8fdd606d5cda94f8a6eabb1a7b07 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Mon, 24 Apr 2023 08:55:13 +0200 Subject: [PATCH 569/739] Swift: accept test expectation changes --- .../NamedFunction_getParam.expected | 2 +- .../CONSISTENCY/PrintAstConsistency.expected | 4 +- .../MethodLookupExpr.expected | 9 ++--- .../MethodLookupExpr_getMember.expected | 6 +-- .../MethodLookupExpr_getType.expected | 9 ++--- .../run_under/Strings.expected | 4 +- .../extractor-tests/updates/PrintAst.expected | 38 +++++++++---------- 7 files changed, 33 insertions(+), 39 deletions(-) diff --git a/swift/ql/test/extractor-tests/generated/decl/NamedFunction/NamedFunction_getParam.expected b/swift/ql/test/extractor-tests/generated/decl/NamedFunction/NamedFunction_getParam.expected index 1e4343bc860..f549b8615ad 100644 --- a/swift/ql/test/extractor-tests/generated/decl/NamedFunction/NamedFunction_getParam.expected +++ b/swift/ql/test/extractor-tests/generated/decl/NamedFunction/NamedFunction_getParam.expected @@ -1,6 +1,6 @@ | functions.swift:5:1:7:1 | bar(_:d:) | 0 | functions.swift:5:10:5:15 | x | | functions.swift:5:1:7:1 | bar(_:d:) | 1 | functions.swift:5:20:5:25 | y | | functions.swift:10:5:10:28 | noBody(x:) | 0 | functions.swift:10:17:10:20 | x | -| functions.swift:13:1:15:1 | variadic(_:) | 0 | functions.swift:13:15:13:23 | ints | +| functions.swift:13:1:15:1 | variadic(_:) | 0 | functions.swift:13:15:13:26 | ints | | functions.swift:17:1:19:1 | generic(x:y:) | 0 | functions.swift:17:20:17:23 | x | | functions.swift:17:1:19:1 | generic(x:y:) | 1 | functions.swift:17:26:17:29 | y | diff --git a/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/CONSISTENCY/PrintAstConsistency.expected b/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/CONSISTENCY/PrintAstConsistency.expected index 73431518cde..5fff2a2afde 100644 --- a/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/CONSISTENCY/PrintAstConsistency.expected +++ b/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/CONSISTENCY/PrintAstConsistency.expected @@ -1,3 +1,3 @@ doubleIndexes -| method_lookups.swift:44:13:44:13 | [AutoClosureExpr] { ... } | 2 | getParam(0) | 4 | getParam(1) | file://:0:0:0:0 | [ParamDecl] argument | -| method_lookups.swift:44:13:44:13 | [AutoClosureExpr] { ... } | 4 | getParam(1) | 2 | getParam(0) | file://:0:0:0:0 | [ParamDecl] argument | +| method_lookups.swift:44:11:44:13 | [AutoClosureExpr] { ... } | 2 | getParam(0) | 4 | getParam(1) | file://:0:0:0:0 | [ParamDecl] argument | +| method_lookups.swift:44:11:44:13 | [AutoClosureExpr] { ... } | 4 | getParam(1) | 2 | getParam(0) | file://:0:0:0:0 | [ParamDecl] argument | diff --git a/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr.expected b/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr.expected index c0a25151b0f..8e528ff32a2 100644 --- a/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr.expected +++ b/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr.expected @@ -9,8 +9,7 @@ | method_lookups.swift:33:3:33:5 | .bar() | hasType: | yes | getBase: | method_lookups.swift:33:3:33:3 | X.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:33:5:33:5 | bar() | | method_lookups.swift:34:3:34:3 | X.init() | hasType: | yes | getBase: | method_lookups.swift:34:3:34:3 | X.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:34:3:34:3 | X.init() | | method_lookups.swift:34:3:34:7 | .baz(_:) | hasType: | yes | getBase: | method_lookups.swift:34:3:34:5 | call to X.init() | hasMember: | yes | getMethodRef: | method_lookups.swift:34:7:34:7 | baz(_:) | -| method_lookups.swift:36:11:36:13 | (no string representation) | hasType: | yes | getBase: | method_lookups.swift:36:11:36:11 | X.Type | hasMember: | no | getMethodRef: | method_lookups.swift:36:13:36:13 | { ... } | -| method_lookups.swift:36:13:36:13 | .bar() | hasType: | yes | getBase: | file://:0:0:0:0 | self | hasMember: | yes | getMethodRef: | method_lookups.swift:36:13:36:13 | bar() | +| method_lookups.swift:36:11:36:13 | .bar() | hasType: | yes | getBase: | method_lookups.swift:36:11:36:11 | X.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:36:13:36:13 | bar() | | method_lookups.swift:37:11:37:11 | X.init() | hasType: | yes | getBase: | method_lookups.swift:37:11:37:11 | X.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:37:11:37:11 | X.init() | | method_lookups.swift:37:11:37:15 | (no string representation) | hasType: | yes | getBase: | method_lookups.swift:37:11:37:13 | call to X.init() | hasMember: | no | getMethodRef: | method_lookups.swift:37:15:37:15 | { ... } | | method_lookups.swift:37:15:37:15 | .baz(_:) | hasType: | yes | getBase: | file://:0:0:0:0 | self | hasMember: | yes | getMethodRef: | method_lookups.swift:37:15:37:15 | baz(_:) | @@ -18,15 +17,13 @@ | method_lookups.swift:41:3:41:5 | .foo(_:_:) | hasType: | yes | getBase: | method_lookups.swift:41:3:41:3 | Y.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:41:5:41:5 | foo(_:_:) | | method_lookups.swift:42:9:42:9 | Y.init() | hasType: | yes | getBase: | method_lookups.swift:42:9:42:9 | Y.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:42:9:42:9 | Y.init() | | method_lookups.swift:42:9:42:13 | .baz(_:) | hasType: | yes | getBase: | method_lookups.swift:42:9:42:11 | call to Y.init() | hasMember: | yes | getMethodRef: | method_lookups.swift:42:13:42:13 | baz(_:) | -| method_lookups.swift:44:11:44:13 | (no string representation) | hasType: | yes | getBase: | method_lookups.swift:44:11:44:11 | Y.Type | hasMember: | no | getMethodRef: | method_lookups.swift:44:13:44:13 | { ... } | -| method_lookups.swift:44:13:44:13 | .foo(_:_:) | hasType: | yes | getBase: | file://:0:0:0:0 | self | hasMember: | yes | getMethodRef: | method_lookups.swift:44:13:44:13 | foo(_:_:) | +| method_lookups.swift:44:11:44:13 | .foo(_:_:) | hasType: | yes | getBase: | method_lookups.swift:44:11:44:11 | Y.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:44:13:44:13 | foo(_:_:) | | method_lookups.swift:47:1:47:1 | Task<Success, Never>.init(priority:operation:) | hasType: | yes | getBase: | method_lookups.swift:47:1:47:1 | Task<(), Never>.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:47:1:47:1 | Task<Success, Never>.init(priority:operation:) | | method_lookups.swift:48:9:48:11 | .foo(_:_:) | hasType: | yes | getBase: | method_lookups.swift:48:9:48:9 | Z.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:48:11:48:11 | foo(_:_:) | | method_lookups.swift:49:9:49:11 | .bar() | hasType: | yes | getBase: | method_lookups.swift:49:9:49:9 | Z.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:49:11:49:11 | bar() | | method_lookups.swift:50:9:50:9 | Z.init() | hasType: | yes | getBase: | method_lookups.swift:50:9:50:9 | Z.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:50:9:50:9 | Z.init() | | method_lookups.swift:50:9:50:13 | .baz(_:) | hasType: | yes | getBase: | method_lookups.swift:50:9:50:11 | call to Z.init() | hasMember: | yes | getMethodRef: | method_lookups.swift:50:13:50:13 | baz(_:) | -| method_lookups.swift:52:11:52:13 | (no string representation) | hasType: | yes | getBase: | method_lookups.swift:52:11:52:11 | Z.Type | hasMember: | no | getMethodRef: | method_lookups.swift:52:13:52:13 | { ... } | -| method_lookups.swift:52:13:52:13 | .bar() | hasType: | yes | getBase: | file://:0:0:0:0 | self | hasMember: | yes | getMethodRef: | method_lookups.swift:52:13:52:13 | bar() | +| method_lookups.swift:52:11:52:13 | .bar() | hasType: | yes | getBase: | method_lookups.swift:52:11:52:11 | Z.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:52:13:52:13 | bar() | | method_lookups.swift:53:11:53:23 | (no string representation) | hasType: | yes | getBase: | method_lookups.swift:53:18:53:20 | call to Z.init() | hasMember: | no | getMethodRef: | method_lookups.swift:53:23:53:23 | { ... } | | method_lookups.swift:53:18:53:18 | Z.init() | hasType: | yes | getBase: | method_lookups.swift:53:18:53:18 | Z.Type | hasMember: | yes | getMethodRef: | method_lookups.swift:53:18:53:18 | Z.init() | | method_lookups.swift:53:23:53:23 | .baz(_:) | hasType: | yes | getBase: | file://:0:0:0:0 | self | hasMember: | yes | getMethodRef: | method_lookups.swift:53:23:53:23 | baz(_:) | diff --git a/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr_getMember.expected b/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr_getMember.expected index 28a139bc463..0b599fe3fe3 100644 --- a/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr_getMember.expected +++ b/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr_getMember.expected @@ -6,19 +6,19 @@ | method_lookups.swift:33:3:33:5 | .bar() | method_lookups.swift:3:3:3:21 | bar() | | method_lookups.swift:34:3:34:3 | X.init() | method_lookups.swift:6:3:8:3 | X.init() | | method_lookups.swift:34:3:34:7 | .baz(_:) | method_lookups.swift:4:3:4:21 | baz(_:) | -| method_lookups.swift:36:13:36:13 | .bar() | method_lookups.swift:3:3:3:21 | bar() | +| method_lookups.swift:36:11:36:13 | .bar() | method_lookups.swift:3:3:3:21 | bar() | | method_lookups.swift:37:11:37:11 | X.init() | method_lookups.swift:6:3:8:3 | X.init() | | method_lookups.swift:37:15:37:15 | .baz(_:) | method_lookups.swift:4:3:4:21 | baz(_:) | | method_lookups.swift:40:1:40:1 | Task<Success, Never>.init(priority:operation:) | file://:0:0:0:0 | Task<Success, Never>.init(priority:operation:) | | method_lookups.swift:41:3:41:5 | .foo(_:_:) | method_lookups.swift:12:3:12:35 | foo(_:_:) | | method_lookups.swift:42:9:42:9 | Y.init() | method_lookups.swift:15:3:17:3 | Y.init() | | method_lookups.swift:42:9:42:13 | .baz(_:) | method_lookups.swift:13:3:13:21 | baz(_:) | -| method_lookups.swift:44:13:44:13 | .foo(_:_:) | method_lookups.swift:12:3:12:35 | foo(_:_:) | +| method_lookups.swift:44:11:44:13 | .foo(_:_:) | method_lookups.swift:12:3:12:35 | foo(_:_:) | | method_lookups.swift:47:1:47:1 | Task<Success, Never>.init(priority:operation:) | file://:0:0:0:0 | Task<Success, Never>.init(priority:operation:) | | method_lookups.swift:48:9:48:11 | .foo(_:_:) | method_lookups.swift:22:3:22:35 | foo(_:_:) | | method_lookups.swift:49:9:49:11 | .bar() | method_lookups.swift:23:3:23:21 | bar() | | method_lookups.swift:50:9:50:9 | Z.init() | method_lookups.swift:26:3:28:3 | Z.init() | | method_lookups.swift:50:9:50:13 | .baz(_:) | method_lookups.swift:24:3:24:21 | baz(_:) | -| method_lookups.swift:52:13:52:13 | .bar() | method_lookups.swift:23:3:23:21 | bar() | +| method_lookups.swift:52:11:52:13 | .bar() | method_lookups.swift:23:3:23:21 | bar() | | method_lookups.swift:53:18:53:18 | Z.init() | method_lookups.swift:26:3:28:3 | Z.init() | | method_lookups.swift:53:23:53:23 | .baz(_:) | method_lookups.swift:24:3:24:21 | baz(_:) | diff --git a/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr_getType.expected index f78acd18203..689812463da 100644 --- a/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr_getType.expected +++ b/swift/ql/test/extractor-tests/generated/expr/MethodLookupExpr/MethodLookupExpr_getType.expected @@ -9,8 +9,7 @@ | method_lookups.swift:33:3:33:5 | .bar() | () -> () | | method_lookups.swift:34:3:34:3 | X.init() | () -> X | | method_lookups.swift:34:3:34:7 | .baz(_:) | (Int) -> () | -| method_lookups.swift:36:11:36:13 | (no string representation) | () -> () | -| method_lookups.swift:36:13:36:13 | .bar() | () -> () | +| method_lookups.swift:36:11:36:13 | .bar() | () -> () | | method_lookups.swift:37:11:37:11 | X.init() | () -> X | | method_lookups.swift:37:11:37:15 | (no string representation) | (Int) -> () | | method_lookups.swift:37:15:37:15 | .baz(_:) | (Int) -> () | @@ -18,15 +17,13 @@ | method_lookups.swift:41:3:41:5 | .foo(_:_:) | (Int, Int) -> () | | method_lookups.swift:42:9:42:9 | Y.init() | () -> Y | | method_lookups.swift:42:9:42:13 | .baz(_:) | (Int) -> () | -| method_lookups.swift:44:11:44:13 | (no string representation) | (Int, Int) -> () | -| method_lookups.swift:44:13:44:13 | .foo(_:_:) | (Int, Int) -> () | +| method_lookups.swift:44:11:44:13 | .foo(_:_:) | (Int, Int) -> () | | method_lookups.swift:47:1:47:1 | Task<Success, Never>.init(priority:operation:) | (TaskPriority?, __owned @escaping @Sendable () async -> ()) -> Task<(), Never> | | method_lookups.swift:48:9:48:11 | .foo(_:_:) | @MainActor (Int, Int) -> () | | method_lookups.swift:49:9:49:11 | .bar() | @MainActor () -> () | | method_lookups.swift:50:9:50:9 | Z.init() | @MainActor () -> Z | | method_lookups.swift:50:9:50:13 | .baz(_:) | @MainActor (Int) -> () | -| method_lookups.swift:52:11:52:13 | (no string representation) | @MainActor () -> () | -| method_lookups.swift:52:13:52:13 | .bar() | () -> () | +| method_lookups.swift:52:11:52:13 | .bar() | () -> () | | method_lookups.swift:53:11:53:23 | (no string representation) | @MainActor (Int) -> () | | method_lookups.swift:53:18:53:18 | Z.init() | @MainActor () -> Z | | method_lookups.swift:53:23:53:23 | .baz(_:) | (Int) -> () | diff --git a/swift/ql/test/extractor-tests/run_under/Strings.expected b/swift/ql/test/extractor-tests/run_under/Strings.expected index 042e306b4bb..8732de344db 100644 --- a/swift/ql/test/extractor-tests/run_under/Strings.expected +++ b/swift/ql/test/extractor-tests/run_under/Strings.expected @@ -1,2 +1,2 @@ -| run_under: $CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor -sdk $CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk -c -primary-file filtered_in.swift | -| run_under: $CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor -sdk $CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk -c -primary-file unfiltered.swift | +| run_under: $CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor -sdk $CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk -resource-dir $CODEQL_EXTRACTOR_SWIFT_ROOT/resource-dir/$CODEQL_PLATFORM -c -primary-file filtered_in.swift | +| run_under: $CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor -sdk $CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk -resource-dir $CODEQL_EXTRACTOR_SWIFT_ROOT/resource-dir/$CODEQL_PLATFORM -c -primary-file unfiltered.swift | diff --git a/swift/ql/test/extractor-tests/updates/PrintAst.expected b/swift/ql/test/extractor-tests/updates/PrintAst.expected index 904eee573f0..7c9962f5d64 100644 --- a/swift/ql/test/extractor-tests/updates/PrintAst.expected +++ b/swift/ql/test/extractor-tests/updates/PrintAst.expected @@ -8,7 +8,7 @@ v5.8.swift: # 5| getTypeRepr(): [TypeRepr] Double # 5| getMember(1): [ConcreteVarDecl] degreesCelsius # 5| Type = Double -# 5| getAccessorDecl(0): [AccessorDecl] get +# 5| getAccessor(0): [Accessor] get # 5| InterfaceType = (Temperature) -> () -> Double # 5| getSelfParam(): [ParamDecl] self # 5| Type = Temperature @@ -16,7 +16,7 @@ v5.8.swift: #-----| getElement(0): [ReturnStmt] return ... #-----| getResult(): [MemberRefExpr] .degreesCelsius #-----| getBase(): [DeclRefExpr] self -# 5| getAccessorDecl(1): [AccessorDecl] set +# 5| getAccessor(1): [Accessor] set # 5| InterfaceType = (inout Temperature) -> (Double) -> () # 5| getSelfParam(): [ParamDecl] self # 5| Type = Temperature @@ -27,7 +27,7 @@ v5.8.swift: #-----| getDest(): [MemberRefExpr] .degreesCelsius #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 5| getAccessorDecl(2): [AccessorDecl] _modify +# 5| getAccessor(2): [Accessor] _modify # 5| InterfaceType = (inout Temperature) -> () -> () # 5| getSelfParam(): [ParamDecl] self # 5| Type = Temperature @@ -36,7 +36,7 @@ v5.8.swift: #-----| getResult(0): [InOutExpr] &... #-----| getSubExpr(): [MemberRefExpr] .degreesCelsius #-----| getBase(): [DeclRefExpr] self -# 4| getMember(2): [ConstructorDecl] Temperature.init(degreesCelsius:) +# 4| getMember(2): [Initializer] Temperature.init(degreesCelsius:) # 4| InterfaceType = (Temperature.Type) -> (Double) -> Temperature # 4| getSelfParam(): [ParamDecl] self # 4| Type = Temperature @@ -51,7 +51,7 @@ v5.8.swift: # 13| getTypeRepr(): [TypeRepr] Double # 13| getMember(1): [ConcreteVarDecl] degreesFahrenheit # 13| Type = Double -# 13| getAccessorDecl(0): [AccessorDecl] get +# 13| getAccessor(0): [Accessor] get # 13| InterfaceType = (Temperature) -> () -> Double # 13| getSelfParam(): [ParamDecl] self # 13| Type = Temperature @@ -84,7 +84,7 @@ v5.8.swift: # 14| getExpr().getFullyConverted(): [ParenExpr] (...) # 14| getArgument(1): [Argument] : 32 # 14| getExpr(): [IntegerLiteralExpr] 32 -# 18| [ConcreteFuncDecl] collectionDowncast(_:) +# 18| [NamedFunction] collectionDowncast(_:) # 18| InterfaceType = ([Any]) -> () # 18| getParam(0): [ParamDecl] arr # 18| Type = [Any] @@ -120,7 +120,7 @@ v5.8.swift: # 30| getTypeRepr(): [TypeRepr] (() -> ())? # 30| getMember(1): [ConcreteVarDecl] tapHandler # 30| Type = (() -> ())? -# 30| getAccessorDecl(0): [AccessorDecl] get +# 30| getAccessor(0): [Accessor] get # 30| InterfaceType = (Button) -> () -> (() -> ())? # 30| getSelfParam(): [ParamDecl] self # 30| Type = Button @@ -128,7 +128,7 @@ v5.8.swift: #-----| getElement(0): [ReturnStmt] return ... #-----| getResult(): [MemberRefExpr] .tapHandler #-----| getBase(): [DeclRefExpr] self -# 30| getAccessorDecl(1): [AccessorDecl] set +# 30| getAccessor(1): [Accessor] set # 30| InterfaceType = (inout Button) -> ((() -> ())?) -> () # 30| getSelfParam(): [ParamDecl] self # 30| Type = Button @@ -139,7 +139,7 @@ v5.8.swift: #-----| getDest(): [MemberRefExpr] .tapHandler #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 30| getAccessorDecl(2): [AccessorDecl] _modify +# 30| getAccessor(2): [Accessor] _modify # 30| InterfaceType = (inout Button) -> () -> () # 30| getSelfParam(): [ParamDecl] self # 30| Type = Button @@ -148,13 +148,13 @@ v5.8.swift: #-----| getResult(0): [InOutExpr] &... #-----| getSubExpr(): [MemberRefExpr] .tapHandler #-----| getBase(): [DeclRefExpr] self -# 29| getMember(2): [ConstructorDecl] Button.init() +# 29| getMember(2): [Initializer] Button.init() # 29| InterfaceType = (Button.Type) -> () -> Button # 29| getSelfParam(): [ParamDecl] self # 29| Type = Button # 29| getBody(): [BraceStmt] { ... } # 29| getElement(0): [ReturnStmt] return -# 29| getMember(3): [ConstructorDecl] Button.init(tapHandler:) +# 29| getMember(3): [Initializer] Button.init(tapHandler:) # 29| InterfaceType = (Button.Type) -> ((() -> ())?) -> Button # 29| getSelfParam(): [ParamDecl] self # 29| Type = Button @@ -172,7 +172,7 @@ v5.8.swift: # 34| getTypeRepr(): [TypeRepr] Button # 34| getMember(1): [ConcreteVarDecl] button # 34| Type = Button -# 34| getAccessorDecl(0): [AccessorDecl] get +# 34| getAccessor(0): [Accessor] get # 34| InterfaceType = (ViewController) -> () -> Button # 34| getSelfParam(): [ParamDecl] self # 34| Type = ViewController @@ -180,7 +180,7 @@ v5.8.swift: #-----| getElement(0): [ReturnStmt] return ... #-----| getResult(): [MemberRefExpr] .button #-----| getBase(): [DeclRefExpr] self -# 34| getAccessorDecl(1): [AccessorDecl] set +# 34| getAccessor(1): [Accessor] set # 34| InterfaceType = (ViewController) -> (Button) -> () # 34| getSelfParam(): [ParamDecl] self # 34| Type = ViewController @@ -191,7 +191,7 @@ v5.8.swift: #-----| getDest(): [MemberRefExpr] .button #-----| getBase(): [DeclRefExpr] self #-----| getSource(): [DeclRefExpr] value -# 34| getAccessorDecl(2): [AccessorDecl] _modify +# 34| getAccessor(2): [Accessor] _modify # 34| InterfaceType = (ViewController) -> () -> () # 34| getSelfParam(): [ParamDecl] self # 34| Type = ViewController @@ -200,7 +200,7 @@ v5.8.swift: #-----| getResult(0): [InOutExpr] &... #-----| getSubExpr(): [MemberRefExpr] .button #-----| getBase(): [DeclRefExpr] self -# 36| getMember(2): [ConcreteFuncDecl] setup() +# 36| getMember(2): [NamedFunction] setup() # 36| InterfaceType = (ViewController) -> () -> () # 36| getSelfParam(): [ParamDecl] self # 36| Type = ViewController @@ -214,7 +214,7 @@ v5.8.swift: # 37| getInit(0): [DeclRefExpr] self # 37| getInit(0).getFullyConverted(): [InjectIntoOptionalExpr] (ViewController?) ... # 37| getPattern(0): [NamedPattern] self -# 37| getClosureBody(): [ClosureExpr] { ... } +# 37| getClosureBody(): [ExplicitClosureExpr] { ... } # 37| getBody(): [BraceStmt] { ... } # 38| getElement(0): [GuardStmt] guard ... else { ... } # 38| getCondition(): [StmtCondition] StmtCondition @@ -232,17 +232,17 @@ v5.8.swift: # 39| getMethodRef(): [DeclRefExpr] dismiss() # 38| getCapture(0): [CapturedDecl] self # 37| getSource().getFullyConverted(): [InjectIntoOptionalExpr] ((() -> ())?) ... -# 43| getMember(3): [ConcreteFuncDecl] dismiss() +# 43| getMember(3): [NamedFunction] dismiss() # 43| InterfaceType = (ViewController) -> () -> () # 43| getSelfParam(): [ParamDecl] self # 43| Type = ViewController # 43| getBody(): [BraceStmt] { ... } -# 33| getMember(4): [DestructorDecl] ViewController.deinit() +# 33| getMember(4): [Deinitializer] ViewController.deinit() # 33| InterfaceType = (ViewController) -> () -> () # 33| getSelfParam(): [ParamDecl] self # 33| Type = ViewController # 33| getBody(): [BraceStmt] { ... } -# 33| getMember(5): [ConstructorDecl] ViewController.init() +# 33| getMember(5): [Initializer] ViewController.init() # 33| InterfaceType = (ViewController.Type) -> () -> ViewController # 33| getSelfParam(): [ParamDecl] self # 33| Type = ViewController From 2daa001109886cda7a4471524490d43f6a7d2654 Mon Sep 17 00:00:00 2001 From: Alex Denisov <alexdenisov@github.com> Date: Mon, 12 Jun 2023 10:32:36 +0200 Subject: [PATCH 570/739] Swift: setup Swift 5.8 unconditionally --- swift/actions/run-integration-tests/action.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/swift/actions/run-integration-tests/action.yml b/swift/actions/run-integration-tests/action.yml index 58bd728d7e1..6db78e2e01e 100644 --- a/swift/actions/run-integration-tests/action.yml +++ b/swift/actions/run-integration-tests/action.yml @@ -4,18 +4,12 @@ runs: using: composite steps: - uses: ./swift/actions/share-extractor-pack - - name: Get Swift version - id: get_swift_version - shell: bash - run: | - VERSION=$(swift/extractor-pack/tools/*/extractor --version | awk '/version/ { print $3 }') - echo "version=$VERSION" | tee -a $GITHUB_OUTPUT - uses: actions/setup-python@v4 with: python-version-file: 'swift/.python-version' - uses: swift-actions/setup-swift@65540b95f51493d65f5e59e97dcef9629ddf11bf with: - swift-version: "${{steps.get_swift_version.outputs.version}}" + swift-version: "5.8" - uses: ./.github/actions/fetch-codeql - id: query-cache uses: ./.github/actions/cache-query-compilation From 526f6cd5b5599e80510f21938992b6d775cb7bfd Mon Sep 17 00:00:00 2001 From: Alex Denisov <alexdenisov@github.com> Date: Mon, 12 Jun 2023 12:32:51 +0200 Subject: [PATCH 571/739] Swift: skip print_unextracted --- swift/actions/build-and-test/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/swift/actions/build-and-test/action.yml b/swift/actions/build-and-test/action.yml index f800bd3ffc2..4553952f2c2 100644 --- a/swift/actions/build-and-test/action.yml +++ b/swift/actions/build-and-test/action.yml @@ -44,10 +44,10 @@ runs: mkdir -p bazel-cache/{repository,disk} echo build --repository_cache=bazel-cache/repository --disk_cache=bazel-cache/disk > local.bazelrc echo test --test_output=errors >> local.bazelrc - - name: Print unextracted entities - shell: bash - run: | - bazel run //swift/extractor/print_unextracted + # - name: Print unextracted entities + # shell: bash + # run: | + # bazel run //swift/extractor/print_unextracted - uses: ./swift/actions/share-extractor-pack - name: Build Swift extractor shell: bash From c080cba88d6d64a80cd67ef887bdc7bef31fa67a Mon Sep 17 00:00:00 2001 From: Alex Denisov <alexdenisov@github.com> Date: Wed, 14 Jun 2023 11:49:16 +0200 Subject: [PATCH 572/739] Swift: add database migration scripts --- .../downgrade.ql | 36 + .../old.dbscheme | 2618 +++++++++++++++++ .../swift.dbscheme | 2618 +++++++++++++++++ .../upgrade.properties | 5 + .../old.dbscheme | 2618 +++++++++++++++++ .../swift.dbscheme | 2618 +++++++++++++++++ .../upgrade.properties | 2 + 7 files changed, 10515 insertions(+) create mode 100644 swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/downgrade.ql create mode 100644 swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/old.dbscheme create mode 100644 swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/swift.dbscheme create mode 100644 swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/upgrade.properties create mode 100644 swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/old.dbscheme create mode 100644 swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/swift.dbscheme create mode 100644 swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties diff --git a/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/downgrade.ql b/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/downgrade.ql new file mode 100644 index 00000000000..929ffb4e927 --- /dev/null +++ b/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/downgrade.ql @@ -0,0 +1,36 @@ +class Element extends @element { + string toString() { none() } +} + +newtype TAddedUnspecifiedElement = + TNonExplicitClosureExprClosureBody(Element list, Element body) { + capture_list_exprs(list, body) and not explicit_closure_exprs(body) + } + +module Fresh = QlBuiltins::NewEntity<TAddedUnspecifiedElement>; + +class TNewElement = @element or Fresh::EntityId; + +class NewElement extends TNewElement { + string toString() { none() } +} + +query predicate new_unspecified_elements(NewElement u, string property, string error) { + unspecified_elements(u, property, error) + or + u = Fresh::map(TNonExplicitClosureExprClosureBody(_, _)) and + property = "closure_body" and + error = "while downgrading: closure_body not an @explicit_closure_expr" +} + +query predicate new_unspecified_element_parents(NewElement u, Element parent) { + unspecified_element_parents(u, parent) + or + u = Fresh::map(TNonExplicitClosureExprClosureBody(parent, _)) +} + +query predicate new_capture_list_exprs(Element list, NewElement body) { + capture_list_exprs(list, body) and explicit_closure_exprs(body) + or + body = Fresh::map(TNonExplicitClosureExprClosureBody(list, _)) +} diff --git a/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/old.dbscheme b/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/old.dbscheme new file mode 100644 index 00000000000..147e087e57e --- /dev/null +++ b/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/old.dbscheme @@ -0,0 +1,2618 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @key_path_component +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +key_path_components( + unique int id: @key_path_component, + int kind: int ref, + int component_type: @type_or_none ref +); + +#keyset[id, index] +key_path_component_subscript_arguments( + int id: @key_path_component ref, + int index: int ref, + int subscript_argument: @argument_or_none ref +); + +#keyset[id] +key_path_component_tuple_indices( + int id: @key_path_component ref, + int tuple_index: int ref +); + +#keyset[id] +key_path_component_decl_refs( + int id: @key_path_component ref, + int decl_ref: @value_decl_or_none ref +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @extension_decl +| @function +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_storage_decl +| @enum_element_decl +| @function +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessors( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor: @accessor_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@function = + @accessor_or_named_function +| @deinitializer +| @initializer +; + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +@accessor_or_named_function = + @accessor +| @named_function +; + +deinitializers( //dir=decl + unique int id: @deinitializer +); + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +initializers( //dir=decl + unique int id: @initializer +); + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessors( //dir=decl + unique int id: @accessor +); + +#keyset[id] +accessor_is_getter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_setter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_will_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_did_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_read( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_modify( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_address( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_mutable_address( //dir=decl + int id: @accessor ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +named_functions( //dir=decl + unique int id: @named_function +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @closure_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initialization_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_initializer_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_initializer_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@closure_expr = + @auto_closure_expr +| @explicit_closure_expr +; + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id, index] +key_path_expr_components( //dir=expr + int id: @key_path_expr ref, + int index: int ref, + int component: @key_path_component_or_none ref +); + +lazy_initialization_exprs( //dir=expr + unique int id: @lazy_initialization_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @function_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_initializer_ref_exprs( //dir=expr + unique int id: @other_initializer_ref_expr, + int initializer: @initializer_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_initializer_exprs( //dir=expr + unique int id: @rebind_self_in_initializer_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +explicit_closure_exprs( //dir=expr + unique int id: @explicit_closure_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @dot_syntax_call_expr +| @initializer_ref_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +initializer_ref_call_exprs( //dir=expr + unique int id: @initializer_ref_call_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@accessor_or_none = + @accessor +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@function_or_none = + @function +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@initializer_or_none = + @initializer +| @unspecified_element +; + +@key_path_component_or_none = + @key_path_component +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/swift.dbscheme b/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/swift.dbscheme new file mode 100644 index 00000000000..44e36e15e90 --- /dev/null +++ b/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/swift.dbscheme @@ -0,0 +1,2618 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @key_path_component +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +key_path_components( + unique int id: @key_path_component, + int kind: int ref, + int component_type: @type_or_none ref +); + +#keyset[id, index] +key_path_component_subscript_arguments( + int id: @key_path_component ref, + int index: int ref, + int subscript_argument: @argument_or_none ref +); + +#keyset[id] +key_path_component_tuple_indices( + int id: @key_path_component ref, + int tuple_index: int ref +); + +#keyset[id] +key_path_component_decl_refs( + int id: @key_path_component ref, + int decl_ref: @value_decl_or_none ref +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @extension_decl +| @function +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_storage_decl +| @enum_element_decl +| @function +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessors( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor: @accessor_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@function = + @accessor_or_named_function +| @deinitializer +| @initializer +; + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +@accessor_or_named_function = + @accessor +| @named_function +; + +deinitializers( //dir=decl + unique int id: @deinitializer +); + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +initializers( //dir=decl + unique int id: @initializer +); + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessors( //dir=decl + unique int id: @accessor +); + +#keyset[id] +accessor_is_getter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_setter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_will_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_did_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_read( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_modify( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_address( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_mutable_address( //dir=decl + int id: @accessor ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +named_functions( //dir=decl + unique int id: @named_function +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @closure_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initialization_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_initializer_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_initializer_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @explicit_closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@closure_expr = + @auto_closure_expr +| @explicit_closure_expr +; + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id, index] +key_path_expr_components( //dir=expr + int id: @key_path_expr ref, + int index: int ref, + int component: @key_path_component_or_none ref +); + +lazy_initialization_exprs( //dir=expr + unique int id: @lazy_initialization_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @function_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_initializer_ref_exprs( //dir=expr + unique int id: @other_initializer_ref_expr, + int initializer: @initializer_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_initializer_exprs( //dir=expr + unique int id: @rebind_self_in_initializer_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +explicit_closure_exprs( //dir=expr + unique int id: @explicit_closure_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @dot_syntax_call_expr +| @initializer_ref_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +initializer_ref_call_exprs( //dir=expr + unique int id: @initializer_ref_call_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@accessor_or_none = + @accessor +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@explicit_closure_expr_or_none = + @explicit_closure_expr +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@function_or_none = + @function +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@initializer_or_none = + @initializer +| @unspecified_element +; + +@key_path_component_or_none = + @key_path_component +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/upgrade.properties b/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/upgrade.properties new file mode 100644 index 00000000000..81989b85b9e --- /dev/null +++ b/swift/downgrades/147e087e57e51b2eb41e75c9c97380d0e6c20ecb/upgrade.properties @@ -0,0 +1,5 @@ +description: Revert making closure_body have type @abstract_closure_expr +compatibility: backwards +unspecified_elements.rel: run downgrade.qlo new_unspecified_elements +unspecified_element_parents.rel: run downgrade.qlo new_unspecified_element_parents +capture_list_exprs.rel: run downgrade.qlo new_capture_list_exprs diff --git a/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/old.dbscheme b/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/old.dbscheme new file mode 100644 index 00000000000..44e36e15e90 --- /dev/null +++ b/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/old.dbscheme @@ -0,0 +1,2618 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @key_path_component +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +key_path_components( + unique int id: @key_path_component, + int kind: int ref, + int component_type: @type_or_none ref +); + +#keyset[id, index] +key_path_component_subscript_arguments( + int id: @key_path_component ref, + int index: int ref, + int subscript_argument: @argument_or_none ref +); + +#keyset[id] +key_path_component_tuple_indices( + int id: @key_path_component ref, + int tuple_index: int ref +); + +#keyset[id] +key_path_component_decl_refs( + int id: @key_path_component ref, + int decl_ref: @value_decl_or_none ref +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @extension_decl +| @function +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_storage_decl +| @enum_element_decl +| @function +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessors( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor: @accessor_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@function = + @accessor_or_named_function +| @deinitializer +| @initializer +; + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +@accessor_or_named_function = + @accessor +| @named_function +; + +deinitializers( //dir=decl + unique int id: @deinitializer +); + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +initializers( //dir=decl + unique int id: @initializer +); + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessors( //dir=decl + unique int id: @accessor +); + +#keyset[id] +accessor_is_getter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_setter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_will_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_did_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_read( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_modify( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_address( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_mutable_address( //dir=decl + int id: @accessor ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +named_functions( //dir=decl + unique int id: @named_function +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @closure_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initialization_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_initializer_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_initializer_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @explicit_closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@closure_expr = + @auto_closure_expr +| @explicit_closure_expr +; + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id, index] +key_path_expr_components( //dir=expr + int id: @key_path_expr ref, + int index: int ref, + int component: @key_path_component_or_none ref +); + +lazy_initialization_exprs( //dir=expr + unique int id: @lazy_initialization_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @function_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_initializer_ref_exprs( //dir=expr + unique int id: @other_initializer_ref_expr, + int initializer: @initializer_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_initializer_exprs( //dir=expr + unique int id: @rebind_self_in_initializer_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +explicit_closure_exprs( //dir=expr + unique int id: @explicit_closure_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @dot_syntax_call_expr +| @initializer_ref_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +initializer_ref_call_exprs( //dir=expr + unique int id: @initializer_ref_call_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@accessor_or_none = + @accessor +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@explicit_closure_expr_or_none = + @explicit_closure_expr +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@function_or_none = + @function +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@initializer_or_none = + @initializer +| @unspecified_element +; + +@key_path_component_or_none = + @key_path_component +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/swift.dbscheme b/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/swift.dbscheme new file mode 100644 index 00000000000..147e087e57e --- /dev/null +++ b/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/swift.dbscheme @@ -0,0 +1,2618 @@ +// generated by codegen/codegen.py + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @callable +| @file +| @generic_context +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#keyset[id] +callable_self_params( + int id: @callable ref, + int self_param: @param_decl_or_none ref +); + +#keyset[id, index] +callable_params( + int id: @callable ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +#keyset[id] +callable_bodies( + int id: @callable ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file ref +); + +@locatable = + @argument +| @ast_node +| @comment +| @diagnostics +| @error_element +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_or_none ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file_or_none ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +@ast_node = + @availability_info +| @availability_spec +| @case_label_item +| @condition_element +| @decl +| @expr +| @key_path_component +| @pattern +| @stmt +| @stmt_condition +| @type_repr +; + +comments( + unique int id: @comment, + string text: string ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +diagnostics( + unique int id: @diagnostics, + string text: string ref, + int kind: int ref +); + +@error_element = + @error_expr +| @error_type +| @overloaded_decl_ref_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_chain_result_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @unresolved_type +| @unresolved_type_conversion_expr +| @unspecified_element +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +key_path_components( + unique int id: @key_path_component, + int kind: int ref, + int component_type: @type_or_none ref +); + +#keyset[id, index] +key_path_component_subscript_arguments( + int id: @key_path_component ref, + int index: int ref, + int subscript_argument: @argument_or_none ref +); + +#keyset[id] +key_path_component_tuple_indices( + int id: @key_path_component ref, + int tuple_index: int ref +); + +#keyset[id] +key_path_component_decl_refs( + int id: @key_path_component ref, + int decl_ref: @value_decl_or_none ref +); + +unspecified_elements( + unique int id: @unspecified_element, + string property: string ref, + string error: string ref +); + +#keyset[id] +unspecified_element_parents( + int id: @unspecified_element ref, + int parent: @element ref +); + +#keyset[id] +unspecified_element_indices( + int id: @unspecified_element ref, + int index: int ref +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_decl +| @enum_case_decl +| @extension_decl +| @if_config_decl +| @import_decl +| @missing_member_decl +| @operator_decl +| @pattern_binding_decl +| @pound_diagnostic_decl +| @precedence_group_decl +| @top_level_code_decl +| @value_decl +; + +#keyset[id] +decls( //dir=decl + int id: @decl ref, + int module: @module_decl_or_none ref +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @decl_or_none ref +); + +@generic_context = + @extension_decl +| @function +| @generic_type_decl +| @subscript_decl +; + +#keyset[id, index] +generic_context_generic_type_params( //dir=decl + int id: @generic_context ref, + int index: int ref, + int generic_type_param: @generic_type_param_decl_or_none ref +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl ref +); + +enum_case_decls( //dir=decl + unique int id: @enum_case_decl +); + +#keyset[id, index] +enum_case_decl_elements( //dir=decl + int id: @enum_case_decl ref, + int index: int ref, + int element: @enum_element_decl_or_none ref +); + +extension_decls( //dir=decl + unique int id: @extension_decl, + int extended_type_decl: @nominal_type_decl_or_none ref +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +if_config_decls( //dir=decl + unique int id: @if_config_decl +); + +#keyset[id, index] +if_config_decl_active_elements( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int active_element: @ast_node_or_none ref +); + +import_decls( //dir=decl + unique int id: @import_decl +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id] +import_decl_imported_modules( //dir=decl + int id: @import_decl ref, + int imported_module: @module_decl_or_none ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl_or_none ref +); + +missing_member_decls( //dir=decl + unique int id: @missing_member_decl, + string name: string ref +); + +@operator_decl = + @infix_operator_decl +| @postfix_operator_decl +| @prefix_operator_decl +; + +#keyset[id] +operator_decls( //dir=decl + int id: @operator_decl ref, + string name: string ref +); + +pattern_binding_decls( //dir=decl + unique int id: @pattern_binding_decl +); + +#keyset[id, index] +pattern_binding_decl_inits( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int init: @expr_or_none ref +); + +#keyset[id, index] +pattern_binding_decl_patterns( //dir=decl + int id: @pattern_binding_decl ref, + int index: int ref, + int pattern: @pattern_or_none ref +); + +pound_diagnostic_decls( //dir=decl + unique int id: @pound_diagnostic_decl, + int kind: int ref, + int message: @string_literal_expr_or_none ref +); + +precedence_group_decls( //dir=decl + unique int id: @precedence_group_decl +); + +top_level_code_decls( //dir=decl + unique int id: @top_level_code_decl, + int body: @brace_stmt_or_none ref +); + +@value_decl = + @abstract_storage_decl +| @enum_element_decl +| @function +| @type_decl +; + +#keyset[id] +value_decls( //dir=decl + int id: @value_decl ref, + int interface_type: @type_or_none ref +); + +@abstract_storage_decl = + @subscript_decl +| @var_decl +; + +#keyset[id, index] +abstract_storage_decl_accessors( //dir=decl + int id: @abstract_storage_decl ref, + int index: int ref, + int accessor: @accessor_or_none ref +); + +enum_element_decls( //dir=decl + unique int id: @enum_element_decl, + string name: string ref +); + +#keyset[id, index] +enum_element_decl_params( //dir=decl + int id: @enum_element_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@function = + @accessor_or_named_function +| @deinitializer +| @initializer +; + +infix_operator_decls( //dir=decl + unique int id: @infix_operator_decl +); + +#keyset[id] +infix_operator_decl_precedence_groups( //dir=decl + int id: @infix_operator_decl ref, + int precedence_group: @precedence_group_decl_or_none ref +); + +postfix_operator_decls( //dir=decl + unique int id: @postfix_operator_decl +); + +prefix_operator_decls( //dir=decl + unique int id: @prefix_operator_decl +); + +@type_decl = + @abstract_type_param_decl +| @generic_type_decl +| @module_decl +; + +#keyset[id] +type_decls( //dir=decl + int id: @type_decl ref, + string name: string ref +); + +#keyset[id, index] +type_decl_base_types( //dir=decl + int id: @type_decl ref, + int index: int ref, + int base_type: @type_or_none ref +); + +@abstract_type_param_decl = + @associated_type_decl +| @generic_type_param_decl +; + +@accessor_or_named_function = + @accessor +| @named_function +; + +deinitializers( //dir=decl + unique int id: @deinitializer +); + +@generic_type_decl = + @nominal_type_decl +| @opaque_type_decl +| @type_alias_decl +; + +initializers( //dir=decl + unique int id: @initializer +); + +module_decls( //dir=decl + unique int id: @module_decl +); + +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + +module_decl_imported_modules( //dir=decl + int id: @module_decl ref, + int imported_module: @module_decl_or_none ref +); + +module_decl_exported_modules( //dir=decl + int id: @module_decl ref, + int exported_module: @module_decl_or_none ref +); + +subscript_decls( //dir=decl + unique int id: @subscript_decl, + int element_type: @type_or_none ref +); + +#keyset[id, index] +subscript_decl_params( //dir=decl + int id: @subscript_decl ref, + int index: int ref, + int param: @param_decl_or_none ref +); + +@var_decl = + @concrete_var_decl +| @param_decl +; + +#keyset[id] +var_decls( //dir=decl + int id: @var_decl ref, + string name: string ref, + int type_: @type_or_none ref +); + +#keyset[id] +var_decl_attached_property_wrapper_types( //dir=decl + int id: @var_decl ref, + int attached_property_wrapper_type: @type_or_none ref +); + +#keyset[id] +var_decl_parent_patterns( //dir=decl + int id: @var_decl ref, + int parent_pattern: @pattern_or_none ref +); + +#keyset[id] +var_decl_parent_initializers( //dir=decl + int id: @var_decl ref, + int parent_initializer: @expr_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_backing_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_backing_var: @var_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_var_bindings( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +var_decl_property_wrapper_projection_vars( //dir=decl + int id: @var_decl ref, + int property_wrapper_projection_var: @var_decl_or_none ref +); + +accessors( //dir=decl + unique int id: @accessor +); + +#keyset[id] +accessor_is_getter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_setter( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_will_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_did_set( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_read( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_modify( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_address( //dir=decl + int id: @accessor ref +); + +#keyset[id] +accessor_is_unsafe_mutable_address( //dir=decl + int id: @accessor ref +); + +associated_type_decls( //dir=decl + unique int id: @associated_type_decl +); + +concrete_var_decls( //dir=decl + unique int id: @concrete_var_decl, + int introducer_int: int ref +); + +generic_type_param_decls( //dir=decl + unique int id: @generic_type_param_decl +); + +named_functions( //dir=decl + unique int id: @named_function +); + +@nominal_type_decl = + @class_decl +| @enum_decl +| @protocol_decl +| @struct_decl +; + +#keyset[id] +nominal_type_decls( //dir=decl + int id: @nominal_type_decl ref, + int type_: @type_or_none ref +); + +opaque_type_decls( //dir=decl + unique int id: @opaque_type_decl, + int naming_declaration: @value_decl_or_none ref +); + +#keyset[id, index] +opaque_type_decl_opaque_generic_params( //dir=decl + int id: @opaque_type_decl ref, + int index: int ref, + int opaque_generic_param: @generic_type_param_type_or_none ref +); + +param_decls( //dir=decl + unique int id: @param_decl +); + +#keyset[id] +param_decl_is_inout( //dir=decl + int id: @param_decl ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_var_bindings( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var_binding: @pattern_binding_decl_or_none ref +); + +#keyset[id] +param_decl_property_wrapper_local_wrapped_vars( //dir=decl + int id: @param_decl ref, + int property_wrapper_local_wrapped_var: @var_decl_or_none ref +); + +type_alias_decls( //dir=decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref +); + +class_decls( //dir=decl + unique int id: @class_decl +); + +enum_decls( //dir=decl + unique int id: @enum_decl +); + +protocol_decls( //dir=decl + unique int id: @protocol_decl +); + +struct_decls( //dir=decl + unique int id: @struct_decl +); + +arguments( //dir=expr + unique int id: @argument, + string label: string ref, + int expr: @expr_or_none ref +); + +@expr = + @any_try_expr +| @applied_property_wrapper_expr +| @apply_expr +| @assign_expr +| @bind_optional_expr +| @capture_list_expr +| @closure_expr +| @collection_expr +| @decl_ref_expr +| @default_argument_expr +| @discard_assignment_expr +| @dot_syntax_base_ignored_expr +| @dynamic_type_expr +| @enum_is_case_expr +| @error_expr +| @explicit_cast_expr +| @force_value_expr +| @identity_expr +| @if_expr +| @implicit_conversion_expr +| @in_out_expr +| @key_path_application_expr +| @key_path_dot_expr +| @key_path_expr +| @lazy_initialization_expr +| @literal_expr +| @lookup_expr +| @make_temporarily_escapable_expr +| @obj_c_selector_expr +| @one_way_expr +| @opaque_value_expr +| @open_existential_expr +| @optional_evaluation_expr +| @other_initializer_ref_expr +| @overloaded_decl_ref_expr +| @property_wrapper_value_placeholder_expr +| @rebind_self_in_initializer_expr +| @sequence_expr +| @super_ref_expr +| @tap_expr +| @tuple_element_expr +| @tuple_expr +| @type_expr +| @unresolved_decl_ref_expr +| @unresolved_dot_expr +| @unresolved_member_expr +| @unresolved_pattern_expr +| @unresolved_specialize_expr +| @vararg_expansion_expr +; + +#keyset[id] +expr_types( //dir=expr + int id: @expr ref, + int type_: @type_or_none ref +); + +@any_try_expr = + @force_try_expr +| @optional_try_expr +| @try_expr +; + +#keyset[id] +any_try_exprs( //dir=expr + int id: @any_try_expr ref, + int sub_expr: @expr_or_none ref +); + +applied_property_wrapper_exprs( //dir=expr + unique int id: @applied_property_wrapper_expr, + int kind: int ref, + int value: @expr_or_none ref, + int param: @param_decl_or_none ref +); + +@apply_expr = + @binary_expr +| @call_expr +| @postfix_unary_expr +| @prefix_unary_expr +| @self_apply_expr +; + +#keyset[id] +apply_exprs( //dir=expr + int id: @apply_expr ref, + int function: @expr_or_none ref +); + +#keyset[id, index] +apply_expr_arguments( //dir=expr + int id: @apply_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +assign_exprs( //dir=expr + unique int id: @assign_expr, + int dest: @expr_or_none ref, + int source: @expr_or_none ref +); + +bind_optional_exprs( //dir=expr + unique int id: @bind_optional_expr, + int sub_expr: @expr_or_none ref +); + +capture_list_exprs( //dir=expr + unique int id: @capture_list_expr, + int closure_body: @closure_expr_or_none ref +); + +#keyset[id, index] +capture_list_expr_binding_decls( //dir=expr + int id: @capture_list_expr ref, + int index: int ref, + int binding_decl: @pattern_binding_decl_or_none ref +); + +@closure_expr = + @auto_closure_expr +| @explicit_closure_expr +; + +@collection_expr = + @array_expr +| @dictionary_expr +; + +decl_ref_exprs( //dir=expr + unique int id: @decl_ref_expr, + int decl: @decl_or_none ref +); + +#keyset[id, index] +decl_ref_expr_replacement_types( //dir=expr + int id: @decl_ref_expr ref, + int index: int ref, + int replacement_type: @type_or_none ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_ordinary_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +#keyset[id] +decl_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @decl_ref_expr ref +); + +default_argument_exprs( //dir=expr + unique int id: @default_argument_expr, + int param_decl: @param_decl_or_none ref, + int param_index: int ref +); + +#keyset[id] +default_argument_expr_caller_side_defaults( //dir=expr + int id: @default_argument_expr ref, + int caller_side_default: @expr_or_none ref +); + +discard_assignment_exprs( //dir=expr + unique int id: @discard_assignment_expr +); + +dot_syntax_base_ignored_exprs( //dir=expr + unique int id: @dot_syntax_base_ignored_expr, + int qualifier: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +dynamic_type_exprs( //dir=expr + unique int id: @dynamic_type_expr, + int base: @expr_or_none ref +); + +enum_is_case_exprs( //dir=expr + unique int id: @enum_is_case_expr, + int sub_expr: @expr_or_none ref, + int element: @enum_element_decl_or_none ref +); + +error_exprs( //dir=expr + unique int id: @error_expr +); + +@explicit_cast_expr = + @checked_cast_expr +| @coerce_expr +; + +#keyset[id] +explicit_cast_exprs( //dir=expr + int id: @explicit_cast_expr ref, + int sub_expr: @expr_or_none ref +); + +force_value_exprs( //dir=expr + unique int id: @force_value_expr, + int sub_expr: @expr_or_none ref +); + +@identity_expr = + @await_expr +| @dot_self_expr +| @paren_expr +| @unresolved_member_chain_result_expr +; + +#keyset[id] +identity_exprs( //dir=expr + int id: @identity_expr ref, + int sub_expr: @expr_or_none ref +); + +if_exprs( //dir=expr + unique int id: @if_expr, + int condition: @expr_or_none ref, + int then_expr: @expr_or_none ref, + int else_expr: @expr_or_none ref +); + +@implicit_conversion_expr = + @abi_safe_conversion_expr +| @any_hashable_erasure_expr +| @archetype_to_super_expr +| @array_to_pointer_expr +| @bridge_from_obj_c_expr +| @bridge_to_obj_c_expr +| @class_metatype_to_object_expr +| @collection_upcast_conversion_expr +| @conditional_bridge_from_obj_c_expr +| @covariant_function_conversion_expr +| @covariant_return_conversion_expr +| @derived_to_base_expr +| @destructure_tuple_expr +| @differentiable_function_expr +| @differentiable_function_extract_original_expr +| @erasure_expr +| @existential_metatype_to_object_expr +| @foreign_object_conversion_expr +| @function_conversion_expr +| @in_out_to_pointer_expr +| @inject_into_optional_expr +| @linear_function_expr +| @linear_function_extract_original_expr +| @linear_to_differentiable_function_expr +| @load_expr +| @metatype_conversion_expr +| @pointer_to_pointer_expr +| @protocol_metatype_to_object_expr +| @string_to_pointer_expr +| @underlying_to_opaque_expr +| @unevaluated_instance_expr +| @unresolved_type_conversion_expr +; + +#keyset[id] +implicit_conversion_exprs( //dir=expr + int id: @implicit_conversion_expr ref, + int sub_expr: @expr_or_none ref +); + +in_out_exprs( //dir=expr + unique int id: @in_out_expr, + int sub_expr: @expr_or_none ref +); + +key_path_application_exprs( //dir=expr + unique int id: @key_path_application_expr, + int base: @expr_or_none ref, + int key_path: @expr_or_none ref +); + +key_path_dot_exprs( //dir=expr + unique int id: @key_path_dot_expr +); + +key_path_exprs( //dir=expr + unique int id: @key_path_expr +); + +#keyset[id] +key_path_expr_roots( //dir=expr + int id: @key_path_expr ref, + int root: @type_repr_or_none ref +); + +#keyset[id, index] +key_path_expr_components( //dir=expr + int id: @key_path_expr ref, + int index: int ref, + int component: @key_path_component_or_none ref +); + +lazy_initialization_exprs( //dir=expr + unique int id: @lazy_initialization_expr, + int sub_expr: @expr_or_none ref +); + +@literal_expr = + @builtin_literal_expr +| @interpolated_string_literal_expr +| @nil_literal_expr +| @object_literal_expr +| @regex_literal_expr +; + +@lookup_expr = + @dynamic_lookup_expr +| @member_ref_expr +| @subscript_expr +; + +#keyset[id] +lookup_exprs( //dir=expr + int id: @lookup_expr ref, + int base: @expr_or_none ref +); + +#keyset[id] +lookup_expr_members( //dir=expr + int id: @lookup_expr ref, + int member: @decl_or_none ref +); + +make_temporarily_escapable_exprs( //dir=expr + unique int id: @make_temporarily_escapable_expr, + int escaping_closure: @opaque_value_expr_or_none ref, + int nonescaping_closure: @expr_or_none ref, + int sub_expr: @expr_or_none ref +); + +obj_c_selector_exprs( //dir=expr + unique int id: @obj_c_selector_expr, + int sub_expr: @expr_or_none ref, + int method: @function_or_none ref +); + +one_way_exprs( //dir=expr + unique int id: @one_way_expr, + int sub_expr: @expr_or_none ref +); + +opaque_value_exprs( //dir=expr + unique int id: @opaque_value_expr +); + +open_existential_exprs( //dir=expr + unique int id: @open_existential_expr, + int sub_expr: @expr_or_none ref, + int existential: @expr_or_none ref, + int opaque_expr: @opaque_value_expr_or_none ref +); + +optional_evaluation_exprs( //dir=expr + unique int id: @optional_evaluation_expr, + int sub_expr: @expr_or_none ref +); + +other_initializer_ref_exprs( //dir=expr + unique int id: @other_initializer_ref_expr, + int initializer: @initializer_or_none ref +); + +overloaded_decl_ref_exprs( //dir=expr + unique int id: @overloaded_decl_ref_expr +); + +#keyset[id, index] +overloaded_decl_ref_expr_possible_declarations( //dir=expr + int id: @overloaded_decl_ref_expr ref, + int index: int ref, + int possible_declaration: @value_decl_or_none ref +); + +property_wrapper_value_placeholder_exprs( //dir=expr + unique int id: @property_wrapper_value_placeholder_expr, + int placeholder: @opaque_value_expr_or_none ref +); + +#keyset[id] +property_wrapper_value_placeholder_expr_wrapped_values( //dir=expr + int id: @property_wrapper_value_placeholder_expr ref, + int wrapped_value: @expr_or_none ref +); + +rebind_self_in_initializer_exprs( //dir=expr + unique int id: @rebind_self_in_initializer_expr, + int sub_expr: @expr_or_none ref, + int self: @var_decl_or_none ref +); + +sequence_exprs( //dir=expr + unique int id: @sequence_expr +); + +#keyset[id, index] +sequence_expr_elements( //dir=expr + int id: @sequence_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +super_ref_exprs( //dir=expr + unique int id: @super_ref_expr, + int self: @var_decl_or_none ref +); + +tap_exprs( //dir=expr + unique int id: @tap_expr, + int body: @brace_stmt_or_none ref, + int var: @var_decl_or_none ref +); + +#keyset[id] +tap_expr_sub_exprs( //dir=expr + int id: @tap_expr ref, + int sub_expr: @expr_or_none ref +); + +tuple_element_exprs( //dir=expr + unique int id: @tuple_element_expr, + int sub_expr: @expr_or_none ref, + int index: int ref +); + +tuple_exprs( //dir=expr + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_elements( //dir=expr + int id: @tuple_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +type_exprs( //dir=expr + unique int id: @type_expr +); + +#keyset[id] +type_expr_type_reprs( //dir=expr + int id: @type_expr ref, + int type_repr: @type_repr_or_none ref +); + +unresolved_decl_ref_exprs( //dir=expr + unique int id: @unresolved_decl_ref_expr +); + +#keyset[id] +unresolved_decl_ref_expr_names( //dir=expr + int id: @unresolved_decl_ref_expr ref, + string name: string ref +); + +unresolved_dot_exprs( //dir=expr + unique int id: @unresolved_dot_expr, + int base: @expr_or_none ref, + string name: string ref +); + +unresolved_member_exprs( //dir=expr + unique int id: @unresolved_member_expr, + string name: string ref +); + +unresolved_pattern_exprs( //dir=expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern_or_none ref +); + +unresolved_specialize_exprs( //dir=expr + unique int id: @unresolved_specialize_expr, + int sub_expr: @expr_or_none ref +); + +vararg_expansion_exprs( //dir=expr + unique int id: @vararg_expansion_expr, + int sub_expr: @expr_or_none ref +); + +abi_safe_conversion_exprs( //dir=expr + unique int id: @abi_safe_conversion_expr +); + +any_hashable_erasure_exprs( //dir=expr + unique int id: @any_hashable_erasure_expr +); + +archetype_to_super_exprs( //dir=expr + unique int id: @archetype_to_super_expr +); + +array_exprs( //dir=expr + unique int id: @array_expr +); + +#keyset[id, index] +array_expr_elements( //dir=expr + int id: @array_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +array_to_pointer_exprs( //dir=expr + unique int id: @array_to_pointer_expr +); + +auto_closure_exprs( //dir=expr + unique int id: @auto_closure_expr +); + +await_exprs( //dir=expr + unique int id: @await_expr +); + +binary_exprs( //dir=expr + unique int id: @binary_expr +); + +bridge_from_obj_c_exprs( //dir=expr + unique int id: @bridge_from_obj_c_expr +); + +bridge_to_obj_c_exprs( //dir=expr + unique int id: @bridge_to_obj_c_expr +); + +@builtin_literal_expr = + @boolean_literal_expr +| @magic_identifier_literal_expr +| @number_literal_expr +| @string_literal_expr +; + +call_exprs( //dir=expr + unique int id: @call_expr +); + +@checked_cast_expr = + @conditional_checked_cast_expr +| @forced_checked_cast_expr +| @is_expr +; + +class_metatype_to_object_exprs( //dir=expr + unique int id: @class_metatype_to_object_expr +); + +coerce_exprs( //dir=expr + unique int id: @coerce_expr +); + +collection_upcast_conversion_exprs( //dir=expr + unique int id: @collection_upcast_conversion_expr +); + +conditional_bridge_from_obj_c_exprs( //dir=expr + unique int id: @conditional_bridge_from_obj_c_expr +); + +covariant_function_conversion_exprs( //dir=expr + unique int id: @covariant_function_conversion_expr +); + +covariant_return_conversion_exprs( //dir=expr + unique int id: @covariant_return_conversion_expr +); + +derived_to_base_exprs( //dir=expr + unique int id: @derived_to_base_expr +); + +destructure_tuple_exprs( //dir=expr + unique int id: @destructure_tuple_expr +); + +dictionary_exprs( //dir=expr + unique int id: @dictionary_expr +); + +#keyset[id, index] +dictionary_expr_elements( //dir=expr + int id: @dictionary_expr ref, + int index: int ref, + int element: @expr_or_none ref +); + +differentiable_function_exprs( //dir=expr + unique int id: @differentiable_function_expr +); + +differentiable_function_extract_original_exprs( //dir=expr + unique int id: @differentiable_function_extract_original_expr +); + +dot_self_exprs( //dir=expr + unique int id: @dot_self_expr +); + +@dynamic_lookup_expr = + @dynamic_member_ref_expr +| @dynamic_subscript_expr +; + +erasure_exprs( //dir=expr + unique int id: @erasure_expr +); + +existential_metatype_to_object_exprs( //dir=expr + unique int id: @existential_metatype_to_object_expr +); + +explicit_closure_exprs( //dir=expr + unique int id: @explicit_closure_expr +); + +force_try_exprs( //dir=expr + unique int id: @force_try_expr +); + +foreign_object_conversion_exprs( //dir=expr + unique int id: @foreign_object_conversion_expr +); + +function_conversion_exprs( //dir=expr + unique int id: @function_conversion_expr +); + +in_out_to_pointer_exprs( //dir=expr + unique int id: @in_out_to_pointer_expr +); + +inject_into_optional_exprs( //dir=expr + unique int id: @inject_into_optional_expr +); + +interpolated_string_literal_exprs( //dir=expr + unique int id: @interpolated_string_literal_expr +); + +#keyset[id] +interpolated_string_literal_expr_interpolation_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int interpolation_expr: @opaque_value_expr_or_none ref +); + +#keyset[id] +interpolated_string_literal_expr_appending_exprs( //dir=expr + int id: @interpolated_string_literal_expr ref, + int appending_expr: @tap_expr_or_none ref +); + +linear_function_exprs( //dir=expr + unique int id: @linear_function_expr +); + +linear_function_extract_original_exprs( //dir=expr + unique int id: @linear_function_extract_original_expr +); + +linear_to_differentiable_function_exprs( //dir=expr + unique int id: @linear_to_differentiable_function_expr +); + +load_exprs( //dir=expr + unique int id: @load_expr +); + +member_ref_exprs( //dir=expr + unique int id: @member_ref_expr +); + +#keyset[id] +member_ref_expr_has_direct_to_storage_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_ordinary_semantics( //dir=expr + int id: @member_ref_expr ref +); + +#keyset[id] +member_ref_expr_has_distributed_thunk_semantics( //dir=expr + int id: @member_ref_expr ref +); + +metatype_conversion_exprs( //dir=expr + unique int id: @metatype_conversion_expr +); + +nil_literal_exprs( //dir=expr + unique int id: @nil_literal_expr +); + +object_literal_exprs( //dir=expr + unique int id: @object_literal_expr, + int kind: int ref +); + +#keyset[id, index] +object_literal_expr_arguments( //dir=expr + int id: @object_literal_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +optional_try_exprs( //dir=expr + unique int id: @optional_try_expr +); + +paren_exprs( //dir=expr + unique int id: @paren_expr +); + +pointer_to_pointer_exprs( //dir=expr + unique int id: @pointer_to_pointer_expr +); + +postfix_unary_exprs( //dir=expr + unique int id: @postfix_unary_expr +); + +prefix_unary_exprs( //dir=expr + unique int id: @prefix_unary_expr +); + +protocol_metatype_to_object_exprs( //dir=expr + unique int id: @protocol_metatype_to_object_expr +); + +regex_literal_exprs( //dir=expr + unique int id: @regex_literal_expr, + string pattern: string ref, + int version: int ref +); + +@self_apply_expr = + @dot_syntax_call_expr +| @initializer_ref_call_expr +; + +#keyset[id] +self_apply_exprs( //dir=expr + int id: @self_apply_expr ref, + int base: @expr_or_none ref +); + +string_to_pointer_exprs( //dir=expr + unique int id: @string_to_pointer_expr +); + +subscript_exprs( //dir=expr + unique int id: @subscript_expr +); + +#keyset[id, index] +subscript_expr_arguments( //dir=expr + int id: @subscript_expr ref, + int index: int ref, + int argument: @argument_or_none ref +); + +#keyset[id] +subscript_expr_has_direct_to_storage_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_direct_to_implementation_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_ordinary_semantics( //dir=expr + int id: @subscript_expr ref +); + +#keyset[id] +subscript_expr_has_distributed_thunk_semantics( //dir=expr + int id: @subscript_expr ref +); + +try_exprs( //dir=expr + unique int id: @try_expr +); + +underlying_to_opaque_exprs( //dir=expr + unique int id: @underlying_to_opaque_expr +); + +unevaluated_instance_exprs( //dir=expr + unique int id: @unevaluated_instance_expr +); + +unresolved_member_chain_result_exprs( //dir=expr + unique int id: @unresolved_member_chain_result_expr +); + +unresolved_type_conversion_exprs( //dir=expr + unique int id: @unresolved_type_conversion_expr +); + +boolean_literal_exprs( //dir=expr + unique int id: @boolean_literal_expr, + boolean value: boolean ref +); + +conditional_checked_cast_exprs( //dir=expr + unique int id: @conditional_checked_cast_expr +); + +dot_syntax_call_exprs( //dir=expr + unique int id: @dot_syntax_call_expr +); + +dynamic_member_ref_exprs( //dir=expr + unique int id: @dynamic_member_ref_expr +); + +dynamic_subscript_exprs( //dir=expr + unique int id: @dynamic_subscript_expr +); + +forced_checked_cast_exprs( //dir=expr + unique int id: @forced_checked_cast_expr +); + +initializer_ref_call_exprs( //dir=expr + unique int id: @initializer_ref_call_expr +); + +is_exprs( //dir=expr + unique int id: @is_expr +); + +magic_identifier_literal_exprs( //dir=expr + unique int id: @magic_identifier_literal_expr, + string kind: string ref +); + +@number_literal_expr = + @float_literal_expr +| @integer_literal_expr +; + +string_literal_exprs( //dir=expr + unique int id: @string_literal_expr, + string value: string ref +); + +float_literal_exprs( //dir=expr + unique int id: @float_literal_expr, + string string_value: string ref +); + +integer_literal_exprs( //dir=expr + unique int id: @integer_literal_expr, + string string_value: string ref +); + +@pattern = + @any_pattern +| @binding_pattern +| @bool_pattern +| @enum_element_pattern +| @expr_pattern +| @is_pattern +| @named_pattern +| @optional_some_pattern +| @paren_pattern +| @tuple_pattern +| @typed_pattern +; + +any_patterns( //dir=pattern + unique int id: @any_pattern +); + +binding_patterns( //dir=pattern + unique int id: @binding_pattern, + int sub_pattern: @pattern_or_none ref +); + +bool_patterns( //dir=pattern + unique int id: @bool_pattern, + boolean value: boolean ref +); + +enum_element_patterns( //dir=pattern + unique int id: @enum_element_pattern, + int element: @enum_element_decl_or_none ref +); + +#keyset[id] +enum_element_pattern_sub_patterns( //dir=pattern + int id: @enum_element_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +expr_patterns( //dir=pattern + unique int id: @expr_pattern, + int sub_expr: @expr_or_none ref +); + +is_patterns( //dir=pattern + unique int id: @is_pattern +); + +#keyset[id] +is_pattern_cast_type_reprs( //dir=pattern + int id: @is_pattern ref, + int cast_type_repr: @type_repr_or_none ref +); + +#keyset[id] +is_pattern_sub_patterns( //dir=pattern + int id: @is_pattern ref, + int sub_pattern: @pattern_or_none ref +); + +named_patterns( //dir=pattern + unique int id: @named_pattern, + string name: string ref +); + +optional_some_patterns( //dir=pattern + unique int id: @optional_some_pattern, + int sub_pattern: @pattern_or_none ref +); + +paren_patterns( //dir=pattern + unique int id: @paren_pattern, + int sub_pattern: @pattern_or_none ref +); + +tuple_patterns( //dir=pattern + unique int id: @tuple_pattern +); + +#keyset[id, index] +tuple_pattern_elements( //dir=pattern + int id: @tuple_pattern ref, + int index: int ref, + int element: @pattern_or_none ref +); + +typed_patterns( //dir=pattern + unique int id: @typed_pattern, + int sub_pattern: @pattern_or_none ref +); + +#keyset[id] +typed_pattern_type_reprs( //dir=pattern + int id: @typed_pattern ref, + int type_repr: @type_repr_or_none ref +); + +case_label_items( //dir=stmt + unique int id: @case_label_item, + int pattern: @pattern_or_none ref +); + +#keyset[id] +case_label_item_guards( //dir=stmt + int id: @case_label_item ref, + int guard: @expr_or_none ref +); + +condition_elements( //dir=stmt + unique int id: @condition_element +); + +#keyset[id] +condition_element_booleans( //dir=stmt + int id: @condition_element ref, + int boolean_: @expr_or_none ref +); + +#keyset[id] +condition_element_patterns( //dir=stmt + int id: @condition_element ref, + int pattern: @pattern_or_none ref +); + +#keyset[id] +condition_element_initializers( //dir=stmt + int id: @condition_element ref, + int initializer: @expr_or_none ref +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_or_none ref +); + +@stmt = + @brace_stmt +| @break_stmt +| @case_stmt +| @continue_stmt +| @defer_stmt +| @fail_stmt +| @fallthrough_stmt +| @labeled_stmt +| @pound_assert_stmt +| @return_stmt +| @throw_stmt +| @yield_stmt +; + +stmt_conditions( //dir=stmt + unique int id: @stmt_condition +); + +#keyset[id, index] +stmt_condition_elements( //dir=stmt + int id: @stmt_condition ref, + int index: int ref, + int element: @condition_element_or_none ref +); + +brace_stmts( //dir=stmt + unique int id: @brace_stmt +); + +#keyset[id, index] +brace_stmt_elements( //dir=stmt + int id: @brace_stmt ref, + int index: int ref, + int element: @ast_node_or_none ref +); + +break_stmts( //dir=stmt + unique int id: @break_stmt +); + +#keyset[id] +break_stmt_target_names( //dir=stmt + int id: @break_stmt ref, + string target_name: string ref +); + +#keyset[id] +break_stmt_targets( //dir=stmt + int id: @break_stmt ref, + int target: @stmt_or_none ref +); + +case_stmts( //dir=stmt + unique int id: @case_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +case_stmt_labels( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int label: @case_label_item_or_none ref +); + +#keyset[id, index] +case_stmt_variables( //dir=stmt + int id: @case_stmt ref, + int index: int ref, + int variable: @var_decl_or_none ref +); + +continue_stmts( //dir=stmt + unique int id: @continue_stmt +); + +#keyset[id] +continue_stmt_target_names( //dir=stmt + int id: @continue_stmt ref, + string target_name: string ref +); + +#keyset[id] +continue_stmt_targets( //dir=stmt + int id: @continue_stmt ref, + int target: @stmt_or_none ref +); + +defer_stmts( //dir=stmt + unique int id: @defer_stmt, + int body: @brace_stmt_or_none ref +); + +fail_stmts( //dir=stmt + unique int id: @fail_stmt +); + +fallthrough_stmts( //dir=stmt + unique int id: @fallthrough_stmt, + int fallthrough_source: @case_stmt_or_none ref, + int fallthrough_dest: @case_stmt_or_none ref +); + +@labeled_stmt = + @do_catch_stmt +| @do_stmt +| @for_each_stmt +| @labeled_conditional_stmt +| @repeat_while_stmt +| @switch_stmt +; + +#keyset[id] +labeled_stmt_labels( //dir=stmt + int id: @labeled_stmt ref, + string label: string ref +); + +pound_assert_stmts( //dir=stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref +); + +return_stmts( //dir=stmt + unique int id: @return_stmt +); + +#keyset[id] +return_stmt_results( //dir=stmt + int id: @return_stmt ref, + int result: @expr_or_none ref +); + +throw_stmts( //dir=stmt + unique int id: @throw_stmt, + int sub_expr: @expr_or_none ref +); + +yield_stmts( //dir=stmt + unique int id: @yield_stmt +); + +#keyset[id, index] +yield_stmt_results( //dir=stmt + int id: @yield_stmt ref, + int index: int ref, + int result: @expr_or_none ref +); + +do_catch_stmts( //dir=stmt + unique int id: @do_catch_stmt, + int body: @stmt_or_none ref +); + +#keyset[id, index] +do_catch_stmt_catches( //dir=stmt + int id: @do_catch_stmt ref, + int index: int ref, + int catch: @case_stmt_or_none ref +); + +do_stmts( //dir=stmt + unique int id: @do_stmt, + int body: @brace_stmt_or_none ref +); + +for_each_stmts( //dir=stmt + unique int id: @for_each_stmt, + int pattern: @pattern_or_none ref, + int sequence: @expr_or_none ref, + int body: @brace_stmt_or_none ref +); + +#keyset[id] +for_each_stmt_wheres( //dir=stmt + int id: @for_each_stmt ref, + int where: @expr_or_none ref +); + +@labeled_conditional_stmt = + @guard_stmt +| @if_stmt +| @while_stmt +; + +#keyset[id] +labeled_conditional_stmts( //dir=stmt + int id: @labeled_conditional_stmt ref, + int condition: @stmt_condition_or_none ref +); + +repeat_while_stmts( //dir=stmt + unique int id: @repeat_while_stmt, + int condition: @expr_or_none ref, + int body: @stmt_or_none ref +); + +switch_stmts( //dir=stmt + unique int id: @switch_stmt, + int expr: @expr_or_none ref +); + +#keyset[id, index] +switch_stmt_cases( //dir=stmt + int id: @switch_stmt ref, + int index: int ref, + int case_: @case_stmt_or_none ref +); + +guard_stmts( //dir=stmt + unique int id: @guard_stmt, + int body: @brace_stmt_or_none ref +); + +if_stmts( //dir=stmt + unique int id: @if_stmt, + int then: @stmt_or_none ref +); + +#keyset[id] +if_stmt_elses( //dir=stmt + int id: @if_stmt ref, + int else: @stmt_or_none ref +); + +while_stmts( //dir=stmt + unique int id: @while_stmt, + int body: @stmt_or_none ref +); + +@type = + @any_function_type +| @any_generic_type +| @any_metatype_type +| @builtin_type +| @dependent_member_type +| @dynamic_self_type +| @error_type +| @existential_type +| @in_out_type +| @l_value_type +| @module_type +| @parameterized_protocol_type +| @protocol_composition_type +| @reference_storage_type +| @substitutable_type +| @sugar_type +| @tuple_type +| @unresolved_type +; + +#keyset[id] +types( //dir=type + int id: @type ref, + string name: string ref, + int canonical_type: @type_or_none ref +); + +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type_or_none ref +); + +@any_function_type = + @function_type +| @generic_function_type +; + +#keyset[id] +any_function_types( //dir=type + int id: @any_function_type ref, + int result: @type_or_none ref +); + +#keyset[id, index] +any_function_type_param_types( //dir=type + int id: @any_function_type ref, + int index: int ref, + int param_type: @type_or_none ref +); + +#keyset[id] +any_function_type_is_throwing( //dir=type + int id: @any_function_type ref +); + +#keyset[id] +any_function_type_is_async( //dir=type + int id: @any_function_type ref +); + +@any_generic_type = + @nominal_or_bound_generic_nominal_type +| @unbound_generic_type +; + +#keyset[id] +any_generic_types( //dir=type + int id: @any_generic_type ref, + int declaration: @generic_type_decl_or_none ref +); + +#keyset[id] +any_generic_type_parents( //dir=type + int id: @any_generic_type ref, + int parent: @type_or_none ref +); + +@any_metatype_type = + @existential_metatype_type +| @metatype_type +; + +@builtin_type = + @any_builtin_integer_type +| @builtin_bridge_object_type +| @builtin_default_actor_storage_type +| @builtin_executor_type +| @builtin_float_type +| @builtin_job_type +| @builtin_native_object_type +| @builtin_raw_pointer_type +| @builtin_raw_unsafe_continuation_type +| @builtin_unsafe_value_buffer_type +| @builtin_vector_type +; + +dependent_member_types( //dir=type + unique int id: @dependent_member_type, + int base_type: @type_or_none ref, + int associated_type_decl: @associated_type_decl_or_none ref +); + +dynamic_self_types( //dir=type + unique int id: @dynamic_self_type, + int static_self_type: @type_or_none ref +); + +error_types( //dir=type + unique int id: @error_type +); + +existential_types( //dir=type + unique int id: @existential_type, + int constraint: @type_or_none ref +); + +in_out_types( //dir=type + unique int id: @in_out_type, + int object_type: @type_or_none ref +); + +l_value_types( //dir=type + unique int id: @l_value_type, + int object_type: @type_or_none ref +); + +module_types( //dir=type + unique int id: @module_type, + int module: @module_decl_or_none ref +); + +parameterized_protocol_types( //dir=type + unique int id: @parameterized_protocol_type, + int base: @protocol_type_or_none ref +); + +#keyset[id, index] +parameterized_protocol_type_args( //dir=type + int id: @parameterized_protocol_type ref, + int index: int ref, + int arg: @type_or_none ref +); + +protocol_composition_types( //dir=type + unique int id: @protocol_composition_type +); + +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type_or_none ref +); + +@reference_storage_type = + @unmanaged_storage_type +| @unowned_storage_type +| @weak_storage_type +; + +#keyset[id] +reference_storage_types( //dir=type + int id: @reference_storage_type ref, + int referent_type: @type_or_none ref +); + +@substitutable_type = + @archetype_type +| @generic_type_param_type +; + +@sugar_type = + @paren_type +| @syntax_sugar_type +| @type_alias_type +; + +tuple_types( //dir=type + unique int id: @tuple_type +); + +#keyset[id, index] +tuple_type_types( //dir=type + int id: @tuple_type ref, + int index: int ref, + int type_: @type_or_none ref +); + +#keyset[id, index] +tuple_type_names( //dir=type + int id: @tuple_type ref, + int index: int ref, + string name: string ref +); + +unresolved_types( //dir=type + unique int id: @unresolved_type +); + +@any_builtin_integer_type = + @builtin_integer_literal_type +| @builtin_integer_type +; + +@archetype_type = + @opaque_type_archetype_type +| @opened_archetype_type +| @primary_archetype_type +; + +#keyset[id] +archetype_types( //dir=type + int id: @archetype_type ref, + int interface_type: @type_or_none ref +); + +#keyset[id] +archetype_type_superclasses( //dir=type + int id: @archetype_type ref, + int superclass: @type_or_none ref +); + +#keyset[id, index] +archetype_type_protocols( //dir=type + int id: @archetype_type ref, + int index: int ref, + int protocol: @protocol_decl_or_none ref +); + +builtin_bridge_object_types( //dir=type + unique int id: @builtin_bridge_object_type +); + +builtin_default_actor_storage_types( //dir=type + unique int id: @builtin_default_actor_storage_type +); + +builtin_executor_types( //dir=type + unique int id: @builtin_executor_type +); + +builtin_float_types( //dir=type + unique int id: @builtin_float_type +); + +builtin_job_types( //dir=type + unique int id: @builtin_job_type +); + +builtin_native_object_types( //dir=type + unique int id: @builtin_native_object_type +); + +builtin_raw_pointer_types( //dir=type + unique int id: @builtin_raw_pointer_type +); + +builtin_raw_unsafe_continuation_types( //dir=type + unique int id: @builtin_raw_unsafe_continuation_type +); + +builtin_unsafe_value_buffer_types( //dir=type + unique int id: @builtin_unsafe_value_buffer_type +); + +builtin_vector_types( //dir=type + unique int id: @builtin_vector_type +); + +existential_metatype_types( //dir=type + unique int id: @existential_metatype_type +); + +function_types( //dir=type + unique int id: @function_type +); + +generic_function_types( //dir=type + unique int id: @generic_function_type +); + +#keyset[id, index] +generic_function_type_generic_params( //dir=type + int id: @generic_function_type ref, + int index: int ref, + int generic_param: @generic_type_param_type_or_none ref +); + +generic_type_param_types( //dir=type + unique int id: @generic_type_param_type +); + +metatype_types( //dir=type + unique int id: @metatype_type +); + +@nominal_or_bound_generic_nominal_type = + @bound_generic_type +| @nominal_type +; + +paren_types( //dir=type + unique int id: @paren_type, + int type_: @type_or_none ref +); + +@syntax_sugar_type = + @dictionary_type +| @unary_syntax_sugar_type +; + +type_alias_types( //dir=type + unique int id: @type_alias_type, + int decl: @type_alias_decl_or_none ref +); + +unbound_generic_types( //dir=type + unique int id: @unbound_generic_type +); + +unmanaged_storage_types( //dir=type + unique int id: @unmanaged_storage_type +); + +unowned_storage_types( //dir=type + unique int id: @unowned_storage_type +); + +weak_storage_types( //dir=type + unique int id: @weak_storage_type +); + +@bound_generic_type = + @bound_generic_class_type +| @bound_generic_enum_type +| @bound_generic_struct_type +; + +#keyset[id, index] +bound_generic_type_arg_types( //dir=type + int id: @bound_generic_type ref, + int index: int ref, + int arg_type: @type_or_none ref +); + +builtin_integer_literal_types( //dir=type + unique int id: @builtin_integer_literal_type +); + +builtin_integer_types( //dir=type + unique int id: @builtin_integer_type +); + +#keyset[id] +builtin_integer_type_widths( //dir=type + int id: @builtin_integer_type ref, + int width: int ref +); + +dictionary_types( //dir=type + unique int id: @dictionary_type, + int key_type: @type_or_none ref, + int value_type: @type_or_none ref +); + +@nominal_type = + @class_type +| @enum_type +| @protocol_type +| @struct_type +; + +opaque_type_archetype_types( //dir=type + unique int id: @opaque_type_archetype_type, + int declaration: @opaque_type_decl_or_none ref +); + +opened_archetype_types( //dir=type + unique int id: @opened_archetype_type +); + +primary_archetype_types( //dir=type + unique int id: @primary_archetype_type +); + +@unary_syntax_sugar_type = + @array_slice_type +| @optional_type +| @variadic_sequence_type +; + +#keyset[id] +unary_syntax_sugar_types( //dir=type + int id: @unary_syntax_sugar_type ref, + int base_type: @type_or_none ref +); + +array_slice_types( //dir=type + unique int id: @array_slice_type +); + +bound_generic_class_types( //dir=type + unique int id: @bound_generic_class_type +); + +bound_generic_enum_types( //dir=type + unique int id: @bound_generic_enum_type +); + +bound_generic_struct_types( //dir=type + unique int id: @bound_generic_struct_type +); + +class_types( //dir=type + unique int id: @class_type +); + +enum_types( //dir=type + unique int id: @enum_type +); + +optional_types( //dir=type + unique int id: @optional_type +); + +protocol_types( //dir=type + unique int id: @protocol_type +); + +struct_types( //dir=type + unique int id: @struct_type +); + +variadic_sequence_types( //dir=type + unique int id: @variadic_sequence_type +); + +@accessor_or_none = + @accessor +| @unspecified_element +; + +@argument_or_none = + @argument +| @unspecified_element +; + +@associated_type_decl_or_none = + @associated_type_decl +| @unspecified_element +; + +@ast_node_or_none = + @ast_node +| @unspecified_element +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @unspecified_element +; + +@case_label_item_or_none = + @case_label_item +| @unspecified_element +; + +@case_stmt_or_none = + @case_stmt +| @unspecified_element +; + +@closure_expr_or_none = + @closure_expr +| @unspecified_element +; + +@condition_element_or_none = + @condition_element +| @unspecified_element +; + +@decl_or_none = + @decl +| @unspecified_element +; + +@enum_element_decl_or_none = + @enum_element_decl +| @unspecified_element +; + +@expr_or_none = + @expr +| @unspecified_element +; + +@file_or_none = + @file +| @unspecified_element +; + +@function_or_none = + @function +| @unspecified_element +; + +@generic_type_decl_or_none = + @generic_type_decl +| @unspecified_element +; + +@generic_type_param_decl_or_none = + @generic_type_param_decl +| @unspecified_element +; + +@generic_type_param_type_or_none = + @generic_type_param_type +| @unspecified_element +; + +@initializer_or_none = + @initializer +| @unspecified_element +; + +@key_path_component_or_none = + @key_path_component +| @unspecified_element +; + +@location_or_none = + @location +| @unspecified_element +; + +@module_decl_or_none = + @module_decl +| @unspecified_element +; + +@nominal_type_decl_or_none = + @nominal_type_decl +| @unspecified_element +; + +@opaque_type_decl_or_none = + @opaque_type_decl +| @unspecified_element +; + +@opaque_value_expr_or_none = + @opaque_value_expr +| @unspecified_element +; + +@param_decl_or_none = + @param_decl +| @unspecified_element +; + +@pattern_or_none = + @pattern +| @unspecified_element +; + +@pattern_binding_decl_or_none = + @pattern_binding_decl +| @unspecified_element +; + +@precedence_group_decl_or_none = + @precedence_group_decl +| @unspecified_element +; + +@protocol_decl_or_none = + @protocol_decl +| @unspecified_element +; + +@protocol_type_or_none = + @protocol_type +| @unspecified_element +; + +@stmt_or_none = + @stmt +| @unspecified_element +; + +@stmt_condition_or_none = + @stmt_condition +| @unspecified_element +; + +@string_literal_expr_or_none = + @string_literal_expr +| @unspecified_element +; + +@tap_expr_or_none = + @tap_expr +| @unspecified_element +; + +@type_or_none = + @type +| @unspecified_element +; + +@type_alias_decl_or_none = + @type_alias_decl +| @unspecified_element +; + +@type_repr_or_none = + @type_repr +| @unspecified_element +; + +@value_decl_or_none = + @unspecified_element +| @value_decl +; + +@var_decl_or_none = + @unspecified_element +| @var_decl +; diff --git a/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties b/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties new file mode 100644 index 00000000000..2a5e31eda2f --- /dev/null +++ b/swift/ql/lib/upgrades/44e36e15e90bc1535964d9b86b3cd06a8b0d26e3/upgrade.properties @@ -0,0 +1,2 @@ +description: New entities added +compatibility: full From 3ff6d033d3def3e8781e8cd09bb2b471de580c1d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 15:25:49 +0100 Subject: [PATCH 573/739] Rename to `neverSkipInPathGraph` --- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 2 +- .../semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll | 5 +++-- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 2 +- .../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 5 +++-- .../semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 2 +- .../semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll | 5 +++-- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 5 +++-- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 2 +- .../semmle/code/java/dataflow/internal/DataFlowPrivate.qll | 5 +++-- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll | 2 +- .../semmle/python/dataflow/new/internal/DataFlowPrivate.qll | 5 +++-- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll | 2 +- .../ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll | 5 +++-- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll | 2 +- .../lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll | 5 +++-- 16 files changed, 32 insertions(+), 24 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 41341c6be5c..284fff191ae 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -2022,7 +2022,7 @@ module Impl<FullStateConfigSig Config> { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or expectsContentCached(this.asNode(), _) or - flowCheckNodeSpecific(this.asNode()) + neverSkipInPathGraph(this.asNode()) } } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index 9b7b92f6fb8..b380748fb3c 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -236,9 +236,10 @@ class CastNode extends Node { } /** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + * Holds if `n` should never be skipped over in the `PathGraph` and in path + * explanations. */ -predicate flowCheckNodeSpecific(Node n) { none() } +predicate neverSkipInPathGraph(Node n) { none() } class DataFlowCallable = Function; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 41341c6be5c..284fff191ae 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -2022,7 +2022,7 @@ module Impl<FullStateConfigSig Config> { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or expectsContentCached(this.asNode(), _) or - flowCheckNodeSpecific(this.asNode()) + neverSkipInPathGraph(this.asNode()) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index dfd8fcbaccf..ef006bbff0a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -784,9 +784,10 @@ class CastNode extends Node { } /** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + * Holds if `n` should never be skipped over in the `PathGraph` and in path + * explanations. */ -predicate flowCheckNodeSpecific(Node n) { none() } +predicate neverSkipInPathGraph(Node n) { none() } /** * A function that may contain code or a variable that may contain itself. When diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 41341c6be5c..284fff191ae 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -2022,7 +2022,7 @@ module Impl<FullStateConfigSig Config> { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or expectsContentCached(this.asNode(), _) or - flowCheckNodeSpecific(this.asNode()) + neverSkipInPathGraph(this.asNode()) } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 27d35568e09..c8287255f4f 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -2148,9 +2148,10 @@ class CastNode extends Node { } /** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + * Holds if `n` should never be skipped over in the `PathGraph` and in path + * explanations. */ -predicate flowCheckNodeSpecific(Node n) { none() } +predicate neverSkipInPathGraph(Node n) { none() } class DataFlowExpr = DotNet::Expr; diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 41341c6be5c..284fff191ae 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -2022,7 +2022,7 @@ module Impl<FullStateConfigSig Config> { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or expectsContentCached(this.asNode(), _) or - flowCheckNodeSpecific(this.asNode()) + neverSkipInPathGraph(this.asNode()) } } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index c014e89e397..277c92703e7 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -229,9 +229,10 @@ class CastNode extends ExprNode { } /** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + * Holds if `n` should never be skipped over in the `PathGraph` and in path + * explanations. */ -predicate flowCheckNodeSpecific(Node n) { none() } +predicate neverSkipInPathGraph(Node n) { none() } class DataFlowExpr = Expr; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 41341c6be5c..284fff191ae 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -2022,7 +2022,7 @@ module Impl<FullStateConfigSig Config> { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or expectsContentCached(this.asNode(), _) or - flowCheckNodeSpecific(this.asNode()) + neverSkipInPathGraph(this.asNode()) } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index eabfa3ecfc5..216523023d9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -243,9 +243,10 @@ class CastNode extends ExprNode { } /** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + * Holds if `n` should never be skipped over in the `PathGraph` and in path + * explanations. */ -predicate flowCheckNodeSpecific(Node n) { none() } +predicate neverSkipInPathGraph(Node n) { none() } private newtype TDataFlowCallable = TSrcCallable(Callable c) or diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 41341c6be5c..284fff191ae 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -2022,7 +2022,7 @@ module Impl<FullStateConfigSig Config> { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or expectsContentCached(this.asNode(), _) or - flowCheckNodeSpecific(this.asNode()) + neverSkipInPathGraph(this.asNode()) } } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 8df16662e07..29504b6aa38 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -490,9 +490,10 @@ class CastNode extends Node { } /** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + * Holds if `n` should never be skipped over in the `PathGraph` and in path + * explanations. */ -predicate flowCheckNodeSpecific(Node n) { +predicate neverSkipInPathGraph(Node n) { // We include read- and store steps here to force them to be // shown in path explanations. // This hack is necessary, because we have included some of these diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 41341c6be5c..284fff191ae 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -2022,7 +2022,7 @@ module Impl<FullStateConfigSig Config> { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or expectsContentCached(this.asNode(), _) or - flowCheckNodeSpecific(this.asNode()) + neverSkipInPathGraph(this.asNode()) } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 6cabe899d5a..f8469e99a23 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1294,9 +1294,10 @@ class CastNode extends Node { } /** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + * Holds if `n` should never be skipped over in the `PathGraph` and in path + * explanations. */ -predicate flowCheckNodeSpecific(Node n) { +predicate neverSkipInPathGraph(Node n) { // ensure that all variable assignments are included in the path graph n.(SsaDefinitionExtNode).getDefinitionExt() instanceof Ssa::WriteDefinition } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 41341c6be5c..284fff191ae 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -2022,7 +2022,7 @@ module Impl<FullStateConfigSig Config> { castNode(this.asNode()) or clearsContentCached(this.asNode(), _) or expectsContentCached(this.asNode(), _) or - flowCheckNodeSpecific(this.asNode()) + neverSkipInPathGraph(this.asNode()) } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index b18f38cbb65..c0f01a67df3 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -850,9 +850,10 @@ class CastNode extends Node { } /** - * Holds if `n` should be a FlowCheckNode, which will appear in path summaries. + * Holds if `n` should never be skipped over in the `PathGraph` and in path + * explanations. */ -predicate flowCheckNodeSpecific(Node n) { none() } +predicate neverSkipInPathGraph(Node n) { none() } class DataFlowExpr = Expr; From 74b39b42a181600c6f1f5f9dcb30535db4787856 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 15:47:25 +0100 Subject: [PATCH 574/739] Accept test changes --- .../semmle/go/dataflow/ExternalFlow/sinks.expected | 10 +++++++--- .../semmle/go/dataflow/ExternalFlow/srcs.expected | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/sinks.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/sinks.expected index 21199db73df..38dc380b55b 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/sinks.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/sinks.expected @@ -26,6 +26,10 @@ invalidModelRow | test.go:133:10:133:17 | call to Get | qltest | | test.go:137:10:137:17 | call to Get | qltest | | test.go:142:10:142:17 | call to Get | qltest | -| test.go:148:17:148:20 | arg1 | qltest | -| test.go:148:23:148:26 | arg2 | qltest | -| test.go:148:29:148:32 | arg3 | qltest | +| test.go:146:10:146:14 | selection of F | qltest | +| test.go:149:10:149:32 | call to GetThroughPointer | qltest | +| test.go:153:10:153:32 | call to GetThroughPointer | qltest | +| test.go:158:10:158:32 | call to GetThroughPointer | qltest | +| test.go:164:17:164:20 | arg1 | qltest | +| test.go:164:23:164:26 | arg2 | qltest | +| test.go:164:29:164:32 | arg3 | qltest | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/srcs.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/srcs.expected index 7b721110c67..2f1e3256778 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/srcs.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/srcs.expected @@ -17,3 +17,7 @@ invalidModelRow | test.go:132:15:132:22 | call to Src1 | qltest | | test.go:136:9:136:16 | call to Src1 | qltest | | test.go:140:9:140:16 | call to Src1 | qltest | +| test.go:145:24:145:31 | call to Src1 | qltest | +| test.go:148:17:148:24 | call to Src1 | qltest | +| test.go:152:24:152:31 | call to Src1 | qltest | +| test.go:156:24:156:31 | call to Src1 | qltest | From afb7070fd3d2192d38242fc70bd1810f6d29a6b3 Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Wed, 14 Jun 2023 15:41:30 +0100 Subject: [PATCH 575/739] Swift: Don't use `std::hash<fs::path>`. --- .../extractor/infra/SwiftLocationExtractor.h | 2 +- swift/extractor/infra/file/BUILD.bazel | 21 +------------------ swift/extractor/infra/file/PathHash.h | 11 ++++++++++ swift/extractor/infra/file/PathHash.h.fixed | 4 ---- .../infra/file/PathHash.h.workaround | 17 --------------- .../remapping/SwiftFileInterception.cpp | 3 +-- 6 files changed, 14 insertions(+), 44 deletions(-) create mode 100644 swift/extractor/infra/file/PathHash.h delete mode 100644 swift/extractor/infra/file/PathHash.h.fixed delete mode 100644 swift/extractor/infra/file/PathHash.h.workaround diff --git a/swift/extractor/infra/SwiftLocationExtractor.h b/swift/extractor/infra/SwiftLocationExtractor.h index 2dba1c31b96..40b0ade944c 100644 --- a/swift/extractor/infra/SwiftLocationExtractor.h +++ b/swift/extractor/infra/SwiftLocationExtractor.h @@ -104,7 +104,7 @@ class SwiftLocationExtractor { private: TrapLabel<FileTag> fetchFileLabel(const std::filesystem::path& file); TrapDomain& trap; - std::unordered_map<std::filesystem::path, TrapLabel<FileTag>> store; + std::unordered_map<std::filesystem::path, TrapLabel<FileTag>, codeql::PathHash> store; }; template <typename Locatable> diff --git a/swift/extractor/infra/file/BUILD.bazel b/swift/extractor/infra/file/BUILD.bazel index d14a28ce622..51b34a1e6d9 100644 --- a/swift/extractor/infra/file/BUILD.bazel +++ b/swift/extractor/infra/file/BUILD.bazel @@ -9,26 +9,7 @@ swift_cc_library( hdrs = glob( ["*.h"], exclude = ["FsLogger.h"], - ) + [":path_hash_workaround"], + ), visibility = ["//swift:__subpackages__"], deps = ["//swift/logging"], ) - -genrule( - name = "path_hash_workaround", - srcs = [ - "PathHash.h.workaround", - "PathHash.h.fixed", - ], - outs = ["PathHash.h"], - # see if https://cplusplus.github.io/LWG/issue3657 is fixed with the current compiler or not - # if fixed, PathHash.h.workaround will not compile - cmd = "\n".join([ - "if clang -c -x c++ -std=c++20 -Wno-pragma-once-outside-header \\", - " $(rootpath PathHash.h.workaround) -o /dev/null &> /dev/null; then", - " cp $(rootpath PathHash.h.workaround) $@", - "else", - " cp $(rootpath PathHash.h.fixed) $@", - "fi", - ]), -) diff --git a/swift/extractor/infra/file/PathHash.h b/swift/extractor/infra/file/PathHash.h new file mode 100644 index 00000000000..3f9a21b06c6 --- /dev/null +++ b/swift/extractor/infra/file/PathHash.h @@ -0,0 +1,11 @@ +#pragma once + +#include <filesystem> + +namespace codeql { +struct PathHash { + auto operator()(const std::filesystem::path& path) const { + return std::filesystem::hash_value(path); + } +}; +} // namespace codeql diff --git a/swift/extractor/infra/file/PathHash.h.fixed b/swift/extractor/infra/file/PathHash.h.fixed deleted file mode 100644 index b4444fcc8e7..00000000000 --- a/swift/extractor/infra/file/PathHash.h.fixed +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -#include <filesystem> -#include <functional> diff --git a/swift/extractor/infra/file/PathHash.h.workaround b/swift/extractor/infra/file/PathHash.h.workaround deleted file mode 100644 index bdfffcb5dfe..00000000000 --- a/swift/extractor/infra/file/PathHash.h.workaround +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include <filesystem> -#include <functional> - -// workaround for https://cplusplus.github.io/LWG/issue3657 -// notice that theoretically by the standard you are not allowed to specialize on std types... -// but it works, and this is recognized as a defect of the standard. -// Using a non-standard Hasher type would be a huge pain, as the automatic hash implementation of -// std::variant would not kick in (we use std::filesystem::path in a variant used as a map key). -namespace std { -template <> -struct hash<filesystem::path> { - size_t operator()(const filesystem::path& path) const { return hash_value(path); } -}; - -} // namespace std diff --git a/swift/extractor/remapping/SwiftFileInterception.cpp b/swift/extractor/remapping/SwiftFileInterception.cpp index 7b22aabec8f..c83049bcbcc 100644 --- a/swift/extractor/remapping/SwiftFileInterception.cpp +++ b/swift/extractor/remapping/SwiftFileInterception.cpp @@ -114,7 +114,6 @@ class FileInterceptor { } int open(const char* path, int flags, mode_t mode = 0) const { - fs::path fsPath{path}; CODEQL_ASSERT((flags & O_ACCMODE) == O_RDONLY, "We should only be intercepting file reads"); // try to use the hash map first errno = 0; @@ -162,7 +161,7 @@ class FileInterceptor { }; std::optional<std::string> getHashOfRealFile(const fs::path& path) { - static std::unordered_map<fs::path, std::string> cache; + static std::unordered_map<fs::path, std::string, codeql::PathHash> cache; auto resolved = resolvePath(path); if (auto found = cache.find(resolved); found != cache.end()) { return found->second; From 0419b6e50546884f44e8dc6d917cb0dff2bf3b50 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Wed, 14 Jun 2023 17:45:58 +0100 Subject: [PATCH 576/739] Kotlin: Remove use of AccessControlException We were getting warnings about it being deprecated, and it was all dead code anyway. --- .../java/com/semmle/util/files/FileUtil.java | 215 ------------------ 1 file changed, 215 deletions(-) diff --git a/java/kotlin-extractor/src/main/java/com/semmle/util/files/FileUtil.java b/java/kotlin-extractor/src/main/java/com/semmle/util/files/FileUtil.java index 81a9f46a71f..79ce2d8d8d3 100644 --- a/java/kotlin-extractor/src/main/java/com/semmle/util/files/FileUtil.java +++ b/java/kotlin-extractor/src/main/java/com/semmle/util/files/FileUtil.java @@ -27,7 +27,6 @@ import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.AccessControlException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -279,47 +278,6 @@ public class FileUtil || path.charAt(2) == '\\')); } - /** - * Copies a file - * - * @return false if failed to copy. - */ - public static boolean copy (File from, File to) - { - boolean targetFileExisted = to.exists(); - try { - copyFile(from, to, false); - return true; - } - catch (IOException e) { - // If the target did not exist before, make sure - // we delete it if there was any error - if (!targetFileExisted) - to.delete(); - - logger.error("Cannot copy " + from + " to " + to, e); - return false; - } - } - - /** - * Append all of <code>sourceFile</code> to the end of <code>targetFile</code> - like - * <code>copy</code>, but just adds to the end of the file. - * - * @return <code>true</code> iff the append succeeded - */ - public static boolean append (File sourceFile, File targetFile) - { - try { - copyFile(sourceFile, targetFile, true); - return true; - } - catch (IOException e) { - logger.error("Cannot append contents of " + sourceFile + " to " + targetFile, e); - return false; - } - } - /** * Write the contents of the given string to the file, creating it if it does not exist and overwriting it if it does. * @@ -443,82 +401,6 @@ public class FileUtil } } - /** - * Copies a folder recursively, by overwriting files if necessary. Copies all folders but filters - * files. - * <p> - * <b>IMPORTANT:</b>The contents of <code>from</code> are copied to <code>to</code>, but a - * subdirectory is not created for them. This behaves like <code>rsync -a from/ to</code>. - * <p> - * If {@code from} is a file rather than a directory, it is copied (assuming the filter matches - * it) to the file named by {@code to} -- this must not already exist as a directory. - * - * @deprecated Use <code>FileUtil8.recursiveCopy</code> instead. - * @param from Directory whose contents should be copied, or a file. - * @param to Directory to which files and subdirectories of <code>from</code> should be copied, or - * a file path (if {@code from} is a file). - * @param filter the filter to use for selecting which files to copy, or <code>null</code> - * @return false if failed to copy. - */ - @Deprecated - public static boolean recursiveCopy (File from, File to, final FileFilter filter) - { - // Make sure we include all subfolders - FileFilter realFilter = new FileFilter() { - @Override - public boolean accept (File pathname) - { - if (filter == null || pathname.isDirectory()) - return true; - else - return filter == null || filter.accept(pathname); - } - }; - return strictRecursiveCopy(from, to, realFilter); - } - - /** - * Copies a folder recursively, by overwriting files if necessary. Unlike - * {@link #recursiveCopy(File, File, FileFilter)}, this version applies the filter to directories - * as well, and only recurses into directories that are accepted by the filter. - * <p> - * <b>IMPORTANT:</b>The contents of <code>from</code> are copied to <code>to</code>, but a - * subdirectory is not created for them. This behaves like <code>rsync -a from/ to</code>. - * <p> - * If {@code from} is a file rather than a directory, it is copied (assuming the filter matches - * it) to the file named by {@code to} -- this must not already exist as a directory. - * - * @deprecated Use <code>FileUtil8.recursiveCopy</code> instead. - * @param from Directory whose contents should be copied, or a file. - * @param to Directory to which files and subdirectories of <code>from</code> should be copied, or - * a file path (if {@code from} is a file). - * @param filter the filter to use for selecting which files to copy, or <code>null</code> - * @return false if failed to copy. - */ - @Deprecated - public static boolean strictRecursiveCopy (File from, File to, FileFilter filter) - { - if (!from.exists()) { - return false; - } - if (from.isFile()) { - return copy(from, to); - } - else { - if (!to.exists()) { - if (!to.mkdir()) { - return false; - } - } - boolean success = true; - for (File childFrom : list(from, filter)) { - File childTo = new File(to, childFrom.getName()); - success &= strictRecursiveCopy(childFrom, childTo, filter); - } - return success; - } - } - /** * Writes the entire contents of a stream to a file. Closes input stream when writing is done * @@ -589,62 +471,6 @@ public class FileUtil } } - private static void copyFile (File from, File to, boolean append) throws IOException - { - // Try to exclude the case where the files are the same. If that happens, - // succeed except in 'append' mode since that is probably not the intention - // The logic below works if from and to both exist - and if one of them - // doesn't they can't be the same file! - from = tryMakeCanonical(from); - to = tryMakeCanonical(to); - if (from.equals(to)) { - if (append) - throw new IOException("Trying to append the contents of file " + from + " onto itself"); - else - return; // Nothing to do. - } - - try (FileInputStream fis = new FileInputStream(from); - InputStream in = new BufferedInputStream(fis)) - { - if (!to.exists()) - to.createNewFile(); - try (FileOutputStream fos = new FileOutputStream(to, append); - OutputStream out = new BufferedOutputStream(fos)) - { - byte[] buf = new byte[16 * 1024]; - int count; - while ((count = in.read(buf)) > 0) - out.write(buf, 0, count); - } - } - to.setExecutable(canExecute(from)); - } - - /** - * In the current Java security model, calling {@link File#canExecute()} requires the same - * permission as calling {@link Runtime#exec(String)}. This makes it impossible to run under a - * restrictive security manager if we blindly check for a file's execute bit. - * <p> - * To work around, if an {@link AccessControlException} arises, and it seems to refer to a lack of - * {@link SecurityConstants#FILE_EXECUTE_ACTION} permission, we suppress the exception and return - * <code>false</code>. Other {@link AccessControlException}s are re-thrown, and otherwise the - * return value coincides with {@link File#canExecute()} on the argument. - */ - private static boolean canExecute (File file) - { - try { - return file.canExecute(); - } - catch (AccessControlException e) { - if (e.getPermission() instanceof FilePermission - && ((FilePermission) e.getPermission()).getActions().contains("execute")) - return false; // deliberately ignoring security failure - throw e; - } - } - - private static final BitSet allowedCharacters = new BitSet(256); static { for (int i = 'a'; i <= 'z'; i++) @@ -1633,22 +1459,6 @@ public class FileUtil } } - /** - * Copy the source properties file to the target, appending the given variable definitions as - * properties (with proper escaping). An optional marker string is printed as a comment before the - * extra variables, if any. - */ - public static void copyPropertiesFile ( - File source, - File target, - Set<Pair<String, String>> extraVariables, - String extraComment) - { - if (source.isFile()) - copy(source, target); - appendProperties(target, extraVariables, extraComment); - } - /** * Append the given set of properties to a specified file, taking care of proper escaping of * special characters. @@ -1904,31 +1714,6 @@ public class FileUtil + "'."); } - /** - * Copy a file, creating any directories as needed. If the destination file (or directory) - * exists, it is overwritten. - * - * @param src The file to be renamed. Must be non-null and must exist. - * @param dest The path to copy the file to. Must be non-null. Will be overwritten if it already exists. - */ - public static void forceCopy(File src, File dest) - { - final String errorPrefix = "FileUtil.forceCopy: "; - if (src == null) - throw new CatastrophicError(errorPrefix + "source File is null."); - if (dest == null) - throw new CatastrophicError(errorPrefix + "destination File is null."); - if (!src.exists()) - throw new ResourceError(errorPrefix + "source File '" + src.toString() + "' does not exist.", new FileNotFoundException(src.toString())); - - mkdirs(dest.getAbsoluteFile().getParentFile()); - if (dest.exists() && !recursiveDelete(dest)) - throw new ResourceError(errorPrefix + "Couldn't overwrite destination file '" + dest.toString() + "'."); - if (!copy(src, dest)) - throw new ResourceError(errorPrefix + "Couldn't copy file '" + src.toString() + "' to '" + dest.toString() - + "'."); - } - /** * Query whether a {@link File} is non-null, and represents an existing <b>file</b> that can be * read. From 2ae5dae474f821e20b9b036d0a158556d65756ae Mon Sep 17 00:00:00 2001 From: yoff <lerchedahl@gmail.com> Date: Wed, 14 Jun 2023 20:55:45 +0200 Subject: [PATCH 577/739] Apply suggestions from code review Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com> --- .../dataflow/new/internal/SummaryTypeTracker.qll | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll index d1a65e1c3e5..9ecc1b5ea1d 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll @@ -16,7 +16,8 @@ signature module Input { // Relating content and filters /** - * Gets a content filter to use for a `WithoutContent[content]` step, or has no result if + * Gets a content filter to use for a `WithoutContent[content]` step, (data is not allowed to be stored in `content`) + * or has no result if * the step should be treated as ordinary flow. * * `WithoutContent` is often used to perform strong updates on individual collection elements, but for @@ -26,7 +27,8 @@ signature module Input { TypeTrackerContentFilter getFilterFromWithoutContentStep(TypeTrackerContent content); /** - * Gets a content filter to use for a `WithContent[content]` step, or has no result if + * Gets a content filter to use for a `WithContent[content]` step, (data must be stored in `content`) + * or has no result if * the step cannot be handled by type-tracking. * * `WithContent` is often used to perform strong updates on individual collection elements (or rather @@ -57,10 +59,10 @@ signature module Input { /** Gets a summary component for content `c`. */ SummaryComponent content(TypeTrackerContent contents); - /** Gets a summary component where data is not allowed to be stored in `c`. */ + /** Gets a summary component where data is not allowed to be stored in `contents`. */ SummaryComponent withoutContent(TypeTrackerContent contents); - /** Gets a summary component where data must be stored in `c`. */ + /** Gets a summary component where data must be stored in `contents`. */ SummaryComponent withContent(TypeTrackerContent contents); // Callables From af72509ce6bd61462cde7f3fd1b24b154f8f3bcd Mon Sep 17 00:00:00 2001 From: yoff <lerchedahl@gmail.com> Date: Wed, 14 Jun 2023 20:57:14 +0200 Subject: [PATCH 578/739] Update python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com> --- .../new/internal/TypeTrackerSpecific.qll | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index 6acc4036c16..48881d37285 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -200,24 +200,18 @@ private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { class SummaryComponentStack = FlowSummary::SummaryComponentStack; - SummaryComponentStack singleton(SummaryComponent component) { - result = FlowSummary::SummaryComponentStack::singleton(component) - } + predicate singleton = FlowSummary::SummaryComponentStack::singleton/1; - SummaryComponentStack push(SummaryComponent component, SummaryComponentStack stack) { - result = FlowSummary::SummaryComponentStack::push(component, stack) - } + predicate push = FlowSummary::SummaryComponentStack::push/2; // Relating content to summaries - SummaryComponent content(TypeTrackerContent contents) { - result = FlowSummary::SummaryComponent::content(contents) - } + predicate content = FlowSummary::SummaryComponent::content/1; - SummaryComponent withoutContent(TypeTrackerContent contents) { none() } + predicate withoutContent = FlowSummary::SummaryComponent::withoutContent/1; - SummaryComponent withContent(TypeTrackerContent contents) { none() } + predicate withContent = FlowSummary::SummaryComponent::withContent/1; - SummaryComponent return() { result = FlowSummary::SummaryComponent::return() } + predicate return = FlowSummary::SummaryComponent::return/0; // Relating nodes to summaries Node argumentOf(Node call, SummaryComponent arg) { From 0e713e6fc10f57ce13ab49c8ae5738347527180d Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 14 Jun 2023 21:02:42 +0200 Subject: [PATCH 579/739] ruby/python: more consistent naming of parameters --- .../dataflow/new/internal/SummaryTypeTracker.qll | 2 +- .../typetracking/internal/SummaryTypeTracker.qll | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll index 9ecc1b5ea1d..9c6f841651d 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll @@ -50,7 +50,7 @@ signature module Input { /** * Gets the stack obtained by pushing `head` onto `tail`. */ - SummaryComponentStack push(SummaryComponent component, SummaryComponentStack stack); + SummaryComponentStack push(SummaryComponent head, SummaryComponentStack tail); /** Gets a singleton stack representing a return. */ SummaryComponent return(); diff --git a/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll index d1a65e1c3e5..9c6f841651d 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll @@ -16,7 +16,8 @@ signature module Input { // Relating content and filters /** - * Gets a content filter to use for a `WithoutContent[content]` step, or has no result if + * Gets a content filter to use for a `WithoutContent[content]` step, (data is not allowed to be stored in `content`) + * or has no result if * the step should be treated as ordinary flow. * * `WithoutContent` is often used to perform strong updates on individual collection elements, but for @@ -26,7 +27,8 @@ signature module Input { TypeTrackerContentFilter getFilterFromWithoutContentStep(TypeTrackerContent content); /** - * Gets a content filter to use for a `WithContent[content]` step, or has no result if + * Gets a content filter to use for a `WithContent[content]` step, (data must be stored in `content`) + * or has no result if * the step cannot be handled by type-tracking. * * `WithContent` is often used to perform strong updates on individual collection elements (or rather @@ -48,7 +50,7 @@ signature module Input { /** * Gets the stack obtained by pushing `head` onto `tail`. */ - SummaryComponentStack push(SummaryComponent component, SummaryComponentStack stack); + SummaryComponentStack push(SummaryComponent head, SummaryComponentStack tail); /** Gets a singleton stack representing a return. */ SummaryComponent return(); @@ -57,10 +59,10 @@ signature module Input { /** Gets a summary component for content `c`. */ SummaryComponent content(TypeTrackerContent contents); - /** Gets a summary component where data is not allowed to be stored in `c`. */ + /** Gets a summary component where data is not allowed to be stored in `contents`. */ SummaryComponent withoutContent(TypeTrackerContent contents); - /** Gets a summary component where data must be stored in `c`. */ + /** Gets a summary component where data must be stored in `contents`. */ SummaryComponent withContent(TypeTrackerContent contents); // Callables From 6521a51d93e6cf034e8727e281e10191928f8124 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 14 Jun 2023 21:14:50 +0200 Subject: [PATCH 580/739] python: unique strings in tests --- .../dataflow/summaries/TestSummaries.qll | 2 +- .../typetracking-summaries/TestSummaries.qll | 18 +++++++++--------- .../typetracking-summaries/summaries.py | 3 ++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/python/ql/test/experimental/dataflow/summaries/TestSummaries.qll b/python/ql/test/experimental/dataflow/summaries/TestSummaries.qll index 971a653c469..cdd61420bbb 100644 --- a/python/ql/test/experimental/dataflow/summaries/TestSummaries.qll +++ b/python/ql/test/experimental/dataflow/summaries/TestSummaries.qll @@ -60,7 +60,7 @@ private class SummarizedCallableApplyLambda extends SummarizedCallable { } private class SummarizedCallableReversed extends SummarizedCallable { - SummarizedCallableReversed() { this = "reversed" } + SummarizedCallableReversed() { this = "list_reversed" } override DataFlow::CallCfgNode getACall() { result.getFunction().asCfgNode().(NameNode).getId() = this diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll b/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll index c139308c00e..8d626b332a3 100644 --- a/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/TestSummaries.qll @@ -11,7 +11,7 @@ module RecursionGuard { private import semmle.python.dataflow.new.internal.TypeTrackerSpecific as TT private class RecursionGuard extends SummarizedCallable { - RecursionGuard() { this = "RecursionGuard" } + RecursionGuard() { this = "TypeTrackingSummariesRecursionGuard" } override DataFlow::CallCfgNode getACall() { result.getFunction().asCfgNode().(NameNode).getId() = this and @@ -29,7 +29,7 @@ module RecursionGuard { } private class SummarizedCallableIdentity extends SummarizedCallable { - SummarizedCallableIdentity() { this = "identity" } + SummarizedCallableIdentity() { this = "TTS_identity" } override DataFlow::CallCfgNode getACall() { none() } @@ -48,7 +48,7 @@ private class SummarizedCallableIdentity extends SummarizedCallable { // For lambda flow to work, implement lambdaCall and lambdaCreation private class SummarizedCallableApplyLambda extends SummarizedCallable { - SummarizedCallableApplyLambda() { this = "apply_lambda" } + SummarizedCallableApplyLambda() { this = "TTS_apply_lambda" } override DataFlow::CallCfgNode getACall() { none() } @@ -70,7 +70,7 @@ private class SummarizedCallableApplyLambda extends SummarizedCallable { } private class SummarizedCallableReversed extends SummarizedCallable { - SummarizedCallableReversed() { this = "reversed" } + SummarizedCallableReversed() { this = "TTS_reversed" } override DataFlow::CallCfgNode getACall() { none() } @@ -88,7 +88,7 @@ private class SummarizedCallableReversed extends SummarizedCallable { } private class SummarizedCallableMap extends SummarizedCallable { - SummarizedCallableMap() { this = "list_map" } + SummarizedCallableMap() { this = "TTS_list_map" } override DataFlow::CallCfgNode getACall() { none() } @@ -110,7 +110,7 @@ private class SummarizedCallableMap extends SummarizedCallable { } private class SummarizedCallableAppend extends SummarizedCallable { - SummarizedCallableAppend() { this = "append_to_list" } + SummarizedCallableAppend() { this = "TTS_append_to_list" } override DataFlow::CallCfgNode getACall() { none() } @@ -132,7 +132,7 @@ private class SummarizedCallableAppend extends SummarizedCallable { } private class SummarizedCallableJsonLoads extends SummarizedCallable { - SummarizedCallableJsonLoads() { this = "json.loads" } + SummarizedCallableJsonLoads() { this = "TTS_json.loads" } override DataFlow::CallCfgNode getACall() { result = API::moduleImport("json").getMember("loads").getACall() @@ -153,7 +153,7 @@ private class SummarizedCallableJsonLoads extends SummarizedCallable { // read and store private class SummarizedCallableReadSecret extends SummarizedCallable { - SummarizedCallableReadSecret() { this = "read_secret" } + SummarizedCallableReadSecret() { this = "TTS_read_secret" } override DataFlow::CallCfgNode getACall() { none() } @@ -171,7 +171,7 @@ private class SummarizedCallableReadSecret extends SummarizedCallable { } private class SummarizedCallableSetSecret extends SummarizedCallable { - SummarizedCallableSetSecret() { this = "set_secret" } + SummarizedCallableSetSecret() { this = "TTS_set_secret" } override DataFlow::CallCfgNode getACall() { none() } diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py index 728456cc711..d4195787185 100644 --- a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py @@ -46,6 +46,7 @@ another_tainted_list = append_to_list([], tracked) # $ tracked atl = another_tainted_list[0] atl # $ MISSING: tracked +# This will not work, as the call is not found by `getACallSimple`. from json import loads as json_loads tainted_resultlist = json_loads(tracked) # $ tracked tr = tainted_resultlist[0] @@ -57,4 +58,4 @@ r # $ tracked y # $ tracked=secret set_secret(y, tracked) # $ tracked tracked=secret -y.secret # $ tracked tracked=secret \ No newline at end of file +y.secret # $ tracked tracked=secret From 2491fda58e7a014ed41f383955e8f0b232ba3b17 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 14 Jun 2023 21:16:39 +0200 Subject: [PATCH 581/739] python: update comment --- .../semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index 48881d37285..823e26688da 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -243,7 +243,7 @@ private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { Node returnOf(Node callable, SummaryComponent return) { return = FlowSummary::SummaryComponent::return() and - // result should be return value of callable which should be a lambda + // `result` should be the return value of a callable expresion (lambda or function) referenced by `callable` result.asCfgNode() = callable.getALocalSource().asExpr().(CallableExpr).getInnerScope().getAReturnValueFlowNode() } From 0267b329040171f11255231f6d36bc1ed257cb62 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 14 Jun 2023 21:17:12 +0200 Subject: [PATCH 582/739] fix eol --- config/identical-files.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/identical-files.json b/config/identical-files.json index 39dadd75ab3..ceed02ba5d6 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -603,4 +603,4 @@ "python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll", "java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll" ] -} \ No newline at end of file +} From 4fded84a49cbc07d69d5c8659a96fb25dc6c07bd Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 14 Jun 2023 21:30:58 +0200 Subject: [PATCH 583/739] python: implement missing predicates --- .../python/dataflow/new/internal/TypeTrackerSpecific.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index 823e26688da..8817cdf21ce 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -207,9 +207,9 @@ private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { // Relating content to summaries predicate content = FlowSummary::SummaryComponent::content/1; - predicate withoutContent = FlowSummary::SummaryComponent::withoutContent/1; + SummaryComponent withoutContent(TypeTrackerContent contents) { none() } - predicate withContent = FlowSummary::SummaryComponent::withContent/1; + SummaryComponent withContent(TypeTrackerContent contents) { none() } predicate return = FlowSummary::SummaryComponent::return/0; From b7bf750174f5494776799b63288c9a3cc6ad979b Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Wed, 14 Jun 2023 22:23:21 +0200 Subject: [PATCH 584/739] python: use updated names in test --- .../typetracking-summaries/summaries.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py index d4195787185..5801b8e7961 100644 --- a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py @@ -2,25 +2,25 @@ import sys import os # Simple summary -tainted = identity(tracked) # $ tracked +tainted = TTS_identity(tracked) # $ tracked tainted # $ tracked # Lambda summary # I think the missing result is expected because type tracking # is not allowed to flow back out of a call. -tainted_lambda = apply_lambda(lambda x: x, tracked) # $ tracked +tainted_lambda = TTS_apply_lambda(lambda x: x, tracked) # $ tracked tainted_lambda # $ MISSING: tracked # A lambda that directly introduces taint -bad_lambda = apply_lambda(lambda x: tracked, 1) # $ tracked +bad_lambda = TTS_apply_lambda(lambda x: tracked, 1) # $ tracked bad_lambda # $ tracked # A lambda that breaks the flow -untainted_lambda = apply_lambda(lambda x: 1, tracked) # $ tracked +untainted_lambda = TTS_apply_lambda(lambda x: 1, tracked) # $ tracked untainted_lambda # Collection summaries -tainted_list = reversed([tracked]) # $ tracked +tainted_list = TTS_reversed([tracked]) # $ tracked tl = tainted_list[0] tl # $ MISSING: tracked @@ -28,21 +28,21 @@ tl # $ MISSING: tracked def add_colon(x): return x + ":" -tainted_mapped = list_map(add_colon, [tracked]) # $ tracked +tainted_mapped = TTS_list_map(add_colon, [tracked]) # $ tracked tm = tainted_mapped[0] tm # $ MISSING: tracked def explicit_identity(x): return x -tainted_mapped_explicit = list_map(explicit_identity, [tracked]) # $ tracked +tainted_mapped_explicit = TTS_list_map(explicit_identity, [tracked]) # $ tracked tainted_mapped_explicit[0] # $ MISSING: tracked -tainted_mapped_summary = list_map(identity, [tracked]) # $ tracked +tainted_mapped_summary = TTS_list_map(identity, [tracked]) # $ tracked tms = tainted_mapped_summary[0] tms # $ MISSING: tracked -another_tainted_list = append_to_list([], tracked) # $ tracked +another_tainted_list = TTS_append_to_list([], tracked) # $ tracked atl = another_tainted_list[0] atl # $ MISSING: tracked @@ -53,9 +53,9 @@ tr = tainted_resultlist[0] tr # $ MISSING: tracked x.secret = tracked # $ tracked=secret tracked -r = read_secret(x) # $ tracked=secret tracked +r = TTS_read_secret(x) # $ tracked=secret tracked r # $ tracked y # $ tracked=secret -set_secret(y, tracked) # $ tracked tracked=secret +TTS_set_secret(y, tracked) # $ tracked tracked=secret y.secret # $ tracked tracked=secret From e6160b8e496aafb61a519453ca8d2e777ddee538 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 00:18:04 +0000 Subject: [PATCH 585/739] Add changed framework coverage reports --- .../library-coverage/coverage.csv | 2 +- .../library-coverage/coverage.rst | 4 +- .../library-coverage/coverage.csv | 354 +++++++++--------- .../library-coverage/coverage.rst | 4 +- 4 files changed, 185 insertions(+), 179 deletions(-) diff --git a/csharp/documentation/library-coverage/coverage.csv b/csharp/documentation/library-coverage/coverage.csv index a4a6a534105..be4c929650c 100644 --- a/csharp/documentation/library-coverage/coverage.csv +++ b/csharp/documentation/library-coverage/coverage.csv @@ -24,5 +24,5 @@ Microsoft.Win32,,,8,,,,,,,,,,,,,,8, MySql.Data.MySqlClient,48,,,,,,,,,,,48,,,,,, Newtonsoft.Json,,,91,,,,,,,,,,,,,,73,18 ServiceStack,194,,7,27,,,,,75,,,92,,,,,7, -System,65,25,12157,,8,8,9,,,4,3,33,1,17,3,4,10163,1994 +System,65,25,12148,,8,8,9,,,4,3,33,1,17,3,4,10163,1985 Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,, diff --git a/csharp/documentation/library-coverage/coverage.rst b/csharp/documentation/library-coverage/coverage.rst index 163638d895f..8f5b7ee0a8c 100644 --- a/csharp/documentation/library-coverage/coverage.rst +++ b/csharp/documentation/library-coverage/coverage.rst @@ -8,7 +8,7 @@ C# framework & library support Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting` `ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194, - System,"``System.*``, ``System``",25,12157,65,7 + System,"``System.*``, ``System``",25,12148,65,7 Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``Windows.Security.Cryptography.Core``",,568,138, - Totals,,25,12732,397,7 + Totals,,25,12723,397,7 diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 447797aff24..abe364cb2b8 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -1,174 +1,180 @@ -package,sink,source,summary,sink:bean-validation,sink:file-content-store,sink:fragment-injection,sink:groovy-injection,sink:hostname-verification,sink:html-injection,sink:information-leak,sink:intent-redirection,sink:jexl-injection,sink:jndi-injection,sink:js-injection,sink:ldap-injection,sink:log-injection,sink:mvel-injection,sink:ognl-injection,sink:path-injection,sink:pending-intents,sink:regex-use,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:request-forgery,sink:response-splitting,sink:sql-injection,sink:template-injection,sink:url-redirection,sink:xpath-injection,sink:xslt-injection,source:android-external-storage-dir,source:contentprovider,source:remote,summary:taint,summary:value -android.app,35,,103,,,11,,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,18,85 -android.content,24,31,154,,,,,,,,16,,,,,,,,,,,,,,,,,,,8,,,,,4,27,,63,91 -android.database,59,,41,,,,,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,41, -android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 -android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,41,81 -android.support.v4.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -android.util,6,16,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,2,,,,,1,,,,,,,,,,,,,,,,,,,,,,,2,, -android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1, -androidx.core.app,6,,95,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,12,83 -androidx.fragment.app,11,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -androidx.slice,2,5,88,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,5,,27,61 -cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.alibaba.druid.sql,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,2,,6,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,6, -com.google.common.base,4,,87,,,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,63,24 -com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 -com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 -com.google.common.flogger,29,,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,, -com.google.common.io,8,,73,,1,,,,,,,,,,,,,,7,,,,,,,,,,,,,,,,,,,72,1 -com.google.gson,,,44,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30,14 -com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, -com.jcraft.jsch,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,1, -com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, -com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,, -com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, -com.thoughtworks.xstream,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -com.unboundid.ldap.sdk,17,,,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,, -com.zaxxer.hikari,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, -flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,, -freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,, -groovy.lang,26,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.text,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.util,5,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hudson,44,,16,,2,,,,,,,,,,,,,,36,,,,,,,,,6,,,,,,,,,,16, -io.jsonwebtoken,,2,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,4, -io.netty.bootstrap,3,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,,,, -io.netty.buffer,,,207,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,130,77 -io.netty.channel,9,2,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,2,, -io.netty.handler.codec,4,13,259,,,,,,,,,,,,,,,,1,,,,,,,,,3,,,,,,,,,13,143,116 -io.netty.handler.ssl,4,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,, -io.netty.handler.stream,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -io.netty.resolver,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -io.netty.util,2,,23,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,,,,,,,21,2 -jakarta.faces.context,2,7,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,, -jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,94,55 -java.awt,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3 -java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,49,,45,,22,,,,,,,,,,,,,,27,,,,,,,,,,,,,,,,,,,43,2 -java.lang,18,,92,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36 -java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20, -java.nio,47,,35,,3,,,,,,,,,,,,,,44,,,,,,,,,,,,,,,,,,,35, -java.sql,13,,2,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2, -java.util,44,,484,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440 -javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -javax.faces.context,2,7,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,, -javax.imageio.stream,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, -javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -javax.management.remote,2,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.naming,7,,1,,,,,,,,,,6,,1,,,,,,,,,,,,,,,,,,,,,,,1, -javax.net.ssl,2,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.script,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, -javax.servlet,5,21,2,,,,,,,1,,,,,,,,,1,,,,,,,,,,3,,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, -javax.ws.rs.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -javax.ws.rs.core,3,,149,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,2,,,,,,94,55 -javax.xml.transform,2,,6,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,1,,,,6, -javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,, -jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -kotlin,16,,1847,,,,,,,,,,,,,,,,14,,,,,,,,,2,,,,,,,,,,1836,11 -net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,, -ognl,6,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, -okhttp3,4,,48,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,23,25 -org.antlr.runtime,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.compress.archivers.tar,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4, -org.apache.commons.httpclient.util,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.commons.io,111,,560,,2,,,,,,,,,,,,,,94,,,,,,,,,15,,,,,,,,,,546,14 -org.apache.commons.jelly,6,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, -org.apache.commons.jexl2,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl3,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,293,131 -org.apache.commons.logging,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.net,9,12,,,,,,,,,,,,,,,,,3,,,,,,,,,6,,,,,,,,,12,, -org.apache.commons.ognl,6,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 -org.apache.directory.ldap.client.api,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hadoop.fs,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10, -org.apache.hadoop.hive.metastore,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,, -org.apache.hc.client5.http.async.methods,84,,,,,,,,,,,,,,,,,,,,,,,,,,,84,,,,,,,,,,, -org.apache.hc.client5.http.classic.methods,37,,,,,,,,,,,,,,,,,,,,,,,,,,,37,,,,,,,,,,, -org.apache.hc.client5.http.fluent,19,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,, -org.apache.hc.core5.benchmark,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.hc.core5.http,73,2,45,,,,,,1,,,,,,,,,,,,,,,,,,,72,,,,,,,,,2,45, -org.apache.hc.core5.net,,,18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18, -org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 -org.apache.hive.hcatalog.templeton,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,, -org.apache.http,48,3,94,,,,,,2,,,,,,,,,,,,,,,,,,,46,,,,,,,,,3,86,8 -org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,57, -org.apache.log4j,11,,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,, -org.apache.logging.log4j,359,,8,,,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,4,4 -org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.shiro.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.tools.ant,11,,,,,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,, -org.apache.tools.zip,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,, -org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,, -org.codehaus.cargo.container.installer,3,,,,,,,,,,,,,,,,,,2,,,,,,,,,1,,,,,,,,,,, -org.codehaus.groovy.control,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,, -org.eclipse.jetty.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -org.fusesource.leveldbjni,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -org.geogebra.web.full.main,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,, -org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,, -org.influxdb,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -org.jboss.logging,324,,,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,, -org.jdbi.v3.core,6,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, -org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,, -org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.kohsuke.stapler,3,,1,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,1,,,,,,1, -org.mvel2,16,,,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,, -org.openjdk.jmh.runner.options,1,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -org.scijava.log,13,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,, -org.slf4j,55,,6,,,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,2,4 -org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 -org.springframework.boot.jdbc,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 -org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -org.springframework.core.io,2,,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,,,,,,,, -org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -org.springframework.http,14,,71,,,,,,,,,,,,,,,,,,,,,,,,,14,,,,,,,,,,61,10 -org.springframework.jdbc.core,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,, -org.springframework.jdbc.datasource,4,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,, -org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,, -org.springframework.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.ldap,47,,,,,,,,,,,,33,,14,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, -org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 -org.springframework.util,3,,142,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,90,52 -org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, -org.springframework.web.client,13,3,,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, -org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, -org.springframework.web.util,,,165,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,140,25 -org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,2, -org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -org.yaml.snakeyaml,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -play.libs.ws,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, -play.mvc,,13,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,24, -ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 -ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -retrofit2,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +package,sink,source,summary,sink:bean-validation,sink:command-injection,sink:file-content-store,sink:fragment-injection,sink:groovy-injection,sink:hostname-verification,sink:html-injection,sink:information-leak,sink:intent-redirection,sink:jexl-injection,sink:jndi-injection,sink:js-injection,sink:ldap-injection,sink:log-injection,sink:mvel-injection,sink:ognl-injection,sink:path-injection,sink:pending-intents,sink:regex-use,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:request-forgery,sink:response-splitting,sink:sql-injection,sink:template-injection,sink:url-redirection,sink:xpath-injection,sink:xslt-injection,source:android-external-storage-dir,source:contentprovider,source:remote,summary:taint,summary:value +android.app,35,,103,,,,11,,,,,7,,,,,,,,,17,,,,,,,,,,,,,,,,,,18,85 +android.content,24,31,154,,,,,,,,,16,,,,,,,,,,,,,,,,,,,8,,,,,4,27,,63,91 +android.database,59,,41,,,,,,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,41, +android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 +android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,41,81 +android.support.v4.app,11,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +android.util,6,16,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,,2,,,,,1,,,,,,,,,,,,,,,,,,,,,,,2,, +android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1, +androidx.core.app,6,,95,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,12,83 +androidx.fragment.app,11,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +androidx.slice,2,5,88,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,5,,27,61 +antlr,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.alibaba.druid.sql,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,2,,6,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,6, +com.google.common.base,4,,87,,,,,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,63,24 +com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 +com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 +com.google.common.flogger,29,,,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,, +com.google.common.io,8,,73,,,1,,,,,,,,,,,,,,7,,,,,,,,,,,,,,,,,,,72,1 +com.google.gson,,,44,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30,14 +com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, +com.jcraft.jsch,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,1, +com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, +com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,, +com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, +com.thoughtworks.xstream,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +com.unboundid.ldap.sdk,17,,,,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,, +com.zaxxer.hikari,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, +flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,, +freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,, +groovy.lang,26,,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.text,1,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.util,5,,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hudson,68,4,2334,,4,3,,,,4,,,,,,,,,,51,,,,,,,,,6,,,,,,,,,4,2258,76 +io.jsonwebtoken,,2,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,4, +io.netty.bootstrap,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,,,, +io.netty.buffer,,,207,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,130,77 +io.netty.channel,9,2,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,2,, +io.netty.handler.codec,4,13,259,,,,,,,,,,,,,,,,,1,,,,,,,,,3,,,,,,,,,13,143,116 +io.netty.handler.ssl,4,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,,,,,,,,,, +io.netty.handler.stream,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +io.netty.resolver,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +io.netty.util,2,,23,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,,,,,,,21,2 +jakarta.faces.context,2,7,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,, +jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,94,55 +java.awt,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3 +java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +java.io,49,,45,,,22,,,,,,,,,,,,,,27,,,,,,,,,,,,,,,,,,,43,2 +java.lang,18,,92,,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36 +java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20, +java.nio,47,,35,,,3,,,,,,,,,,,,,,44,,,,,,,,,,,,,,,,,,,35, +java.sql,13,,2,,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2, +java.util,44,,484,,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440 +javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +javax.faces.context,2,7,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,, +javax.imageio.stream,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, +javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +javax.management.remote,2,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.naming,7,,1,,,,,,,,,,,6,,1,,,,,,,,,,,,,,,,,,,,,,,1, +javax.net.ssl,2,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.script,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, +javax.servlet,5,21,2,,,,,,,,1,,,,,,,,,1,,,,,,,,,,3,,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, +javax.ws.rs.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +javax.ws.rs.core,3,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,2,,,,,,94,55 +javax.xml.transform,2,,6,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,1,,,,6, +javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,, +jenkins,,,446,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,423,23 +jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 +kotlin,16,,1847,,,,,,,,,,,,,,,,,14,,,,,,,,,2,,,,,,,,,,1836,11 +net.sf.json,2,,338,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,321,17 +net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,, +ognl,6,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, +okhttp3,4,,48,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,23,25 +org.acegisecurity,,,49,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,49, +org.antlr.runtime,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.compress.archivers.tar,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4, +org.apache.commons.httpclient.util,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.commons.io,111,,560,,,2,,,,,,,,,,,,,,94,,,,,,,,,15,,,,,,,,,,546,14 +org.apache.commons.jelly,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, +org.apache.commons.jexl2,15,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.jexl3,15,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,293,131 +org.apache.commons.logging,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.net,9,12,,,,,,,,,,,,,,,,,,3,,,,,,,,,6,,,,,,,,,12,, +org.apache.commons.ognl,6,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 +org.apache.directory.ldap.client.api,1,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.hadoop.fs,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10, +org.apache.hadoop.hive.metastore,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,, +org.apache.hc.client5.http.async.methods,84,,,,,,,,,,,,,,,,,,,,,,,,,,,,84,,,,,,,,,,, +org.apache.hc.client5.http.classic.methods,37,,,,,,,,,,,,,,,,,,,,,,,,,,,,37,,,,,,,,,,, +org.apache.hc.client5.http.fluent,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,, +org.apache.hc.core5.benchmark,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.hc.core5.http,73,2,45,,,,,,,1,,,,,,,,,,,,,,,,,,,72,,,,,,,,,2,45, +org.apache.hc.core5.net,,,18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18, +org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 +org.apache.hive.hcatalog.templeton,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,, +org.apache.http,48,3,94,,,,,,,2,,,,,,,,,,,,,,,,,,,46,,,,,,,,,3,86,8 +org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,57, +org.apache.log4j,11,,,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,, +org.apache.logging.log4j,359,,8,,,,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,4,4 +org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.shiro.jndi,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.tools.ant,11,,,,,,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,, +org.apache.tools.zip,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,, +org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,, +org.codehaus.cargo.container.installer,3,,,,,,,,,,,,,,,,,,,2,,,,,,,,,1,,,,,,,,,,, +org.codehaus.groovy.control,1,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,, +org.eclipse.jetty.client,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.fusesource.leveldbjni,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +org.geogebra.web.full.main,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,, +org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,, +org.influxdb,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.jboss.logging,324,,,,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,, +org.jdbi.v3.core,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,, +org.jenkins.ui.icon,,,42,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41,1 +org.jenkins.ui.symbol,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,8 +org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,, +org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 +org.kohsuke.stapler,3,,343,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,1,,,,,,332,11 +org.mvel2,16,,,,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,, +org.openjdk.jmh.runner.options,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +org.scijava.log,13,,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,, +org.slf4j,55,,6,,,,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,2,4 +org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 +org.springframework.boot.jdbc,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, +org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 +org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.core.io,2,,,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,,,,,,,, +org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +org.springframework.http,14,,71,,,,,,,,,,,,,,,,,,,,,,,,,,14,,,,,,,,,,61,10 +org.springframework.jdbc.core,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,, +org.springframework.jdbc.datasource,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,, +org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,, +org.springframework.jndi,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.ldap,47,,,,,,,,,,,,,33,,14,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, +org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 +org.springframework.util,3,,142,,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,90,52 +org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, +org.springframework.web.client,13,3,,,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, +org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, +org.springframework.web.util,,,165,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,140,25 +org.thymeleaf,2,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,2, +org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +org.yaml.snakeyaml,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +play.libs.ws,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,, +play.mvc,,13,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,24, +ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 +ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +retrofit2,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 8464e0ca23e..ebcd040ceb8 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -22,6 +22,6 @@ Java framework & library support Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,115,4,,28,14,,35 - Others,"``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,899,528,66,,18,18,,195 - Totals,,255,9198,1997,263,10,122,33,1,385 + Others,"``antlr``, ``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",102,4467,554,81,4,18,18,,197 + Totals,,259,12766,2023,278,14,122,33,1,387 From 04736b6e1095d77f2001f9d0f98c3b1590d3b3d4 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 10:00:09 +0200 Subject: [PATCH 586/739] C#: Add lost QL Doc. --- .../code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index 3c0b6329f36..096f3b765f4 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -61,6 +61,7 @@ DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { ) } +/** Gets the return type of kind `rk` for callable `c`. */ DataFlowType getReturnType(DotNet::Callable c, ReturnKind rk) { exists(Type t | result = Gvn::getGlobalValueNumber(t) | rk instanceof NormalReturnKind and From 8fb3d838c95d6d4673a05eb8e3fdd16a48a95e5e Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 15 Jun 2023 10:03:31 +0200 Subject: [PATCH 587/739] C++: Add FP test case for `cpp/invalid-pointer-deref` --- .../InvalidPointerDeref.expected | 36 +++++++++++++++++++ .../CWE/CWE-193/pointer-deref/test.cpp | 11 ++++++ 2 files changed, 47 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 0d92ae6db5a..e176aa0a701 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -748,6 +748,30 @@ edges | test.cpp:381:5:381:9 | ... ++ | test.cpp:384:14:384:16 | end | | test.cpp:381:5:381:9 | ... ++ | test.cpp:384:14:384:16 | end | | test.cpp:384:14:384:16 | end | test.cpp:384:13:384:16 | Load: * ... | +| test.cpp:388:14:388:27 | new[] | test.cpp:389:16:389:17 | xs | +| test.cpp:388:14:388:27 | new[] | test.cpp:392:5:392:6 | xs | +| test.cpp:389:16:389:17 | xs | test.cpp:392:5:392:8 | ... ++ | +| test.cpp:389:16:389:17 | xs | test.cpp:392:5:392:8 | ... ++ | +| test.cpp:389:16:389:17 | xs | test.cpp:392:5:392:8 | ... ++ | +| test.cpp:389:16:389:17 | xs | test.cpp:392:5:392:8 | ... ++ | +| test.cpp:389:16:389:17 | xs | test.cpp:393:9:393:10 | xs | +| test.cpp:389:16:389:17 | xs | test.cpp:393:9:393:10 | xs | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:392:5:392:8 | ... ++ | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:392:5:392:8 | ... ++ | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:393:9:393:10 | xs | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:393:9:393:10 | xs | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:393:9:393:10 | xs | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:393:9:393:10 | xs | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:395:5:395:6 | xs | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:395:5:395:6 | xs | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:395:5:395:13 | Store: ... = ... | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:395:5:395:13 | Store: ... = ... | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:395:5:395:13 | Store: ... = ... | +| test.cpp:392:5:392:8 | ... ++ | test.cpp:395:5:395:13 | Store: ... = ... | +| test.cpp:393:9:393:10 | xs | test.cpp:395:5:395:6 | xs | +| test.cpp:393:9:393:10 | xs | test.cpp:395:5:395:13 | Store: ... = ... | +| test.cpp:393:9:393:10 | xs | test.cpp:395:5:395:13 | Store: ... = ... | +| test.cpp:395:5:395:6 | xs | test.cpp:395:5:395:13 | Store: ... = ... | nodes | test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc | | test.cpp:5:15:5:15 | p | semmle.label | p | @@ -1087,6 +1111,17 @@ nodes | test.cpp:381:5:381:9 | ... ++ | semmle.label | ... ++ | | test.cpp:384:13:384:16 | Load: * ... | semmle.label | Load: * ... | | test.cpp:384:14:384:16 | end | semmle.label | end | +| test.cpp:388:14:388:27 | new[] | semmle.label | new[] | +| test.cpp:389:16:389:17 | xs | semmle.label | xs | +| test.cpp:392:5:392:6 | xs | semmle.label | xs | +| test.cpp:392:5:392:8 | ... ++ | semmle.label | ... ++ | +| test.cpp:392:5:392:8 | ... ++ | semmle.label | ... ++ | +| test.cpp:392:5:392:8 | ... ++ | semmle.label | ... ++ | +| test.cpp:392:5:392:8 | ... ++ | semmle.label | ... ++ | +| test.cpp:393:9:393:10 | xs | semmle.label | xs | +| test.cpp:393:9:393:10 | xs | semmle.label | xs | +| test.cpp:395:5:395:6 | xs | semmle.label | xs | +| test.cpp:395:5:395:13 | Store: ... = ... | semmle.label | Store: ... = ... | subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | @@ -1113,3 +1148,4 @@ subpaths | test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:372:15:372:16 | Load: * ... | test.cpp:363:14:363:27 | new[] | test.cpp:372:15:372:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:363:14:363:27 | new[] | new[] | test.cpp:365:19:365:22 | size | size | | test.cpp:384:13:384:16 | Load: * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size | +| test.cpp:395:5:395:13 | Store: ... = ... | test.cpp:388:14:388:27 | new[] | test.cpp:395:5:395:13 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:388:14:388:27 | new[] | new[] | test.cpp:389:19:389:22 | size | size | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index 05b0f1c07ca..4b6cd37dd4f 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -383,3 +383,14 @@ void test27(unsigned size, bool b) { int val = *end; // BAD } + +void test28(unsigned size) { + char *xs = new char[size]; + char *end = &xs[size]; + if (xs >= end) + return; + xs++; + if (xs >= end) + return; + xs[0] = 0; // GOOD [FALSE POSITIVE] +} From eb62df6ece139eaa02241f96c608da9ed0b6d680 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 13 Jun 2023 14:52:32 +0200 Subject: [PATCH 588/739] Go: Rewrite `InlineFlowTest` as a parameterized module --- .../2023-06-14-log-injection-deprecation.md | 4 + go/ql/lib/semmle/go/security/LogInjection.qll | 15 +- go/ql/src/Security/CWE-117/LogInjection.ql | 6 +- go/ql/test/TestUtilities/InlineFlowTest.qll | 128 +++++++++--------- .../ExternalFlow/completetest.expected | 1 + .../go/dataflow/ExternalFlow/completetest.ql | 14 +- .../GenericFunctionsAndTypes/Flows.expected | 2 + .../GenericFunctionsAndTypes/Flows.ql | 1 + .../CWE-117/LogInjectionTest.expected | 2 + .../Security/CWE-117/LogInjectionTest.ql | 9 +- 10 files changed, 95 insertions(+), 87 deletions(-) create mode 100644 go/ql/lib/change-notes/2023-06-14-log-injection-deprecation.md diff --git a/go/ql/lib/change-notes/2023-06-14-log-injection-deprecation.md b/go/ql/lib/change-notes/2023-06-14-log-injection-deprecation.md new file mode 100644 index 00000000000..88ec05c17ce --- /dev/null +++ b/go/ql/lib/change-notes/2023-06-14-log-injection-deprecation.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The `LogInjection::Configuration` taint flow configuration class has been deprecated. Use the `LogInjection::Flow` module instead. \ No newline at end of file diff --git a/go/ql/lib/semmle/go/security/LogInjection.qll b/go/ql/lib/semmle/go/security/LogInjection.qll index 12f64c87e4a..70e0947c53b 100644 --- a/go/ql/lib/semmle/go/security/LogInjection.qll +++ b/go/ql/lib/semmle/go/security/LogInjection.qll @@ -17,7 +17,7 @@ module LogInjection { /** * A taint-tracking configuration for reasoning about log injection vulnerabilities. */ - class Configuration extends TaintTracking::Configuration { + deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "LogInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } @@ -30,4 +30,17 @@ module LogInjection { guard instanceof SanitizerGuard } } + + /** + * A taint-tracking configuration for reasoning about log injection vulnerabilities. + */ + module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof Sanitizer } + } + + module Flow = TaintTracking::Global<Config>; } diff --git a/go/ql/src/Security/CWE-117/LogInjection.ql b/go/ql/src/Security/CWE-117/LogInjection.ql index 39952dbbfa1..5b6586c8e4e 100644 --- a/go/ql/src/Security/CWE-117/LogInjection.ql +++ b/go/ql/src/Security/CWE-117/LogInjection.ql @@ -13,9 +13,9 @@ import go import semmle.go.security.LogInjection -import DataFlow::PathGraph +import LogInjection::Flow::PathGraph -from LogInjection::Configuration c, DataFlow::PathNode source, DataFlow::PathNode sink -where c.hasFlowPath(source, sink) +from LogInjection::Flow::PathNode source, LogInjection::Flow::PathNode sink +where LogInjection::Flow::flowPath(source, sink) select sink.getNode(), source, sink, "This log entry depends on a $@.", source.getNode(), "user-provided value" diff --git a/go/ql/test/TestUtilities/InlineFlowTest.qll b/go/ql/test/TestUtilities/InlineFlowTest.qll index 0726265699f..f8d54c82f3f 100644 --- a/go/ql/test/TestUtilities/InlineFlowTest.qll +++ b/go/ql/test/TestUtilities/InlineFlowTest.qll @@ -3,37 +3,30 @@ * * Example for a test.ql: * ```ql - * import java + * import go * import TestUtilities.InlineFlowTest + * import DefaultFlowTest * ``` * * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. - * Example of the corresponding test file, e.g. Test.java + * Example of the corresponding test file, e.g. Test.go * ```go - * public class Test { - * - * Object source() { return null; } - * String taint() { return null; } - * void sink(Object o) { } - * - * public void test() { - * Object s = source(); - * sink(s); //$hasValueFlow - * String t = "foo" + taint(); - * sink(t); //$hasTaintFlow - * } + * func source() string { return ""; } + * func taint() string { return ""; } + * func sink(s string) { } * + * func test() { + * s := source() + * sink(s) // $ hasValueFlow="s" + * t := "foo" + taint() + * sink(t) // $ hasTaintFlow="t" * } * ``` * - * If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows: - * ```ql - * class HasFlowTest extends InlineFlowTest { - * override DataFlow::Configuration getTaintFlowConfig() { none() } - * - * override DataFlow::Configuration getValueFlowConfig() { none() } - * } - * ``` + * If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import + * `ValueFlowTest<DefaultFlowConfig>`. Similarly, if you are only interested in taint flow, then instead of + * importing `DefaultFlowTest`, you can import `TaintFlowTest<DefaultFlowConfig>`. In both cases + * `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`. * * If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`. */ @@ -47,57 +40,62 @@ private predicate defaultSource(DataFlow::Node source) { ) } -class DefaultValueFlowConf extends DataFlow::Configuration { - DefaultValueFlowConf() { this = "qltest:defaultValueFlowConf" } - - override predicate isSource(DataFlow::Node source) { defaultSource(source) } - - override predicate isSink(DataFlow::Node sink) { - exists(Function fn | fn.hasQualifiedName(_, "sink") | sink = fn.getACall().getAnArgument()) - } - - override int fieldFlowBranchLimit() { result = 1000 } +private predicate defaultSink(DataFlow::Node sink) { + exists(Function fn | fn.hasQualifiedName(_, "sink") | sink = fn.getACall().getAnArgument()) } -class DefaultTaintFlowConf extends TaintTracking::Configuration { - DefaultTaintFlowConf() { this = "qltest:defaultTaintFlowConf" } +module DefaultFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { defaultSource(source) } - override predicate isSource(DataFlow::Node source) { defaultSource(source) } + predicate isSink(DataFlow::Node sink) { defaultSink(sink) } - override predicate isSink(DataFlow::Node sink) { - exists(Function fn | fn.hasQualifiedName(_, "sink") | sink = fn.getACall().getAnArgument()) - } - - override int fieldFlowBranchLimit() { result = 1000 } + int fieldFlowBranchLimit() { result = 1000 } } -class InlineFlowTest extends InlineExpectationsTest { - InlineFlowTest() { this = "HasFlowTest" } +private module NoFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { none() } - override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + predicate isSink(DataFlow::Node sink) { none() } +} - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "hasValueFlow" and - exists(DataFlow::Node sink | this.getValueFlowConfig().hasFlowTo(sink) | - sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), - location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and - element = sink.toString() and - value = "\"" + sink.toString() + "\"" - ) - or - tag = "hasTaintFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | - this.getTaintFlowConfig().hasFlow(src, sink) and - not this.getValueFlowConfig().hasFlow(src, sink) - | - sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), - location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and - element = sink.toString() and - value = "\"" + sink.toString() + "\"" - ) +module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> { + module ValueFlow = DataFlow::Global<ValueFlowConfig>; + + module TaintFlow = TaintTracking::Global<TaintFlowConfig>; + + private module InlineTest implements TestSig { + string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasValueFlow" and + exists(DataFlow::Node sink | ValueFlow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "\"" + sink.toString() + "\"" + ) + or + tag = "hasTaintFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | + TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink) + | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "\"" + sink.toString() + "\"" + ) + } } - DataFlow::Configuration getValueFlowConfig() { result = any(DefaultValueFlowConf config) } - - DataFlow::Configuration getTaintFlowConfig() { result = any(DefaultTaintFlowConf config) } + import MakeTest<InlineTest> +} + +module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>; + +module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> { + import FlowTest<ValueFlowConfig, NoFlowConfig> +} + +module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> { + import FlowTest<NoFlowConfig, TaintFlowConfig> } diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.expected index 81332464f79..105b7026d0c 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.expected @@ -1,2 +1,3 @@ failures invalidModelRow +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ql index 9719a9d69a6..2b719551ae0 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ql @@ -8,16 +8,10 @@ import ModelValidation import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineFlowTest -class Config extends TaintTracking::Configuration { - Config() { this = "external-flow-test" } +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { sourceNode(src, "qltest") } - override predicate isSource(DataFlow::Node src) { sourceNode(src, "qltest") } - - override predicate isSink(DataFlow::Node src) { sinkNode(src, "qltest") } + predicate isSink(DataFlow::Node src) { sinkNode(src, "qltest") } } -class ExternalFlowTest extends InlineFlowTest { - override DataFlow::Configuration getValueFlowConfig() { none() } - - override DataFlow::Configuration getTaintFlowConfig() { result = any(Config config) } -} +import TaintFlowTest<Config> diff --git a/go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/Flows.expected b/go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/Flows.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/Flows.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/Flows.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/Flows.ql index 881d262f400..1b27b27d6dc 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/Flows.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/Flows.ql @@ -1,2 +1,3 @@ import go import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/go/ql/test/query-tests/Security/CWE-117/LogInjectionTest.expected b/go/ql/test/query-tests/Security/CWE-117/LogInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/query-tests/Security/CWE-117/LogInjectionTest.expected +++ b/go/ql/test/query-tests/Security/CWE-117/LogInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/query-tests/Security/CWE-117/LogInjectionTest.ql b/go/ql/test/query-tests/Security/CWE-117/LogInjectionTest.ql index 576ce9ba342..298287ec4aa 100644 --- a/go/ql/test/query-tests/Security/CWE-117/LogInjectionTest.ql +++ b/go/ql/test/query-tests/Security/CWE-117/LogInjectionTest.ql @@ -1,11 +1,4 @@ import go import TestUtilities.InlineFlowTest import semmle.go.security.LogInjection - -class LogInjectionTest extends InlineFlowTest { - override DataFlow::Configuration getTaintFlowConfig() { - result = any(LogInjection::Configuration config) - } - - override DataFlow::Configuration getValueFlowConfig() { none() } -} +import TaintFlowTest<LogInjection::Config> From 853bf2ae4eda2f20aa03df78dae47b0db2a8d658 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Wed, 14 Jun 2023 12:04:49 +0200 Subject: [PATCH 589/739] C#: Rewrite `InlineFlowTest` as a parameterized module --- .../ql/test/TestUtilities/InlineFlowTest.qll | 87 +++++++++++-------- .../dataflow/fields/FieldFlow.expected | 1 + .../dataflow/fields/FieldFlow.ql | 7 +- .../dataflow/operators/operatorFlow.expected | 1 + .../dataflow/operators/operatorFlow.ql | 7 +- .../dataflow/patterns/PatternFlow.expected | 1 + .../dataflow/patterns/PatternFlow.ql | 7 +- .../dataflow/tuples/Tuples.expected | 1 + .../library-tests/dataflow/tuples/Tuples.ql | 7 +- 9 files changed, 71 insertions(+), 48 deletions(-) diff --git a/csharp/ql/test/TestUtilities/InlineFlowTest.qll b/csharp/ql/test/TestUtilities/InlineFlowTest.qll index a31d531e1b6..dc95063f03f 100644 --- a/csharp/ql/test/TestUtilities/InlineFlowTest.qll +++ b/csharp/ql/test/TestUtilities/InlineFlowTest.qll @@ -4,11 +4,12 @@ * Example for a test.ql: * ```ql * import csharp - * import DefaultValueFlow::PathGraph * import TestUtilities.InlineFlowTest + * import DefaultFlowTest + * import ValueFlow::PathGraph * - * from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink - * where DefaultValueFlow::flowPath(source, sink) + * from ValueFlow::PathNode source, ValueFlow::PathNode sink + * where ValueFlow::flowPath(source, sink) * select sink, source, sink, "$@", source, source.toString() * * ``` @@ -32,14 +33,10 @@ * } * ``` * - * If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows: - * ```ql - * class HasFlowTest extends InlineFlowTest { - * override DataFlow::Configuration getTaintFlowConfig() { none() } - * - * override DataFlow::Configuration getValueFlowConfig() { none() } - * } - * ``` + * If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import + * `ValueFlowTest<DefaultFlowConfig>`. Similarly, if you are only interested in taint flow, then instead of + * importing `DefaultFlowTest`, you can import `TaintFlowTest<DefaultFlowConfig>`. In both cases + * `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`. * * If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`. */ @@ -47,8 +44,8 @@ import csharp import TestUtilities.InlineExpectationsTest -private predicate defaultSource(DataFlow::Node src) { - src.asExpr().(MethodCall).getTarget().getUndecoratedName() = ["Source", "Taint"] +private predicate defaultSource(DataFlow::Node source) { + source.asExpr().(MethodCall).getTarget().getUndecoratedName() = ["Source", "Taint"] } private predicate defaultSink(DataFlow::Node sink) { @@ -58,42 +55,60 @@ private predicate defaultSink(DataFlow::Node sink) { } module DefaultFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node n) { defaultSource(n) } + predicate isSource(DataFlow::Node source) { defaultSource(source) } - predicate isSink(DataFlow::Node n) { defaultSink(n) } + predicate isSink(DataFlow::Node sink) { defaultSink(sink) } int fieldFlowBranchLimit() { result = 1000 } } -module DefaultValueFlow = DataFlow::Global<DefaultFlowConfig>; +private module NoFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { none() } -module DefaultTaintFlow = TaintTracking::Global<DefaultFlowConfig>; + predicate isSink(DataFlow::Node sink) { none() } +} private string getSourceArgString(DataFlow::Node src) { defaultSource(src) and src.asExpr().(MethodCall).getAnArgument().getValue() = result } -class InlineFlowTest extends InlineExpectationsTest { - InlineFlowTest() { this = "HasFlowTest" } +module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> { + module ValueFlow = DataFlow::Global<ValueFlowConfig>; - override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + module TaintFlow = TaintTracking::Global<TaintFlowConfig>; - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "hasValueFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | DefaultValueFlow::flow(src, sink) | - sink.getLocation() = location and - element = sink.toString() and - if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" - ) - or - tag = "hasTaintFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | - DefaultTaintFlow::flow(src, sink) and not DefaultValueFlow::flow(src, sink) - | - sink.getLocation() = location and - element = sink.toString() and - if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" - ) + private module InlineTest implements TestSig { + string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasValueFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) + or + tag = "hasTaintFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | + TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink) + | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) + } } + + import MakeTest<InlineTest> +} + +module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>; + +module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> { + import FlowTest<ValueFlowConfig, NoFlowConfig> +} + +module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> { + import FlowTest<NoFlowConfig, TaintFlowConfig> } diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected index aa9ac0493aa..a0d9a917702 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | A.cs:5:17:5:28 | call to method Source<C> : C | A.cs:6:24:6:24 | access to local variable c : C | | A.cs:6:17:6:25 | call to method Make : B [field c] : C | A.cs:7:14:7:14 | access to local variable b : B [field c] : C | diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql index b01c0f7fcaf..39395ad831b 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql @@ -3,9 +3,10 @@ */ import csharp -import DefaultValueFlow::PathGraph import TestUtilities.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph -from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink -where DefaultValueFlow::flowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected index 7b173a98e41..3f4f02ff6a1 100644 --- a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | | Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | diff --git a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql index b01c0f7fcaf..39395ad831b 100644 --- a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql @@ -3,9 +3,10 @@ */ import csharp -import DefaultValueFlow::PathGraph import TestUtilities.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph -from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink -where DefaultValueFlow::flowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected index f965891244c..f2ab31c12b3 100644 --- a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected @@ -1,4 +1,5 @@ failures +testFailures edges nodes subpaths diff --git a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql index b01c0f7fcaf..39395ad831b 100644 --- a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql @@ -3,9 +3,10 @@ */ import csharp -import DefaultValueFlow::PathGraph import TestUtilities.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph -from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink -where DefaultValueFlow::flowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected index dae85aa45aa..bb1715df029 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected +++ b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected @@ -1,4 +1,5 @@ failures +testFailures edges | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:10:21:10:22 | access to local variable o1 : Object | | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:10:29:10:30 | access to local variable o2 : Object | diff --git a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql index b01c0f7fcaf..39395ad831b 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql +++ b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql @@ -3,9 +3,10 @@ */ import csharp -import DefaultValueFlow::PathGraph import TestUtilities.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph -from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink -where DefaultValueFlow::flowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() From 742eb8dd12c1b07cc112ff26a9caaa9c472ba23b Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Wed, 14 Jun 2023 13:42:13 +0200 Subject: [PATCH 590/739] Java: Rewrite `InlineFlowTest` as a parameterized module --- .../flowtestcasegenerator/testHeader.qlfrag | 1 + java/ql/test/TestUtilities/InlineFlowTest.qll | 97 ++++++++++--------- java/ql/test/ext/TestModels/test.expected | 2 + java/ql/test/ext/TestModels/test.ql | 1 + .../dataflow/summaries/test.expected | 2 + .../library-tests/dataflow/summaries/test.ql | 1 + .../dataflow/callctx/test.expected | 2 + .../library-tests/dataflow/callctx/test.ql | 1 + .../collections/containerflow.expected | 2 + .../dataflow/collections/containerflow.ql | 1 + .../dataflow/fluent-methods/flow.expected | 2 + .../dataflow/fluent-methods/flow.ql | 1 + .../dataflow/stream-collect/test.expected | 2 + .../dataflow/stream-collect/test.ql | 1 + .../dataflow/synth-global/test.expected | 1 + .../dataflow/synth-global/test.ql | 1 + .../dataflow/taint-format/test.expected | 2 + .../dataflow/taint-format/test.ql | 1 + .../dataflow/taint-gson/dataFlow.expected | 2 + .../dataflow/taint-gson/dataFlow.ql | 1 + .../dataflow/taint-jackson/dataFlow.expected | 2 + .../dataflow/taint-jackson/dataFlow.ql | 1 + .../frameworks/JaxWs/JaxRsFlow.expected | 2 + .../frameworks/JaxWs/JaxRsFlow.ql | 14 +-- .../android/asynctask/test.expected | 2 + .../frameworks/android/asynctask/test.ql | 1 + .../content-provider-summaries/test.expected | 2 + .../content-provider-summaries/test.ql | 1 + .../android/content-provider/test.expected | 2 + .../android/content-provider/test.ql | 10 +- .../android/external-storage/test.expected | 2 + .../android/external-storage/test.ql | 8 +- .../android/flow-steps/test.expected | 2 + .../frameworks/android/flow-steps/test.ql | 1 + .../frameworks/android/intent/test.expected | 2 + .../frameworks/android/intent/test.ql | 1 + .../android/notification/test.expected | 2 + .../frameworks/android/notification/test.ql | 1 + .../frameworks/android/slice/test.expected | 2 + .../frameworks/android/slice/test.ql | 14 +-- .../OnActivityResultSourceTest.expected | 2 + .../sources/OnActivityResultSourceTest.ql | 10 +- .../frameworks/android/uri/test.expected | 2 + .../frameworks/android/uri/test.ql | 1 + .../frameworks/android/widget/test.expected | 1 + .../frameworks/android/widget/test.ql | 1 + .../frameworks/apache-ant/test.expected | 2 + .../frameworks/apache-ant/test.ql | 1 + .../apache-collections/test.expected | 2 + .../frameworks/apache-collections/test.ql | 1 + .../apache-commons-compress/test.expected | 2 + .../apache-commons-compress/test.ql | 1 + .../apache-commons-lang3/flow.expected | 2 + .../frameworks/apache-commons-lang3/flow.ql | 1 + .../frameworks/apache-http/flow.expected | 2 + .../frameworks/apache-http/flow.ql | 8 +- .../frameworks/gson/test.expected | 2 + .../library-tests/frameworks/gson/test.ql | 1 + .../guava/generated/cache/test.expected | 2 + .../frameworks/guava/generated/cache/test.ql | 1 + .../guava/generated/collect/test.expected | 2 + .../guava/generated/collect/test.ql | 1 + .../frameworks/hudson/test.expected | 2 + .../library-tests/frameworks/hudson/test.ql | 1 + .../frameworks/jackson/test.expected | 2 + .../library-tests/frameworks/jackson/test.ql | 1 + .../frameworks/javax-json/test.expected | 2 + .../frameworks/javax-json/test.ql | 1 + .../frameworks/jdk/java.io/test.expected | 2 + .../frameworks/jdk/java.io/test.ql | 1 + .../frameworks/jdk/java.net/test.expected | 2 + .../frameworks/jdk/java.net/test.ql | 1 + .../jdk/java.nio.file/test.expected | 2 + .../frameworks/jdk/java.nio.file/test.ql | 1 + .../frameworks/json-java/test.expected | 2 + .../frameworks/json-java/test.ql | 1 + .../frameworks/netty/generated/test.expected | 2 + .../frameworks/netty/generated/test.ql | 1 + .../frameworks/netty/manual/test.expected | 2 + .../frameworks/netty/manual/test.ql | 8 +- .../frameworks/okhttp/test.expected | 2 + .../library-tests/frameworks/okhttp/test.ql | 8 +- .../frameworks/play/test.expected | 2 + .../library-tests/frameworks/play/test.ql | 1 + .../frameworks/rabbitmq/FlowTest.expected | 2 + .../frameworks/rabbitmq/FlowTest.ql | 8 +- .../frameworks/ratpack/flow.expected | 2 + .../library-tests/frameworks/ratpack/flow.ql | 10 +- .../frameworks/retrofit/test.expected | 2 + .../library-tests/frameworks/retrofit/test.ql | 6 +- .../frameworks/spring/beans/test.expected | 2 + .../frameworks/spring/beans/test.ql | 1 + .../frameworks/spring/cache/test.expected | 2 + .../frameworks/spring/cache/test.ql | 1 + .../frameworks/spring/context/flow.expected | 2 + .../frameworks/spring/context/flow.ql | 1 + .../spring/controller/test.expected | 2 + .../frameworks/spring/controller/test.ql | 8 +- .../frameworks/spring/data/test.expected | 2 + .../frameworks/spring/data/test.ql | 1 + .../frameworks/spring/http/flow.expected | 2 + .../frameworks/spring/http/flow.ql | 1 + .../frameworks/spring/ui/test.expected | 2 + .../frameworks/spring/ui/test.ql | 1 + .../frameworks/spring/util/test.expected | 2 + .../frameworks/spring/util/test.ql | 1 + .../spring/validation/test.expected | 2 + .../frameworks/spring/validation/test.ql | 1 + .../spring/webmultipart/test.expected | 2 + .../frameworks/spring/webmultipart/test.ql | 1 + .../frameworks/spring/webutil/test.expected | 2 + .../frameworks/spring/webutil/test.ql | 1 + .../frameworks/stapler/test.expected | 2 + .../library-tests/frameworks/stapler/test.ql | 1 + .../frameworks/stream/test.expected | 2 + .../library-tests/frameworks/stream/test.ql | 1 + .../frameworks/thymeleaf/test.expected | 2 + .../frameworks/thymeleaf/test.ql | 1 + .../test/library-tests/logging/test.expected | 2 + java/ql/test/library-tests/logging/test.ql | 1 + .../test/library-tests/optional/test.expected | 2 + java/ql/test/library-tests/optional/test.ql | 1 + .../ql/test/library-tests/paths/test.expected | 2 + java/ql/test/library-tests/paths/test.ql | 1 + .../library-tests/pathsanitizer/test.expected | 2 + .../test/library-tests/pathsanitizer/test.ql | 10 +- .../ql/test/library-tests/regex/test.expected | 2 + java/ql/test/library-tests/regex/test.ql | 1 + .../test/library-tests/scanner/test.expected | 2 + java/ql/test/library-tests/scanner/test.ql | 1 + .../CWE-117/LogInjectionTest.expected | 2 + .../security/CWE-117/LogInjectionTest.ql | 8 +- ...tentUriPermissionManipulationTest.expected | 2 + .../IntentUriPermissionManipulationTest.ql | 9 +- .../UnsafeContentUriResolutionTest.expected | 2 + .../CWE-441/UnsafeContentUriResolutionTest.ql | 9 +- .../CWE-470/FragmentInjectionTest.expected | 2 + .../security/CWE-470/FragmentInjectionTest.ql | 9 +- .../WebviewDebuggingEnabled.expected | 2 + .../WebviewDebuggingEnabled.ql | 9 +- .../CWE-532/SensitiveLogInfo.expected | 2 + .../security/CWE-532/SensitiveLogInfo.ql | 9 +- .../query-tests/security/CWE-611/XXE.expected | 2 + .../test/query-tests/security/CWE-611/XXE.ql | 9 +- .../CWE-780/RsaWithoutOaepTest.expected | 2 + .../security/CWE-780/RsaWithoutOaepTest.ql | 9 +- .../CWE-927/SensitiveCommunication.expected | 2 + .../CWE-927/SensitiveCommunication.ql | 9 +- 148 files changed, 271 insertions(+), 224 deletions(-) diff --git a/java/ql/src/utils/flowtestcasegenerator/testHeader.qlfrag b/java/ql/src/utils/flowtestcasegenerator/testHeader.qlfrag index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/src/utils/flowtestcasegenerator/testHeader.qlfrag +++ b/java/ql/src/utils/flowtestcasegenerator/testHeader.qlfrag @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/TestUtilities/InlineFlowTest.qll b/java/ql/test/TestUtilities/InlineFlowTest.qll index 5e37770a279..6f344c5074e 100644 --- a/java/ql/test/TestUtilities/InlineFlowTest.qll +++ b/java/ql/test/TestUtilities/InlineFlowTest.qll @@ -5,6 +5,7 @@ * ```ql * import java * import TestUtilities.InlineFlowTest + * import DefaultFlowTest * ``` * * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. @@ -18,22 +19,18 @@ * * public void test() { * Object s = source(); - * sink(s); //$hasValueFlow + * sink(s); // $ hasValueFlow * String t = "foo" + taint(); - * sink(t); //$hasTaintFlow + * sink(t); // $ hasTaintFlow * } * * } * ``` * - * If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows: - * ```ql - * class HasFlowTest extends InlineFlowTest { - * override DataFlow::Configuration getTaintFlowConfig() { none() } - * - * override DataFlow::Configuration getValueFlowConfig() { none() } - * } - * ``` + * If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import + * `ValueFlowTest<DefaultFlowConfig>`. Similarly, if you are only interested in taint flow, then instead of + * importing `DefaultFlowTest`, you can import `TaintFlowTest<DefaultFlowConfig>`. In both cases + * `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`. * * If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`. */ @@ -43,57 +40,69 @@ import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.TaintTracking import TestUtilities.InlineExpectationsTest -private predicate defaultSource(DataFlow::Node src) { - src.asExpr().(MethodAccess).getMethod().getName() = ["source", "taint"] +private predicate defaultSource(DataFlow::Node source) { + source.asExpr().(MethodAccess).getMethod().getName() = ["source", "taint"] +} + +private predicate defaultSink(DataFlow::Node sink) { + exists(MethodAccess ma | ma.getMethod().hasName("sink") | sink.asExpr() = ma.getAnArgument()) } module DefaultFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node n) { defaultSource(n) } + predicate isSource(DataFlow::Node source) { defaultSource(source) } - predicate isSink(DataFlow::Node n) { - exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument()) - } + predicate isSink(DataFlow::Node sink) { defaultSink(sink) } int fieldFlowBranchLimit() { result = 1000 } } -private module DefaultValueFlow = DataFlow::Global<DefaultFlowConfig>; +private module NoFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { none() } -private module DefaultTaintFlow = TaintTracking::Global<DefaultFlowConfig>; + predicate isSink(DataFlow::Node sink) { none() } +} private string getSourceArgString(DataFlow::Node src) { defaultSource(src) and src.asExpr().(MethodAccess).getAnArgument().(StringLiteral).getValue() = result } -class InlineFlowTest extends InlineExpectationsTest { - InlineFlowTest() { this = "HasFlowTest" } +module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> { + module ValueFlow = DataFlow::Global<ValueFlowConfig>; - override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + module TaintFlow = TaintTracking::Global<TaintFlowConfig>; - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "hasValueFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | this.hasValueFlow(src, sink) | - sink.getLocation() = location and - element = sink.toString() and - if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" - ) - or - tag = "hasTaintFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | - this.hasTaintFlow(src, sink) and not this.hasValueFlow(src, sink) - | - sink.getLocation() = location and - element = sink.toString() and - if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" - ) + private module InlineTest implements TestSig { + string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasValueFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) + or + tag = "hasTaintFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | + TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink) + | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) + } } - predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { - DefaultValueFlow::flow(src, sink) - } - - predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - DefaultTaintFlow::flow(src, sink) - } + import MakeTest<InlineTest> +} + +module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>; + +module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> { + import FlowTest<ValueFlowConfig, NoFlowConfig> +} + +module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> { + import FlowTest<NoFlowConfig, TaintFlowConfig> } diff --git a/java/ql/test/ext/TestModels/test.expected b/java/ql/test/ext/TestModels/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/ext/TestModels/test.expected +++ b/java/ql/test/ext/TestModels/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/ext/TestModels/test.ql b/java/ql/test/ext/TestModels/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/ext/TestModels/test.ql +++ b/java/ql/test/ext/TestModels/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/kotlin/library-tests/dataflow/summaries/test.expected b/java/ql/test/kotlin/library-tests/dataflow/summaries/test.expected index f566914ba89..f72956fded3 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/summaries/test.expected +++ b/java/ql/test/kotlin/library-tests/dataflow/summaries/test.expected @@ -1,3 +1,5 @@ +failures +testFailures | test.kt:28:14:28:21 | getSecond(...) | Unexpected result: hasTaintFlow=a | | test.kt:35:14:35:27 | component1(...) | Unexpected result: hasTaintFlow=d | | test.kt:41:14:41:22 | getSecond(...) | Unexpected result: hasTaintFlow=e | diff --git a/java/ql/test/kotlin/library-tests/dataflow/summaries/test.ql b/java/ql/test/kotlin/library-tests/dataflow/summaries/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/summaries/test.ql +++ b/java/ql/test/kotlin/library-tests/dataflow/summaries/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/dataflow/callctx/test.expected b/java/ql/test/library-tests/dataflow/callctx/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/callctx/test.expected +++ b/java/ql/test/library-tests/dataflow/callctx/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/callctx/test.ql b/java/ql/test/library-tests/dataflow/callctx/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/dataflow/callctx/test.ql +++ b/java/ql/test/library-tests/dataflow/callctx/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.expected b/java/ql/test/library-tests/dataflow/collections/containerflow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/collections/containerflow.expected +++ b/java/ql/test/library-tests/dataflow/collections/containerflow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.ql b/java/ql/test/library-tests/dataflow/collections/containerflow.ql index 992971d6dc7..4b1a19535ea 100644 --- a/java/ql/test/library-tests/dataflow/collections/containerflow.ql +++ b/java/ql/test/library-tests/dataflow/collections/containerflow.ql @@ -1,3 +1,4 @@ import java import semmle.code.java.dataflow.DataFlow import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/dataflow/fluent-methods/flow.expected b/java/ql/test/library-tests/dataflow/fluent-methods/flow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/fluent-methods/flow.expected +++ b/java/ql/test/library-tests/dataflow/fluent-methods/flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/fluent-methods/flow.ql b/java/ql/test/library-tests/dataflow/fluent-methods/flow.ql index 4a9794ab351..944abac0642 100644 --- a/java/ql/test/library-tests/dataflow/fluent-methods/flow.ql +++ b/java/ql/test/library-tests/dataflow/fluent-methods/flow.ql @@ -2,6 +2,7 @@ import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.FlowSteps import TestUtilities.InlineFlowTest +import DefaultFlowTest class Model extends FluentMethod { Model() { this.getName() = "modelledFluentMethod" } diff --git a/java/ql/test/library-tests/dataflow/stream-collect/test.expected b/java/ql/test/library-tests/dataflow/stream-collect/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/stream-collect/test.expected +++ b/java/ql/test/library-tests/dataflow/stream-collect/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/stream-collect/test.ql b/java/ql/test/library-tests/dataflow/stream-collect/test.ql index c4b63c87071..50e3f8d2f7d 100644 --- a/java/ql/test/library-tests/dataflow/stream-collect/test.ql +++ b/java/ql/test/library-tests/dataflow/stream-collect/test.ql @@ -1 +1,2 @@ import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/dataflow/synth-global/test.expected b/java/ql/test/library-tests/dataflow/synth-global/test.expected index 81332464f79..ae4c33edb3d 100644 --- a/java/ql/test/library-tests/dataflow/synth-global/test.expected +++ b/java/ql/test/library-tests/dataflow/synth-global/test.expected @@ -1,2 +1,3 @@ failures +testFailures invalidModelRow diff --git a/java/ql/test/library-tests/dataflow/synth-global/test.ql b/java/ql/test/library-tests/dataflow/synth-global/test.ql index 0d9f2265afc..53f8aa6a6f6 100644 --- a/java/ql/test/library-tests/dataflow/synth-global/test.ql +++ b/java/ql/test/library-tests/dataflow/synth-global/test.ql @@ -1,3 +1,4 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest import ModelValidation diff --git a/java/ql/test/library-tests/dataflow/taint-format/test.expected b/java/ql/test/library-tests/dataflow/taint-format/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/taint-format/test.expected +++ b/java/ql/test/library-tests/dataflow/taint-format/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/taint-format/test.ql b/java/ql/test/library-tests/dataflow/taint-format/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/dataflow/taint-format/test.ql +++ b/java/ql/test/library-tests/dataflow/taint-format/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.expected b/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.expected +++ b/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.ql b/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.ql +++ b/java/ql/test/library-tests/dataflow/taint-gson/dataFlow.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/dataflow/taint-jackson/dataFlow.expected b/java/ql/test/library-tests/dataflow/taint-jackson/dataFlow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/dataflow/taint-jackson/dataFlow.expected +++ b/java/ql/test/library-tests/dataflow/taint-jackson/dataFlow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/dataflow/taint-jackson/dataFlow.ql b/java/ql/test/library-tests/dataflow/taint-jackson/dataFlow.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/dataflow/taint-jackson/dataFlow.ql +++ b/java/ql/test/library-tests/dataflow/taint-jackson/dataFlow.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.expected b/java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.expected +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.ql b/java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.ql index d0ab4274b12..93ab3fe066d 100644 --- a/java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.ql +++ b/java/ql/test/library-tests/frameworks/JaxWs/JaxRsFlow.ql @@ -13,16 +13,4 @@ module Config implements DataFlow::ConfigSig { predicate isSink = DefaultFlowConfig::isSink/1; } -module TaintFlow = TaintTracking::Global<Config>; - -module ValueFlow = DataFlow::Global<Config>; - -class Test extends InlineFlowTest { - override predicate hasTaintFlow(DataFlow::Node source, DataFlow::Node sink) { - TaintFlow::flow(source, sink) - } - - override predicate hasValueFlow(DataFlow::Node source, DataFlow::Node sink) { - ValueFlow::flow(source, sink) - } -} +import FlowTest<Config, Config> diff --git a/java/ql/test/library-tests/frameworks/android/asynctask/test.expected b/java/ql/test/library-tests/frameworks/android/asynctask/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/asynctask/test.expected +++ b/java/ql/test/library-tests/frameworks/android/asynctask/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/asynctask/test.ql b/java/ql/test/library-tests/frameworks/android/asynctask/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/android/asynctask/test.ql +++ b/java/ql/test/library-tests/frameworks/android/asynctask/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.expected b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.expected +++ b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql +++ b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/android/content-provider/test.expected b/java/ql/test/library-tests/frameworks/android/content-provider/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/content-provider/test.expected +++ b/java/ql/test/library-tests/frameworks/android/content-provider/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/content-provider/test.ql b/java/ql/test/library-tests/frameworks/android/content-provider/test.ql index f068b30b0d5..2c6bd09dc40 100644 --- a/java/ql/test/library-tests/frameworks/android/content-provider/test.ql +++ b/java/ql/test/library-tests/frameworks/android/content-provider/test.ql @@ -10,12 +10,4 @@ module ProviderTaintFlowConfig implements DataFlow::ConfigSig { int fieldFlowBranchLimit() { result = DefaultFlowConfig::fieldFlowBranchLimit() } } -module ProviderTaintFlow = TaintTracking::Global<ProviderTaintFlowConfig>; - -class ProviderInlineFlowTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - ProviderTaintFlow::flow(src, sink) - } -} +import TaintFlowTest<ProviderTaintFlowConfig> diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/test.expected b/java/ql/test/library-tests/frameworks/android/external-storage/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/external-storage/test.expected +++ b/java/ql/test/library-tests/frameworks/android/external-storage/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/test.ql b/java/ql/test/library-tests/frameworks/android/external-storage/test.ql index c73c0a5c6c9..64ff27077df 100644 --- a/java/ql/test/library-tests/frameworks/android/external-storage/test.ql +++ b/java/ql/test/library-tests/frameworks/android/external-storage/test.ql @@ -11,10 +11,4 @@ module Config implements DataFlow::ConfigSig { } } -module Flow = TaintTracking::Global<Config>; - -class ExternalStorageTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { Flow::flow(src, sink) } -} +import TaintFlowTest<Config> diff --git a/java/ql/test/library-tests/frameworks/android/flow-steps/test.expected b/java/ql/test/library-tests/frameworks/android/flow-steps/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/flow-steps/test.expected +++ b/java/ql/test/library-tests/frameworks/android/flow-steps/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/flow-steps/test.ql b/java/ql/test/library-tests/frameworks/android/flow-steps/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/android/flow-steps/test.ql +++ b/java/ql/test/library-tests/frameworks/android/flow-steps/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/android/intent/test.expected b/java/ql/test/library-tests/frameworks/android/intent/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/intent/test.expected +++ b/java/ql/test/library-tests/frameworks/android/intent/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/intent/test.ql b/java/ql/test/library-tests/frameworks/android/intent/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/android/intent/test.ql +++ b/java/ql/test/library-tests/frameworks/android/intent/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/android/notification/test.expected b/java/ql/test/library-tests/frameworks/android/notification/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/notification/test.expected +++ b/java/ql/test/library-tests/frameworks/android/notification/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/notification/test.ql b/java/ql/test/library-tests/frameworks/android/notification/test.ql index f0a60550d4d..07c022b1265 100644 --- a/java/ql/test/library-tests/frameworks/android/notification/test.ql +++ b/java/ql/test/library-tests/frameworks/android/notification/test.ql @@ -1,3 +1,4 @@ import java import semmle.code.java.frameworks.android.Intent import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/android/slice/test.expected b/java/ql/test/library-tests/frameworks/android/slice/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/slice/test.expected +++ b/java/ql/test/library-tests/frameworks/android/slice/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/slice/test.ql b/java/ql/test/library-tests/frameworks/android/slice/test.ql index b3c5fe78094..787f93df5a0 100644 --- a/java/ql/test/library-tests/frameworks/android/slice/test.ql +++ b/java/ql/test/library-tests/frameworks/android/slice/test.ql @@ -11,8 +11,6 @@ module SliceValueFlowConfig implements DataFlow::ConfigSig { predicate isSink = DefaultFlowConfig::isSink/1; } -module SliceValueFlow = DataFlow::Global<SliceValueFlowConfig>; - module SliceTaintFlowConfig implements DataFlow::ConfigSig { predicate isSource = DefaultFlowConfig::isSource/1; @@ -24,14 +22,4 @@ module SliceTaintFlowConfig implements DataFlow::ConfigSig { } } -module SliceTaintFlow = TaintTracking::Global<SliceTaintFlowConfig>; - -class SliceFlowTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node source, DataFlow::Node sink) { - SliceValueFlow::flow(source, sink) - } - - override predicate hasTaintFlow(DataFlow::Node source, DataFlow::Node sink) { - SliceTaintFlow::flow(source, sink) - } -} +import FlowTest<SliceValueFlowConfig, SliceTaintFlowConfig> diff --git a/java/ql/test/library-tests/frameworks/android/sources/OnActivityResultSourceTest.expected b/java/ql/test/library-tests/frameworks/android/sources/OnActivityResultSourceTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/sources/OnActivityResultSourceTest.expected +++ b/java/ql/test/library-tests/frameworks/android/sources/OnActivityResultSourceTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/sources/OnActivityResultSourceTest.ql b/java/ql/test/library-tests/frameworks/android/sources/OnActivityResultSourceTest.ql index 64c0f48ffa6..5b163a81935 100644 --- a/java/ql/test/library-tests/frameworks/android/sources/OnActivityResultSourceTest.ql +++ b/java/ql/test/library-tests/frameworks/android/sources/OnActivityResultSourceTest.ql @@ -10,12 +10,4 @@ module SourceValueFlowConfig implements DataFlow::ConfigSig { int fieldFlowBranchLimit() { result = DefaultFlowConfig::fieldFlowBranchLimit() } } -module SourceValueFlow = DataFlow::Global<SourceValueFlowConfig>; - -class SourceInlineFlowTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { - SourceValueFlow::flow(src, sink) - } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { none() } -} +import ValueFlowTest<SourceValueFlowConfig> diff --git a/java/ql/test/library-tests/frameworks/android/uri/test.expected b/java/ql/test/library-tests/frameworks/android/uri/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/android/uri/test.expected +++ b/java/ql/test/library-tests/frameworks/android/uri/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/android/uri/test.ql b/java/ql/test/library-tests/frameworks/android/uri/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/android/uri/test.ql +++ b/java/ql/test/library-tests/frameworks/android/uri/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/android/widget/test.expected b/java/ql/test/library-tests/frameworks/android/widget/test.expected index 8329ef6b41b..5390495c737 100644 --- a/java/ql/test/library-tests/frameworks/android/widget/test.expected +++ b/java/ql/test/library-tests/frameworks/android/widget/test.expected @@ -1,2 +1,3 @@ failures +testFailures valueOf diff --git a/java/ql/test/library-tests/frameworks/android/widget/test.ql b/java/ql/test/library-tests/frameworks/android/widget/test.ql index ddabfd1f27a..3d476b8bd5e 100644 --- a/java/ql/test/library-tests/frameworks/android/widget/test.ql +++ b/java/ql/test/library-tests/frameworks/android/widget/test.ql @@ -1,6 +1,7 @@ import java import semmle.code.java.dataflow.FlowSources import TestUtilities.InlineFlowTest +import DefaultFlowTest query predicate valueOf(MethodAccess ma) { ma.getMethod().hasQualifiedName("java.lang", "String", "valueOf") diff --git a/java/ql/test/library-tests/frameworks/apache-ant/test.expected b/java/ql/test/library-tests/frameworks/apache-ant/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/apache-ant/test.expected +++ b/java/ql/test/library-tests/frameworks/apache-ant/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/apache-ant/test.ql b/java/ql/test/library-tests/frameworks/apache-ant/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/apache-ant/test.ql +++ b/java/ql/test/library-tests/frameworks/apache-ant/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/apache-collections/test.expected b/java/ql/test/library-tests/frameworks/apache-collections/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/apache-collections/test.expected +++ b/java/ql/test/library-tests/frameworks/apache-collections/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/apache-collections/test.ql b/java/ql/test/library-tests/frameworks/apache-collections/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/apache-collections/test.ql +++ b/java/ql/test/library-tests/frameworks/apache-collections/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/apache-commons-compress/test.expected b/java/ql/test/library-tests/frameworks/apache-commons-compress/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-compress/test.expected +++ b/java/ql/test/library-tests/frameworks/apache-commons-compress/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/apache-commons-compress/test.ql b/java/ql/test/library-tests/frameworks/apache-commons-compress/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-compress/test.ql +++ b/java/ql/test/library-tests/frameworks/apache-commons-compress/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.ql b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.ql +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/apache-http/flow.expected b/java/ql/test/library-tests/frameworks/apache-http/flow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/apache-http/flow.expected +++ b/java/ql/test/library-tests/frameworks/apache-http/flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/apache-http/flow.ql b/java/ql/test/library-tests/frameworks/apache-http/flow.ql index 20069103a4a..540b4847ff3 100644 --- a/java/ql/test/library-tests/frameworks/apache-http/flow.ql +++ b/java/ql/test/library-tests/frameworks/apache-http/flow.ql @@ -21,10 +21,4 @@ module Config implements DataFlow::ConfigSig { } } -module Flow = TaintTracking::Global<Config>; - -class HasFlowTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { Flow::flow(src, sink) } -} +import TaintFlowTest<Config> diff --git a/java/ql/test/library-tests/frameworks/gson/test.expected b/java/ql/test/library-tests/frameworks/gson/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/gson/test.expected +++ b/java/ql/test/library-tests/frameworks/gson/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/gson/test.ql b/java/ql/test/library-tests/frameworks/gson/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/gson/test.ql +++ b/java/ql/test/library-tests/frameworks/gson/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/guava/generated/cache/test.expected b/java/ql/test/library-tests/frameworks/guava/generated/cache/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/guava/generated/cache/test.expected +++ b/java/ql/test/library-tests/frameworks/guava/generated/cache/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/guava/generated/cache/test.ql b/java/ql/test/library-tests/frameworks/guava/generated/cache/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/guava/generated/cache/test.ql +++ b/java/ql/test/library-tests/frameworks/guava/generated/cache/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.expected b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.expected +++ b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql +++ b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/hudson/test.expected b/java/ql/test/library-tests/frameworks/hudson/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/hudson/test.expected +++ b/java/ql/test/library-tests/frameworks/hudson/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/hudson/test.ql b/java/ql/test/library-tests/frameworks/hudson/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/hudson/test.ql +++ b/java/ql/test/library-tests/frameworks/hudson/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/jackson/test.expected b/java/ql/test/library-tests/frameworks/jackson/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/jackson/test.expected +++ b/java/ql/test/library-tests/frameworks/jackson/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/jackson/test.ql b/java/ql/test/library-tests/frameworks/jackson/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/jackson/test.ql +++ b/java/ql/test/library-tests/frameworks/jackson/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/javax-json/test.expected b/java/ql/test/library-tests/frameworks/javax-json/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/javax-json/test.expected +++ b/java/ql/test/library-tests/frameworks/javax-json/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/javax-json/test.ql b/java/ql/test/library-tests/frameworks/javax-json/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/javax-json/test.ql +++ b/java/ql/test/library-tests/frameworks/javax-json/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/jdk/java.io/test.expected b/java/ql/test/library-tests/frameworks/jdk/java.io/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.io/test.expected +++ b/java/ql/test/library-tests/frameworks/jdk/java.io/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/jdk/java.io/test.ql b/java/ql/test/library-tests/frameworks/jdk/java.io/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.io/test.ql +++ b/java/ql/test/library-tests/frameworks/jdk/java.io/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/jdk/java.net/test.expected b/java/ql/test/library-tests/frameworks/jdk/java.net/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.net/test.expected +++ b/java/ql/test/library-tests/frameworks/jdk/java.net/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/jdk/java.net/test.ql b/java/ql/test/library-tests/frameworks/jdk/java.net/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.net/test.ql +++ b/java/ql/test/library-tests/frameworks/jdk/java.net/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/jdk/java.nio.file/test.expected b/java/ql/test/library-tests/frameworks/jdk/java.nio.file/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.nio.file/test.expected +++ b/java/ql/test/library-tests/frameworks/jdk/java.nio.file/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/jdk/java.nio.file/test.ql b/java/ql/test/library-tests/frameworks/jdk/java.nio.file/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.nio.file/test.ql +++ b/java/ql/test/library-tests/frameworks/jdk/java.nio.file/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/json-java/test.expected b/java/ql/test/library-tests/frameworks/json-java/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/json-java/test.expected +++ b/java/ql/test/library-tests/frameworks/json-java/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/json-java/test.ql b/java/ql/test/library-tests/frameworks/json-java/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/json-java/test.ql +++ b/java/ql/test/library-tests/frameworks/json-java/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/netty/generated/test.expected b/java/ql/test/library-tests/frameworks/netty/generated/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/netty/generated/test.expected +++ b/java/ql/test/library-tests/frameworks/netty/generated/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/netty/generated/test.ql b/java/ql/test/library-tests/frameworks/netty/generated/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/netty/generated/test.ql +++ b/java/ql/test/library-tests/frameworks/netty/generated/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/netty/manual/test.expected b/java/ql/test/library-tests/frameworks/netty/manual/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/netty/manual/test.expected +++ b/java/ql/test/library-tests/frameworks/netty/manual/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/netty/manual/test.ql b/java/ql/test/library-tests/frameworks/netty/manual/test.ql index 111db20f792..c67cf1835fa 100644 --- a/java/ql/test/library-tests/frameworks/netty/manual/test.ql +++ b/java/ql/test/library-tests/frameworks/netty/manual/test.ql @@ -13,10 +13,4 @@ module Config implements DataFlow::ConfigSig { predicate isSink = DefaultFlowConfig::isSink/1; } -module Flow = TaintTracking::Global<Config>; - -class Test extends InlineFlowTest { - override predicate hasTaintFlow(DataFlow::Node source, DataFlow::Node sink) { - Flow::flow(source, sink) - } -} +import FlowTest<DefaultFlowConfig, Config> diff --git a/java/ql/test/library-tests/frameworks/okhttp/test.expected b/java/ql/test/library-tests/frameworks/okhttp/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/okhttp/test.expected +++ b/java/ql/test/library-tests/frameworks/okhttp/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/okhttp/test.ql b/java/ql/test/library-tests/frameworks/okhttp/test.ql index 52e8a47132a..04cb3e7f7ac 100644 --- a/java/ql/test/library-tests/frameworks/okhttp/test.ql +++ b/java/ql/test/library-tests/frameworks/okhttp/test.ql @@ -10,10 +10,4 @@ module OkHttpFlowConfig implements DataFlow::ConfigSig { } } -module OkHttpFlow = DataFlow::Global<OkHttpFlowConfig>; - -class OkHttpTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { - OkHttpFlow::flow(src, sink) - } -} +import FlowTest<OkHttpFlowConfig, DefaultFlowConfig> diff --git a/java/ql/test/library-tests/frameworks/play/test.expected b/java/ql/test/library-tests/frameworks/play/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/play/test.expected +++ b/java/ql/test/library-tests/frameworks/play/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/play/test.ql b/java/ql/test/library-tests/frameworks/play/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/play/test.ql +++ b/java/ql/test/library-tests/frameworks/play/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.expected b/java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.expected +++ b/java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.ql b/java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.ql index 47cc6b07ad2..0adb5a87783 100644 --- a/java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.ql +++ b/java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.ql @@ -11,10 +11,4 @@ module Config implements DataFlow::ConfigSig { } } -module Flow = TaintTracking::Global<Config>; - -class HasFlowTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { Flow::flow(src, sink) } -} +import TaintFlowTest<Config> diff --git a/java/ql/test/library-tests/frameworks/ratpack/flow.expected b/java/ql/test/library-tests/frameworks/ratpack/flow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/ratpack/flow.expected +++ b/java/ql/test/library-tests/frameworks/ratpack/flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/ratpack/flow.ql b/java/ql/test/library-tests/frameworks/ratpack/flow.ql index dae21e78f7c..eab631f0589 100644 --- a/java/ql/test/library-tests/frameworks/ratpack/flow.ql +++ b/java/ql/test/library-tests/frameworks/ratpack/flow.ql @@ -15,12 +15,4 @@ module Config implements DataFlow::ConfigSig { } } -module Flow = TaintTracking::Global<Config>; - -class HasFlowTest extends InlineFlowTest { - HasFlowTest() { this = "HasFlowTest" } - - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { Flow::flow(src, sink) } -} +import TaintFlowTest<Config> diff --git a/java/ql/test/library-tests/frameworks/retrofit/test.expected b/java/ql/test/library-tests/frameworks/retrofit/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/retrofit/test.expected +++ b/java/ql/test/library-tests/frameworks/retrofit/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/retrofit/test.ql b/java/ql/test/library-tests/frameworks/retrofit/test.ql index e09f1ed41d7..0abbff1f958 100644 --- a/java/ql/test/library-tests/frameworks/retrofit/test.ql +++ b/java/ql/test/library-tests/frameworks/retrofit/test.ql @@ -10,8 +10,4 @@ module FlowConfig implements DataFlow::ConfigSig { } } -module Flow = DataFlow::Global<FlowConfig>; - -class RetrofitFlowTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { Flow::flow(src, sink) } -} +import FlowTest<FlowConfig, DefaultFlowConfig> diff --git a/java/ql/test/library-tests/frameworks/spring/beans/test.expected b/java/ql/test/library-tests/frameworks/spring/beans/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/beans/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/beans/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/beans/test.ql b/java/ql/test/library-tests/frameworks/spring/beans/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/beans/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/beans/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/cache/test.expected b/java/ql/test/library-tests/frameworks/spring/cache/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/cache/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/cache/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/cache/test.ql b/java/ql/test/library-tests/frameworks/spring/cache/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/cache/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/cache/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/context/flow.expected b/java/ql/test/library-tests/frameworks/spring/context/flow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/context/flow.expected +++ b/java/ql/test/library-tests/frameworks/spring/context/flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/context/flow.ql b/java/ql/test/library-tests/frameworks/spring/context/flow.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/context/flow.ql +++ b/java/ql/test/library-tests/frameworks/spring/context/flow.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/controller/test.expected b/java/ql/test/library-tests/frameworks/spring/controller/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/controller/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/controller/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/controller/test.ql b/java/ql/test/library-tests/frameworks/spring/controller/test.ql index b6beb8e1e75..35b3d064e5a 100644 --- a/java/ql/test/library-tests/frameworks/spring/controller/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/controller/test.ql @@ -10,10 +10,4 @@ module ValueFlowConfig implements DataFlow::ConfigSig { } } -module ValueFlow = DataFlow::Global<ValueFlowConfig>; - -class Test extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { - ValueFlow::flow(src, sink) - } -} +import FlowTest<ValueFlowConfig, DefaultFlowConfig> diff --git a/java/ql/test/library-tests/frameworks/spring/data/test.expected b/java/ql/test/library-tests/frameworks/spring/data/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/data/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/data/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/data/test.ql b/java/ql/test/library-tests/frameworks/spring/data/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/data/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/data/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/http/flow.expected b/java/ql/test/library-tests/frameworks/spring/http/flow.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/http/flow.expected +++ b/java/ql/test/library-tests/frameworks/spring/http/flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/http/flow.ql b/java/ql/test/library-tests/frameworks/spring/http/flow.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/http/flow.ql +++ b/java/ql/test/library-tests/frameworks/spring/http/flow.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/ui/test.expected b/java/ql/test/library-tests/frameworks/spring/ui/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/ui/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/ui/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/ui/test.ql b/java/ql/test/library-tests/frameworks/spring/ui/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/ui/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/ui/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/util/test.expected b/java/ql/test/library-tests/frameworks/spring/util/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/util/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/util/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/util/test.ql b/java/ql/test/library-tests/frameworks/spring/util/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/util/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/util/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/validation/test.expected b/java/ql/test/library-tests/frameworks/spring/validation/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/validation/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/validation/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/validation/test.ql b/java/ql/test/library-tests/frameworks/spring/validation/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/validation/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/validation/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/webmultipart/test.expected b/java/ql/test/library-tests/frameworks/spring/webmultipart/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/webmultipart/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/webmultipart/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/webmultipart/test.ql b/java/ql/test/library-tests/frameworks/spring/webmultipart/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/webmultipart/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/webmultipart/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/spring/webutil/test.expected b/java/ql/test/library-tests/frameworks/spring/webutil/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/spring/webutil/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/webutil/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/webutil/test.ql b/java/ql/test/library-tests/frameworks/spring/webutil/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/spring/webutil/test.ql +++ b/java/ql/test/library-tests/frameworks/spring/webutil/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/stapler/test.expected b/java/ql/test/library-tests/frameworks/stapler/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/stapler/test.expected +++ b/java/ql/test/library-tests/frameworks/stapler/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/stapler/test.ql b/java/ql/test/library-tests/frameworks/stapler/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/stapler/test.ql +++ b/java/ql/test/library-tests/frameworks/stapler/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/stream/test.expected b/java/ql/test/library-tests/frameworks/stream/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/stream/test.expected +++ b/java/ql/test/library-tests/frameworks/stream/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/stream/test.ql b/java/ql/test/library-tests/frameworks/stream/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/stream/test.ql +++ b/java/ql/test/library-tests/frameworks/stream/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/frameworks/thymeleaf/test.expected b/java/ql/test/library-tests/frameworks/thymeleaf/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/frameworks/thymeleaf/test.expected +++ b/java/ql/test/library-tests/frameworks/thymeleaf/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/frameworks/thymeleaf/test.ql b/java/ql/test/library-tests/frameworks/thymeleaf/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/frameworks/thymeleaf/test.ql +++ b/java/ql/test/library-tests/frameworks/thymeleaf/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/logging/test.expected b/java/ql/test/library-tests/logging/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/logging/test.expected +++ b/java/ql/test/library-tests/logging/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/logging/test.ql b/java/ql/test/library-tests/logging/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/logging/test.ql +++ b/java/ql/test/library-tests/logging/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/optional/test.expected b/java/ql/test/library-tests/optional/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/optional/test.expected +++ b/java/ql/test/library-tests/optional/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/optional/test.ql b/java/ql/test/library-tests/optional/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/optional/test.ql +++ b/java/ql/test/library-tests/optional/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/paths/test.expected b/java/ql/test/library-tests/paths/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/paths/test.expected +++ b/java/ql/test/library-tests/paths/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/paths/test.ql b/java/ql/test/library-tests/paths/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/paths/test.ql +++ b/java/ql/test/library-tests/paths/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/pathsanitizer/test.expected b/java/ql/test/library-tests/pathsanitizer/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/pathsanitizer/test.expected +++ b/java/ql/test/library-tests/pathsanitizer/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/pathsanitizer/test.ql b/java/ql/test/library-tests/pathsanitizer/test.ql index cefce3276e6..0a20ad012b9 100644 --- a/java/ql/test/library-tests/pathsanitizer/test.ql +++ b/java/ql/test/library-tests/pathsanitizer/test.ql @@ -10,12 +10,4 @@ module PathSanitizerConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof PathInjectionSanitizer } } -module PathSanitizerFlow = TaintTracking::Global<PathSanitizerConfig>; - -class Test extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - PathSanitizerFlow::flow(src, sink) - } -} +import TaintFlowTest<PathSanitizerConfig> diff --git a/java/ql/test/library-tests/regex/test.expected b/java/ql/test/library-tests/regex/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/regex/test.expected +++ b/java/ql/test/library-tests/regex/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/regex/test.ql b/java/ql/test/library-tests/regex/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/regex/test.ql +++ b/java/ql/test/library-tests/regex/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/library-tests/scanner/test.expected b/java/ql/test/library-tests/scanner/test.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/library-tests/scanner/test.expected +++ b/java/ql/test/library-tests/scanner/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/library-tests/scanner/test.ql b/java/ql/test/library-tests/scanner/test.ql index 5d91e4e8e26..aca87429a3a 100644 --- a/java/ql/test/library-tests/scanner/test.ql +++ b/java/ql/test/library-tests/scanner/test.ql @@ -1,2 +1,3 @@ import java import TestUtilities.InlineFlowTest +import DefaultFlowTest diff --git a/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.expected b/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.ql b/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.ql index 73a41b1bd8e..a2707b5df44 100644 --- a/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.ql @@ -8,10 +8,4 @@ private class TestSource extends RemoteFlowSource { override string getSourceType() { result = "test source" } } -private class LogInjectionTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - LogInjectionFlow::flow(src, sink) - } -} +import TaintFlowTest<LogInjectionConfig> diff --git a/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.expected b/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.expected +++ b/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.ql b/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.ql index d90039cf920..86feb7843ce 100644 --- a/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.ql +++ b/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.ql @@ -1,11 +1,4 @@ import java import TestUtilities.InlineFlowTest import semmle.code.java.security.IntentUriPermissionManipulationQuery - -class IntentUriPermissionManipulationTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - IntentUriPermissionManipulationFlow::flow(src, sink) - } -} +import TaintFlowTest<IntentUriPermissionManipulationConfig> diff --git a/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.expected b/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.expected +++ b/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.ql b/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.ql index 55c07bbd301..ae1258a66c5 100644 --- a/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.ql +++ b/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.ql @@ -1,11 +1,4 @@ import java import TestUtilities.InlineFlowTest import semmle.code.java.security.UnsafeContentUriResolutionQuery - -class Test extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - UnsafeContentResolutionFlow::flow(src, sink) - } -} +import TaintFlowTest<UnsafeContentResolutionConfig> diff --git a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.expected b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.expected +++ b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.ql b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.ql index 2771dd3af90..a1cff04f4c6 100644 --- a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.ql @@ -1,11 +1,4 @@ import java import semmle.code.java.security.FragmentInjectionQuery import TestUtilities.InlineFlowTest - -class Test extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - FragmentInjectionTaintFlow::flow(src, sink) - } -} +import TaintFlowTest<FragmentInjectionTaintConfig> diff --git a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.expected b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.expected +++ b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql index 5bd19fb5b9e..99ac3d4e03c 100644 --- a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql +++ b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql @@ -1,11 +1,4 @@ import java import TestUtilities.InlineFlowTest import semmle.code.java.security.WebviewDebuggingEnabledQuery - -class HasFlowTest extends InlineFlowTest { - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { - WebviewDebugEnabledFlow::flow(src, sink) - } -} +import ValueFlowTest<WebviewDebugEnabledConfig> diff --git a/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.expected b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.expected +++ b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql index 5de153a9e35..389cff934a9 100644 --- a/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql +++ b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql @@ -1,11 +1,4 @@ import java import TestUtilities.InlineFlowTest import semmle.code.java.security.SensitiveLoggingQuery - -class HasFlowTest extends InlineFlowTest { - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - SensitiveLoggerFlow::flow(src, sink) - } - - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } -} +import TaintFlowTest<SensitiveLoggerConfig> diff --git a/java/ql/test/query-tests/security/CWE-611/XXE.expected b/java/ql/test/query-tests/security/CWE-611/XXE.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-611/XXE.expected +++ b/java/ql/test/query-tests/security/CWE-611/XXE.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-611/XXE.ql b/java/ql/test/query-tests/security/CWE-611/XXE.ql index f1463f561f3..ed12823a6bb 100644 --- a/java/ql/test/query-tests/security/CWE-611/XXE.ql +++ b/java/ql/test/query-tests/security/CWE-611/XXE.ql @@ -1,11 +1,4 @@ import java import TestUtilities.InlineFlowTest import semmle.code.java.security.XxeRemoteQuery - -class HasFlowTest extends InlineFlowTest { - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - XxeFlow::flow(src, sink) - } - - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } -} +import TaintFlowTest<XxeConfig> diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.expected b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.expected +++ b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql index 01af77284f0..c1bc2049c76 100644 --- a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql +++ b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql @@ -2,11 +2,4 @@ import java import TestUtilities.InlineExpectationsTest import TestUtilities.InlineFlowTest import semmle.code.java.security.RsaWithoutOaepQuery - -class HasFlowTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - RsaWithoutOaepFlow::flow(src, sink) - } -} +import TaintFlowTest<RsaWithoutOaepConfig> diff --git a/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.expected b/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.expected index e69de29bb2d..48de9172b36 100644 --- a/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.expected +++ b/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.ql b/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.ql index 0f1864398b4..cf7e46b6e8e 100644 --- a/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.ql +++ b/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.ql @@ -2,11 +2,4 @@ import java import semmle.code.java.security.AndroidSensitiveCommunicationQuery import TestUtilities.InlineExpectationsTest import TestUtilities.InlineFlowTest - -class HasFlowTest extends InlineFlowTest { - override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - - override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - SensitiveCommunicationFlow::flow(src, sink) - } -} +import TaintFlowTest<SensitiveCommunicationConfig> From d82c3ce11ac9efdab8e2d835fa5ca40cff41fda4 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Wed, 14 Jun 2023 18:07:57 +0200 Subject: [PATCH 591/739] Ruby: Rewrite `InlineFlowTest` as a parameterized module --- .../2023-06-14-insecure-download-config.md | 4 + .../ruby/security/InsecureDownloadQuery.qll | 29 ++++- .../security/cwe-829/InsecureDownload.ql | 6 +- ruby/ql/test/TestUtilities/InlineFlowTest.qll | 113 ++++++++---------- .../dataflow/array-flow/array-flow.expected | 1 + .../dataflow/array-flow/array-flow.ql | 5 +- .../call-sensitivity.expected | 1 + .../call-sensitivity/call-sensitivity.ql | 7 +- .../flow-summaries/semantics.expected | 1 + .../dataflow/flow-summaries/semantics.ql | 1 + .../dataflow/global/Flow.expected | 1 + .../library-tests/dataflow/global/Flow.ql | 7 +- .../dataflow/hash-flow/hash-flow.expected | 1 + .../dataflow/hash-flow/hash-flow.ql | 9 +- .../dataflow/local/InlineFlowTest.expected | 1 + .../dataflow/local/InlineFlowTest.ql | 5 +- .../dataflow/params/params-flow.expected | 1 + .../dataflow/params/params-flow.ql | 9 +- .../pathname-flow/pathame-flow.expected | 1 + .../dataflow/pathname-flow/pathame-flow.ql | 5 +- .../dataflow/ssa-flow/ssa-flow.expected | 1 + .../dataflow/ssa-flow/ssa-flow.ql | 5 +- .../dataflow/string-flow/string-flow.expected | 1 + .../dataflow/string-flow/string-flow.ql | 5 +- .../dataflow/summaries/Summaries.expected | 1 + .../dataflow/summaries/Summaries.ql | 22 ++-- .../action_controller/params-flow.expected | 1 + .../action_controller/params-flow.ql | 14 ++- .../action_mailer/params-flow.expected | 1 + .../frameworks/action_mailer/params-flow.ql | 14 ++- .../ActiveSupportDataFlow.expected | 1 + .../active_support/ActiveSupportDataFlow.ql | 5 +- .../frameworks/arel/Arel.expected | 1 + .../library-tests/frameworks/arel/Arel.ql | 5 +- .../frameworks/json/JsonDataFlow.expected | 1 + .../frameworks/json/JsonDataFlow.ql | 1 + .../frameworks/sinatra/Flow.expected | 1 + .../library-tests/frameworks/sinatra/Flow.ql | 12 +- .../cwe-829/InsecureDownload.expected | 1 + .../security/cwe-829/InsecureDownload.ql | 27 +++-- 40 files changed, 188 insertions(+), 140 deletions(-) create mode 100644 ruby/ql/lib/change-notes/2023-06-14-insecure-download-config.md diff --git a/ruby/ql/lib/change-notes/2023-06-14-insecure-download-config.md b/ruby/ql/lib/change-notes/2023-06-14-insecure-download-config.md new file mode 100644 index 00000000000..6bf019cd051 --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-06-14-insecure-download-config.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The `Configuration` taint flow configuration class from `codeql.ruby.security.InsecureDownloadQuery` has been deprecated. Use the `Flow` module instead. diff --git a/ruby/ql/lib/codeql/ruby/security/InsecureDownloadQuery.qll b/ruby/ql/lib/codeql/ruby/security/InsecureDownloadQuery.qll index b701a3d1dd4..0b4c63f4392 100644 --- a/ruby/ql/lib/codeql/ruby/security/InsecureDownloadQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/InsecureDownloadQuery.qll @@ -13,7 +13,7 @@ import InsecureDownloadCustomizations::InsecureDownload /** * A taint tracking configuration for download of sensitive file through insecure connection. */ -class Configuration extends DataFlow::Configuration { +deprecated class Configuration extends DataFlow::Configuration { Configuration() { this = "InsecureDownload" } override predicate isSource(DataFlow::Node source, DataFlow::FlowState label) { @@ -29,3 +29,30 @@ class Configuration extends DataFlow::Configuration { node instanceof Sanitizer } } + +/** + * A taint tracking configuration for download of sensitive file through insecure connection. + */ +module Config implements DataFlow::StateConfigSig { + class FlowState = string; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState label) { + source.(Source).getALabel() = label + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState label) { + sink.(Sink).getALabel() = label + } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isBarrier(DataFlow::Node node, FlowState state) { none() } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 + ) { + none() + } +} + +module Flow = DataFlow::GlobalWithState<Config>; diff --git a/ruby/ql/src/queries/security/cwe-829/InsecureDownload.ql b/ruby/ql/src/queries/security/cwe-829/InsecureDownload.ql index b5f2610ae2e..cdd494134a5 100644 --- a/ruby/ql/src/queries/security/cwe-829/InsecureDownload.ql +++ b/ruby/ql/src/queries/security/cwe-829/InsecureDownload.ql @@ -14,9 +14,9 @@ import codeql.ruby.AST import codeql.ruby.DataFlow import codeql.ruby.security.InsecureDownloadQuery -import DataFlow::PathGraph +import Flow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from Flow::PathNode source, Flow::PathNode sink +where Flow::flowPath(source, sink) select sink.getNode(), source, sink, "$@ of sensitive file from $@.", sink.getNode().(Sink).getDownloadCall(), "Download", source.getNode(), "HTTP source" diff --git a/ruby/ql/test/TestUtilities/InlineFlowTest.qll b/ruby/ql/test/TestUtilities/InlineFlowTest.qll index d653a3e414e..af83862803c 100644 --- a/ruby/ql/test/TestUtilities/InlineFlowTest.qll +++ b/ruby/ql/test/TestUtilities/InlineFlowTest.qll @@ -4,10 +4,11 @@ * Example for a test.ql: * ```ql * import TestUtilities.InlineFlowTest + * import DefaultFlowTest * import PathGraph * - * from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf - * where conf.hasFlowPath(source, sink) + * from ValueFlow::PathNode source, ValueFlow::PathNode sink + * where ValueFlow::flowPath(source, sink) * select sink, source, sink, "$@", source, source.toString() * ``` * @@ -20,14 +21,10 @@ * sink(t); // $ hasTaintFlow=2 * ``` * - * If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows: - * ```ql - * class HasFlowTest extends InlineFlowTest { - * override DataFlow::Configuration getTaintFlowConfig() { none() } - * - * override DataFlow::Configuration getValueFlowConfig() { none() } - * } - * ``` + * If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import + * `ValueFlowTest<DefaultFlowConfig>`. Similarly, if you are only interested in taint flow, then instead of + * importing `DefaultFlowTest`, you can import `TaintFlowTest<DefaultFlowConfig>`. In both cases + * `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`. * * If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`. */ @@ -38,72 +35,62 @@ import codeql.ruby.TaintTracking import TestUtilities.InlineExpectationsTest import TestUtilities.InlineFlowTestUtil -class DefaultValueFlowConf extends DataFlow::Configuration { - DefaultValueFlowConf() { this = "qltest:defaultValueFlowConf" } +module DefaultFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { defaultSource(source) } - override predicate isSource(DataFlow::Node n) { defaultSource(n) } + predicate isSink(DataFlow::Node sink) { defaultSink(sink) } - override predicate isSink(DataFlow::Node n) { defaultSink(n) } - - override int fieldFlowBranchLimit() { result = 1000 } + int fieldFlowBranchLimit() { result = 1000 } } -class DefaultTaintFlowConf extends TaintTracking::Configuration { - DefaultTaintFlowConf() { this = "qltest:defaultTaintFlowConf" } +private module NoFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { none() } - override predicate isSource(DataFlow::Node n) { defaultSource(n) } - - override predicate isSink(DataFlow::Node n) { defaultSink(n) } - - override int fieldFlowBranchLimit() { result = 1000 } + predicate isSink(DataFlow::Node sink) { none() } } -class InlineFlowTest extends InlineExpectationsTest { - InlineFlowTest() { this = "HasFlowTest" } +module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> { + module ValueFlow = DataFlow::Global<ValueFlowConfig>; - override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + module TaintFlow = TaintTracking::Global<TaintFlowConfig>; - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "hasValueFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | this.getValueFlowConfig().hasFlow(src, sink) | - sink.getLocation() = location and - element = sink.toString() and - if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" - ) - or - tag = "hasTaintFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | - this.getTaintFlowConfig().hasFlow(src, sink) and - not this.getValueFlowConfig().hasFlow(src, sink) - | - sink.getLocation() = location and - element = sink.toString() and - if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" - ) - } + private module InlineTest implements TestSig { + string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } - DataFlow::Configuration getValueFlowConfig() { result = any(DefaultValueFlowConf config) } - - DataFlow::Configuration getTaintFlowConfig() { result = any(DefaultTaintFlowConf config) } -} - -module PathGraph { - private import DataFlow::PathGraph as PG - - private class PathNode extends DataFlow::PathNode { - PathNode() { - this.getConfiguration() = - [any(InlineFlowTest t).getValueFlowConfig(), any(InlineFlowTest t).getTaintFlowConfig()] + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasValueFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) + or + tag = "hasTaintFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | + TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink) + | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) } } - /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { PG::edges(a, b) } + import MakeTest<InlineTest> + import DataFlow::MergePathGraph<ValueFlow::PathNode, TaintFlow::PathNode, ValueFlow::PathGraph, TaintFlow::PathGraph> - /** Holds if `n` is a node in the graph of data flow path explanations. */ - query predicate nodes(PathNode n, string key, string val) { PG::nodes(n, key, val) } - - query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { - PG::subpaths(arg, par, ret, out) + predicate flowPath(PathNode source, PathNode sink) { + ValueFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) or + TaintFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) } } + +module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>; + +module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> { + import FlowTest<ValueFlowConfig, NoFlowConfig> +} + +module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> { + import FlowTest<NoFlowConfig, TaintFlowConfig> +} diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected index d258253537a..b406f9feecb 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | array_flow.rb:2:5:2:5 | a [element 0] | array_flow.rb:3:10:3:10 | a [element 0] | | array_flow.rb:2:5:2:5 | a [element 0] | array_flow.rb:3:10:3:10 | a [element 0] | diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.ql b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.ql index 0c4597b8f07..dfd6242a414 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.ql +++ b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.ql @@ -4,8 +4,9 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest +import DefaultFlowTest import PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf -where conf.hasFlowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.expected b/ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.expected index 58d5861bae9..a3ea8f01feb 100644 --- a/ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.expected +++ b/ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.expected @@ -1,4 +1,5 @@ failures +testFailures edges | call_sensitivity.rb:9:7:9:13 | call to taint | call_sensitivity.rb:9:6:9:14 | ( ... ) | | call_sensitivity.rb:9:7:9:13 | call to taint | call_sensitivity.rb:9:6:9:14 | ( ... ) | diff --git a/ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.ql b/ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.ql index 6403c4b04c2..08c0fa8fc45 100644 --- a/ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.ql +++ b/ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.ql @@ -5,13 +5,14 @@ import codeql.ruby.AST import codeql.ruby.DataFlow import TestUtilities.InlineFlowTest -import DataFlow::PathGraph +import DefaultFlowTest +import PathGraph import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch query predicate mayBenefitFromCallContext = DataFlowDispatch::mayBenefitFromCallContext/2; query predicate viableImplInCallContext = DataFlowDispatch::viableImplInCallContext/2; -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf -where conf.hasFlowPath(source, sink) +from TaintFlow::PathNode source, TaintFlow::PathNode sink +where TaintFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected index fc781f05d3c..b3e010e86b6 100644 --- a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected +++ b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected @@ -1,4 +1,5 @@ failures +testFailures edges | semantics.rb:2:5:2:5 | a | semantics.rb:3:9:3:9 | a | | semantics.rb:2:5:2:5 | a | semantics.rb:3:9:3:9 | a | diff --git a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.ql b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.ql index 9733e0c5393..c3c2e45322a 100644 --- a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.ql +++ b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.ql @@ -5,6 +5,7 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest +import DefaultFlowTest import PathGraph private import codeql.ruby.dataflow.FlowSummary diff --git a/ruby/ql/test/library-tests/dataflow/global/Flow.expected b/ruby/ql/test/library-tests/dataflow/global/Flow.expected index 63359aa9a36..5ddbe3ce98c 100644 --- a/ruby/ql/test/library-tests/dataflow/global/Flow.expected +++ b/ruby/ql/test/library-tests/dataflow/global/Flow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | captured_variables.rb:1:24:1:24 | x | captured_variables.rb:2:20:2:20 | x | | captured_variables.rb:1:24:1:24 | x | captured_variables.rb:2:20:2:20 | x | diff --git a/ruby/ql/test/library-tests/dataflow/global/Flow.ql b/ruby/ql/test/library-tests/dataflow/global/Flow.ql index 33825f765c2..64ce30508fb 100644 --- a/ruby/ql/test/library-tests/dataflow/global/Flow.ql +++ b/ruby/ql/test/library-tests/dataflow/global/Flow.ql @@ -5,8 +5,9 @@ import codeql.ruby.AST import codeql.ruby.DataFlow private import TestUtilities.InlineFlowTest -import DataFlow::PathGraph +import DefaultFlowTest +import PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf -where conf.hasFlowPath(source, sink) +from TaintFlow::PathNode source, TaintFlow::PathNode sink +where TaintFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected index fff890f80b9..7be100aa1fe 100644 --- a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | hash_flow.rb:10:5:10:8 | hash [element 0] | hash_flow.rb:30:10:30:13 | hash [element 0] | | hash_flow.rb:10:5:10:8 | hash [element :a] | hash_flow.rb:22:10:22:13 | hash [element :a] | diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.ql b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.ql index bb1b611d7fc..31941897936 100644 --- a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.ql +++ b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.ql @@ -4,12 +4,9 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest +import ValueFlowTest<DefaultFlowConfig> import PathGraph -class HasFlowTest extends InlineFlowTest { - override DataFlow::Configuration getTaintFlowConfig() { none() } -} - -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf -where conf.hasFlowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.expected b/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.expected index b5ad38dfcbb..d979e6f052a 100644 --- a/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.expected +++ b/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.expected @@ -1,4 +1,5 @@ failures +testFailures edges | local_dataflow.rb:78:3:78:3 | z | local_dataflow.rb:89:8:89:8 | z | | local_dataflow.rb:78:12:78:20 | call to source | local_dataflow.rb:79:13:79:13 | b | diff --git a/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.ql b/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.ql index 4f6740c7e17..9a5ca73aa12 100644 --- a/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.ql +++ b/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.ql @@ -4,8 +4,9 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest +import DefaultFlowTest import PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf -where conf.hasFlowPath(source, sink) +from TaintFlow::PathNode source, TaintFlow::PathNode sink +where TaintFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected index cd2d1c87b28..b54948d17a4 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | params_flow.rb:9:16:9:17 | p1 | params_flow.rb:10:10:10:11 | p1 | | params_flow.rb:9:20:9:21 | p2 | params_flow.rb:11:10:11:11 | p2 | diff --git a/ruby/ql/test/library-tests/dataflow/params/params-flow.ql b/ruby/ql/test/library-tests/dataflow/params/params-flow.ql index bb1b611d7fc..31941897936 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params-flow.ql +++ b/ruby/ql/test/library-tests/dataflow/params/params-flow.ql @@ -4,12 +4,9 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest +import ValueFlowTest<DefaultFlowConfig> import PathGraph -class HasFlowTest extends InlineFlowTest { - override DataFlow::Configuration getTaintFlowConfig() { none() } -} - -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf -where conf.hasFlowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected index 37a7d126193..44fc7a3d3d9 100644 --- a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | pathname_flow.rb:4:5:4:6 | pn | pathname_flow.rb:5:10:5:11 | pn | | pathname_flow.rb:4:10:4:33 | call to new | pathname_flow.rb:4:5:4:6 | pn | diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql index 0c4597b8f07..dfd6242a414 100644 --- a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql @@ -4,8 +4,9 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest +import DefaultFlowTest import PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf -where conf.hasFlowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/ssa-flow/ssa-flow.expected b/ruby/ql/test/library-tests/dataflow/ssa-flow/ssa-flow.expected index e1e2893fad6..744c508f33f 100644 --- a/ruby/ql/test/library-tests/dataflow/ssa-flow/ssa-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/ssa-flow/ssa-flow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | ssa_flow.rb:12:9:12:9 | [post] a [element 0] | ssa_flow.rb:16:10:16:10 | a [element 0] | | ssa_flow.rb:12:9:12:9 | [post] a [element 0] | ssa_flow.rb:16:10:16:10 | a [element 0] | diff --git a/ruby/ql/test/library-tests/dataflow/ssa-flow/ssa-flow.ql b/ruby/ql/test/library-tests/dataflow/ssa-flow/ssa-flow.ql index 0c4597b8f07..dfd6242a414 100644 --- a/ruby/ql/test/library-tests/dataflow/ssa-flow/ssa-flow.ql +++ b/ruby/ql/test/library-tests/dataflow/ssa-flow/ssa-flow.ql @@ -4,8 +4,9 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest +import DefaultFlowTest import PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf -where conf.hasFlowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected b/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected index 4cab79b9e42..57eb688e6af 100644 --- a/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected @@ -1,4 +1,5 @@ failures +testFailures | string_flow.rb:85:10:85:10 | a | Unexpected result: hasValueFlow=a | | string_flow.rb:227:10:227:10 | a | Unexpected result: hasValueFlow=a | edges diff --git a/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.ql b/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.ql index 0c4597b8f07..dfd6242a414 100644 --- a/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.ql +++ b/ruby/ql/test/library-tests/dataflow/string-flow/string-flow.ql @@ -4,8 +4,9 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest +import DefaultFlowTest import PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf -where conf.hasFlowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected index eb990f9ab27..0597947595a 100644 --- a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected +++ b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected @@ -1,4 +1,5 @@ failures +testFailures edges | summaries.rb:1:1:1:7 | tainted | summaries.rb:2:6:2:12 | tainted | | summaries.rb:1:1:1:7 | tainted | summaries.rb:2:6:2:12 | tainted | diff --git a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql index b59862d0e5a..11145ed991c 100644 --- a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql +++ b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql @@ -10,7 +10,7 @@ import codeql.ruby.dataflow.internal.FlowSummaryImpl import codeql.ruby.dataflow.internal.AccessPathSyntax import codeql.ruby.frameworks.data.ModelsAsData import TestUtilities.InlineFlowTest -import DataFlow::PathGraph +import PathGraph query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) { (sc.propagatesFlowExt(s, _, _) or sc.propagatesFlowExt(_, s, _)) and @@ -149,22 +149,18 @@ private class SinkFromModel extends ModelInput::SinkModelCsv { } } -class CustomValueSink extends DefaultValueFlowConf { - override predicate isSink(DataFlow::Node sink) { - super.isSink(sink) +module CustomConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { DefaultFlowConfig::isSource(source) } + + predicate isSink(DataFlow::Node sink) { + DefaultFlowConfig::isSink(sink) or sink = ModelOutput::getASinkNode("test-sink").asSink() } } -class CustomTaintSink extends DefaultTaintFlowConf { - override predicate isSink(DataFlow::Node sink) { - super.isSink(sink) - or - sink = ModelOutput::getASinkNode("test-sink").asSink() - } -} +import FlowTest<CustomConfig, CustomConfig> -from DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Configuration conf -where conf.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected b/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected index 2fb3829dd40..d9b6f59f4af 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected +++ b/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected @@ -1,4 +1,5 @@ failures +testFailures | filter_flow.rb:21:10:21:13 | @foo | Unexpected result: hasTaintFlow= | | filter_flow.rb:38:10:38:13 | @foo | Unexpected result: hasTaintFlow= | | filter_flow.rb:55:10:55:13 | @foo | Unexpected result: hasTaintFlow= | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.ql b/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.ql index 412ba5534b8..1e4e66c5584 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.ql +++ b/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.ql @@ -7,12 +7,14 @@ import TestUtilities.InlineFlowTest import PathGraph import codeql.ruby.frameworks.Rails -class ParamsTaintFlowConf extends DefaultTaintFlowConf { - override predicate isSource(DataFlow::Node n) { - n.asExpr().getExpr() instanceof Rails::ParamsCall - } +module ParamsTaintFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr().getExpr() instanceof Rails::ParamsCall } + + predicate isSink(DataFlow::Node n) { DefaultFlowConfig::isSink(n) } } -from DataFlow::PathNode source, DataFlow::PathNode sink, ParamsTaintFlowConf conf -where conf.hasFlowPath(source, sink) +import FlowTest<DefaultFlowConfig, ParamsTaintFlowConfig> + +from TaintFlow::PathNode source, TaintFlow::PathNode sink +where TaintFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/action_mailer/params-flow.expected b/ruby/ql/test/library-tests/frameworks/action_mailer/params-flow.expected index 39a6a7b8d8e..11ff425927b 100644 --- a/ruby/ql/test/library-tests/frameworks/action_mailer/params-flow.expected +++ b/ruby/ql/test/library-tests/frameworks/action_mailer/params-flow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | mailer.rb:3:10:3:15 | call to params | mailer.rb:3:10:3:21 | ...[...] | nodes diff --git a/ruby/ql/test/library-tests/frameworks/action_mailer/params-flow.ql b/ruby/ql/test/library-tests/frameworks/action_mailer/params-flow.ql index 412ba5534b8..1e4e66c5584 100644 --- a/ruby/ql/test/library-tests/frameworks/action_mailer/params-flow.ql +++ b/ruby/ql/test/library-tests/frameworks/action_mailer/params-flow.ql @@ -7,12 +7,14 @@ import TestUtilities.InlineFlowTest import PathGraph import codeql.ruby.frameworks.Rails -class ParamsTaintFlowConf extends DefaultTaintFlowConf { - override predicate isSource(DataFlow::Node n) { - n.asExpr().getExpr() instanceof Rails::ParamsCall - } +module ParamsTaintFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr().getExpr() instanceof Rails::ParamsCall } + + predicate isSink(DataFlow::Node n) { DefaultFlowConfig::isSink(n) } } -from DataFlow::PathNode source, DataFlow::PathNode sink, ParamsTaintFlowConf conf -where conf.hasFlowPath(source, sink) +import FlowTest<DefaultFlowConfig, ParamsTaintFlowConfig> + +from TaintFlow::PathNode source, TaintFlow::PathNode sink +where TaintFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected index 7bce95e2b45..7f1f8d6c756 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -1,4 +1,5 @@ failures +testFailures | hash_extensions.rb:126:10:126:19 | call to sole | Unexpected result: hasValueFlow=b | edges | active_support.rb:10:5:10:5 | x | active_support.rb:11:10:11:10 | x | diff --git a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.ql b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.ql index 8a14d5f686e..7c19d2e3904 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.ql +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.ql @@ -5,8 +5,9 @@ import codeql.ruby.AST import TestUtilities.InlineFlowTest import codeql.ruby.Frameworks +import DefaultFlowTest import PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf -where conf.hasFlowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/arel/Arel.expected b/ruby/ql/test/library-tests/frameworks/arel/Arel.expected index d34ccbcb1a1..4fdc2574ccc 100644 --- a/ruby/ql/test/library-tests/frameworks/arel/Arel.expected +++ b/ruby/ql/test/library-tests/frameworks/arel/Arel.expected @@ -1,3 +1,4 @@ failures +testFailures #select | arel.rb:3:8:3:18 | call to sql | arel.rb:2:7:2:14 | call to source | arel.rb:3:8:3:18 | call to sql | $@ | arel.rb:2:7:2:14 | call to source | call to source | diff --git a/ruby/ql/test/library-tests/frameworks/arel/Arel.ql b/ruby/ql/test/library-tests/frameworks/arel/Arel.ql index 01d7b5a5d1c..e1cc2782ceb 100644 --- a/ruby/ql/test/library-tests/frameworks/arel/Arel.ql +++ b/ruby/ql/test/library-tests/frameworks/arel/Arel.ql @@ -5,7 +5,8 @@ import codeql.ruby.frameworks.Arel import codeql.ruby.AST import TestUtilities.InlineFlowTest +import DefaultFlowTest -from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf -where conf.hasFlowPath(source, sink) +from TaintFlow::PathNode source, TaintFlow::PathNode sink +where TaintFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected index db04aefd22f..ad5802c2aae 100644 --- a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | json.rb:1:17:1:26 | call to source | json.rb:1:6:1:27 | call to parse | | json.rb:2:18:2:27 | call to source | json.rb:2:6:2:28 | call to parse! | diff --git a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql index 11a25d33e71..6fe0aeda9b1 100644 --- a/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql +++ b/ruby/ql/test/library-tests/frameworks/json/JsonDataFlow.ql @@ -4,4 +4,5 @@ import TestUtilities.InlineFlowTest import codeql.ruby.Frameworks +import DefaultFlowTest import PathGraph diff --git a/ruby/ql/test/library-tests/frameworks/sinatra/Flow.expected b/ruby/ql/test/library-tests/frameworks/sinatra/Flow.expected index 2ace7832268..a2ea0e9a06e 100644 --- a/ruby/ql/test/library-tests/frameworks/sinatra/Flow.expected +++ b/ruby/ql/test/library-tests/frameworks/sinatra/Flow.expected @@ -1,4 +1,5 @@ failures +testFailures | views/index.erb:2:10:2:12 | call to foo | Unexpected result: hasTaintFlow= | edges | app.rb:75:5:75:8 | [post] self [@foo] | app.rb:76:32:76:35 | self [@foo] | diff --git a/ruby/ql/test/library-tests/frameworks/sinatra/Flow.ql b/ruby/ql/test/library-tests/frameworks/sinatra/Flow.ql index d54f73c9144..413511eac08 100644 --- a/ruby/ql/test/library-tests/frameworks/sinatra/Flow.ql +++ b/ruby/ql/test/library-tests/frameworks/sinatra/Flow.ql @@ -8,12 +8,16 @@ import PathGraph import codeql.ruby.frameworks.Sinatra import codeql.ruby.Concepts -class SinatraConf extends DefaultTaintFlowConf { - override predicate isSource(DataFlow::Node source) { +module SinatraConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Http::Server::RequestInputAccess::Range } + + predicate isSink(DataFlow::Node sink) { DefaultFlowConfig::isSink(sink) } } -from DataFlow::PathNode source, DataFlow::PathNode sink, SinatraConf conf -where conf.hasFlowPath(source, sink) +import FlowTest<DefaultFlowConfig, SinatraConfig> + +from TaintFlow::PathNode source, TaintFlow::PathNode sink +where TaintFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected b/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected index 6e30aeeb235..82fbafcfc89 100644 --- a/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected +++ b/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected @@ -18,6 +18,7 @@ nodes | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | semmle.label | "http://example.org/unsafe.unk..." | | insecure_download.rb:53:65:53:78 | "/myscript.sh" | semmle.label | "/myscript.sh" | subpaths +testFailures #select | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | "http://example.org/unsafe.APK" | | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | "http://example.org/unsafe.APK" | diff --git a/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.ql b/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.ql index 8690a0ec120..ab9ce62a21c 100644 --- a/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.ql +++ b/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.ql @@ -1,22 +1,25 @@ import codeql.ruby.AST import codeql.ruby.DataFlow -import PathGraph -import TestUtilities.InlineFlowTest import codeql.ruby.security.InsecureDownloadQuery +import Flow::PathGraph +import TestUtilities.InlineExpectationsTest +import TestUtilities.InlineFlowTestUtil -class FlowTest extends InlineFlowTest { - override DataFlow::Configuration getValueFlowConfig() { result = any(Configuration config) } +module FlowTest implements TestSig { + string getARelevantTag() { result = "BAD" } - override DataFlow::Configuration getTaintFlowConfig() { none() } - - override string getARelevantTag() { result = "BAD" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "BAD" and - super.hasActualResult(location, element, "hasValueFlow", value) + exists(DataFlow::Node src, DataFlow::Node sink | Flow::flow(src, sink) | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) } } -from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration conf -where conf.hasFlowPath(source, sink) +import MakeTest<FlowTest> + +from Flow::PathNode source, Flow::PathNode sink +where Flow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() From 21b55ce0cf9b1c128c010459f5ebb8739b4b42eb Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 15 Jun 2023 12:49:02 +0200 Subject: [PATCH 592/739] stop spuriously matching everything when encountering an unsupported charclass --- shared/regex/codeql/regex/nfa/NfaUtils.qll | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index 3fd4b97c829..5bad1e80727 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -451,7 +451,15 @@ module Make<RegexTreeViewSig TreeImpl> { } bindingset[char] - override predicate matches(string char) { not hasChildThatMatches(cc, char) } + override predicate matches(string char) { + not hasChildThatMatches(cc, char) and + ( + // detect unsupported char classes that doesn't match anything (e.g. `\p{L}` in ruby), and don't report any matches + exists(string c | hasChildThatMatches(cc, c)) + or + not exists(cc.getAChild()) // [^] still matches everything + ) + } } /** @@ -536,7 +544,9 @@ module Make<RegexTreeViewSig TreeImpl> { bindingset[char] override predicate matches(string char) { - not classEscapeMatches(charClass.toLowerCase(), char) + not classEscapeMatches(charClass.toLowerCase(), char) and + // detect unsupported char classes (e.g. `\p{L}` in ruby), and don't report any matches + exists(string c | classEscapeMatches(charClass.toLowerCase(), c)) } } From 087e6d1c15e174c83b7f6bcd0c53cf8cf0546f81 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 15 Jun 2023 13:52:29 +0200 Subject: [PATCH 593/739] fix QL-for-QL warning --- shared/regex/codeql/regex/nfa/NfaUtils.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index 5bad1e80727..b690bfdd5e9 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -455,7 +455,7 @@ module Make<RegexTreeViewSig TreeImpl> { not hasChildThatMatches(cc, char) and ( // detect unsupported char classes that doesn't match anything (e.g. `\p{L}` in ruby), and don't report any matches - exists(string c | hasChildThatMatches(cc, c)) + hasChildThatMatches(cc, _) or not exists(cc.getAChild()) // [^] still matches everything ) @@ -546,7 +546,7 @@ module Make<RegexTreeViewSig TreeImpl> { override predicate matches(string char) { not classEscapeMatches(charClass.toLowerCase(), char) and // detect unsupported char classes (e.g. `\p{L}` in ruby), and don't report any matches - exists(string c | classEscapeMatches(charClass.toLowerCase(), c)) + classEscapeMatches(charClass.toLowerCase(), _) } } From 7dd88ddff647d809ab7b8d0f63cf168b7d64e684 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 13 Jun 2023 14:33:52 +0200 Subject: [PATCH 594/739] C#: Base tests for CWE-011 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-011/options | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-011/options diff --git a/csharp/ql/test/query-tests/Security Features/CWE-011/options b/csharp/ql/test/query-tests/Security Features/CWE-011/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-011/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From 3e8102a0c867d78459748df69f2d7afea547d66a Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 13 Jun 2023 14:40:14 +0200 Subject: [PATCH 595/739] C#: Base tests for CWE-016 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-016/options | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-016/options diff --git a/csharp/ql/test/query-tests/Security Features/CWE-016/options b/csharp/ql/test/query-tests/Security Features/CWE-016/options new file mode 100644 index 00000000000..a5ea8b797c5 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-016/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From d0844bbe6e6f130567291747b3b037dfe76413eb Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 13 Jun 2023 15:02:57 +0200 Subject: [PATCH 596/739] C#: Base tests for CWE-020 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-020/options | 4 +++- csharp/ql/test/resources/stubs/System.Web.cs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-020/options b/csharp/ql/test/query-tests/Security Features/CWE-020/options index 319fd18ddcc..96b0b028bdd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-020/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-020/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:${testdir}/../../../resources/assemblies/System.Web.dll /r:${testdir}/../../../resources/assemblies/System.Web.ApplicationServices.dll /r:${testdir}/../../../resources/assemblies/System.Data.dll /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Data.Common.dll /r:System.Security.Cryptography.X509Certificates.dll /r:System.Runtime.InteropServices.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/resources/stubs/System.Web.cs b/csharp/ql/test/resources/stubs/System.Web.cs index 725b672fbe8..58865f82e6a 100644 --- a/csharp/ql/test/resources/stubs/System.Web.cs +++ b/csharp/ql/test/resources/stubs/System.Web.cs @@ -156,6 +156,7 @@ namespace System.Web public class HttpResponse { public void Write(object o) { } + public void Write(string s) { } public void WriteFile(string s) { } public HttpCookieCollection Cookies => null; public void AddHeader(string name, string value) { } From 47621ca6027ba6679052fd06f7085385941fbe8a Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 09:07:58 +0200 Subject: [PATCH 597/739] C#: Base tests for CWE-022 on stubs. --- .../query-tests/Security Features/CWE-022/TaintedPath/options | 4 +++- .../query-tests/Security Features/CWE-022/ZipSlip/options | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/options b/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/options index 17bfec6a531..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-022/TaintedPath/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.IO.FileSystem.dll /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/options b/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/options index acca6983965..a5ea8b797c5 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-022/ZipSlip/options @@ -1 +1,2 @@ -semmle-extractor-options: /r:System.IO.Compression.dll /r:System.IO.Compression.FileSystem.dll /r:System.IO.Compression.ZipFile.dll /r:System.IO.FileSystem.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From 0d10f5ca2acb5fcf9729cec4fdec1484af370c1c Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 09:19:14 +0200 Subject: [PATCH 598/739] C#: Base tests for CWE-078 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-078/options | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-078/options b/csharp/ql/test/query-tests/Security Features/CWE-078/options index de7d3478af5..7faed1b92ed 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-078/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-078/options @@ -1 +1,2 @@ -semmle-extractor-options: /r:System.ComponentModel.Primitives.dll /r:System.Diagnostics.Process.dll /r:System.Runtime.InteropServices.dll ${testdir}/../../../resources/stubs/System.Data.cs /r:System.Data.Common.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj From b674a8eab751808c949db690c14c026575b676ba Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 12:03:11 +0200 Subject: [PATCH 599/739] C#: Split the StoredXss test from XSS Asp test. Make the former based on stubs. --- .../Security Features/CWE-079/StoredXSS/StoredXSS.cs | 2 -- .../CWE-079/StoredXSS/StoredXSS.expected | 8 ++++---- .../Security Features/CWE-079/StoredXSS/options | 4 +++- .../CWE-079/{StoredXSS => XSSAsp}/AspInline.expected | 4 ++-- .../CWE-079/{StoredXSS => XSSAsp}/AspInline.ql | 0 .../CWE-079/{StoredXSS => XSSAsp}/XSS.cs | 5 +++-- .../CWE-079/{StoredXSS => XSSAsp}/XSS.expected | 4 ++-- .../CWE-079/{StoredXSS => XSSAsp}/XSS.qlref | 0 .../query-tests/Security Features/CWE-079/XSSAsp/options | 1 + .../CWE-079/{StoredXSS => XSSAsp}/script.aspx | 0 10 files changed, 15 insertions(+), 13 deletions(-) rename csharp/ql/test/query-tests/Security Features/CWE-079/{StoredXSS => XSSAsp}/AspInline.expected (66%) rename csharp/ql/test/query-tests/Security Features/CWE-079/{StoredXSS => XSSAsp}/AspInline.ql (100%) rename csharp/ql/test/query-tests/Security Features/CWE-079/{StoredXSS => XSSAsp}/XSS.cs (93%) rename csharp/ql/test/query-tests/Security Features/CWE-079/{StoredXSS => XSSAsp}/XSS.expected (97%) rename csharp/ql/test/query-tests/Security Features/CWE-079/{StoredXSS => XSSAsp}/XSS.qlref (100%) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/options rename csharp/ql/test/query-tests/Security Features/CWE-079/{StoredXSS => XSSAsp}/script.aspx (100%) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.cs b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.cs index 24c4eb73912..1096634b690 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.cs @@ -1,5 +1,3 @@ -// semmle-extractor-options: /r:${testdir}/../../../../resources/assemblies/System.Data.dll /r:${testdir}/../../../../resources/assemblies/System.Web.dll /r:${testdir}/../../../../resources/assemblies/System.Web.Mvc.dll /r:System.ComponentModel.Primitives.dll /r:System.Collections.Specialized.dll /r:${testdir}/../../../../resources/assemblies/System.Net.Http.dll - using System; using System.Data.SqlClient; using System.Web; diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected index bafe7257095..beef5ec2968 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/StoredXSS.expected @@ -1,8 +1,8 @@ edges -| StoredXSS.cs:24:60:24:86 | call to method GetString : String | StoredXSS.cs:24:44:24:86 | ... + ... | +| StoredXSS.cs:22:60:22:86 | call to method GetString : String | StoredXSS.cs:22:44:22:86 | ... + ... | nodes -| StoredXSS.cs:24:44:24:86 | ... + ... | semmle.label | ... + ... | -| StoredXSS.cs:24:60:24:86 | call to method GetString : String | semmle.label | call to method GetString : String | +| StoredXSS.cs:22:44:22:86 | ... + ... | semmle.label | ... + ... | +| StoredXSS.cs:22:60:22:86 | call to method GetString : String | semmle.label | call to method GetString : String | subpaths #select -| StoredXSS.cs:24:44:24:86 | ... + ... | StoredXSS.cs:24:60:24:86 | call to method GetString : String | StoredXSS.cs:24:44:24:86 | ... + ... | This HTML or JavaScript write depends on a $@. | StoredXSS.cs:24:60:24:86 | call to method GetString | stored (potentially user-provided) value | +| StoredXSS.cs:22:44:22:86 | ... + ... | StoredXSS.cs:22:60:22:86 | call to method GetString : String | StoredXSS.cs:22:44:22:86 | ... + ... | This HTML or JavaScript write depends on a $@. | StoredXSS.cs:22:60:22:86 | call to method GetString | stored (potentially user-provided) value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/options b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/options index a95668cbc59..34d9e62e93c 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Net.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.expected b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/AspInline.expected similarity index 66% rename from csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.expected rename to csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/AspInline.expected index d296914aba7..66468b41a68 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/AspInline.expected @@ -1,5 +1,5 @@ -| script.aspx:4:1:4:23 | <%= ... %> | XSS.cs:114:16:114:29 | someJavascript | -| script.aspx:8:1:8:12 | <%= ... %> | XSS.cs:121:24:121:28 | Field | +| script.aspx:4:1:4:23 | <%= ... %> | XSS.cs:115:16:115:29 | someJavascript | +| script.aspx:8:1:8:12 | <%= ... %> | XSS.cs:122:24:122:28 | Field | | script.aspx:12:1:12:14 | <%= ... %> | <outside test directory> | Request | | script.aspx:16:1:16:34 | <%= ... %> | <outside test directory> | QueryString | | script.aspx:20:1:20:41 | <%= ... %> | <outside test directory> | QueryString | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.ql b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/AspInline.ql similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.ql rename to csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/AspInline.ql diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.cs b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/XSS.cs similarity index 93% rename from csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.cs rename to csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/XSS.cs index da82672c6df..1fc8a99e61b 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/XSS.cs @@ -1,4 +1,4 @@ - +// semmle-extractor-options: /r:${testdir}/../../../../resources/assemblies/System.Web.dll /r:${testdir}/../../../../resources/assemblies/System.Web.Mvc.dll /r:System.Collections.Specialized.dll /r:${testdir}/../../../../resources/assemblies/System.Net.Http.dll using System; using System.Net; using System.Net.Http; @@ -102,7 +102,8 @@ namespace Test new StringContent(HttpUtility.HtmlEncode(name)); } - public void UrlEncoded(HttpContextBase context) { + public void UrlEncoded(HttpContextBase context) + { // GOOD: URL encoding string name = context.Request.QueryString["name"]; new StringContent(HttpUtility.UrlEncode(name)); diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.expected b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/XSS.expected similarity index 97% rename from csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.expected rename to csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/XSS.expected index f1f4c631769..4b1440cee4a 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/XSS.expected @@ -56,7 +56,7 @@ nodes | XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | | XSS.cs:94:27:94:61 | access to indexer : String | semmle.label | access to indexer : String | | XSS.cs:95:31:95:34 | access to local variable name | semmle.label | access to local variable name | -| XSS.cs:134:20:134:33 | access to property RawUrl | semmle.label | access to property RawUrl | +| XSS.cs:135:20:135:33 | access to property RawUrl | semmle.label | access to property RawUrl | | script.aspx:12:1:12:14 | <%= ... %> | semmle.label | <%= ... %> | | script.aspx:16:1:16:34 | <%= ... %> | semmle.label | <%= ... %> | | script.aspx:20:1:20:41 | <%= ... %> | semmle.label | <%= ... %> | @@ -72,7 +72,7 @@ subpaths | XSS.cs:86:28:86:31 | access to local variable name | XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:86:28:86:31 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | User-provided value | | XSS.cs:87:31:87:34 | access to local variable name | XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:87:31:87:34 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | User-provided value | | XSS.cs:95:31:95:34 | access to local variable name | XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | XSS.cs:95:31:95:34 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | User-provided value | -| XSS.cs:134:20:134:33 | access to property RawUrl | XSS.cs:134:20:134:33 | access to property RawUrl | XSS.cs:134:20:134:33 | access to property RawUrl | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:134:20:134:33 | access to property RawUrl | User-provided value | +| XSS.cs:135:20:135:33 | access to property RawUrl | XSS.cs:135:20:135:33 | access to property RawUrl | XSS.cs:135:20:135:33 | access to property RawUrl | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:135:20:135:33 | access to property RawUrl | User-provided value | | script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:12:1:12:14 | <%= ... %> | User-provided value | | script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:16:1:16:34 | <%= ... %> | User-provided value | | script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:20:1:20:41 | <%= ... %> | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.qlref b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/XSS.qlref similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.qlref rename to csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/XSS.qlref diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/options b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/options new file mode 100644 index 00000000000..a95668cbc59 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/options @@ -0,0 +1 @@ +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Net.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/script.aspx b/csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/script.aspx similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/script.aspx rename to csharp/ql/test/query-tests/Security Features/CWE-079/XSSAsp/script.aspx From 8e36a880f2a20b14645b2a83c1fe9d241fbfebb3 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 15:36:11 +0200 Subject: [PATCH 600/739] C#: Adjust paths relative to the test directory for CWE-089 test dependencies. --- .../ql/test/query-tests/Security Features/CWE-089/options | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/options b/csharp/ql/test/query-tests/Security Features/CWE-089/options index 036514ceb74..b1124d05dcd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/options @@ -1,6 +1,6 @@ semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/Dapper/2.0.90/Dapper.csproj -semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj -semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/System.Data.SQLite/1.0.116/System.Data.SQLite.csproj +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/Dapper/2.0.90/Dapper.csproj +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SQLite/1.0.116/System.Data.SQLite.csproj semmle-extractor-options: ${testdir}/../../../resources/stubs/EntityFramework.cs semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Windows.cs From f4b5cbf7eb586a61a5f0eeeccf9cafdbdff14e7c Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 14:31:28 +0200 Subject: [PATCH 601/739] C#: Base tests for CWE-090 on stubs. --- .../ql/test/query-tests/Security Features/CWE-090/options | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-090/options b/csharp/ql/test/query-tests/Security Features/CWE-090/options index dfc3914bb98..1a54f1e9c36 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-090/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-090/options @@ -1,2 +1,4 @@ -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs ${testdir}/../../../resources/stubs/System.DirectoryServices.cs /r:System.ComponentModel.Primitives.dll /r:System.Collections.Specialized.dll /r:System.ComponentModel.TypeConverter.dll /r:System.Private.Xml.dll -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Data.cs /r:System.Data.Common.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.DirectoryServices.cs From 7d58a9c3d391e02e1fb9472f33e42211fc52290b Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 15:23:44 +0200 Subject: [PATCH 602/739] C#: Base tests for CWE-091 on stubs. --- .../Security Features/CWE-091/XMLInjection/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-091/XMLInjection/options b/csharp/ql/test/query-tests/Security Features/CWE-091/XMLInjection/options index 5194fddbe4d..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-091/XMLInjection/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-091/XMLInjection/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Private.Xml.dll /r:System.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs From 95fddaebef3ef29cbf722b6942220713d5815c14 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 15:27:25 +0200 Subject: [PATCH 603/739] C#: Base tests for CWE-094 on stubs. --- .../ql/test/query-tests/Security Features/CWE-094/options | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-094/options b/csharp/ql/test/query-tests/Security Features/CWE-094/options index 97b9301f4dc..cce2f114af6 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-094/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-094/options @@ -1 +1,5 @@ -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll ${testdir}/../../../resources/stubs/Microsoft.CSharp.cs /r:System.ComponentModel.Primitives.dll ${testdir}/../../../resources/stubs/System.Windows.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Windows.cs +semmle-extractor-options: ${testdir}/../../../resources/stubs/Microsoft.CSharp.cs From 981468f64e48012d5cfbb97ef4a274c8fdaafd82 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 14 Jun 2023 15:31:00 +0200 Subject: [PATCH 604/739] C#: Base tests for CWE-099 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-099/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-099/options b/csharp/ql/test/query-tests/Security Features/CWE-099/options index 2878eb40d52..6f56ddfc468 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-099/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-099/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Collections.Specialized.dll ${testdir}/../../../resources/stubs/System.Web.cs /r:${testdir}/../../../resources/assemblies/System.Data.dll /r:System.Data.Common.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs From 1b39faadede91de9e810665ff9ed7575fbc768c2 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Thu, 15 Jun 2023 16:20:39 +0200 Subject: [PATCH 605/739] QLDoc correction --- java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll b/java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll index dbccfc99c04..f17090ed307 100644 --- a/java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll +++ b/java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll @@ -99,7 +99,7 @@ private class GenerateResponseMethod extends Method { } } -/** Gets the static type of `e`, or an upper bound of the runtime type of `e`. */ +/** Holds if `t` is the static type of `e`, or an upper bound of the runtime type of `e`. */ private predicate boundOrStaticType(Expr e, RefType t) { exprTypeFlow(e, t, false) or From 3aaa649076d5b7e726452a480588698b62df75a6 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 15 Jun 2023 16:50:42 +0200 Subject: [PATCH 606/739] Exclude `cpp/overrun-write` from `cpp-security-extended.qls` --- cpp/ql/src/codeql-suites/cpp-security-extended.qls | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpp/ql/src/codeql-suites/cpp-security-extended.qls b/cpp/ql/src/codeql-suites/cpp-security-extended.qls index 69c014c4c6f..75deda24ef5 100644 --- a/cpp/ql/src/codeql-suites/cpp-security-extended.qls +++ b/cpp/ql/src/codeql-suites/cpp-security-extended.qls @@ -3,3 +3,6 @@ - apply: security-extended-selectors.yml from: codeql/suite-helpers - apply: codeql-suites/exclude-slow-queries.yml +- exclude: + id: cpp/overrun-write + From 3e96fe60c5250b92d03a45ba4519c92aa371725b Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Fri, 16 Jun 2023 08:50:47 +0200 Subject: [PATCH 607/739] Go/Java/JS/Python/Ruby: Update the description and qhelp of the ZipSlip query All filesystem operations, not just writes, with paths built from untrusted archive entry names are dangerous --- csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp | 10 +++++----- csharp/ql/src/Security Features/CWE-022/ZipSlip.ql | 8 ++++---- go/ql/src/Security/CWE-022/ZipSlip.qhelp | 10 +++++----- go/ql/src/Security/CWE-022/ZipSlip.ql | 8 ++++---- java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp | 11 +++++------ java/ql/src/Security/CWE/CWE-022/ZipSlip.ql | 8 ++++---- javascript/ql/src/Security/CWE-022/ZipSlip.qhelp | 10 +++++----- javascript/ql/src/Security/CWE-022/ZipSlip.ql | 8 ++++---- .../src/experimental/Security/CWE-022/ZipSlip.qhelp | 10 +++++----- .../ql/src/experimental/Security/CWE-022/ZipSlip.ql | 8 ++++---- .../ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp | 10 +++++----- ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql | 8 ++++---- 12 files changed, 54 insertions(+), 55 deletions(-) diff --git a/csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp b/csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp index bee5d819836..e1e2974ed4f 100644 --- a/csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp +++ b/csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp @@ -3,16 +3,16 @@ "qhelp.dtd"> <qhelp> <overview> -<p>Extracting files from a malicious zip archive without validating that the destination file path -is within the destination directory can cause files outside the destination directory to be -overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in +<p>Accessing filesystem paths built from the name of an archive entry without validating that the +destination file path is within the destination directory can allow an attacker to access +unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in archive paths.</p> <p>Zip archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain unexpected special elements such as the directory traversal element (<code>..</code>). If these -file paths are used to determine an output file to write the contents of the archive item to, then -the file may be written to an unexpected location. This can result in sensitive information being +file paths are used to create a filesystem path, then a file operation may happen in an +unexpected location. This can result in sensitive information being revealed or deleted, or an attacker being able to influence behavior by modifying unexpected files.</p> diff --git a/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql b/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql index 87850cde7d6..25a1e9bcd19 100644 --- a/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql +++ b/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** - * @name Arbitrary file write during zip extraction ("Zip Slip") - * @description Extracting files from a malicious zip archive without validating that the - * destination file path is within the destination directory can cause files outside - * the destination directory to be overwritten. + * @name Arbitrary file access during archive extraction ("Zip Slip") + * @description Accessing filesystem paths built from the name of an archive entry without + * validating that the destination file path is within the destination directory + * can allow an attacker to access unexpected resources. * @kind path-problem * @id cs/zipslip * @problem.severity error diff --git a/go/ql/src/Security/CWE-022/ZipSlip.qhelp b/go/ql/src/Security/CWE-022/ZipSlip.qhelp index 1322dc18c13..1c47eac9a53 100644 --- a/go/ql/src/Security/CWE-022/ZipSlip.qhelp +++ b/go/ql/src/Security/CWE-022/ZipSlip.qhelp @@ -5,9 +5,9 @@ <overview> <p> -Extracting files from a malicious zip archive without validating that the destination file path -is within the destination directory can cause files outside the destination directory to be -overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in +Accessing filesystem paths built from the name of an archive entry without validating that the +destination file path is within the destination directory can allow an attacker to access +unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in archive paths. </p> @@ -15,8 +15,8 @@ archive paths. Zip archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain unexpected special elements such as the directory traversal element (<code>..</code>). If these -file paths are used to determine which output file the contents of an archive item should be written to, then -the file may be written to an unexpected location. This can result in sensitive information being +file paths are used to create a filesystem path, then a file operation may happen in an +unexpected location. This can result in sensitive information being revealed or deleted, or an attacker being able to influence behavior by modifying unexpected files. </p> diff --git a/go/ql/src/Security/CWE-022/ZipSlip.ql b/go/ql/src/Security/CWE-022/ZipSlip.ql index ceec7dc57e3..27c18248ad5 100644 --- a/go/ql/src/Security/CWE-022/ZipSlip.ql +++ b/go/ql/src/Security/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** - * @name Arbitrary file write during zip extraction ("zip slip") - * @description Extracting files from a malicious zip archive without validating that the - * destination file path is within the destination directory can cause files outside - * the destination directory to be overwritten. + * @name Arbitrary file access during archive extraction ("Zip Slip") + * @description Accessing filesystem paths built from the name of an archive entry without + * validating that the destination file path is within the destination directory + * can allow an attacker to access unexpected resources. * @kind path-problem * @id go/zipslip * @problem.severity error diff --git a/java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp b/java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp index adea1b89c49..726b2d15cb6 100644 --- a/java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp +++ b/java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp @@ -3,17 +3,16 @@ "qhelp.dtd"> <qhelp> <overview> -<p>Extracting files from a malicious zip archive (or another archive format) -without validating that the destination file path -is within the destination directory can cause files outside the destination directory to be -overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in +<p>Accessing filesystem paths built from the name of an archive entry without validating that the +destination file path is within the destination directory can allow an attacker to access +unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in archive paths.</p> <p>Zip archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain unexpected special elements such as the directory traversal element (<code>..</code>). If these -file paths are used to determine an output file to write the contents of the archive item to, then -the file may be written to an unexpected location. This can result in sensitive information being +file paths are used to create a filesystem path, then a file operation may happen in an +unexpected location. This can result in sensitive information being revealed or deleted, or an attacker being able to influence behavior by modifying unexpected files.</p> diff --git a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql index 3488c97c057..2c48ecb2aa1 100644 --- a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql +++ b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** - * @name Arbitrary file write during archive extraction ("Zip Slip") - * @description Extracting files from a malicious archive without validating that the - * destination file path is within the destination directory can cause files outside - * the destination directory to be overwritten. + * @name Arbitrary file access during archive extraction ("Zip Slip") + * @description Accessing filesystem paths built from the name of an archive entry without + * validating that the destination file path is within the destination directory + * can allow an attacker to access unexpected resources. * @kind path-problem * @id java/zipslip * @problem.severity error diff --git a/javascript/ql/src/Security/CWE-022/ZipSlip.qhelp b/javascript/ql/src/Security/CWE-022/ZipSlip.qhelp index d9dc0fb67a8..bbb3824e41e 100644 --- a/javascript/ql/src/Security/CWE-022/ZipSlip.qhelp +++ b/javascript/ql/src/Security/CWE-022/ZipSlip.qhelp @@ -4,16 +4,16 @@ <qhelp> <overview> -<p>Extracting files from a malicious zip archive without validating that the destination file path -is within the destination directory can cause files outside the destination directory to be -overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in +<p>Accessing filesystem paths built from the name of an archive entry without validating that the +destination file path is within the destination directory can allow an attacker to access +unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in archive paths.</p> <p>Zip archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain unexpected special elements such as the directory traversal element (<code>..</code>). If these -file paths are used to determine an output file to write the contents of the archive item to, then -the file may be written to an unexpected location. This can result in sensitive information being +file paths are used to create a filesystem path, then a file operation may happen in an +unexpected location. This can result in sensitive information being revealed or deleted, or an attacker being able to influence behavior by modifying unexpected files.</p> diff --git a/javascript/ql/src/Security/CWE-022/ZipSlip.ql b/javascript/ql/src/Security/CWE-022/ZipSlip.ql index 0380031ad66..f9c468c388a 100644 --- a/javascript/ql/src/Security/CWE-022/ZipSlip.ql +++ b/javascript/ql/src/Security/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** - * @name Arbitrary file write during zip extraction ("Zip Slip") - * @description Extracting files from a malicious zip archive without validating that the - * destination file path is within the destination directory can cause files outside - * the destination directory to be overwritten. + * @name Arbitrary file access during archive extraction ("Zip Slip") + * @description Accessing filesystem paths built from the name of an archive entry without + * validating that the destination file path is within the destination directory + * can allow an attacker to access unexpected resources. * @kind path-problem * @id js/zipslip * @problem.severity error diff --git a/python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp b/python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp index 89260db7bd7..dfd563ea19b 100644 --- a/python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp +++ b/python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp @@ -4,16 +4,16 @@ <qhelp> <overview> -<p>Extracting files from a malicious zip archive without validating that the destination file path -is within the destination directory can cause files outside the destination directory to be -overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in +<p>Accessing filesystem paths built from the name of an archive entry without validating that the +destination file path is within the destination directory can allow an attacker to access +unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in archive paths.</p> <p>Zip archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain unexpected special elements such as the directory traversal element (<code>..</code>). If these -file paths are used to determine an output file to write the contents of the archive item to, then -the file may be written to an unexpected location. This can result in sensitive information being +file paths are used to create a filesystem path, then a file operation may happen in an +unexpected location. This can result in sensitive information being revealed or deleted, or an attacker being able to influence behavior by modifying unexpected files.</p> diff --git a/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql b/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql index aea193dde36..b00214cfe68 100644 --- a/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql +++ b/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** - * @name Arbitrary file write during archive extraction ("Zip Slip") - * @description Extracting files from a malicious archive without validating that the - * destination file path is within the destination directory can cause files outside - * the destination directory to be overwritten. + * @name Arbitrary file access during archive extraction ("Zip Slip") + * @description Accessing filesystem paths built from the name of an archive entry without + * validating that the destination file path is within the destination directory + * can allow an attacker to access unexpected resources. * @kind path-problem * @id py/zipslip * @problem.severity error diff --git a/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp b/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp index 759be8d95d0..2794db7efbd 100644 --- a/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp +++ b/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp @@ -4,16 +4,16 @@ <qhelp> <overview> -<p>Extracting files from a malicious tar archive without validating that the destination file path -is within the destination directory can cause files outside the destination directory to be -overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in +<p>Accessing filesystem paths built from the name of an archive entry without validating that the +destination file path is within the destination directory can allow an attacker to access +unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in archive paths.</p> <p>Tar archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain unexpected special elements such as the directory traversal element (<code>..</code>). If these -file paths are used to determine an output file to write the contents of the archive item to, then -the file may be written to an unexpected location. This can result in sensitive information being +file paths are used to create a filesystem path, then a file operation may happen in an +unexpected location. This can result in sensitive information being revealed or deleted, or an attacker being able to influence behavior by modifying unexpected files.</p> diff --git a/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql b/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql index e8be92fff75..709e89f98e8 100644 --- a/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql +++ b/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql @@ -1,8 +1,8 @@ /** - * @name Arbitrary file write during zipfile/tarfile extraction - * @description Extracting files from a malicious tar archive without validating that the - * destination file path is within the destination directory can cause files outside - * the destination directory to be overwritten. + * @name Arbitrary file access during archive extraction ("Zip Slip") + * @description Accessing filesystem paths built from the name of an archive entry without + * validating that the destination file path is within the destination directory + * can allow an attacker to access unexpected resources. * @kind path-problem * @id rb/zip-slip * @problem.severity error From c97868f7743a5c223933b1ff9c1662586c2fe441 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Fri, 16 Jun 2023 09:01:02 +0200 Subject: [PATCH 608/739] Add change notes --- csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md | 4 ++++ go/ql/src/change-notes/2023-06-16-zipslip-rename.md | 4 ++++ java/ql/src/change-notes/2023-06-16-zipslip-rename.md | 4 ++++ javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md | 4 ++++ python/ql/src/change-notes/2023-06-16-zipslip-rename.md | 4 ++++ ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md | 4 ++++ 6 files changed, 24 insertions(+) create mode 100644 csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md create mode 100644 go/ql/src/change-notes/2023-06-16-zipslip-rename.md create mode 100644 java/ql/src/change-notes/2023-06-16-zipslip-rename.md create mode 100644 javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md create mode 100644 python/ql/src/change-notes/2023-06-16-zipslip-rename.md create mode 100644 ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md diff --git a/csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md b/csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md new file mode 100644 index 00000000000..2816d74945c --- /dev/null +++ b/csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* The query "Arbitrary file write during zip extraction ("Zip Slip")" (`cs/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". diff --git a/go/ql/src/change-notes/2023-06-16-zipslip-rename.md b/go/ql/src/change-notes/2023-06-16-zipslip-rename.md new file mode 100644 index 00000000000..9e9d1483ad6 --- /dev/null +++ b/go/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* The query "Arbitrary file write during zip extraction ("zip slip")" (`go/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". diff --git a/java/ql/src/change-notes/2023-06-16-zipslip-rename.md b/java/ql/src/change-notes/2023-06-16-zipslip-rename.md new file mode 100644 index 00000000000..39316e46f5d --- /dev/null +++ b/java/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`java/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". diff --git a/javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md b/javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md new file mode 100644 index 00000000000..0d866964347 --- /dev/null +++ b/javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* The query "Arbitrary file write during zip extraction ("Zip Slip")" (`js/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". diff --git a/python/ql/src/change-notes/2023-06-16-zipslip-rename.md b/python/ql/src/change-notes/2023-06-16-zipslip-rename.md new file mode 100644 index 00000000000..50313eb7d27 --- /dev/null +++ b/python/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`py/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". diff --git a/ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md b/ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md new file mode 100644 index 00000000000..8e56e960ec4 --- /dev/null +++ b/ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* The experimental query "Arbitrary file write during zipfile/tarfile extraction" (`ruby/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". From 6028f4b76ff0e8ab3c878108ab156d605560ce98 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:28:46 +0200 Subject: [PATCH 609/739] C#: Base tests for CWE-112 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-112/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-112/options b/csharp/ql/test/query-tests/Security Features/CWE-112/options index c72ec0605ab..96b0b028bdd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-112/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-112/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Collections.Specialized.dll /r:System.Runtime.Extensions.dll ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Xml.ReaderWriter.dll /r:System.Private.Xml.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs From b726fe8735b897be426e1b2516c2dc228f9fc69a Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:31:25 +0200 Subject: [PATCH 610/739] C#: Base tests for CWE-114 on stubs. --- .../Security Features/CWE-114/AssemblyPathInjection/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/options b/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/options index 2fe55538006..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-114/AssemblyPathInjection/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs From d1b704fb453375a5c9ef3c4a062affbcd6b0eade Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:34:22 +0200 Subject: [PATCH 611/739] C#: Base tests for CWE-119 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-119/options | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-119/options diff --git a/csharp/ql/test/query-tests/Security Features/CWE-119/options b/csharp/ql/test/query-tests/Security Features/CWE-119/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-119/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From e0b661c5553fef650296e3fb3ab37db98e70460b Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:36:37 +0200 Subject: [PATCH 612/739] C#: Base tests for CWE-134 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-134/options | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/options b/csharp/ql/test/query-tests/Security Features/CWE-134/options index 54d2098bf4e..ab08ee323e2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/options @@ -1 +1,4 @@ -semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../resources/stubs/System.Web.cs ${testdir}/../../../resources/stubs/System.Windows.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Windows.cs From 596a8ecf970f6dcfb3713987b604f1132b576418 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:40:53 +0200 Subject: [PATCH 613/739] C#: Base tests for CWE-201 on stubs. --- .../CWE-201/ExposureInTransmittedData/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/options b/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/options index 3d76f691ef2..34d9e62e93c 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-201/ExposureInTransmittedData/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs ${testdir}/../../../../resources/stubs/System.Data.cs ${testdir}/../../../../resources/stubs/System.Net.cs /r:System.Data.Common.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs From 680762572abe55a57de4f8663d6da43781c29d31 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:43:01 +0200 Subject: [PATCH 614/739] C#: Base tests for CWE-209 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-209/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-209/options b/csharp/ql/test/query-tests/Security Features/CWE-209/options index 326ff69528b..96b0b028bdd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-209/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-209/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs From 02dbc600a4f5113355aab10aa0bdd918e3076ac3 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:47:26 +0200 Subject: [PATCH 615/739] C#: Base tests for CWE-248 on stubs. --- .../MissingASPNETGlobalErrorHandler/WebConfigOff/options | 4 +++- .../WebConfigOffButGlobal/options | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-248/MissingASPNETGlobalErrorHandler/WebConfigOff/options b/csharp/ql/test/query-tests/Security Features/CWE-248/MissingASPNETGlobalErrorHandler/WebConfigOff/options index 96837650998..9d05f9bf06d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-248/MissingASPNETGlobalErrorHandler/WebConfigOff/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-248/MissingASPNETGlobalErrorHandler/WebConfigOff/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-248/MissingASPNETGlobalErrorHandler/WebConfigOffButGlobal/options b/csharp/ql/test/query-tests/Security Features/CWE-248/MissingASPNETGlobalErrorHandler/WebConfigOffButGlobal/options index 96837650998..9d05f9bf06d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-248/MissingASPNETGlobalErrorHandler/WebConfigOffButGlobal/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-248/MissingASPNETGlobalErrorHandler/WebConfigOffButGlobal/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs From 4500170bb4f4997f71aac5d7ab7532333bdd631a Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:50:21 +0200 Subject: [PATCH 616/739] C#: Base tests for CWE-312 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-312/options | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-312/options b/csharp/ql/test/query-tests/Security Features/CWE-312/options index 4b3bf418201..ab08ee323e2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-312/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-312/options @@ -1 +1,4 @@ -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll /r:System.Security.Cryptography.dll {testdir}/../../../../resources/stubs/System.Windows.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Windows.cs From ae5c149150fec1b52a4b338330e6401432d1ddf7 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:53:38 +0200 Subject: [PATCH 617/739] C#: Base tests for CWE-338 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-338/options | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-338/options b/csharp/ql/test/query-tests/Security Features/CWE-338/options index 1225f3c0220..bd9f6e49ece 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-338/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-338/options @@ -1,2 +1,3 @@ -semmle-extractor-options: /r:System.Security.Cryptography.Csp.dll /r:System.Security.Cryptography.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj semmle-extractor-options: ${testdir}/../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs From b35af64a9d38a8e6c797165556bf15710a0f2ff1 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 15:59:22 +0200 Subject: [PATCH 618/739] C#: Base tests for CWE-352 on stubs. --- .../test/query-tests/Security Features/CWE-352/global/options | 4 +++- .../query-tests/Security Features/CWE-352/missing/options | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-352/global/options b/csharp/ql/test/query-tests/Security Features/CWE-352/global/options index 5ce3b321a94..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-352/global/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-352/global/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-352/missing/options b/csharp/ql/test/query-tests/Security Features/CWE-352/missing/options index 5ce3b321a94..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-352/missing/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-352/missing/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs From 6ec4338cca0a51da38a7c45c477d66536e1be57e Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 16:09:14 +0200 Subject: [PATCH 619/739] C#: Base tests for CWE-359 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-359/options | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-359/options b/csharp/ql/test/query-tests/Security Features/CWE-359/options index aa088071c5d..ab08ee323e2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-359/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-359/options @@ -1 +1,4 @@ -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll /r:System.Security.Cryptography.dll ${testdir}/../../../resources/stubs/System.Windows.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Windows.cs From 33e798418eb2c31ce92b68d0040f710787c60e8a Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 16:12:09 +0200 Subject: [PATCH 620/739] C#: Base tests for CWE-384 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-384/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-384/options b/csharp/ql/test/query-tests/Security Features/CWE-384/options index 326ff69528b..96b0b028bdd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-384/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-384/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs From faaf26157bb7d36b82b30136e7f3507987af9b71 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 16:16:44 +0200 Subject: [PATCH 621/739] C#: Base tests for CWE-451 on stubs. --- .../CWE-451/MissingXFrameOptions/CodeAddedHeader/options | 4 +++- .../CWE-451/MissingXFrameOptions/NoHeader/options | 4 +++- .../CWE-451/MissingXFrameOptions/WebConfigAddedHeader/options | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/CodeAddedHeader/options b/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/CodeAddedHeader/options index 96837650998..9d05f9bf06d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/CodeAddedHeader/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/CodeAddedHeader/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/NoHeader/options b/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/NoHeader/options index 96837650998..9d05f9bf06d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/NoHeader/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/NoHeader/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/WebConfigAddedHeader/options b/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/WebConfigAddedHeader/options index 96837650998..9d05f9bf06d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/WebConfigAddedHeader/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-451/MissingXFrameOptions/WebConfigAddedHeader/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs From 5e4d31c10d29af5e8af913b182c3c681b7a890a4 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 16:24:40 +0200 Subject: [PATCH 622/739] C#: Base tests for CWE-502 on stubs. --- .../Security Features/CWE-502/DeserializedDelegate/options | 3 ++- .../Security Features/CWE-502/UnsafeDeserialization/options | 4 +++- .../CWE-502/UnsafeDeserializationUntrustedInput/options | 4 +++- .../UnsafeDeserializationUntrustedInputNewtonsoftJson/options | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-502/DeserializedDelegate/options b/csharp/ql/test/query-tests/Security Features/CWE-502/DeserializedDelegate/options index bd4d77c7377..a5ea8b797c5 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-502/DeserializedDelegate/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-502/DeserializedDelegate/options @@ -1 +1,2 @@ -semmle-extractor-options: /r:System.Runtime.Serialization.Formatters.dll /r:System.IO.FileSystem.dll /r:System.Linq.Expressions.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/options b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/options index 182f92f8d84..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Private.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Private.DataContractSerialization.dll /r:System.Runtime.Serialization.Formatters.dll /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/options b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/options index 182f92f8d84..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Private.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Private.DataContractSerialization.dll /r:System.Runtime.Serialization.Formatters.dll /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInputNewtonsoftJson/options b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInputNewtonsoftJson/options index bd183f95f5c..81ebad48b0d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInputNewtonsoftJson/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInputNewtonsoftJson/options @@ -1 +1,3 @@ -semmle-extractor-options: /nostdlib /noconfig --load-sources-from-project:${testdir}/../../../../resources/stubs/Newtonsoft.Json/13.0.1/Newtonsoft.Json.csproj ${testdir}/../../../../resources/stubs/System.Web.cs +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/Newtonsoft.Json/13.0.1/Newtonsoft.Json.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs From 7766aaeb1e4d1b31c8cc5ccd60e3150da105fde7 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 16:26:46 +0200 Subject: [PATCH 623/739] C#: Base tests for CWE-539 on stubs. --- .../Security Features/CWE-539/PersistentCookie/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-539/PersistentCookie/options b/csharp/ql/test/query-tests/Security Features/CWE-539/PersistentCookie/options index 5ce3b321a94..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-539/PersistentCookie/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-539/PersistentCookie/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs From d414ce046fa27dfbf0e03a32c8dc511fd3d61055 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 16:30:33 +0200 Subject: [PATCH 624/739] C#: Base tests for CWE-548 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-548/options | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-548/options diff --git a/csharp/ql/test/query-tests/Security Features/CWE-548/options b/csharp/ql/test/query-tests/Security Features/CWE-548/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-548/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From 58d469b93237a1eb1df8ad97a2472e3fb3ed3671 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 16:33:06 +0200 Subject: [PATCH 625/739] C#: Make path relative to testdir explicit in CWE-601 testcase. --- .../query-tests/Security Features/CWE-601/UrlRedirect/options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/options b/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/options index fb116749418..daca5d73f55 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-601/UrlRedirect/options @@ -1,4 +1,4 @@ semmle-extractor-options: /nostdlib /noconfig semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: --load-sources-from-project:../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs From 2857145bba014581b09a70c43bc85433f928891e Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 19:38:40 +0200 Subject: [PATCH 626/739] C#: Base tests for CWE-614 on stubs. --- .../Security Features/CWE-614/RequireSSL/AddedInCode/options | 4 +++- .../Security Features/CWE-614/RequireSSL/AddedInForms/options | 2 ++ .../CWE-614/RequireSSL/HttpCookiesCorrect/options | 2 ++ .../CWE-614/RequireSSL/RequireSSLMissing/options | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/AddedInForms/options create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/HttpCookiesCorrect/options create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/RequireSSLMissing/options diff --git a/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/AddedInCode/options b/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/AddedInCode/options index 96837650998..9d05f9bf06d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/AddedInCode/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/AddedInCode/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/AddedInForms/options b/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/AddedInForms/options new file mode 100644 index 00000000000..f4586e95ef0 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/AddedInForms/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/HttpCookiesCorrect/options b/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/HttpCookiesCorrect/options new file mode 100644 index 00000000000..f4586e95ef0 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/HttpCookiesCorrect/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/RequireSSLMissing/options b/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/RequireSSLMissing/options new file mode 100644 index 00000000000..f4586e95ef0 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-614/RequireSSL/RequireSSLMissing/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From 5483756f17017752203e133a349a8dece14c8b4c Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 19:44:04 +0200 Subject: [PATCH 627/739] C#: Base tests for CWE-643 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-643/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-643/options b/csharp/ql/test/query-tests/Security Features/CWE-643/options index 9ab01d95193..6f56ddfc468 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-643/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-643/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll ${testdir}/../../../resources/stubs/System.Data.cs /r:System.Private.Xml.dll /r:System.Xml.XPath.dll /r:System.Data.Common.dll /r:System.Runtime.Extensions.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs From 6058cfc037829a2785b8fa2f51a0288b17523c9b Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 15 Jun 2023 19:48:51 +0200 Subject: [PATCH 628/739] C#: Base tests for CWE-730 on stubs. --- .../test/query-tests/Security Features/CWE-730/ReDoS/options | 4 +++- .../Security Features/CWE-730/ReDoSGlobalTimeout/options | 4 +++- .../Security Features/CWE-730/RegexInjection/options | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/options b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/options index 84463712411..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoS/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/options b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/options index 1a4a26ba9ed..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/ReDoSGlobalTimeout/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Runtime.Extensions.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/options b/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/options index 84463712411..9290f65d5b2 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-730/RegexInjection/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs From 52c4a47a6159039d5f6570f5fcd0bbcd6dd645d1 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 16 Jun 2023 10:03:29 +0200 Subject: [PATCH 629/739] C#: Base tests for CWE-798 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-798/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-798/options b/csharp/ql/test/query-tests/Security Features/CWE-798/options index 3145ab2441c..a361e4fde29 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-798/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-798/options @@ -1,2 +1,4 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs semmle-extractor-options: ${testdir}/../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs -semmle-extractor-options: /r:${testdir}/../../../resources/assemblies/System.Web.dll /r:${testdir}/../../../resources/assemblies/System.Web.ApplicationServices.dll /r:${testdir}/../../../resources/assemblies/System.Data.dll /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Data.Common.dll /r:System.Security.Cryptography.dll /r:System.Runtime.InteropServices.dll From f4f195c837f4df59b1f5d1db7b73bf3af86911b8 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 16 Jun 2023 10:06:34 +0200 Subject: [PATCH 630/739] C#: Base tests for CWE-807 on stubs. --- csharp/ql/test/query-tests/Security Features/CWE-807/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-807/options b/csharp/ql/test/query-tests/Security Features/CWE-807/options index e2ddeb7dac8..96b0b028bdd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-807/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-807/options @@ -1 +1,3 @@ -semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Net.cs ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs From a8acf160884dc299d1167e535f78cafcc73149a3 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Fri, 16 Jun 2023 12:57:19 +0100 Subject: [PATCH 631/739] Kotlin: Remove diags.ql from classes test The diags consistency test already handles this for us. --- java/ql/test/kotlin/library-tests/classes/diags.expected | 0 java/ql/test/kotlin/library-tests/classes/diags.ql | 8 -------- 2 files changed, 8 deletions(-) delete mode 100644 java/ql/test/kotlin/library-tests/classes/diags.expected delete mode 100644 java/ql/test/kotlin/library-tests/classes/diags.ql diff --git a/java/ql/test/kotlin/library-tests/classes/diags.expected b/java/ql/test/kotlin/library-tests/classes/diags.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/java/ql/test/kotlin/library-tests/classes/diags.ql b/java/ql/test/kotlin/library-tests/classes/diags.ql deleted file mode 100644 index f791c30d153..00000000000 --- a/java/ql/test/kotlin/library-tests/classes/diags.ql +++ /dev/null @@ -1,8 +0,0 @@ -import semmle.code.java.Diagnostics - -from Diagnostic d -where d.getSeverity() > 2 -select d, d.getGeneratedBy(), d.getSeverity(), d.getTag(), d.getMessage(), - d.getFullMessage() - .regexpReplaceAll("^\\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} K\\] ", - "[DATE TIME K] ") From daf274314331318ecffd16e1bf7de399fe06cadc Mon Sep 17 00:00:00 2001 From: Jean Helie <jhelie@github.com> Date: Wed, 14 Jun 2023 15:07:12 +0200 Subject: [PATCH 632/739] only use neutral models of kind "sink" --- .../src/Telemetry/AutomodelApplicationModeCharacteristics.qll | 2 +- java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 86aff731ba2..9b2eecb0307 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -79,7 +79,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig predicate isNeutral(Endpoint e) { exists(string package, string type, string name, string signature | sinkSpec(e, package, type, name, signature, _, _) and - ExternalFlow::neutralModel(package, type, name, [signature, ""], _, _) + ExternalFlow::neutralModel(package, type, name, [signature, ""], "sink", _) ) } diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index da37726d8f0..5dbca626159 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -60,7 +60,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { predicate isNeutral(Endpoint e) { exists(string package, string type, string name, string signature | sinkSpec(e, package, type, name, signature, _, _) and - ExternalFlow::neutralModel(package, type, name, [signature, ""], _, _) + ExternalFlow::neutralModel(package, type, name, [signature, ""], "sink", _) ) } From baf6b7494534bef30e58ee928029c52e1a6f3851 Mon Sep 17 00:00:00 2001 From: Jean Helie <jhelie@github.com> Date: Wed, 14 Jun 2023 17:54:16 +0200 Subject: [PATCH 633/739] use new sink mad kinds and simplify isKnownKind predicate --- ...utomodelApplicationModeCharacteristics.qll | 4 +-- .../src/Telemetry/AutomodelEndpointTypes.qll | 10 +++---- .../AutomodelFrameworkModeCharacteristics.qll | 2 +- java/ql/src/Telemetry/AutomodelJavaUtil.qll | 26 +++++-------------- .../AutomodelSharedCharacteristics.qll | 8 ++++-- 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll index 9b2eecb0307..51e786eebdc 100644 --- a/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll @@ -59,13 +59,13 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig e.getType() instanceof NumberType ) or - t instanceof AutomodelEndpointTypes::TaintedPathSinkType and + t instanceof AutomodelEndpointTypes::PathInjectionSinkType and e instanceof PathSanitizer::PathInjectionSanitizer } RelatedLocation asLocation(Endpoint e) { result = e.asExpr() } - predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3; + predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2; predicate isSink(Endpoint e, string kind) { exists(string package, string type, string name, string signature, string ext, string input | diff --git a/java/ql/src/Telemetry/AutomodelEndpointTypes.qll b/java/ql/src/Telemetry/AutomodelEndpointTypes.qll index 7414837b605..618fa4bc7dd 100644 --- a/java/ql/src/Telemetry/AutomodelEndpointTypes.qll +++ b/java/ql/src/Telemetry/AutomodelEndpointTypes.qll @@ -40,18 +40,18 @@ class NegativeSinkType extends SinkType { } /** A sink relevant to the SQL injection query */ -class SqlSinkType extends SinkType { - SqlSinkType() { this = "sql" } +class SqlInjectionSinkType extends SinkType { + SqlInjectionSinkType() { this = "sql-injection" } } /** A sink relevant to the tainted path injection query. */ -class TaintedPathSinkType extends SinkType { - TaintedPathSinkType() { this = "tainted-path" } +class PathInjectionSinkType extends SinkType { + PathInjectionSinkType() { this = "path-injection" } } /** A sink relevant to the SSRF query. */ class RequestForgerySinkType extends SinkType { - RequestForgerySinkType() { this = "ssrf" } + RequestForgerySinkType() { this = "request-forgery" } } /** A sink relevant to the command injection query. */ diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index 5dbca626159..bc5c3b59a91 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -48,7 +48,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig { RelatedLocation asLocation(Endpoint e) { result = e.asParameter() } - predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3; + predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2; predicate isSink(Endpoint e, string kind) { exists(string package, string type, string name, string signature, string ext, string input | diff --git a/java/ql/src/Telemetry/AutomodelJavaUtil.qll b/java/ql/src/Telemetry/AutomodelJavaUtil.qll index 215ab1fca1a..03b73da1015 100644 --- a/java/ql/src/Telemetry/AutomodelJavaUtil.qll +++ b/java/ql/src/Telemetry/AutomodelJavaUtil.qll @@ -27,31 +27,17 @@ class DollarAtString extends string { * Holds for all combinations of MaD kinds (`kind`) and their human readable * descriptions. */ -predicate isKnownKind( - string kind, string humanReadableKind, AutomodelEndpointTypes::EndpointType type -) { - kind = "read-file" and - humanReadableKind = "read file" and - type instanceof AutomodelEndpointTypes::TaintedPathSinkType +predicate isKnownKind(string kind, AutomodelEndpointTypes::EndpointType type) { + kind = "path-injection" and + type instanceof AutomodelEndpointTypes::PathInjectionSinkType or - kind = "create-file" and - humanReadableKind = "create file" and - type instanceof AutomodelEndpointTypes::TaintedPathSinkType + kind = "sql-injection" and + type instanceof AutomodelEndpointTypes::SqlInjectionSinkType or - kind = "sql" and - humanReadableKind = "mad modeled sql" and - type instanceof AutomodelEndpointTypes::SqlSinkType - or - kind = "open-url" and - humanReadableKind = "open url" and - type instanceof AutomodelEndpointTypes::RequestForgerySinkType - or - kind = "jdbc-url" and - humanReadableKind = "jdbc url" and + kind = "request-forgery" and type instanceof AutomodelEndpointTypes::RequestForgerySinkType or kind = "command-injection" and - humanReadableKind = "command injection" and type instanceof AutomodelEndpointTypes::CommandInjectionSinkType } diff --git a/java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll b/java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll index f23340bf34f..b077f77deb9 100644 --- a/java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll @@ -50,7 +50,7 @@ signature module CandidateSig { /** * Defines what MaD kinds are known, and what endpoint type they correspond to. */ - predicate isKnownKind(string kind, string humanReadableLabel, EndpointType type); + predicate isKnownKind(string kind, EndpointType type); /** * Holds if `e` is a flow sanitizer, and has type `t`. @@ -276,7 +276,11 @@ module SharedCharacteristics<CandidateSig Candidate> { string madKind; Candidate::EndpointType endpointType; - KnownSinkCharacteristic() { Candidate::isKnownKind(madKind, this, endpointType) } + KnownSinkCharacteristic() { + Candidate::isKnownKind(madKind, endpointType) and + // bind "this" to a unique string differing from that of the SinkType classes + this = madKind + "-characteristic" + } override predicate appliesToEndpoint(Candidate::Endpoint e) { Candidate::isSink(e, madKind) } From afafaac0d785c0f7b31345aa4a28e25f99c58d80 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Fri, 16 Jun 2023 14:41:36 +0200 Subject: [PATCH 634/739] Python: Fix typo --- .../semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index 8817cdf21ce..bac194aae9e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -243,7 +243,7 @@ private module SummaryTypeTrackerInput implements SummaryTypeTracker::Input { Node returnOf(Node callable, SummaryComponent return) { return = FlowSummary::SummaryComponent::return() and - // `result` should be the return value of a callable expresion (lambda or function) referenced by `callable` + // `result` should be the return value of a callable expression (lambda or function) referenced by `callable` result.asCfgNode() = callable.getALocalSource().asExpr().(CallableExpr).getInnerScope().getAReturnValueFlowNode() } From fb6955edf98bb51054650b3e9187d7451d9ab901 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Fri, 16 Jun 2023 14:43:45 +0200 Subject: [PATCH 635/739] Python: Add tests of methods in summaries --- .../dataflow/summaries/summaries.py | 18 ++++++++++++++++++ .../typetracking-summaries/summaries.py | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.py b/python/ql/test/experimental/dataflow/summaries/summaries.py index 1532a5393d8..806b39f6dc8 100644 --- a/python/ql/test/experimental/dataflow/summaries/summaries.py +++ b/python/ql/test/experimental/dataflow/summaries/summaries.py @@ -66,3 +66,21 @@ SINK(tainted_list[0]) # $ flow="SOURCE, l:-1 -> tainted_list[0]" from json import loads as json_loads tainted_resultlist = json_loads(SOURCE) SINK(tainted_resultlist[0]) # $ flow="SOURCE, l:-1 -> tainted_resultlist[0]" + + +# Class methods are not handled right now + +class MyClass: + @staticmethod + def foo(x): + return x + + def bar(self, x): + return x + +through_staticmethod = apply_lambda(MyClass.foo, SOURCE) +through_staticmethod # $ MISSING: flow + +mc = MyClass() +through_method = apply_lambda(mc.bar, SOURCE) +through_method # $ MISSING: flow diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py index 5801b8e7961..f838032b063 100644 --- a/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py +++ b/python/ql/test/experimental/dataflow/typetracking-summaries/summaries.py @@ -59,3 +59,20 @@ r # $ tracked y # $ tracked=secret TTS_set_secret(y, tracked) # $ tracked tracked=secret y.secret # $ tracked tracked=secret + +# Class methods are not handled right now + +class MyClass: + @staticmethod + def foo(x): + return x + + def bar(self, x): + return x + +through_staticmethod = TTS_apply_lambda(MyClass.foo, tracked) # $ tracked +through_staticmethod # $ MISSING: tracked + +mc = MyClass() +through_method = TTS_apply_lambda(mc.bar, tracked) # $ tracked +through_method # $ MISSING: tracked From 0e68767efc5848ce346c2196363e740d6e428859 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 16 Jun 2023 15:28:05 +0200 Subject: [PATCH 636/739] C++: Add more `cpp/invalid-pointer-deref` FPs --- .../InvalidPointerDeref.expected | 30 +++++++++++++++++++ .../CWE/CWE-193/pointer-deref/test.cpp | 27 +++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index e176aa0a701..7906dcf0a4c 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -772,6 +772,19 @@ edges | test.cpp:393:9:393:10 | xs | test.cpp:395:5:395:13 | Store: ... = ... | | test.cpp:393:9:393:10 | xs | test.cpp:395:5:395:13 | Store: ... = ... | | test.cpp:395:5:395:6 | xs | test.cpp:395:5:395:13 | Store: ... = ... | +| test.cpp:404:3:404:25 | ... = ... | test.cpp:404:7:404:8 | val indirection [post update] [xs] | +| test.cpp:404:7:404:8 | val indirection [post update] [xs] | test.cpp:407:3:407:5 | val indirection [xs] | +| test.cpp:404:12:404:25 | new[] | test.cpp:404:3:404:25 | ... = ... | +| test.cpp:406:3:406:25 | ... = ... | test.cpp:406:7:406:8 | val indirection [post update] [xs] | +| test.cpp:406:7:406:8 | val indirection [post update] [xs] | test.cpp:407:3:407:5 | val indirection [xs] | +| test.cpp:406:12:406:25 | new[] | test.cpp:406:3:406:25 | ... = ... | +| test.cpp:407:3:407:5 | val indirection [xs] | test.cpp:407:7:407:8 | xs indirection | +| test.cpp:407:3:407:18 | access to array | test.cpp:407:3:407:22 | Store: ... = ... | +| test.cpp:407:7:407:8 | xs | test.cpp:407:3:407:18 | access to array | +| test.cpp:407:7:407:8 | xs indirection | test.cpp:407:7:407:8 | xs | +| test.cpp:417:16:417:33 | new[] | test.cpp:419:7:419:8 | xs | +| test.cpp:419:7:419:8 | xs | test.cpp:419:7:419:11 | access to array | +| test.cpp:419:7:419:11 | access to array | test.cpp:419:7:419:15 | Store: ... = ... | nodes | test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc | | test.cpp:5:15:5:15 | p | semmle.label | p | @@ -1122,6 +1135,21 @@ nodes | test.cpp:393:9:393:10 | xs | semmle.label | xs | | test.cpp:395:5:395:6 | xs | semmle.label | xs | | test.cpp:395:5:395:13 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:404:3:404:25 | ... = ... | semmle.label | ... = ... | +| test.cpp:404:7:404:8 | val indirection [post update] [xs] | semmle.label | val indirection [post update] [xs] | +| test.cpp:404:12:404:25 | new[] | semmle.label | new[] | +| test.cpp:406:3:406:25 | ... = ... | semmle.label | ... = ... | +| test.cpp:406:7:406:8 | val indirection [post update] [xs] | semmle.label | val indirection [post update] [xs] | +| test.cpp:406:12:406:25 | new[] | semmle.label | new[] | +| test.cpp:407:3:407:5 | val indirection [xs] | semmle.label | val indirection [xs] | +| test.cpp:407:3:407:18 | access to array | semmle.label | access to array | +| test.cpp:407:3:407:22 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:407:7:407:8 | xs | semmle.label | xs | +| test.cpp:407:7:407:8 | xs indirection | semmle.label | xs indirection | +| test.cpp:417:16:417:33 | new[] | semmle.label | new[] | +| test.cpp:419:7:419:8 | xs | semmle.label | xs | +| test.cpp:419:7:419:11 | access to array | semmle.label | access to array | +| test.cpp:419:7:419:15 | Store: ... = ... | semmle.label | Store: ... = ... | subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | @@ -1149,3 +1177,5 @@ subpaths | test.cpp:372:15:372:16 | Load: * ... | test.cpp:363:14:363:27 | new[] | test.cpp:372:15:372:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:363:14:363:27 | new[] | new[] | test.cpp:365:19:365:22 | size | size | | test.cpp:384:13:384:16 | Load: * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size | | test.cpp:395:5:395:13 | Store: ... = ... | test.cpp:388:14:388:27 | new[] | test.cpp:395:5:395:13 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:388:14:388:27 | new[] | new[] | test.cpp:389:19:389:22 | size | size | +| test.cpp:407:3:407:22 | Store: ... = ... | test.cpp:404:12:404:25 | new[] | test.cpp:407:3:407:22 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:404:12:404:25 | new[] | new[] | test.cpp:407:10:407:17 | ... - ... | ... - ... | +| test.cpp:419:7:419:15 | Store: ... = ... | test.cpp:417:16:417:33 | new[] | test.cpp:419:7:419:15 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:417:16:417:33 | new[] | new[] | test.cpp:419:10:419:10 | i | i | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index 4b6cd37dd4f..e260f555bfb 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -394,3 +394,30 @@ void test28(unsigned size) { return; xs[0] = 0; // GOOD [FALSE POSITIVE] } + +struct test29_struct { + char* xs; +}; + +void test29(unsigned size) { + test29_struct val; + val.xs = new char[size]; + size++; + val.xs = new char[size]; + val.xs[size - 1] = 0; // GOOD [FALSE POSITIVE] +} + +void test30(int *size) +{ + int new_size = 0, tmp_size = 0; + + test30(&tmp_size); + if (tmp_size + 1 > new_size) { + new_size = tmp_size + 1; + char *xs = new char[new_size]; + for (int i = 0; i < new_size; i++) { + xs[i] = 0; // GOOD [FALSE POSITIVE] + } + } + *size = new_size; +} From 9ff575447363fe7cbf294ee1d156cf0617a0c063 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 16 Jun 2023 16:48:24 +0200 Subject: [PATCH 637/739] C++: Add `cpp/invalid-pointer-def` FP test case --- .../pointer-deref/InvalidPointerDeref.expected | 8 ++++++++ .../Security/CWE/CWE-193/pointer-deref/test.cpp | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 7906dcf0a4c..7c27659de1f 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -785,6 +785,9 @@ edges | test.cpp:417:16:417:33 | new[] | test.cpp:419:7:419:8 | xs | | test.cpp:419:7:419:8 | xs | test.cpp:419:7:419:11 | access to array | | test.cpp:419:7:419:11 | access to array | test.cpp:419:7:419:15 | Store: ... = ... | +| test.cpp:427:14:427:27 | new[] | test.cpp:433:5:433:6 | xs | +| test.cpp:433:5:433:6 | xs | test.cpp:433:5:433:17 | access to array | +| test.cpp:433:5:433:17 | access to array | test.cpp:433:5:433:21 | Store: ... = ... | nodes | test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc | | test.cpp:5:15:5:15 | p | semmle.label | p | @@ -1150,6 +1153,10 @@ nodes | test.cpp:419:7:419:8 | xs | semmle.label | xs | | test.cpp:419:7:419:11 | access to array | semmle.label | access to array | | test.cpp:419:7:419:15 | Store: ... = ... | semmle.label | Store: ... = ... | +| test.cpp:427:14:427:27 | new[] | semmle.label | new[] | +| test.cpp:433:5:433:6 | xs | semmle.label | xs | +| test.cpp:433:5:433:17 | access to array | semmle.label | access to array | +| test.cpp:433:5:433:21 | Store: ... = ... | semmle.label | Store: ... = ... | subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | @@ -1179,3 +1186,4 @@ subpaths | test.cpp:395:5:395:13 | Store: ... = ... | test.cpp:388:14:388:27 | new[] | test.cpp:395:5:395:13 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:388:14:388:27 | new[] | new[] | test.cpp:389:19:389:22 | size | size | | test.cpp:407:3:407:22 | Store: ... = ... | test.cpp:404:12:404:25 | new[] | test.cpp:407:3:407:22 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:404:12:404:25 | new[] | new[] | test.cpp:407:10:407:17 | ... - ... | ... - ... | | test.cpp:419:7:419:15 | Store: ... = ... | test.cpp:417:16:417:33 | new[] | test.cpp:419:7:419:15 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:417:16:417:33 | new[] | new[] | test.cpp:419:10:419:10 | i | i | +| test.cpp:433:5:433:21 | Store: ... = ... | test.cpp:427:14:427:27 | new[] | test.cpp:433:5:433:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:427:14:427:27 | new[] | new[] | test.cpp:433:8:433:16 | ... ++ | ... ++ | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index e260f555bfb..4048c15be8b 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -421,3 +421,15 @@ void test30(int *size) } *size = new_size; } + +void test31(unsigned size, unsigned src_pos) +{ + char *xs = new char[size]; + if (src_pos > size) { + src_pos = size; + } + unsigned dst_pos = src_pos; + if(dst_pos < size - 3) { + xs[dst_pos++] = 0; // GOOD [FALSE POSITIVE] + } +} From aedd9f5f6b1ea5f2e2ab2045c4ab331d90688261 Mon Sep 17 00:00:00 2001 From: Philip Ginsbach <ginsbach@github.com> Date: Fri, 26 May 2023 15:00:03 +0100 Subject: [PATCH 638/739] add QL specification section on module instantiations --- .../ql-language-specification.rst | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 71dcbdce571..59510bc8edd 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -199,10 +199,21 @@ Kinds of modules A module may be: +- A *declared module*, if it is defined by the ``module`` or ``ql`` grammar rules. +- A *non-declared module*, if it is not a *declared module*. + +A *declared module* may be: + - A *file module*, if it is defined implicitly by a QL file or a QLL file. - A *query module*, if it is defined implicitly by a QL file. - A *library module*, if it is not a query module. +A *non-declared module* may be: + +- A *built-in module*. +- An *instantiated module* (see :ref:`Parameterized modules`). +- An *instantiation-nested module* (see :ref:`Parameterized modules`). + A query module must contain one or more queries. Import directives @@ -249,6 +260,67 @@ For qualified identifiers (``a.b``): A qualified module identifier is only valid within an import. +.. _Parameterized modules: + +Parameterized modules +~~~~~~~~~~~~~~~~~~~~~ + +Modules with parameters are called *parameterized modules*. A *declared module* has parameters if and only if it is a *library module* and its declaration uses the ``parameters`` syntax. + +*Parameterized modules* can be instantiated with arguments that match the signatures of the parameters: + +- Given a type signature, the corresponding argument must be a type that transitively extends the specified ``extends`` types and is a transitive subtype of the specified ``instanceof`` types. +- Given a predicate signature, the corresponding argument must be a predicate with exactly matching relational types. +- Given a module signature, the corresponding argument must be a module that exports all the specified type and predicate members. Furthermore, the module must be declared as matching the module signature via the ``implements`` syntax. + +The result of instantiating a *parameterized module* is an *instantiated module*. The parameterized module is called the *underlying module* of the *instantiated module*. + +Instantiation-relative and instantiation-nested entities +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Given an *instantiated module*, every entity has a corresponding entity called the *instantiation-relative* entity, which is determined as follows: + +- If the entity is the *underlying module*, its *instantiation-relative entity* is the *instantiated module*. +- If the entity is a parameter of the *underlying module*, its *instantiation-relative entity* is the corresponding argument. +- If the entity is declared inside the *underlying module* or its nested modules, its *instantiation-relative* entity is an *instantiation-nested* entity that is generated by the module instantiation. Parameters of any modules that are nested inside the *underlying module* are considered declared inside the module for this purpose. +- Otherwise, the entity's *instantiation-relative* entity is the initial entity itself. + +When the *instantiation-relative* entity of an entity is an *instantiation-nested* entity, then the initial entity is called the *underlying nested* entity of the *instantiation-nested* entity*, the *instantiated module* is called the *instantiation root* of the *instantiation-nested* entity, and the *underlying module* is called the *underlying root* of the *instantiation-nested* entity. + +The components of an *instantiation-nested* entity are the *instantiation-relative* entities of the components of its *underlying nested* entity. Among other things, this applies to: + +- values in the exported environments of *instantiation-nested* modules, +- relational types of *instantiation-nested* predicates and predicate signatures, +- required signatures of *instantiation-nested* parameters, +- parameters of an *instantiation-nested* *parameterized module*, +- fields and member predicates of *instantiation-nested* dataclasses. + +Given an *instantiated module*, any alias in the program has a corresponding alias called the *instantiation-relative* alias, which targets the *instantiation-relative* entity. + +Applicative instantiation +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Every entity has an *underlying completely uninstantiated* entity that is determined as follows: + +- If the entity is an *instantiated module*, its *underlying completely uninstantiated* entity is the *underlying completely uninstantiated* entity of the *underlying module*. +- If the entity is an *instantiation-nested* entity, its *underlying completely uninstantiated* entity is the *underlying completely uninstantiated* entity of the *underlying nested* entity. +- Otherwise, its *underlying completely uninstantiated* entity is the entity itself. + +An entity is called *completely uninstantiated* entity if it is its own *underlying completely uninstantiated* entity. + +Every *completely uninstantiated* entity has a *relevant set of parameters*, which is the set of all parameters of all the modules that the entity is transitively nested inside. For entities that are not nested inside any modules, the *relevant set of parameters* is empty. + +Note that the *relevant set of parameters* by construction contains only *completely uninstantiated* parameters. + +For a *completely uninstantiated* parameter, the *bottom-up instantiation-resolved* parameter relative to an entity is defined as: + +- If the entity is an *instantiated module* or an *instantiation-nested* entity, the *bottom-up instantiation-resolved* parameter is the *instantiation-relative* parameter of the *bottom-up instantiation-resolved* parameter relative to the *underlying module*. +- Otherwise, the *bottom-up instantiation-resolved* parameter is the parameter itself. + +Two *instantiated modules* or two *instantiation-nested* entities are considered *equivalent* if they have the same *underlying completely uninstantiated* entity and each parameter in its *relevant set of parameters* has the same *bottom-up instantiation-resolved* parameter relative to either *instantiated module*. + +Module instantiation is applicative, meaning that *equivalent* *instantiated modules* and *equivalent* *instantiation-nested* entities are indistinguishable. + Module references and active modules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 45426b928929ec68208b5b3506a33387927aa894 Mon Sep 17 00:00:00 2001 From: Philip Ginsbach <ginsbach@github.com> Date: Tue, 13 Jun 2023 15:55:47 +0100 Subject: [PATCH 639/739] mention parameters and instantiation-nested types --- docs/codeql/ql-language-reference/ql-language-specification.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 59510bc8edd..f6edaf2e121 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -340,7 +340,7 @@ QL is a typed language. This section specifies the kinds of types available, the Kinds of types ~~~~~~~~~~~~~~ -Types in QL are either *primitive* types, *database* types, *class* types, *character* types or *class domain* types. +Types in QL are either *primitive* types, *database* types, *class* types, *character* types, *class domain* types, type *parameters*, or *instantiation-nested* types. The primitive types are ``boolean``, ``date``, ``float``, ``int``, and ``string``. From 1ed3baea1739fb527d36a6233e5bc960d8e5b75b Mon Sep 17 00:00:00 2001 From: Philip Ginsbach <ginsbach@github.com> Date: Fri, 16 Jun 2023 16:03:25 +0100 Subject: [PATCH 640/739] mention instantiation in the section on module resolution --- .../ql-language-specification.rst | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index f6edaf2e121..a1b5eb0068d 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -219,15 +219,17 @@ A query module must contain one or more queries. Import directives ~~~~~~~~~~~~~~~~~ -An import directive refers to a module identifier: +An import directive refers to a module expression: :: import ::= annotations "import" importModuleExpr ("as" modulename)? - qualId ::= simpleId | qualId "." simpleId + importModuleExpr ::= importModuleId arguments? - importModuleExpr ::= qualId | importModuleExpr "::" modulename arguments? + importModuleId ::= qualId | importModuleExpr "::" modulename + + qualId ::= simpleId | qualId "." simpleId arguments ::= "<" argument ("," argument)* ">" @@ -260,6 +262,10 @@ For qualified identifiers (``a.b``): A qualified module identifier is only valid within an import. +Module expressions contain a module identifier and optional arguments. If arguments are present, the module expression instantiates the module that the identifier resolves to (see :ref:`Parameterized modules`). + +Module expressions cannot refer to :ref:`Parameterized modules`. Instead, parameterized modules must always be fully instantiated when they are referenced. + .. _Parameterized modules: Parameterized modules @@ -361,7 +367,9 @@ With the exception of class domain types and character types (which cannot be re type ::= (moduleExpr "::")? classname | dbasetype | "boolean" | "date" | "float" | "int" | "string" - moduleExpr ::= modulename arguments? | moduleExpr "::" modulename arguments? + moduleExpr ::= moduleId arguments? + + moduleId ::= modulename | moduleExpr "::" modulename A type reference is resolved to a type as follows: From 096e9a4ba4bfe92f3af1a47a0f1c5f128b71f07e Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Fri, 16 Jun 2023 17:04:47 +0100 Subject: [PATCH 641/739] Kotlin: Avoid another cause of ConcurrentModificationException with 1.9 --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index c471662e631..3db4321d094 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -5316,7 +5316,10 @@ open class KotlinFileExtractor( private fun extractTypeAccessRecursive(t: IrType, location: Label<out DbLocation>, parent: Label<out DbExprparent>, idx: Int, typeContext: TypeContext = TypeContext.OTHER): Label<out DbExpr> { val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx) if (t is IrSimpleType) { - t.arguments.forEachIndexed { argIdx, arg -> + // From 1.9, the list might change when we call erase, + // so we make a copy that it is safe to iterate over. + val argumentsCopy = t.arguments.toList() + argumentsCopy.forEachIndexed { argIdx, arg -> extractWildcardTypeAccessRecursive(arg, location, typeAccessId, argIdx) } } From bc48968defe3117d4a4453347da52565a482074d Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Fri, 16 Jun 2023 17:22:43 +0100 Subject: [PATCH 642/739] Swift: Build incompatible OS diagnostic on all platforms. --- swift/BUILD.bazel | 6 +++--- swift/logging/SwiftLogging.cpp | 4 ++++ swift/rules.bzl | 12 +++++++----- swift/tools/autobuilder-diagnostics/BUILD.bazel | 2 ++ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/swift/BUILD.bazel b/swift/BUILD.bazel index b5042dc19d8..af21fcc0c66 100644 --- a/swift/BUILD.bazel +++ b/swift/BUILD.bazel @@ -85,12 +85,12 @@ pkg_filegroup( ":swift-test-sdk-arch", ":resource-dir-arch", ] + select({ - "@platforms//os:linux": [ - ":incompatible-os", - ], "@platforms//os:macos": [ ":xcode-autobuilder", ], + "//conditions:default": [ + ":incompatible-os", + ], }), visibility = ["//visibility:public"], ) diff --git a/swift/logging/SwiftLogging.cpp b/swift/logging/SwiftLogging.cpp index 952021f740f..6c065e858c1 100644 --- a/swift/logging/SwiftLogging.cpp +++ b/swift/logging/SwiftLogging.cpp @@ -3,7 +3,11 @@ #include <filesystem> #include <stdlib.h> #include <optional> +#ifdef _WIN32 +#include <process.h> +#else #include <unistd.h> +#endif #include "absl/strings/str_cat.h" #define LEVEL_REGEX_PATTERN "trace|debug|info|warning|error|critical|no_logs" diff --git a/swift/rules.bzl b/swift/rules.bzl index ba9e4b0e8bf..6ed085de63c 100644 --- a/swift/rules.bzl +++ b/swift/rules.bzl @@ -10,11 +10,13 @@ def _wrap_cc(rule, kwargs): # temporary, before we do universal merging "-universal_binaries", ]) - _add_args(kwargs, "target_compatible_with", select({ - "@platforms//os:linux": [], - "@platforms//os:macos": [], - "//conditions:default": ["@platforms//:incompatible"], - })) + if "target_compatible_with" not in kwargs: + # Restrict to Linux or macOS by default, but allow overriding + _add_args(kwargs, "target_compatible_with", select({ + "@platforms//os:linux": [], + "@platforms//os:macos": [], + "//conditions:default": ["@platforms//:incompatible"], + })) rule(**kwargs) def swift_cc_binary(**kwargs): diff --git a/swift/tools/autobuilder-diagnostics/BUILD.bazel b/swift/tools/autobuilder-diagnostics/BUILD.bazel index 32d6ce703e9..8e76b553c73 100644 --- a/swift/tools/autobuilder-diagnostics/BUILD.bazel +++ b/swift/tools/autobuilder-diagnostics/BUILD.bazel @@ -7,4 +7,6 @@ swift_cc_binary( deps = [ "//swift/logging", ], + # No restrictions (Windows allowed) + target_compatible_with = [], ) From 2bb3101316265c5d8640d520b68daac68269c19f Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Fri, 16 Jun 2023 17:22:43 +0100 Subject: [PATCH 643/739] Swift: Rename incompatible OS diagnostic to clarify that it's for the autobuilder. --- swift/BUILD.bazel | 8 ++++---- swift/tools/autobuild.sh | 2 +- .../AutobuilderIncompatibleOs.cpp} | 0 .../{autobuilder-diagnostics => diagnostics}/BUILD.bazel | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) rename swift/tools/{autobuilder-diagnostics/IncompatibleOs.cpp => diagnostics/AutobuilderIncompatibleOs.cpp} (100%) rename swift/tools/{autobuilder-diagnostics => diagnostics}/BUILD.bazel (72%) diff --git a/swift/BUILD.bazel b/swift/BUILD.bazel index af21fcc0c66..8ea073e991a 100644 --- a/swift/BUILD.bazel +++ b/swift/BUILD.bazel @@ -59,8 +59,8 @@ pkg_runfiles( ) pkg_runfiles( - name = "incompatible-os", - srcs = ["//swift/tools/autobuilder-diagnostics:incompatible-os"], + name = "diagnostics", + srcs = ["//swift/tools/diagnostics:autobuilder-incompatible-os"], prefix = "tools/" + codeql_platform, ) @@ -89,7 +89,7 @@ pkg_filegroup( ":xcode-autobuilder", ], "//conditions:default": [ - ":incompatible-os", + ":diagnostics", ], }), visibility = ["//visibility:public"], @@ -122,7 +122,7 @@ generate_cmake( "//swift/extractor:extractor.real", "//swift/logging/tests/assertion-diagnostics:assert-false", ] + select({ - "@platforms//os:linux": ["//swift/tools/autobuilder-diagnostics:incompatible-os"], + "@platforms//os:linux": ["//swift/tools/diagnostics:autobuilder-incompatible-os"], "@platforms//os:macos": ["//swift/xcode-autobuilder"], }), visibility = ["//visibility:public"], diff --git a/swift/tools/autobuild.sh b/swift/tools/autobuild.sh index 9be42363be6..3e25e800ced 100755 --- a/swift/tools/autobuild.sh +++ b/swift/tools/autobuild.sh @@ -3,5 +3,5 @@ if [[ "$OSTYPE" == "darwin"* ]]; then exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/xcode-autobuilder" else - exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/incompatible-os" + exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/autobuilder-incompatible-os" fi diff --git a/swift/tools/autobuilder-diagnostics/IncompatibleOs.cpp b/swift/tools/diagnostics/AutobuilderIncompatibleOs.cpp similarity index 100% rename from swift/tools/autobuilder-diagnostics/IncompatibleOs.cpp rename to swift/tools/diagnostics/AutobuilderIncompatibleOs.cpp diff --git a/swift/tools/autobuilder-diagnostics/BUILD.bazel b/swift/tools/diagnostics/BUILD.bazel similarity index 72% rename from swift/tools/autobuilder-diagnostics/BUILD.bazel rename to swift/tools/diagnostics/BUILD.bazel index 8e76b553c73..e02d6aed13b 100644 --- a/swift/tools/autobuilder-diagnostics/BUILD.bazel +++ b/swift/tools/diagnostics/BUILD.bazel @@ -1,12 +1,12 @@ load("//swift:rules.bzl", "swift_cc_binary") swift_cc_binary( - name = "incompatible-os", - srcs = ["IncompatibleOs.cpp"], + name = "autobuilder-incompatible-os", + srcs = ["AutobuilderIncompatibleOs.cpp"], + # No restrictions (Windows allowed) + target_compatible_with = [], visibility = ["//swift:__subpackages__"], deps = [ "//swift/logging", ], - # No restrictions (Windows allowed) - target_compatible_with = [], ) From 679df1e61b3fff76d8586eca9e1eece0142d4f35 Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Fri, 16 Jun 2023 17:23:50 +0100 Subject: [PATCH 644/739] Swift: Add "autobuilder" on Windows that simply shows an error. --- swift/BUILD.bazel | 23 +++++++++++++++-------- swift/tools/BUILD.bazel | 3 ++- swift/tools/autobuild.cmd | 1 + 3 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 swift/tools/autobuild.cmd diff --git a/swift/BUILD.bazel b/swift/BUILD.bazel index 8ea073e991a..83dff3f8033 100644 --- a/swift/BUILD.bazel +++ b/swift/BUILD.bazel @@ -38,11 +38,15 @@ pkg_files( pkg_filegroup( name = "extractor-pack-generic", srcs = [ - ":dbscheme_files", ":manifest", - "//swift/downgrades", "//swift/tools", - ], + ] + select({ + "@platforms//os:windows": [], + "//conditions:default": [ + ":dbscheme_files", + "//swift/downgrades", + ], + }), visibility = ["//visibility:public"], ) @@ -80,11 +84,14 @@ pkg_files( pkg_filegroup( name = "extractor-pack-arch", - srcs = [ - ":extractor", - ":swift-test-sdk-arch", - ":resource-dir-arch", - ] + select({ + srcs = select({ + "@platforms//os:windows": [], + "//conditions:default": [ + ":extractor", + ":resource-dir-arch", + ":swift-test-sdk-arch", + ], + }) + select({ "@platforms//os:macos": [ ":xcode-autobuilder", ], diff --git a/swift/tools/BUILD.bazel b/swift/tools/BUILD.bazel index 8a3496a2700..ee834e543cc 100644 --- a/swift/tools/BUILD.bazel +++ b/swift/tools/BUILD.bazel @@ -19,8 +19,9 @@ sh_binary( pkg_files( name = "scripts", srcs = [ - ":identify-environment", + "autobuild.cmd", ":autobuild", + ":identify-environment", ":qltest", ], attributes = pkg_attributes(mode = "0755"), diff --git a/swift/tools/autobuild.cmd b/swift/tools/autobuild.cmd new file mode 100644 index 00000000000..fc90f9f2f05 --- /dev/null +++ b/swift/tools/autobuild.cmd @@ -0,0 +1 @@ +"%CODEQL_EXTRACTOR_SWIFT_ROOT%/tools/%CODEQL_PLATFORM%/autobuilder-incompatible-os.exe" From abc6d62b6fa29763a4536708f91690d927a7ec0f Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov <sashabu@github.com> Date: Fri, 16 Jun 2023 17:24:04 +0100 Subject: [PATCH 645/739] Swift: Use platform-specific Bazel config. --- .bazelrc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.bazelrc b/.bazelrc index e0ab5a34335..214258e775a 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,3 +1,9 @@ -build --repo_env=CC=clang --repo_env=CXX=clang++ --cxxopt="-std=c++20" +common --enable_platform_specific_config + +build --repo_env=CC=clang --repo_env=CXX=clang++ + +build:linux --cxxopt=-std=c++20 +build:macos --cxxopt=-std=c++20 --cpu=darwin_x86_64 +build:windows --cxxopt=/std:c++20 --cxxopt=/Zc:preprocessor try-import %workspace%/local.bazelrc From 000add206c7b68a3546fb575e215a3ba3d4dc8c9 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 16 Jun 2023 19:05:04 +0200 Subject: [PATCH 646/739] Revert "Exclude `cpp/overrun-write` from `cpp-security-extended.qls`" This reverts commit 3aaa649076d5b7e726452a480588698b62df75a6. --- cpp/ql/src/codeql-suites/cpp-security-extended.qls | 3 --- 1 file changed, 3 deletions(-) diff --git a/cpp/ql/src/codeql-suites/cpp-security-extended.qls b/cpp/ql/src/codeql-suites/cpp-security-extended.qls index 75deda24ef5..69c014c4c6f 100644 --- a/cpp/ql/src/codeql-suites/cpp-security-extended.qls +++ b/cpp/ql/src/codeql-suites/cpp-security-extended.qls @@ -3,6 +3,3 @@ - apply: security-extended-selectors.yml from: codeql/suite-helpers - apply: codeql-suites/exclude-slow-queries.yml -- exclude: - id: cpp/overrun-write - From 0bb67e45b330340e0fbddb13d2215065360d7fa2 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 16 Jun 2023 19:07:56 +0200 Subject: [PATCH 647/739] C++: lower the precision of `cpp/overrun-write` to exclude it from our query suites --- cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql index 0d8648aac0a..a9af2d08f51 100644 --- a/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql +++ b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql @@ -5,7 +5,7 @@ * @kind path-problem * @problem.severity error * @security-severity 9.3 - * @precision medium + * @precision low * @id cpp/overrun-write * @tags reliability * security From 849e732c483b534d104a0b3921f0a670097e5dec Mon Sep 17 00:00:00 2001 From: Maiky <76447395+maikypedia@users.noreply.github.com> Date: Mon, 19 Jun 2023 01:16:27 +0200 Subject: [PATCH 648/739] typos --- ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll | 2 +- ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll index f74e919ffe5..350eb5028e3 100644 --- a/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/SqlInjectionQuery.qll @@ -15,7 +15,7 @@ class Configuration extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof Source } - override predicate isSink(DataFlow::Node source) { source instanceof Sink } + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } diff --git a/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll b/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll index 827e582be6c..2726f053b8c 100644 --- a/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll @@ -15,7 +15,7 @@ class Configuration extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof Source } - override predicate isSink(DataFlow::Node source) { source instanceof Sink } + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } From 433fc680ecb608b5db1a2ea9305acba99ba2d852 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 19 Jun 2023 10:17:40 +0200 Subject: [PATCH 649/739] Apply suggestions from code review Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md | 2 +- go/ql/src/change-notes/2023-06-16-zipslip-rename.md | 2 +- java/ql/src/change-notes/2023-06-16-zipslip-rename.md | 2 +- javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md | 2 +- python/ql/src/change-notes/2023-06-16-zipslip-rename.md | 2 +- ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md b/csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md index 2816d74945c..3c13e6da67a 100644 --- a/csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md +++ b/csharp/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -1,4 +1,4 @@ --- category: fix --- -* The query "Arbitrary file write during zip extraction ("Zip Slip")" (`cs/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". +* The query "Arbitrary file write during zip extraction ("Zip Slip")" (`cs/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")." diff --git a/go/ql/src/change-notes/2023-06-16-zipslip-rename.md b/go/ql/src/change-notes/2023-06-16-zipslip-rename.md index 9e9d1483ad6..72913f37c06 100644 --- a/go/ql/src/change-notes/2023-06-16-zipslip-rename.md +++ b/go/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -1,4 +1,4 @@ --- category: fix --- -* The query "Arbitrary file write during zip extraction ("zip slip")" (`go/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". +* The query "Arbitrary file write during zip extraction ("zip slip")" (`go/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")." diff --git a/java/ql/src/change-notes/2023-06-16-zipslip-rename.md b/java/ql/src/change-notes/2023-06-16-zipslip-rename.md index 39316e46f5d..fa1343317ba 100644 --- a/java/ql/src/change-notes/2023-06-16-zipslip-rename.md +++ b/java/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -1,4 +1,4 @@ --- category: fix --- -* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`java/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". +* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`java/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")." diff --git a/javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md b/javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md index 0d866964347..3a0654e642e 100644 --- a/javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md +++ b/javascript/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -1,4 +1,4 @@ --- category: fix --- -* The query "Arbitrary file write during zip extraction ("Zip Slip")" (`js/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". +* The query "Arbitrary file write during zip extraction ("Zip Slip")" (`js/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")." diff --git a/python/ql/src/change-notes/2023-06-16-zipslip-rename.md b/python/ql/src/change-notes/2023-06-16-zipslip-rename.md index 50313eb7d27..4d4d4db15c3 100644 --- a/python/ql/src/change-notes/2023-06-16-zipslip-rename.md +++ b/python/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -1,4 +1,4 @@ --- category: fix --- -* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`py/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". +* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`py/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")." diff --git a/ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md b/ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md index 8e56e960ec4..eeb9c5254bb 100644 --- a/ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md +++ b/ruby/ql/src/change-notes/2023-06-16-zipslip-rename.md @@ -1,4 +1,4 @@ --- category: fix --- -* The experimental query "Arbitrary file write during zipfile/tarfile extraction" (`ruby/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")". +* The experimental query "Arbitrary file write during zipfile/tarfile extraction" (`ruby/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")." From 3c4d938cf1c91572d4d43f8e09653c1da34f751a Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 19 Jun 2023 10:18:02 +0200 Subject: [PATCH 650/739] Apply code review suggestions. Co-authored-by: Asger F <asgerf@github.com> --- csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp | 7 +++---- go/ql/src/Security/CWE-022/ZipSlip.qhelp | 6 +++--- java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp | 7 +++---- javascript/ql/src/Security/CWE-022/ZipSlip.qhelp | 6 +++--- python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp | 7 +++---- ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp | 7 +++---- 6 files changed, 18 insertions(+), 22 deletions(-) diff --git a/csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp b/csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp index e1e2974ed4f..a1f39d27b8c 100644 --- a/csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp +++ b/csharp/ql/src/Security Features/CWE-022/ZipSlip.qhelp @@ -3,10 +3,9 @@ "qhelp.dtd"> <qhelp> <overview> -<p>Accessing filesystem paths built from the name of an archive entry without validating that the -destination file path is within the destination directory can allow an attacker to access -unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in -archive paths.</p> +<p>Extracting files from a malicious zip file, or similar type of archive, +is at risk of directory traversal attacks if filenames from the archive are +not properly validated.</p> <p>Zip archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain diff --git a/go/ql/src/Security/CWE-022/ZipSlip.qhelp b/go/ql/src/Security/CWE-022/ZipSlip.qhelp index 1c47eac9a53..ecea2eaeec9 100644 --- a/go/ql/src/Security/CWE-022/ZipSlip.qhelp +++ b/go/ql/src/Security/CWE-022/ZipSlip.qhelp @@ -5,9 +5,9 @@ <overview> <p> -Accessing filesystem paths built from the name of an archive entry without validating that the -destination file path is within the destination directory can allow an attacker to access -unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in +Extracting files from a malicious zip file, or similar type of archive, +is at risk of directory traversal attacks if filenames from the archive are +not properly validated. archive paths. </p> diff --git a/java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp b/java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp index 726b2d15cb6..2caf0ccc8b0 100644 --- a/java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp +++ b/java/ql/src/Security/CWE/CWE-022/ZipSlip.qhelp @@ -3,10 +3,9 @@ "qhelp.dtd"> <qhelp> <overview> -<p>Accessing filesystem paths built from the name of an archive entry without validating that the -destination file path is within the destination directory can allow an attacker to access -unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in -archive paths.</p> +<p>Extracting files from a malicious zip file, or similar type of archive, +is at risk of directory traversal attacks if filenames from the archive are +not properly validated.</p> <p>Zip archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain diff --git a/javascript/ql/src/Security/CWE-022/ZipSlip.qhelp b/javascript/ql/src/Security/CWE-022/ZipSlip.qhelp index bbb3824e41e..2318ad859f0 100644 --- a/javascript/ql/src/Security/CWE-022/ZipSlip.qhelp +++ b/javascript/ql/src/Security/CWE-022/ZipSlip.qhelp @@ -4,9 +4,9 @@ <qhelp> <overview> -<p>Accessing filesystem paths built from the name of an archive entry without validating that the -destination file path is within the destination directory can allow an attacker to access -unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in +<p>Extracting files from a malicious zip file, or similar type of archive, +is at risk of directory traversal attacks if filenames from the archive are +not properly validated. archive paths.</p> <p>Zip archives contain archive entries representing each file in the archive. These entries diff --git a/python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp b/python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp index dfd563ea19b..4afb7cc9a2a 100644 --- a/python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp +++ b/python/ql/src/experimental/Security/CWE-022/ZipSlip.qhelp @@ -4,10 +4,9 @@ <qhelp> <overview> -<p>Accessing filesystem paths built from the name of an archive entry without validating that the -destination file path is within the destination directory can allow an attacker to access -unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in -archive paths.</p> +<p>Extracting files from a malicious zip file, or similar type of archive, +is at risk of directory traversal attacks if filenames from the archive are +not properly validated.</p> <p>Zip archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain diff --git a/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp b/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp index 2794db7efbd..7d7435ee907 100644 --- a/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp +++ b/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.qhelp @@ -4,10 +4,9 @@ <qhelp> <overview> -<p>Accessing filesystem paths built from the name of an archive entry without validating that the -destination file path is within the destination directory can allow an attacker to access -unexpected resources, due to the possible presence of directory traversal elements (<code>..</code>) in -archive paths.</p> +<p>Extracting files from a malicious zip file, or similar type of archive, +is at risk of directory traversal attacks if filenames from the archive are +not properly validated.</p> <p>Tar archives contain archive entries representing each file in the archive. These entries include a file path for the entry, but these file paths are not restricted and may contain From 8f6d2ed2f9045420e8331852f1b7e1942d9775fc Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 19 Jun 2023 10:27:41 +0200 Subject: [PATCH 651/739] Adjust ZipSlip query description according to review suggestions. --- csharp/ql/src/Security Features/CWE-022/ZipSlip.ql | 4 ++-- go/ql/src/Security/CWE-022/ZipSlip.ql | 4 ++-- java/ql/src/Security/CWE/CWE-022/ZipSlip.ql | 4 ++-- javascript/ql/src/Security/CWE-022/ZipSlip.ql | 4 ++-- python/ql/src/experimental/Security/CWE-022/ZipSlip.ql | 4 ++-- ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql b/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql index 25a1e9bcd19..2e4d59aaf7e 100644 --- a/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql +++ b/csharp/ql/src/Security Features/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** * @name Arbitrary file access during archive extraction ("Zip Slip") - * @description Accessing filesystem paths built from the name of an archive entry without + * @description Extracting files from a malicious ZIP file, or similar type of archive, without * validating that the destination file path is within the destination directory - * can allow an attacker to access unexpected resources. + * can allow an attacker to unexpectedly gain access to resources. * @kind path-problem * @id cs/zipslip * @problem.severity error diff --git a/go/ql/src/Security/CWE-022/ZipSlip.ql b/go/ql/src/Security/CWE-022/ZipSlip.ql index 27c18248ad5..5cfb3998f4d 100644 --- a/go/ql/src/Security/CWE-022/ZipSlip.ql +++ b/go/ql/src/Security/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** * @name Arbitrary file access during archive extraction ("Zip Slip") - * @description Accessing filesystem paths built from the name of an archive entry without + * @description Extracting files from a malicious ZIP file, or similar type of archive, without * validating that the destination file path is within the destination directory - * can allow an attacker to access unexpected resources. + * can allow an attacker to unexpectedly gain access to resources. * @kind path-problem * @id go/zipslip * @problem.severity error diff --git a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql index 2c48ecb2aa1..0d165a73521 100644 --- a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql +++ b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** * @name Arbitrary file access during archive extraction ("Zip Slip") - * @description Accessing filesystem paths built from the name of an archive entry without + * @description Extracting files from a malicious ZIP file, or similar type of archive, without * validating that the destination file path is within the destination directory - * can allow an attacker to access unexpected resources. + * can allow an attacker to unexpectedly gain access to resources. * @kind path-problem * @id java/zipslip * @problem.severity error diff --git a/javascript/ql/src/Security/CWE-022/ZipSlip.ql b/javascript/ql/src/Security/CWE-022/ZipSlip.ql index f9c468c388a..aef13830eb1 100644 --- a/javascript/ql/src/Security/CWE-022/ZipSlip.ql +++ b/javascript/ql/src/Security/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** * @name Arbitrary file access during archive extraction ("Zip Slip") - * @description Accessing filesystem paths built from the name of an archive entry without + * @description Extracting files from a malicious ZIP file, or similar type of archive, without * validating that the destination file path is within the destination directory - * can allow an attacker to access unexpected resources. + * can allow an attacker to unexpectedly gain access to resources. * @kind path-problem * @id js/zipslip * @problem.severity error diff --git a/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql b/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql index b00214cfe68..eba8da087b3 100644 --- a/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql +++ b/python/ql/src/experimental/Security/CWE-022/ZipSlip.ql @@ -1,8 +1,8 @@ /** * @name Arbitrary file access during archive extraction ("Zip Slip") - * @description Accessing filesystem paths built from the name of an archive entry without + * @description Extracting files from a malicious ZIP file, or similar type of archive, without * validating that the destination file path is within the destination directory - * can allow an attacker to access unexpected resources. + * can allow an attacker to unexpectedly gain access to resources. * @kind path-problem * @id py/zipslip * @problem.severity error diff --git a/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql b/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql index 709e89f98e8..329f4b89977 100644 --- a/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql +++ b/ruby/ql/src/experimental/cwe-022-zipslip/ZipSlip.ql @@ -1,8 +1,8 @@ /** * @name Arbitrary file access during archive extraction ("Zip Slip") - * @description Accessing filesystem paths built from the name of an archive entry without + * @description Extracting files from a malicious ZIP file, or similar type of archive, without * validating that the destination file path is within the destination directory - * can allow an attacker to access unexpected resources. + * can allow an attacker to unexpectedly gain access to resources. * @kind path-problem * @id rb/zip-slip * @problem.severity error From 6a84e6cbfd285feb9fb4fde4395782a10532b2c0 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 19 Jun 2023 10:28:10 +0200 Subject: [PATCH 652/739] Add the merged `PathGraph` to all copies of the `InlineFlowTest` library --- csharp/ql/test/TestUtilities/InlineFlowTest.qll | 12 +++++++++--- go/ql/test/TestUtilities/InlineFlowTest.qll | 11 +++++++++++ java/ql/test/TestUtilities/InlineFlowTest.qll | 12 ++++++++++++ ruby/ql/test/TestUtilities/InlineFlowTest.qll | 4 ++-- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/csharp/ql/test/TestUtilities/InlineFlowTest.qll b/csharp/ql/test/TestUtilities/InlineFlowTest.qll index dc95063f03f..718752a978a 100644 --- a/csharp/ql/test/TestUtilities/InlineFlowTest.qll +++ b/csharp/ql/test/TestUtilities/InlineFlowTest.qll @@ -6,10 +6,10 @@ * import csharp * import TestUtilities.InlineFlowTest * import DefaultFlowTest - * import ValueFlow::PathGraph + * import PathGraph * - * from ValueFlow::PathNode source, ValueFlow::PathNode sink - * where ValueFlow::flowPath(source, sink) + * from PathNode source, PathNode sink + * where flowPath(source, sink) * select sink, source, sink, "$@", source, source.toString() * * ``` @@ -101,6 +101,12 @@ module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFl } import MakeTest<InlineTest> + import DataFlow::MergePathGraph<ValueFlow::PathNode, TaintFlow::PathNode, ValueFlow::PathGraph, TaintFlow::PathGraph> + + predicate flowPath(PathNode source, PathNode sink) { + ValueFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) or + TaintFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) + } } module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>; diff --git a/go/ql/test/TestUtilities/InlineFlowTest.qll b/go/ql/test/TestUtilities/InlineFlowTest.qll index f8d54c82f3f..4f3cfc7599a 100644 --- a/go/ql/test/TestUtilities/InlineFlowTest.qll +++ b/go/ql/test/TestUtilities/InlineFlowTest.qll @@ -6,6 +6,11 @@ * import go * import TestUtilities.InlineFlowTest * import DefaultFlowTest + * import PathGraph + * + * from PathNode source, PathNode sink + * where flowPath(source, sink) + * select sink, source, sink, "$@", source, source.toString() * ``` * * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. @@ -88,6 +93,12 @@ module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFl } import MakeTest<InlineTest> + import DataFlow::MergePathGraph<ValueFlow::PathNode, TaintFlow::PathNode, ValueFlow::PathGraph, TaintFlow::PathGraph> + + predicate flowPath(PathNode source, PathNode sink) { + ValueFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) or + TaintFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) + } } module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>; diff --git a/java/ql/test/TestUtilities/InlineFlowTest.qll b/java/ql/test/TestUtilities/InlineFlowTest.qll index 6f344c5074e..45ba10ee149 100644 --- a/java/ql/test/TestUtilities/InlineFlowTest.qll +++ b/java/ql/test/TestUtilities/InlineFlowTest.qll @@ -6,6 +6,12 @@ * import java * import TestUtilities.InlineFlowTest * import DefaultFlowTest + * import PathGraph + * + * from PathNode source, PathNode sink + * where flowPath(source, sink) + * select sink, source, sink, "$@", source, source.toString() + * ``` * * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. @@ -95,6 +101,12 @@ module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFl } import MakeTest<InlineTest> + import DataFlow::MergePathGraph<ValueFlow::PathNode, TaintFlow::PathNode, ValueFlow::PathGraph, TaintFlow::PathGraph> + + predicate flowPath(PathNode source, PathNode sink) { + ValueFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) or + TaintFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) + } } module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>; diff --git a/ruby/ql/test/TestUtilities/InlineFlowTest.qll b/ruby/ql/test/TestUtilities/InlineFlowTest.qll index af83862803c..cefd109f0a9 100644 --- a/ruby/ql/test/TestUtilities/InlineFlowTest.qll +++ b/ruby/ql/test/TestUtilities/InlineFlowTest.qll @@ -7,8 +7,8 @@ * import DefaultFlowTest * import PathGraph * - * from ValueFlow::PathNode source, ValueFlow::PathNode sink - * where ValueFlow::flowPath(source, sink) + * from PathNode source, PathNode sink + * where flowPath(source, sink) * select sink, source, sink, "$@", source, source.toString() * ``` * From b420455e2baf315252a2cff980484f9fb2490f43 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 19 Jun 2023 10:28:54 +0200 Subject: [PATCH 653/739] C#: Update `InlineFlowTest`s to use the merged path graph --- .../dataflow/fields/FieldFlow.expected | 1095 +++++++++++++++++ .../dataflow/fields/FieldFlow.ql | 6 +- .../dataflow/operators/operatorFlow.expected | 90 ++ .../dataflow/operators/operatorFlow.ql | 6 +- .../dataflow/patterns/PatternFlow.ql | 6 +- .../dataflow/tuples/Tuples.expected | 228 ++++ .../library-tests/dataflow/tuples/Tuples.ql | 6 +- 7 files changed, 1425 insertions(+), 12 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected index a0d9a917702..7466125341d 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected @@ -2,1100 +2,2195 @@ failures testFailures edges | A.cs:5:17:5:28 | call to method Source<C> : C | A.cs:6:24:6:24 | access to local variable c : C | +| A.cs:5:17:5:28 | call to method Source<C> : C | A.cs:6:24:6:24 | access to local variable c : C | +| A.cs:6:17:6:25 | call to method Make : B [field c] : C | A.cs:7:14:7:14 | access to local variable b : B [field c] : C | | A.cs:6:17:6:25 | call to method Make : B [field c] : C | A.cs:7:14:7:14 | access to local variable b : B [field c] : C | | A.cs:6:24:6:24 | access to local variable c : C | A.cs:6:17:6:25 | call to method Make : B [field c] : C | +| A.cs:6:24:6:24 | access to local variable c : C | A.cs:6:17:6:25 | call to method Make : B [field c] : C | +| A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | | A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | | A.cs:7:14:7:14 | access to local variable b : B [field c] : C | A.cs:7:14:7:16 | access to field c | +| A.cs:7:14:7:14 | access to local variable b : B [field c] : C | A.cs:7:14:7:16 | access to field c | +| A.cs:13:9:13:9 | [post] access to local variable b : B [field c] : C1 | A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | | A.cs:13:9:13:9 | [post] access to local variable b : B [field c] : C1 | A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | | A.cs:13:15:13:29 | call to method Source<C1> : C1 | A.cs:13:9:13:9 | [post] access to local variable b : B [field c] : C1 | +| A.cs:13:15:13:29 | call to method Source<C1> : C1 | A.cs:13:9:13:9 | [post] access to local variable b : B [field c] : C1 | +| A.cs:13:15:13:29 | call to method Source<C1> : C1 | A.cs:145:27:145:27 | c : C1 | | A.cs:13:15:13:29 | call to method Source<C1> : C1 | A.cs:145:27:145:27 | c : C1 | | A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | A.cs:14:14:14:20 | call to method Get | +| A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | A.cs:14:14:14:20 | call to method Get | +| A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | A.cs:146:18:146:20 | this : B [field c] : C1 | | A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | A.cs:146:18:146:20 | this : B [field c] : C1 | | A.cs:15:15:15:35 | object creation of type B : B [field c] : C | A.cs:15:14:15:42 | call to method Get | +| A.cs:15:15:15:35 | object creation of type B : B [field c] : C | A.cs:15:14:15:42 | call to method Get | +| A.cs:15:15:15:35 | object creation of type B : B [field c] : C | A.cs:146:18:146:20 | this : B [field c] : C | | A.cs:15:15:15:35 | object creation of type B : B [field c] : C | A.cs:146:18:146:20 | this : B [field c] : C | | A.cs:15:21:15:34 | call to method Source<C> : C | A.cs:15:15:15:35 | object creation of type B : B [field c] : C | +| A.cs:15:21:15:34 | call to method Source<C> : C | A.cs:15:15:15:35 | object creation of type B : B [field c] : C | +| A.cs:15:21:15:34 | call to method Source<C> : C | A.cs:141:20:141:20 | c : C | | A.cs:15:21:15:34 | call to method Source<C> : C | A.cs:141:20:141:20 | c : C | | A.cs:22:14:22:38 | call to method SetOnB : B [field c] : C2 | A.cs:24:14:24:15 | access to local variable b2 : B [field c] : C2 | +| A.cs:22:14:22:38 | call to method SetOnB : B [field c] : C2 | A.cs:24:14:24:15 | access to local variable b2 : B [field c] : C2 | +| A.cs:22:25:22:37 | call to method Source<C2> : C2 | A.cs:22:14:22:38 | call to method SetOnB : B [field c] : C2 | | A.cs:22:25:22:37 | call to method Source<C2> : C2 | A.cs:22:14:22:38 | call to method SetOnB : B [field c] : C2 | | A.cs:22:25:22:37 | call to method Source<C2> : C2 | A.cs:42:29:42:29 | c : C2 | +| A.cs:22:25:22:37 | call to method Source<C2> : C2 | A.cs:42:29:42:29 | c : C2 | +| A.cs:24:14:24:15 | access to local variable b2 : B [field c] : C2 | A.cs:24:14:24:17 | access to field c | | A.cs:24:14:24:15 | access to local variable b2 : B [field c] : C2 | A.cs:24:14:24:17 | access to field c | | A.cs:31:14:31:42 | call to method SetOnBWrap : B [field c] : C2 | A.cs:33:14:33:15 | access to local variable b2 : B [field c] : C2 | +| A.cs:31:14:31:42 | call to method SetOnBWrap : B [field c] : C2 | A.cs:33:14:33:15 | access to local variable b2 : B [field c] : C2 | +| A.cs:31:29:31:41 | call to method Source<C2> : C2 | A.cs:31:14:31:42 | call to method SetOnBWrap : B [field c] : C2 | | A.cs:31:29:31:41 | call to method Source<C2> : C2 | A.cs:31:14:31:42 | call to method SetOnBWrap : B [field c] : C2 | | A.cs:31:29:31:41 | call to method Source<C2> : C2 | A.cs:36:33:36:33 | c : C2 | +| A.cs:31:29:31:41 | call to method Source<C2> : C2 | A.cs:36:33:36:33 | c : C2 | +| A.cs:33:14:33:15 | access to local variable b2 : B [field c] : C2 | A.cs:33:14:33:17 | access to field c | | A.cs:33:14:33:15 | access to local variable b2 : B [field c] : C2 | A.cs:33:14:33:17 | access to field c | | A.cs:36:33:36:33 | c : C2 | A.cs:38:29:38:29 | access to parameter c : C2 | +| A.cs:36:33:36:33 | c : C2 | A.cs:38:29:38:29 | access to parameter c : C2 | +| A.cs:38:18:38:30 | call to method SetOnB : B [field c] : C2 | A.cs:39:16:39:28 | ... ? ... : ... : B [field c] : C2 | | A.cs:38:18:38:30 | call to method SetOnB : B [field c] : C2 | A.cs:39:16:39:28 | ... ? ... : ... : B [field c] : C2 | | A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:38:18:38:30 | call to method SetOnB : B [field c] : C2 | +| A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:38:18:38:30 | call to method SetOnB : B [field c] : C2 | +| A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:42:29:42:29 | c : C2 | | A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:42:29:42:29 | c : C2 | | A.cs:42:29:42:29 | c : C2 | A.cs:47:20:47:20 | access to parameter c : C2 | +| A.cs:42:29:42:29 | c : C2 | A.cs:47:20:47:20 | access to parameter c : C2 | +| A.cs:47:13:47:14 | [post] access to local variable b2 : B [field c] : C2 | A.cs:48:20:48:21 | access to local variable b2 : B [field c] : C2 | | A.cs:47:13:47:14 | [post] access to local variable b2 : B [field c] : C2 | A.cs:48:20:48:21 | access to local variable b2 : B [field c] : C2 | | A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:47:13:47:14 | [post] access to local variable b2 : B [field c] : C2 | +| A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:47:13:47:14 | [post] access to local variable b2 : B [field c] : C2 | +| A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:145:27:145:27 | c : C2 | | A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:145:27:145:27 | c : C2 | | A.cs:55:17:55:28 | call to method Source<A> : A | A.cs:57:16:57:16 | access to local variable a : A | +| A.cs:55:17:55:28 | call to method Source<A> : A | A.cs:57:16:57:16 | access to local variable a : A | +| A.cs:57:9:57:10 | [post] access to local variable c1 : C1 [field a] : A | A.cs:58:12:58:13 | access to local variable c1 : C1 [field a] : A | | A.cs:57:9:57:10 | [post] access to local variable c1 : C1 [field a] : A | A.cs:58:12:58:13 | access to local variable c1 : C1 [field a] : A | | A.cs:57:16:57:16 | access to local variable a : A | A.cs:57:9:57:10 | [post] access to local variable c1 : C1 [field a] : A | +| A.cs:57:16:57:16 | access to local variable a : A | A.cs:57:9:57:10 | [post] access to local variable c1 : C1 [field a] : A | +| A.cs:58:12:58:13 | access to local variable c1 : C1 [field a] : A | A.cs:60:22:60:22 | c : C1 [field a] : A | | A.cs:58:12:58:13 | access to local variable c1 : C1 [field a] : A | A.cs:60:22:60:22 | c : C1 [field a] : A | | A.cs:60:22:60:22 | c : C1 [field a] : A | A.cs:64:19:64:23 | (...) ... : C1 [field a] : A | +| A.cs:60:22:60:22 | c : C1 [field a] : A | A.cs:64:19:64:23 | (...) ... : C1 [field a] : A | +| A.cs:64:19:64:23 | (...) ... : C1 [field a] : A | A.cs:64:18:64:26 | access to field a | | A.cs:64:19:64:23 | (...) ... : C1 [field a] : A | A.cs:64:18:64:26 | access to field a | | A.cs:83:9:83:9 | [post] access to parameter b : B [field c] : C | A.cs:88:12:88:12 | [post] access to local variable b : B [field c] : C | +| A.cs:83:9:83:9 | [post] access to parameter b : B [field c] : C | A.cs:88:12:88:12 | [post] access to local variable b : B [field c] : C | +| A.cs:83:15:83:26 | call to method Source<C> : C | A.cs:83:9:83:9 | [post] access to parameter b : B [field c] : C | | A.cs:83:15:83:26 | call to method Source<C> : C | A.cs:83:9:83:9 | [post] access to parameter b : B [field c] : C | | A.cs:83:15:83:26 | call to method Source<C> : C | A.cs:145:27:145:27 | c : C | +| A.cs:83:15:83:26 | call to method Source<C> : C | A.cs:145:27:145:27 | c : C | +| A.cs:88:12:88:12 | [post] access to local variable b : B [field c] : C | A.cs:89:14:89:14 | access to local variable b : B [field c] : C | | A.cs:88:12:88:12 | [post] access to local variable b : B [field c] : C | A.cs:89:14:89:14 | access to local variable b : B [field c] : C | | A.cs:89:14:89:14 | access to local variable b : B [field c] : C | A.cs:89:14:89:16 | access to field c | +| A.cs:89:14:89:14 | access to local variable b : B [field c] : C | A.cs:89:14:89:16 | access to field c | +| A.cs:95:20:95:20 | b : B | A.cs:97:13:97:13 | access to parameter b : B | | A.cs:95:20:95:20 | b : B | A.cs:97:13:97:13 | access to parameter b : B | | A.cs:97:13:97:13 | [post] access to parameter b : B [field c] : C | A.cs:98:22:98:43 | ... ? ... : ... : B [field c] : C | +| A.cs:97:13:97:13 | [post] access to parameter b : B [field c] : C | A.cs:98:22:98:43 | ... ? ... : ... : B [field c] : C | +| A.cs:97:13:97:13 | [post] access to parameter b : B [field c] : C | A.cs:105:23:105:23 | [post] access to local variable b : B [field c] : C | | A.cs:97:13:97:13 | [post] access to parameter b : B [field c] : C | A.cs:105:23:105:23 | [post] access to local variable b : B [field c] : C | | A.cs:97:13:97:13 | access to parameter b : B | A.cs:98:22:98:43 | ... ? ... : ... : B | +| A.cs:97:13:97:13 | access to parameter b : B | A.cs:98:22:98:43 | ... ? ... : ... : B | +| A.cs:97:19:97:32 | call to method Source<C> : C | A.cs:97:13:97:13 | [post] access to parameter b : B [field c] : C | | A.cs:97:19:97:32 | call to method Source<C> : C | A.cs:97:13:97:13 | [post] access to parameter b : B [field c] : C | | A.cs:98:13:98:16 | [post] this access : D [field b, field c] : C | A.cs:105:17:105:29 | object creation of type D : D [field b, field c] : C | +| A.cs:98:13:98:16 | [post] this access : D [field b, field c] : C | A.cs:105:17:105:29 | object creation of type D : D [field b, field c] : C | +| A.cs:98:13:98:16 | [post] this access : D [field b] : B | A.cs:105:17:105:29 | object creation of type D : D [field b] : B | | A.cs:98:13:98:16 | [post] this access : D [field b] : B | A.cs:105:17:105:29 | object creation of type D : D [field b] : B | | A.cs:98:22:98:43 | ... ? ... : ... : B | A.cs:98:13:98:16 | [post] this access : D [field b] : B | | A.cs:98:22:98:43 | ... ? ... : ... : B | A.cs:98:13:98:16 | [post] this access : D [field b] : B | +| A.cs:98:22:98:43 | ... ? ... : ... : B | A.cs:98:13:98:16 | [post] this access : D [field b] : B | +| A.cs:98:22:98:43 | ... ? ... : ... : B | A.cs:98:13:98:16 | [post] this access : D [field b] : B | +| A.cs:98:22:98:43 | ... ? ... : ... : B [field c] : C | A.cs:98:13:98:16 | [post] this access : D [field b, field c] : C | | A.cs:98:22:98:43 | ... ? ... : ... : B [field c] : C | A.cs:98:13:98:16 | [post] this access : D [field b, field c] : C | | A.cs:98:30:98:43 | call to method Source<B> : B | A.cs:98:22:98:43 | ... ? ... : ... : B | +| A.cs:98:30:98:43 | call to method Source<B> : B | A.cs:98:22:98:43 | ... ? ... : ... : B | +| A.cs:104:17:104:30 | call to method Source<B> : B | A.cs:105:23:105:23 | access to local variable b : B | | A.cs:104:17:104:30 | call to method Source<B> : B | A.cs:105:23:105:23 | access to local variable b : B | | A.cs:105:17:105:29 | object creation of type D : D [field b, field c] : C | A.cs:107:14:107:14 | access to local variable d : D [field b, field c] : C | +| A.cs:105:17:105:29 | object creation of type D : D [field b, field c] : C | A.cs:107:14:107:14 | access to local variable d : D [field b, field c] : C | +| A.cs:105:17:105:29 | object creation of type D : D [field b] : B | A.cs:106:14:106:14 | access to local variable d : D [field b] : B | | A.cs:105:17:105:29 | object creation of type D : D [field b] : B | A.cs:106:14:106:14 | access to local variable d : D [field b] : B | | A.cs:105:23:105:23 | [post] access to local variable b : B [field c] : C | A.cs:108:14:108:14 | access to local variable b : B [field c] : C | +| A.cs:105:23:105:23 | [post] access to local variable b : B [field c] : C | A.cs:108:14:108:14 | access to local variable b : B [field c] : C | +| A.cs:105:23:105:23 | access to local variable b : B | A.cs:95:20:95:20 | b : B | | A.cs:105:23:105:23 | access to local variable b : B | A.cs:95:20:95:20 | b : B | | A.cs:105:23:105:23 | access to local variable b : B | A.cs:105:17:105:29 | object creation of type D : D [field b] : B | +| A.cs:105:23:105:23 | access to local variable b : B | A.cs:105:17:105:29 | object creation of type D : D [field b] : B | +| A.cs:106:14:106:14 | access to local variable d : D [field b] : B | A.cs:106:14:106:16 | access to field b | | A.cs:106:14:106:14 | access to local variable d : D [field b] : B | A.cs:106:14:106:16 | access to field b | | A.cs:107:14:107:14 | access to local variable d : D [field b, field c] : C | A.cs:107:14:107:16 | access to field b : B [field c] : C | +| A.cs:107:14:107:14 | access to local variable d : D [field b, field c] : C | A.cs:107:14:107:16 | access to field b : B [field c] : C | +| A.cs:107:14:107:16 | access to field b : B [field c] : C | A.cs:107:14:107:18 | access to field c | | A.cs:107:14:107:16 | access to field b : B [field c] : C | A.cs:107:14:107:18 | access to field c | | A.cs:108:14:108:14 | access to local variable b : B [field c] : C | A.cs:108:14:108:16 | access to field c | +| A.cs:108:14:108:14 | access to local variable b : B [field c] : C | A.cs:108:14:108:16 | access to field c | +| A.cs:113:17:113:29 | call to method Source<B> : B | A.cs:114:29:114:29 | access to local variable b : B | | A.cs:113:17:113:29 | call to method Source<B> : B | A.cs:114:29:114:29 | access to local variable b : B | | A.cs:114:18:114:54 | object creation of type MyList : MyList [field head] : B | A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | +| A.cs:114:18:114:54 | object creation of type MyList : MyList [field head] : B | A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | +| A.cs:114:29:114:29 | access to local variable b : B | A.cs:114:18:114:54 | object creation of type MyList : MyList [field head] : B | | A.cs:114:29:114:29 | access to local variable b : B | A.cs:114:18:114:54 | object creation of type MyList : MyList [field head] : B | | A.cs:114:29:114:29 | access to local variable b : B | A.cs:157:25:157:28 | head : B | +| A.cs:114:29:114:29 | access to local variable b : B | A.cs:157:25:157:28 | head : B | +| A.cs:115:18:115:37 | object creation of type MyList : MyList [field next, field head] : B | A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | | A.cs:115:18:115:37 | object creation of type MyList : MyList [field next, field head] : B | A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | | A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | A.cs:115:18:115:37 | object creation of type MyList : MyList [field next, field head] : B | +| A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | A.cs:115:18:115:37 | object creation of type MyList : MyList [field next, field head] : B | +| A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | A.cs:157:38:157:41 | next : MyList [field head] : B | | A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | A.cs:157:38:157:41 | next : MyList [field head] : B | | A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | A.cs:119:14:119:15 | access to local variable l3 : MyList [field next, field next, field head] : B | +| A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | A.cs:119:14:119:15 | access to local variable l3 : MyList [field next, field next, field head] : B | +| A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | A.cs:121:41:121:41 | access to local variable l : MyList [field next, field next, field head] : B | | A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | A.cs:121:41:121:41 | access to local variable l : MyList [field next, field next, field head] : B | | A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | +| A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | +| A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | A.cs:157:38:157:41 | next : MyList [field next, field head] : B | | A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | A.cs:157:38:157:41 | next : MyList [field next, field head] : B | | A.cs:119:14:119:15 | access to local variable l3 : MyList [field next, field next, field head] : B | A.cs:119:14:119:20 | access to field next : MyList [field next, field head] : B | +| A.cs:119:14:119:15 | access to local variable l3 : MyList [field next, field next, field head] : B | A.cs:119:14:119:20 | access to field next : MyList [field next, field head] : B | +| A.cs:119:14:119:20 | access to field next : MyList [field next, field head] : B | A.cs:119:14:119:25 | access to field next : MyList [field head] : B | | A.cs:119:14:119:20 | access to field next : MyList [field next, field head] : B | A.cs:119:14:119:25 | access to field next : MyList [field head] : B | | A.cs:119:14:119:25 | access to field next : MyList [field head] : B | A.cs:119:14:119:30 | access to field head | +| A.cs:119:14:119:25 | access to field next : MyList [field head] : B | A.cs:119:14:119:30 | access to field head | +| A.cs:121:41:121:41 | access to local variable l : MyList [field next, field head] : B | A.cs:121:41:121:46 | access to field next : MyList [field head] : B | | A.cs:121:41:121:41 | access to local variable l : MyList [field next, field head] : B | A.cs:121:41:121:46 | access to field next : MyList [field head] : B | | A.cs:121:41:121:41 | access to local variable l : MyList [field next, field next, field head] : B | A.cs:121:41:121:46 | access to field next : MyList [field next, field head] : B | +| A.cs:121:41:121:41 | access to local variable l : MyList [field next, field next, field head] : B | A.cs:121:41:121:46 | access to field next : MyList [field next, field head] : B | +| A.cs:121:41:121:46 | access to field next : MyList [field head] : B | A.cs:123:18:123:18 | access to local variable l : MyList [field head] : B | | A.cs:121:41:121:46 | access to field next : MyList [field head] : B | A.cs:123:18:123:18 | access to local variable l : MyList [field head] : B | | A.cs:121:41:121:46 | access to field next : MyList [field next, field head] : B | A.cs:121:41:121:41 | access to local variable l : MyList [field next, field head] : B | +| A.cs:121:41:121:46 | access to field next : MyList [field next, field head] : B | A.cs:121:41:121:41 | access to local variable l : MyList [field next, field head] : B | +| A.cs:123:18:123:18 | access to local variable l : MyList [field head] : B | A.cs:123:18:123:23 | access to field head | | A.cs:123:18:123:18 | access to local variable l : MyList [field head] : B | A.cs:123:18:123:23 | access to field head | | A.cs:141:20:141:20 | c : C | A.cs:143:22:143:22 | access to parameter c : C | +| A.cs:141:20:141:20 | c : C | A.cs:143:22:143:22 | access to parameter c : C | +| A.cs:143:22:143:22 | access to parameter c : C | A.cs:143:13:143:16 | [post] this access : B [field c] : C | | A.cs:143:22:143:22 | access to parameter c : C | A.cs:143:13:143:16 | [post] this access : B [field c] : C | | A.cs:145:27:145:27 | c : C | A.cs:145:41:145:41 | access to parameter c : C | +| A.cs:145:27:145:27 | c : C | A.cs:145:41:145:41 | access to parameter c : C | +| A.cs:145:27:145:27 | c : C1 | A.cs:145:41:145:41 | access to parameter c : C1 | | A.cs:145:27:145:27 | c : C1 | A.cs:145:41:145:41 | access to parameter c : C1 | | A.cs:145:27:145:27 | c : C2 | A.cs:145:41:145:41 | access to parameter c : C2 | +| A.cs:145:27:145:27 | c : C2 | A.cs:145:41:145:41 | access to parameter c : C2 | +| A.cs:145:41:145:41 | access to parameter c : C | A.cs:145:32:145:35 | [post] this access : B [field c] : C | | A.cs:145:41:145:41 | access to parameter c : C | A.cs:145:32:145:35 | [post] this access : B [field c] : C | | A.cs:145:41:145:41 | access to parameter c : C1 | A.cs:145:32:145:35 | [post] this access : B [field c] : C1 | +| A.cs:145:41:145:41 | access to parameter c : C1 | A.cs:145:32:145:35 | [post] this access : B [field c] : C1 | +| A.cs:145:41:145:41 | access to parameter c : C2 | A.cs:145:32:145:35 | [post] this access : B [field c] : C2 | | A.cs:145:41:145:41 | access to parameter c : C2 | A.cs:145:32:145:35 | [post] this access : B [field c] : C2 | | A.cs:146:18:146:20 | this : B [field c] : C | A.cs:146:33:146:36 | this access : B [field c] : C | +| A.cs:146:18:146:20 | this : B [field c] : C | A.cs:146:33:146:36 | this access : B [field c] : C | +| A.cs:146:18:146:20 | this : B [field c] : C1 | A.cs:146:33:146:36 | this access : B [field c] : C1 | | A.cs:146:18:146:20 | this : B [field c] : C1 | A.cs:146:33:146:36 | this access : B [field c] : C1 | | A.cs:146:33:146:36 | this access : B [field c] : C | A.cs:146:33:146:38 | access to field c : C | +| A.cs:146:33:146:36 | this access : B [field c] : C | A.cs:146:33:146:38 | access to field c : C | +| A.cs:146:33:146:36 | this access : B [field c] : C1 | A.cs:146:33:146:38 | access to field c : C1 | | A.cs:146:33:146:36 | this access : B [field c] : C1 | A.cs:146:33:146:38 | access to field c : C1 | | A.cs:147:32:147:32 | c : C | A.cs:149:26:149:26 | access to parameter c : C | +| A.cs:147:32:147:32 | c : C | A.cs:149:26:149:26 | access to parameter c : C | +| A.cs:149:26:149:26 | access to parameter c : C | A.cs:141:20:141:20 | c : C | | A.cs:149:26:149:26 | access to parameter c : C | A.cs:141:20:141:20 | c : C | | A.cs:149:26:149:26 | access to parameter c : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | +| A.cs:149:26:149:26 | access to parameter c : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | +| A.cs:157:25:157:28 | head : B | A.cs:159:25:159:28 | access to parameter head : B | | A.cs:157:25:157:28 | head : B | A.cs:159:25:159:28 | access to parameter head : B | | A.cs:157:38:157:41 | next : MyList [field head] : B | A.cs:160:25:160:28 | access to parameter next : MyList [field head] : B | +| A.cs:157:38:157:41 | next : MyList [field head] : B | A.cs:160:25:160:28 | access to parameter next : MyList [field head] : B | +| A.cs:157:38:157:41 | next : MyList [field next, field head] : B | A.cs:160:25:160:28 | access to parameter next : MyList [field next, field head] : B | | A.cs:157:38:157:41 | next : MyList [field next, field head] : B | A.cs:160:25:160:28 | access to parameter next : MyList [field next, field head] : B | | A.cs:159:25:159:28 | access to parameter head : B | A.cs:159:13:159:16 | [post] this access : MyList [field head] : B | +| A.cs:159:25:159:28 | access to parameter head : B | A.cs:159:13:159:16 | [post] this access : MyList [field head] : B | +| A.cs:160:25:160:28 | access to parameter next : MyList [field head] : B | A.cs:160:13:160:16 | [post] this access : MyList [field next, field head] : B | | A.cs:160:25:160:28 | access to parameter next : MyList [field head] : B | A.cs:160:13:160:16 | [post] this access : MyList [field next, field head] : B | | A.cs:160:25:160:28 | access to parameter next : MyList [field next, field head] : B | A.cs:160:13:160:16 | [post] this access : MyList [field next, field next, field head] : B | +| A.cs:160:25:160:28 | access to parameter next : MyList [field next, field head] : B | A.cs:160:13:160:16 | [post] this access : MyList [field next, field next, field head] : B | +| B.cs:5:17:5:31 | call to method Source<Elem> : Elem | B.cs:6:27:6:27 | access to local variable e : Elem | | B.cs:5:17:5:31 | call to method Source<Elem> : Elem | B.cs:6:27:6:27 | access to local variable e : Elem | | B.cs:6:18:6:34 | object creation of type Box1 : Box1 [field elem1] : Elem | B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | +| B.cs:6:18:6:34 | object creation of type Box1 : Box1 [field elem1] : Elem | B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | +| B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:6:18:6:34 | object creation of type Box1 : Box1 [field elem1] : Elem | | B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:6:18:6:34 | object creation of type Box1 : Box1 [field elem1] : Elem | | B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:29:26:29:27 | e1 : Elem | +| B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:29:26:29:27 | e1 : Elem | +| B.cs:7:18:7:29 | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | B.cs:8:14:8:15 | access to local variable b2 : Box2 [field box1, field elem1] : Elem | | B.cs:7:18:7:29 | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | B.cs:8:14:8:15 | access to local variable b2 : Box2 [field box1, field elem1] : Elem | | B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | B.cs:7:18:7:29 | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | +| B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | B.cs:7:18:7:29 | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | +| B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | B.cs:39:26:39:27 | b1 : Box1 [field elem1] : Elem | | B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | B.cs:39:26:39:27 | b1 : Box1 [field elem1] : Elem | | B.cs:8:14:8:15 | access to local variable b2 : Box2 [field box1, field elem1] : Elem | B.cs:8:14:8:20 | access to field box1 : Box1 [field elem1] : Elem | +| B.cs:8:14:8:15 | access to local variable b2 : Box2 [field box1, field elem1] : Elem | B.cs:8:14:8:20 | access to field box1 : Box1 [field elem1] : Elem | +| B.cs:8:14:8:20 | access to field box1 : Box1 [field elem1] : Elem | B.cs:8:14:8:26 | access to field elem1 | | B.cs:8:14:8:20 | access to field box1 : Box1 [field elem1] : Elem | B.cs:8:14:8:26 | access to field elem1 | | B.cs:14:17:14:31 | call to method Source<Elem> : Elem | B.cs:15:33:15:33 | access to local variable e : Elem | +| B.cs:14:17:14:31 | call to method Source<Elem> : Elem | B.cs:15:33:15:33 | access to local variable e : Elem | +| B.cs:15:18:15:34 | object creation of type Box1 : Box1 [field elem2] : Elem | B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | | B.cs:15:18:15:34 | object creation of type Box1 : Box1 [field elem2] : Elem | B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | | B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:15:18:15:34 | object creation of type Box1 : Box1 [field elem2] : Elem | +| B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:15:18:15:34 | object creation of type Box1 : Box1 [field elem2] : Elem | +| B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:29:35:29:36 | e2 : Elem | | B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:29:35:29:36 | e2 : Elem | | B.cs:16:18:16:29 | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | B.cs:18:14:18:15 | access to local variable b2 : Box2 [field box1, field elem2] : Elem | +| B.cs:16:18:16:29 | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | B.cs:18:14:18:15 | access to local variable b2 : Box2 [field box1, field elem2] : Elem | +| B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | B.cs:16:18:16:29 | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | | B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | B.cs:16:18:16:29 | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | | B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | B.cs:39:26:39:27 | b1 : Box1 [field elem2] : Elem | +| B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | B.cs:39:26:39:27 | b1 : Box1 [field elem2] : Elem | +| B.cs:18:14:18:15 | access to local variable b2 : Box2 [field box1, field elem2] : Elem | B.cs:18:14:18:20 | access to field box1 : Box1 [field elem2] : Elem | | B.cs:18:14:18:15 | access to local variable b2 : Box2 [field box1, field elem2] : Elem | B.cs:18:14:18:20 | access to field box1 : Box1 [field elem2] : Elem | | B.cs:18:14:18:20 | access to field box1 : Box1 [field elem2] : Elem | B.cs:18:14:18:26 | access to field elem2 | +| B.cs:18:14:18:20 | access to field box1 : Box1 [field elem2] : Elem | B.cs:18:14:18:26 | access to field elem2 | +| B.cs:29:26:29:27 | e1 : Elem | B.cs:31:26:31:27 | access to parameter e1 : Elem | | B.cs:29:26:29:27 | e1 : Elem | B.cs:31:26:31:27 | access to parameter e1 : Elem | | B.cs:29:35:29:36 | e2 : Elem | B.cs:32:26:32:27 | access to parameter e2 : Elem | +| B.cs:29:35:29:36 | e2 : Elem | B.cs:32:26:32:27 | access to parameter e2 : Elem | +| B.cs:31:26:31:27 | access to parameter e1 : Elem | B.cs:31:13:31:16 | [post] this access : Box1 [field elem1] : Elem | | B.cs:31:26:31:27 | access to parameter e1 : Elem | B.cs:31:13:31:16 | [post] this access : Box1 [field elem1] : Elem | | B.cs:32:26:32:27 | access to parameter e2 : Elem | B.cs:32:13:32:16 | [post] this access : Box1 [field elem2] : Elem | +| B.cs:32:26:32:27 | access to parameter e2 : Elem | B.cs:32:13:32:16 | [post] this access : Box1 [field elem2] : Elem | +| B.cs:39:26:39:27 | b1 : Box1 [field elem1] : Elem | B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem1] : Elem | | B.cs:39:26:39:27 | b1 : Box1 [field elem1] : Elem | B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem1] : Elem | | B.cs:39:26:39:27 | b1 : Box1 [field elem2] : Elem | B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem2] : Elem | +| B.cs:39:26:39:27 | b1 : Box1 [field elem2] : Elem | B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem2] : Elem | +| B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem1] : Elem | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem1] : Elem | | B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem1] : Elem | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem1] : Elem | | B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem2] : Elem | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem2] : Elem | +| B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem2] : Elem | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem2] : Elem | +| C.cs:3:18:3:19 | [post] this access : C [field s1] : Elem | C.cs:12:15:12:21 | object creation of type C : C [field s1] : Elem | | C.cs:3:18:3:19 | [post] this access : C [field s1] : Elem | C.cs:12:15:12:21 | object creation of type C : C [field s1] : Elem | | C.cs:3:23:3:37 | call to method Source<Elem> : Elem | C.cs:3:18:3:19 | [post] this access : C [field s1] : Elem | +| C.cs:3:23:3:37 | call to method Source<Elem> : Elem | C.cs:3:18:3:19 | [post] this access : C [field s1] : Elem | +| C.cs:4:27:4:28 | [post] this access : C [field s2] : Elem | C.cs:12:15:12:21 | object creation of type C : C [field s2] : Elem | | C.cs:4:27:4:28 | [post] this access : C [field s2] : Elem | C.cs:12:15:12:21 | object creation of type C : C [field s2] : Elem | | C.cs:4:32:4:46 | call to method Source<Elem> : Elem | C.cs:4:27:4:28 | [post] this access : C [field s2] : Elem | +| C.cs:4:32:4:46 | call to method Source<Elem> : Elem | C.cs:4:27:4:28 | [post] this access : C [field s2] : Elem | +| C.cs:6:30:6:44 | call to method Source<Elem> : Elem | C.cs:26:14:26:15 | access to field s4 | | C.cs:6:30:6:44 | call to method Source<Elem> : Elem | C.cs:26:14:26:15 | access to field s4 | | C.cs:7:18:7:19 | [post] this access : C [property s5] : Elem | C.cs:12:15:12:21 | object creation of type C : C [property s5] : Elem | +| C.cs:7:18:7:19 | [post] this access : C [property s5] : Elem | C.cs:12:15:12:21 | object creation of type C : C [property s5] : Elem | +| C.cs:7:37:7:51 | call to method Source<Elem> : Elem | C.cs:7:18:7:19 | [post] this access : C [property s5] : Elem | | C.cs:7:37:7:51 | call to method Source<Elem> : Elem | C.cs:7:18:7:19 | [post] this access : C [property s5] : Elem | | C.cs:8:30:8:44 | call to method Source<Elem> : Elem | C.cs:28:14:28:15 | access to property s6 | +| C.cs:8:30:8:44 | call to method Source<Elem> : Elem | C.cs:28:14:28:15 | access to property s6 | +| C.cs:12:15:12:21 | object creation of type C : C [field s1] : Elem | C.cs:13:9:13:9 | access to local variable c : C [field s1] : Elem | | C.cs:12:15:12:21 | object creation of type C : C [field s1] : Elem | C.cs:13:9:13:9 | access to local variable c : C [field s1] : Elem | | C.cs:12:15:12:21 | object creation of type C : C [field s2] : Elem | C.cs:13:9:13:9 | access to local variable c : C [field s2] : Elem | +| C.cs:12:15:12:21 | object creation of type C : C [field s2] : Elem | C.cs:13:9:13:9 | access to local variable c : C [field s2] : Elem | +| C.cs:12:15:12:21 | object creation of type C : C [field s3] : Elem | C.cs:13:9:13:9 | access to local variable c : C [field s3] : Elem | | C.cs:12:15:12:21 | object creation of type C : C [field s3] : Elem | C.cs:13:9:13:9 | access to local variable c : C [field s3] : Elem | | C.cs:12:15:12:21 | object creation of type C : C [property s5] : Elem | C.cs:13:9:13:9 | access to local variable c : C [property s5] : Elem | +| C.cs:12:15:12:21 | object creation of type C : C [property s5] : Elem | C.cs:13:9:13:9 | access to local variable c : C [property s5] : Elem | +| C.cs:13:9:13:9 | access to local variable c : C [field s1] : Elem | C.cs:21:17:21:18 | this : C [field s1] : Elem | | C.cs:13:9:13:9 | access to local variable c : C [field s1] : Elem | C.cs:21:17:21:18 | this : C [field s1] : Elem | | C.cs:13:9:13:9 | access to local variable c : C [field s2] : Elem | C.cs:21:17:21:18 | this : C [field s2] : Elem | +| C.cs:13:9:13:9 | access to local variable c : C [field s2] : Elem | C.cs:21:17:21:18 | this : C [field s2] : Elem | +| C.cs:13:9:13:9 | access to local variable c : C [field s3] : Elem | C.cs:21:17:21:18 | this : C [field s3] : Elem | | C.cs:13:9:13:9 | access to local variable c : C [field s3] : Elem | C.cs:21:17:21:18 | this : C [field s3] : Elem | | C.cs:13:9:13:9 | access to local variable c : C [property s5] : Elem | C.cs:21:17:21:18 | this : C [property s5] : Elem | +| C.cs:13:9:13:9 | access to local variable c : C [property s5] : Elem | C.cs:21:17:21:18 | this : C [property s5] : Elem | +| C.cs:18:9:18:12 | [post] this access : C [field s3] : Elem | C.cs:12:15:12:21 | object creation of type C : C [field s3] : Elem | | C.cs:18:9:18:12 | [post] this access : C [field s3] : Elem | C.cs:12:15:12:21 | object creation of type C : C [field s3] : Elem | | C.cs:18:19:18:33 | call to method Source<Elem> : Elem | C.cs:18:9:18:12 | [post] this access : C [field s3] : Elem | +| C.cs:18:19:18:33 | call to method Source<Elem> : Elem | C.cs:18:9:18:12 | [post] this access : C [field s3] : Elem | +| C.cs:21:17:21:18 | this : C [field s1] : Elem | C.cs:23:14:23:15 | this access : C [field s1] : Elem | | C.cs:21:17:21:18 | this : C [field s1] : Elem | C.cs:23:14:23:15 | this access : C [field s1] : Elem | | C.cs:21:17:21:18 | this : C [field s2] : Elem | C.cs:24:14:24:15 | this access : C [field s2] : Elem | +| C.cs:21:17:21:18 | this : C [field s2] : Elem | C.cs:24:14:24:15 | this access : C [field s2] : Elem | +| C.cs:21:17:21:18 | this : C [field s3] : Elem | C.cs:25:14:25:15 | this access : C [field s3] : Elem | | C.cs:21:17:21:18 | this : C [field s3] : Elem | C.cs:25:14:25:15 | this access : C [field s3] : Elem | | C.cs:21:17:21:18 | this : C [property s5] : Elem | C.cs:27:14:27:15 | this access : C [property s5] : Elem | +| C.cs:21:17:21:18 | this : C [property s5] : Elem | C.cs:27:14:27:15 | this access : C [property s5] : Elem | +| C.cs:23:14:23:15 | this access : C [field s1] : Elem | C.cs:23:14:23:15 | access to field s1 | | C.cs:23:14:23:15 | this access : C [field s1] : Elem | C.cs:23:14:23:15 | access to field s1 | | C.cs:24:14:24:15 | this access : C [field s2] : Elem | C.cs:24:14:24:15 | access to field s2 | +| C.cs:24:14:24:15 | this access : C [field s2] : Elem | C.cs:24:14:24:15 | access to field s2 | +| C.cs:25:14:25:15 | this access : C [field s3] : Elem | C.cs:25:14:25:15 | access to field s3 | | C.cs:25:14:25:15 | this access : C [field s3] : Elem | C.cs:25:14:25:15 | access to field s3 | | C.cs:27:14:27:15 | this access : C [property s5] : Elem | C.cs:27:14:27:15 | access to property s5 | +| C.cs:27:14:27:15 | this access : C [property s5] : Elem | C.cs:27:14:27:15 | access to property s5 | +| C_ctor.cs:3:18:3:19 | [post] this access : C_no_ctor [field s1] : Elem | C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor : C_no_ctor [field s1] : Elem | | C_ctor.cs:3:18:3:19 | [post] this access : C_no_ctor [field s1] : Elem | C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor : C_no_ctor [field s1] : Elem | | C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | C_ctor.cs:3:18:3:19 | [post] this access : C_no_ctor [field s1] : Elem | +| C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | C_ctor.cs:3:18:3:19 | [post] this access : C_no_ctor [field s1] : Elem | +| C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor : C_no_ctor [field s1] : Elem | C_ctor.cs:8:9:8:9 | access to local variable c : C_no_ctor [field s1] : Elem | | C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor : C_no_ctor [field s1] : Elem | C_ctor.cs:8:9:8:9 | access to local variable c : C_no_ctor [field s1] : Elem | | C_ctor.cs:8:9:8:9 | access to local variable c : C_no_ctor [field s1] : Elem | C_ctor.cs:11:17:11:18 | this : C_no_ctor [field s1] : Elem | +| C_ctor.cs:8:9:8:9 | access to local variable c : C_no_ctor [field s1] : Elem | C_ctor.cs:11:17:11:18 | this : C_no_ctor [field s1] : Elem | +| C_ctor.cs:11:17:11:18 | this : C_no_ctor [field s1] : Elem | C_ctor.cs:13:19:13:20 | this access : C_no_ctor [field s1] : Elem | | C_ctor.cs:11:17:11:18 | this : C_no_ctor [field s1] : Elem | C_ctor.cs:13:19:13:20 | this access : C_no_ctor [field s1] : Elem | | C_ctor.cs:13:19:13:20 | this access : C_no_ctor [field s1] : Elem | C_ctor.cs:13:19:13:20 | access to field s1 | +| C_ctor.cs:13:19:13:20 | this access : C_no_ctor [field s1] : Elem | C_ctor.cs:13:19:13:20 | access to field s1 | +| C_ctor.cs:19:18:19:19 | [post] this access : C_with_ctor [field s1] : Elem | C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor : C_with_ctor [field s1] : Elem | | C_ctor.cs:19:18:19:19 | [post] this access : C_with_ctor [field s1] : Elem | C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor : C_with_ctor [field s1] : Elem | | C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | C_ctor.cs:19:18:19:19 | [post] this access : C_with_ctor [field s1] : Elem | +| C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | C_ctor.cs:19:18:19:19 | [post] this access : C_with_ctor [field s1] : Elem | +| C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor : C_with_ctor [field s1] : Elem | C_ctor.cs:24:9:24:9 | access to local variable c : C_with_ctor [field s1] : Elem | | C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor : C_with_ctor [field s1] : Elem | C_ctor.cs:24:9:24:9 | access to local variable c : C_with_ctor [field s1] : Elem | | C_ctor.cs:24:9:24:9 | access to local variable c : C_with_ctor [field s1] : Elem | C_ctor.cs:29:17:29:18 | this : C_with_ctor [field s1] : Elem | +| C_ctor.cs:24:9:24:9 | access to local variable c : C_with_ctor [field s1] : Elem | C_ctor.cs:29:17:29:18 | this : C_with_ctor [field s1] : Elem | +| C_ctor.cs:29:17:29:18 | this : C_with_ctor [field s1] : Elem | C_ctor.cs:31:19:31:20 | this access : C_with_ctor [field s1] : Elem | | C_ctor.cs:29:17:29:18 | this : C_with_ctor [field s1] : Elem | C_ctor.cs:31:19:31:20 | this access : C_with_ctor [field s1] : Elem | | C_ctor.cs:31:19:31:20 | this access : C_with_ctor [field s1] : Elem | C_ctor.cs:31:19:31:20 | access to field s1 | +| C_ctor.cs:31:19:31:20 | this access : C_with_ctor [field s1] : Elem | C_ctor.cs:31:19:31:20 | access to field s1 | +| D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | D.cs:8:22:8:25 | this access : D [field trivialPropField] : Object | | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | D.cs:8:22:8:25 | this access : D [field trivialPropField] : Object | | D.cs:8:22:8:25 | this access : D [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | +| D.cs:8:22:8:25 | this access : D [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | +| D.cs:9:9:9:11 | value : Object | D.cs:9:39:9:43 | access to parameter value : Object | | D.cs:9:9:9:11 | value : Object | D.cs:9:39:9:43 | access to parameter value : Object | | D.cs:9:39:9:43 | access to parameter value : Object | D.cs:9:15:9:18 | [post] this access : D [field trivialPropField] : Object | +| D.cs:9:39:9:43 | access to parameter value : Object | D.cs:9:15:9:18 | [post] this access : D [field trivialPropField] : Object | +| D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | D.cs:14:22:14:25 | this access : D [field trivialPropField] : Object | | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | D.cs:14:22:14:25 | this access : D [field trivialPropField] : Object | | D.cs:14:22:14:25 | this access : D [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | +| D.cs:14:22:14:25 | this access : D [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | +| D.cs:15:9:15:11 | value : Object | D.cs:15:34:15:38 | access to parameter value : Object | | D.cs:15:9:15:11 | value : Object | D.cs:15:34:15:38 | access to parameter value : Object | | D.cs:15:34:15:38 | access to parameter value : Object | D.cs:9:9:9:11 | value : Object | +| D.cs:15:34:15:38 | access to parameter value : Object | D.cs:9:9:9:11 | value : Object | +| D.cs:15:34:15:38 | access to parameter value : Object | D.cs:15:15:15:18 | [post] this access : D [field trivialPropField] : Object | | D.cs:15:34:15:38 | access to parameter value : Object | D.cs:15:15:15:18 | [post] this access : D [field trivialPropField] : Object | | D.cs:18:28:18:29 | o1 : Object | D.cs:21:24:21:25 | access to parameter o1 : Object | +| D.cs:18:28:18:29 | o1 : Object | D.cs:21:24:21:25 | access to parameter o1 : Object | +| D.cs:18:39:18:40 | o2 : Object | D.cs:22:27:22:28 | access to parameter o2 : Object | | D.cs:18:39:18:40 | o2 : Object | D.cs:22:27:22:28 | access to parameter o2 : Object | | D.cs:18:50:18:51 | o3 : Object | D.cs:23:27:23:28 | access to parameter o3 : Object | +| D.cs:18:50:18:51 | o3 : Object | D.cs:23:27:23:28 | access to parameter o3 : Object | +| D.cs:21:9:21:11 | [post] access to local variable ret : D [property AutoProp] : Object | D.cs:24:16:24:18 | access to local variable ret : D [property AutoProp] : Object | | D.cs:21:9:21:11 | [post] access to local variable ret : D [property AutoProp] : Object | D.cs:24:16:24:18 | access to local variable ret : D [property AutoProp] : Object | | D.cs:21:24:21:25 | access to parameter o1 : Object | D.cs:21:9:21:11 | [post] access to local variable ret : D [property AutoProp] : Object | +| D.cs:21:24:21:25 | access to parameter o1 : Object | D.cs:21:9:21:11 | [post] access to local variable ret : D [property AutoProp] : Object | +| D.cs:22:9:22:11 | [post] access to local variable ret : D [field trivialPropField] : Object | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | | D.cs:22:9:22:11 | [post] access to local variable ret : D [field trivialPropField] : Object | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | | D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:9:9:9:11 | value : Object | +| D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:9:9:9:11 | value : Object | +| D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:22:9:22:11 | [post] access to local variable ret : D [field trivialPropField] : Object | | D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:22:9:22:11 | [post] access to local variable ret : D [field trivialPropField] : Object | | D.cs:23:9:23:11 | [post] access to local variable ret : D [field trivialPropField] : Object | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | +| D.cs:23:9:23:11 | [post] access to local variable ret : D [field trivialPropField] : Object | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | +| D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:15:9:15:11 | value : Object | | D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:15:9:15:11 | value : Object | | D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:23:9:23:11 | [post] access to local variable ret : D [field trivialPropField] : Object | +| D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:23:9:23:11 | [post] access to local variable ret : D [field trivialPropField] : Object | +| D.cs:29:17:29:33 | call to method Source<Object> : Object | D.cs:31:24:31:24 | access to local variable o : Object | | D.cs:29:17:29:33 | call to method Source<Object> : Object | D.cs:31:24:31:24 | access to local variable o : Object | | D.cs:31:17:31:37 | call to method Create : D [property AutoProp] : Object | D.cs:32:14:32:14 | access to local variable d : D [property AutoProp] : Object | +| D.cs:31:17:31:37 | call to method Create : D [property AutoProp] : Object | D.cs:32:14:32:14 | access to local variable d : D [property AutoProp] : Object | +| D.cs:31:24:31:24 | access to local variable o : Object | D.cs:18:28:18:29 | o1 : Object | | D.cs:31:24:31:24 | access to local variable o : Object | D.cs:18:28:18:29 | o1 : Object | | D.cs:31:24:31:24 | access to local variable o : Object | D.cs:31:17:31:37 | call to method Create : D [property AutoProp] : Object | +| D.cs:31:24:31:24 | access to local variable o : Object | D.cs:31:17:31:37 | call to method Create : D [property AutoProp] : Object | +| D.cs:32:14:32:14 | access to local variable d : D [property AutoProp] : Object | D.cs:32:14:32:23 | access to property AutoProp | | D.cs:32:14:32:14 | access to local variable d : D [property AutoProp] : Object | D.cs:32:14:32:23 | access to property AutoProp | | D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | +| D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | +| D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | D.cs:40:14:40:14 | access to local variable d : D [field trivialPropField] : Object | | D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | D.cs:40:14:40:14 | access to local variable d : D [field trivialPropField] : Object | | D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | +| D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | +| D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:18:39:18:40 | o2 : Object | | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:18:39:18:40 | o2 : Object | | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | +| D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | +| D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | | D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | | D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:39:14:39:26 | access to property TrivialProp | +| D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:39:14:39:26 | access to property TrivialProp | +| D.cs:40:14:40:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:40:14:40:31 | access to field trivialPropField | | D.cs:40:14:40:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:40:14:40:31 | access to field trivialPropField | | D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | +| D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | +| D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:41:14:41:26 | access to property ComplexProp | | D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:41:14:41:26 | access to property ComplexProp | | D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | +| D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | +| D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | D.cs:46:14:46:14 | access to local variable d : D [field trivialPropField] : Object | | D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | D.cs:46:14:46:14 | access to local variable d : D [field trivialPropField] : Object | | D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | +| D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | +| D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:18:50:18:51 | o3 : Object | | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:18:50:18:51 | o3 : Object | | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | +| D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | +| D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | | D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | | D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:45:14:45:26 | access to property TrivialProp | +| D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:45:14:45:26 | access to property TrivialProp | +| D.cs:46:14:46:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:46:14:46:31 | access to field trivialPropField | | D.cs:46:14:46:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:46:14:46:31 | access to field trivialPropField | | D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | +| D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | +| D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:47:14:47:26 | access to property ComplexProp | | D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:47:14:47:26 | access to property ComplexProp | | E.cs:8:29:8:29 | o : Object | E.cs:11:21:11:21 | access to parameter o : Object | +| E.cs:8:29:8:29 | o : Object | E.cs:11:21:11:21 | access to parameter o : Object | +| E.cs:11:9:11:11 | [post] access to local variable ret : S [field Field] : Object | E.cs:12:16:12:18 | access to local variable ret : S [field Field] : Object | | E.cs:11:9:11:11 | [post] access to local variable ret : S [field Field] : Object | E.cs:12:16:12:18 | access to local variable ret : S [field Field] : Object | | E.cs:11:21:11:21 | access to parameter o : Object | E.cs:11:9:11:11 | [post] access to local variable ret : S [field Field] : Object | +| E.cs:11:21:11:21 | access to parameter o : Object | E.cs:11:9:11:11 | [post] access to local variable ret : S [field Field] : Object | +| E.cs:22:17:22:33 | call to method Source<Object> : Object | E.cs:23:25:23:25 | access to local variable o : Object | | E.cs:22:17:22:33 | call to method Source<Object> : Object | E.cs:23:25:23:25 | access to local variable o : Object | | E.cs:23:17:23:26 | call to method CreateS : S [field Field] : Object | E.cs:24:14:24:14 | access to local variable s : S [field Field] : Object | +| E.cs:23:17:23:26 | call to method CreateS : S [field Field] : Object | E.cs:24:14:24:14 | access to local variable s : S [field Field] : Object | +| E.cs:23:25:23:25 | access to local variable o : Object | E.cs:8:29:8:29 | o : Object | | E.cs:23:25:23:25 | access to local variable o : Object | E.cs:8:29:8:29 | o : Object | | E.cs:23:25:23:25 | access to local variable o : Object | E.cs:23:17:23:26 | call to method CreateS : S [field Field] : Object | +| E.cs:23:25:23:25 | access to local variable o : Object | E.cs:23:17:23:26 | call to method CreateS : S [field Field] : Object | +| E.cs:24:14:24:14 | access to local variable s : S [field Field] : Object | E.cs:24:14:24:20 | access to field Field | | E.cs:24:14:24:14 | access to local variable s : S [field Field] : Object | E.cs:24:14:24:20 | access to field Field | | F.cs:6:28:6:29 | o1 : Object | F.cs:6:65:6:66 | access to parameter o1 : Object | +| F.cs:6:28:6:29 | o1 : Object | F.cs:6:65:6:66 | access to parameter o1 : Object | +| F.cs:6:39:6:40 | o2 : Object | F.cs:6:78:6:79 | access to parameter o2 : Object | | F.cs:6:39:6:40 | o2 : Object | F.cs:6:78:6:79 | access to parameter o2 : Object | | F.cs:6:54:6:81 | { ..., ... } : F [field Field1] : Object | F.cs:6:46:6:81 | object creation of type F : F [field Field1] : Object | +| F.cs:6:54:6:81 | { ..., ... } : F [field Field1] : Object | F.cs:6:46:6:81 | object creation of type F : F [field Field1] : Object | +| F.cs:6:54:6:81 | { ..., ... } : F [field Field2] : Object | F.cs:6:46:6:81 | object creation of type F : F [field Field2] : Object | | F.cs:6:54:6:81 | { ..., ... } : F [field Field2] : Object | F.cs:6:46:6:81 | object creation of type F : F [field Field2] : Object | | F.cs:6:65:6:66 | access to parameter o1 : Object | F.cs:6:54:6:81 | { ..., ... } : F [field Field1] : Object | +| F.cs:6:65:6:66 | access to parameter o1 : Object | F.cs:6:54:6:81 | { ..., ... } : F [field Field1] : Object | +| F.cs:6:78:6:79 | access to parameter o2 : Object | F.cs:6:54:6:81 | { ..., ... } : F [field Field2] : Object | | F.cs:6:78:6:79 | access to parameter o2 : Object | F.cs:6:54:6:81 | { ..., ... } : F [field Field2] : Object | | F.cs:10:17:10:33 | call to method Source<Object> : Object | F.cs:11:24:11:24 | access to local variable o : Object | +| F.cs:10:17:10:33 | call to method Source<Object> : Object | F.cs:11:24:11:24 | access to local variable o : Object | +| F.cs:11:17:11:31 | call to method Create : F [field Field1] : Object | F.cs:12:14:12:14 | access to local variable f : F [field Field1] : Object | | F.cs:11:17:11:31 | call to method Create : F [field Field1] : Object | F.cs:12:14:12:14 | access to local variable f : F [field Field1] : Object | | F.cs:11:24:11:24 | access to local variable o : Object | F.cs:6:28:6:29 | o1 : Object | +| F.cs:11:24:11:24 | access to local variable o : Object | F.cs:6:28:6:29 | o1 : Object | +| F.cs:11:24:11:24 | access to local variable o : Object | F.cs:11:17:11:31 | call to method Create : F [field Field1] : Object | | F.cs:11:24:11:24 | access to local variable o : Object | F.cs:11:17:11:31 | call to method Create : F [field Field1] : Object | | F.cs:12:14:12:14 | access to local variable f : F [field Field1] : Object | F.cs:12:14:12:21 | access to field Field1 | +| F.cs:12:14:12:14 | access to local variable f : F [field Field1] : Object | F.cs:12:14:12:21 | access to field Field1 | +| F.cs:15:13:15:43 | call to method Create : F [field Field2] : Object | F.cs:17:14:17:14 | access to local variable f : F [field Field2] : Object | | F.cs:15:13:15:43 | call to method Create : F [field Field2] : Object | F.cs:17:14:17:14 | access to local variable f : F [field Field2] : Object | | F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:6:39:6:40 | o2 : Object | +| F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:6:39:6:40 | o2 : Object | +| F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:15:13:15:43 | call to method Create : F [field Field2] : Object | | F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:15:13:15:43 | call to method Create : F [field Field2] : Object | | F.cs:17:14:17:14 | access to local variable f : F [field Field2] : Object | F.cs:17:14:17:21 | access to field Field2 | +| F.cs:17:14:17:14 | access to local variable f : F [field Field2] : Object | F.cs:17:14:17:21 | access to field Field2 | +| F.cs:19:21:19:50 | { ..., ... } : F [field Field1] : Object | F.cs:20:14:20:14 | access to local variable f : F [field Field1] : Object | | F.cs:19:21:19:50 | { ..., ... } : F [field Field1] : Object | F.cs:20:14:20:14 | access to local variable f : F [field Field1] : Object | | F.cs:19:32:19:48 | call to method Source<Object> : Object | F.cs:19:21:19:50 | { ..., ... } : F [field Field1] : Object | +| F.cs:19:32:19:48 | call to method Source<Object> : Object | F.cs:19:21:19:50 | { ..., ... } : F [field Field1] : Object | +| F.cs:20:14:20:14 | access to local variable f : F [field Field1] : Object | F.cs:20:14:20:21 | access to field Field1 | | F.cs:20:14:20:14 | access to local variable f : F [field Field1] : Object | F.cs:20:14:20:21 | access to field Field1 | | F.cs:23:21:23:50 | { ..., ... } : F [field Field2] : Object | F.cs:25:14:25:14 | access to local variable f : F [field Field2] : Object | +| F.cs:23:21:23:50 | { ..., ... } : F [field Field2] : Object | F.cs:25:14:25:14 | access to local variable f : F [field Field2] : Object | +| F.cs:23:32:23:48 | call to method Source<Object> : Object | F.cs:23:21:23:50 | { ..., ... } : F [field Field2] : Object | | F.cs:23:32:23:48 | call to method Source<Object> : Object | F.cs:23:21:23:50 | { ..., ... } : F [field Field2] : Object | | F.cs:25:14:25:14 | access to local variable f : F [field Field2] : Object | F.cs:25:14:25:21 | access to field Field2 | +| F.cs:25:14:25:14 | access to local variable f : F [field Field2] : Object | F.cs:25:14:25:21 | access to field Field2 | +| F.cs:30:17:30:33 | call to method Source<Object> : Object | F.cs:32:27:32:27 | access to local variable o : Object | | F.cs:30:17:30:33 | call to method Source<Object> : Object | F.cs:32:27:32:27 | access to local variable o : Object | | F.cs:32:17:32:40 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | F.cs:33:14:33:14 | access to local variable a : <>__AnonType0<Object,Object> [property X] : Object | +| F.cs:32:17:32:40 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | F.cs:33:14:33:14 | access to local variable a : <>__AnonType0<Object,Object> [property X] : Object | +| F.cs:32:27:32:27 | access to local variable o : Object | F.cs:32:17:32:40 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | | F.cs:32:27:32:27 | access to local variable o : Object | F.cs:32:17:32:40 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | | F.cs:33:14:33:14 | access to local variable a : <>__AnonType0<Object,Object> [property X] : Object | F.cs:33:14:33:16 | access to property X | +| F.cs:33:14:33:14 | access to local variable a : <>__AnonType0<Object,Object> [property X] : Object | F.cs:33:14:33:16 | access to property X | +| G.cs:7:18:7:32 | call to method Source<Elem> : Elem | G.cs:9:23:9:23 | access to local variable e : Elem | | G.cs:7:18:7:32 | call to method Source<Elem> : Elem | G.cs:9:23:9:23 | access to local variable e : Elem | | G.cs:9:9:9:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:10:18:10:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:9:9:9:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:10:18:10:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:9:9:9:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | G.cs:9:9:9:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:9:9:9:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | G.cs:9:9:9:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:9:23:9:23 | access to local variable e : Elem | G.cs:9:9:9:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:9:23:9:23 | access to local variable e : Elem | G.cs:9:9:9:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:10:18:10:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | | G.cs:10:18:10:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | | G.cs:15:18:15:32 | call to method Source<Elem> : Elem | G.cs:17:24:17:24 | access to local variable e : Elem | +| G.cs:15:18:15:32 | call to method Source<Elem> : Elem | G.cs:17:24:17:24 | access to local variable e : Elem | +| G.cs:17:9:17:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:18:18:18:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:17:9:17:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:18:18:18:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:17:9:17:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | G.cs:17:9:17:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:17:9:17:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | G.cs:17:9:17:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:17:9:17:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | | G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:17:9:17:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | | G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | +| G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | +| G.cs:18:18:18:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | | G.cs:18:18:18:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | | G.cs:23:18:23:32 | call to method Source<Elem> : Elem | G.cs:25:28:25:28 | access to local variable e : Elem | +| G.cs:23:18:23:32 | call to method Source<Elem> : Elem | G.cs:25:28:25:28 | access to local variable e : Elem | +| G.cs:25:9:25:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:26:18:26:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:25:9:25:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:26:18:26:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:25:9:25:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:25:9:25:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:25:9:25:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:25:9:25:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:25:28:25:28 | access to local variable e : Elem | G.cs:25:9:25:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | | G.cs:25:28:25:28 | access to local variable e : Elem | G.cs:25:9:25:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | | G.cs:26:18:26:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | +| G.cs:26:18:26:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | +| G.cs:31:18:31:32 | call to method Source<Elem> : Elem | G.cs:33:29:33:29 | access to local variable e : Elem | | G.cs:31:18:31:32 | call to method Source<Elem> : Elem | G.cs:33:29:33:29 | access to local variable e : Elem | | G.cs:33:9:33:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:34:18:34:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:33:9:33:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:34:18:34:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:33:9:33:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:33:9:33:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:33:9:33:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:33:9:33:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:33:9:33:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:33:9:33:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | | G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | | G.cs:34:18:34:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | +| G.cs:34:18:34:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | +| G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | | G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | G.cs:71:21:71:27 | this : Box2 [field Box1, field Elem] : Elem | | G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | G.cs:71:21:71:27 | this : Box2 [field Box1, field Elem] : Elem | | G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:39:14:39:35 | call to method GetElem | +| G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:39:14:39:35 | call to method GetElem | +| G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:63:21:63:27 | this : Box1 [field Elem] : Elem | | G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:63:21:63:27 | this : Box1 [field Elem] : Elem | | G.cs:44:18:44:32 | call to method Source<Elem> : Elem | G.cs:46:30:46:30 | access to local variable e : Elem | +| G.cs:44:18:44:32 | call to method Source<Elem> : Elem | G.cs:46:30:46:30 | access to local variable e : Elem | +| G.cs:46:9:46:16 | [post] access to field boxfield : Box2 [field Box1, field Elem] : Elem | G.cs:46:9:46:16 | [post] this access : G [field boxfield, field Box1, field Elem] : Elem | | G.cs:46:9:46:16 | [post] access to field boxfield : Box2 [field Box1, field Elem] : Elem | G.cs:46:9:46:16 | [post] this access : G [field boxfield, field Box1, field Elem] : Elem | | G.cs:46:9:46:16 | [post] this access : G [field boxfield, field Box1, field Elem] : Elem | G.cs:47:9:47:13 | this access : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:46:9:46:16 | [post] this access : G [field boxfield, field Box1, field Elem] : Elem | G.cs:47:9:47:13 | this access : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:46:9:46:21 | [post] access to field Box1 : Box1 [field Elem] : Elem | G.cs:46:9:46:16 | [post] access to field boxfield : Box2 [field Box1, field Elem] : Elem | | G.cs:46:9:46:21 | [post] access to field Box1 : Box1 [field Elem] : Elem | G.cs:46:9:46:16 | [post] access to field boxfield : Box2 [field Box1, field Elem] : Elem | | G.cs:46:30:46:30 | access to local variable e : Elem | G.cs:46:9:46:21 | [post] access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:46:30:46:30 | access to local variable e : Elem | G.cs:46:9:46:21 | [post] access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:47:9:47:13 | this access : G [field boxfield, field Box1, field Elem] : Elem | G.cs:50:18:50:20 | this : G [field boxfield, field Box1, field Elem] : Elem | | G.cs:47:9:47:13 | this access : G [field boxfield, field Box1, field Elem] : Elem | G.cs:50:18:50:20 | this : G [field boxfield, field Box1, field Elem] : Elem | | G.cs:50:18:50:20 | this : G [field boxfield, field Box1, field Elem] : Elem | G.cs:52:14:52:21 | this access : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:50:18:50:20 | this : G [field boxfield, field Box1, field Elem] : Elem | G.cs:52:14:52:21 | this access : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:52:14:52:21 | access to field boxfield : Box2 [field Box1, field Elem] : Elem | G.cs:52:14:52:26 | access to field Box1 : Box1 [field Elem] : Elem | | G.cs:52:14:52:21 | access to field boxfield : Box2 [field Box1, field Elem] : Elem | G.cs:52:14:52:26 | access to field Box1 : Box1 [field Elem] : Elem | | G.cs:52:14:52:21 | this access : G [field boxfield, field Box1, field Elem] : Elem | G.cs:52:14:52:21 | access to field boxfield : Box2 [field Box1, field Elem] : Elem | +| G.cs:52:14:52:21 | this access : G [field boxfield, field Box1, field Elem] : Elem | G.cs:52:14:52:21 | access to field boxfield : Box2 [field Box1, field Elem] : Elem | +| G.cs:52:14:52:26 | access to field Box1 : Box1 [field Elem] : Elem | G.cs:52:14:52:31 | access to field Elem | | G.cs:52:14:52:26 | access to field Box1 : Box1 [field Elem] : Elem | G.cs:52:14:52:31 | access to field Elem | | G.cs:63:21:63:27 | this : Box1 [field Elem] : Elem | G.cs:63:34:63:37 | this access : Box1 [field Elem] : Elem | +| G.cs:63:21:63:27 | this : Box1 [field Elem] : Elem | G.cs:63:34:63:37 | this access : Box1 [field Elem] : Elem | +| G.cs:63:34:63:37 | this access : Box1 [field Elem] : Elem | G.cs:63:34:63:37 | access to field Elem : Elem | | G.cs:63:34:63:37 | this access : Box1 [field Elem] : Elem | G.cs:63:34:63:37 | access to field Elem : Elem | | G.cs:64:34:64:34 | e : Elem | G.cs:64:46:64:46 | access to parameter e : Elem | +| G.cs:64:34:64:34 | e : Elem | G.cs:64:46:64:46 | access to parameter e : Elem | +| G.cs:64:46:64:46 | access to parameter e : Elem | G.cs:64:39:64:42 | [post] this access : Box1 [field Elem] : Elem | | G.cs:64:46:64:46 | access to parameter e : Elem | G.cs:64:39:64:42 | [post] this access : Box1 [field Elem] : Elem | | G.cs:71:21:71:27 | this : Box2 [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | this access : Box2 [field Box1, field Elem] : Elem | +| G.cs:71:21:71:27 | this : Box2 [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | this access : Box2 [field Box1, field Elem] : Elem | +| G.cs:71:34:71:37 | this access : Box2 [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | access to field Box1 : Box1 [field Elem] : Elem | | G.cs:71:34:71:37 | this access : Box2 [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | access to field Box1 : Box1 [field Elem] : Elem | | H.cs:13:15:13:15 | a : A [field FieldA] : Object | H.cs:16:22:16:22 | access to parameter a : A [field FieldA] : Object | +| H.cs:13:15:13:15 | a : A [field FieldA] : Object | H.cs:16:22:16:22 | access to parameter a : A [field FieldA] : Object | +| H.cs:16:9:16:11 | [post] access to local variable ret : A [field FieldA] : Object | H.cs:17:16:17:18 | access to local variable ret : A [field FieldA] : Object | | H.cs:16:9:16:11 | [post] access to local variable ret : A [field FieldA] : Object | H.cs:17:16:17:18 | access to local variable ret : A [field FieldA] : Object | | H.cs:16:22:16:22 | access to parameter a : A [field FieldA] : Object | H.cs:16:22:16:29 | access to field FieldA : Object | +| H.cs:16:22:16:22 | access to parameter a : A [field FieldA] : Object | H.cs:16:22:16:29 | access to field FieldA : Object | +| H.cs:16:22:16:29 | access to field FieldA : Object | H.cs:16:9:16:11 | [post] access to local variable ret : A [field FieldA] : Object | | H.cs:16:22:16:29 | access to field FieldA : Object | H.cs:16:9:16:11 | [post] access to local variable ret : A [field FieldA] : Object | | H.cs:23:9:23:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | +| H.cs:23:9:23:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | +| H.cs:23:20:23:36 | call to method Source<Object> : Object | H.cs:23:9:23:9 | [post] access to local variable a : A [field FieldA] : Object | | H.cs:23:20:23:36 | call to method Source<Object> : Object | H.cs:23:9:23:9 | [post] access to local variable a : A [field FieldA] : Object | | H.cs:24:21:24:28 | call to method Clone : A [field FieldA] : Object | H.cs:25:14:25:18 | access to local variable clone : A [field FieldA] : Object | +| H.cs:24:21:24:28 | call to method Clone : A [field FieldA] : Object | H.cs:25:14:25:18 | access to local variable clone : A [field FieldA] : Object | +| H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | H.cs:13:15:13:15 | a : A [field FieldA] : Object | | H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | H.cs:13:15:13:15 | a : A [field FieldA] : Object | | H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | H.cs:24:21:24:28 | call to method Clone : A [field FieldA] : Object | +| H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | H.cs:24:21:24:28 | call to method Clone : A [field FieldA] : Object | +| H.cs:25:14:25:18 | access to local variable clone : A [field FieldA] : Object | H.cs:25:14:25:25 | access to field FieldA | | H.cs:25:14:25:18 | access to local variable clone : A [field FieldA] : Object | H.cs:25:14:25:25 | access to field FieldA | | H.cs:33:19:33:19 | a : A [field FieldA] : A | H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : A | +| H.cs:33:19:33:19 | a : A [field FieldA] : A | H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : A | +| H.cs:33:19:33:19 | a : A [field FieldA] : Object | H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : Object | | H.cs:33:19:33:19 | a : A [field FieldA] : Object | H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : Object | | H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : A | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : A | +| H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : A | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : A | +| H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : Object | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | | H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : Object | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | | H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : A | H.cs:36:20:36:27 | access to field FieldA : A | +| H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : A | H.cs:36:20:36:27 | access to field FieldA : A | +| H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : Object | H.cs:36:20:36:27 | access to field FieldA : Object | | H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : Object | H.cs:36:20:36:27 | access to field FieldA : Object | | H.cs:36:20:36:27 | access to field FieldA : A | H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : A | +| H.cs:36:20:36:27 | access to field FieldA : A | H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : A | +| H.cs:36:20:36:27 | access to field FieldA : Object | H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : Object | | H.cs:36:20:36:27 | access to field FieldA : Object | H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : Object | | H.cs:43:9:43:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | +| H.cs:43:9:43:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | +| H.cs:43:20:43:36 | call to method Source<Object> : Object | H.cs:43:9:43:9 | [post] access to local variable a : A [field FieldA] : Object | | H.cs:43:20:43:36 | call to method Source<Object> : Object | H.cs:43:9:43:9 | [post] access to local variable a : A [field FieldA] : Object | | H.cs:44:17:44:28 | call to method Transform : B [field FieldB] : Object | H.cs:45:14:45:14 | access to local variable b : B [field FieldB] : Object | +| H.cs:44:17:44:28 | call to method Transform : B [field FieldB] : Object | H.cs:45:14:45:14 | access to local variable b : B [field FieldB] : Object | +| H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | | H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | | H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | H.cs:44:17:44:28 | call to method Transform : B [field FieldB] : Object | +| H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | H.cs:44:17:44:28 | call to method Transform : B [field FieldB] : Object | +| H.cs:45:14:45:14 | access to local variable b : B [field FieldB] : Object | H.cs:45:14:45:21 | access to field FieldB | | H.cs:45:14:45:14 | access to local variable b : B [field FieldB] : Object | H.cs:45:14:45:21 | access to field FieldB | | H.cs:53:25:53:25 | a : A [field FieldA] : Object | H.cs:55:21:55:21 | access to parameter a : A [field FieldA] : Object | +| H.cs:53:25:53:25 | a : A [field FieldA] : Object | H.cs:55:21:55:21 | access to parameter a : A [field FieldA] : Object | +| H.cs:55:21:55:21 | access to parameter a : A [field FieldA] : Object | H.cs:55:21:55:28 | access to field FieldA : Object | | H.cs:55:21:55:21 | access to parameter a : A [field FieldA] : Object | H.cs:55:21:55:28 | access to field FieldA : Object | | H.cs:55:21:55:28 | access to field FieldA : Object | H.cs:55:9:55:10 | [post] access to parameter b1 : B [field FieldB] : Object | +| H.cs:55:21:55:28 | access to field FieldA : Object | H.cs:55:9:55:10 | [post] access to parameter b1 : B [field FieldB] : Object | +| H.cs:63:9:63:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | | H.cs:63:9:63:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | | H.cs:63:20:63:36 | call to method Source<Object> : Object | H.cs:63:9:63:9 | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:63:20:63:36 | call to method Source<Object> : Object | H.cs:63:9:63:9 | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | H.cs:53:25:53:25 | a : A [field FieldA] : Object | | H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | H.cs:53:25:53:25 | a : A [field FieldA] : Object | | H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | H.cs:64:25:64:26 | [post] access to local variable b1 : B [field FieldB] : Object | +| H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | H.cs:64:25:64:26 | [post] access to local variable b1 : B [field FieldB] : Object | +| H.cs:64:25:64:26 | [post] access to local variable b1 : B [field FieldB] : Object | H.cs:65:14:65:15 | access to local variable b1 : B [field FieldB] : Object | | H.cs:64:25:64:26 | [post] access to local variable b1 : B [field FieldB] : Object | H.cs:65:14:65:15 | access to local variable b1 : B [field FieldB] : Object | | H.cs:65:14:65:15 | access to local variable b1 : B [field FieldB] : Object | H.cs:65:14:65:22 | access to field FieldB | +| H.cs:65:14:65:15 | access to local variable b1 : B [field FieldB] : Object | H.cs:65:14:65:22 | access to field FieldB | +| H.cs:77:30:77:30 | o : Object | H.cs:79:20:79:20 | access to parameter o : Object | | H.cs:77:30:77:30 | o : Object | H.cs:79:20:79:20 | access to parameter o : Object | | H.cs:79:9:79:9 | [post] access to parameter a : A [field FieldA] : Object | H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | +| H.cs:79:9:79:9 | [post] access to parameter a : A [field FieldA] : Object | H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | +| H.cs:79:20:79:20 | access to parameter o : Object | H.cs:79:9:79:9 | [post] access to parameter a : A [field FieldA] : Object | | H.cs:79:20:79:20 | access to parameter o : Object | H.cs:79:9:79:9 | [post] access to parameter a : A [field FieldA] : Object | | H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | H.cs:53:25:53:25 | a : A [field FieldA] : Object | +| H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | H.cs:53:25:53:25 | a : A [field FieldA] : Object | +| H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | H.cs:80:25:80:26 | [post] access to parameter b1 : B [field FieldB] : Object | | H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | H.cs:80:25:80:26 | [post] access to parameter b1 : B [field FieldB] : Object | | H.cs:88:17:88:17 | [post] access to local variable a : A [field FieldA] : Object | H.cs:89:14:89:14 | access to local variable a : A [field FieldA] : Object | +| H.cs:88:17:88:17 | [post] access to local variable a : A [field FieldA] : Object | H.cs:89:14:89:14 | access to local variable a : A [field FieldA] : Object | +| H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:77:30:77:30 | o : Object | | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:77:30:77:30 | o : Object | | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:88:17:88:17 | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:88:17:88:17 | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:88:39:88:40 | [post] access to local variable b1 : B [field FieldB] : Object | | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:88:39:88:40 | [post] access to local variable b1 : B [field FieldB] : Object | | H.cs:88:39:88:40 | [post] access to local variable b1 : B [field FieldB] : Object | H.cs:90:14:90:15 | access to local variable b1 : B [field FieldB] : Object | +| H.cs:88:39:88:40 | [post] access to local variable b1 : B [field FieldB] : Object | H.cs:90:14:90:15 | access to local variable b1 : B [field FieldB] : Object | +| H.cs:89:14:89:14 | access to local variable a : A [field FieldA] : Object | H.cs:89:14:89:21 | access to field FieldA | | H.cs:89:14:89:14 | access to local variable a : A [field FieldA] : Object | H.cs:89:14:89:21 | access to field FieldA | | H.cs:90:14:90:15 | access to local variable b1 : B [field FieldB] : Object | H.cs:90:14:90:22 | access to field FieldB | +| H.cs:90:14:90:15 | access to local variable b1 : B [field FieldB] : Object | H.cs:90:14:90:22 | access to field FieldB | +| H.cs:102:23:102:23 | a : A [field FieldA] : Object | H.cs:105:23:105:23 | access to parameter a : A [field FieldA] : Object | | H.cs:102:23:102:23 | a : A [field FieldA] : Object | H.cs:105:23:105:23 | access to parameter a : A [field FieldA] : Object | | H.cs:105:9:105:12 | [post] access to local variable temp : B [field FieldB, field FieldA] : Object | H.cs:106:29:106:32 | access to local variable temp : B [field FieldB, field FieldA] : Object | +| H.cs:105:9:105:12 | [post] access to local variable temp : B [field FieldB, field FieldA] : Object | H.cs:106:29:106:32 | access to local variable temp : B [field FieldB, field FieldA] : Object | +| H.cs:105:23:105:23 | access to parameter a : A [field FieldA] : Object | H.cs:105:9:105:12 | [post] access to local variable temp : B [field FieldB, field FieldA] : Object | | H.cs:105:23:105:23 | access to parameter a : A [field FieldA] : Object | H.cs:105:9:105:12 | [post] access to local variable temp : B [field FieldB, field FieldA] : Object | | H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | +| H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | +| H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | H.cs:106:16:106:40 | call to method Transform : B [field FieldB] : Object | | H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | H.cs:106:16:106:40 | call to method Transform : B [field FieldB] : Object | | H.cs:106:29:106:32 | access to local variable temp : B [field FieldB, field FieldA] : Object | H.cs:106:29:106:39 | access to field FieldB : A [field FieldA] : Object | +| H.cs:106:29:106:32 | access to local variable temp : B [field FieldB, field FieldA] : Object | H.cs:106:29:106:39 | access to field FieldB : A [field FieldA] : Object | +| H.cs:106:29:106:39 | access to field FieldB : A [field FieldA] : Object | H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | | H.cs:106:29:106:39 | access to field FieldB : A [field FieldA] : Object | H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | | H.cs:112:9:112:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | +| H.cs:112:9:112:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | +| H.cs:112:20:112:36 | call to method Source<Object> : Object | H.cs:112:9:112:9 | [post] access to local variable a : A [field FieldA] : Object | | H.cs:112:20:112:36 | call to method Source<Object> : Object | H.cs:112:9:112:9 | [post] access to local variable a : A [field FieldA] : Object | | H.cs:113:17:113:32 | call to method TransformWrap : B [field FieldB] : Object | H.cs:114:14:114:14 | access to local variable b : B [field FieldB] : Object | +| H.cs:113:17:113:32 | call to method TransformWrap : B [field FieldB] : Object | H.cs:114:14:114:14 | access to local variable b : B [field FieldB] : Object | +| H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | H.cs:102:23:102:23 | a : A [field FieldA] : Object | | H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | H.cs:102:23:102:23 | a : A [field FieldA] : Object | | H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | H.cs:113:17:113:32 | call to method TransformWrap : B [field FieldB] : Object | +| H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | H.cs:113:17:113:32 | call to method TransformWrap : B [field FieldB] : Object | +| H.cs:114:14:114:14 | access to local variable b : B [field FieldB] : Object | H.cs:114:14:114:21 | access to field FieldB | | H.cs:114:14:114:14 | access to local variable b : B [field FieldB] : Object | H.cs:114:14:114:21 | access to field FieldB | | H.cs:122:18:122:18 | a : A [field FieldA] : Object | H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | +| H.cs:122:18:122:18 | a : A [field FieldA] : Object | H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | +| H.cs:124:16:124:27 | call to method Transform : B [field FieldB] : Object | H.cs:124:16:124:34 | access to field FieldB : Object | | H.cs:124:16:124:27 | call to method Transform : B [field FieldB] : Object | H.cs:124:16:124:34 | access to field FieldB : Object | | H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | +| H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | +| H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | H.cs:124:16:124:27 | call to method Transform : B [field FieldB] : Object | | H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | H.cs:124:16:124:27 | call to method Transform : B [field FieldB] : Object | | H.cs:130:9:130:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | +| H.cs:130:9:130:9 | [post] access to local variable a : A [field FieldA] : Object | H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | +| H.cs:130:20:130:36 | call to method Source<Object> : Object | H.cs:130:9:130:9 | [post] access to local variable a : A [field FieldA] : Object | | H.cs:130:20:130:36 | call to method Source<Object> : Object | H.cs:130:9:130:9 | [post] access to local variable a : A [field FieldA] : Object | | H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | H.cs:122:18:122:18 | a : A [field FieldA] : Object | +| H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | H.cs:122:18:122:18 | a : A [field FieldA] : Object | +| H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | H.cs:131:14:131:19 | call to method Get | | H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | H.cs:131:14:131:19 | call to method Get | | H.cs:138:27:138:27 | o : A | H.cs:141:20:141:25 | ... as ... : A | +| H.cs:138:27:138:27 | o : A | H.cs:141:20:141:25 | ... as ... : A | +| H.cs:141:9:141:9 | [post] access to local variable a : A [field FieldA] : A | H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | | H.cs:141:9:141:9 | [post] access to local variable a : A [field FieldA] : A | H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | | H.cs:141:20:141:25 | ... as ... : A | H.cs:141:9:141:9 | [post] access to local variable a : A [field FieldA] : A | +| H.cs:141:20:141:25 | ... as ... : A | H.cs:141:9:141:9 | [post] access to local variable a : A [field FieldA] : A | +| H.cs:142:16:142:27 | call to method Transform : B [field FieldB] : A | H.cs:142:16:142:34 | access to field FieldB : A | | H.cs:142:16:142:27 | call to method Transform : B [field FieldB] : A | H.cs:142:16:142:34 | access to field FieldB : A | | H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | H.cs:33:19:33:19 | a : A [field FieldA] : A | +| H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | H.cs:33:19:33:19 | a : A [field FieldA] : A | +| H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | H.cs:142:16:142:27 | call to method Transform : B [field FieldB] : A | | H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | H.cs:142:16:142:27 | call to method Transform : B [field FieldB] : A | | H.cs:147:17:147:39 | call to method Through : A | H.cs:148:14:148:14 | access to local variable a | +| H.cs:147:17:147:39 | call to method Through : A | H.cs:148:14:148:14 | access to local variable a | +| H.cs:147:25:147:38 | call to method Source<A> : A | H.cs:138:27:138:27 | o : A | | H.cs:147:25:147:38 | call to method Source<A> : A | H.cs:138:27:138:27 | o : A | | H.cs:147:25:147:38 | call to method Source<A> : A | H.cs:147:17:147:39 | call to method Through : A | +| H.cs:147:25:147:38 | call to method Source<A> : A | H.cs:147:17:147:39 | call to method Through : A | +| H.cs:153:32:153:32 | o : Object | H.cs:156:20:156:20 | access to parameter o : Object | | H.cs:153:32:153:32 | o : Object | H.cs:156:20:156:20 | access to parameter o : Object | | H.cs:155:17:155:30 | call to method Source<B> : B | H.cs:156:9:156:9 | access to local variable b : B | +| H.cs:155:17:155:30 | call to method Source<B> : B | H.cs:156:9:156:9 | access to local variable b : B | +| H.cs:156:9:156:9 | [post] access to local variable b : B [field FieldB] : Object | H.cs:157:20:157:20 | access to local variable b : B [field FieldB] : Object | | H.cs:156:9:156:9 | [post] access to local variable b : B [field FieldB] : Object | H.cs:157:20:157:20 | access to local variable b : B [field FieldB] : Object | | H.cs:156:9:156:9 | access to local variable b : B | H.cs:157:20:157:20 | access to local variable b : B | +| H.cs:156:9:156:9 | access to local variable b : B | H.cs:157:20:157:20 | access to local variable b : B | +| H.cs:156:20:156:20 | access to parameter o : Object | H.cs:156:9:156:9 | [post] access to local variable b : B [field FieldB] : Object | | H.cs:156:20:156:20 | access to parameter o : Object | H.cs:156:9:156:9 | [post] access to local variable b : B [field FieldB] : Object | | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA] : B | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA] : B | +| H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA] : B | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA] : B | +| H.cs:157:20:157:20 | access to local variable b : B | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA] : B | | H.cs:157:20:157:20 | access to local variable b : B | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA] : B | | H.cs:157:20:157:20 | access to local variable b : B [field FieldB] : Object | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA, field FieldB] : Object | +| H.cs:157:20:157:20 | access to local variable b : B [field FieldB] : Object | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA, field FieldB] : Object | +| H.cs:163:17:163:35 | call to method Source<Object> : Object | H.cs:164:22:164:22 | access to local variable o : Object | | H.cs:163:17:163:35 | call to method Source<Object> : Object | H.cs:164:22:164:22 | access to local variable o : Object | | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA, field FieldB] : Object | H.cs:165:20:165:20 | access to local variable a : A [field FieldA, field FieldB] : Object | +| H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA, field FieldB] : Object | H.cs:165:20:165:20 | access to local variable a : A [field FieldA, field FieldB] : Object | +| H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA] : B | H.cs:165:20:165:20 | access to local variable a : A [field FieldA] : B | | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA] : B | H.cs:165:20:165:20 | access to local variable a : A [field FieldA] : B | | H.cs:164:22:164:22 | access to local variable o : Object | H.cs:153:32:153:32 | o : Object | +| H.cs:164:22:164:22 | access to local variable o : Object | H.cs:153:32:153:32 | o : Object | +| H.cs:164:22:164:22 | access to local variable o : Object | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA, field FieldB] : Object | | H.cs:164:22:164:22 | access to local variable o : Object | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA, field FieldB] : Object | | H.cs:165:17:165:27 | (...) ... : B | H.cs:166:14:166:14 | access to local variable b | +| H.cs:165:17:165:27 | (...) ... : B | H.cs:166:14:166:14 | access to local variable b | +| H.cs:165:17:165:27 | (...) ... : B [field FieldB] : Object | H.cs:167:14:167:14 | access to local variable b : B [field FieldB] : Object | | H.cs:165:17:165:27 | (...) ... : B [field FieldB] : Object | H.cs:167:14:167:14 | access to local variable b : B [field FieldB] : Object | | H.cs:165:20:165:20 | access to local variable a : A [field FieldA, field FieldB] : Object | H.cs:165:20:165:27 | access to field FieldA : B [field FieldB] : Object | +| H.cs:165:20:165:20 | access to local variable a : A [field FieldA, field FieldB] : Object | H.cs:165:20:165:27 | access to field FieldA : B [field FieldB] : Object | +| H.cs:165:20:165:20 | access to local variable a : A [field FieldA] : B | H.cs:165:20:165:27 | access to field FieldA : B | | H.cs:165:20:165:20 | access to local variable a : A [field FieldA] : B | H.cs:165:20:165:27 | access to field FieldA : B | | H.cs:165:20:165:27 | access to field FieldA : B | H.cs:165:17:165:27 | (...) ... : B | +| H.cs:165:20:165:27 | access to field FieldA : B | H.cs:165:17:165:27 | (...) ... : B | +| H.cs:165:20:165:27 | access to field FieldA : B [field FieldB] : Object | H.cs:165:17:165:27 | (...) ... : B [field FieldB] : Object | | H.cs:165:20:165:27 | access to field FieldA : B [field FieldB] : Object | H.cs:165:17:165:27 | (...) ... : B [field FieldB] : Object | | H.cs:167:14:167:14 | access to local variable b : B [field FieldB] : Object | H.cs:167:14:167:21 | access to field FieldB | +| H.cs:167:14:167:14 | access to local variable b : B [field FieldB] : Object | H.cs:167:14:167:21 | access to field FieldB | +| I.cs:7:9:7:14 | [post] this access : I [field Field1] : Object | I.cs:21:13:21:19 | object creation of type I : I [field Field1] : Object | | I.cs:7:9:7:14 | [post] this access : I [field Field1] : Object | I.cs:21:13:21:19 | object creation of type I : I [field Field1] : Object | | I.cs:7:9:7:14 | [post] this access : I [field Field1] : Object | I.cs:26:13:26:37 | [pre-initializer] object creation of type I : I [field Field1] : Object | +| I.cs:7:9:7:14 | [post] this access : I [field Field1] : Object | I.cs:26:13:26:37 | [pre-initializer] object creation of type I : I [field Field1] : Object | +| I.cs:7:18:7:34 | call to method Source<Object> : Object | I.cs:7:9:7:14 | [post] this access : I [field Field1] : Object | | I.cs:7:18:7:34 | call to method Source<Object> : Object | I.cs:7:9:7:14 | [post] this access : I [field Field1] : Object | | I.cs:13:17:13:33 | call to method Source<Object> : Object | I.cs:15:20:15:20 | access to local variable o : Object | +| I.cs:13:17:13:33 | call to method Source<Object> : Object | I.cs:15:20:15:20 | access to local variable o : Object | +| I.cs:15:9:15:9 | [post] access to local variable i : I [field Field1] : Object | I.cs:16:9:16:9 | access to local variable i : I [field Field1] : Object | | I.cs:15:9:15:9 | [post] access to local variable i : I [field Field1] : Object | I.cs:16:9:16:9 | access to local variable i : I [field Field1] : Object | | I.cs:15:20:15:20 | access to local variable o : Object | I.cs:15:9:15:9 | [post] access to local variable i : I [field Field1] : Object | +| I.cs:15:20:15:20 | access to local variable o : Object | I.cs:15:9:15:9 | [post] access to local variable i : I [field Field1] : Object | +| I.cs:16:9:16:9 | access to local variable i : I [field Field1] : Object | I.cs:17:9:17:9 | access to local variable i : I [field Field1] : Object | | I.cs:16:9:16:9 | access to local variable i : I [field Field1] : Object | I.cs:17:9:17:9 | access to local variable i : I [field Field1] : Object | | I.cs:17:9:17:9 | access to local variable i : I [field Field1] : Object | I.cs:18:14:18:14 | access to local variable i : I [field Field1] : Object | +| I.cs:17:9:17:9 | access to local variable i : I [field Field1] : Object | I.cs:18:14:18:14 | access to local variable i : I [field Field1] : Object | +| I.cs:18:14:18:14 | access to local variable i : I [field Field1] : Object | I.cs:18:14:18:21 | access to field Field1 | | I.cs:18:14:18:14 | access to local variable i : I [field Field1] : Object | I.cs:18:14:18:21 | access to field Field1 | | I.cs:21:13:21:19 | object creation of type I : I [field Field1] : Object | I.cs:22:9:22:9 | access to local variable i : I [field Field1] : Object | +| I.cs:21:13:21:19 | object creation of type I : I [field Field1] : Object | I.cs:22:9:22:9 | access to local variable i : I [field Field1] : Object | +| I.cs:22:9:22:9 | access to local variable i : I [field Field1] : Object | I.cs:23:14:23:14 | access to local variable i : I [field Field1] : Object | | I.cs:22:9:22:9 | access to local variable i : I [field Field1] : Object | I.cs:23:14:23:14 | access to local variable i : I [field Field1] : Object | | I.cs:23:14:23:14 | access to local variable i : I [field Field1] : Object | I.cs:23:14:23:21 | access to field Field1 | +| I.cs:23:14:23:14 | access to local variable i : I [field Field1] : Object | I.cs:23:14:23:21 | access to field Field1 | +| I.cs:26:13:26:37 | [pre-initializer] object creation of type I : I [field Field1] : Object | I.cs:27:14:27:14 | access to local variable i : I [field Field1] : Object | | I.cs:26:13:26:37 | [pre-initializer] object creation of type I : I [field Field1] : Object | I.cs:27:14:27:14 | access to local variable i : I [field Field1] : Object | | I.cs:27:14:27:14 | access to local variable i : I [field Field1] : Object | I.cs:27:14:27:21 | access to field Field1 | +| I.cs:27:14:27:14 | access to local variable i : I [field Field1] : Object | I.cs:27:14:27:21 | access to field Field1 | +| I.cs:31:13:31:29 | call to method Source<Object> : Object | I.cs:32:20:32:20 | access to local variable o : Object | | I.cs:31:13:31:29 | call to method Source<Object> : Object | I.cs:32:20:32:20 | access to local variable o : Object | | I.cs:32:9:32:9 | [post] access to local variable i : I [field Field1] : Object | I.cs:33:9:33:9 | access to local variable i : I [field Field1] : Object | +| I.cs:32:9:32:9 | [post] access to local variable i : I [field Field1] : Object | I.cs:33:9:33:9 | access to local variable i : I [field Field1] : Object | +| I.cs:32:20:32:20 | access to local variable o : Object | I.cs:32:9:32:9 | [post] access to local variable i : I [field Field1] : Object | | I.cs:32:20:32:20 | access to local variable o : Object | I.cs:32:9:32:9 | [post] access to local variable i : I [field Field1] : Object | | I.cs:33:9:33:9 | access to local variable i : I [field Field1] : Object | I.cs:34:12:34:12 | access to local variable i : I [field Field1] : Object | +| I.cs:33:9:33:9 | access to local variable i : I [field Field1] : Object | I.cs:34:12:34:12 | access to local variable i : I [field Field1] : Object | +| I.cs:34:12:34:12 | access to local variable i : I [field Field1] : Object | I.cs:37:23:37:23 | i : I [field Field1] : Object | | I.cs:34:12:34:12 | access to local variable i : I [field Field1] : Object | I.cs:37:23:37:23 | i : I [field Field1] : Object | | I.cs:37:23:37:23 | i : I [field Field1] : Object | I.cs:39:9:39:9 | access to parameter i : I [field Field1] : Object | +| I.cs:37:23:37:23 | i : I [field Field1] : Object | I.cs:39:9:39:9 | access to parameter i : I [field Field1] : Object | +| I.cs:39:9:39:9 | access to parameter i : I [field Field1] : Object | I.cs:40:14:40:14 | access to parameter i : I [field Field1] : Object | | I.cs:39:9:39:9 | access to parameter i : I [field Field1] : Object | I.cs:40:14:40:14 | access to parameter i : I [field Field1] : Object | | I.cs:40:14:40:14 | access to parameter i : I [field Field1] : Object | I.cs:40:14:40:21 | access to field Field1 | +| I.cs:40:14:40:14 | access to parameter i : I [field Field1] : Object | I.cs:40:14:40:21 | access to field Field1 | +| J.cs:14:26:14:30 | field : Object | J.cs:14:66:14:70 | access to parameter field : Object | | J.cs:14:26:14:30 | field : Object | J.cs:14:66:14:70 | access to parameter field : Object | | J.cs:14:40:14:43 | prop : Object | J.cs:14:73:14:76 | access to parameter prop : Object | +| J.cs:14:40:14:43 | prop : Object | J.cs:14:73:14:76 | access to parameter prop : Object | +| J.cs:14:66:14:70 | access to parameter field : Object | J.cs:14:50:14:54 | [post] this access : Struct [field Field] : Object | | J.cs:14:66:14:70 | access to parameter field : Object | J.cs:14:50:14:54 | [post] this access : Struct [field Field] : Object | | J.cs:14:73:14:76 | access to parameter prop : Object | J.cs:14:57:14:60 | [post] this access : Struct [property Prop] : Object | +| J.cs:14:73:14:76 | access to parameter prop : Object | J.cs:14:57:14:60 | [post] this access : Struct [property Prop] : Object | +| J.cs:21:17:21:33 | call to method Source<Object> : Object | J.cs:22:34:22:34 | access to local variable o : Object | | J.cs:21:17:21:33 | call to method Source<Object> : Object | J.cs:22:34:22:34 | access to local variable o : Object | | J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | J.cs:23:14:23:15 | access to local variable r1 : RecordClass [property Prop1] : Object | +| J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | J.cs:23:14:23:15 | access to local variable r1 : RecordClass [property Prop1] : Object | +| J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | J.cs:27:14:27:15 | access to local variable r2 : RecordClass [property Prop1] : Object | | J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | J.cs:27:14:27:15 | access to local variable r2 : RecordClass [property Prop1] : Object | | J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | J.cs:31:14:31:15 | access to local variable r3 : RecordClass [property Prop1] : Object | +| J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | J.cs:31:14:31:15 | access to local variable r3 : RecordClass [property Prop1] : Object | +| J.cs:22:34:22:34 | access to local variable o : Object | J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | | J.cs:22:34:22:34 | access to local variable o : Object | J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | | J.cs:23:14:23:15 | access to local variable r1 : RecordClass [property Prop1] : Object | J.cs:23:14:23:21 | access to property Prop1 | +| J.cs:23:14:23:15 | access to local variable r1 : RecordClass [property Prop1] : Object | J.cs:23:14:23:21 | access to property Prop1 | +| J.cs:27:14:27:15 | access to local variable r2 : RecordClass [property Prop1] : Object | J.cs:27:14:27:21 | access to property Prop1 | | J.cs:27:14:27:15 | access to local variable r2 : RecordClass [property Prop1] : Object | J.cs:27:14:27:21 | access to property Prop1 | | J.cs:30:18:30:54 | ... with { ... } : RecordClass [property Prop2] : Object | J.cs:32:14:32:15 | access to local variable r3 : RecordClass [property Prop2] : Object | +| J.cs:30:18:30:54 | ... with { ... } : RecordClass [property Prop2] : Object | J.cs:32:14:32:15 | access to local variable r3 : RecordClass [property Prop2] : Object | +| J.cs:30:36:30:52 | call to method Source<Object> : Object | J.cs:30:18:30:54 | ... with { ... } : RecordClass [property Prop2] : Object | | J.cs:30:36:30:52 | call to method Source<Object> : Object | J.cs:30:18:30:54 | ... with { ... } : RecordClass [property Prop2] : Object | | J.cs:31:14:31:15 | access to local variable r3 : RecordClass [property Prop1] : Object | J.cs:31:14:31:21 | access to property Prop1 | +| J.cs:31:14:31:15 | access to local variable r3 : RecordClass [property Prop1] : Object | J.cs:31:14:31:21 | access to property Prop1 | +| J.cs:32:14:32:15 | access to local variable r3 : RecordClass [property Prop2] : Object | J.cs:32:14:32:21 | access to property Prop2 | | J.cs:32:14:32:15 | access to local variable r3 : RecordClass [property Prop2] : Object | J.cs:32:14:32:21 | access to property Prop2 | | J.cs:41:17:41:33 | call to method Source<Object> : Object | J.cs:42:35:42:35 | access to local variable o : Object | +| J.cs:41:17:41:33 | call to method Source<Object> : Object | J.cs:42:35:42:35 | access to local variable o : Object | +| J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | J.cs:43:14:43:15 | access to local variable r1 : RecordStruct [property Prop1] : Object | | J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | J.cs:43:14:43:15 | access to local variable r1 : RecordStruct [property Prop1] : Object | | J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | J.cs:47:14:47:15 | access to local variable r2 : RecordStruct [property Prop1] : Object | +| J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | J.cs:47:14:47:15 | access to local variable r2 : RecordStruct [property Prop1] : Object | +| J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | J.cs:51:14:51:15 | access to local variable r3 : RecordStruct [property Prop1] : Object | | J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | J.cs:51:14:51:15 | access to local variable r3 : RecordStruct [property Prop1] : Object | | J.cs:42:35:42:35 | access to local variable o : Object | J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | +| J.cs:42:35:42:35 | access to local variable o : Object | J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | +| J.cs:43:14:43:15 | access to local variable r1 : RecordStruct [property Prop1] : Object | J.cs:43:14:43:21 | access to property Prop1 | | J.cs:43:14:43:15 | access to local variable r1 : RecordStruct [property Prop1] : Object | J.cs:43:14:43:21 | access to property Prop1 | | J.cs:47:14:47:15 | access to local variable r2 : RecordStruct [property Prop1] : Object | J.cs:47:14:47:21 | access to property Prop1 | +| J.cs:47:14:47:15 | access to local variable r2 : RecordStruct [property Prop1] : Object | J.cs:47:14:47:21 | access to property Prop1 | +| J.cs:50:18:50:54 | ... with { ... } : RecordStruct [property Prop2] : Object | J.cs:52:14:52:15 | access to local variable r3 : RecordStruct [property Prop2] : Object | | J.cs:50:18:50:54 | ... with { ... } : RecordStruct [property Prop2] : Object | J.cs:52:14:52:15 | access to local variable r3 : RecordStruct [property Prop2] : Object | | J.cs:50:36:50:52 | call to method Source<Object> : Object | J.cs:50:18:50:54 | ... with { ... } : RecordStruct [property Prop2] : Object | +| J.cs:50:36:50:52 | call to method Source<Object> : Object | J.cs:50:18:50:54 | ... with { ... } : RecordStruct [property Prop2] : Object | +| J.cs:51:14:51:15 | access to local variable r3 : RecordStruct [property Prop1] : Object | J.cs:51:14:51:21 | access to property Prop1 | | J.cs:51:14:51:15 | access to local variable r3 : RecordStruct [property Prop1] : Object | J.cs:51:14:51:21 | access to property Prop1 | | J.cs:52:14:52:15 | access to local variable r3 : RecordStruct [property Prop2] : Object | J.cs:52:14:52:21 | access to property Prop2 | +| J.cs:52:14:52:15 | access to local variable r3 : RecordStruct [property Prop2] : Object | J.cs:52:14:52:21 | access to property Prop2 | +| J.cs:61:17:61:33 | call to method Source<Object> : Object | J.cs:62:29:62:29 | access to local variable o : Object | | J.cs:61:17:61:33 | call to method Source<Object> : Object | J.cs:62:29:62:29 | access to local variable o : Object | | J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | J.cs:65:14:65:15 | access to local variable s2 : Struct [field Field] : Object | +| J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | J.cs:65:14:65:15 | access to local variable s2 : Struct [field Field] : Object | +| J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | J.cs:69:14:69:15 | access to local variable s3 : Struct [field Field] : Object | | J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | J.cs:69:14:69:15 | access to local variable s3 : Struct [field Field] : Object | | J.cs:62:29:62:29 | access to local variable o : Object | J.cs:14:26:14:30 | field : Object | +| J.cs:62:29:62:29 | access to local variable o : Object | J.cs:14:26:14:30 | field : Object | +| J.cs:62:29:62:29 | access to local variable o : Object | J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | | J.cs:62:29:62:29 | access to local variable o : Object | J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | | J.cs:65:14:65:15 | access to local variable s2 : Struct [field Field] : Object | J.cs:65:14:65:21 | access to field Field | +| J.cs:65:14:65:15 | access to local variable s2 : Struct [field Field] : Object | J.cs:65:14:65:21 | access to field Field | +| J.cs:68:18:68:53 | ... with { ... } : Struct [property Prop] : Object | J.cs:70:14:70:15 | access to local variable s3 : Struct [property Prop] : Object | | J.cs:68:18:68:53 | ... with { ... } : Struct [property Prop] : Object | J.cs:70:14:70:15 | access to local variable s3 : Struct [property Prop] : Object | | J.cs:68:35:68:51 | call to method Source<Object> : Object | J.cs:68:18:68:53 | ... with { ... } : Struct [property Prop] : Object | +| J.cs:68:35:68:51 | call to method Source<Object> : Object | J.cs:68:18:68:53 | ... with { ... } : Struct [property Prop] : Object | +| J.cs:69:14:69:15 | access to local variable s3 : Struct [field Field] : Object | J.cs:69:14:69:21 | access to field Field | | J.cs:69:14:69:15 | access to local variable s3 : Struct [field Field] : Object | J.cs:69:14:69:21 | access to field Field | | J.cs:70:14:70:15 | access to local variable s3 : Struct [property Prop] : Object | J.cs:70:14:70:20 | access to property Prop | +| J.cs:70:14:70:15 | access to local variable s3 : Struct [property Prop] : Object | J.cs:70:14:70:20 | access to property Prop | +| J.cs:79:17:79:33 | call to method Source<Object> : Object | J.cs:80:35:80:35 | access to local variable o : Object | | J.cs:79:17:79:33 | call to method Source<Object> : Object | J.cs:80:35:80:35 | access to local variable o : Object | | J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | J.cs:84:14:84:15 | access to local variable s2 : Struct [property Prop] : Object | +| J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | J.cs:84:14:84:15 | access to local variable s2 : Struct [property Prop] : Object | +| J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | J.cs:88:14:88:15 | access to local variable s3 : Struct [property Prop] : Object | | J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | J.cs:88:14:88:15 | access to local variable s3 : Struct [property Prop] : Object | | J.cs:80:35:80:35 | access to local variable o : Object | J.cs:14:40:14:43 | prop : Object | +| J.cs:80:35:80:35 | access to local variable o : Object | J.cs:14:40:14:43 | prop : Object | +| J.cs:80:35:80:35 | access to local variable o : Object | J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | | J.cs:80:35:80:35 | access to local variable o : Object | J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | | J.cs:84:14:84:15 | access to local variable s2 : Struct [property Prop] : Object | J.cs:84:14:84:20 | access to property Prop | +| J.cs:84:14:84:15 | access to local variable s2 : Struct [property Prop] : Object | J.cs:84:14:84:20 | access to property Prop | +| J.cs:86:18:86:54 | ... with { ... } : Struct [field Field] : Object | J.cs:87:14:87:15 | access to local variable s3 : Struct [field Field] : Object | | J.cs:86:18:86:54 | ... with { ... } : Struct [field Field] : Object | J.cs:87:14:87:15 | access to local variable s3 : Struct [field Field] : Object | | J.cs:86:36:86:52 | call to method Source<Object> : Object | J.cs:86:18:86:54 | ... with { ... } : Struct [field Field] : Object | +| J.cs:86:36:86:52 | call to method Source<Object> : Object | J.cs:86:18:86:54 | ... with { ... } : Struct [field Field] : Object | +| J.cs:87:14:87:15 | access to local variable s3 : Struct [field Field] : Object | J.cs:87:14:87:21 | access to field Field | | J.cs:87:14:87:15 | access to local variable s3 : Struct [field Field] : Object | J.cs:87:14:87:21 | access to field Field | | J.cs:88:14:88:15 | access to local variable s3 : Struct [property Prop] : Object | J.cs:88:14:88:20 | access to property Prop | +| J.cs:88:14:88:15 | access to local variable s3 : Struct [property Prop] : Object | J.cs:88:14:88:20 | access to property Prop | +| J.cs:97:17:97:33 | call to method Source<Object> : Object | J.cs:99:28:99:28 | access to local variable o : Object | | J.cs:97:17:97:33 | call to method Source<Object> : Object | J.cs:99:28:99:28 | access to local variable o : Object | | J.cs:99:18:99:41 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | J.cs:102:14:102:15 | access to local variable a2 : <>__AnonType0<Object,Object> [property X] : Object | +| J.cs:99:18:99:41 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | J.cs:102:14:102:15 | access to local variable a2 : <>__AnonType0<Object,Object> [property X] : Object | +| J.cs:99:18:99:41 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | J.cs:106:14:106:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property X] : Object | | J.cs:99:18:99:41 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | J.cs:106:14:106:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property X] : Object | | J.cs:99:28:99:28 | access to local variable o : Object | J.cs:99:18:99:41 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | +| J.cs:99:28:99:28 | access to local variable o : Object | J.cs:99:18:99:41 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | +| J.cs:102:14:102:15 | access to local variable a2 : <>__AnonType0<Object,Object> [property X] : Object | J.cs:102:14:102:17 | access to property X | | J.cs:102:14:102:15 | access to local variable a2 : <>__AnonType0<Object,Object> [property X] : Object | J.cs:102:14:102:17 | access to property X | | J.cs:105:18:105:50 | ... with { ... } : <>__AnonType0<Object,Object> [property Y] : Object | J.cs:107:14:107:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property Y] : Object | +| J.cs:105:18:105:50 | ... with { ... } : <>__AnonType0<Object,Object> [property Y] : Object | J.cs:107:14:107:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property Y] : Object | +| J.cs:105:32:105:48 | call to method Source<Object> : Object | J.cs:105:18:105:50 | ... with { ... } : <>__AnonType0<Object,Object> [property Y] : Object | | J.cs:105:32:105:48 | call to method Source<Object> : Object | J.cs:105:18:105:50 | ... with { ... } : <>__AnonType0<Object,Object> [property Y] : Object | | J.cs:106:14:106:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property X] : Object | J.cs:106:14:106:17 | access to property X | +| J.cs:106:14:106:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property X] : Object | J.cs:106:14:106:17 | access to property X | +| J.cs:107:14:107:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property Y] : Object | J.cs:107:14:107:17 | access to property Y | | J.cs:107:14:107:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property Y] : Object | J.cs:107:14:107:17 | access to property Y | | J.cs:119:13:119:13 | [post] access to local variable a : Int32[] [element] : Int32 | J.cs:125:14:125:14 | access to local variable a : Int32[] [element] : Int32 | +| J.cs:119:13:119:13 | [post] access to local variable a : Int32[] [element] : Int32 | J.cs:125:14:125:14 | access to local variable a : Int32[] [element] : Int32 | +| J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | J.cs:119:13:119:13 | [post] access to local variable a : Int32[] [element] : Int32 | | J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | J.cs:119:13:119:13 | [post] access to local variable a : Int32[] [element] : Int32 | | J.cs:125:14:125:14 | access to local variable a : Int32[] [element] : Int32 | J.cs:125:14:125:17 | access to array element : Int32 | +| J.cs:125:14:125:14 | access to local variable a : Int32[] [element] : Int32 | J.cs:125:14:125:17 | access to array element : Int32 | +| J.cs:125:14:125:17 | access to array element : Int32 | J.cs:125:14:125:17 | (...) ... | | J.cs:125:14:125:17 | access to array element : Int32 | J.cs:125:14:125:17 | (...) ... | nodes | A.cs:5:17:5:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| A.cs:5:17:5:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| A.cs:6:17:6:25 | call to method Make : B [field c] : C | semmle.label | call to method Make : B [field c] : C | | A.cs:6:17:6:25 | call to method Make : B [field c] : C | semmle.label | call to method Make : B [field c] : C | | A.cs:6:24:6:24 | access to local variable c : C | semmle.label | access to local variable c : C | +| A.cs:6:24:6:24 | access to local variable c : C | semmle.label | access to local variable c : C | +| A.cs:7:14:7:14 | access to local variable b : B [field c] : C | semmle.label | access to local variable b : B [field c] : C | | A.cs:7:14:7:14 | access to local variable b : B [field c] : C | semmle.label | access to local variable b : B [field c] : C | | A.cs:7:14:7:16 | access to field c | semmle.label | access to field c | +| A.cs:7:14:7:16 | access to field c | semmle.label | access to field c | +| A.cs:13:9:13:9 | [post] access to local variable b : B [field c] : C1 | semmle.label | [post] access to local variable b : B [field c] : C1 | | A.cs:13:9:13:9 | [post] access to local variable b : B [field c] : C1 | semmle.label | [post] access to local variable b : B [field c] : C1 | | A.cs:13:15:13:29 | call to method Source<C1> : C1 | semmle.label | call to method Source<C1> : C1 | +| A.cs:13:15:13:29 | call to method Source<C1> : C1 | semmle.label | call to method Source<C1> : C1 | +| A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | semmle.label | access to local variable b : B [field c] : C1 | | A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | semmle.label | access to local variable b : B [field c] : C1 | | A.cs:14:14:14:20 | call to method Get | semmle.label | call to method Get | +| A.cs:14:14:14:20 | call to method Get | semmle.label | call to method Get | +| A.cs:15:14:15:42 | call to method Get | semmle.label | call to method Get | | A.cs:15:14:15:42 | call to method Get | semmle.label | call to method Get | | A.cs:15:15:15:35 | object creation of type B : B [field c] : C | semmle.label | object creation of type B : B [field c] : C | +| A.cs:15:15:15:35 | object creation of type B : B [field c] : C | semmle.label | object creation of type B : B [field c] : C | +| A.cs:15:21:15:34 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | | A.cs:15:21:15:34 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | | A.cs:22:14:22:38 | call to method SetOnB : B [field c] : C2 | semmle.label | call to method SetOnB : B [field c] : C2 | +| A.cs:22:14:22:38 | call to method SetOnB : B [field c] : C2 | semmle.label | call to method SetOnB : B [field c] : C2 | +| A.cs:22:25:22:37 | call to method Source<C2> : C2 | semmle.label | call to method Source<C2> : C2 | | A.cs:22:25:22:37 | call to method Source<C2> : C2 | semmle.label | call to method Source<C2> : C2 | | A.cs:24:14:24:15 | access to local variable b2 : B [field c] : C2 | semmle.label | access to local variable b2 : B [field c] : C2 | +| A.cs:24:14:24:15 | access to local variable b2 : B [field c] : C2 | semmle.label | access to local variable b2 : B [field c] : C2 | +| A.cs:24:14:24:17 | access to field c | semmle.label | access to field c | | A.cs:24:14:24:17 | access to field c | semmle.label | access to field c | | A.cs:31:14:31:42 | call to method SetOnBWrap : B [field c] : C2 | semmle.label | call to method SetOnBWrap : B [field c] : C2 | +| A.cs:31:14:31:42 | call to method SetOnBWrap : B [field c] : C2 | semmle.label | call to method SetOnBWrap : B [field c] : C2 | +| A.cs:31:29:31:41 | call to method Source<C2> : C2 | semmle.label | call to method Source<C2> : C2 | | A.cs:31:29:31:41 | call to method Source<C2> : C2 | semmle.label | call to method Source<C2> : C2 | | A.cs:33:14:33:15 | access to local variable b2 : B [field c] : C2 | semmle.label | access to local variable b2 : B [field c] : C2 | +| A.cs:33:14:33:15 | access to local variable b2 : B [field c] : C2 | semmle.label | access to local variable b2 : B [field c] : C2 | +| A.cs:33:14:33:17 | access to field c | semmle.label | access to field c | | A.cs:33:14:33:17 | access to field c | semmle.label | access to field c | | A.cs:36:33:36:33 | c : C2 | semmle.label | c : C2 | +| A.cs:36:33:36:33 | c : C2 | semmle.label | c : C2 | +| A.cs:38:18:38:30 | call to method SetOnB : B [field c] : C2 | semmle.label | call to method SetOnB : B [field c] : C2 | | A.cs:38:18:38:30 | call to method SetOnB : B [field c] : C2 | semmle.label | call to method SetOnB : B [field c] : C2 | | A.cs:38:29:38:29 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:38:29:38:29 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:39:16:39:28 | ... ? ... : ... : B [field c] : C2 | semmle.label | ... ? ... : ... : B [field c] : C2 | | A.cs:39:16:39:28 | ... ? ... : ... : B [field c] : C2 | semmle.label | ... ? ... : ... : B [field c] : C2 | | A.cs:42:29:42:29 | c : C2 | semmle.label | c : C2 | +| A.cs:42:29:42:29 | c : C2 | semmle.label | c : C2 | +| A.cs:47:13:47:14 | [post] access to local variable b2 : B [field c] : C2 | semmle.label | [post] access to local variable b2 : B [field c] : C2 | | A.cs:47:13:47:14 | [post] access to local variable b2 : B [field c] : C2 | semmle.label | [post] access to local variable b2 : B [field c] : C2 | | A.cs:47:20:47:20 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:47:20:47:20 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:48:20:48:21 | access to local variable b2 : B [field c] : C2 | semmle.label | access to local variable b2 : B [field c] : C2 | | A.cs:48:20:48:21 | access to local variable b2 : B [field c] : C2 | semmle.label | access to local variable b2 : B [field c] : C2 | | A.cs:55:17:55:28 | call to method Source<A> : A | semmle.label | call to method Source<A> : A | +| A.cs:55:17:55:28 | call to method Source<A> : A | semmle.label | call to method Source<A> : A | +| A.cs:57:9:57:10 | [post] access to local variable c1 : C1 [field a] : A | semmle.label | [post] access to local variable c1 : C1 [field a] : A | | A.cs:57:9:57:10 | [post] access to local variable c1 : C1 [field a] : A | semmle.label | [post] access to local variable c1 : C1 [field a] : A | | A.cs:57:16:57:16 | access to local variable a : A | semmle.label | access to local variable a : A | +| A.cs:57:16:57:16 | access to local variable a : A | semmle.label | access to local variable a : A | +| A.cs:58:12:58:13 | access to local variable c1 : C1 [field a] : A | semmle.label | access to local variable c1 : C1 [field a] : A | | A.cs:58:12:58:13 | access to local variable c1 : C1 [field a] : A | semmle.label | access to local variable c1 : C1 [field a] : A | | A.cs:60:22:60:22 | c : C1 [field a] : A | semmle.label | c : C1 [field a] : A | +| A.cs:60:22:60:22 | c : C1 [field a] : A | semmle.label | c : C1 [field a] : A | +| A.cs:64:18:64:26 | access to field a | semmle.label | access to field a | | A.cs:64:18:64:26 | access to field a | semmle.label | access to field a | | A.cs:64:19:64:23 | (...) ... : C1 [field a] : A | semmle.label | (...) ... : C1 [field a] : A | +| A.cs:64:19:64:23 | (...) ... : C1 [field a] : A | semmle.label | (...) ... : C1 [field a] : A | +| A.cs:83:9:83:9 | [post] access to parameter b : B [field c] : C | semmle.label | [post] access to parameter b : B [field c] : C | | A.cs:83:9:83:9 | [post] access to parameter b : B [field c] : C | semmle.label | [post] access to parameter b : B [field c] : C | | A.cs:83:15:83:26 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| A.cs:83:15:83:26 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| A.cs:88:12:88:12 | [post] access to local variable b : B [field c] : C | semmle.label | [post] access to local variable b : B [field c] : C | | A.cs:88:12:88:12 | [post] access to local variable b : B [field c] : C | semmle.label | [post] access to local variable b : B [field c] : C | | A.cs:89:14:89:14 | access to local variable b : B [field c] : C | semmle.label | access to local variable b : B [field c] : C | +| A.cs:89:14:89:14 | access to local variable b : B [field c] : C | semmle.label | access to local variable b : B [field c] : C | +| A.cs:89:14:89:16 | access to field c | semmle.label | access to field c | | A.cs:89:14:89:16 | access to field c | semmle.label | access to field c | | A.cs:95:20:95:20 | b : B | semmle.label | b : B | +| A.cs:95:20:95:20 | b : B | semmle.label | b : B | +| A.cs:97:13:97:13 | [post] access to parameter b : B [field c] : C | semmle.label | [post] access to parameter b : B [field c] : C | | A.cs:97:13:97:13 | [post] access to parameter b : B [field c] : C | semmle.label | [post] access to parameter b : B [field c] : C | | A.cs:97:13:97:13 | access to parameter b : B | semmle.label | access to parameter b : B | +| A.cs:97:13:97:13 | access to parameter b : B | semmle.label | access to parameter b : B | | A.cs:97:19:97:32 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| A.cs:97:19:97:32 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| A.cs:98:13:98:16 | [post] this access : D [field b, field c] : C | semmle.label | [post] this access : D [field b, field c] : C | | A.cs:98:13:98:16 | [post] this access : D [field b, field c] : C | semmle.label | [post] this access : D [field b, field c] : C | | A.cs:98:13:98:16 | [post] this access : D [field b] : B | semmle.label | [post] this access : D [field b] : B | | A.cs:98:13:98:16 | [post] this access : D [field b] : B | semmle.label | [post] this access : D [field b] : B | +| A.cs:98:13:98:16 | [post] this access : D [field b] : B | semmle.label | [post] this access : D [field b] : B | +| A.cs:98:13:98:16 | [post] this access : D [field b] : B | semmle.label | [post] this access : D [field b] : B | +| A.cs:98:22:98:43 | ... ? ... : ... : B | semmle.label | ... ? ... : ... : B | +| A.cs:98:22:98:43 | ... ? ... : ... : B | semmle.label | ... ? ... : ... : B | | A.cs:98:22:98:43 | ... ? ... : ... : B | semmle.label | ... ? ... : ... : B | | A.cs:98:22:98:43 | ... ? ... : ... : B | semmle.label | ... ? ... : ... : B | | A.cs:98:22:98:43 | ... ? ... : ... : B [field c] : C | semmle.label | ... ? ... : ... : B [field c] : C | +| A.cs:98:22:98:43 | ... ? ... : ... : B [field c] : C | semmle.label | ... ? ... : ... : B [field c] : C | +| A.cs:98:30:98:43 | call to method Source<B> : B | semmle.label | call to method Source<B> : B | | A.cs:98:30:98:43 | call to method Source<B> : B | semmle.label | call to method Source<B> : B | | A.cs:104:17:104:30 | call to method Source<B> : B | semmle.label | call to method Source<B> : B | +| A.cs:104:17:104:30 | call to method Source<B> : B | semmle.label | call to method Source<B> : B | +| A.cs:105:17:105:29 | object creation of type D : D [field b, field c] : C | semmle.label | object creation of type D : D [field b, field c] : C | | A.cs:105:17:105:29 | object creation of type D : D [field b, field c] : C | semmle.label | object creation of type D : D [field b, field c] : C | | A.cs:105:17:105:29 | object creation of type D : D [field b] : B | semmle.label | object creation of type D : D [field b] : B | +| A.cs:105:17:105:29 | object creation of type D : D [field b] : B | semmle.label | object creation of type D : D [field b] : B | +| A.cs:105:23:105:23 | [post] access to local variable b : B [field c] : C | semmle.label | [post] access to local variable b : B [field c] : C | | A.cs:105:23:105:23 | [post] access to local variable b : B [field c] : C | semmle.label | [post] access to local variable b : B [field c] : C | | A.cs:105:23:105:23 | access to local variable b : B | semmle.label | access to local variable b : B | +| A.cs:105:23:105:23 | access to local variable b : B | semmle.label | access to local variable b : B | +| A.cs:106:14:106:14 | access to local variable d : D [field b] : B | semmle.label | access to local variable d : D [field b] : B | | A.cs:106:14:106:14 | access to local variable d : D [field b] : B | semmle.label | access to local variable d : D [field b] : B | | A.cs:106:14:106:16 | access to field b | semmle.label | access to field b | +| A.cs:106:14:106:16 | access to field b | semmle.label | access to field b | +| A.cs:107:14:107:14 | access to local variable d : D [field b, field c] : C | semmle.label | access to local variable d : D [field b, field c] : C | | A.cs:107:14:107:14 | access to local variable d : D [field b, field c] : C | semmle.label | access to local variable d : D [field b, field c] : C | | A.cs:107:14:107:16 | access to field b : B [field c] : C | semmle.label | access to field b : B [field c] : C | +| A.cs:107:14:107:16 | access to field b : B [field c] : C | semmle.label | access to field b : B [field c] : C | +| A.cs:107:14:107:18 | access to field c | semmle.label | access to field c | | A.cs:107:14:107:18 | access to field c | semmle.label | access to field c | | A.cs:108:14:108:14 | access to local variable b : B [field c] : C | semmle.label | access to local variable b : B [field c] : C | +| A.cs:108:14:108:14 | access to local variable b : B [field c] : C | semmle.label | access to local variable b : B [field c] : C | +| A.cs:108:14:108:16 | access to field c | semmle.label | access to field c | | A.cs:108:14:108:16 | access to field c | semmle.label | access to field c | | A.cs:113:17:113:29 | call to method Source<B> : B | semmle.label | call to method Source<B> : B | +| A.cs:113:17:113:29 | call to method Source<B> : B | semmle.label | call to method Source<B> : B | +| A.cs:114:18:114:54 | object creation of type MyList : MyList [field head] : B | semmle.label | object creation of type MyList : MyList [field head] : B | | A.cs:114:18:114:54 | object creation of type MyList : MyList [field head] : B | semmle.label | object creation of type MyList : MyList [field head] : B | | A.cs:114:29:114:29 | access to local variable b : B | semmle.label | access to local variable b : B | +| A.cs:114:29:114:29 | access to local variable b : B | semmle.label | access to local variable b : B | +| A.cs:115:18:115:37 | object creation of type MyList : MyList [field next, field head] : B | semmle.label | object creation of type MyList : MyList [field next, field head] : B | | A.cs:115:18:115:37 | object creation of type MyList : MyList [field next, field head] : B | semmle.label | object creation of type MyList : MyList [field next, field head] : B | | A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | semmle.label | access to local variable l1 : MyList [field head] : B | +| A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | semmle.label | access to local variable l1 : MyList [field head] : B | +| A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | semmle.label | object creation of type MyList : MyList [field next, field next, field head] : B | | A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | semmle.label | object creation of type MyList : MyList [field next, field next, field head] : B | | A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | semmle.label | access to local variable l2 : MyList [field next, field head] : B | +| A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | semmle.label | access to local variable l2 : MyList [field next, field head] : B | +| A.cs:119:14:119:15 | access to local variable l3 : MyList [field next, field next, field head] : B | semmle.label | access to local variable l3 : MyList [field next, field next, field head] : B | | A.cs:119:14:119:15 | access to local variable l3 : MyList [field next, field next, field head] : B | semmle.label | access to local variable l3 : MyList [field next, field next, field head] : B | | A.cs:119:14:119:20 | access to field next : MyList [field next, field head] : B | semmle.label | access to field next : MyList [field next, field head] : B | +| A.cs:119:14:119:20 | access to field next : MyList [field next, field head] : B | semmle.label | access to field next : MyList [field next, field head] : B | +| A.cs:119:14:119:25 | access to field next : MyList [field head] : B | semmle.label | access to field next : MyList [field head] : B | | A.cs:119:14:119:25 | access to field next : MyList [field head] : B | semmle.label | access to field next : MyList [field head] : B | | A.cs:119:14:119:30 | access to field head | semmle.label | access to field head | +| A.cs:119:14:119:30 | access to field head | semmle.label | access to field head | +| A.cs:121:41:121:41 | access to local variable l : MyList [field next, field head] : B | semmle.label | access to local variable l : MyList [field next, field head] : B | | A.cs:121:41:121:41 | access to local variable l : MyList [field next, field head] : B | semmle.label | access to local variable l : MyList [field next, field head] : B | | A.cs:121:41:121:41 | access to local variable l : MyList [field next, field next, field head] : B | semmle.label | access to local variable l : MyList [field next, field next, field head] : B | +| A.cs:121:41:121:41 | access to local variable l : MyList [field next, field next, field head] : B | semmle.label | access to local variable l : MyList [field next, field next, field head] : B | +| A.cs:121:41:121:46 | access to field next : MyList [field head] : B | semmle.label | access to field next : MyList [field head] : B | | A.cs:121:41:121:46 | access to field next : MyList [field head] : B | semmle.label | access to field next : MyList [field head] : B | | A.cs:121:41:121:46 | access to field next : MyList [field next, field head] : B | semmle.label | access to field next : MyList [field next, field head] : B | +| A.cs:121:41:121:46 | access to field next : MyList [field next, field head] : B | semmle.label | access to field next : MyList [field next, field head] : B | +| A.cs:123:18:123:18 | access to local variable l : MyList [field head] : B | semmle.label | access to local variable l : MyList [field head] : B | | A.cs:123:18:123:18 | access to local variable l : MyList [field head] : B | semmle.label | access to local variable l : MyList [field head] : B | | A.cs:123:18:123:23 | access to field head | semmle.label | access to field head | +| A.cs:123:18:123:23 | access to field head | semmle.label | access to field head | +| A.cs:141:20:141:20 | c : C | semmle.label | c : C | | A.cs:141:20:141:20 | c : C | semmle.label | c : C | | A.cs:143:13:143:16 | [post] this access : B [field c] : C | semmle.label | [post] this access : B [field c] : C | +| A.cs:143:13:143:16 | [post] this access : B [field c] : C | semmle.label | [post] this access : B [field c] : C | +| A.cs:143:22:143:22 | access to parameter c : C | semmle.label | access to parameter c : C | | A.cs:143:22:143:22 | access to parameter c : C | semmle.label | access to parameter c : C | | A.cs:145:27:145:27 | c : C | semmle.label | c : C | +| A.cs:145:27:145:27 | c : C | semmle.label | c : C | +| A.cs:145:27:145:27 | c : C1 | semmle.label | c : C1 | | A.cs:145:27:145:27 | c : C1 | semmle.label | c : C1 | | A.cs:145:27:145:27 | c : C2 | semmle.label | c : C2 | +| A.cs:145:27:145:27 | c : C2 | semmle.label | c : C2 | +| A.cs:145:32:145:35 | [post] this access : B [field c] : C | semmle.label | [post] this access : B [field c] : C | | A.cs:145:32:145:35 | [post] this access : B [field c] : C | semmle.label | [post] this access : B [field c] : C | | A.cs:145:32:145:35 | [post] this access : B [field c] : C1 | semmle.label | [post] this access : B [field c] : C1 | +| A.cs:145:32:145:35 | [post] this access : B [field c] : C1 | semmle.label | [post] this access : B [field c] : C1 | +| A.cs:145:32:145:35 | [post] this access : B [field c] : C2 | semmle.label | [post] this access : B [field c] : C2 | | A.cs:145:32:145:35 | [post] this access : B [field c] : C2 | semmle.label | [post] this access : B [field c] : C2 | | A.cs:145:41:145:41 | access to parameter c : C | semmle.label | access to parameter c : C | +| A.cs:145:41:145:41 | access to parameter c : C | semmle.label | access to parameter c : C | +| A.cs:145:41:145:41 | access to parameter c : C1 | semmle.label | access to parameter c : C1 | | A.cs:145:41:145:41 | access to parameter c : C1 | semmle.label | access to parameter c : C1 | | A.cs:145:41:145:41 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:145:41:145:41 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:146:18:146:20 | this : B [field c] : C | semmle.label | this : B [field c] : C | | A.cs:146:18:146:20 | this : B [field c] : C | semmle.label | this : B [field c] : C | | A.cs:146:18:146:20 | this : B [field c] : C1 | semmle.label | this : B [field c] : C1 | +| A.cs:146:18:146:20 | this : B [field c] : C1 | semmle.label | this : B [field c] : C1 | +| A.cs:146:33:146:36 | this access : B [field c] : C | semmle.label | this access : B [field c] : C | | A.cs:146:33:146:36 | this access : B [field c] : C | semmle.label | this access : B [field c] : C | | A.cs:146:33:146:36 | this access : B [field c] : C1 | semmle.label | this access : B [field c] : C1 | +| A.cs:146:33:146:36 | this access : B [field c] : C1 | semmle.label | this access : B [field c] : C1 | +| A.cs:146:33:146:38 | access to field c : C | semmle.label | access to field c : C | | A.cs:146:33:146:38 | access to field c : C | semmle.label | access to field c : C | | A.cs:146:33:146:38 | access to field c : C1 | semmle.label | access to field c : C1 | +| A.cs:146:33:146:38 | access to field c : C1 | semmle.label | access to field c : C1 | +| A.cs:147:32:147:32 | c : C | semmle.label | c : C | | A.cs:147:32:147:32 | c : C | semmle.label | c : C | | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | semmle.label | object creation of type B : B [field c] : C | +| A.cs:149:20:149:27 | object creation of type B : B [field c] : C | semmle.label | object creation of type B : B [field c] : C | +| A.cs:149:26:149:26 | access to parameter c : C | semmle.label | access to parameter c : C | | A.cs:149:26:149:26 | access to parameter c : C | semmle.label | access to parameter c : C | | A.cs:157:25:157:28 | head : B | semmle.label | head : B | +| A.cs:157:25:157:28 | head : B | semmle.label | head : B | +| A.cs:157:38:157:41 | next : MyList [field head] : B | semmle.label | next : MyList [field head] : B | | A.cs:157:38:157:41 | next : MyList [field head] : B | semmle.label | next : MyList [field head] : B | | A.cs:157:38:157:41 | next : MyList [field next, field head] : B | semmle.label | next : MyList [field next, field head] : B | +| A.cs:157:38:157:41 | next : MyList [field next, field head] : B | semmle.label | next : MyList [field next, field head] : B | +| A.cs:159:13:159:16 | [post] this access : MyList [field head] : B | semmle.label | [post] this access : MyList [field head] : B | | A.cs:159:13:159:16 | [post] this access : MyList [field head] : B | semmle.label | [post] this access : MyList [field head] : B | | A.cs:159:25:159:28 | access to parameter head : B | semmle.label | access to parameter head : B | +| A.cs:159:25:159:28 | access to parameter head : B | semmle.label | access to parameter head : B | +| A.cs:160:13:160:16 | [post] this access : MyList [field next, field head] : B | semmle.label | [post] this access : MyList [field next, field head] : B | | A.cs:160:13:160:16 | [post] this access : MyList [field next, field head] : B | semmle.label | [post] this access : MyList [field next, field head] : B | | A.cs:160:13:160:16 | [post] this access : MyList [field next, field next, field head] : B | semmle.label | [post] this access : MyList [field next, field next, field head] : B | +| A.cs:160:13:160:16 | [post] this access : MyList [field next, field next, field head] : B | semmle.label | [post] this access : MyList [field next, field next, field head] : B | +| A.cs:160:25:160:28 | access to parameter next : MyList [field head] : B | semmle.label | access to parameter next : MyList [field head] : B | | A.cs:160:25:160:28 | access to parameter next : MyList [field head] : B | semmle.label | access to parameter next : MyList [field head] : B | | A.cs:160:25:160:28 | access to parameter next : MyList [field next, field head] : B | semmle.label | access to parameter next : MyList [field next, field head] : B | +| A.cs:160:25:160:28 | access to parameter next : MyList [field next, field head] : B | semmle.label | access to parameter next : MyList [field next, field head] : B | +| B.cs:5:17:5:31 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | B.cs:5:17:5:31 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | B.cs:6:18:6:34 | object creation of type Box1 : Box1 [field elem1] : Elem | semmle.label | object creation of type Box1 : Box1 [field elem1] : Elem | +| B.cs:6:18:6:34 | object creation of type Box1 : Box1 [field elem1] : Elem | semmle.label | object creation of type Box1 : Box1 [field elem1] : Elem | +| B.cs:6:27:6:27 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | | B.cs:6:27:6:27 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | | B.cs:7:18:7:29 | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | semmle.label | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | +| B.cs:7:18:7:29 | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | semmle.label | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | +| B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | semmle.label | access to local variable b1 : Box1 [field elem1] : Elem | | B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | semmle.label | access to local variable b1 : Box1 [field elem1] : Elem | | B.cs:8:14:8:15 | access to local variable b2 : Box2 [field box1, field elem1] : Elem | semmle.label | access to local variable b2 : Box2 [field box1, field elem1] : Elem | +| B.cs:8:14:8:15 | access to local variable b2 : Box2 [field box1, field elem1] : Elem | semmle.label | access to local variable b2 : Box2 [field box1, field elem1] : Elem | +| B.cs:8:14:8:20 | access to field box1 : Box1 [field elem1] : Elem | semmle.label | access to field box1 : Box1 [field elem1] : Elem | | B.cs:8:14:8:20 | access to field box1 : Box1 [field elem1] : Elem | semmle.label | access to field box1 : Box1 [field elem1] : Elem | | B.cs:8:14:8:26 | access to field elem1 | semmle.label | access to field elem1 | +| B.cs:8:14:8:26 | access to field elem1 | semmle.label | access to field elem1 | +| B.cs:14:17:14:31 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | B.cs:14:17:14:31 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | B.cs:15:18:15:34 | object creation of type Box1 : Box1 [field elem2] : Elem | semmle.label | object creation of type Box1 : Box1 [field elem2] : Elem | +| B.cs:15:18:15:34 | object creation of type Box1 : Box1 [field elem2] : Elem | semmle.label | object creation of type Box1 : Box1 [field elem2] : Elem | +| B.cs:15:33:15:33 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | | B.cs:15:33:15:33 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | | B.cs:16:18:16:29 | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | semmle.label | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | +| B.cs:16:18:16:29 | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | semmle.label | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | +| B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | semmle.label | access to local variable b1 : Box1 [field elem2] : Elem | | B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | semmle.label | access to local variable b1 : Box1 [field elem2] : Elem | | B.cs:18:14:18:15 | access to local variable b2 : Box2 [field box1, field elem2] : Elem | semmle.label | access to local variable b2 : Box2 [field box1, field elem2] : Elem | +| B.cs:18:14:18:15 | access to local variable b2 : Box2 [field box1, field elem2] : Elem | semmle.label | access to local variable b2 : Box2 [field box1, field elem2] : Elem | +| B.cs:18:14:18:20 | access to field box1 : Box1 [field elem2] : Elem | semmle.label | access to field box1 : Box1 [field elem2] : Elem | | B.cs:18:14:18:20 | access to field box1 : Box1 [field elem2] : Elem | semmle.label | access to field box1 : Box1 [field elem2] : Elem | | B.cs:18:14:18:26 | access to field elem2 | semmle.label | access to field elem2 | +| B.cs:18:14:18:26 | access to field elem2 | semmle.label | access to field elem2 | +| B.cs:29:26:29:27 | e1 : Elem | semmle.label | e1 : Elem | | B.cs:29:26:29:27 | e1 : Elem | semmle.label | e1 : Elem | | B.cs:29:35:29:36 | e2 : Elem | semmle.label | e2 : Elem | +| B.cs:29:35:29:36 | e2 : Elem | semmle.label | e2 : Elem | +| B.cs:31:13:31:16 | [post] this access : Box1 [field elem1] : Elem | semmle.label | [post] this access : Box1 [field elem1] : Elem | | B.cs:31:13:31:16 | [post] this access : Box1 [field elem1] : Elem | semmle.label | [post] this access : Box1 [field elem1] : Elem | | B.cs:31:26:31:27 | access to parameter e1 : Elem | semmle.label | access to parameter e1 : Elem | +| B.cs:31:26:31:27 | access to parameter e1 : Elem | semmle.label | access to parameter e1 : Elem | +| B.cs:32:13:32:16 | [post] this access : Box1 [field elem2] : Elem | semmle.label | [post] this access : Box1 [field elem2] : Elem | | B.cs:32:13:32:16 | [post] this access : Box1 [field elem2] : Elem | semmle.label | [post] this access : Box1 [field elem2] : Elem | | B.cs:32:26:32:27 | access to parameter e2 : Elem | semmle.label | access to parameter e2 : Elem | +| B.cs:32:26:32:27 | access to parameter e2 : Elem | semmle.label | access to parameter e2 : Elem | +| B.cs:39:26:39:27 | b1 : Box1 [field elem1] : Elem | semmle.label | b1 : Box1 [field elem1] : Elem | | B.cs:39:26:39:27 | b1 : Box1 [field elem1] : Elem | semmle.label | b1 : Box1 [field elem1] : Elem | | B.cs:39:26:39:27 | b1 : Box1 [field elem2] : Elem | semmle.label | b1 : Box1 [field elem2] : Elem | +| B.cs:39:26:39:27 | b1 : Box1 [field elem2] : Elem | semmle.label | b1 : Box1 [field elem2] : Elem | +| B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem1] : Elem | semmle.label | [post] this access : Box2 [field box1, field elem1] : Elem | | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem1] : Elem | semmle.label | [post] this access : Box2 [field box1, field elem1] : Elem | | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem2] : Elem | semmle.label | [post] this access : Box2 [field box1, field elem2] : Elem | +| B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem2] : Elem | semmle.label | [post] this access : Box2 [field box1, field elem2] : Elem | +| B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem1] : Elem | semmle.label | access to parameter b1 : Box1 [field elem1] : Elem | | B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem1] : Elem | semmle.label | access to parameter b1 : Box1 [field elem1] : Elem | | B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem2] : Elem | semmle.label | access to parameter b1 : Box1 [field elem2] : Elem | +| B.cs:41:25:41:26 | access to parameter b1 : Box1 [field elem2] : Elem | semmle.label | access to parameter b1 : Box1 [field elem2] : Elem | +| C.cs:3:18:3:19 | [post] this access : C [field s1] : Elem | semmle.label | [post] this access : C [field s1] : Elem | | C.cs:3:18:3:19 | [post] this access : C [field s1] : Elem | semmle.label | [post] this access : C [field s1] : Elem | | C.cs:3:23:3:37 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C.cs:3:23:3:37 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C.cs:4:27:4:28 | [post] this access : C [field s2] : Elem | semmle.label | [post] this access : C [field s2] : Elem | | C.cs:4:27:4:28 | [post] this access : C [field s2] : Elem | semmle.label | [post] this access : C [field s2] : Elem | | C.cs:4:32:4:46 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C.cs:4:32:4:46 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C.cs:6:30:6:44 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | C.cs:6:30:6:44 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | C.cs:7:18:7:19 | [post] this access : C [property s5] : Elem | semmle.label | [post] this access : C [property s5] : Elem | +| C.cs:7:18:7:19 | [post] this access : C [property s5] : Elem | semmle.label | [post] this access : C [property s5] : Elem | +| C.cs:7:37:7:51 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | C.cs:7:37:7:51 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | C.cs:8:30:8:44 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C.cs:8:30:8:44 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C.cs:12:15:12:21 | object creation of type C : C [field s1] : Elem | semmle.label | object creation of type C : C [field s1] : Elem | | C.cs:12:15:12:21 | object creation of type C : C [field s1] : Elem | semmle.label | object creation of type C : C [field s1] : Elem | | C.cs:12:15:12:21 | object creation of type C : C [field s2] : Elem | semmle.label | object creation of type C : C [field s2] : Elem | +| C.cs:12:15:12:21 | object creation of type C : C [field s2] : Elem | semmle.label | object creation of type C : C [field s2] : Elem | +| C.cs:12:15:12:21 | object creation of type C : C [field s3] : Elem | semmle.label | object creation of type C : C [field s3] : Elem | | C.cs:12:15:12:21 | object creation of type C : C [field s3] : Elem | semmle.label | object creation of type C : C [field s3] : Elem | | C.cs:12:15:12:21 | object creation of type C : C [property s5] : Elem | semmle.label | object creation of type C : C [property s5] : Elem | +| C.cs:12:15:12:21 | object creation of type C : C [property s5] : Elem | semmle.label | object creation of type C : C [property s5] : Elem | +| C.cs:13:9:13:9 | access to local variable c : C [field s1] : Elem | semmle.label | access to local variable c : C [field s1] : Elem | | C.cs:13:9:13:9 | access to local variable c : C [field s1] : Elem | semmle.label | access to local variable c : C [field s1] : Elem | | C.cs:13:9:13:9 | access to local variable c : C [field s2] : Elem | semmle.label | access to local variable c : C [field s2] : Elem | +| C.cs:13:9:13:9 | access to local variable c : C [field s2] : Elem | semmle.label | access to local variable c : C [field s2] : Elem | +| C.cs:13:9:13:9 | access to local variable c : C [field s3] : Elem | semmle.label | access to local variable c : C [field s3] : Elem | | C.cs:13:9:13:9 | access to local variable c : C [field s3] : Elem | semmle.label | access to local variable c : C [field s3] : Elem | | C.cs:13:9:13:9 | access to local variable c : C [property s5] : Elem | semmle.label | access to local variable c : C [property s5] : Elem | +| C.cs:13:9:13:9 | access to local variable c : C [property s5] : Elem | semmle.label | access to local variable c : C [property s5] : Elem | +| C.cs:18:9:18:12 | [post] this access : C [field s3] : Elem | semmle.label | [post] this access : C [field s3] : Elem | | C.cs:18:9:18:12 | [post] this access : C [field s3] : Elem | semmle.label | [post] this access : C [field s3] : Elem | | C.cs:18:19:18:33 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C.cs:18:19:18:33 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C.cs:21:17:21:18 | this : C [field s1] : Elem | semmle.label | this : C [field s1] : Elem | | C.cs:21:17:21:18 | this : C [field s1] : Elem | semmle.label | this : C [field s1] : Elem | | C.cs:21:17:21:18 | this : C [field s2] : Elem | semmle.label | this : C [field s2] : Elem | +| C.cs:21:17:21:18 | this : C [field s2] : Elem | semmle.label | this : C [field s2] : Elem | +| C.cs:21:17:21:18 | this : C [field s3] : Elem | semmle.label | this : C [field s3] : Elem | | C.cs:21:17:21:18 | this : C [field s3] : Elem | semmle.label | this : C [field s3] : Elem | | C.cs:21:17:21:18 | this : C [property s5] : Elem | semmle.label | this : C [property s5] : Elem | +| C.cs:21:17:21:18 | this : C [property s5] : Elem | semmle.label | this : C [property s5] : Elem | +| C.cs:23:14:23:15 | access to field s1 | semmle.label | access to field s1 | | C.cs:23:14:23:15 | access to field s1 | semmle.label | access to field s1 | | C.cs:23:14:23:15 | this access : C [field s1] : Elem | semmle.label | this access : C [field s1] : Elem | +| C.cs:23:14:23:15 | this access : C [field s1] : Elem | semmle.label | this access : C [field s1] : Elem | +| C.cs:24:14:24:15 | access to field s2 | semmle.label | access to field s2 | | C.cs:24:14:24:15 | access to field s2 | semmle.label | access to field s2 | | C.cs:24:14:24:15 | this access : C [field s2] : Elem | semmle.label | this access : C [field s2] : Elem | +| C.cs:24:14:24:15 | this access : C [field s2] : Elem | semmle.label | this access : C [field s2] : Elem | +| C.cs:25:14:25:15 | access to field s3 | semmle.label | access to field s3 | | C.cs:25:14:25:15 | access to field s3 | semmle.label | access to field s3 | | C.cs:25:14:25:15 | this access : C [field s3] : Elem | semmle.label | this access : C [field s3] : Elem | +| C.cs:25:14:25:15 | this access : C [field s3] : Elem | semmle.label | this access : C [field s3] : Elem | +| C.cs:26:14:26:15 | access to field s4 | semmle.label | access to field s4 | | C.cs:26:14:26:15 | access to field s4 | semmle.label | access to field s4 | | C.cs:27:14:27:15 | access to property s5 | semmle.label | access to property s5 | +| C.cs:27:14:27:15 | access to property s5 | semmle.label | access to property s5 | +| C.cs:27:14:27:15 | this access : C [property s5] : Elem | semmle.label | this access : C [property s5] : Elem | | C.cs:27:14:27:15 | this access : C [property s5] : Elem | semmle.label | this access : C [property s5] : Elem | | C.cs:28:14:28:15 | access to property s6 | semmle.label | access to property s6 | +| C.cs:28:14:28:15 | access to property s6 | semmle.label | access to property s6 | +| C_ctor.cs:3:18:3:19 | [post] this access : C_no_ctor [field s1] : Elem | semmle.label | [post] this access : C_no_ctor [field s1] : Elem | | C_ctor.cs:3:18:3:19 | [post] this access : C_no_ctor [field s1] : Elem | semmle.label | [post] this access : C_no_ctor [field s1] : Elem | | C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor : C_no_ctor [field s1] : Elem | semmle.label | object creation of type C_no_ctor : C_no_ctor [field s1] : Elem | | C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor : C_no_ctor [field s1] : Elem | semmle.label | object creation of type C_no_ctor : C_no_ctor [field s1] : Elem | | C_ctor.cs:8:9:8:9 | access to local variable c : C_no_ctor [field s1] : Elem | semmle.label | access to local variable c : C_no_ctor [field s1] : Elem | +| C_ctor.cs:8:9:8:9 | access to local variable c : C_no_ctor [field s1] : Elem | semmle.label | access to local variable c : C_no_ctor [field s1] : Elem | +| C_ctor.cs:11:17:11:18 | this : C_no_ctor [field s1] : Elem | semmle.label | this : C_no_ctor [field s1] : Elem | | C_ctor.cs:11:17:11:18 | this : C_no_ctor [field s1] : Elem | semmle.label | this : C_no_ctor [field s1] : Elem | | C_ctor.cs:13:19:13:20 | access to field s1 | semmle.label | access to field s1 | +| C_ctor.cs:13:19:13:20 | access to field s1 | semmle.label | access to field s1 | +| C_ctor.cs:13:19:13:20 | this access : C_no_ctor [field s1] : Elem | semmle.label | this access : C_no_ctor [field s1] : Elem | | C_ctor.cs:13:19:13:20 | this access : C_no_ctor [field s1] : Elem | semmle.label | this access : C_no_ctor [field s1] : Elem | | C_ctor.cs:19:18:19:19 | [post] this access : C_with_ctor [field s1] : Elem | semmle.label | [post] this access : C_with_ctor [field s1] : Elem | +| C_ctor.cs:19:18:19:19 | [post] this access : C_with_ctor [field s1] : Elem | semmle.label | [post] this access : C_with_ctor [field s1] : Elem | +| C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor : C_with_ctor [field s1] : Elem | semmle.label | object creation of type C_with_ctor : C_with_ctor [field s1] : Elem | +| C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor : C_with_ctor [field s1] : Elem | semmle.label | object creation of type C_with_ctor : C_with_ctor [field s1] : Elem | +| C_ctor.cs:24:9:24:9 | access to local variable c : C_with_ctor [field s1] : Elem | semmle.label | access to local variable c : C_with_ctor [field s1] : Elem | | C_ctor.cs:24:9:24:9 | access to local variable c : C_with_ctor [field s1] : Elem | semmle.label | access to local variable c : C_with_ctor [field s1] : Elem | | C_ctor.cs:29:17:29:18 | this : C_with_ctor [field s1] : Elem | semmle.label | this : C_with_ctor [field s1] : Elem | +| C_ctor.cs:29:17:29:18 | this : C_with_ctor [field s1] : Elem | semmle.label | this : C_with_ctor [field s1] : Elem | +| C_ctor.cs:31:19:31:20 | access to field s1 | semmle.label | access to field s1 | | C_ctor.cs:31:19:31:20 | access to field s1 | semmle.label | access to field s1 | | C_ctor.cs:31:19:31:20 | this access : C_with_ctor [field s1] : Elem | semmle.label | this access : C_with_ctor [field s1] : Elem | +| C_ctor.cs:31:19:31:20 | this access : C_with_ctor [field s1] : Elem | semmle.label | this access : C_with_ctor [field s1] : Elem | +| D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | semmle.label | this : D [field trivialPropField] : Object | | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | semmle.label | this : D [field trivialPropField] : Object | | D.cs:8:22:8:25 | this access : D [field trivialPropField] : Object | semmle.label | this access : D [field trivialPropField] : Object | +| D.cs:8:22:8:25 | this access : D [field trivialPropField] : Object | semmle.label | this access : D [field trivialPropField] : Object | +| D.cs:8:22:8:42 | access to field trivialPropField : Object | semmle.label | access to field trivialPropField : Object | | D.cs:8:22:8:42 | access to field trivialPropField : Object | semmle.label | access to field trivialPropField : Object | | D.cs:9:9:9:11 | value : Object | semmle.label | value : Object | +| D.cs:9:9:9:11 | value : Object | semmle.label | value : Object | +| D.cs:9:15:9:18 | [post] this access : D [field trivialPropField] : Object | semmle.label | [post] this access : D [field trivialPropField] : Object | | D.cs:9:15:9:18 | [post] this access : D [field trivialPropField] : Object | semmle.label | [post] this access : D [field trivialPropField] : Object | | D.cs:9:39:9:43 | access to parameter value : Object | semmle.label | access to parameter value : Object | +| D.cs:9:39:9:43 | access to parameter value : Object | semmle.label | access to parameter value : Object | +| D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | semmle.label | this : D [field trivialPropField] : Object | | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | semmle.label | this : D [field trivialPropField] : Object | | D.cs:14:22:14:25 | this access : D [field trivialPropField] : Object | semmle.label | this access : D [field trivialPropField] : Object | +| D.cs:14:22:14:25 | this access : D [field trivialPropField] : Object | semmle.label | this access : D [field trivialPropField] : Object | +| D.cs:14:22:14:42 | access to field trivialPropField : Object | semmle.label | access to field trivialPropField : Object | | D.cs:14:22:14:42 | access to field trivialPropField : Object | semmle.label | access to field trivialPropField : Object | | D.cs:15:9:15:11 | value : Object | semmle.label | value : Object | +| D.cs:15:9:15:11 | value : Object | semmle.label | value : Object | +| D.cs:15:15:15:18 | [post] this access : D [field trivialPropField] : Object | semmle.label | [post] this access : D [field trivialPropField] : Object | | D.cs:15:15:15:18 | [post] this access : D [field trivialPropField] : Object | semmle.label | [post] this access : D [field trivialPropField] : Object | | D.cs:15:34:15:38 | access to parameter value : Object | semmle.label | access to parameter value : Object | +| D.cs:15:34:15:38 | access to parameter value : Object | semmle.label | access to parameter value : Object | +| D.cs:18:28:18:29 | o1 : Object | semmle.label | o1 : Object | | D.cs:18:28:18:29 | o1 : Object | semmle.label | o1 : Object | | D.cs:18:39:18:40 | o2 : Object | semmle.label | o2 : Object | +| D.cs:18:39:18:40 | o2 : Object | semmle.label | o2 : Object | +| D.cs:18:50:18:51 | o3 : Object | semmle.label | o3 : Object | | D.cs:18:50:18:51 | o3 : Object | semmle.label | o3 : Object | | D.cs:21:9:21:11 | [post] access to local variable ret : D [property AutoProp] : Object | semmle.label | [post] access to local variable ret : D [property AutoProp] : Object | +| D.cs:21:9:21:11 | [post] access to local variable ret : D [property AutoProp] : Object | semmle.label | [post] access to local variable ret : D [property AutoProp] : Object | +| D.cs:21:24:21:25 | access to parameter o1 : Object | semmle.label | access to parameter o1 : Object | | D.cs:21:24:21:25 | access to parameter o1 : Object | semmle.label | access to parameter o1 : Object | | D.cs:22:9:22:11 | [post] access to local variable ret : D [field trivialPropField] : Object | semmle.label | [post] access to local variable ret : D [field trivialPropField] : Object | +| D.cs:22:9:22:11 | [post] access to local variable ret : D [field trivialPropField] : Object | semmle.label | [post] access to local variable ret : D [field trivialPropField] : Object | +| D.cs:22:27:22:28 | access to parameter o2 : Object | semmle.label | access to parameter o2 : Object | | D.cs:22:27:22:28 | access to parameter o2 : Object | semmle.label | access to parameter o2 : Object | | D.cs:23:9:23:11 | [post] access to local variable ret : D [field trivialPropField] : Object | semmle.label | [post] access to local variable ret : D [field trivialPropField] : Object | +| D.cs:23:9:23:11 | [post] access to local variable ret : D [field trivialPropField] : Object | semmle.label | [post] access to local variable ret : D [field trivialPropField] : Object | +| D.cs:23:27:23:28 | access to parameter o3 : Object | semmle.label | access to parameter o3 : Object | | D.cs:23:27:23:28 | access to parameter o3 : Object | semmle.label | access to parameter o3 : Object | | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | semmle.label | access to local variable ret : D [field trivialPropField] : Object | | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | semmle.label | access to local variable ret : D [field trivialPropField] : Object | +| D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | semmle.label | access to local variable ret : D [field trivialPropField] : Object | +| D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | semmle.label | access to local variable ret : D [field trivialPropField] : Object | +| D.cs:24:16:24:18 | access to local variable ret : D [property AutoProp] : Object | semmle.label | access to local variable ret : D [property AutoProp] : Object | | D.cs:24:16:24:18 | access to local variable ret : D [property AutoProp] : Object | semmle.label | access to local variable ret : D [property AutoProp] : Object | | D.cs:29:17:29:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| D.cs:29:17:29:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| D.cs:31:17:31:37 | call to method Create : D [property AutoProp] : Object | semmle.label | call to method Create : D [property AutoProp] : Object | | D.cs:31:17:31:37 | call to method Create : D [property AutoProp] : Object | semmle.label | call to method Create : D [property AutoProp] : Object | | D.cs:31:24:31:24 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| D.cs:31:24:31:24 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| D.cs:32:14:32:14 | access to local variable d : D [property AutoProp] : Object | semmle.label | access to local variable d : D [property AutoProp] : Object | | D.cs:32:14:32:14 | access to local variable d : D [property AutoProp] : Object | semmle.label | access to local variable d : D [property AutoProp] : Object | | D.cs:32:14:32:23 | access to property AutoProp | semmle.label | access to property AutoProp | +| D.cs:32:14:32:23 | access to property AutoProp | semmle.label | access to property AutoProp | +| D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | semmle.label | call to method Create : D [field trivialPropField] : Object | | D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | semmle.label | call to method Create : D [field trivialPropField] : Object | | D.cs:37:26:37:42 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| D.cs:37:26:37:42 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:39:14:39:26 | access to property TrivialProp | semmle.label | access to property TrivialProp | +| D.cs:39:14:39:26 | access to property TrivialProp | semmle.label | access to property TrivialProp | +| D.cs:40:14:40:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:40:14:40:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:40:14:40:31 | access to field trivialPropField | semmle.label | access to field trivialPropField | +| D.cs:40:14:40:31 | access to field trivialPropField | semmle.label | access to field trivialPropField | +| D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:41:14:41:26 | access to property ComplexProp | semmle.label | access to property ComplexProp | +| D.cs:41:14:41:26 | access to property ComplexProp | semmle.label | access to property ComplexProp | +| D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | semmle.label | call to method Create : D [field trivialPropField] : Object | | D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | semmle.label | call to method Create : D [field trivialPropField] : Object | | D.cs:43:32:43:48 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| D.cs:43:32:43:48 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:45:14:45:26 | access to property TrivialProp | semmle.label | access to property TrivialProp | +| D.cs:45:14:45:26 | access to property TrivialProp | semmle.label | access to property TrivialProp | +| D.cs:46:14:46:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:46:14:46:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:46:14:46:31 | access to field trivialPropField | semmle.label | access to field trivialPropField | +| D.cs:46:14:46:31 | access to field trivialPropField | semmle.label | access to field trivialPropField | +| D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | semmle.label | access to local variable d : D [field trivialPropField] : Object | | D.cs:47:14:47:26 | access to property ComplexProp | semmle.label | access to property ComplexProp | +| D.cs:47:14:47:26 | access to property ComplexProp | semmle.label | access to property ComplexProp | +| E.cs:8:29:8:29 | o : Object | semmle.label | o : Object | | E.cs:8:29:8:29 | o : Object | semmle.label | o : Object | | E.cs:11:9:11:11 | [post] access to local variable ret : S [field Field] : Object | semmle.label | [post] access to local variable ret : S [field Field] : Object | +| E.cs:11:9:11:11 | [post] access to local variable ret : S [field Field] : Object | semmle.label | [post] access to local variable ret : S [field Field] : Object | +| E.cs:11:21:11:21 | access to parameter o : Object | semmle.label | access to parameter o : Object | | E.cs:11:21:11:21 | access to parameter o : Object | semmle.label | access to parameter o : Object | | E.cs:12:16:12:18 | access to local variable ret : S [field Field] : Object | semmle.label | access to local variable ret : S [field Field] : Object | +| E.cs:12:16:12:18 | access to local variable ret : S [field Field] : Object | semmle.label | access to local variable ret : S [field Field] : Object | +| E.cs:22:17:22:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | E.cs:22:17:22:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | E.cs:23:17:23:26 | call to method CreateS : S [field Field] : Object | semmle.label | call to method CreateS : S [field Field] : Object | +| E.cs:23:17:23:26 | call to method CreateS : S [field Field] : Object | semmle.label | call to method CreateS : S [field Field] : Object | +| E.cs:23:25:23:25 | access to local variable o : Object | semmle.label | access to local variable o : Object | | E.cs:23:25:23:25 | access to local variable o : Object | semmle.label | access to local variable o : Object | | E.cs:24:14:24:14 | access to local variable s : S [field Field] : Object | semmle.label | access to local variable s : S [field Field] : Object | +| E.cs:24:14:24:14 | access to local variable s : S [field Field] : Object | semmle.label | access to local variable s : S [field Field] : Object | +| E.cs:24:14:24:20 | access to field Field | semmle.label | access to field Field | | E.cs:24:14:24:20 | access to field Field | semmle.label | access to field Field | | F.cs:6:28:6:29 | o1 : Object | semmle.label | o1 : Object | +| F.cs:6:28:6:29 | o1 : Object | semmle.label | o1 : Object | +| F.cs:6:39:6:40 | o2 : Object | semmle.label | o2 : Object | | F.cs:6:39:6:40 | o2 : Object | semmle.label | o2 : Object | | F.cs:6:46:6:81 | object creation of type F : F [field Field1] : Object | semmle.label | object creation of type F : F [field Field1] : Object | +| F.cs:6:46:6:81 | object creation of type F : F [field Field1] : Object | semmle.label | object creation of type F : F [field Field1] : Object | +| F.cs:6:46:6:81 | object creation of type F : F [field Field2] : Object | semmle.label | object creation of type F : F [field Field2] : Object | | F.cs:6:46:6:81 | object creation of type F : F [field Field2] : Object | semmle.label | object creation of type F : F [field Field2] : Object | | F.cs:6:54:6:81 | { ..., ... } : F [field Field1] : Object | semmle.label | { ..., ... } : F [field Field1] : Object | +| F.cs:6:54:6:81 | { ..., ... } : F [field Field1] : Object | semmle.label | { ..., ... } : F [field Field1] : Object | +| F.cs:6:54:6:81 | { ..., ... } : F [field Field2] : Object | semmle.label | { ..., ... } : F [field Field2] : Object | | F.cs:6:54:6:81 | { ..., ... } : F [field Field2] : Object | semmle.label | { ..., ... } : F [field Field2] : Object | | F.cs:6:65:6:66 | access to parameter o1 : Object | semmle.label | access to parameter o1 : Object | +| F.cs:6:65:6:66 | access to parameter o1 : Object | semmle.label | access to parameter o1 : Object | +| F.cs:6:78:6:79 | access to parameter o2 : Object | semmle.label | access to parameter o2 : Object | | F.cs:6:78:6:79 | access to parameter o2 : Object | semmle.label | access to parameter o2 : Object | | F.cs:10:17:10:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| F.cs:10:17:10:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| F.cs:11:17:11:31 | call to method Create : F [field Field1] : Object | semmle.label | call to method Create : F [field Field1] : Object | | F.cs:11:17:11:31 | call to method Create : F [field Field1] : Object | semmle.label | call to method Create : F [field Field1] : Object | | F.cs:11:24:11:24 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| F.cs:11:24:11:24 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| F.cs:12:14:12:14 | access to local variable f : F [field Field1] : Object | semmle.label | access to local variable f : F [field Field1] : Object | | F.cs:12:14:12:14 | access to local variable f : F [field Field1] : Object | semmle.label | access to local variable f : F [field Field1] : Object | | F.cs:12:14:12:21 | access to field Field1 | semmle.label | access to field Field1 | +| F.cs:12:14:12:21 | access to field Field1 | semmle.label | access to field Field1 | +| F.cs:15:13:15:43 | call to method Create : F [field Field2] : Object | semmle.label | call to method Create : F [field Field2] : Object | | F.cs:15:13:15:43 | call to method Create : F [field Field2] : Object | semmle.label | call to method Create : F [field Field2] : Object | | F.cs:15:26:15:42 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| F.cs:15:26:15:42 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| F.cs:17:14:17:14 | access to local variable f : F [field Field2] : Object | semmle.label | access to local variable f : F [field Field2] : Object | | F.cs:17:14:17:14 | access to local variable f : F [field Field2] : Object | semmle.label | access to local variable f : F [field Field2] : Object | | F.cs:17:14:17:21 | access to field Field2 | semmle.label | access to field Field2 | +| F.cs:17:14:17:21 | access to field Field2 | semmle.label | access to field Field2 | +| F.cs:19:21:19:50 | { ..., ... } : F [field Field1] : Object | semmle.label | { ..., ... } : F [field Field1] : Object | | F.cs:19:21:19:50 | { ..., ... } : F [field Field1] : Object | semmle.label | { ..., ... } : F [field Field1] : Object | | F.cs:19:32:19:48 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| F.cs:19:32:19:48 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| F.cs:20:14:20:14 | access to local variable f : F [field Field1] : Object | semmle.label | access to local variable f : F [field Field1] : Object | | F.cs:20:14:20:14 | access to local variable f : F [field Field1] : Object | semmle.label | access to local variable f : F [field Field1] : Object | | F.cs:20:14:20:21 | access to field Field1 | semmle.label | access to field Field1 | +| F.cs:20:14:20:21 | access to field Field1 | semmle.label | access to field Field1 | +| F.cs:23:21:23:50 | { ..., ... } : F [field Field2] : Object | semmle.label | { ..., ... } : F [field Field2] : Object | | F.cs:23:21:23:50 | { ..., ... } : F [field Field2] : Object | semmle.label | { ..., ... } : F [field Field2] : Object | | F.cs:23:32:23:48 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| F.cs:23:32:23:48 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| F.cs:25:14:25:14 | access to local variable f : F [field Field2] : Object | semmle.label | access to local variable f : F [field Field2] : Object | | F.cs:25:14:25:14 | access to local variable f : F [field Field2] : Object | semmle.label | access to local variable f : F [field Field2] : Object | | F.cs:25:14:25:21 | access to field Field2 | semmle.label | access to field Field2 | +| F.cs:25:14:25:21 | access to field Field2 | semmle.label | access to field Field2 | +| F.cs:30:17:30:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | F.cs:30:17:30:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | F.cs:32:17:32:40 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | +| F.cs:32:17:32:40 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | +| F.cs:32:27:32:27 | access to local variable o : Object | semmle.label | access to local variable o : Object | | F.cs:32:27:32:27 | access to local variable o : Object | semmle.label | access to local variable o : Object | | F.cs:33:14:33:14 | access to local variable a : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | access to local variable a : <>__AnonType0<Object,Object> [property X] : Object | +| F.cs:33:14:33:14 | access to local variable a : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | access to local variable a : <>__AnonType0<Object,Object> [property X] : Object | +| F.cs:33:14:33:16 | access to property X | semmle.label | access to property X | | F.cs:33:14:33:16 | access to property X | semmle.label | access to property X | | G.cs:7:18:7:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| G.cs:7:18:7:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| G.cs:9:9:9:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:9:9:9:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:9:9:9:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:9:9:9:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:9:23:9:23 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | | G.cs:9:23:9:23 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | | G.cs:10:18:10:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:10:18:10:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:15:18:15:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | G.cs:15:18:15:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | G.cs:17:9:17:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:17:9:17:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:17:9:17:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 : Box1 [field Elem] : Elem | | G.cs:17:9:17:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 : Box1 [field Elem] : Elem | | G.cs:17:24:17:24 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | +| G.cs:17:24:17:24 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | +| G.cs:18:18:18:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:18:18:18:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:23:18:23:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| G.cs:23:18:23:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| G.cs:25:9:25:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:25:9:25:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:25:9:25:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | semmle.label | [post] call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:25:9:25:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | semmle.label | [post] call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:25:28:25:28 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | | G.cs:25:28:25:28 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | | G.cs:26:18:26:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:26:18:26:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:31:18:31:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | G.cs:31:18:31:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | | G.cs:33:9:33:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:33:9:33:9 | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b : Box2 [field Box1, field Elem] : Elem | +| G.cs:33:9:33:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | semmle.label | [post] call to method GetBox1 : Box1 [field Elem] : Elem | | G.cs:33:9:33:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | semmle.label | [post] call to method GetBox1 : Box1 [field Elem] : Elem | | G.cs:33:29:33:29 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | +| G.cs:33:29:33:29 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | +| G.cs:34:18:34:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:34:18:34:18 | access to local variable b : Box2 [field Box1, field Elem] : Elem | semmle.label | access to local variable b : Box2 [field Box1, field Elem] : Elem | | G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | semmle.label | b2 : Box2 [field Box1, field Elem] : Elem | +| G.cs:37:38:37:39 | b2 : Box2 [field Box1, field Elem] : Elem | semmle.label | b2 : Box2 [field Box1, field Elem] : Elem | +| G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | semmle.label | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | | G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | semmle.label | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | | G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | semmle.label | call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | semmle.label | call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:39:14:39:35 | call to method GetElem | semmle.label | call to method GetElem | | G.cs:39:14:39:35 | call to method GetElem | semmle.label | call to method GetElem | | G.cs:44:18:44:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| G.cs:44:18:44:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem | +| G.cs:46:9:46:16 | [post] access to field boxfield : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to field boxfield : Box2 [field Box1, field Elem] : Elem | | G.cs:46:9:46:16 | [post] access to field boxfield : Box2 [field Box1, field Elem] : Elem | semmle.label | [post] access to field boxfield : Box2 [field Box1, field Elem] : Elem | | G.cs:46:9:46:16 | [post] this access : G [field boxfield, field Box1, field Elem] : Elem | semmle.label | [post] this access : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:46:9:46:16 | [post] this access : G [field boxfield, field Box1, field Elem] : Elem | semmle.label | [post] this access : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:46:9:46:21 | [post] access to field Box1 : Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 : Box1 [field Elem] : Elem | | G.cs:46:9:46:21 | [post] access to field Box1 : Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 : Box1 [field Elem] : Elem | | G.cs:46:30:46:30 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | +| G.cs:46:30:46:30 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | +| G.cs:47:9:47:13 | this access : G [field boxfield, field Box1, field Elem] : Elem | semmle.label | this access : G [field boxfield, field Box1, field Elem] : Elem | | G.cs:47:9:47:13 | this access : G [field boxfield, field Box1, field Elem] : Elem | semmle.label | this access : G [field boxfield, field Box1, field Elem] : Elem | | G.cs:50:18:50:20 | this : G [field boxfield, field Box1, field Elem] : Elem | semmle.label | this : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:50:18:50:20 | this : G [field boxfield, field Box1, field Elem] : Elem | semmle.label | this : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:52:14:52:21 | access to field boxfield : Box2 [field Box1, field Elem] : Elem | semmle.label | access to field boxfield : Box2 [field Box1, field Elem] : Elem | | G.cs:52:14:52:21 | access to field boxfield : Box2 [field Box1, field Elem] : Elem | semmle.label | access to field boxfield : Box2 [field Box1, field Elem] : Elem | | G.cs:52:14:52:21 | this access : G [field boxfield, field Box1, field Elem] : Elem | semmle.label | this access : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:52:14:52:21 | this access : G [field boxfield, field Box1, field Elem] : Elem | semmle.label | this access : G [field boxfield, field Box1, field Elem] : Elem | +| G.cs:52:14:52:26 | access to field Box1 : Box1 [field Elem] : Elem | semmle.label | access to field Box1 : Box1 [field Elem] : Elem | | G.cs:52:14:52:26 | access to field Box1 : Box1 [field Elem] : Elem | semmle.label | access to field Box1 : Box1 [field Elem] : Elem | | G.cs:52:14:52:31 | access to field Elem | semmle.label | access to field Elem | +| G.cs:52:14:52:31 | access to field Elem | semmle.label | access to field Elem | +| G.cs:63:21:63:27 | this : Box1 [field Elem] : Elem | semmle.label | this : Box1 [field Elem] : Elem | | G.cs:63:21:63:27 | this : Box1 [field Elem] : Elem | semmle.label | this : Box1 [field Elem] : Elem | | G.cs:63:34:63:37 | access to field Elem : Elem | semmle.label | access to field Elem : Elem | +| G.cs:63:34:63:37 | access to field Elem : Elem | semmle.label | access to field Elem : Elem | +| G.cs:63:34:63:37 | this access : Box1 [field Elem] : Elem | semmle.label | this access : Box1 [field Elem] : Elem | | G.cs:63:34:63:37 | this access : Box1 [field Elem] : Elem | semmle.label | this access : Box1 [field Elem] : Elem | | G.cs:64:34:64:34 | e : Elem | semmle.label | e : Elem | +| G.cs:64:34:64:34 | e : Elem | semmle.label | e : Elem | +| G.cs:64:39:64:42 | [post] this access : Box1 [field Elem] : Elem | semmle.label | [post] this access : Box1 [field Elem] : Elem | | G.cs:64:39:64:42 | [post] this access : Box1 [field Elem] : Elem | semmle.label | [post] this access : Box1 [field Elem] : Elem | | G.cs:64:46:64:46 | access to parameter e : Elem | semmle.label | access to parameter e : Elem | +| G.cs:64:46:64:46 | access to parameter e : Elem | semmle.label | access to parameter e : Elem | +| G.cs:71:21:71:27 | this : Box2 [field Box1, field Elem] : Elem | semmle.label | this : Box2 [field Box1, field Elem] : Elem | | G.cs:71:21:71:27 | this : Box2 [field Box1, field Elem] : Elem | semmle.label | this : Box2 [field Box1, field Elem] : Elem | | G.cs:71:34:71:37 | access to field Box1 : Box1 [field Elem] : Elem | semmle.label | access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:71:34:71:37 | access to field Box1 : Box1 [field Elem] : Elem | semmle.label | access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:71:34:71:37 | this access : Box2 [field Box1, field Elem] : Elem | semmle.label | this access : Box2 [field Box1, field Elem] : Elem | | G.cs:71:34:71:37 | this access : Box2 [field Box1, field Elem] : Elem | semmle.label | this access : Box2 [field Box1, field Elem] : Elem | | H.cs:13:15:13:15 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | +| H.cs:13:15:13:15 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | +| H.cs:16:9:16:11 | [post] access to local variable ret : A [field FieldA] : Object | semmle.label | [post] access to local variable ret : A [field FieldA] : Object | | H.cs:16:9:16:11 | [post] access to local variable ret : A [field FieldA] : Object | semmle.label | [post] access to local variable ret : A [field FieldA] : Object | | H.cs:16:22:16:22 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | +| H.cs:16:22:16:22 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | +| H.cs:16:22:16:29 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | | H.cs:16:22:16:29 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | | H.cs:17:16:17:18 | access to local variable ret : A [field FieldA] : Object | semmle.label | access to local variable ret : A [field FieldA] : Object | +| H.cs:17:16:17:18 | access to local variable ret : A [field FieldA] : Object | semmle.label | access to local variable ret : A [field FieldA] : Object | +| H.cs:23:9:23:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | | H.cs:23:9:23:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | | H.cs:23:20:23:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| H.cs:23:20:23:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| H.cs:24:21:24:28 | call to method Clone : A [field FieldA] : Object | semmle.label | call to method Clone : A [field FieldA] : Object | | H.cs:24:21:24:28 | call to method Clone : A [field FieldA] : Object | semmle.label | call to method Clone : A [field FieldA] : Object | | H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | +| H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | +| H.cs:25:14:25:18 | access to local variable clone : A [field FieldA] : Object | semmle.label | access to local variable clone : A [field FieldA] : Object | | H.cs:25:14:25:18 | access to local variable clone : A [field FieldA] : Object | semmle.label | access to local variable clone : A [field FieldA] : Object | | H.cs:25:14:25:25 | access to field FieldA | semmle.label | access to field FieldA | +| H.cs:25:14:25:25 | access to field FieldA | semmle.label | access to field FieldA | +| H.cs:33:19:33:19 | a : A [field FieldA] : A | semmle.label | a : A [field FieldA] : A | | H.cs:33:19:33:19 | a : A [field FieldA] : A | semmle.label | a : A [field FieldA] : A | | H.cs:33:19:33:19 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | +| H.cs:33:19:33:19 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | +| H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : A | semmle.label | [post] access to local variable b : B [field FieldB] : A | | H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : A | semmle.label | [post] access to local variable b : B [field FieldB] : A | | H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : Object | semmle.label | [post] access to local variable b : B [field FieldB] : Object | +| H.cs:36:9:36:9 | [post] access to local variable b : B [field FieldB] : Object | semmle.label | [post] access to local variable b : B [field FieldB] : Object | +| H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : A | semmle.label | access to parameter a : A [field FieldA] : A | | H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : A | semmle.label | access to parameter a : A [field FieldA] : A | | H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | +| H.cs:36:20:36:20 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | +| H.cs:36:20:36:27 | access to field FieldA : A | semmle.label | access to field FieldA : A | | H.cs:36:20:36:27 | access to field FieldA : A | semmle.label | access to field FieldA : A | | H.cs:36:20:36:27 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | +| H.cs:36:20:36:27 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | +| H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : A | semmle.label | access to local variable b : B [field FieldB] : A | | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : A | semmle.label | access to local variable b : B [field FieldB] : A | | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | +| H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | +| H.cs:43:9:43:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | | H.cs:43:9:43:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | | H.cs:43:20:43:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| H.cs:43:20:43:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| H.cs:44:17:44:28 | call to method Transform : B [field FieldB] : Object | semmle.label | call to method Transform : B [field FieldB] : Object | | H.cs:44:17:44:28 | call to method Transform : B [field FieldB] : Object | semmle.label | call to method Transform : B [field FieldB] : Object | | H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | +| H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | +| H.cs:45:14:45:14 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | | H.cs:45:14:45:14 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | | H.cs:45:14:45:21 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:45:14:45:21 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:53:25:53:25 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | | H.cs:53:25:53:25 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | | H.cs:55:9:55:10 | [post] access to parameter b1 : B [field FieldB] : Object | semmle.label | [post] access to parameter b1 : B [field FieldB] : Object | +| H.cs:55:9:55:10 | [post] access to parameter b1 : B [field FieldB] : Object | semmle.label | [post] access to parameter b1 : B [field FieldB] : Object | +| H.cs:55:21:55:21 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | | H.cs:55:21:55:21 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | | H.cs:55:21:55:28 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | +| H.cs:55:21:55:28 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | +| H.cs:63:9:63:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | | H.cs:63:9:63:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | | H.cs:63:20:63:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| H.cs:63:20:63:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | | H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | | H.cs:64:25:64:26 | [post] access to local variable b1 : B [field FieldB] : Object | semmle.label | [post] access to local variable b1 : B [field FieldB] : Object | +| H.cs:64:25:64:26 | [post] access to local variable b1 : B [field FieldB] : Object | semmle.label | [post] access to local variable b1 : B [field FieldB] : Object | +| H.cs:65:14:65:15 | access to local variable b1 : B [field FieldB] : Object | semmle.label | access to local variable b1 : B [field FieldB] : Object | | H.cs:65:14:65:15 | access to local variable b1 : B [field FieldB] : Object | semmle.label | access to local variable b1 : B [field FieldB] : Object | | H.cs:65:14:65:22 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:65:14:65:22 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:77:30:77:30 | o : Object | semmle.label | o : Object | | H.cs:77:30:77:30 | o : Object | semmle.label | o : Object | | H.cs:79:9:79:9 | [post] access to parameter a : A [field FieldA] : Object | semmle.label | [post] access to parameter a : A [field FieldA] : Object | +| H.cs:79:9:79:9 | [post] access to parameter a : A [field FieldA] : Object | semmle.label | [post] access to parameter a : A [field FieldA] : Object | +| H.cs:79:20:79:20 | access to parameter o : Object | semmle.label | access to parameter o : Object | | H.cs:79:20:79:20 | access to parameter o : Object | semmle.label | access to parameter o : Object | | H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | +| H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | +| H.cs:80:25:80:26 | [post] access to parameter b1 : B [field FieldB] : Object | semmle.label | [post] access to parameter b1 : B [field FieldB] : Object | | H.cs:80:25:80:26 | [post] access to parameter b1 : B [field FieldB] : Object | semmle.label | [post] access to parameter b1 : B [field FieldB] : Object | | H.cs:88:17:88:17 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:88:17:88:17 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:88:20:88:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | H.cs:88:20:88:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | H.cs:88:39:88:40 | [post] access to local variable b1 : B [field FieldB] : Object | semmle.label | [post] access to local variable b1 : B [field FieldB] : Object | +| H.cs:88:39:88:40 | [post] access to local variable b1 : B [field FieldB] : Object | semmle.label | [post] access to local variable b1 : B [field FieldB] : Object | +| H.cs:89:14:89:14 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | | H.cs:89:14:89:14 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | | H.cs:89:14:89:21 | access to field FieldA | semmle.label | access to field FieldA | +| H.cs:89:14:89:21 | access to field FieldA | semmle.label | access to field FieldA | +| H.cs:90:14:90:15 | access to local variable b1 : B [field FieldB] : Object | semmle.label | access to local variable b1 : B [field FieldB] : Object | | H.cs:90:14:90:15 | access to local variable b1 : B [field FieldB] : Object | semmle.label | access to local variable b1 : B [field FieldB] : Object | | H.cs:90:14:90:22 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:90:14:90:22 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:102:23:102:23 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | | H.cs:102:23:102:23 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | | H.cs:105:9:105:12 | [post] access to local variable temp : B [field FieldB, field FieldA] : Object | semmle.label | [post] access to local variable temp : B [field FieldB, field FieldA] : Object | +| H.cs:105:9:105:12 | [post] access to local variable temp : B [field FieldB, field FieldA] : Object | semmle.label | [post] access to local variable temp : B [field FieldB, field FieldA] : Object | +| H.cs:105:23:105:23 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | | H.cs:105:23:105:23 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | | H.cs:106:16:106:40 | call to method Transform : B [field FieldB] : Object | semmle.label | call to method Transform : B [field FieldB] : Object | +| H.cs:106:16:106:40 | call to method Transform : B [field FieldB] : Object | semmle.label | call to method Transform : B [field FieldB] : Object | +| H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | semmle.label | (...) ... : A [field FieldA] : Object | | H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | semmle.label | (...) ... : A [field FieldA] : Object | | H.cs:106:29:106:32 | access to local variable temp : B [field FieldB, field FieldA] : Object | semmle.label | access to local variable temp : B [field FieldB, field FieldA] : Object | +| H.cs:106:29:106:32 | access to local variable temp : B [field FieldB, field FieldA] : Object | semmle.label | access to local variable temp : B [field FieldB, field FieldA] : Object | +| H.cs:106:29:106:39 | access to field FieldB : A [field FieldA] : Object | semmle.label | access to field FieldB : A [field FieldA] : Object | | H.cs:106:29:106:39 | access to field FieldB : A [field FieldA] : Object | semmle.label | access to field FieldB : A [field FieldA] : Object | | H.cs:112:9:112:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:112:9:112:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:112:20:112:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | H.cs:112:20:112:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | H.cs:113:17:113:32 | call to method TransformWrap : B [field FieldB] : Object | semmle.label | call to method TransformWrap : B [field FieldB] : Object | +| H.cs:113:17:113:32 | call to method TransformWrap : B [field FieldB] : Object | semmle.label | call to method TransformWrap : B [field FieldB] : Object | +| H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | | H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | | H.cs:114:14:114:14 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | +| H.cs:114:14:114:14 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | +| H.cs:114:14:114:21 | access to field FieldB | semmle.label | access to field FieldB | | H.cs:114:14:114:21 | access to field FieldB | semmle.label | access to field FieldB | | H.cs:122:18:122:18 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | +| H.cs:122:18:122:18 | a : A [field FieldA] : Object | semmle.label | a : A [field FieldA] : Object | +| H.cs:124:16:124:27 | call to method Transform : B [field FieldB] : Object | semmle.label | call to method Transform : B [field FieldB] : Object | | H.cs:124:16:124:27 | call to method Transform : B [field FieldB] : Object | semmle.label | call to method Transform : B [field FieldB] : Object | | H.cs:124:16:124:34 | access to field FieldB : Object | semmle.label | access to field FieldB : Object | +| H.cs:124:16:124:34 | access to field FieldB : Object | semmle.label | access to field FieldB : Object | +| H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | | H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | semmle.label | access to parameter a : A [field FieldA] : Object | | H.cs:130:9:130:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:130:9:130:9 | [post] access to local variable a : A [field FieldA] : Object | semmle.label | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:130:20:130:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | H.cs:130:20:130:36 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | H.cs:131:14:131:19 | call to method Get | semmle.label | call to method Get | +| H.cs:131:14:131:19 | call to method Get | semmle.label | call to method Get | +| H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | | H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | semmle.label | access to local variable a : A [field FieldA] : Object | | H.cs:138:27:138:27 | o : A | semmle.label | o : A | +| H.cs:138:27:138:27 | o : A | semmle.label | o : A | +| H.cs:141:9:141:9 | [post] access to local variable a : A [field FieldA] : A | semmle.label | [post] access to local variable a : A [field FieldA] : A | | H.cs:141:9:141:9 | [post] access to local variable a : A [field FieldA] : A | semmle.label | [post] access to local variable a : A [field FieldA] : A | | H.cs:141:20:141:25 | ... as ... : A | semmle.label | ... as ... : A | +| H.cs:141:20:141:25 | ... as ... : A | semmle.label | ... as ... : A | +| H.cs:142:16:142:27 | call to method Transform : B [field FieldB] : A | semmle.label | call to method Transform : B [field FieldB] : A | | H.cs:142:16:142:27 | call to method Transform : B [field FieldB] : A | semmle.label | call to method Transform : B [field FieldB] : A | | H.cs:142:16:142:34 | access to field FieldB : A | semmle.label | access to field FieldB : A | +| H.cs:142:16:142:34 | access to field FieldB : A | semmle.label | access to field FieldB : A | +| H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | semmle.label | access to local variable a : A [field FieldA] : A | | H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | semmle.label | access to local variable a : A [field FieldA] : A | | H.cs:147:17:147:39 | call to method Through : A | semmle.label | call to method Through : A | +| H.cs:147:17:147:39 | call to method Through : A | semmle.label | call to method Through : A | +| H.cs:147:25:147:38 | call to method Source<A> : A | semmle.label | call to method Source<A> : A | | H.cs:147:25:147:38 | call to method Source<A> : A | semmle.label | call to method Source<A> : A | | H.cs:148:14:148:14 | access to local variable a | semmle.label | access to local variable a | +| H.cs:148:14:148:14 | access to local variable a | semmle.label | access to local variable a | +| H.cs:153:32:153:32 | o : Object | semmle.label | o : Object | | H.cs:153:32:153:32 | o : Object | semmle.label | o : Object | | H.cs:155:17:155:30 | call to method Source<B> : B | semmle.label | call to method Source<B> : B | +| H.cs:155:17:155:30 | call to method Source<B> : B | semmle.label | call to method Source<B> : B | +| H.cs:156:9:156:9 | [post] access to local variable b : B [field FieldB] : Object | semmle.label | [post] access to local variable b : B [field FieldB] : Object | | H.cs:156:9:156:9 | [post] access to local variable b : B [field FieldB] : Object | semmle.label | [post] access to local variable b : B [field FieldB] : Object | | H.cs:156:9:156:9 | access to local variable b : B | semmle.label | access to local variable b : B | +| H.cs:156:9:156:9 | access to local variable b : B | semmle.label | access to local variable b : B | +| H.cs:156:20:156:20 | access to parameter o : Object | semmle.label | access to parameter o : Object | | H.cs:156:20:156:20 | access to parameter o : Object | semmle.label | access to parameter o : Object | | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA, field FieldB] : Object | semmle.label | [post] access to parameter a : A [field FieldA, field FieldB] : Object | +| H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA, field FieldB] : Object | semmle.label | [post] access to parameter a : A [field FieldA, field FieldB] : Object | +| H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA] : B | semmle.label | [post] access to parameter a : A [field FieldA] : B | | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA] : B | semmle.label | [post] access to parameter a : A [field FieldA] : B | | H.cs:157:20:157:20 | access to local variable b : B | semmle.label | access to local variable b : B | +| H.cs:157:20:157:20 | access to local variable b : B | semmle.label | access to local variable b : B | +| H.cs:157:20:157:20 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | | H.cs:157:20:157:20 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | | H.cs:163:17:163:35 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| H.cs:163:17:163:35 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA, field FieldB] : Object | semmle.label | [post] access to local variable a : A [field FieldA, field FieldB] : Object | | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA, field FieldB] : Object | semmle.label | [post] access to local variable a : A [field FieldA, field FieldB] : Object | | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA] : B | semmle.label | [post] access to local variable a : A [field FieldA] : B | +| H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA] : B | semmle.label | [post] access to local variable a : A [field FieldA] : B | +| H.cs:164:22:164:22 | access to local variable o : Object | semmle.label | access to local variable o : Object | | H.cs:164:22:164:22 | access to local variable o : Object | semmle.label | access to local variable o : Object | | H.cs:165:17:165:27 | (...) ... : B | semmle.label | (...) ... : B | +| H.cs:165:17:165:27 | (...) ... : B | semmle.label | (...) ... : B | +| H.cs:165:17:165:27 | (...) ... : B [field FieldB] : Object | semmle.label | (...) ... : B [field FieldB] : Object | | H.cs:165:17:165:27 | (...) ... : B [field FieldB] : Object | semmle.label | (...) ... : B [field FieldB] : Object | | H.cs:165:20:165:20 | access to local variable a : A [field FieldA, field FieldB] : Object | semmle.label | access to local variable a : A [field FieldA, field FieldB] : Object | +| H.cs:165:20:165:20 | access to local variable a : A [field FieldA, field FieldB] : Object | semmle.label | access to local variable a : A [field FieldA, field FieldB] : Object | +| H.cs:165:20:165:20 | access to local variable a : A [field FieldA] : B | semmle.label | access to local variable a : A [field FieldA] : B | | H.cs:165:20:165:20 | access to local variable a : A [field FieldA] : B | semmle.label | access to local variable a : A [field FieldA] : B | | H.cs:165:20:165:27 | access to field FieldA : B | semmle.label | access to field FieldA : B | +| H.cs:165:20:165:27 | access to field FieldA : B | semmle.label | access to field FieldA : B | +| H.cs:165:20:165:27 | access to field FieldA : B [field FieldB] : Object | semmle.label | access to field FieldA : B [field FieldB] : Object | | H.cs:165:20:165:27 | access to field FieldA : B [field FieldB] : Object | semmle.label | access to field FieldA : B [field FieldB] : Object | | H.cs:166:14:166:14 | access to local variable b | semmle.label | access to local variable b | +| H.cs:166:14:166:14 | access to local variable b | semmle.label | access to local variable b | +| H.cs:167:14:167:14 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | | H.cs:167:14:167:14 | access to local variable b : B [field FieldB] : Object | semmle.label | access to local variable b : B [field FieldB] : Object | | H.cs:167:14:167:21 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:167:14:167:21 | access to field FieldB | semmle.label | access to field FieldB | +| I.cs:7:9:7:14 | [post] this access : I [field Field1] : Object | semmle.label | [post] this access : I [field Field1] : Object | | I.cs:7:9:7:14 | [post] this access : I [field Field1] : Object | semmle.label | [post] this access : I [field Field1] : Object | | I.cs:7:18:7:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| I.cs:7:18:7:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| I.cs:13:17:13:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | I.cs:13:17:13:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | I.cs:15:9:15:9 | [post] access to local variable i : I [field Field1] : Object | semmle.label | [post] access to local variable i : I [field Field1] : Object | +| I.cs:15:9:15:9 | [post] access to local variable i : I [field Field1] : Object | semmle.label | [post] access to local variable i : I [field Field1] : Object | +| I.cs:15:20:15:20 | access to local variable o : Object | semmle.label | access to local variable o : Object | | I.cs:15:20:15:20 | access to local variable o : Object | semmle.label | access to local variable o : Object | | I.cs:16:9:16:9 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | +| I.cs:16:9:16:9 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | +| I.cs:17:9:17:9 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | | I.cs:17:9:17:9 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | | I.cs:18:14:18:14 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | +| I.cs:18:14:18:14 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | +| I.cs:18:14:18:21 | access to field Field1 | semmle.label | access to field Field1 | | I.cs:18:14:18:21 | access to field Field1 | semmle.label | access to field Field1 | | I.cs:21:13:21:19 | object creation of type I : I [field Field1] : Object | semmle.label | object creation of type I : I [field Field1] : Object | +| I.cs:21:13:21:19 | object creation of type I : I [field Field1] : Object | semmle.label | object creation of type I : I [field Field1] : Object | +| I.cs:22:9:22:9 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | | I.cs:22:9:22:9 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | | I.cs:23:14:23:14 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | +| I.cs:23:14:23:14 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | +| I.cs:23:14:23:21 | access to field Field1 | semmle.label | access to field Field1 | | I.cs:23:14:23:21 | access to field Field1 | semmle.label | access to field Field1 | | I.cs:26:13:26:37 | [pre-initializer] object creation of type I : I [field Field1] : Object | semmle.label | [pre-initializer] object creation of type I : I [field Field1] : Object | +| I.cs:26:13:26:37 | [pre-initializer] object creation of type I : I [field Field1] : Object | semmle.label | [pre-initializer] object creation of type I : I [field Field1] : Object | +| I.cs:27:14:27:14 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | | I.cs:27:14:27:14 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | | I.cs:27:14:27:21 | access to field Field1 | semmle.label | access to field Field1 | +| I.cs:27:14:27:21 | access to field Field1 | semmle.label | access to field Field1 | +| I.cs:31:13:31:29 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | I.cs:31:13:31:29 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | I.cs:32:9:32:9 | [post] access to local variable i : I [field Field1] : Object | semmle.label | [post] access to local variable i : I [field Field1] : Object | +| I.cs:32:9:32:9 | [post] access to local variable i : I [field Field1] : Object | semmle.label | [post] access to local variable i : I [field Field1] : Object | +| I.cs:32:20:32:20 | access to local variable o : Object | semmle.label | access to local variable o : Object | | I.cs:32:20:32:20 | access to local variable o : Object | semmle.label | access to local variable o : Object | | I.cs:33:9:33:9 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | +| I.cs:33:9:33:9 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | +| I.cs:34:12:34:12 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | | I.cs:34:12:34:12 | access to local variable i : I [field Field1] : Object | semmle.label | access to local variable i : I [field Field1] : Object | | I.cs:37:23:37:23 | i : I [field Field1] : Object | semmle.label | i : I [field Field1] : Object | +| I.cs:37:23:37:23 | i : I [field Field1] : Object | semmle.label | i : I [field Field1] : Object | +| I.cs:39:9:39:9 | access to parameter i : I [field Field1] : Object | semmle.label | access to parameter i : I [field Field1] : Object | | I.cs:39:9:39:9 | access to parameter i : I [field Field1] : Object | semmle.label | access to parameter i : I [field Field1] : Object | | I.cs:40:14:40:14 | access to parameter i : I [field Field1] : Object | semmle.label | access to parameter i : I [field Field1] : Object | +| I.cs:40:14:40:14 | access to parameter i : I [field Field1] : Object | semmle.label | access to parameter i : I [field Field1] : Object | +| I.cs:40:14:40:21 | access to field Field1 | semmle.label | access to field Field1 | | I.cs:40:14:40:21 | access to field Field1 | semmle.label | access to field Field1 | | J.cs:14:26:14:30 | field : Object | semmle.label | field : Object | +| J.cs:14:26:14:30 | field : Object | semmle.label | field : Object | +| J.cs:14:40:14:43 | prop : Object | semmle.label | prop : Object | | J.cs:14:40:14:43 | prop : Object | semmle.label | prop : Object | | J.cs:14:50:14:54 | [post] this access : Struct [field Field] : Object | semmle.label | [post] this access : Struct [field Field] : Object | +| J.cs:14:50:14:54 | [post] this access : Struct [field Field] : Object | semmle.label | [post] this access : Struct [field Field] : Object | +| J.cs:14:57:14:60 | [post] this access : Struct [property Prop] : Object | semmle.label | [post] this access : Struct [property Prop] : Object | | J.cs:14:57:14:60 | [post] this access : Struct [property Prop] : Object | semmle.label | [post] this access : Struct [property Prop] : Object | | J.cs:14:66:14:70 | access to parameter field : Object | semmle.label | access to parameter field : Object | +| J.cs:14:66:14:70 | access to parameter field : Object | semmle.label | access to parameter field : Object | +| J.cs:14:73:14:76 | access to parameter prop : Object | semmle.label | access to parameter prop : Object | | J.cs:14:73:14:76 | access to parameter prop : Object | semmle.label | access to parameter prop : Object | | J.cs:21:17:21:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:21:17:21:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | semmle.label | object creation of type RecordClass : RecordClass [property Prop1] : Object | | J.cs:22:18:22:41 | object creation of type RecordClass : RecordClass [property Prop1] : Object | semmle.label | object creation of type RecordClass : RecordClass [property Prop1] : Object | | J.cs:22:34:22:34 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| J.cs:22:34:22:34 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| J.cs:23:14:23:15 | access to local variable r1 : RecordClass [property Prop1] : Object | semmle.label | access to local variable r1 : RecordClass [property Prop1] : Object | | J.cs:23:14:23:15 | access to local variable r1 : RecordClass [property Prop1] : Object | semmle.label | access to local variable r1 : RecordClass [property Prop1] : Object | | J.cs:23:14:23:21 | access to property Prop1 | semmle.label | access to property Prop1 | +| J.cs:23:14:23:21 | access to property Prop1 | semmle.label | access to property Prop1 | +| J.cs:27:14:27:15 | access to local variable r2 : RecordClass [property Prop1] : Object | semmle.label | access to local variable r2 : RecordClass [property Prop1] : Object | | J.cs:27:14:27:15 | access to local variable r2 : RecordClass [property Prop1] : Object | semmle.label | access to local variable r2 : RecordClass [property Prop1] : Object | | J.cs:27:14:27:21 | access to property Prop1 | semmle.label | access to property Prop1 | +| J.cs:27:14:27:21 | access to property Prop1 | semmle.label | access to property Prop1 | +| J.cs:30:18:30:54 | ... with { ... } : RecordClass [property Prop2] : Object | semmle.label | ... with { ... } : RecordClass [property Prop2] : Object | | J.cs:30:18:30:54 | ... with { ... } : RecordClass [property Prop2] : Object | semmle.label | ... with { ... } : RecordClass [property Prop2] : Object | | J.cs:30:36:30:52 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:30:36:30:52 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:31:14:31:15 | access to local variable r3 : RecordClass [property Prop1] : Object | semmle.label | access to local variable r3 : RecordClass [property Prop1] : Object | | J.cs:31:14:31:15 | access to local variable r3 : RecordClass [property Prop1] : Object | semmle.label | access to local variable r3 : RecordClass [property Prop1] : Object | | J.cs:31:14:31:21 | access to property Prop1 | semmle.label | access to property Prop1 | +| J.cs:31:14:31:21 | access to property Prop1 | semmle.label | access to property Prop1 | +| J.cs:32:14:32:15 | access to local variable r3 : RecordClass [property Prop2] : Object | semmle.label | access to local variable r3 : RecordClass [property Prop2] : Object | | J.cs:32:14:32:15 | access to local variable r3 : RecordClass [property Prop2] : Object | semmle.label | access to local variable r3 : RecordClass [property Prop2] : Object | | J.cs:32:14:32:21 | access to property Prop2 | semmle.label | access to property Prop2 | +| J.cs:32:14:32:21 | access to property Prop2 | semmle.label | access to property Prop2 | +| J.cs:41:17:41:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | J.cs:41:17:41:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | semmle.label | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | +| J.cs:42:18:42:42 | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | semmle.label | object creation of type RecordStruct : RecordStruct [property Prop1] : Object | +| J.cs:42:35:42:35 | access to local variable o : Object | semmle.label | access to local variable o : Object | | J.cs:42:35:42:35 | access to local variable o : Object | semmle.label | access to local variable o : Object | | J.cs:43:14:43:15 | access to local variable r1 : RecordStruct [property Prop1] : Object | semmle.label | access to local variable r1 : RecordStruct [property Prop1] : Object | +| J.cs:43:14:43:15 | access to local variable r1 : RecordStruct [property Prop1] : Object | semmle.label | access to local variable r1 : RecordStruct [property Prop1] : Object | +| J.cs:43:14:43:21 | access to property Prop1 | semmle.label | access to property Prop1 | | J.cs:43:14:43:21 | access to property Prop1 | semmle.label | access to property Prop1 | | J.cs:47:14:47:15 | access to local variable r2 : RecordStruct [property Prop1] : Object | semmle.label | access to local variable r2 : RecordStruct [property Prop1] : Object | +| J.cs:47:14:47:15 | access to local variable r2 : RecordStruct [property Prop1] : Object | semmle.label | access to local variable r2 : RecordStruct [property Prop1] : Object | +| J.cs:47:14:47:21 | access to property Prop1 | semmle.label | access to property Prop1 | | J.cs:47:14:47:21 | access to property Prop1 | semmle.label | access to property Prop1 | | J.cs:50:18:50:54 | ... with { ... } : RecordStruct [property Prop2] : Object | semmle.label | ... with { ... } : RecordStruct [property Prop2] : Object | +| J.cs:50:18:50:54 | ... with { ... } : RecordStruct [property Prop2] : Object | semmle.label | ... with { ... } : RecordStruct [property Prop2] : Object | +| J.cs:50:36:50:52 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | J.cs:50:36:50:52 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | J.cs:51:14:51:15 | access to local variable r3 : RecordStruct [property Prop1] : Object | semmle.label | access to local variable r3 : RecordStruct [property Prop1] : Object | +| J.cs:51:14:51:15 | access to local variable r3 : RecordStruct [property Prop1] : Object | semmle.label | access to local variable r3 : RecordStruct [property Prop1] : Object | +| J.cs:51:14:51:21 | access to property Prop1 | semmle.label | access to property Prop1 | | J.cs:51:14:51:21 | access to property Prop1 | semmle.label | access to property Prop1 | | J.cs:52:14:52:15 | access to local variable r3 : RecordStruct [property Prop2] : Object | semmle.label | access to local variable r3 : RecordStruct [property Prop2] : Object | +| J.cs:52:14:52:15 | access to local variable r3 : RecordStruct [property Prop2] : Object | semmle.label | access to local variable r3 : RecordStruct [property Prop2] : Object | +| J.cs:52:14:52:21 | access to property Prop2 | semmle.label | access to property Prop2 | | J.cs:52:14:52:21 | access to property Prop2 | semmle.label | access to property Prop2 | | J.cs:61:17:61:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:61:17:61:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | semmle.label | object creation of type Struct : Struct [field Field] : Object | | J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | semmle.label | object creation of type Struct : Struct [field Field] : Object | | J.cs:62:29:62:29 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| J.cs:62:29:62:29 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| J.cs:65:14:65:15 | access to local variable s2 : Struct [field Field] : Object | semmle.label | access to local variable s2 : Struct [field Field] : Object | | J.cs:65:14:65:15 | access to local variable s2 : Struct [field Field] : Object | semmle.label | access to local variable s2 : Struct [field Field] : Object | | J.cs:65:14:65:21 | access to field Field | semmle.label | access to field Field | +| J.cs:65:14:65:21 | access to field Field | semmle.label | access to field Field | +| J.cs:68:18:68:53 | ... with { ... } : Struct [property Prop] : Object | semmle.label | ... with { ... } : Struct [property Prop] : Object | | J.cs:68:18:68:53 | ... with { ... } : Struct [property Prop] : Object | semmle.label | ... with { ... } : Struct [property Prop] : Object | | J.cs:68:35:68:51 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:68:35:68:51 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:69:14:69:15 | access to local variable s3 : Struct [field Field] : Object | semmle.label | access to local variable s3 : Struct [field Field] : Object | | J.cs:69:14:69:15 | access to local variable s3 : Struct [field Field] : Object | semmle.label | access to local variable s3 : Struct [field Field] : Object | | J.cs:69:14:69:21 | access to field Field | semmle.label | access to field Field | +| J.cs:69:14:69:21 | access to field Field | semmle.label | access to field Field | +| J.cs:70:14:70:15 | access to local variable s3 : Struct [property Prop] : Object | semmle.label | access to local variable s3 : Struct [property Prop] : Object | | J.cs:70:14:70:15 | access to local variable s3 : Struct [property Prop] : Object | semmle.label | access to local variable s3 : Struct [property Prop] : Object | | J.cs:70:14:70:20 | access to property Prop | semmle.label | access to property Prop | +| J.cs:70:14:70:20 | access to property Prop | semmle.label | access to property Prop | +| J.cs:79:17:79:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | J.cs:79:17:79:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | semmle.label | object creation of type Struct : Struct [property Prop] : Object | +| J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | semmle.label | object creation of type Struct : Struct [property Prop] : Object | +| J.cs:80:35:80:35 | access to local variable o : Object | semmle.label | access to local variable o : Object | | J.cs:80:35:80:35 | access to local variable o : Object | semmle.label | access to local variable o : Object | | J.cs:84:14:84:15 | access to local variable s2 : Struct [property Prop] : Object | semmle.label | access to local variable s2 : Struct [property Prop] : Object | +| J.cs:84:14:84:15 | access to local variable s2 : Struct [property Prop] : Object | semmle.label | access to local variable s2 : Struct [property Prop] : Object | +| J.cs:84:14:84:20 | access to property Prop | semmle.label | access to property Prop | | J.cs:84:14:84:20 | access to property Prop | semmle.label | access to property Prop | | J.cs:86:18:86:54 | ... with { ... } : Struct [field Field] : Object | semmle.label | ... with { ... } : Struct [field Field] : Object | +| J.cs:86:18:86:54 | ... with { ... } : Struct [field Field] : Object | semmle.label | ... with { ... } : Struct [field Field] : Object | +| J.cs:86:36:86:52 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | J.cs:86:36:86:52 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | J.cs:87:14:87:15 | access to local variable s3 : Struct [field Field] : Object | semmle.label | access to local variable s3 : Struct [field Field] : Object | +| J.cs:87:14:87:15 | access to local variable s3 : Struct [field Field] : Object | semmle.label | access to local variable s3 : Struct [field Field] : Object | +| J.cs:87:14:87:21 | access to field Field | semmle.label | access to field Field | | J.cs:87:14:87:21 | access to field Field | semmle.label | access to field Field | | J.cs:88:14:88:15 | access to local variable s3 : Struct [property Prop] : Object | semmle.label | access to local variable s3 : Struct [property Prop] : Object | +| J.cs:88:14:88:15 | access to local variable s3 : Struct [property Prop] : Object | semmle.label | access to local variable s3 : Struct [property Prop] : Object | +| J.cs:88:14:88:20 | access to property Prop | semmle.label | access to property Prop | | J.cs:88:14:88:20 | access to property Prop | semmle.label | access to property Prop | | J.cs:97:17:97:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:97:17:97:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:99:18:99:41 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | | J.cs:99:18:99:41 | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | { ..., ... } : <>__AnonType0<Object,Object> [property X] : Object | | J.cs:99:28:99:28 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| J.cs:99:28:99:28 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| J.cs:102:14:102:15 | access to local variable a2 : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | access to local variable a2 : <>__AnonType0<Object,Object> [property X] : Object | | J.cs:102:14:102:15 | access to local variable a2 : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | access to local variable a2 : <>__AnonType0<Object,Object> [property X] : Object | | J.cs:102:14:102:17 | access to property X | semmle.label | access to property X | +| J.cs:102:14:102:17 | access to property X | semmle.label | access to property X | +| J.cs:105:18:105:50 | ... with { ... } : <>__AnonType0<Object,Object> [property Y] : Object | semmle.label | ... with { ... } : <>__AnonType0<Object,Object> [property Y] : Object | | J.cs:105:18:105:50 | ... with { ... } : <>__AnonType0<Object,Object> [property Y] : Object | semmle.label | ... with { ... } : <>__AnonType0<Object,Object> [property Y] : Object | | J.cs:105:32:105:48 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:105:32:105:48 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| J.cs:106:14:106:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | access to local variable a3 : <>__AnonType0<Object,Object> [property X] : Object | | J.cs:106:14:106:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property X] : Object | semmle.label | access to local variable a3 : <>__AnonType0<Object,Object> [property X] : Object | | J.cs:106:14:106:17 | access to property X | semmle.label | access to property X | +| J.cs:106:14:106:17 | access to property X | semmle.label | access to property X | +| J.cs:107:14:107:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property Y] : Object | semmle.label | access to local variable a3 : <>__AnonType0<Object,Object> [property Y] : Object | | J.cs:107:14:107:15 | access to local variable a3 : <>__AnonType0<Object,Object> [property Y] : Object | semmle.label | access to local variable a3 : <>__AnonType0<Object,Object> [property Y] : Object | | J.cs:107:14:107:17 | access to property Y | semmle.label | access to property Y | +| J.cs:107:14:107:17 | access to property Y | semmle.label | access to property Y | +| J.cs:119:13:119:13 | [post] access to local variable a : Int32[] [element] : Int32 | semmle.label | [post] access to local variable a : Int32[] [element] : Int32 | | J.cs:119:13:119:13 | [post] access to local variable a : Int32[] [element] : Int32 | semmle.label | [post] access to local variable a : Int32[] [element] : Int32 | | J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | semmle.label | call to method Source<Int32> : Int32 | +| J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | semmle.label | call to method Source<Int32> : Int32 | +| J.cs:125:14:125:14 | access to local variable a : Int32[] [element] : Int32 | semmle.label | access to local variable a : Int32[] [element] : Int32 | | J.cs:125:14:125:14 | access to local variable a : Int32[] [element] : Int32 | semmle.label | access to local variable a : Int32[] [element] : Int32 | | J.cs:125:14:125:17 | (...) ... | semmle.label | (...) ... | +| J.cs:125:14:125:17 | (...) ... | semmle.label | (...) ... | +| J.cs:125:14:125:17 | access to array element : Int32 | semmle.label | access to array element : Int32 | | J.cs:125:14:125:17 | access to array element : Int32 | semmle.label | access to array element : Int32 | subpaths | A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | A.cs:6:17:6:25 | call to method Make : B [field c] : C | +| A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | A.cs:6:17:6:25 | call to method Make : B [field c] : C | +| A.cs:13:15:13:29 | call to method Source<C1> : C1 | A.cs:145:27:145:27 | c : C1 | A.cs:145:32:145:35 | [post] this access : B [field c] : C1 | A.cs:13:9:13:9 | [post] access to local variable b : B [field c] : C1 | | A.cs:13:15:13:29 | call to method Source<C1> : C1 | A.cs:145:27:145:27 | c : C1 | A.cs:145:32:145:35 | [post] this access : B [field c] : C1 | A.cs:13:9:13:9 | [post] access to local variable b : B [field c] : C1 | | A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | A.cs:146:18:146:20 | this : B [field c] : C1 | A.cs:146:33:146:38 | access to field c : C1 | A.cs:14:14:14:20 | call to method Get | +| A.cs:14:14:14:14 | access to local variable b : B [field c] : C1 | A.cs:146:18:146:20 | this : B [field c] : C1 | A.cs:146:33:146:38 | access to field c : C1 | A.cs:14:14:14:20 | call to method Get | +| A.cs:15:15:15:35 | object creation of type B : B [field c] : C | A.cs:146:18:146:20 | this : B [field c] : C | A.cs:146:33:146:38 | access to field c : C | A.cs:15:14:15:42 | call to method Get | | A.cs:15:15:15:35 | object creation of type B : B [field c] : C | A.cs:146:18:146:20 | this : B [field c] : C | A.cs:146:33:146:38 | access to field c : C | A.cs:15:14:15:42 | call to method Get | | A.cs:15:21:15:34 | call to method Source<C> : C | A.cs:141:20:141:20 | c : C | A.cs:143:13:143:16 | [post] this access : B [field c] : C | A.cs:15:15:15:35 | object creation of type B : B [field c] : C | +| A.cs:15:21:15:34 | call to method Source<C> : C | A.cs:141:20:141:20 | c : C | A.cs:143:13:143:16 | [post] this access : B [field c] : C | A.cs:15:15:15:35 | object creation of type B : B [field c] : C | +| A.cs:22:25:22:37 | call to method Source<C2> : C2 | A.cs:42:29:42:29 | c : C2 | A.cs:48:20:48:21 | access to local variable b2 : B [field c] : C2 | A.cs:22:14:22:38 | call to method SetOnB : B [field c] : C2 | | A.cs:22:25:22:37 | call to method Source<C2> : C2 | A.cs:42:29:42:29 | c : C2 | A.cs:48:20:48:21 | access to local variable b2 : B [field c] : C2 | A.cs:22:14:22:38 | call to method SetOnB : B [field c] : C2 | | A.cs:31:29:31:41 | call to method Source<C2> : C2 | A.cs:36:33:36:33 | c : C2 | A.cs:39:16:39:28 | ... ? ... : ... : B [field c] : C2 | A.cs:31:14:31:42 | call to method SetOnBWrap : B [field c] : C2 | +| A.cs:31:29:31:41 | call to method Source<C2> : C2 | A.cs:36:33:36:33 | c : C2 | A.cs:39:16:39:28 | ... ? ... : ... : B [field c] : C2 | A.cs:31:14:31:42 | call to method SetOnBWrap : B [field c] : C2 | +| A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:42:29:42:29 | c : C2 | A.cs:48:20:48:21 | access to local variable b2 : B [field c] : C2 | A.cs:38:18:38:30 | call to method SetOnB : B [field c] : C2 | | A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:42:29:42:29 | c : C2 | A.cs:48:20:48:21 | access to local variable b2 : B [field c] : C2 | A.cs:38:18:38:30 | call to method SetOnB : B [field c] : C2 | | A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:145:27:145:27 | c : C2 | A.cs:145:32:145:35 | [post] this access : B [field c] : C2 | A.cs:47:13:47:14 | [post] access to local variable b2 : B [field c] : C2 | +| A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:145:27:145:27 | c : C2 | A.cs:145:32:145:35 | [post] this access : B [field c] : C2 | A.cs:47:13:47:14 | [post] access to local variable b2 : B [field c] : C2 | +| A.cs:83:15:83:26 | call to method Source<C> : C | A.cs:145:27:145:27 | c : C | A.cs:145:32:145:35 | [post] this access : B [field c] : C | A.cs:83:9:83:9 | [post] access to parameter b : B [field c] : C | | A.cs:83:15:83:26 | call to method Source<C> : C | A.cs:145:27:145:27 | c : C | A.cs:145:32:145:35 | [post] this access : B [field c] : C | A.cs:83:9:83:9 | [post] access to parameter b : B [field c] : C | | A.cs:105:23:105:23 | access to local variable b : B | A.cs:95:20:95:20 | b : B | A.cs:98:13:98:16 | [post] this access : D [field b] : B | A.cs:105:17:105:29 | object creation of type D : D [field b] : B | +| A.cs:105:23:105:23 | access to local variable b : B | A.cs:95:20:95:20 | b : B | A.cs:98:13:98:16 | [post] this access : D [field b] : B | A.cs:105:17:105:29 | object creation of type D : D [field b] : B | +| A.cs:114:29:114:29 | access to local variable b : B | A.cs:157:25:157:28 | head : B | A.cs:159:13:159:16 | [post] this access : MyList [field head] : B | A.cs:114:18:114:54 | object creation of type MyList : MyList [field head] : B | | A.cs:114:29:114:29 | access to local variable b : B | A.cs:157:25:157:28 | head : B | A.cs:159:13:159:16 | [post] this access : MyList [field head] : B | A.cs:114:18:114:54 | object creation of type MyList : MyList [field head] : B | | A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | A.cs:157:38:157:41 | next : MyList [field head] : B | A.cs:160:13:160:16 | [post] this access : MyList [field next, field head] : B | A.cs:115:18:115:37 | object creation of type MyList : MyList [field next, field head] : B | +| A.cs:115:35:115:36 | access to local variable l1 : MyList [field head] : B | A.cs:157:38:157:41 | next : MyList [field head] : B | A.cs:160:13:160:16 | [post] this access : MyList [field next, field head] : B | A.cs:115:18:115:37 | object creation of type MyList : MyList [field next, field head] : B | +| A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | A.cs:157:38:157:41 | next : MyList [field next, field head] : B | A.cs:160:13:160:16 | [post] this access : MyList [field next, field next, field head] : B | A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | | A.cs:116:35:116:36 | access to local variable l2 : MyList [field next, field head] : B | A.cs:157:38:157:41 | next : MyList [field next, field head] : B | A.cs:160:13:160:16 | [post] this access : MyList [field next, field next, field head] : B | A.cs:116:18:116:37 | object creation of type MyList : MyList [field next, field next, field head] : B | | A.cs:149:26:149:26 | access to parameter c : C | A.cs:141:20:141:20 | c : C | A.cs:143:13:143:16 | [post] this access : B [field c] : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | +| A.cs:149:26:149:26 | access to parameter c : C | A.cs:141:20:141:20 | c : C | A.cs:143:13:143:16 | [post] this access : B [field c] : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | +| B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:29:26:29:27 | e1 : Elem | B.cs:31:13:31:16 | [post] this access : Box1 [field elem1] : Elem | B.cs:6:18:6:34 | object creation of type Box1 : Box1 [field elem1] : Elem | | B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:29:26:29:27 | e1 : Elem | B.cs:31:13:31:16 | [post] this access : Box1 [field elem1] : Elem | B.cs:6:18:6:34 | object creation of type Box1 : Box1 [field elem1] : Elem | | B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | B.cs:39:26:39:27 | b1 : Box1 [field elem1] : Elem | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem1] : Elem | B.cs:7:18:7:29 | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | +| B.cs:7:27:7:28 | access to local variable b1 : Box1 [field elem1] : Elem | B.cs:39:26:39:27 | b1 : Box1 [field elem1] : Elem | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem1] : Elem | B.cs:7:18:7:29 | object creation of type Box2 : Box2 [field box1, field elem1] : Elem | +| B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:29:35:29:36 | e2 : Elem | B.cs:32:13:32:16 | [post] this access : Box1 [field elem2] : Elem | B.cs:15:18:15:34 | object creation of type Box1 : Box1 [field elem2] : Elem | | B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:29:35:29:36 | e2 : Elem | B.cs:32:13:32:16 | [post] this access : Box1 [field elem2] : Elem | B.cs:15:18:15:34 | object creation of type Box1 : Box1 [field elem2] : Elem | | B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | B.cs:39:26:39:27 | b1 : Box1 [field elem2] : Elem | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem2] : Elem | B.cs:16:18:16:29 | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | +| B.cs:16:27:16:28 | access to local variable b1 : Box1 [field elem2] : Elem | B.cs:39:26:39:27 | b1 : Box1 [field elem2] : Elem | B.cs:41:13:41:16 | [post] this access : Box2 [field box1, field elem2] : Elem | B.cs:16:18:16:29 | object creation of type Box2 : Box2 [field box1, field elem2] : Elem | +| D.cs:15:34:15:38 | access to parameter value : Object | D.cs:9:9:9:11 | value : Object | D.cs:9:15:9:18 | [post] this access : D [field trivialPropField] : Object | D.cs:15:15:15:18 | [post] this access : D [field trivialPropField] : Object | | D.cs:15:34:15:38 | access to parameter value : Object | D.cs:9:9:9:11 | value : Object | D.cs:9:15:9:18 | [post] this access : D [field trivialPropField] : Object | D.cs:15:15:15:18 | [post] this access : D [field trivialPropField] : Object | | D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:9:9:9:11 | value : Object | D.cs:9:15:9:18 | [post] this access : D [field trivialPropField] : Object | D.cs:22:9:22:11 | [post] access to local variable ret : D [field trivialPropField] : Object | +| D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:9:9:9:11 | value : Object | D.cs:9:15:9:18 | [post] this access : D [field trivialPropField] : Object | D.cs:22:9:22:11 | [post] access to local variable ret : D [field trivialPropField] : Object | +| D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:15:9:15:11 | value : Object | D.cs:15:15:15:18 | [post] this access : D [field trivialPropField] : Object | D.cs:23:9:23:11 | [post] access to local variable ret : D [field trivialPropField] : Object | | D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:15:9:15:11 | value : Object | D.cs:15:15:15:18 | [post] this access : D [field trivialPropField] : Object | D.cs:23:9:23:11 | [post] access to local variable ret : D [field trivialPropField] : Object | | D.cs:31:24:31:24 | access to local variable o : Object | D.cs:18:28:18:29 | o1 : Object | D.cs:24:16:24:18 | access to local variable ret : D [property AutoProp] : Object | D.cs:31:17:31:37 | call to method Create : D [property AutoProp] : Object | +| D.cs:31:24:31:24 | access to local variable o : Object | D.cs:18:28:18:29 | o1 : Object | D.cs:24:16:24:18 | access to local variable ret : D [property AutoProp] : Object | D.cs:31:17:31:37 | call to method Create : D [property AutoProp] : Object | +| D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:18:39:18:40 | o2 : Object | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:18:39:18:40 | o2 : Object | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | D.cs:37:13:37:49 | call to method Create : D [field trivialPropField] : Object | | D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | D.cs:39:14:39:26 | access to property TrivialProp | +| D.cs:39:14:39:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | D.cs:39:14:39:26 | access to property TrivialProp | +| D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | D.cs:41:14:41:26 | access to property ComplexProp | | D.cs:41:14:41:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | D.cs:41:14:41:26 | access to property ComplexProp | | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:18:50:18:51 | o3 : Object | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | +| D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:18:50:18:51 | o3 : Object | D.cs:24:16:24:18 | access to local variable ret : D [field trivialPropField] : Object | D.cs:43:13:43:49 | call to method Create : D [field trivialPropField] : Object | +| D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | D.cs:45:14:45:26 | access to property TrivialProp | | D.cs:45:14:45:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:8:9:8:11 | this : D [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | D.cs:45:14:45:26 | access to property TrivialProp | | D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | D.cs:47:14:47:26 | access to property ComplexProp | +| D.cs:47:14:47:14 | access to local variable d : D [field trivialPropField] : Object | D.cs:14:9:14:11 | this : D [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | D.cs:47:14:47:26 | access to property ComplexProp | +| E.cs:23:25:23:25 | access to local variable o : Object | E.cs:8:29:8:29 | o : Object | E.cs:12:16:12:18 | access to local variable ret : S [field Field] : Object | E.cs:23:17:23:26 | call to method CreateS : S [field Field] : Object | | E.cs:23:25:23:25 | access to local variable o : Object | E.cs:8:29:8:29 | o : Object | E.cs:12:16:12:18 | access to local variable ret : S [field Field] : Object | E.cs:23:17:23:26 | call to method CreateS : S [field Field] : Object | | F.cs:11:24:11:24 | access to local variable o : Object | F.cs:6:28:6:29 | o1 : Object | F.cs:6:46:6:81 | object creation of type F : F [field Field1] : Object | F.cs:11:17:11:31 | call to method Create : F [field Field1] : Object | +| F.cs:11:24:11:24 | access to local variable o : Object | F.cs:6:28:6:29 | o1 : Object | F.cs:6:46:6:81 | object creation of type F : F [field Field1] : Object | F.cs:11:17:11:31 | call to method Create : F [field Field1] : Object | +| F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:6:39:6:40 | o2 : Object | F.cs:6:46:6:81 | object creation of type F : F [field Field2] : Object | F.cs:15:13:15:43 | call to method Create : F [field Field2] : Object | | F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:6:39:6:40 | o2 : Object | F.cs:6:46:6:81 | object creation of type F : F [field Field2] : Object | F.cs:15:13:15:43 | call to method Create : F [field Field2] : Object | | G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | G.cs:64:39:64:42 | [post] this access : Box1 [field Elem] : Elem | G.cs:17:9:17:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | G.cs:64:39:64:42 | [post] this access : Box1 [field Elem] : Elem | G.cs:17:9:17:14 | [post] access to field Box1 : Box1 [field Elem] : Elem | +| G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | G.cs:64:39:64:42 | [post] this access : Box1 [field Elem] : Elem | G.cs:33:9:33:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | | G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | G.cs:64:39:64:42 | [post] this access : Box1 [field Elem] : Elem | G.cs:33:9:33:19 | [post] call to method GetBox1 : Box1 [field Elem] : Elem | | G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | G.cs:71:21:71:27 | this : Box2 [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | access to field Box1 : Box1 [field Elem] : Elem | G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:39:14:39:15 | access to parameter b2 : Box2 [field Box1, field Elem] : Elem | G.cs:71:21:71:27 | this : Box2 [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | access to field Box1 : Box1 [field Elem] : Elem | G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | +| G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:63:21:63:27 | this : Box1 [field Elem] : Elem | G.cs:63:34:63:37 | access to field Elem : Elem | G.cs:39:14:39:35 | call to method GetElem | | G.cs:39:14:39:25 | call to method GetBox1 : Box1 [field Elem] : Elem | G.cs:63:21:63:27 | this : Box1 [field Elem] : Elem | G.cs:63:34:63:37 | access to field Elem : Elem | G.cs:39:14:39:35 | call to method GetElem | | H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | H.cs:13:15:13:15 | a : A [field FieldA] : Object | H.cs:17:16:17:18 | access to local variable ret : A [field FieldA] : Object | H.cs:24:21:24:28 | call to method Clone : A [field FieldA] : Object | +| H.cs:24:27:24:27 | access to local variable a : A [field FieldA] : Object | H.cs:13:15:13:15 | a : A [field FieldA] : Object | H.cs:17:16:17:18 | access to local variable ret : A [field FieldA] : Object | H.cs:24:21:24:28 | call to method Clone : A [field FieldA] : Object | +| H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | H.cs:44:17:44:28 | call to method Transform : B [field FieldB] : Object | | H.cs:44:27:44:27 | access to local variable a : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | H.cs:44:17:44:28 | call to method Transform : B [field FieldB] : Object | | H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | H.cs:53:25:53:25 | a : A [field FieldA] : Object | H.cs:55:9:55:10 | [post] access to parameter b1 : B [field FieldB] : Object | H.cs:64:25:64:26 | [post] access to local variable b1 : B [field FieldB] : Object | +| H.cs:64:22:64:22 | access to local variable a : A [field FieldA] : Object | H.cs:53:25:53:25 | a : A [field FieldA] : Object | H.cs:55:9:55:10 | [post] access to parameter b1 : B [field FieldB] : Object | H.cs:64:25:64:26 | [post] access to local variable b1 : B [field FieldB] : Object | +| H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | H.cs:53:25:53:25 | a : A [field FieldA] : Object | H.cs:55:9:55:10 | [post] access to parameter b1 : B [field FieldB] : Object | H.cs:80:25:80:26 | [post] access to parameter b1 : B [field FieldB] : Object | | H.cs:80:22:80:22 | access to parameter a : A [field FieldA] : Object | H.cs:53:25:53:25 | a : A [field FieldA] : Object | H.cs:55:9:55:10 | [post] access to parameter b1 : B [field FieldB] : Object | H.cs:80:25:80:26 | [post] access to parameter b1 : B [field FieldB] : Object | | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:77:30:77:30 | o : Object | H.cs:79:9:79:9 | [post] access to parameter a : A [field FieldA] : Object | H.cs:88:17:88:17 | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:77:30:77:30 | o : Object | H.cs:79:9:79:9 | [post] access to parameter a : A [field FieldA] : Object | H.cs:88:17:88:17 | [post] access to local variable a : A [field FieldA] : Object | +| H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:77:30:77:30 | o : Object | H.cs:80:25:80:26 | [post] access to parameter b1 : B [field FieldB] : Object | H.cs:88:39:88:40 | [post] access to local variable b1 : B [field FieldB] : Object | | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:77:30:77:30 | o : Object | H.cs:80:25:80:26 | [post] access to parameter b1 : B [field FieldB] : Object | H.cs:88:39:88:40 | [post] access to local variable b1 : B [field FieldB] : Object | | H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | H.cs:106:16:106:40 | call to method Transform : B [field FieldB] : Object | +| H.cs:106:26:106:39 | (...) ... : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | H.cs:106:16:106:40 | call to method Transform : B [field FieldB] : Object | +| H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | H.cs:102:23:102:23 | a : A [field FieldA] : Object | H.cs:106:16:106:40 | call to method Transform : B [field FieldB] : Object | H.cs:113:17:113:32 | call to method TransformWrap : B [field FieldB] : Object | | H.cs:113:31:113:31 | access to local variable a : A [field FieldA] : Object | H.cs:102:23:102:23 | a : A [field FieldA] : Object | H.cs:106:16:106:40 | call to method Transform : B [field FieldB] : Object | H.cs:113:17:113:32 | call to method TransformWrap : B [field FieldB] : Object | | H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | H.cs:124:16:124:27 | call to method Transform : B [field FieldB] : Object | +| H.cs:124:26:124:26 | access to parameter a : A [field FieldA] : Object | H.cs:33:19:33:19 | a : A [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : Object | H.cs:124:16:124:27 | call to method Transform : B [field FieldB] : Object | +| H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | H.cs:122:18:122:18 | a : A [field FieldA] : Object | H.cs:124:16:124:34 | access to field FieldB : Object | H.cs:131:14:131:19 | call to method Get | | H.cs:131:18:131:18 | access to local variable a : A [field FieldA] : Object | H.cs:122:18:122:18 | a : A [field FieldA] : Object | H.cs:124:16:124:34 | access to field FieldB : Object | H.cs:131:14:131:19 | call to method Get | | H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | H.cs:33:19:33:19 | a : A [field FieldA] : A | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : A | H.cs:142:16:142:27 | call to method Transform : B [field FieldB] : A | +| H.cs:142:26:142:26 | access to local variable a : A [field FieldA] : A | H.cs:33:19:33:19 | a : A [field FieldA] : A | H.cs:37:16:37:16 | access to local variable b : B [field FieldB] : A | H.cs:142:16:142:27 | call to method Transform : B [field FieldB] : A | +| H.cs:147:25:147:38 | call to method Source<A> : A | H.cs:138:27:138:27 | o : A | H.cs:142:16:142:34 | access to field FieldB : A | H.cs:147:17:147:39 | call to method Through : A | | H.cs:147:25:147:38 | call to method Source<A> : A | H.cs:138:27:138:27 | o : A | H.cs:142:16:142:34 | access to field FieldB : A | H.cs:147:17:147:39 | call to method Through : A | | H.cs:164:22:164:22 | access to local variable o : Object | H.cs:153:32:153:32 | o : Object | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA, field FieldB] : Object | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA, field FieldB] : Object | +| H.cs:164:22:164:22 | access to local variable o : Object | H.cs:153:32:153:32 | o : Object | H.cs:157:9:157:9 | [post] access to parameter a : A [field FieldA, field FieldB] : Object | H.cs:164:19:164:19 | [post] access to local variable a : A [field FieldA, field FieldB] : Object | | J.cs:62:29:62:29 | access to local variable o : Object | J.cs:14:26:14:30 | field : Object | J.cs:14:50:14:54 | [post] this access : Struct [field Field] : Object | J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | +| J.cs:62:29:62:29 | access to local variable o : Object | J.cs:14:26:14:30 | field : Object | J.cs:14:50:14:54 | [post] this access : Struct [field Field] : Object | J.cs:62:18:62:36 | object creation of type Struct : Struct [field Field] : Object | +| J.cs:80:35:80:35 | access to local variable o : Object | J.cs:14:40:14:43 | prop : Object | J.cs:14:57:14:60 | [post] this access : Struct [property Prop] : Object | J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | | J.cs:80:35:80:35 | access to local variable o : Object | J.cs:14:40:14:43 | prop : Object | J.cs:14:57:14:60 | [post] this access : Struct [property Prop] : Object | J.cs:80:18:80:36 | object creation of type Struct : Struct [property Prop] : Object | #select | A.cs:7:14:7:16 | access to field c | A.cs:5:17:5:28 | call to method Source<C> : C | A.cs:7:14:7:16 | access to field c | $@ | A.cs:5:17:5:28 | call to method Source<C> : C | call to method Source<C> : C | +| A.cs:7:14:7:16 | access to field c | A.cs:5:17:5:28 | call to method Source<C> : C | A.cs:7:14:7:16 | access to field c | $@ | A.cs:5:17:5:28 | call to method Source<C> : C | call to method Source<C> : C | +| A.cs:14:14:14:20 | call to method Get | A.cs:13:15:13:29 | call to method Source<C1> : C1 | A.cs:14:14:14:20 | call to method Get | $@ | A.cs:13:15:13:29 | call to method Source<C1> : C1 | call to method Source<C1> : C1 | | A.cs:14:14:14:20 | call to method Get | A.cs:13:15:13:29 | call to method Source<C1> : C1 | A.cs:14:14:14:20 | call to method Get | $@ | A.cs:13:15:13:29 | call to method Source<C1> : C1 | call to method Source<C1> : C1 | | A.cs:15:14:15:42 | call to method Get | A.cs:15:21:15:34 | call to method Source<C> : C | A.cs:15:14:15:42 | call to method Get | $@ | A.cs:15:21:15:34 | call to method Source<C> : C | call to method Source<C> : C | +| A.cs:15:14:15:42 | call to method Get | A.cs:15:21:15:34 | call to method Source<C> : C | A.cs:15:14:15:42 | call to method Get | $@ | A.cs:15:21:15:34 | call to method Source<C> : C | call to method Source<C> : C | +| A.cs:24:14:24:17 | access to field c | A.cs:22:25:22:37 | call to method Source<C2> : C2 | A.cs:24:14:24:17 | access to field c | $@ | A.cs:22:25:22:37 | call to method Source<C2> : C2 | call to method Source<C2> : C2 | | A.cs:24:14:24:17 | access to field c | A.cs:22:25:22:37 | call to method Source<C2> : C2 | A.cs:24:14:24:17 | access to field c | $@ | A.cs:22:25:22:37 | call to method Source<C2> : C2 | call to method Source<C2> : C2 | | A.cs:33:14:33:17 | access to field c | A.cs:31:29:31:41 | call to method Source<C2> : C2 | A.cs:33:14:33:17 | access to field c | $@ | A.cs:31:29:31:41 | call to method Source<C2> : C2 | call to method Source<C2> : C2 | +| A.cs:33:14:33:17 | access to field c | A.cs:31:29:31:41 | call to method Source<C2> : C2 | A.cs:33:14:33:17 | access to field c | $@ | A.cs:31:29:31:41 | call to method Source<C2> : C2 | call to method Source<C2> : C2 | +| A.cs:64:18:64:26 | access to field a | A.cs:55:17:55:28 | call to method Source<A> : A | A.cs:64:18:64:26 | access to field a | $@ | A.cs:55:17:55:28 | call to method Source<A> : A | call to method Source<A> : A | | A.cs:64:18:64:26 | access to field a | A.cs:55:17:55:28 | call to method Source<A> : A | A.cs:64:18:64:26 | access to field a | $@ | A.cs:55:17:55:28 | call to method Source<A> : A | call to method Source<A> : A | | A.cs:89:14:89:16 | access to field c | A.cs:83:15:83:26 | call to method Source<C> : C | A.cs:89:14:89:16 | access to field c | $@ | A.cs:83:15:83:26 | call to method Source<C> : C | call to method Source<C> : C | +| A.cs:89:14:89:16 | access to field c | A.cs:83:15:83:26 | call to method Source<C> : C | A.cs:89:14:89:16 | access to field c | $@ | A.cs:83:15:83:26 | call to method Source<C> : C | call to method Source<C> : C | +| A.cs:106:14:106:16 | access to field b | A.cs:98:30:98:43 | call to method Source<B> : B | A.cs:106:14:106:16 | access to field b | $@ | A.cs:98:30:98:43 | call to method Source<B> : B | call to method Source<B> : B | | A.cs:106:14:106:16 | access to field b | A.cs:98:30:98:43 | call to method Source<B> : B | A.cs:106:14:106:16 | access to field b | $@ | A.cs:98:30:98:43 | call to method Source<B> : B | call to method Source<B> : B | | A.cs:106:14:106:16 | access to field b | A.cs:104:17:104:30 | call to method Source<B> : B | A.cs:106:14:106:16 | access to field b | $@ | A.cs:104:17:104:30 | call to method Source<B> : B | call to method Source<B> : B | +| A.cs:106:14:106:16 | access to field b | A.cs:104:17:104:30 | call to method Source<B> : B | A.cs:106:14:106:16 | access to field b | $@ | A.cs:104:17:104:30 | call to method Source<B> : B | call to method Source<B> : B | +| A.cs:107:14:107:18 | access to field c | A.cs:97:19:97:32 | call to method Source<C> : C | A.cs:107:14:107:18 | access to field c | $@ | A.cs:97:19:97:32 | call to method Source<C> : C | call to method Source<C> : C | | A.cs:107:14:107:18 | access to field c | A.cs:97:19:97:32 | call to method Source<C> : C | A.cs:107:14:107:18 | access to field c | $@ | A.cs:97:19:97:32 | call to method Source<C> : C | call to method Source<C> : C | | A.cs:108:14:108:16 | access to field c | A.cs:97:19:97:32 | call to method Source<C> : C | A.cs:108:14:108:16 | access to field c | $@ | A.cs:97:19:97:32 | call to method Source<C> : C | call to method Source<C> : C | +| A.cs:108:14:108:16 | access to field c | A.cs:97:19:97:32 | call to method Source<C> : C | A.cs:108:14:108:16 | access to field c | $@ | A.cs:97:19:97:32 | call to method Source<C> : C | call to method Source<C> : C | +| A.cs:119:14:119:30 | access to field head | A.cs:113:17:113:29 | call to method Source<B> : B | A.cs:119:14:119:30 | access to field head | $@ | A.cs:113:17:113:29 | call to method Source<B> : B | call to method Source<B> : B | | A.cs:119:14:119:30 | access to field head | A.cs:113:17:113:29 | call to method Source<B> : B | A.cs:119:14:119:30 | access to field head | $@ | A.cs:113:17:113:29 | call to method Source<B> : B | call to method Source<B> : B | | A.cs:123:18:123:23 | access to field head | A.cs:113:17:113:29 | call to method Source<B> : B | A.cs:123:18:123:23 | access to field head | $@ | A.cs:113:17:113:29 | call to method Source<B> : B | call to method Source<B> : B | +| A.cs:123:18:123:23 | access to field head | A.cs:113:17:113:29 | call to method Source<B> : B | A.cs:123:18:123:23 | access to field head | $@ | A.cs:113:17:113:29 | call to method Source<B> : B | call to method Source<B> : B | +| B.cs:8:14:8:26 | access to field elem1 | B.cs:5:17:5:31 | call to method Source<Elem> : Elem | B.cs:8:14:8:26 | access to field elem1 | $@ | B.cs:5:17:5:31 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | B.cs:8:14:8:26 | access to field elem1 | B.cs:5:17:5:31 | call to method Source<Elem> : Elem | B.cs:8:14:8:26 | access to field elem1 | $@ | B.cs:5:17:5:31 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | B.cs:18:14:18:26 | access to field elem2 | B.cs:14:17:14:31 | call to method Source<Elem> : Elem | B.cs:18:14:18:26 | access to field elem2 | $@ | B.cs:14:17:14:31 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| B.cs:18:14:18:26 | access to field elem2 | B.cs:14:17:14:31 | call to method Source<Elem> : Elem | B.cs:18:14:18:26 | access to field elem2 | $@ | B.cs:14:17:14:31 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| C.cs:23:14:23:15 | access to field s1 | C.cs:3:23:3:37 | call to method Source<Elem> : Elem | C.cs:23:14:23:15 | access to field s1 | $@ | C.cs:3:23:3:37 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | C.cs:23:14:23:15 | access to field s1 | C.cs:3:23:3:37 | call to method Source<Elem> : Elem | C.cs:23:14:23:15 | access to field s1 | $@ | C.cs:3:23:3:37 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | C.cs:24:14:24:15 | access to field s2 | C.cs:4:32:4:46 | call to method Source<Elem> : Elem | C.cs:24:14:24:15 | access to field s2 | $@ | C.cs:4:32:4:46 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| C.cs:24:14:24:15 | access to field s2 | C.cs:4:32:4:46 | call to method Source<Elem> : Elem | C.cs:24:14:24:15 | access to field s2 | $@ | C.cs:4:32:4:46 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| C.cs:25:14:25:15 | access to field s3 | C.cs:18:19:18:33 | call to method Source<Elem> : Elem | C.cs:25:14:25:15 | access to field s3 | $@ | C.cs:18:19:18:33 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | C.cs:25:14:25:15 | access to field s3 | C.cs:18:19:18:33 | call to method Source<Elem> : Elem | C.cs:25:14:25:15 | access to field s3 | $@ | C.cs:18:19:18:33 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | C.cs:26:14:26:15 | access to field s4 | C.cs:6:30:6:44 | call to method Source<Elem> : Elem | C.cs:26:14:26:15 | access to field s4 | $@ | C.cs:6:30:6:44 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| C.cs:26:14:26:15 | access to field s4 | C.cs:6:30:6:44 | call to method Source<Elem> : Elem | C.cs:26:14:26:15 | access to field s4 | $@ | C.cs:6:30:6:44 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| C.cs:27:14:27:15 | access to property s5 | C.cs:7:37:7:51 | call to method Source<Elem> : Elem | C.cs:27:14:27:15 | access to property s5 | $@ | C.cs:7:37:7:51 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | C.cs:27:14:27:15 | access to property s5 | C.cs:7:37:7:51 | call to method Source<Elem> : Elem | C.cs:27:14:27:15 | access to property s5 | $@ | C.cs:7:37:7:51 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | C.cs:28:14:28:15 | access to property s6 | C.cs:8:30:8:44 | call to method Source<Elem> : Elem | C.cs:28:14:28:15 | access to property s6 | $@ | C.cs:8:30:8:44 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| C.cs:28:14:28:15 | access to property s6 | C.cs:8:30:8:44 | call to method Source<Elem> : Elem | C.cs:28:14:28:15 | access to property s6 | $@ | C.cs:8:30:8:44 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| C_ctor.cs:13:19:13:20 | access to field s1 | C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | C_ctor.cs:13:19:13:20 | access to field s1 | $@ | C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | C_ctor.cs:13:19:13:20 | access to field s1 | C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | C_ctor.cs:13:19:13:20 | access to field s1 | $@ | C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | C_ctor.cs:31:19:31:20 | access to field s1 | C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | C_ctor.cs:31:19:31:20 | access to field s1 | $@ | C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| C_ctor.cs:31:19:31:20 | access to field s1 | C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | C_ctor.cs:31:19:31:20 | access to field s1 | $@ | C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| D.cs:32:14:32:23 | access to property AutoProp | D.cs:29:17:29:33 | call to method Source<Object> : Object | D.cs:32:14:32:23 | access to property AutoProp | $@ | D.cs:29:17:29:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | D.cs:32:14:32:23 | access to property AutoProp | D.cs:29:17:29:33 | call to method Source<Object> : Object | D.cs:32:14:32:23 | access to property AutoProp | $@ | D.cs:29:17:29:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | D.cs:39:14:39:26 | access to property TrivialProp | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:39:14:39:26 | access to property TrivialProp | $@ | D.cs:37:26:37:42 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| D.cs:39:14:39:26 | access to property TrivialProp | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:39:14:39:26 | access to property TrivialProp | $@ | D.cs:37:26:37:42 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| D.cs:40:14:40:31 | access to field trivialPropField | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:40:14:40:31 | access to field trivialPropField | $@ | D.cs:37:26:37:42 | call to method Source<Object> : Object | call to method Source<Object> : Object | | D.cs:40:14:40:31 | access to field trivialPropField | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:40:14:40:31 | access to field trivialPropField | $@ | D.cs:37:26:37:42 | call to method Source<Object> : Object | call to method Source<Object> : Object | | D.cs:41:14:41:26 | access to property ComplexProp | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:41:14:41:26 | access to property ComplexProp | $@ | D.cs:37:26:37:42 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| D.cs:41:14:41:26 | access to property ComplexProp | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:41:14:41:26 | access to property ComplexProp | $@ | D.cs:37:26:37:42 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| D.cs:45:14:45:26 | access to property TrivialProp | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:45:14:45:26 | access to property TrivialProp | $@ | D.cs:43:32:43:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | | D.cs:45:14:45:26 | access to property TrivialProp | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:45:14:45:26 | access to property TrivialProp | $@ | D.cs:43:32:43:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | | D.cs:46:14:46:31 | access to field trivialPropField | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:46:14:46:31 | access to field trivialPropField | $@ | D.cs:43:32:43:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| D.cs:46:14:46:31 | access to field trivialPropField | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:46:14:46:31 | access to field trivialPropField | $@ | D.cs:43:32:43:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| D.cs:47:14:47:26 | access to property ComplexProp | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:47:14:47:26 | access to property ComplexProp | $@ | D.cs:43:32:43:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | | D.cs:47:14:47:26 | access to property ComplexProp | D.cs:43:32:43:48 | call to method Source<Object> : Object | D.cs:47:14:47:26 | access to property ComplexProp | $@ | D.cs:43:32:43:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | | E.cs:24:14:24:20 | access to field Field | E.cs:22:17:22:33 | call to method Source<Object> : Object | E.cs:24:14:24:20 | access to field Field | $@ | E.cs:22:17:22:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| E.cs:24:14:24:20 | access to field Field | E.cs:22:17:22:33 | call to method Source<Object> : Object | E.cs:24:14:24:20 | access to field Field | $@ | E.cs:22:17:22:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| F.cs:12:14:12:21 | access to field Field1 | F.cs:10:17:10:33 | call to method Source<Object> : Object | F.cs:12:14:12:21 | access to field Field1 | $@ | F.cs:10:17:10:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | F.cs:12:14:12:21 | access to field Field1 | F.cs:10:17:10:33 | call to method Source<Object> : Object | F.cs:12:14:12:21 | access to field Field1 | $@ | F.cs:10:17:10:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | F.cs:17:14:17:21 | access to field Field2 | F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:17:14:17:21 | access to field Field2 | $@ | F.cs:15:26:15:42 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| F.cs:17:14:17:21 | access to field Field2 | F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:17:14:17:21 | access to field Field2 | $@ | F.cs:15:26:15:42 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| F.cs:20:14:20:21 | access to field Field1 | F.cs:19:32:19:48 | call to method Source<Object> : Object | F.cs:20:14:20:21 | access to field Field1 | $@ | F.cs:19:32:19:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | | F.cs:20:14:20:21 | access to field Field1 | F.cs:19:32:19:48 | call to method Source<Object> : Object | F.cs:20:14:20:21 | access to field Field1 | $@ | F.cs:19:32:19:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | | F.cs:25:14:25:21 | access to field Field2 | F.cs:23:32:23:48 | call to method Source<Object> : Object | F.cs:25:14:25:21 | access to field Field2 | $@ | F.cs:23:32:23:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| F.cs:25:14:25:21 | access to field Field2 | F.cs:23:32:23:48 | call to method Source<Object> : Object | F.cs:25:14:25:21 | access to field Field2 | $@ | F.cs:23:32:23:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| F.cs:33:14:33:16 | access to property X | F.cs:30:17:30:33 | call to method Source<Object> : Object | F.cs:33:14:33:16 | access to property X | $@ | F.cs:30:17:30:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | F.cs:33:14:33:16 | access to property X | F.cs:30:17:30:33 | call to method Source<Object> : Object | F.cs:33:14:33:16 | access to property X | $@ | F.cs:30:17:30:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | G.cs:39:14:39:35 | call to method GetElem | G.cs:7:18:7:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:7:18:7:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| G.cs:39:14:39:35 | call to method GetElem | G.cs:7:18:7:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:7:18:7:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| G.cs:39:14:39:35 | call to method GetElem | G.cs:15:18:15:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:15:18:15:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | G.cs:39:14:39:35 | call to method GetElem | G.cs:15:18:15:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:15:18:15:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | G.cs:39:14:39:35 | call to method GetElem | G.cs:23:18:23:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:23:18:23:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| G.cs:39:14:39:35 | call to method GetElem | G.cs:23:18:23:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:23:18:23:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| G.cs:39:14:39:35 | call to method GetElem | G.cs:31:18:31:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:31:18:31:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | G.cs:39:14:39:35 | call to method GetElem | G.cs:31:18:31:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:31:18:31:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | | G.cs:52:14:52:31 | access to field Elem | G.cs:44:18:44:32 | call to method Source<Elem> : Elem | G.cs:52:14:52:31 | access to field Elem | $@ | G.cs:44:18:44:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| G.cs:52:14:52:31 | access to field Elem | G.cs:44:18:44:32 | call to method Source<Elem> : Elem | G.cs:52:14:52:31 | access to field Elem | $@ | G.cs:44:18:44:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem | +| H.cs:25:14:25:25 | access to field FieldA | H.cs:23:20:23:36 | call to method Source<Object> : Object | H.cs:25:14:25:25 | access to field FieldA | $@ | H.cs:23:20:23:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | | H.cs:25:14:25:25 | access to field FieldA | H.cs:23:20:23:36 | call to method Source<Object> : Object | H.cs:25:14:25:25 | access to field FieldA | $@ | H.cs:23:20:23:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | | H.cs:45:14:45:21 | access to field FieldB | H.cs:43:20:43:36 | call to method Source<Object> : Object | H.cs:45:14:45:21 | access to field FieldB | $@ | H.cs:43:20:43:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| H.cs:45:14:45:21 | access to field FieldB | H.cs:43:20:43:36 | call to method Source<Object> : Object | H.cs:45:14:45:21 | access to field FieldB | $@ | H.cs:43:20:43:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| H.cs:65:14:65:22 | access to field FieldB | H.cs:63:20:63:36 | call to method Source<Object> : Object | H.cs:65:14:65:22 | access to field FieldB | $@ | H.cs:63:20:63:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | | H.cs:65:14:65:22 | access to field FieldB | H.cs:63:20:63:36 | call to method Source<Object> : Object | H.cs:65:14:65:22 | access to field FieldB | $@ | H.cs:63:20:63:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | | H.cs:89:14:89:21 | access to field FieldA | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:89:14:89:21 | access to field FieldA | $@ | H.cs:88:20:88:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| H.cs:89:14:89:21 | access to field FieldA | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:89:14:89:21 | access to field FieldA | $@ | H.cs:88:20:88:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| H.cs:90:14:90:22 | access to field FieldB | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:90:14:90:22 | access to field FieldB | $@ | H.cs:88:20:88:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | | H.cs:90:14:90:22 | access to field FieldB | H.cs:88:20:88:36 | call to method Source<Object> : Object | H.cs:90:14:90:22 | access to field FieldB | $@ | H.cs:88:20:88:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | | H.cs:114:14:114:21 | access to field FieldB | H.cs:112:20:112:36 | call to method Source<Object> : Object | H.cs:114:14:114:21 | access to field FieldB | $@ | H.cs:112:20:112:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| H.cs:114:14:114:21 | access to field FieldB | H.cs:112:20:112:36 | call to method Source<Object> : Object | H.cs:114:14:114:21 | access to field FieldB | $@ | H.cs:112:20:112:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| H.cs:131:14:131:19 | call to method Get | H.cs:130:20:130:36 | call to method Source<Object> : Object | H.cs:131:14:131:19 | call to method Get | $@ | H.cs:130:20:130:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | | H.cs:131:14:131:19 | call to method Get | H.cs:130:20:130:36 | call to method Source<Object> : Object | H.cs:131:14:131:19 | call to method Get | $@ | H.cs:130:20:130:36 | call to method Source<Object> : Object | call to method Source<Object> : Object | | H.cs:148:14:148:14 | access to local variable a | H.cs:147:25:147:38 | call to method Source<A> : A | H.cs:148:14:148:14 | access to local variable a | $@ | H.cs:147:25:147:38 | call to method Source<A> : A | call to method Source<A> : A | +| H.cs:148:14:148:14 | access to local variable a | H.cs:147:25:147:38 | call to method Source<A> : A | H.cs:148:14:148:14 | access to local variable a | $@ | H.cs:147:25:147:38 | call to method Source<A> : A | call to method Source<A> : A | +| H.cs:166:14:166:14 | access to local variable b | H.cs:155:17:155:30 | call to method Source<B> : B | H.cs:166:14:166:14 | access to local variable b | $@ | H.cs:155:17:155:30 | call to method Source<B> : B | call to method Source<B> : B | | H.cs:166:14:166:14 | access to local variable b | H.cs:155:17:155:30 | call to method Source<B> : B | H.cs:166:14:166:14 | access to local variable b | $@ | H.cs:155:17:155:30 | call to method Source<B> : B | call to method Source<B> : B | | H.cs:167:14:167:21 | access to field FieldB | H.cs:163:17:163:35 | call to method Source<Object> : Object | H.cs:167:14:167:21 | access to field FieldB | $@ | H.cs:163:17:163:35 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| H.cs:167:14:167:21 | access to field FieldB | H.cs:163:17:163:35 | call to method Source<Object> : Object | H.cs:167:14:167:21 | access to field FieldB | $@ | H.cs:163:17:163:35 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| I.cs:18:14:18:21 | access to field Field1 | I.cs:13:17:13:33 | call to method Source<Object> : Object | I.cs:18:14:18:21 | access to field Field1 | $@ | I.cs:13:17:13:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | I.cs:18:14:18:21 | access to field Field1 | I.cs:13:17:13:33 | call to method Source<Object> : Object | I.cs:18:14:18:21 | access to field Field1 | $@ | I.cs:13:17:13:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | I.cs:23:14:23:21 | access to field Field1 | I.cs:7:18:7:34 | call to method Source<Object> : Object | I.cs:23:14:23:21 | access to field Field1 | $@ | I.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| I.cs:23:14:23:21 | access to field Field1 | I.cs:7:18:7:34 | call to method Source<Object> : Object | I.cs:23:14:23:21 | access to field Field1 | $@ | I.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| I.cs:27:14:27:21 | access to field Field1 | I.cs:7:18:7:34 | call to method Source<Object> : Object | I.cs:27:14:27:21 | access to field Field1 | $@ | I.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | I.cs:27:14:27:21 | access to field Field1 | I.cs:7:18:7:34 | call to method Source<Object> : Object | I.cs:27:14:27:21 | access to field Field1 | $@ | I.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | I.cs:40:14:40:21 | access to field Field1 | I.cs:31:13:31:29 | call to method Source<Object> : Object | I.cs:40:14:40:21 | access to field Field1 | $@ | I.cs:31:13:31:29 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| I.cs:40:14:40:21 | access to field Field1 | I.cs:31:13:31:29 | call to method Source<Object> : Object | I.cs:40:14:40:21 | access to field Field1 | $@ | I.cs:31:13:31:29 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:23:14:23:21 | access to property Prop1 | J.cs:21:17:21:33 | call to method Source<Object> : Object | J.cs:23:14:23:21 | access to property Prop1 | $@ | J.cs:21:17:21:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:23:14:23:21 | access to property Prop1 | J.cs:21:17:21:33 | call to method Source<Object> : Object | J.cs:23:14:23:21 | access to property Prop1 | $@ | J.cs:21:17:21:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:27:14:27:21 | access to property Prop1 | J.cs:21:17:21:33 | call to method Source<Object> : Object | J.cs:27:14:27:21 | access to property Prop1 | $@ | J.cs:21:17:21:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:27:14:27:21 | access to property Prop1 | J.cs:21:17:21:33 | call to method Source<Object> : Object | J.cs:27:14:27:21 | access to property Prop1 | $@ | J.cs:21:17:21:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:31:14:31:21 | access to property Prop1 | J.cs:21:17:21:33 | call to method Source<Object> : Object | J.cs:31:14:31:21 | access to property Prop1 | $@ | J.cs:21:17:21:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:31:14:31:21 | access to property Prop1 | J.cs:21:17:21:33 | call to method Source<Object> : Object | J.cs:31:14:31:21 | access to property Prop1 | $@ | J.cs:21:17:21:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:32:14:32:21 | access to property Prop2 | J.cs:30:36:30:52 | call to method Source<Object> : Object | J.cs:32:14:32:21 | access to property Prop2 | $@ | J.cs:30:36:30:52 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:32:14:32:21 | access to property Prop2 | J.cs:30:36:30:52 | call to method Source<Object> : Object | J.cs:32:14:32:21 | access to property Prop2 | $@ | J.cs:30:36:30:52 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:43:14:43:21 | access to property Prop1 | J.cs:41:17:41:33 | call to method Source<Object> : Object | J.cs:43:14:43:21 | access to property Prop1 | $@ | J.cs:41:17:41:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:43:14:43:21 | access to property Prop1 | J.cs:41:17:41:33 | call to method Source<Object> : Object | J.cs:43:14:43:21 | access to property Prop1 | $@ | J.cs:41:17:41:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:47:14:47:21 | access to property Prop1 | J.cs:41:17:41:33 | call to method Source<Object> : Object | J.cs:47:14:47:21 | access to property Prop1 | $@ | J.cs:41:17:41:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:47:14:47:21 | access to property Prop1 | J.cs:41:17:41:33 | call to method Source<Object> : Object | J.cs:47:14:47:21 | access to property Prop1 | $@ | J.cs:41:17:41:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:51:14:51:21 | access to property Prop1 | J.cs:41:17:41:33 | call to method Source<Object> : Object | J.cs:51:14:51:21 | access to property Prop1 | $@ | J.cs:41:17:41:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:51:14:51:21 | access to property Prop1 | J.cs:41:17:41:33 | call to method Source<Object> : Object | J.cs:51:14:51:21 | access to property Prop1 | $@ | J.cs:41:17:41:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:52:14:52:21 | access to property Prop2 | J.cs:50:36:50:52 | call to method Source<Object> : Object | J.cs:52:14:52:21 | access to property Prop2 | $@ | J.cs:50:36:50:52 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:52:14:52:21 | access to property Prop2 | J.cs:50:36:50:52 | call to method Source<Object> : Object | J.cs:52:14:52:21 | access to property Prop2 | $@ | J.cs:50:36:50:52 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:65:14:65:21 | access to field Field | J.cs:61:17:61:33 | call to method Source<Object> : Object | J.cs:65:14:65:21 | access to field Field | $@ | J.cs:61:17:61:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:65:14:65:21 | access to field Field | J.cs:61:17:61:33 | call to method Source<Object> : Object | J.cs:65:14:65:21 | access to field Field | $@ | J.cs:61:17:61:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:69:14:69:21 | access to field Field | J.cs:61:17:61:33 | call to method Source<Object> : Object | J.cs:69:14:69:21 | access to field Field | $@ | J.cs:61:17:61:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:69:14:69:21 | access to field Field | J.cs:61:17:61:33 | call to method Source<Object> : Object | J.cs:69:14:69:21 | access to field Field | $@ | J.cs:61:17:61:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:70:14:70:20 | access to property Prop | J.cs:68:35:68:51 | call to method Source<Object> : Object | J.cs:70:14:70:20 | access to property Prop | $@ | J.cs:68:35:68:51 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:70:14:70:20 | access to property Prop | J.cs:68:35:68:51 | call to method Source<Object> : Object | J.cs:70:14:70:20 | access to property Prop | $@ | J.cs:68:35:68:51 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:84:14:84:20 | access to property Prop | J.cs:79:17:79:33 | call to method Source<Object> : Object | J.cs:84:14:84:20 | access to property Prop | $@ | J.cs:79:17:79:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:84:14:84:20 | access to property Prop | J.cs:79:17:79:33 | call to method Source<Object> : Object | J.cs:84:14:84:20 | access to property Prop | $@ | J.cs:79:17:79:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:87:14:87:21 | access to field Field | J.cs:86:36:86:52 | call to method Source<Object> : Object | J.cs:87:14:87:21 | access to field Field | $@ | J.cs:86:36:86:52 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:87:14:87:21 | access to field Field | J.cs:86:36:86:52 | call to method Source<Object> : Object | J.cs:87:14:87:21 | access to field Field | $@ | J.cs:86:36:86:52 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:88:14:88:20 | access to property Prop | J.cs:79:17:79:33 | call to method Source<Object> : Object | J.cs:88:14:88:20 | access to property Prop | $@ | J.cs:79:17:79:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:88:14:88:20 | access to property Prop | J.cs:79:17:79:33 | call to method Source<Object> : Object | J.cs:88:14:88:20 | access to property Prop | $@ | J.cs:79:17:79:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:102:14:102:17 | access to property X | J.cs:97:17:97:33 | call to method Source<Object> : Object | J.cs:102:14:102:17 | access to property X | $@ | J.cs:97:17:97:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:102:14:102:17 | access to property X | J.cs:97:17:97:33 | call to method Source<Object> : Object | J.cs:102:14:102:17 | access to property X | $@ | J.cs:97:17:97:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:106:14:106:17 | access to property X | J.cs:97:17:97:33 | call to method Source<Object> : Object | J.cs:106:14:106:17 | access to property X | $@ | J.cs:97:17:97:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:106:14:106:17 | access to property X | J.cs:97:17:97:33 | call to method Source<Object> : Object | J.cs:106:14:106:17 | access to property X | $@ | J.cs:97:17:97:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| J.cs:107:14:107:17 | access to property Y | J.cs:105:32:105:48 | call to method Source<Object> : Object | J.cs:107:14:107:17 | access to property Y | $@ | J.cs:105:32:105:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:107:14:107:17 | access to property Y | J.cs:105:32:105:48 | call to method Source<Object> : Object | J.cs:107:14:107:17 | access to property Y | $@ | J.cs:105:32:105:48 | call to method Source<Object> : Object | call to method Source<Object> : Object | | J.cs:125:14:125:17 | (...) ... | J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | J.cs:125:14:125:17 | (...) ... | $@ | J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | call to method Source<Int32> : Int32 | +| J.cs:125:14:125:17 | (...) ... | J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | J.cs:125:14:125:17 | (...) ... | $@ | J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | call to method Source<Int32> : Int32 | diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql index 39395ad831b..9336e1b28be 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql @@ -5,8 +5,8 @@ import csharp import TestUtilities.InlineFlowTest import DefaultFlowTest -import ValueFlow::PathGraph +import PathGraph -from ValueFlow::PathNode source, ValueFlow::PathNode sink -where ValueFlow::flowPath(source, sink) +from PathNode source, PathNode sink +where flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected index 3f4f02ff6a1..2bddf573b6a 100644 --- a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected @@ -2,95 +2,185 @@ failures testFailures edges | Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | +| Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | +| Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | | Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | | Operator.cs:18:51:18:51 | y : C | Operator.cs:18:57:18:57 | access to parameter y : C | +| Operator.cs:18:51:18:51 | y : C | Operator.cs:18:57:18:57 | access to parameter y : C | +| Operator.cs:19:38:19:38 | x : C | Operator.cs:19:49:19:49 | access to parameter x : C | | Operator.cs:19:38:19:38 | x : C | Operator.cs:19:49:19:49 | access to parameter x : C | | Operator.cs:21:43:21:43 | y : C | Operator.cs:21:49:21:49 | access to parameter y : C | +| Operator.cs:21:43:21:43 | y : C | Operator.cs:21:49:21:49 | access to parameter y : C | +| Operator.cs:22:51:22:51 | y : C | Operator.cs:22:57:22:57 | access to parameter y : C | | Operator.cs:22:51:22:51 | y : C | Operator.cs:22:57:22:57 | access to parameter y : C | | Operator.cs:27:17:27:28 | call to method Source<C> : C | Operator.cs:29:17:29:17 | access to local variable x : C | +| Operator.cs:27:17:27:28 | call to method Source<C> : C | Operator.cs:29:17:29:17 | access to local variable x : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:16:38:16:38 | x : C | | Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:16:38:16:38 | x : C | | Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:29:17:29:21 | call to operator + : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:29:17:29:21 | call to operator + : C | +| Operator.cs:29:17:29:21 | call to operator + : C | Operator.cs:30:14:30:14 | access to local variable z | | Operator.cs:29:17:29:21 | call to operator + : C | Operator.cs:30:14:30:14 | access to local variable z | | Operator.cs:35:17:35:28 | call to method Source<C> : C | Operator.cs:37:27:37:27 | access to local variable x : C | +| Operator.cs:35:17:35:28 | call to method Source<C> : C | Operator.cs:37:27:37:27 | access to local variable x : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:19:38:19:38 | x : C | | Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:19:38:19:38 | x : C | | Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:37:27:37:31 | call to operator - : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:37:27:37:31 | call to operator - : C | +| Operator.cs:37:27:37:31 | call to operator - : C | Operator.cs:38:14:38:14 | access to local variable z | | Operator.cs:37:27:37:31 | call to operator - : C | Operator.cs:38:14:38:14 | access to local variable z | | Operator.cs:44:17:44:28 | call to method Source<C> : C | Operator.cs:45:29:45:29 | access to local variable y : C | +| Operator.cs:44:17:44:28 | call to method Source<C> : C | Operator.cs:45:29:45:29 | access to local variable y : C | +| Operator.cs:45:25:45:29 | call to operator checked - : C | Operator.cs:46:14:46:14 | access to local variable z | | Operator.cs:45:25:45:29 | call to operator checked - : C | Operator.cs:46:14:46:14 | access to local variable z | | Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:18:51:18:51 | y : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:18:51:18:51 | y : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:45:25:45:29 | call to operator checked - : C | | Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:45:25:45:29 | call to operator checked - : C | | Operator.cs:49:28:49:28 | x : C | Operator.cs:51:17:51:17 | access to parameter x : C | +| Operator.cs:49:28:49:28 | x : C | Operator.cs:51:17:51:17 | access to parameter x : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:9:39:9:39 | x : C | | Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:9:39:9:39 | x : C | | Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:51:17:51:21 | call to operator * : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:51:17:51:21 | call to operator * : C | +| Operator.cs:51:17:51:21 | call to operator * : C | Operator.cs:52:14:52:14 | (...) ... | | Operator.cs:51:17:51:21 | call to operator * : C | Operator.cs:52:14:52:14 | (...) ... | | Operator.cs:57:17:57:28 | call to method Source<C> : C | Operator.cs:59:15:59:15 | access to local variable x : C | +| Operator.cs:57:17:57:28 | call to method Source<C> : C | Operator.cs:59:15:59:15 | access to local variable x : C | +| Operator.cs:59:15:59:15 | access to local variable x : C | Operator.cs:49:28:49:28 | x : C | | Operator.cs:59:15:59:15 | access to local variable x : C | Operator.cs:49:28:49:28 | x : C | | Operator.cs:62:33:62:33 | y : C | Operator.cs:64:21:64:21 | access to parameter y : C | +| Operator.cs:62:33:62:33 | y : C | Operator.cs:64:21:64:21 | access to parameter y : C | +| Operator.cs:64:17:64:21 | call to operator / : C | Operator.cs:65:14:65:14 | (...) ... | | Operator.cs:64:17:64:21 | call to operator / : C | Operator.cs:65:14:65:14 | (...) ... | | Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:21:43:21:43 | y : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:21:43:21:43 | y : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:64:17:64:21 | call to operator / : C | | Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:64:17:64:21 | call to operator / : C | | Operator.cs:71:17:71:29 | call to method Source<C> : C | Operator.cs:72:18:72:18 | access to local variable y : C | +| Operator.cs:71:17:71:29 | call to method Source<C> : C | Operator.cs:72:18:72:18 | access to local variable y : C | +| Operator.cs:72:18:72:18 | access to local variable y : C | Operator.cs:62:33:62:33 | y : C | | Operator.cs:72:18:72:18 | access to local variable y : C | Operator.cs:62:33:62:33 | y : C | | Operator.cs:75:33:75:33 | y : C | Operator.cs:77:29:77:29 | access to parameter y : C | +| Operator.cs:75:33:75:33 | y : C | Operator.cs:77:29:77:29 | access to parameter y : C | +| Operator.cs:77:25:77:29 | call to operator checked / : C | Operator.cs:78:14:78:14 | (...) ... | | Operator.cs:77:25:77:29 | call to operator checked / : C | Operator.cs:78:14:78:14 | (...) ... | | Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:22:51:22:51 | y : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:22:51:22:51 | y : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:77:25:77:29 | call to operator checked / : C | | Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:77:25:77:29 | call to operator checked / : C | | Operator.cs:84:17:84:29 | call to method Source<C> : C | Operator.cs:85:18:85:18 | access to local variable y : C | +| Operator.cs:84:17:84:29 | call to method Source<C> : C | Operator.cs:85:18:85:18 | access to local variable y : C | +| Operator.cs:85:18:85:18 | access to local variable y : C | Operator.cs:75:33:75:33 | y : C | | Operator.cs:85:18:85:18 | access to local variable y : C | Operator.cs:75:33:75:33 | y : C | nodes | Operator.cs:9:39:9:39 | x : C | semmle.label | x : C | +| Operator.cs:9:39:9:39 | x : C | semmle.label | x : C | +| Operator.cs:9:50:9:50 | access to parameter x : C | semmle.label | access to parameter x : C | | Operator.cs:9:50:9:50 | access to parameter x : C | semmle.label | access to parameter x : C | | Operator.cs:16:38:16:38 | x : C | semmle.label | x : C | +| Operator.cs:16:38:16:38 | x : C | semmle.label | x : C | +| Operator.cs:16:49:16:49 | access to parameter x : C | semmle.label | access to parameter x : C | | Operator.cs:16:49:16:49 | access to parameter x : C | semmle.label | access to parameter x : C | | Operator.cs:18:51:18:51 | y : C | semmle.label | y : C | +| Operator.cs:18:51:18:51 | y : C | semmle.label | y : C | +| Operator.cs:18:57:18:57 | access to parameter y : C | semmle.label | access to parameter y : C | | Operator.cs:18:57:18:57 | access to parameter y : C | semmle.label | access to parameter y : C | | Operator.cs:19:38:19:38 | x : C | semmle.label | x : C | +| Operator.cs:19:38:19:38 | x : C | semmle.label | x : C | +| Operator.cs:19:49:19:49 | access to parameter x : C | semmle.label | access to parameter x : C | | Operator.cs:19:49:19:49 | access to parameter x : C | semmle.label | access to parameter x : C | | Operator.cs:21:43:21:43 | y : C | semmle.label | y : C | +| Operator.cs:21:43:21:43 | y : C | semmle.label | y : C | +| Operator.cs:21:49:21:49 | access to parameter y : C | semmle.label | access to parameter y : C | | Operator.cs:21:49:21:49 | access to parameter y : C | semmle.label | access to parameter y : C | | Operator.cs:22:51:22:51 | y : C | semmle.label | y : C | +| Operator.cs:22:51:22:51 | y : C | semmle.label | y : C | +| Operator.cs:22:57:22:57 | access to parameter y : C | semmle.label | access to parameter y : C | | Operator.cs:22:57:22:57 | access to parameter y : C | semmle.label | access to parameter y : C | | Operator.cs:27:17:27:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:27:17:27:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | semmle.label | access to local variable x : C | | Operator.cs:29:17:29:17 | access to local variable x : C | semmle.label | access to local variable x : C | | Operator.cs:29:17:29:21 | call to operator + : C | semmle.label | call to operator + : C | +| Operator.cs:29:17:29:21 | call to operator + : C | semmle.label | call to operator + : C | +| Operator.cs:30:14:30:14 | access to local variable z | semmle.label | access to local variable z | | Operator.cs:30:14:30:14 | access to local variable z | semmle.label | access to local variable z | | Operator.cs:35:17:35:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:35:17:35:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | semmle.label | access to local variable x : C | | Operator.cs:37:27:37:27 | access to local variable x : C | semmle.label | access to local variable x : C | | Operator.cs:37:27:37:31 | call to operator - : C | semmle.label | call to operator - : C | +| Operator.cs:37:27:37:31 | call to operator - : C | semmle.label | call to operator - : C | +| Operator.cs:38:14:38:14 | access to local variable z | semmle.label | access to local variable z | | Operator.cs:38:14:38:14 | access to local variable z | semmle.label | access to local variable z | | Operator.cs:44:17:44:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:44:17:44:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:45:25:45:29 | call to operator checked - : C | semmle.label | call to operator checked - : C | | Operator.cs:45:25:45:29 | call to operator checked - : C | semmle.label | call to operator checked - : C | | Operator.cs:45:29:45:29 | access to local variable y : C | semmle.label | access to local variable y : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | semmle.label | access to local variable y : C | +| Operator.cs:46:14:46:14 | access to local variable z | semmle.label | access to local variable z | | Operator.cs:46:14:46:14 | access to local variable z | semmle.label | access to local variable z | | Operator.cs:49:28:49:28 | x : C | semmle.label | x : C | +| Operator.cs:49:28:49:28 | x : C | semmle.label | x : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | semmle.label | access to parameter x : C | | Operator.cs:51:17:51:17 | access to parameter x : C | semmle.label | access to parameter x : C | | Operator.cs:51:17:51:21 | call to operator * : C | semmle.label | call to operator * : C | +| Operator.cs:51:17:51:21 | call to operator * : C | semmle.label | call to operator * : C | +| Operator.cs:52:14:52:14 | (...) ... | semmle.label | (...) ... | | Operator.cs:52:14:52:14 | (...) ... | semmle.label | (...) ... | | Operator.cs:57:17:57:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:57:17:57:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:59:15:59:15 | access to local variable x : C | semmle.label | access to local variable x : C | | Operator.cs:59:15:59:15 | access to local variable x : C | semmle.label | access to local variable x : C | | Operator.cs:62:33:62:33 | y : C | semmle.label | y : C | +| Operator.cs:62:33:62:33 | y : C | semmle.label | y : C | +| Operator.cs:64:17:64:21 | call to operator / : C | semmle.label | call to operator / : C | | Operator.cs:64:17:64:21 | call to operator / : C | semmle.label | call to operator / : C | | Operator.cs:64:21:64:21 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:65:14:65:14 | (...) ... | semmle.label | (...) ... | | Operator.cs:65:14:65:14 | (...) ... | semmle.label | (...) ... | | Operator.cs:71:17:71:29 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:71:17:71:29 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:72:18:72:18 | access to local variable y : C | semmle.label | access to local variable y : C | | Operator.cs:72:18:72:18 | access to local variable y : C | semmle.label | access to local variable y : C | | Operator.cs:75:33:75:33 | y : C | semmle.label | y : C | +| Operator.cs:75:33:75:33 | y : C | semmle.label | y : C | +| Operator.cs:77:25:77:29 | call to operator checked / : C | semmle.label | call to operator checked / : C | | Operator.cs:77:25:77:29 | call to operator checked / : C | semmle.label | call to operator checked / : C | | Operator.cs:77:29:77:29 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | semmle.label | access to parameter y : C | +| Operator.cs:78:14:78:14 | (...) ... | semmle.label | (...) ... | | Operator.cs:78:14:78:14 | (...) ... | semmle.label | (...) ... | | Operator.cs:84:17:84:29 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:84:17:84:29 | call to method Source<C> : C | semmle.label | call to method Source<C> : C | +| Operator.cs:85:18:85:18 | access to local variable y : C | semmle.label | access to local variable y : C | | Operator.cs:85:18:85:18 | access to local variable y : C | semmle.label | access to local variable y : C | subpaths | Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | Operator.cs:29:17:29:21 | call to operator + : C | +| Operator.cs:29:17:29:17 | access to local variable x : C | Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | Operator.cs:29:17:29:21 | call to operator + : C | +| Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:19:38:19:38 | x : C | Operator.cs:19:49:19:49 | access to parameter x : C | Operator.cs:37:27:37:31 | call to operator - : C | | Operator.cs:37:27:37:27 | access to local variable x : C | Operator.cs:19:38:19:38 | x : C | Operator.cs:19:49:19:49 | access to parameter x : C | Operator.cs:37:27:37:31 | call to operator - : C | | Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:18:51:18:51 | y : C | Operator.cs:18:57:18:57 | access to parameter y : C | Operator.cs:45:25:45:29 | call to operator checked - : C | +| Operator.cs:45:29:45:29 | access to local variable y : C | Operator.cs:18:51:18:51 | y : C | Operator.cs:18:57:18:57 | access to parameter y : C | Operator.cs:45:25:45:29 | call to operator checked - : C | +| Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | Operator.cs:51:17:51:21 | call to operator * : C | | Operator.cs:51:17:51:17 | access to parameter x : C | Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | Operator.cs:51:17:51:21 | call to operator * : C | | Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:21:43:21:43 | y : C | Operator.cs:21:49:21:49 | access to parameter y : C | Operator.cs:64:17:64:21 | call to operator / : C | +| Operator.cs:64:21:64:21 | access to parameter y : C | Operator.cs:21:43:21:43 | y : C | Operator.cs:21:49:21:49 | access to parameter y : C | Operator.cs:64:17:64:21 | call to operator / : C | +| Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:22:51:22:51 | y : C | Operator.cs:22:57:22:57 | access to parameter y : C | Operator.cs:77:25:77:29 | call to operator checked / : C | | Operator.cs:77:29:77:29 | access to parameter y : C | Operator.cs:22:51:22:51 | y : C | Operator.cs:22:57:22:57 | access to parameter y : C | Operator.cs:77:25:77:29 | call to operator checked / : C | #select | Operator.cs:30:14:30:14 | access to local variable z | Operator.cs:27:17:27:28 | call to method Source<C> : C | Operator.cs:30:14:30:14 | access to local variable z | $@ | Operator.cs:27:17:27:28 | call to method Source<C> : C | call to method Source<C> : C | +| Operator.cs:30:14:30:14 | access to local variable z | Operator.cs:27:17:27:28 | call to method Source<C> : C | Operator.cs:30:14:30:14 | access to local variable z | $@ | Operator.cs:27:17:27:28 | call to method Source<C> : C | call to method Source<C> : C | +| Operator.cs:38:14:38:14 | access to local variable z | Operator.cs:35:17:35:28 | call to method Source<C> : C | Operator.cs:38:14:38:14 | access to local variable z | $@ | Operator.cs:35:17:35:28 | call to method Source<C> : C | call to method Source<C> : C | | Operator.cs:38:14:38:14 | access to local variable z | Operator.cs:35:17:35:28 | call to method Source<C> : C | Operator.cs:38:14:38:14 | access to local variable z | $@ | Operator.cs:35:17:35:28 | call to method Source<C> : C | call to method Source<C> : C | | Operator.cs:46:14:46:14 | access to local variable z | Operator.cs:44:17:44:28 | call to method Source<C> : C | Operator.cs:46:14:46:14 | access to local variable z | $@ | Operator.cs:44:17:44:28 | call to method Source<C> : C | call to method Source<C> : C | +| Operator.cs:46:14:46:14 | access to local variable z | Operator.cs:44:17:44:28 | call to method Source<C> : C | Operator.cs:46:14:46:14 | access to local variable z | $@ | Operator.cs:44:17:44:28 | call to method Source<C> : C | call to method Source<C> : C | +| Operator.cs:52:14:52:14 | (...) ... | Operator.cs:57:17:57:28 | call to method Source<C> : C | Operator.cs:52:14:52:14 | (...) ... | $@ | Operator.cs:57:17:57:28 | call to method Source<C> : C | call to method Source<C> : C | | Operator.cs:52:14:52:14 | (...) ... | Operator.cs:57:17:57:28 | call to method Source<C> : C | Operator.cs:52:14:52:14 | (...) ... | $@ | Operator.cs:57:17:57:28 | call to method Source<C> : C | call to method Source<C> : C | | Operator.cs:65:14:65:14 | (...) ... | Operator.cs:71:17:71:29 | call to method Source<C> : C | Operator.cs:65:14:65:14 | (...) ... | $@ | Operator.cs:71:17:71:29 | call to method Source<C> : C | call to method Source<C> : C | +| Operator.cs:65:14:65:14 | (...) ... | Operator.cs:71:17:71:29 | call to method Source<C> : C | Operator.cs:65:14:65:14 | (...) ... | $@ | Operator.cs:71:17:71:29 | call to method Source<C> : C | call to method Source<C> : C | +| Operator.cs:78:14:78:14 | (...) ... | Operator.cs:84:17:84:29 | call to method Source<C> : C | Operator.cs:78:14:78:14 | (...) ... | $@ | Operator.cs:84:17:84:29 | call to method Source<C> : C | call to method Source<C> : C | | Operator.cs:78:14:78:14 | (...) ... | Operator.cs:84:17:84:29 | call to method Source<C> : C | Operator.cs:78:14:78:14 | (...) ... | $@ | Operator.cs:84:17:84:29 | call to method Source<C> : C | call to method Source<C> : C | diff --git a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql index 39395ad831b..9336e1b28be 100644 --- a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql @@ -5,8 +5,8 @@ import csharp import TestUtilities.InlineFlowTest import DefaultFlowTest -import ValueFlow::PathGraph +import PathGraph -from ValueFlow::PathNode source, ValueFlow::PathNode sink -where ValueFlow::flowPath(source, sink) +from PathNode source, PathNode sink +where flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql index 39395ad831b..9336e1b28be 100644 --- a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql @@ -5,8 +5,8 @@ import csharp import TestUtilities.InlineFlowTest import DefaultFlowTest -import ValueFlow::PathGraph +import PathGraph -from ValueFlow::PathNode source, ValueFlow::PathNode sink -where ValueFlow::flowPath(source, sink) +from PathNode source, PathNode sink +where flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected index bb1715df029..10b9a4b66ac 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected +++ b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected @@ -2,233 +2,461 @@ failures testFailures edges | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:10:21:10:22 | access to local variable o1 : Object | +| Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:10:21:10:22 | access to local variable o1 : Object | +| Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:10:29:10:30 | access to local variable o2 : Object | | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:10:29:10:30 | access to local variable o2 : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:26:14:26:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:26:14:26:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:27:14:27:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:27:14:27:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:29:14:29:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:29:14:29:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:10:21:10:22 | access to local variable o1 : Object | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | | Tuples.cs:10:21:10:22 | access to local variable o1 : Object | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | | Tuples.cs:10:25:10:31 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:10:25:10:31 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:10:29:10:30 | access to local variable o2 : Object | Tuples.cs:10:25:10:31 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:10:29:10:30 | access to local variable o2 : Object | Tuples.cs:10:25:10:31 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:11:9:11:27 | SSA def(c) : Object | +| Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:11:9:11:27 | SSA def(c) : Object | +| Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:11:9:11:27 | SSA def(a) : Object | | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:11:9:11:27 | SSA def(a) : Object | | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:11:9:11:27 | SSA def(a) : Object | Tuples.cs:12:14:12:14 | access to local variable a | | Tuples.cs:11:9:11:27 | SSA def(a) : Object | Tuples.cs:12:14:12:14 | access to local variable a | | Tuples.cs:11:9:11:27 | SSA def(c) : Object | Tuples.cs:14:14:14:14 | access to local variable c | +| Tuples.cs:11:9:11:27 | SSA def(c) : Object | Tuples.cs:14:14:14:14 | access to local variable c | +| Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:16:9:16:23 | SSA def(a) : Object | | Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:16:9:16:23 | SSA def(a) : Object | | Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:16:13:16:18 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:16:13:16:18 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:16:9:16:23 | SSA def(a) : Object | Tuples.cs:17:14:17:14 | access to local variable a | | Tuples.cs:16:9:16:23 | SSA def(a) : Object | Tuples.cs:17:14:17:14 | access to local variable a | | Tuples.cs:16:9:16:23 | SSA def(c) : Object | Tuples.cs:19:14:19:14 | access to local variable c | +| Tuples.cs:16:9:16:23 | SSA def(c) : Object | Tuples.cs:19:14:19:14 | access to local variable c | +| Tuples.cs:16:13:16:18 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:16:9:16:23 | SSA def(c) : Object | | Tuples.cs:16:13:16:18 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:16:9:16:23 | SSA def(c) : Object | | Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:21:9:21:26 | SSA def(p) : Object | +| Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:21:9:21:26 | SSA def(p) : Object | +| Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:21:9:21:26 | SSA def(q) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:21:9:21:26 | SSA def(q) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:21:9:21:26 | SSA def(p) : Object | Tuples.cs:22:14:22:14 | access to local variable p | +| Tuples.cs:21:9:21:26 | SSA def(p) : Object | Tuples.cs:22:14:22:14 | access to local variable p | +| Tuples.cs:21:9:21:26 | SSA def(q) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:24:14:24:14 | access to local variable q : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:21:9:21:26 | SSA def(q) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:24:14:24:14 | access to local variable q : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:24:14:24:14 | access to local variable q : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:24:14:24:20 | access to field Item2 | +| Tuples.cs:24:14:24:14 | access to local variable q : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:24:14:24:20 | access to field Item2 | +| Tuples.cs:26:14:26:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:26:14:26:20 | access to field Item1 | | Tuples.cs:26:14:26:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:26:14:26:20 | access to field Item1 | | Tuples.cs:27:14:27:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:27:14:27:16 | access to field Item1 | +| Tuples.cs:27:14:27:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | Tuples.cs:27:14:27:16 | access to field Item1 | +| Tuples.cs:29:14:29:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:29:14:29:20 | access to field Item2 : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:29:14:29:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | Tuples.cs:29:14:29:20 | access to field Item2 : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:29:14:29:20 | access to field Item2 : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:29:14:29:26 | access to field Item2 | +| Tuples.cs:29:14:29:20 | access to field Item2 : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:29:14:29:26 | access to field Item2 | +| Tuples.cs:34:18:34:34 | call to method Source<Object> : Object | Tuples.cs:37:18:37:19 | access to local variable o1 : Object | | Tuples.cs:34:18:34:34 | call to method Source<Object> : Object | Tuples.cs:37:18:37:19 | access to local variable o1 : Object | | Tuples.cs:35:18:35:34 | call to method Source<Object> : Object | Tuples.cs:37:46:37:47 | access to local variable o2 : Object | +| Tuples.cs:35:18:35:34 | call to method Source<Object> : Object | Tuples.cs:37:46:37:47 | access to local variable o2 : Object | +| Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | Tuples.cs:38:14:38:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | | Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | Tuples.cs:38:14:38:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | | Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | Tuples.cs:40:14:40:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | +| Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | Tuples.cs:40:14:40:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | +| Tuples.cs:37:18:37:19 | access to local variable o1 : Object | Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | | Tuples.cs:37:18:37:19 | access to local variable o1 : Object | Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | | Tuples.cs:37:46:37:47 | access to local variable o2 : Object | Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | +| Tuples.cs:37:46:37:47 | access to local variable o2 : Object | Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | +| Tuples.cs:38:14:38:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | Tuples.cs:38:14:38:20 | access to field Item1 | | Tuples.cs:38:14:38:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | Tuples.cs:38:14:38:20 | access to field Item1 | | Tuples.cs:40:14:40:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | Tuples.cs:40:14:40:21 | access to field Item10 | +| Tuples.cs:40:14:40:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | Tuples.cs:40:14:40:21 | access to field Item10 | +| Tuples.cs:45:17:45:33 | call to method Source<String> : String | Tuples.cs:46:48:46:48 | access to local variable o : String | | Tuples.cs:45:17:45:33 | call to method Source<String> : String | Tuples.cs:46:48:46:48 | access to local variable o : String | | Tuples.cs:46:17:46:55 | (...) ... : ValueTuple<String,Int32,Int32> [field Item1] : String | Tuples.cs:47:14:47:14 | access to local variable x : ValueTuple<String,Int32,Int32> [field Item1] : String | +| Tuples.cs:46:17:46:55 | (...) ... : ValueTuple<String,Int32,Int32> [field Item1] : String | Tuples.cs:47:14:47:14 | access to local variable x : ValueTuple<String,Int32,Int32> [field Item1] : String | +| Tuples.cs:46:47:46:55 | (..., ...) : ValueTuple<String,Int32,Int32> [field Item1] : String | Tuples.cs:46:17:46:55 | (...) ... : ValueTuple<String,Int32,Int32> [field Item1] : String | | Tuples.cs:46:47:46:55 | (..., ...) : ValueTuple<String,Int32,Int32> [field Item1] : String | Tuples.cs:46:17:46:55 | (...) ... : ValueTuple<String,Int32,Int32> [field Item1] : String | | Tuples.cs:46:48:46:48 | access to local variable o : String | Tuples.cs:46:47:46:55 | (..., ...) : ValueTuple<String,Int32,Int32> [field Item1] : String | +| Tuples.cs:46:48:46:48 | access to local variable o : String | Tuples.cs:46:47:46:55 | (..., ...) : ValueTuple<String,Int32,Int32> [field Item1] : String | +| Tuples.cs:47:14:47:14 | access to local variable x : ValueTuple<String,Int32,Int32> [field Item1] : String | Tuples.cs:47:14:47:20 | access to field Item1 | | Tuples.cs:47:14:47:14 | access to local variable x : ValueTuple<String,Int32,Int32> [field Item1] : String | Tuples.cs:47:14:47:20 | access to field Item1 | | Tuples.cs:57:18:57:34 | call to method Source<String> : String | Tuples.cs:59:18:59:19 | access to local variable o1 : String | +| Tuples.cs:57:18:57:34 | call to method Source<String> : String | Tuples.cs:59:18:59:19 | access to local variable o1 : String | +| Tuples.cs:58:18:58:34 | call to method Source<String> : String | Tuples.cs:59:26:59:27 | access to local variable o2 : String | | Tuples.cs:58:18:58:34 | call to method Source<String> : String | Tuples.cs:59:26:59:27 | access to local variable o2 : String | | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:59:18:59:19 | access to local variable o1 : String | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:59:18:59:19 | access to local variable o1 : String | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:59:22:59:28 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:59:22:59:28 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:59:26:59:27 | access to local variable o2 : String | Tuples.cs:59:22:59:28 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:59:26:59:27 | access to local variable o2 : String | Tuples.cs:59:22:59:28 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:63:22:63:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | | Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:63:22:63:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | | Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:64:22:64:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:64:22:64:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:63:22:63:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:63:22:63:28 | access to field Item1 | | Tuples.cs:63:22:63:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:63:22:63:28 | access to field Item1 | | Tuples.cs:64:22:64:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:64:22:64:28 | access to field Item2 : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:64:22:64:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:64:22:64:28 | access to field Item2 : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:64:22:64:28 | access to field Item2 : ValueTuple<Int32,String> [field Item2] : String | Tuples.cs:64:22:64:34 | access to field Item2 | | Tuples.cs:64:22:64:28 | access to field Item2 : ValueTuple<Int32,String> [field Item2] : String | Tuples.cs:64:22:64:34 | access to field Item2 | | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | Tuples.cs:67:30:67:30 | SSA def(c) : String | +| Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | Tuples.cs:67:30:67:30 | SSA def(c) : String | +| Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:67:23:67:23 | SSA def(a) : String | | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:67:23:67:23 | SSA def(a) : String | | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:67:23:67:23 | SSA def(a) : String | Tuples.cs:68:22:68:22 | access to local variable a | | Tuples.cs:67:23:67:23 | SSA def(a) : String | Tuples.cs:68:22:68:22 | access to local variable a | | Tuples.cs:67:30:67:30 | SSA def(c) : String | Tuples.cs:69:22:69:22 | access to local variable c | +| Tuples.cs:67:30:67:30 | SSA def(c) : String | Tuples.cs:69:22:69:22 | access to local variable c | +| Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | Tuples.cs:87:30:87:30 | SSA def(r) : String | | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | Tuples.cs:87:30:87:30 | SSA def(r) : String | | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:87:23:87:23 | SSA def(p) : String | +| Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | Tuples.cs:87:23:87:23 | SSA def(p) : String | +| Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | | Tuples.cs:87:23:87:23 | SSA def(p) : String | Tuples.cs:89:18:89:18 | access to local variable p | +| Tuples.cs:87:23:87:23 | SSA def(p) : String | Tuples.cs:89:18:89:18 | access to local variable p | +| Tuples.cs:87:30:87:30 | SSA def(r) : String | Tuples.cs:90:18:90:18 | access to local variable r | | Tuples.cs:87:30:87:30 | SSA def(r) : String | Tuples.cs:90:18:90:18 | access to local variable r | | Tuples.cs:99:17:99:33 | call to method Source<String> : String | Tuples.cs:100:24:100:24 | access to local variable o : String | +| Tuples.cs:99:17:99:33 | call to method Source<String> : String | Tuples.cs:100:24:100:24 | access to local variable o : String | +| Tuples.cs:100:17:100:28 | object creation of type R1 : R1 [property i] : String | Tuples.cs:101:14:101:14 | access to local variable r : R1 [property i] : String | | Tuples.cs:100:17:100:28 | object creation of type R1 : R1 [property i] : String | Tuples.cs:101:14:101:14 | access to local variable r : R1 [property i] : String | | Tuples.cs:100:24:100:24 | access to local variable o : String | Tuples.cs:100:17:100:28 | object creation of type R1 : R1 [property i] : String | +| Tuples.cs:100:24:100:24 | access to local variable o : String | Tuples.cs:100:17:100:28 | object creation of type R1 : R1 [property i] : String | +| Tuples.cs:101:14:101:14 | access to local variable r : R1 [property i] : String | Tuples.cs:101:14:101:16 | access to property i | | Tuples.cs:101:14:101:14 | access to local variable r : R1 [property i] : String | Tuples.cs:101:14:101:16 | access to property i | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:121:28:121:28 | access to local variable o : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:121:28:121:28 | access to local variable o : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:122:14:122:15 | access to local variable x1 | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:122:14:122:15 | access to local variable x1 | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:125:25:125:25 | access to local variable o : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:125:25:125:25 | access to local variable o : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:126:14:126:15 | access to local variable x2 | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:126:14:126:15 | access to local variable x2 | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:129:31:129:31 | access to local variable o : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:129:31:129:31 | access to local variable o : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:130:14:130:15 | access to local variable y3 | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:130:14:130:15 | access to local variable y3 | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:133:28:133:28 | access to local variable o : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:133:28:133:28 | access to local variable o : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:134:14:134:15 | access to local variable y4 | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:134:14:134:15 | access to local variable y4 | | Tuples.cs:121:9:121:23 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | Tuples.cs:121:9:121:32 | SSA def(x1) : Object | +| Tuples.cs:121:9:121:23 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | Tuples.cs:121:9:121:32 | SSA def(x1) : Object | +| Tuples.cs:121:9:121:32 | SSA def(x1) : Object | Tuples.cs:122:14:122:15 | access to local variable x1 | | Tuples.cs:121:9:121:32 | SSA def(x1) : Object | Tuples.cs:122:14:122:15 | access to local variable x1 | | Tuples.cs:121:27:121:32 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | Tuples.cs:121:9:121:23 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | +| Tuples.cs:121:27:121:32 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | Tuples.cs:121:9:121:23 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | +| Tuples.cs:121:28:121:28 | access to local variable o : Object | Tuples.cs:121:27:121:32 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | | Tuples.cs:121:28:121:28 | access to local variable o : Object | Tuples.cs:121:27:121:32 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | | Tuples.cs:125:9:125:20 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | Tuples.cs:125:9:125:29 | SSA def(x2) : Object | +| Tuples.cs:125:9:125:20 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | Tuples.cs:125:9:125:29 | SSA def(x2) : Object | +| Tuples.cs:125:9:125:29 | SSA def(x2) : Object | Tuples.cs:126:14:126:15 | access to local variable x2 | | Tuples.cs:125:9:125:29 | SSA def(x2) : Object | Tuples.cs:126:14:126:15 | access to local variable x2 | | Tuples.cs:125:24:125:29 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | Tuples.cs:125:9:125:20 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | +| Tuples.cs:125:24:125:29 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | Tuples.cs:125:9:125:20 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | +| Tuples.cs:125:25:125:25 | access to local variable o : Object | Tuples.cs:125:24:125:29 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | | Tuples.cs:125:25:125:25 | access to local variable o : Object | Tuples.cs:125:24:125:29 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | | Tuples.cs:129:9:129:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:129:9:129:32 | SSA def(y3) : Object | +| Tuples.cs:129:9:129:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:129:9:129:32 | SSA def(y3) : Object | +| Tuples.cs:129:9:129:32 | SSA def(y3) : Object | Tuples.cs:130:14:130:15 | access to local variable y3 | | Tuples.cs:129:9:129:32 | SSA def(y3) : Object | Tuples.cs:130:14:130:15 | access to local variable y3 | | Tuples.cs:129:27:129:32 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:129:9:129:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:129:27:129:32 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:129:9:129:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:129:31:129:31 | access to local variable o : Object | Tuples.cs:129:27:129:32 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:129:31:129:31 | access to local variable o : Object | Tuples.cs:129:27:129:32 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:133:9:133:20 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:133:9:133:29 | SSA def(y4) : Object | +| Tuples.cs:133:9:133:20 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:133:9:133:29 | SSA def(y4) : Object | +| Tuples.cs:133:9:133:29 | SSA def(y4) : Object | Tuples.cs:134:14:134:15 | access to local variable y4 | | Tuples.cs:133:9:133:29 | SSA def(y4) : Object | Tuples.cs:134:14:134:15 | access to local variable y4 | | Tuples.cs:133:24:133:29 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:133:9:133:20 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:133:24:133:29 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | Tuples.cs:133:9:133:20 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:133:28:133:28 | access to local variable o : Object | Tuples.cs:133:24:133:29 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:133:28:133:28 | access to local variable o : Object | Tuples.cs:133:24:133:29 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | nodes | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:10:17:10:32 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:10:21:10:22 | access to local variable o1 : Object | semmle.label | access to local variable o1 : Object | +| Tuples.cs:10:21:10:22 | access to local variable o1 : Object | semmle.label | access to local variable o1 : Object | +| Tuples.cs:10:25:10:31 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:10:25:10:31 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:10:29:10:30 | access to local variable o2 : Object | semmle.label | access to local variable o2 : Object | +| Tuples.cs:10:29:10:30 | access to local variable o2 : Object | semmle.label | access to local variable o2 : Object | +| Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:11:9:11:23 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:11:9:11:27 | SSA def(a) : Object | semmle.label | SSA def(a) : Object | +| Tuples.cs:11:9:11:27 | SSA def(a) : Object | semmle.label | SSA def(a) : Object | +| Tuples.cs:11:9:11:27 | SSA def(c) : Object | semmle.label | SSA def(c) : Object | | Tuples.cs:11:9:11:27 | SSA def(c) : Object | semmle.label | SSA def(c) : Object | | Tuples.cs:12:14:12:14 | access to local variable a | semmle.label | access to local variable a | +| Tuples.cs:12:14:12:14 | access to local variable a | semmle.label | access to local variable a | +| Tuples.cs:14:14:14:14 | access to local variable c | semmle.label | access to local variable c | | Tuples.cs:14:14:14:14 | access to local variable c | semmle.label | access to local variable c | | Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:16:9:16:19 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | | Tuples.cs:16:9:16:23 | SSA def(a) : Object | semmle.label | SSA def(a) : Object | +| Tuples.cs:16:9:16:23 | SSA def(a) : Object | semmle.label | SSA def(a) : Object | +| Tuples.cs:16:9:16:23 | SSA def(c) : Object | semmle.label | SSA def(c) : Object | | Tuples.cs:16:9:16:23 | SSA def(c) : Object | semmle.label | SSA def(c) : Object | | Tuples.cs:16:13:16:18 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:16:13:16:18 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:17:14:17:14 | access to local variable a | semmle.label | access to local variable a | | Tuples.cs:17:14:17:14 | access to local variable a | semmle.label | access to local variable a | | Tuples.cs:19:14:19:14 | access to local variable c | semmle.label | access to local variable c | +| Tuples.cs:19:14:19:14 | access to local variable c | semmle.label | access to local variable c | +| Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | | Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | | Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:21:9:21:22 | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:21:9:21:26 | SSA def(p) : Object | semmle.label | SSA def(p) : Object | | Tuples.cs:21:9:21:26 | SSA def(p) : Object | semmle.label | SSA def(p) : Object | | Tuples.cs:21:9:21:26 | SSA def(q) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | SSA def(q) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:21:9:21:26 | SSA def(q) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | SSA def(q) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:22:14:22:14 | access to local variable p | semmle.label | access to local variable p | | Tuples.cs:22:14:22:14 | access to local variable p | semmle.label | access to local variable p | | Tuples.cs:24:14:24:14 | access to local variable q : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | access to local variable q : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:24:14:24:14 | access to local variable q : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | access to local variable q : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:24:14:24:20 | access to field Item2 | semmle.label | access to field Item2 | | Tuples.cs:24:14:24:20 | access to field Item2 | semmle.label | access to field Item2 | | Tuples.cs:26:14:26:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:26:14:26:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:26:14:26:20 | access to field Item1 | semmle.label | access to field Item1 | | Tuples.cs:26:14:26:20 | access to field Item1 | semmle.label | access to field Item1 | | Tuples.cs:27:14:27:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:27:14:27:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | semmle.label | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item1] : Object | +| Tuples.cs:27:14:27:16 | access to field Item1 | semmle.label | access to field Item1 | | Tuples.cs:27:14:27:16 | access to field Item1 | semmle.label | access to field Item1 | | Tuples.cs:29:14:29:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:29:14:29:14 | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | semmle.label | access to local variable x : ValueTuple<Object,ValueTuple<Int32,Object>> [field Item2, field Item2] : Object | +| Tuples.cs:29:14:29:20 | access to field Item2 : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | access to field Item2 : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:29:14:29:20 | access to field Item2 : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | access to field Item2 : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:29:14:29:26 | access to field Item2 | semmle.label | access to field Item2 | +| Tuples.cs:29:14:29:26 | access to field Item2 | semmle.label | access to field Item2 | +| Tuples.cs:34:18:34:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | Tuples.cs:34:18:34:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | | Tuples.cs:35:18:35:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| Tuples.cs:35:18:35:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | | Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | | Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | +| Tuples.cs:37:17:37:48 | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | +| Tuples.cs:37:18:37:19 | access to local variable o1 : Object | semmle.label | access to local variable o1 : Object | | Tuples.cs:37:18:37:19 | access to local variable o1 : Object | semmle.label | access to local variable o1 : Object | | Tuples.cs:37:46:37:47 | access to local variable o2 : Object | semmle.label | access to local variable o2 : Object | +| Tuples.cs:37:46:37:47 | access to local variable o2 : Object | semmle.label | access to local variable o2 : Object | +| Tuples.cs:38:14:38:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | semmle.label | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | | Tuples.cs:38:14:38:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | semmle.label | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item1] : Object | | Tuples.cs:38:14:38:20 | access to field Item1 | semmle.label | access to field Item1 | +| Tuples.cs:38:14:38:20 | access to field Item1 | semmle.label | access to field Item1 | +| Tuples.cs:40:14:40:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | semmle.label | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | | Tuples.cs:40:14:40:14 | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | semmle.label | access to local variable x : ValueTuple<Object,Int32,Int32,Int32,Int32,Int32,Int32,ValueTuple<Int32,Int32,Object>> [field Item10] : Object | | Tuples.cs:40:14:40:21 | access to field Item10 | semmle.label | access to field Item10 | +| Tuples.cs:40:14:40:21 | access to field Item10 | semmle.label | access to field Item10 | +| Tuples.cs:45:17:45:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String | | Tuples.cs:45:17:45:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String | | Tuples.cs:46:17:46:55 | (...) ... : ValueTuple<String,Int32,Int32> [field Item1] : String | semmle.label | (...) ... : ValueTuple<String,Int32,Int32> [field Item1] : String | +| Tuples.cs:46:17:46:55 | (...) ... : ValueTuple<String,Int32,Int32> [field Item1] : String | semmle.label | (...) ... : ValueTuple<String,Int32,Int32> [field Item1] : String | +| Tuples.cs:46:47:46:55 | (..., ...) : ValueTuple<String,Int32,Int32> [field Item1] : String | semmle.label | (..., ...) : ValueTuple<String,Int32,Int32> [field Item1] : String | | Tuples.cs:46:47:46:55 | (..., ...) : ValueTuple<String,Int32,Int32> [field Item1] : String | semmle.label | (..., ...) : ValueTuple<String,Int32,Int32> [field Item1] : String | | Tuples.cs:46:48:46:48 | access to local variable o : String | semmle.label | access to local variable o : String | +| Tuples.cs:46:48:46:48 | access to local variable o : String | semmle.label | access to local variable o : String | +| Tuples.cs:47:14:47:14 | access to local variable x : ValueTuple<String,Int32,Int32> [field Item1] : String | semmle.label | access to local variable x : ValueTuple<String,Int32,Int32> [field Item1] : String | | Tuples.cs:47:14:47:14 | access to local variable x : ValueTuple<String,Int32,Int32> [field Item1] : String | semmle.label | access to local variable x : ValueTuple<String,Int32,Int32> [field Item1] : String | | Tuples.cs:47:14:47:20 | access to field Item1 | semmle.label | access to field Item1 | +| Tuples.cs:47:14:47:20 | access to field Item1 | semmle.label | access to field Item1 | +| Tuples.cs:57:18:57:34 | call to method Source<String> : String | semmle.label | call to method Source<String> : String | | Tuples.cs:57:18:57:34 | call to method Source<String> : String | semmle.label | call to method Source<String> : String | | Tuples.cs:58:18:58:34 | call to method Source<String> : String | semmle.label | call to method Source<String> : String | +| Tuples.cs:58:18:58:34 | call to method Source<String> : String | semmle.label | call to method Source<String> : String | +| Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | | Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:59:17:59:32 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:59:18:59:19 | access to local variable o1 : String | semmle.label | access to local variable o1 : String | | Tuples.cs:59:18:59:19 | access to local variable o1 : String | semmle.label | access to local variable o1 : String | | Tuples.cs:59:22:59:28 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | semmle.label | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:59:22:59:28 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | semmle.label | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:59:26:59:27 | access to local variable o2 : String | semmle.label | access to local variable o2 : String | | Tuples.cs:59:26:59:27 | access to local variable o2 : String | semmle.label | access to local variable o2 : String | | Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:62:18:62:57 | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | SSA def(t) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:63:22:63:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:63:22:63:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:63:22:63:28 | access to field Item1 | semmle.label | access to field Item1 | | Tuples.cs:63:22:63:28 | access to field Item1 | semmle.label | access to field Item1 | | Tuples.cs:64:22:64:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:64:22:64:22 | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | access to local variable t : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:64:22:64:28 | access to field Item2 : ValueTuple<Int32,String> [field Item2] : String | semmle.label | access to field Item2 : ValueTuple<Int32,String> [field Item2] : String | | Tuples.cs:64:22:64:28 | access to field Item2 : ValueTuple<Int32,String> [field Item2] : String | semmle.label | access to field Item2 : ValueTuple<Int32,String> [field Item2] : String | | Tuples.cs:64:22:64:34 | access to field Item2 | semmle.label | access to field Item2 | +| Tuples.cs:64:22:64:34 | access to field Item2 | semmle.label | access to field Item2 | +| Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | semmle.label | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | semmle.label | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | +| Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:67:18:67:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | | Tuples.cs:67:23:67:23 | SSA def(a) : String | semmle.label | SSA def(a) : String | +| Tuples.cs:67:23:67:23 | SSA def(a) : String | semmle.label | SSA def(a) : String | +| Tuples.cs:67:30:67:30 | SSA def(c) : String | semmle.label | SSA def(c) : String | | Tuples.cs:67:30:67:30 | SSA def(c) : String | semmle.label | SSA def(c) : String | | Tuples.cs:68:22:68:22 | access to local variable a | semmle.label | access to local variable a | +| Tuples.cs:68:22:68:22 | access to local variable a | semmle.label | access to local variable a | +| Tuples.cs:69:22:69:22 | access to local variable c | semmle.label | access to local variable c | | Tuples.cs:69:22:69:22 | access to local variable c | semmle.label | access to local variable c | | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | semmle.label | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | semmle.label | (..., ...) : ValueTuple<Int32,String> [field Item2] : String | +| Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item1] : String | | Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:87:18:87:35 | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | semmle.label | (..., ...) : ValueTuple<String,ValueTuple<Int32,String>,Int32> [field Item2, field Item2] : String | +| Tuples.cs:87:23:87:23 | SSA def(p) : String | semmle.label | SSA def(p) : String | | Tuples.cs:87:23:87:23 | SSA def(p) : String | semmle.label | SSA def(p) : String | | Tuples.cs:87:30:87:30 | SSA def(r) : String | semmle.label | SSA def(r) : String | +| Tuples.cs:87:30:87:30 | SSA def(r) : String | semmle.label | SSA def(r) : String | +| Tuples.cs:89:18:89:18 | access to local variable p | semmle.label | access to local variable p | | Tuples.cs:89:18:89:18 | access to local variable p | semmle.label | access to local variable p | | Tuples.cs:90:18:90:18 | access to local variable r | semmle.label | access to local variable r | +| Tuples.cs:90:18:90:18 | access to local variable r | semmle.label | access to local variable r | +| Tuples.cs:99:17:99:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String | | Tuples.cs:99:17:99:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String | | Tuples.cs:100:17:100:28 | object creation of type R1 : R1 [property i] : String | semmle.label | object creation of type R1 : R1 [property i] : String | +| Tuples.cs:100:17:100:28 | object creation of type R1 : R1 [property i] : String | semmle.label | object creation of type R1 : R1 [property i] : String | +| Tuples.cs:100:24:100:24 | access to local variable o : String | semmle.label | access to local variable o : String | | Tuples.cs:100:24:100:24 | access to local variable o : String | semmle.label | access to local variable o : String | | Tuples.cs:101:14:101:14 | access to local variable r : R1 [property i] : String | semmle.label | access to local variable r : R1 [property i] : String | +| Tuples.cs:101:14:101:14 | access to local variable r : R1 [property i] : String | semmle.label | access to local variable r : R1 [property i] : String | +| Tuples.cs:101:14:101:16 | access to property i | semmle.label | access to property i | | Tuples.cs:101:14:101:16 | access to property i | semmle.label | access to property i | | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object | +| Tuples.cs:121:9:121:23 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | | Tuples.cs:121:9:121:23 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | | Tuples.cs:121:9:121:32 | SSA def(x1) : Object | semmle.label | SSA def(x1) : Object | +| Tuples.cs:121:9:121:32 | SSA def(x1) : Object | semmle.label | SSA def(x1) : Object | +| Tuples.cs:121:27:121:32 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | | Tuples.cs:121:27:121:32 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | | Tuples.cs:121:28:121:28 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| Tuples.cs:121:28:121:28 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| Tuples.cs:122:14:122:15 | access to local variable x1 | semmle.label | access to local variable x1 | | Tuples.cs:122:14:122:15 | access to local variable x1 | semmle.label | access to local variable x1 | | Tuples.cs:125:9:125:20 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | +| Tuples.cs:125:9:125:20 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | +| Tuples.cs:125:9:125:29 | SSA def(x2) : Object | semmle.label | SSA def(x2) : Object | | Tuples.cs:125:9:125:29 | SSA def(x2) : Object | semmle.label | SSA def(x2) : Object | | Tuples.cs:125:24:125:29 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | +| Tuples.cs:125:24:125:29 | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | semmle.label | (..., ...) : ValueTuple<Object,Int32> [field Item1] : Object | +| Tuples.cs:125:25:125:25 | access to local variable o : Object | semmle.label | access to local variable o : Object | | Tuples.cs:125:25:125:25 | access to local variable o : Object | semmle.label | access to local variable o : Object | | Tuples.cs:126:14:126:15 | access to local variable x2 | semmle.label | access to local variable x2 | +| Tuples.cs:126:14:126:15 | access to local variable x2 | semmle.label | access to local variable x2 | +| Tuples.cs:129:9:129:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:129:9:129:23 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:129:9:129:32 | SSA def(y3) : Object | semmle.label | SSA def(y3) : Object | +| Tuples.cs:129:9:129:32 | SSA def(y3) : Object | semmle.label | SSA def(y3) : Object | +| Tuples.cs:129:27:129:32 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:129:27:129:32 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:129:31:129:31 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| Tuples.cs:129:31:129:31 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| Tuples.cs:130:14:130:15 | access to local variable y3 | semmle.label | access to local variable y3 | | Tuples.cs:130:14:130:15 | access to local variable y3 | semmle.label | access to local variable y3 | | Tuples.cs:133:9:133:20 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:133:9:133:20 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:133:9:133:29 | SSA def(y4) : Object | semmle.label | SSA def(y4) : Object | | Tuples.cs:133:9:133:29 | SSA def(y4) : Object | semmle.label | SSA def(y4) : Object | | Tuples.cs:133:24:133:29 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | +| Tuples.cs:133:24:133:29 | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | semmle.label | (..., ...) : ValueTuple<Int32,Object> [field Item2] : Object | | Tuples.cs:133:28:133:28 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| Tuples.cs:133:28:133:28 | access to local variable o : Object | semmle.label | access to local variable o : Object | +| Tuples.cs:134:14:134:15 | access to local variable y4 | semmle.label | access to local variable y4 | | Tuples.cs:134:14:134:15 | access to local variable y4 | semmle.label | access to local variable y4 | subpaths #select | Tuples.cs:12:14:12:14 | access to local variable a | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:12:14:12:14 | access to local variable a | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:12:14:12:14 | access to local variable a | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:12:14:12:14 | access to local variable a | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:14:14:14:14 | access to local variable c | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:14:14:14:14 | access to local variable c | $@ | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:14:14:14:14 | access to local variable c | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:14:14:14:14 | access to local variable c | $@ | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:17:14:17:14 | access to local variable a | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:17:14:17:14 | access to local variable a | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:17:14:17:14 | access to local variable a | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:17:14:17:14 | access to local variable a | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:19:14:19:14 | access to local variable c | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:19:14:19:14 | access to local variable c | $@ | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:19:14:19:14 | access to local variable c | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:19:14:19:14 | access to local variable c | $@ | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:22:14:22:14 | access to local variable p | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:22:14:22:14 | access to local variable p | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:22:14:22:14 | access to local variable p | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:22:14:22:14 | access to local variable p | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:24:14:24:20 | access to field Item2 | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:24:14:24:20 | access to field Item2 | $@ | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:24:14:24:20 | access to field Item2 | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:24:14:24:20 | access to field Item2 | $@ | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:26:14:26:20 | access to field Item1 | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:26:14:26:20 | access to field Item1 | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:26:14:26:20 | access to field Item1 | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:26:14:26:20 | access to field Item1 | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:27:14:27:16 | access to field Item1 | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:27:14:27:16 | access to field Item1 | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:27:14:27:16 | access to field Item1 | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:27:14:27:16 | access to field Item1 | $@ | Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:29:14:29:26 | access to field Item2 | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:29:14:29:26 | access to field Item2 | $@ | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:29:14:29:26 | access to field Item2 | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:29:14:29:26 | access to field Item2 | $@ | Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:38:14:38:20 | access to field Item1 | Tuples.cs:34:18:34:34 | call to method Source<Object> : Object | Tuples.cs:38:14:38:20 | access to field Item1 | $@ | Tuples.cs:34:18:34:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:38:14:38:20 | access to field Item1 | Tuples.cs:34:18:34:34 | call to method Source<Object> : Object | Tuples.cs:38:14:38:20 | access to field Item1 | $@ | Tuples.cs:34:18:34:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:40:14:40:21 | access to field Item10 | Tuples.cs:35:18:35:34 | call to method Source<Object> : Object | Tuples.cs:40:14:40:21 | access to field Item10 | $@ | Tuples.cs:35:18:35:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:40:14:40:21 | access to field Item10 | Tuples.cs:35:18:35:34 | call to method Source<Object> : Object | Tuples.cs:40:14:40:21 | access to field Item10 | $@ | Tuples.cs:35:18:35:34 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:47:14:47:20 | access to field Item1 | Tuples.cs:45:17:45:33 | call to method Source<String> : String | Tuples.cs:47:14:47:20 | access to field Item1 | $@ | Tuples.cs:45:17:45:33 | call to method Source<String> : String | call to method Source<String> : String | | Tuples.cs:47:14:47:20 | access to field Item1 | Tuples.cs:45:17:45:33 | call to method Source<String> : String | Tuples.cs:47:14:47:20 | access to field Item1 | $@ | Tuples.cs:45:17:45:33 | call to method Source<String> : String | call to method Source<String> : String | | Tuples.cs:63:22:63:28 | access to field Item1 | Tuples.cs:57:18:57:34 | call to method Source<String> : String | Tuples.cs:63:22:63:28 | access to field Item1 | $@ | Tuples.cs:57:18:57:34 | call to method Source<String> : String | call to method Source<String> : String | +| Tuples.cs:63:22:63:28 | access to field Item1 | Tuples.cs:57:18:57:34 | call to method Source<String> : String | Tuples.cs:63:22:63:28 | access to field Item1 | $@ | Tuples.cs:57:18:57:34 | call to method Source<String> : String | call to method Source<String> : String | +| Tuples.cs:64:22:64:34 | access to field Item2 | Tuples.cs:58:18:58:34 | call to method Source<String> : String | Tuples.cs:64:22:64:34 | access to field Item2 | $@ | Tuples.cs:58:18:58:34 | call to method Source<String> : String | call to method Source<String> : String | | Tuples.cs:64:22:64:34 | access to field Item2 | Tuples.cs:58:18:58:34 | call to method Source<String> : String | Tuples.cs:64:22:64:34 | access to field Item2 | $@ | Tuples.cs:58:18:58:34 | call to method Source<String> : String | call to method Source<String> : String | | Tuples.cs:68:22:68:22 | access to local variable a | Tuples.cs:57:18:57:34 | call to method Source<String> : String | Tuples.cs:68:22:68:22 | access to local variable a | $@ | Tuples.cs:57:18:57:34 | call to method Source<String> : String | call to method Source<String> : String | +| Tuples.cs:68:22:68:22 | access to local variable a | Tuples.cs:57:18:57:34 | call to method Source<String> : String | Tuples.cs:68:22:68:22 | access to local variable a | $@ | Tuples.cs:57:18:57:34 | call to method Source<String> : String | call to method Source<String> : String | +| Tuples.cs:69:22:69:22 | access to local variable c | Tuples.cs:58:18:58:34 | call to method Source<String> : String | Tuples.cs:69:22:69:22 | access to local variable c | $@ | Tuples.cs:58:18:58:34 | call to method Source<String> : String | call to method Source<String> : String | | Tuples.cs:69:22:69:22 | access to local variable c | Tuples.cs:58:18:58:34 | call to method Source<String> : String | Tuples.cs:69:22:69:22 | access to local variable c | $@ | Tuples.cs:58:18:58:34 | call to method Source<String> : String | call to method Source<String> : String | | Tuples.cs:89:18:89:18 | access to local variable p | Tuples.cs:57:18:57:34 | call to method Source<String> : String | Tuples.cs:89:18:89:18 | access to local variable p | $@ | Tuples.cs:57:18:57:34 | call to method Source<String> : String | call to method Source<String> : String | +| Tuples.cs:89:18:89:18 | access to local variable p | Tuples.cs:57:18:57:34 | call to method Source<String> : String | Tuples.cs:89:18:89:18 | access to local variable p | $@ | Tuples.cs:57:18:57:34 | call to method Source<String> : String | call to method Source<String> : String | +| Tuples.cs:90:18:90:18 | access to local variable r | Tuples.cs:58:18:58:34 | call to method Source<String> : String | Tuples.cs:90:18:90:18 | access to local variable r | $@ | Tuples.cs:58:18:58:34 | call to method Source<String> : String | call to method Source<String> : String | | Tuples.cs:90:18:90:18 | access to local variable r | Tuples.cs:58:18:58:34 | call to method Source<String> : String | Tuples.cs:90:18:90:18 | access to local variable r | $@ | Tuples.cs:58:18:58:34 | call to method Source<String> : String | call to method Source<String> : String | | Tuples.cs:101:14:101:16 | access to property i | Tuples.cs:99:17:99:33 | call to method Source<String> : String | Tuples.cs:101:14:101:16 | access to property i | $@ | Tuples.cs:99:17:99:33 | call to method Source<String> : String | call to method Source<String> : String | +| Tuples.cs:101:14:101:16 | access to property i | Tuples.cs:99:17:99:33 | call to method Source<String> : String | Tuples.cs:101:14:101:16 | access to property i | $@ | Tuples.cs:99:17:99:33 | call to method Source<String> : String | call to method Source<String> : String | +| Tuples.cs:122:14:122:15 | access to local variable x1 | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:122:14:122:15 | access to local variable x1 | $@ | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:122:14:122:15 | access to local variable x1 | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:122:14:122:15 | access to local variable x1 | $@ | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:126:14:126:15 | access to local variable x2 | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:126:14:126:15 | access to local variable x2 | $@ | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:126:14:126:15 | access to local variable x2 | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:126:14:126:15 | access to local variable x2 | $@ | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:130:14:130:15 | access to local variable y3 | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:130:14:130:15 | access to local variable y3 | $@ | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:130:14:130:15 | access to local variable y3 | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:130:14:130:15 | access to local variable y3 | $@ | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | | Tuples.cs:134:14:134:15 | access to local variable y4 | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:134:14:134:15 | access to local variable y4 | $@ | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | +| Tuples.cs:134:14:134:15 | access to local variable y4 | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | Tuples.cs:134:14:134:15 | access to local variable y4 | $@ | Tuples.cs:118:17:118:33 | call to method Source<Object> : Object | call to method Source<Object> : Object | diff --git a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql index 39395ad831b..9336e1b28be 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql +++ b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql @@ -5,8 +5,8 @@ import csharp import TestUtilities.InlineFlowTest import DefaultFlowTest -import ValueFlow::PathGraph +import PathGraph -from ValueFlow::PathNode source, ValueFlow::PathNode sink -where ValueFlow::flowPath(source, sink) +from PathNode source, PathNode sink +where flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() From bc42308bd3c824554beb349c92819dc124cd182f Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 19 Jun 2023 10:31:49 +0200 Subject: [PATCH 654/739] Java: fix formatting --- java/ql/test/TestUtilities/InlineFlowTest.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/test/TestUtilities/InlineFlowTest.qll b/java/ql/test/TestUtilities/InlineFlowTest.qll index 45ba10ee149..34d7f75ee20 100644 --- a/java/ql/test/TestUtilities/InlineFlowTest.qll +++ b/java/ql/test/TestUtilities/InlineFlowTest.qll @@ -11,7 +11,6 @@ * from PathNode source, PathNode sink * where flowPath(source, sink) * select sink, source, sink, "$@", source, source.toString() - * ``` * * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files. From 1f538cced3a19bdc6a6db5a1128c9897761de9fb Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Fri, 16 Jun 2023 13:33:41 +0100 Subject: [PATCH 655/739] Kotlin: Handle IrSyntheticBodyKind.ENUM_ENTRIES Generated by Kotlin 1.9 for some of our tests. --- .../src/main/kotlin/KotlinFileExtractor.kt | 11 ++++++----- .../utils/versions/v_1_4_32/SyntheticBodyKind.kt | 6 ++++++ .../utils/versions/v_1_8_0/SyntheticBodyKind.kt | 6 ++++++ java/ql/lib/config/semmlecode.dbscheme | 1 + 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/SyntheticBodyKind.kt create mode 100644 java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/SyntheticBodyKind.kt diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index c471662e631..b31452c888a 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -1701,12 +1701,13 @@ open class KotlinFileExtractor( private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label<out DbCallable>) { with("synthetic body", b) { - when (b.kind) { - IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1) - IrSyntheticBodyKind.ENUM_VALUEOF -> tw.writeKtSyntheticBody(callable, 2) + val kind = b.kind + when { + kind == IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1) + kind == IrSyntheticBodyKind.ENUM_VALUEOF -> tw.writeKtSyntheticBody(callable, 2) + kind == kind_ENUM_ENTRIES -> tw.writeKtSyntheticBody(callable, 3) else -> { - // TODO: Support IrSyntheticBodyKind.ENUM_ENTRIES - logger.errorElement("Unhandled synthetic body kind " + b.kind.javaClass, b) + logger.errorElement("Unhandled synthetic body kind " + kind, b) } } } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/SyntheticBodyKind.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/SyntheticBodyKind.kt new file mode 100644 index 00000000000..fd3fc1f8e20 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/SyntheticBodyKind.kt @@ -0,0 +1,6 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind + +val kind_ENUM_ENTRIES: IrSyntheticBodyKind? = null + diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/SyntheticBodyKind.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/SyntheticBodyKind.kt new file mode 100644 index 00000000000..d0dbb5b1247 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/SyntheticBodyKind.kt @@ -0,0 +1,6 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind + +val kind_ENUM_ENTRIES: IrSyntheticBodyKind? = IrSyntheticBodyKind.ENUM_ENTRIES + diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index 7cbc85b1f3e..ecfcf050952 100644 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -1219,6 +1219,7 @@ ktSyntheticBody( int kind: int ref // 1: ENUM_VALUES // 2: ENUM_VALUEOF + // 3: ENUM_ENTRIES ) ktLocalFunction( From ca5bc6f224b63d807cbded524a2fce94f41f59cc Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Fri, 16 Jun 2023 13:36:31 +0100 Subject: [PATCH 656/739] Java: Add up/downgrade scripts --- .../old.dbscheme | 1256 +++++++++++++++++ .../semmlecode.dbscheme | 1255 ++++++++++++++++ .../upgrade.properties | 2 + .../old.dbscheme | 1255 ++++++++++++++++ .../semmlecode.dbscheme | 1256 +++++++++++++++++ .../upgrade.properties | 2 + 6 files changed, 5026 insertions(+) create mode 100644 java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/old.dbscheme create mode 100644 java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/semmlecode.dbscheme create mode 100644 java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/upgrade.properties create mode 100644 java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme create mode 100644 java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme create mode 100644 java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties diff --git a/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/old.dbscheme b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/old.dbscheme new file mode 100644 index 00000000000..ecfcf050952 --- /dev/null +++ b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/old.dbscheme @@ -0,0 +1,1256 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF + // 3: ENUM_ENTRIES +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/semmlecode.dbscheme b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/semmlecode.dbscheme new file mode 100644 index 00000000000..7cbc85b1f3e --- /dev/null +++ b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/semmlecode.dbscheme @@ -0,0 +1,1255 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/upgrade.properties b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/upgrade.properties new file mode 100644 index 00000000000..5ba64f71d70 --- /dev/null +++ b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/upgrade.properties @@ -0,0 +1,2 @@ +description: Remove ENUM_ENTRIES +compatibility: full diff --git a/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme new file mode 100644 index 00000000000..7cbc85b1f3e --- /dev/null +++ b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme @@ -0,0 +1,1255 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme new file mode 100644 index 00000000000..ecfcf050952 --- /dev/null +++ b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme @@ -0,0 +1,1256 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF + // 3: ENUM_ENTRIES +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties new file mode 100644 index 00000000000..47074bcc8ab --- /dev/null +++ b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties @@ -0,0 +1,2 @@ +description: Add ENUM_ENTRIES +compatibility: full From 861ac177b828604ad56b3a81b24137e932e918f3 Mon Sep 17 00:00:00 2001 From: Mathew Payne <2772944+GeekMasher@users.noreply.github.com> Date: Mon, 19 Jun 2023 12:03:38 +0100 Subject: [PATCH 657/739] Update csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com> --- .../code/csharp/security/dataflow/CommandInjectionQuery.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll index 7572d696459..90615faac9f 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll @@ -67,7 +67,7 @@ module CommandInjection = TaintTracking::Global<CommandInjectionConfig>; /** A source of remote user input. */ class RemoteSource extends Source instanceof RemoteFlowSource { } -/** Command Injection sinks defined through CSV models. */ +/** Command Injection sinks defined through Models as Data. */ private class ExternalCommandInjectionExprSink extends Sink { ExternalCommandInjectionExprSink() { sinkNode(this, "command-injection") } } From 45972105193f78aed9d56a5f279bb2d9ee253b47 Mon Sep 17 00:00:00 2001 From: Mathew Payne <2772944+GeekMasher@users.noreply.github.com> Date: Mon, 19 Jun 2023 12:03:46 +0100 Subject: [PATCH 658/739] Update csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com> --- csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 22335fb0dce..6805189d2d7 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -214,7 +214,7 @@ module ModelValidation { not kind = [ "code-injection", "command-injection", "file-content-store", "html-injection", - "ldap-injection", "log-injection", "remote", "sql-injection", "url-redirection", + "ldap-injection", "log-injection", "sql-injection", "url-redirection", "js-injection", ] and not kind.matches("encryption-%") and From a6a86acd9a509f26efcec18bf132e603a9640f0d Mon Sep 17 00:00:00 2001 From: Mathew Payne <geekmasher@gmail.com> Date: Mon, 19 Jun 2023 12:44:01 +0100 Subject: [PATCH 659/739] Fix formatting for ExternalFlow --- csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 6805189d2d7..7a0cc01f7fa 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -214,8 +214,7 @@ module ModelValidation { not kind = [ "code-injection", "command-injection", "file-content-store", "html-injection", - "ldap-injection", "log-injection", "sql-injection", "url-redirection", - "js-injection", + "ldap-injection", "log-injection", "sql-injection", "url-redirection", "js-injection", ] and not kind.matches("encryption-%") and result = "Invalid kind \"" + kind + "\" in sink model." From 00fe8adc092cad90f15ec9eca105fe09f8157e0e Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 19 Jun 2023 15:04:33 +0200 Subject: [PATCH 660/739] Fix name clash --- .../lib/semmle/code/java/security/SensitiveLoggingQuery.qll | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll index 984c9f6fcaa..eb40a045c1f 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll @@ -5,7 +5,6 @@ private import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.SensitiveActions import semmle.code.java.frameworks.android.Compose -import DataFlow /** A variable that may hold sensitive information, judging by its name. */ class CredentialExpr extends Expr { @@ -45,7 +44,7 @@ deprecated class SensitiveLoggerConfiguration extends TaintTracking::Configurati sanitizer.getType() instanceof TypeType } - override predicate isSanitizerIn(Node node) { this.isSource(node) } + override predicate isSanitizerIn(DataFlow::Node node) { this.isSource(node) } } /** A data-flow configuration for identifying potentially-sensitive data flowing to a log output. */ @@ -62,7 +61,7 @@ module SensitiveLoggerConfig implements DataFlow::ConfigSig { sanitizer.getType() instanceof TypeType } - predicate isBarrierIn(Node node) { isSource(node) } + predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } module SensitiveLoggerFlow = TaintTracking::Global<SensitiveLoggerConfig>; From 3ff71481479774097e13935c19ef4d0ae7975985 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Mon, 19 Jun 2023 15:29:45 +0200 Subject: [PATCH 661/739] Swift: remove `std::result_of` from swift headers `std::result_of` was removed in C++20, though the actual removal from the STL library implementations seems to depend on the version. For example using xcode 14.2 one gets away with a deprecation warning, but xcode 14.3 will fail. As Swift 5.8.1 is still compiled with C++14, we cannot replace `std::result_of` with `std::invoke_result` in the prebuilding patches just yet, but we can do that for the extractor itself, patching the prebuilt package. --- swift/third_party/load.bzl | 2 ++ .../patches/remove-result-of.patch | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 swift/third_party/swift-llvm-support/patches/remove-result-of.patch diff --git a/swift/third_party/load.bzl b/swift/third_party/load.bzl index df21ba1a894..7a3af979577 100644 --- a/swift/third_party/load.bzl +++ b/swift/third_party/load.bzl @@ -39,6 +39,8 @@ def load_dependencies(workspace_name): ), build_file = _build(workspace_name, "swift-llvm-support"), sha256 = sha256, + patch_args = ["-p1"], + patches = ["@%s//swift/third_party/swift-llvm-support:patches/remove-result-of.patch" % workspace_name], ) _github_archive( diff --git a/swift/third_party/swift-llvm-support/patches/remove-result-of.patch b/swift/third_party/swift-llvm-support/patches/remove-result-of.patch new file mode 100644 index 00000000000..ab3f2155b67 --- /dev/null +++ b/swift/third_party/swift-llvm-support/patches/remove-result-of.patch @@ -0,0 +1,30 @@ +`std::result_of` was removed in C++20, but is still used in the Swift headers. We can't +remove it from there before prebuilding, as that is still done with C++14, but we can +replace it with `std::invoke_result` for compiling the extractor. + +diff --git a/include/swift/Basic/RelativePointer.h b/include/swift/Basic/RelativePointer.h +index 73f91262afa..bdaa304c804 100644 +--- a/include/swift/Basic/RelativePointer.h ++++ b/include/swift/Basic/RelativePointer.h +@@ -551,7 +551,7 @@ public: + } + + template <typename... ArgTy> +- typename std::result_of<T *(ArgTy...)>::type operator()(ArgTy... arg) const { ++ typename std::invoke_result<T*, ArgTy...>::type operator()(ArgTy... arg) const { + #if SWIFT_PTRAUTH + void *ptr = this->super::getWithoutCast(); + return reinterpret_cast<T *>(ptrauth_sign_unauthenticated( +diff --git a/include/swift/Basic/STLExtras.h b/include/swift/Basic/STLExtras.h +index 7fa3d0c8890..6bc891a9b63 100644 +--- a/include/swift/Basic/STLExtras.h ++++ b/include/swift/Basic/STLExtras.h +@@ -405,7 +405,7 @@ class OptionalTransformIterator { + typename std::iterator_traits<Iterator>::reference; + + using ResultReference = +- typename std::result_of<OptionalTransform(UnderlyingReference)>::type; ++ typename std::invoke_result<OptionalTransform, UnderlyingReference>::type; + + public: + /// Used to indicate when the current iterator has already been From 592e7f0b56a312c4f73836f7180e6ca3540cd7de Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Mon, 19 Jun 2023 15:52:16 +0200 Subject: [PATCH 662/739] Swift: add TODO for later swift updates --- swift/third_party/load.bzl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/swift/third_party/load.bzl b/swift/third_party/load.bzl index 7a3af979577..545ac2b4b95 100644 --- a/swift/third_party/load.bzl +++ b/swift/third_party/load.bzl @@ -1,6 +1,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") +# TODO: remove `remove-result-of.patch` once we update to a Swift version containing +# https://github.com/apple/swift/commit/2ed2cea2 +# (probably when updating to 5.9) _swift_prebuilt_version = "swift-5.8.1-RELEASE.208" _swift_sha_map = { "Linux-X64": "1d93286d6219e5c5746938ab9287d90efea98039f022cb1433296ccbc1684bc0", From f90586bc900e429a0743666432094fde5d320403 Mon Sep 17 00:00:00 2001 From: Henry Mercer <henrymercer@github.com> Date: Mon, 19 Jun 2023 17:35:26 +0100 Subject: [PATCH 663/739] Bump Swift pack versions --- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index f45d347bad3..b2e94cc2667 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.1.0 +version: 0.1.1-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 2a0bee06578..006dd98fdfb 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.1.0 +version: 0.1.1-dev groups: - swift - queries From ead79c98d8408e5c35467dfb288280b8ea25b192 Mon Sep 17 00:00:00 2001 From: Henry Mercer <henrymercer@github.com> Date: Mon, 19 Jun 2023 17:35:58 +0100 Subject: [PATCH 664/739] Run `pack release` for Swift packs --- swift/ql/lib/CHANGELOG.md | 13 +++++++++++++ .../change-notes/2023-05-25-dataprotocol-models.md | 4 ---- .../2023-05-25-fix-ast-and-cfg-inconsistencies.md | 5 ----- .../lib/change-notes/2023-05-30-shared-sensitive.md | 4 ---- swift/ql/lib/change-notes/released/0.1.1.md | 13 +++++++++++++ swift/ql/lib/codeql-pack.release.yml | 2 ++ swift/ql/lib/qlpack.yml | 2 +- ...-string-length-conflation-fp.md => CHANGELOG.md} | 7 ++++--- swift/ql/src/change-notes/released/0.1.1.md | 5 +++++ swift/ql/src/codeql-pack.release.yml | 2 ++ swift/ql/src/qlpack.yml | 2 +- 11 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 swift/ql/lib/CHANGELOG.md delete mode 100644 swift/ql/lib/change-notes/2023-05-25-dataprotocol-models.md delete mode 100644 swift/ql/lib/change-notes/2023-05-25-fix-ast-and-cfg-inconsistencies.md delete mode 100644 swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md create mode 100644 swift/ql/lib/change-notes/released/0.1.1.md create mode 100644 swift/ql/lib/codeql-pack.release.yml rename swift/ql/src/{change-notes/2023-05-25-string-length-conflation-fp.md => CHANGELOG.md} (72%) create mode 100644 swift/ql/src/change-notes/released/0.1.1.md create mode 100644 swift/ql/src/codeql-pack.release.yml diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md new file mode 100644 index 00000000000..572ca004c63 --- /dev/null +++ b/swift/ql/lib/CHANGELOG.md @@ -0,0 +1,13 @@ +## 0.1.1 + +### Major Analysis Improvements + +* Incorporated the cross-language `SensitiveDataHeuristics.qll` heuristics library into the Swift `SensitiveExprs.qll` library. This adds a number of new heuristics enhancing detection from the library. + +### Minor Analysis Improvements + +* Some models for the `Data` class have been generalized to `DataProtocol` so that they apply more widely. + +### Bug Fixes + +* Fixed a number of inconsistencies in the abstract syntax tree (AST) and in the control-flow graph (CFG). This may lead to more results in queries that use these libraries, or libraries that depend on them (such as dataflow). diff --git a/swift/ql/lib/change-notes/2023-05-25-dataprotocol-models.md b/swift/ql/lib/change-notes/2023-05-25-dataprotocol-models.md deleted file mode 100644 index 6e26484f5dc..00000000000 --- a/swift/ql/lib/change-notes/2023-05-25-dataprotocol-models.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Some models for the `Data` class have been generalized to `DataProtocol` so that they apply more widely. \ No newline at end of file diff --git a/swift/ql/lib/change-notes/2023-05-25-fix-ast-and-cfg-inconsistencies.md b/swift/ql/lib/change-notes/2023-05-25-fix-ast-and-cfg-inconsistencies.md deleted file mode 100644 index 208486b8f27..00000000000 --- a/swift/ql/lib/change-notes/2023-05-25-fix-ast-and-cfg-inconsistencies.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: fix ---- - -* Fixed a number of inconsistencies in the abstract syntax tree (AST) and in the control-flow graph (CFG). This may lead to more results in queries that use these libraries, or libraries that depend on them (such as dataflow). diff --git a/swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md b/swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md deleted file mode 100644 index 03de16f4269..00000000000 --- a/swift/ql/lib/change-notes/2023-05-30-shared-sensitive.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Incorporated the cross-language `SensitiveDataHeuristics.qll` heuristics library into the Swift `SensitiveExprs.qll` library. This adds a number of new heuristics enhancing detection from the library. \ No newline at end of file diff --git a/swift/ql/lib/change-notes/released/0.1.1.md b/swift/ql/lib/change-notes/released/0.1.1.md new file mode 100644 index 00000000000..572ca004c63 --- /dev/null +++ b/swift/ql/lib/change-notes/released/0.1.1.md @@ -0,0 +1,13 @@ +## 0.1.1 + +### Major Analysis Improvements + +* Incorporated the cross-language `SensitiveDataHeuristics.qll` heuristics library into the Swift `SensitiveExprs.qll` library. This adds a number of new heuristics enhancing detection from the library. + +### Minor Analysis Improvements + +* Some models for the `Data` class have been generalized to `DataProtocol` so that they apply more widely. + +### Bug Fixes + +* Fixed a number of inconsistencies in the abstract syntax tree (AST) and in the control-flow graph (CFG). This may lead to more results in queries that use these libraries, or libraries that depend on them (such as dataflow). diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml new file mode 100644 index 00000000000..92d1505475f --- /dev/null +++ b/swift/ql/lib/codeql-pack.release.yml @@ -0,0 +1,2 @@ +--- +lastReleaseVersion: 0.1.1 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index b2e94cc2667..5993dfaefcf 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.1.1-dev +version: 0.1.1 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md b/swift/ql/src/CHANGELOG.md similarity index 72% rename from swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md rename to swift/ql/src/CHANGELOG.md index 7166b5e9ed7..a682b626bb8 100644 --- a/swift/ql/src/change-notes/2023-05-25-string-length-conflation-fp.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.1.1 + +### Minor Analysis Improvements + * Fixed some false positive results from the `swift/string-length-conflation` query, caused by imprecise sinks. diff --git a/swift/ql/src/change-notes/released/0.1.1.md b/swift/ql/src/change-notes/released/0.1.1.md new file mode 100644 index 00000000000..a682b626bb8 --- /dev/null +++ b/swift/ql/src/change-notes/released/0.1.1.md @@ -0,0 +1,5 @@ +## 0.1.1 + +### Minor Analysis Improvements + +* Fixed some false positive results from the `swift/string-length-conflation` query, caused by imprecise sinks. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml new file mode 100644 index 00000000000..92d1505475f --- /dev/null +++ b/swift/ql/src/codeql-pack.release.yml @@ -0,0 +1,2 @@ +--- +lastReleaseVersion: 0.1.1 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 006dd98fdfb..3393d61d8d6 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.1.1-dev +version: 0.1.1 groups: - swift - queries From eb28266bcb93c065ad252c9c2c4cdffa39176d2b Mon Sep 17 00:00:00 2001 From: Adrien Pessu <7055334+adrienpessu@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:00:52 +0000 Subject: [PATCH 665/739] improv example the help file --- .../CWE-798/HardcodedCredentials.qhelp | 14 ++++++++++++++ .../HardcodedCredentialsHttpRequest.js | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp index 3fd37c3245a..9f6fb3ddfa0 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp @@ -21,6 +21,20 @@ </p> </recommendation> +<example> + <p> + The following code example connects to an HTTP request using an hard-codes authentication header + </p> + + <sample src="examples/HardcodedCredentialsHttpRequest.js"/> + + <p> + Instead, user name and password can be supplied through the environment variables + <code>username</code> and <code>password</code>, which can be set externally without hard-coding + credentials in the source code. + </p> +</example> + <example> <p> The following code example connects to a Postgres database using the <code>pg</code> package diff --git a/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js new file mode 100644 index 00000000000..5890475085d --- /dev/null +++ b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js @@ -0,0 +1,18 @@ +let base64 = require('base-64'); + +let url = 'http://example.org/auth'; +let username = 'user'; +let password = 'passwd'; + +let headers = new Headers(); + +//headers.append('Content-Type', 'text/json'); +headers.append('Authorization', 'Basic' + base64.encode(username + ":" + password)); + +fetch(url, {method:'GET', + headers: headers, + //credentials: 'user:passwd' + }) +.then(response => response.json()) +.then(json => console.log(json)); +//.done(); From 5fdfd98a1df19ca675d9e7cf7fce79d88e5042f5 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 14 Jun 2023 17:07:30 +0200 Subject: [PATCH 666/739] delete the deprecated Conatiner::getURL predicates --- cpp/ql/lib/semmle/code/cpp/File.qll | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll index b2e4e0a41a5..bac9b66965e 100644 --- a/cpp/ql/lib/semmle/code/cpp/File.qll +++ b/cpp/ql/lib/semmle/code/cpp/File.qll @@ -34,14 +34,6 @@ class Container extends Locatable, @container { */ string getAbsolutePath() { none() } // overridden by subclasses - /** - * DEPRECATED: Use `getLocation` instead. - * Gets a URL representing the location of this container. - * - * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls). - */ - deprecated string getURL() { none() } // overridden by subclasses - /** * Gets the relative path of this file or folder from the root folder of the * analyzed source location. The relative path of the root folder itself is @@ -183,12 +175,6 @@ class Folder extends Container, @folder { } override string getAPrimaryQlClass() { result = "Folder" } - - /** - * DEPRECATED: Use `getLocation` instead. - * Gets the URL of this folder. - */ - deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } } /** @@ -213,12 +199,6 @@ class File extends Container, @file { result.hasLocationInfo(_, 0, 0, 0, 0) } - /** - * DEPRECATED: Use `getLocation` instead. - * Gets the URL of this file. - */ - deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } - /** Holds if this file was compiled as C (at any point). */ predicate compiledAsC() { fileannotations(underlyingElement(this), 1, "compiled as c", "1") } From 2104507cec243edda061237744c79c64ec470b0e Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Mon, 19 Jun 2023 13:56:41 +0200 Subject: [PATCH 667/739] add change-note --- cpp/ql/lib/change-notes/2023-06-19-delete-container-url.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2023-06-19-delete-container-url.md diff --git a/cpp/ql/lib/change-notes/2023-06-19-delete-container-url.md b/cpp/ql/lib/change-notes/2023-06-19-delete-container-url.md new file mode 100644 index 00000000000..9fef359a1e8 --- /dev/null +++ b/cpp/ql/lib/change-notes/2023-06-19-delete-container-url.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Deleted the deprecated `getURL` predicate from the `Container`, `Folder`, and `File` classes. Use the `getLocation` predicate instead. \ No newline at end of file From 6da5ec81964b3dd13cc16851c19a3dc09f6bd129 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:15:43 +0000 Subject: [PATCH 668/739] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 2 +- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index abe364cb2b8..540f282f7c5 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -136,7 +136,7 @@ org.jenkins.ui.icon,,,42,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41,1 org.jenkins.ui.symbol,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,8 org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,, org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.kohsuke.stapler,3,,343,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,1,,,,,,332,11 +org.kohsuke.stapler,20,24,343,,,,,,,2,,,,,,,,,,9,,,,,,,,,4,,,,5,,,,,24,332,11 org.mvel2,16,,,,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,, org.openjdk.jmh.runner.options,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, org.scijava.log,13,,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index ebcd040ceb8..dcf4eb2704d 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -22,6 +22,6 @@ Java framework & library support Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,115,4,,28,14,,35 - Others,"``antlr``, ``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",102,4467,554,81,4,18,18,,197 - Totals,,259,12766,2023,278,14,122,33,1,387 + Others,"``antlr``, ``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",126,4467,571,89,6,18,18,,200 + Totals,,283,12766,2040,286,16,122,33,1,390 From 6848cba68532446865ef25f6d1d1a19ec3735d65 Mon Sep 17 00:00:00 2001 From: Philip Ginsbach <ginsbach@github.com> Date: Tue, 20 Jun 2023 08:56:58 +0100 Subject: [PATCH 669/739] use more consistent terminology --- .../ql-language-specification.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index a1b5eb0068d..c4048236251 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -286,8 +286,8 @@ Instantiation-relative and instantiation-nested entities Given an *instantiated module*, every entity has a corresponding entity called the *instantiation-relative* entity, which is determined as follows: -- If the entity is the *underlying module*, its *instantiation-relative entity* is the *instantiated module*. -- If the entity is a parameter of the *underlying module*, its *instantiation-relative entity* is the corresponding argument. +- If the entity is the *underlying module*, its *instantiation-relative* entity is the *instantiated module*. +- If the entity is a parameter of the *underlying module*, its *instantiation-relative* entity is the corresponding argument. - If the entity is declared inside the *underlying module* or its nested modules, its *instantiation-relative* entity is an *instantiation-nested* entity that is generated by the module instantiation. Parameters of any modules that are nested inside the *underlying module* are considered declared inside the module for this purpose. - Otherwise, the entity's *instantiation-relative* entity is the initial entity itself. @@ -318,12 +318,12 @@ Every *completely uninstantiated* entity has a *relevant set of parameters*, whi Note that the *relevant set of parameters* by construction contains only *completely uninstantiated* parameters. -For a *completely uninstantiated* parameter, the *bottom-up instantiation-resolved* parameter relative to an entity is defined as: +For a *completely uninstantiated* parameter, the *bottom-up instantiation-resolution* relative to an entity is defined as: -- If the entity is an *instantiated module* or an *instantiation-nested* entity, the *bottom-up instantiation-resolved* parameter is the *instantiation-relative* parameter of the *bottom-up instantiation-resolved* parameter relative to the *underlying module*. -- Otherwise, the *bottom-up instantiation-resolved* parameter is the parameter itself. +- If the entity is an *instantiated module* or an *instantiation-nested* entity, the *bottom-up instantiation-resolution* is the *instantiation-relative* entity of the *bottom-up instantiation-resolution* relative to the *underlying module*. +- Otherwise, the *bottom-up instantiation-resolution* is the parameter itself. -Two *instantiated modules* or two *instantiation-nested* entities are considered *equivalent* if they have the same *underlying completely uninstantiated* entity and each parameter in its *relevant set of parameters* has the same *bottom-up instantiation-resolved* parameter relative to either *instantiated module*. +Two *instantiated modules* or two *instantiation-nested* entities are considered *equivalent* if they have the same *underlying completely uninstantiated* entity and each parameter in its *relevant set of parameters* has the same *bottom-up instantiation-resolution* relative to either *instantiated module*. Module instantiation is applicative, meaning that *equivalent* *instantiated modules* and *equivalent* *instantiation-nested* entities are indistinguishable. From 0c4eb6892163c43f576083b71bdfb5cd3b48b6bd Mon Sep 17 00:00:00 2001 From: Philip Ginsbach <ginsbach@github.com> Date: Tue, 20 Jun 2023 08:59:18 +0100 Subject: [PATCH 670/739] introduce concept of fully instantiated entity --- .../ql-language-reference/ql-language-specification.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index c4048236251..32244023c21 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -323,6 +323,8 @@ For a *completely uninstantiated* parameter, the *bottom-up instantiation-resolu - If the entity is an *instantiated module* or an *instantiation-nested* entity, the *bottom-up instantiation-resolution* is the *instantiation-relative* entity of the *bottom-up instantiation-resolution* relative to the *underlying module*. - Otherwise, the *bottom-up instantiation-resolution* is the parameter itself. +An entity is called *fully instantiated* if none of the *bottom-up instantiation-resolutions* of the parameters in the *relevant set of parameters* of the entity's *underlying completely uninstantiated* entity are parameters. + Two *instantiated modules* or two *instantiation-nested* entities are considered *equivalent* if they have the same *underlying completely uninstantiated* entity and each parameter in its *relevant set of parameters* has the same *bottom-up instantiation-resolution* relative to either *instantiated module*. Module instantiation is applicative, meaning that *equivalent* *instantiated modules* and *equivalent* *instantiation-nested* entities are indistinguishable. @@ -2040,7 +2042,7 @@ Stratification A QL program can be *stratified* to a sequence of *layers*. A layer is a set of predicates and types. -A valid stratification must include each predicate and type in the QL program. It must not include any other predicates or types. +A valid stratification must include each predicate and type in the QL program that is *fully instantiated*. It must not include any other predicates or types. A valid stratification must not include the same predicate in multiple layers. From 890a67d2eef1e700e2967015d5b824c5265831ea Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 15 Jun 2023 16:44:29 +0200 Subject: [PATCH 671/739] Introduce modules to merge 3, 4, and 5 inline expectation tests --- .../util/test/InlineExpectationsTest.qll | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/shared/util/codeql/util/test/InlineExpectationsTest.qll b/shared/util/codeql/util/test/InlineExpectationsTest.qll index 7d3806cb4b5..83c6a851f7d 100644 --- a/shared/util/codeql/util/test/InlineExpectationsTest.qll +++ b/shared/util/codeql/util/test/InlineExpectationsTest.qll @@ -396,6 +396,63 @@ module Make<InlineExpectationsTestSig Impl> { } } + /** + * A module that merges three test signatures. + */ + module MergeTests3<TestSig TestImpl1, TestSig TestImpl2, TestSig TestImpl3> implements TestSig { + private module M = MergeTests<MergeTests<TestImpl1, TestImpl2>, TestImpl3>; + + string getARelevantTag() { result = M::getARelevantTag() } + + predicate hasActualResult(Impl::Location location, string element, string tag, string value) { + M::hasActualResult(location, element, tag, value) + } + + predicate hasOptionalResult(Impl::Location location, string element, string tag, string value) { + M::hasOptionalResult(location, element, tag, value) + } + } + + /** + * A module that merges four test signatures. + */ + module MergeTests4<TestSig TestImpl1, TestSig TestImpl2, TestSig TestImpl3, TestSig TestImpl4> + implements TestSig + { + private module M = MergeTests<MergeTests3<TestImpl1, TestImpl2, TestImpl3>, TestImpl4>; + + string getARelevantTag() { result = M::getARelevantTag() } + + predicate hasActualResult(Impl::Location location, string element, string tag, string value) { + M::hasActualResult(location, element, tag, value) + } + + predicate hasOptionalResult(Impl::Location location, string element, string tag, string value) { + M::hasOptionalResult(location, element, tag, value) + } + } + + /** + * A module that merges five test signatures. + */ + module MergeTests5< + TestSig TestImpl1, TestSig TestImpl2, TestSig TestImpl3, TestSig TestImpl4, TestSig TestImpl5> + implements TestSig + { + private module M = + MergeTests<MergeTests4<TestImpl1, TestImpl2, TestImpl3, TestImpl4>, TestImpl5>; + + string getARelevantTag() { result = M::getARelevantTag() } + + predicate hasActualResult(Impl::Location location, string element, string tag, string value) { + M::hasActualResult(location, element, tag, value) + } + + predicate hasOptionalResult(Impl::Location location, string element, string tag, string value) { + M::hasOptionalResult(location, element, tag, value) + } + } + private module LegacyImpl implements TestSig { string getARelevantTag() { result = any(InlineExpectationsTest t).getARelevantTag() } From d6d21e3928d501ca623ea93bb29c726e676460b5 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 15 Jun 2023 16:43:48 +0200 Subject: [PATCH 672/739] Go: Update remaining inline expectation tests to use the paramterized module --- .../frameworks/ElazarlGoproxy/test.expected | 2 + .../go/frameworks/ElazarlGoproxy/test.ql | 46 ++++++-------- .../go/frameworks/SQL/QueryString.expected | 2 + .../semmle/go/frameworks/SQL/QueryString.ql | 38 +++++------ .../semmle/go/frameworks/Yaml/tests.expected | 2 + .../semmle/go/frameworks/Yaml/tests.ql | 63 +++++++++---------- 6 files changed, 72 insertions(+), 81 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.expected b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql index e8c68c1c3e1..2ffca8a692a 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class UntrustedFlowSourceTest extends InlineExpectationsTest { - UntrustedFlowSourceTest() { this = "untrustedflowsource" } +module UntrustedFlowSourceTest implements TestSig { + string getARelevantTag() { result = "untrustedflowsource" } - override string getARelevantTag() { result = "untrustedflowsource" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "untrustedflowsource" and value = element and exists(UntrustedFlowSource src | value = "\"" + src.toString() + "\"" | @@ -16,12 +14,10 @@ class UntrustedFlowSourceTest extends InlineExpectationsTest { } } -class HeaderWriteTest extends InlineExpectationsTest { - HeaderWriteTest() { this = "headerwrite" } +module HeaderWriteTest implements TestSig { + string getARelevantTag() { result = "headerwrite" } - override string getARelevantTag() { result = "headerwrite" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "headerwrite" and exists(Http::HeaderWrite hw, string name, string val | element = hw.toString() | hw.definesHeader(name, val) and @@ -32,12 +28,10 @@ class HeaderWriteTest extends InlineExpectationsTest { } } -class LoggerTest extends InlineExpectationsTest { - LoggerTest() { this = "LoggerTest" } +module LoggerTest implements TestSig { + string getARelevantTag() { result = "logger" } - override string getARelevantTag() { result = "logger" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(LoggerCall log | log.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and @@ -48,32 +42,32 @@ class LoggerTest extends InlineExpectationsTest { } } -class Config extends TaintTracking::Configuration { - Config() { this = "goproxy config" } - - override predicate isSource(DataFlow::Node n) { +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n = any(DataFlow::CallNode c | c.getCalleeName().matches("tainted%")).getResult() } - override predicate isSink(DataFlow::Node n) { + predicate isSink(DataFlow::Node n) { n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() } } -class TaintFlow extends InlineExpectationsTest { - TaintFlow() { this = "goproxy flow" } +module Flow = TaintTracking::Global<Config>; - override string getARelevantTag() { result = "taintflow" } +module TaintFlow implements TestSig { + string getARelevantTag() { result = "taintflow" } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "taintflow" and value = "" and element = "" and - exists(Config c, DataFlow::Node toNode | + exists(DataFlow::Node toNode | toNode .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and - c.hasFlowTo(toNode) + Flow::flowTo(toNode) ) } } + +import MakeTest<MergeTests4<UntrustedFlowSourceTest, HeaderWriteTest, LoggerTest, TaintFlow>> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.expected b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql index 31852f1b862..6b1c1f70e04 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/SQL/QueryString.ql @@ -1,12 +1,10 @@ import go import TestUtilities.InlineExpectationsTest -class SqlTest extends InlineExpectationsTest { - SqlTest() { this = "SQLTest" } +module SqlTest implements TestSig { + string getARelevantTag() { result = "query" } - override string getARelevantTag() { result = "query" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "query" and exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() | q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -17,12 +15,10 @@ class SqlTest extends InlineExpectationsTest { } } -class QueryString extends InlineExpectationsTest { - QueryString() { this = "QueryString no Query" } +module QueryString implements TestSig { + string getARelevantTag() { result = "querystring" } - override string getARelevantTag() { result = "querystring" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "querystring" and element = "" and exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) | @@ -33,30 +29,30 @@ class QueryString extends InlineExpectationsTest { } } -class Config extends TaintTracking::Configuration { - Config() { this = "pg-orm config" } +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit } - override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit } - - override predicate isSink(DataFlow::Node n) { + predicate isSink(DataFlow::Node n) { n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument() } } -class TaintFlow extends InlineExpectationsTest { - TaintFlow() { this = "pg-orm flow" } +module Flow = TaintTracking::Global<Config>; - override string getARelevantTag() { result = "flowfrom" } +module TaintFlow implements TestSig { + string getARelevantTag() { result = "flowfrom" } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "flowfrom" and element = "" and - exists(Config c, DataFlow::Node fromNode, DataFlow::Node toNode | + exists(DataFlow::Node fromNode, DataFlow::Node toNode | toNode .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and - c.hasFlow(fromNode, toNode) and + Flow::flow(fromNode, toNode) and value = fromNode.asExpr().(StringLit).getValue() ) } } + +import MakeTest<MergeTests3<SqlTest, QueryString, TaintFlow>> diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected index e69de29bb2d..48de9172b36 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql index 273f031fc32..c4c0cafb50e 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql @@ -11,32 +11,29 @@ DataFlow::CallNode getAYamlCall() { isYamlFunction(result.getACalleeIncludingExternals().asFunction()) } -class TaintTransitsFunctionConfig extends TaintTracking::Configuration { - TaintTransitsFunctionConfig() { this = "TaintTransitsFunctionConfig" } - - predicate isSourceSinkPair(DataFlow::Node inNode, DataFlow::Node outNode) { - exists(DataFlow::CallNode cn | cn = getAYamlCall() | - inNode = [cn.getAnArgument(), cn.getReceiver()] and - ( - outNode.(DataFlow::PostUpdateNode).getPreUpdateNode() = - [cn.getAnArgument(), cn.getReceiver()] - or - outNode = cn.getAResult() - ) +predicate isSourceSinkPair(DataFlow::Node inNode, DataFlow::Node outNode) { + exists(DataFlow::CallNode cn | cn = getAYamlCall() | + inNode = [cn.getAnArgument(), cn.getReceiver()] and + ( + outNode.(DataFlow::PostUpdateNode).getPreUpdateNode() = [cn.getAnArgument(), cn.getReceiver()] + or + outNode = cn.getAResult() ) - } - - override predicate isSource(DataFlow::Node n) { this.isSourceSinkPair(n, _) } - - override predicate isSink(DataFlow::Node n) { this.isSourceSinkPair(_, n) } + ) } -class TaintFunctionModelTest extends InlineExpectationsTest { - TaintFunctionModelTest() { this = "TaintFunctionModelTest" } +module TaintTransitsFunctionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { isSourceSinkPair(n, _) } - override string getARelevantTag() { result = "ttfnmodelstep" } + predicate isSink(DataFlow::Node n) { isSourceSinkPair(_, n) } +} - override predicate hasActualResult(Location location, string element, string tag, string value) { +module TaintTransitsFunctionFlow = TaintTracking::Global<TaintTransitsFunctionConfig>; + +module TaintFunctionModelTest implements TestSig { + string getARelevantTag() { result = "ttfnmodelstep" } + + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "ttfnmodelstep" and ( exists(TaintTracking::FunctionModel model, DataFlow::CallNode call | call = model.getACall() | @@ -46,9 +43,9 @@ class TaintFunctionModelTest extends InlineExpectationsTest { value = "\"" + model.getAnInputNode(call) + " -> " + model.getAnOutputNode(call) + "\"" ) or - exists(TaintTransitsFunctionConfig config, DataFlow::Node arg, DataFlow::Node output | - config.hasFlow(arg, output) and - config.isSourceSinkPair(arg, output) and + exists(DataFlow::Node arg, DataFlow::Node output | + TaintTransitsFunctionFlow::flow(arg, output) and + isSourceSinkPair(arg, output) and arg.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and element = arg.toString() and @@ -58,12 +55,10 @@ class TaintFunctionModelTest extends InlineExpectationsTest { } } -class MarshalerTest extends InlineExpectationsTest { - MarshalerTest() { this = "MarshalerTest" } +module MarshalerTest implements TestSig { + string getARelevantTag() { result = "marshaler" } - override string getARelevantTag() { result = "marshaler" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "marshaler" and exists(MarshalingFunction m, DataFlow::CallNode call | call = m.getACall() | call.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -76,12 +71,10 @@ class MarshalerTest extends InlineExpectationsTest { } } -class UnmarshalerTest extends InlineExpectationsTest { - UnmarshalerTest() { this = "UnmarshalerTest" } +module UnmarshalerTest implements TestSig { + string getARelevantTag() { result = "unmarshaler" } - override string getARelevantTag() { result = "unmarshaler" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "unmarshaler" and exists(UnmarshalingFunction m, DataFlow::CallNode call | call = m.getACall() | call.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), @@ -93,3 +86,5 @@ class UnmarshalerTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests3<TaintFunctionModelTest, MarshalerTest, UnmarshalerTest>> From c53e529bac89562ad6222f16a69d45e21a7913fa Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 15 Jun 2023 16:44:19 +0200 Subject: [PATCH 673/739] Ruby: Update remaining inline expectation tests to use the paramterized module --- .../test/TestUtilities/InlineTypeTrackingFlowTest.qll | 10 +++++----- .../array-flow/type-tracking-array-flow.expected | 2 ++ .../dataflow/global/TypeTrackingInlineTest.expected | 2 ++ .../hash-flow/type-tracking-hash-flow.expected | 2 ++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ruby/ql/test/TestUtilities/InlineTypeTrackingFlowTest.qll b/ruby/ql/test/TestUtilities/InlineTypeTrackingFlowTest.qll index 2e60d1ce0e8..6d584ef31dc 100644 --- a/ruby/ql/test/TestUtilities/InlineTypeTrackingFlowTest.qll +++ b/ruby/ql/test/TestUtilities/InlineTypeTrackingFlowTest.qll @@ -15,12 +15,10 @@ DataFlow::LocalSourceNode track(DataFlow::CallNode source) { result = track(TypeTracker::end(), source) } -class TypeTrackingFlowTest extends InlineExpectationsTest { - TypeTrackingFlowTest() { this = "TypeTrackingFlowTest" } +module TypeTrackingFlowTest implements TestSig { + string getARelevantTag() { result = "hasValueFlow" } - override string getARelevantTag() { result = "hasValueFlow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Node sink, DataFlow::Node source | defaultSink(sink) and track(source).flowsTo(sink) and @@ -31,3 +29,5 @@ class TypeTrackingFlowTest extends InlineExpectationsTest { ) } } + +import MakeTest<TypeTrackingFlowTest> diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected index 83e81729d98..5374f468c3e 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected @@ -1,3 +1,5 @@ +failures +testFailures | array_flow.rb:107:10:107:13 | ...[...] | Unexpected result: hasValueFlow=11.2 | | array_flow.rb:179:28:179:46 | # $ hasValueFlow=19 | Missing result:hasValueFlow=19 | | array_flow.rb:180:28:180:46 | # $ hasValueFlow=19 | Missing result:hasValueFlow=19 | diff --git a/ruby/ql/test/library-tests/dataflow/global/TypeTrackingInlineTest.expected b/ruby/ql/test/library-tests/dataflow/global/TypeTrackingInlineTest.expected index 88d69578cf7..8fbd6f51044 100644 --- a/ruby/ql/test/library-tests/dataflow/global/TypeTrackingInlineTest.expected +++ b/ruby/ql/test/library-tests/dataflow/global/TypeTrackingInlineTest.expected @@ -1,3 +1,5 @@ +failures +testFailures | captured_variables.rb:9:14:9:14 | x | Fixed missing result:hasValueFlow=1.2 | | captured_variables.rb:16:14:16:14 | x | Fixed missing result:hasValueFlow=1.3 | | instance_variables.rb:20:16:20:33 | # $ hasValueFlow=7 | Missing result:hasValueFlow=7 | diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/type-tracking-hash-flow.expected b/ruby/ql/test/library-tests/dataflow/hash-flow/type-tracking-hash-flow.expected index ff6899d41c2..af062eec4fd 100644 --- a/ruby/ql/test/library-tests/dataflow/hash-flow/type-tracking-hash-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/hash-flow/type-tracking-hash-flow.expected @@ -1,3 +1,5 @@ +failures +testFailures | hash_flow.rb:65:21:65:40 | # $ hasValueFlow=3.3 | Missing result:hasValueFlow=3.3 | | hash_flow.rb:66:21:66:49 | # $ SPURIOUS hasValueFlow=3.3 | Missing result:hasValueFlow=3.3 | | hash_flow.rb:114:10:114:17 | ...[...] | Unexpected result: hasValueFlow=7.2 | From dba44605264630d3a52fd2d0b21f15c6a9daa757 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 15 Jun 2023 16:44:04 +0200 Subject: [PATCH 674/739] Python: Update more inline expectation tests to use the paramterized module --- .../dataflow/TestUtil/DataflowQueryTest.qll | 16 +- .../dataflow/TestUtil/FlowTest.qll | 29 ++- .../dataflow/TestUtil/LocalFlowStepTest.qll | 10 +- .../dataflow/TestUtil/MaximalFlowTest.qll | 22 +- .../dataflow/TestUtil/NormalDataflowTest.qll | 18 +- .../TestUtil/NormalTaintTrackingTest.qll | 16 +- .../dataflow/TestUtil/UnresolvedCalls.qll | 36 ++-- .../dataflow/basic/localFlowStepTest.expected | 2 + .../dataflow/basic/maximalFlowTest.expected | 2 + .../coverage/NormalDataflowTest.expected | 1 + .../exceptions/NormalDataflowTest.expected | 1 + .../fieldflow/NormalDataflowTest.expected | 1 + .../fieldflow/UnresolvedCalls.expected | 2 + .../dataflow/fieldflow/UnresolvedCalls.ql | 8 +- .../match/NormalDataflowTest.expected | 1 + .../module-initialization/localFlow.expected | 2 + .../module-initialization/localFlow.ql | 18 +- .../dataflow/regression/dataflow.ql | 2 +- .../NormalTaintTrackingTest.expected | 1 + .../dataflow/summaries/summaries.ql | 6 +- .../commonSanitizer/InlineTaintTest.expected | 3 +- .../commonSanitizer/InlineTaintTest.ql | 10 +- .../customSanitizer/InlineTaintTest.expected | 45 ++-- .../customSanitizer/InlineTaintTest.ql | 14 +- .../InlineTaintTest.expected | 3 +- .../InlineTaintTest.ql | 1 + .../InlineTaintTest.expected | 3 +- .../InlineTaintTest.ql | 1 + .../generator-flow/InlineTaintTest.expected | 3 +- .../generator-flow/InlineTaintTest.ql | 1 + .../NormalDataflowTest.expected | 1 + .../InlineTaintTest.expected | 3 +- .../unwanted-global-flow/InlineTaintTest.ql | 1 + .../test/experimental/dataflow/testConfig.qll | 12 +- .../experimental/dataflow/testTaintConfig.qll | 12 +- .../dataflow/typetracking/tracked.expected | 2 + .../dataflow/typetracking/tracked.ql | 42 ++-- .../typetracking_imports/tracked.expected | 2 + .../dataflow/variable-capture/CaptureTest.ql | 2 +- .../test/experimental/meta/ConceptsTest.qll | 203 +++++++----------- .../experimental/meta/InlineTaintTest.qll | 90 ++++---- python/ql/test/experimental/meta/MaDTest.qll | 18 +- .../meta/debug/InlineTaintTestPaths.ql | 6 +- .../meta/debug/dataflowTestPaths.ql | 4 +- .../InlineTaintTest.expected | 3 +- .../inline-taint-test-demo/InlineTaintTest.ql | 1 + .../DataflowQueryTest.expected | 1 + .../frameworks/aioch/ConceptsTest.expected | 2 + .../frameworks/aiohttp/ConceptsTest.expected | 2 + .../aiohttp/InlineTaintTest.expected | 3 +- .../frameworks/aiohttp/InlineTaintTest.ql | 1 + .../frameworks/aiomysql/ConceptsTest.expected | 2 + .../frameworks/aiopg/ConceptsTest.expected | 2 + .../aiosqlite/ConceptsTest.expected | 2 + .../frameworks/asyncpg/ConceptsTest.expected | 2 + .../frameworks/asyncpg/MaDTest.expected | 2 + .../cassandra-driver/ConceptsTest.expected | 2 + .../clickhouse_driver/ConceptsTest.expected | 2 + .../frameworks/crypto/ConceptsTest.expected | 2 + .../cryptodome/ConceptsTest.expected | 2 + .../cryptography/ConceptsTest.expected | 2 + .../cx_Oracle/ConceptsTest.expected | 2 + .../frameworks/dill/ConceptsTest.expected | 2 + .../django-orm/NormalDataflowTest.expected | 1 + .../django-v1/ConceptsTest.expected | 2 + .../django-v2-v3/ConceptsTest.expected | 2 + .../django-v2-v3/InlineTaintTest.expected | 3 +- .../django-v2-v3/InlineTaintTest.ql | 1 + .../frameworks/django/ConceptsTest.expected | 2 + .../frameworks/fabric/ConceptsTest.expected | 2 + .../fabric/InlineTaintTest.expected | 3 +- .../frameworks/fabric/InlineTaintTest.ql | 1 + .../frameworks/fastapi/ConceptsTest.expected | 2 + .../fastapi/InlineTaintTest.expected | 3 +- .../frameworks/fastapi/InlineTaintTest.ql | 1 + .../frameworks/flask/ConceptsTest.expected | 2 + .../frameworks/flask/InlineTaintTest.expected | 3 +- .../frameworks/flask/InlineTaintTest.ql | 1 + .../flask_admin/ConceptsTest.expected | 2 + .../flask_admin/InlineTaintTest.expected | 3 +- .../frameworks/flask_admin/InlineTaintTest.ql | 1 + .../flask_sqlalchemy/ConceptsTest.expected | 2 + .../flask_sqlalchemy/InlineTaintTest.expected | 3 +- .../flask_sqlalchemy/InlineTaintTest.ql | 1 + .../frameworks/httpx/ConceptsTest.expected | 2 + .../frameworks/idna/ConceptsTest.expected | 2 + .../frameworks/idna/InlineTaintTest.expected | 3 +- .../frameworks/idna/InlineTaintTest.ql | 1 + .../frameworks/invoke/ConceptsTest.expected | 2 + .../frameworks/jmespath/ConceptsTest.expected | 2 + .../jmespath/InlineTaintTest.expected | 3 +- .../frameworks/jmespath/InlineTaintTest.ql | 1 + .../frameworks/libtaxii/ConceptsTest.expected | 2 + .../frameworks/lxml/ConceptsTest.expected | 2 + .../markupsafe/ConceptsTest.expected | 2 + .../markupsafe/InlineTaintTest.expected | 3 +- .../frameworks/markupsafe/InlineTaintTest.ql | 10 +- .../multidict/ConceptsTest.expected | 2 + .../multidict/InlineTaintTest.expected | 3 +- .../frameworks/multidict/InlineTaintTest.ql | 1 + .../ConceptsTest.expected | 2 + .../frameworks/mysqldb/ConceptsTest.expected | 2 + .../frameworks/oracledb/ConceptsTest.expected | 2 + .../frameworks/peewee/ConceptsTest.expected | 2 + .../peewee/InlineTaintTest.expected | 3 +- .../frameworks/peewee/InlineTaintTest.ql | 1 + .../phoenixdb/ConceptsTest.expected | 2 + .../frameworks/pycurl/ConceptsTest.expected | 2 + .../frameworks/pymssql/ConceptsTest.expected | 2 + .../frameworks/pymysql/ConceptsTest.expected | 2 + .../frameworks/pyodbc/ConceptsTest.expected | 2 + .../frameworks/requests/ConceptsTest.expected | 2 + .../requests/InlineTaintTest.expected | 3 +- .../frameworks/requests/InlineTaintTest.ql | 1 + .../rest_framework/ConceptsTest.expected | 2 + .../rest_framework/InlineTaintTest.expected | 3 +- .../rest_framework/InlineTaintTest.ql | 1 + .../frameworks/rsa/ConceptsTest.expected | 2 + .../frameworks/rsa/InlineTaintTest.expected | 3 +- .../frameworks/rsa/InlineTaintTest.ql | 1 + .../ruamel.yaml/ConceptsTest.expected | 2 + .../simplejson/ConceptsTest.expected | 2 + .../simplejson/InlineTaintTest.expected | 3 +- .../frameworks/simplejson/InlineTaintTest.ql | 1 + .../sqlalchemy/ConceptsTest.expected | 2 + .../sqlalchemy/InlineTaintTest.expected | 3 +- .../frameworks/sqlalchemy/InlineTaintTest.ql | 1 + .../stdlib-py2/ConceptsTest.expected | 2 + .../stdlib-py3/ConceptsTest.expected | 2 + .../frameworks/stdlib/ConceptsTest.expected | 2 + .../stdlib/InlineTaintTest.expected | 3 +- .../frameworks/stdlib/InlineTaintTest.ql | 1 + .../frameworks/toml/ConceptsTest.expected | 2 + .../frameworks/tornado/ConceptsTest.expected | 2 + .../tornado/InlineTaintTest.expected | 3 +- .../frameworks/tornado/InlineTaintTest.ql | 1 + .../frameworks/twisted/ConceptsTest.expected | 2 + .../twisted/InlineTaintTest.expected | 3 +- .../frameworks/twisted/InlineTaintTest.ql | 1 + .../frameworks/ujson/ConceptsTest.expected | 2 + .../frameworks/ujson/InlineTaintTest.expected | 3 +- .../frameworks/ujson/InlineTaintTest.ql | 1 + .../frameworks/urllib3/ConceptsTest.expected | 2 + .../xmltodict/ConceptsTest.expected | 2 + .../frameworks/yaml/ConceptsTest.expected | 2 + .../frameworks/yarl/ConceptsTest.expected | 2 + .../frameworks/yarl/InlineTaintTest.expected | 3 +- .../frameworks/yarl/InlineTaintTest.ql | 1 + .../regex/SubstructureTests.expected | 2 + .../library-tests/regex/SubstructureTests.ql | 34 ++- .../DataflowQueryTest.expected | 1 + .../DataflowQueryTest.expected | 1 + .../DataflowQueryTest.expected | 1 + 153 files changed, 551 insertions(+), 379 deletions(-) diff --git a/python/ql/test/experimental/dataflow/TestUtil/DataflowQueryTest.qll b/python/ql/test/experimental/dataflow/TestUtil/DataflowQueryTest.qll index 1c9259038bc..74a43bb4cc4 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/DataflowQueryTest.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/DataflowQueryTest.qll @@ -3,12 +3,10 @@ import semmle.python.dataflow.new.DataFlow import TestUtilities.InlineExpectationsTest private import semmle.python.dataflow.new.internal.PrintNode -class DataFlowQueryTest extends InlineExpectationsTest { - DataFlowQueryTest() { this = "DataFlowQueryTest" } +module DataFlowQueryTest implements TestSig { + string getARelevantTag() { result = "result" } - override string getARelevantTag() { result = "result" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Configuration cfg, DataFlow::Node sink | cfg.hasFlowTo(sink) | location = sink.getLocation() and tag = "result" and @@ -22,7 +20,7 @@ class DataFlowQueryTest extends InlineExpectationsTest { // Sometimes a line contains both an alert and a safe sink. // In this situation, the annotation form `OK(safe sink)` // can be useful. - override predicate hasOptionalResult(Location location, string element, string tag, string value) { + predicate hasOptionalResult(Location location, string element, string tag, string value) { exists(DataFlow::Configuration cfg, DataFlow::Node sink | cfg.isSink(sink) or cfg.isSink(sink, _) | @@ -34,6 +32,8 @@ class DataFlowQueryTest extends InlineExpectationsTest { } } +import MakeTest<DataFlowQueryTest> + query predicate missingAnnotationOnSink(Location location, string error, string element) { error = "ERROR, you should add `# $ MISSING: result=BAD` or `result=OK` annotation" and exists(DataFlow::Node sink | @@ -42,13 +42,13 @@ query predicate missingAnnotationOnSink(Location location, string error, string location = sink.getLocation() and element = prettyExpr(sink.asExpr()) and not exists(DataFlow::Configuration cfg | cfg.hasFlowTo(sink)) and - not exists(FalseNegativeExpectation missingResult | + not exists(FalseNegativeTestExpectation missingResult | missingResult.getTag() = "result" and missingResult.getValue() = "BAD" and missingResult.getLocation().getFile() = location.getFile() and missingResult.getLocation().getStartLine() = location.getStartLine() ) and - not exists(GoodExpectation okResult | + not exists(GoodTestExpectation okResult | okResult.getTag() = "result" and okResult.getValue() in ["OK", "OK(" + prettyNode(sink) + ")"] and okResult.getLocation().getFile() = location.getFile() and diff --git a/python/ql/test/experimental/dataflow/TestUtil/FlowTest.qll b/python/ql/test/experimental/dataflow/TestUtil/FlowTest.qll index 2f5d7de5952..e6abf741b36 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/FlowTest.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/FlowTest.qll @@ -3,22 +3,21 @@ import semmle.python.dataflow.new.DataFlow import TestUtilities.InlineExpectationsTest private import semmle.python.dataflow.new.internal.PrintNode -abstract class FlowTest extends InlineExpectationsTest { - bindingset[this] - FlowTest() { any() } +signature module FlowTestSig { + string flowTag(); - abstract string flowTag(); + predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode); +} - abstract predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode); +private module FlowTest<FlowTestSig Impl> implements TestSig { + string getARelevantTag() { result = Impl::flowTag() } - override string getARelevantTag() { result = this.flowTag() } - - override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(DataFlow::Node fromNode, DataFlow::Node toNode | this.relevantFlow(fromNode, toNode) | + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node fromNode, DataFlow::Node toNode | Impl::relevantFlow(fromNode, toNode) | location = toNode.getLocation() and - tag = this.flowTag() and + tag = Impl::flowTag() and value = - "\"" + prettyNode(fromNode).replaceAll("\"", "'") + this.lineStr(fromNode, toNode) + " -> " + + "\"" + prettyNode(fromNode).replaceAll("\"", "'") + lineStr(fromNode, toNode) + " -> " + prettyNode(toNode).replaceAll("\"", "'") + "\"" and element = toNode.toString() ) @@ -38,3 +37,11 @@ abstract class FlowTest extends InlineExpectationsTest { ) } } + +module MakeFlowTest<FlowTestSig Impl> { + import MakeTest<FlowTest<Impl>> +} + +module MakeFlowTest2<FlowTestSig Impl1, FlowTestSig Impl2> { + import MakeTest<MergeTests<FlowTest<Impl1>, FlowTest<Impl2>>> +} diff --git a/python/ql/test/experimental/dataflow/TestUtil/LocalFlowStepTest.qll b/python/ql/test/experimental/dataflow/TestUtil/LocalFlowStepTest.qll index c2c180627ec..6cbfe917fd4 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/LocalFlowStepTest.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/LocalFlowStepTest.qll @@ -2,12 +2,12 @@ import python import semmle.python.dataflow.new.DataFlow import FlowTest -class LocalFlowStepTest extends FlowTest { - LocalFlowStepTest() { this = "LocalFlowStepTest" } +module LocalFlowStepTest implements FlowTestSig { + string flowTag() { result = "step" } - override string flowTag() { result = "step" } - - override predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode) { + predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode) { DataFlow::localFlowStep(fromNode, toNode) } } + +import MakeFlowTest<LocalFlowStepTest> diff --git a/python/ql/test/experimental/dataflow/TestUtil/MaximalFlowTest.qll b/python/ql/test/experimental/dataflow/TestUtil/MaximalFlowTest.qll index 6615afb9247..681e51ca604 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/MaximalFlowTest.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/MaximalFlowTest.qll @@ -3,25 +3,23 @@ import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.internal.DataFlowPrivate import FlowTest -class MaximalFlowTest extends FlowTest { - MaximalFlowTest() { this = "MaximalFlowTest" } +module MaximalFlowTest implements FlowTestSig { + string flowTag() { result = "flow" } - override string flowTag() { result = "flow" } - - override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) { + predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) { source != sink and - exists(MaximalFlowsConfig cfg | cfg.hasFlow(source, sink)) + MaximalFlows::flow(source, sink) } } +import MakeFlowTest<MaximalFlowTest> + /** * A configuration to find all "maximal" flows. * To be used on small programs. */ -class MaximalFlowsConfig extends DataFlow::Configuration { - MaximalFlowsConfig() { this = "MaximalFlowsConfig" } - - override predicate isSource(DataFlow::Node node) { +module MaximalFlowsConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { exists(node.getLocation().getFile().getRelativePath()) and not node.asCfgNode() instanceof CallNode and not node.asCfgNode().getNode() instanceof Return and @@ -32,7 +30,7 @@ class MaximalFlowsConfig extends DataFlow::Configuration { not DataFlow::localFlowStep(_, node) } - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { exists(node.getLocation().getFile().getRelativePath()) and not any(CallNode c).getArg(_) = node.asCfgNode() and not node instanceof DataFlow::ArgumentNode and @@ -40,3 +38,5 @@ class MaximalFlowsConfig extends DataFlow::Configuration { not DataFlow::localFlowStep(node, _) } } + +module MaximalFlows = DataFlow::Global<MaximalFlowsConfig>; diff --git a/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll b/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll index f526a1f43ae..a327886fedd 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/NormalDataflowTest.qll @@ -3,20 +3,20 @@ import experimental.dataflow.TestUtil.FlowTest import experimental.dataflow.testConfig private import semmle.python.dataflow.new.internal.PrintNode -class DataFlowTest extends FlowTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements FlowTestSig { + string flowTag() { result = "flow" } - override string flowTag() { result = "flow" } - - override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) { - exists(TestConfiguration cfg | cfg.hasFlow(source, sink)) + predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) { + TestFlow::flow(source, sink) } } +import MakeFlowTest<DataFlowTest> + query predicate missingAnnotationOnSink(Location location, string error, string element) { error = "ERROR, you should add `# $ MISSING: flow` annotation" and exists(DataFlow::Node sink | - any(TestConfiguration config).isSink(sink) and + TestConfig::isSink(sink) and // note: we only care about `SINK` and not `SINK_F`, so we have to reconstruct manually. exists(DataFlow::CallCfgNode call | call.getFunction().asCfgNode().(NameNode).getId() = "SINK" and @@ -24,8 +24,8 @@ query predicate missingAnnotationOnSink(Location location, string error, string ) and location = sink.getLocation() and element = prettyExpr(sink.asExpr()) and - not any(TestConfiguration config).hasFlow(_, sink) and - not exists(FalseNegativeExpectation missingResult | + not TestFlow::flowTo(sink) and + not exists(FalseNegativeTestExpectation missingResult | missingResult.getTag() = "flow" and missingResult.getLocation().getFile() = location.getFile() and missingResult.getLocation().getStartLine() = location.getStartLine() diff --git a/python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll b/python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll index 9619679da03..4a07dc4d2d6 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/NormalTaintTrackingTest.qll @@ -3,16 +3,16 @@ import experimental.dataflow.TestUtil.FlowTest import experimental.dataflow.testTaintConfig private import semmle.python.dataflow.new.internal.PrintNode -class DataFlowTest extends FlowTest { - DataFlowTest() { this = "DataFlowTest" } +module DataFlowTest implements FlowTestSig { + string flowTag() { result = "flow" } - override string flowTag() { result = "flow" } - - override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) { - exists(TestConfiguration cfg | cfg.hasFlow(source, sink)) + predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) { + TestFlow::flow(source, sink) } } +import MakeFlowTest<DataFlowTest> + query predicate missingAnnotationOnSink(Location location, string error, string element) { error = "ERROR, you should add `# $ MISSING: flow` annotation" and exists(DataFlow::Node sink | @@ -23,8 +23,8 @@ query predicate missingAnnotationOnSink(Location location, string error, string ) and location = sink.getLocation() and element = prettyExpr(sink.asExpr()) and - not any(TestConfiguration config).hasFlow(_, sink) and - not exists(FalseNegativeExpectation missingResult | + not TestFlow::flowTo(sink) and + not exists(FalseNegativeTestExpectation missingResult | missingResult.getTag() = "flow" and missingResult.getLocation().getFile() = location.getFile() and missingResult.getLocation().getStartLine() = location.getStartLine() diff --git a/python/ql/test/experimental/dataflow/TestUtil/UnresolvedCalls.qll b/python/ql/test/experimental/dataflow/TestUtil/UnresolvedCalls.qll index 003d02ba530..9b26d8c9175 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/UnresolvedCalls.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/UnresolvedCalls.qll @@ -4,11 +4,11 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPr private import semmle.python.ApiGraphs import TestUtilities.InlineExpectationsTest -class UnresolvedCallExpectations extends InlineExpectationsTest { - UnresolvedCallExpectations() { this = "UnresolvedCallExpectations" } - - override string getARelevantTag() { result = "unresolved_call" } +signature module UnresolvedCallExpectationsSig { + predicate unresolvedCall(CallNode call); +} +module DefaultUnresolvedCallExpectations implements UnresolvedCallExpectationsSig { predicate unresolvedCall(CallNode call) { not exists(DataFlowPrivate::DataFlowCall dfc | exists(dfc.getCallable()) and dfc.getNode() = call @@ -16,14 +16,22 @@ class UnresolvedCallExpectations extends InlineExpectationsTest { not DataFlowPrivate::resolveClassCall(call, _) and not call = API::builtin(_).getACall().asCfgNode() } - - override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(location.getFile().getRelativePath()) and - exists(CallNode call | this.unresolvedCall(call) | - location = call.getLocation() and - tag = "unresolved_call" and - value = prettyExpr(call.getNode()) and - element = call.toString() - ) - } +} + +module MakeUnresolvedCallExpectations<UnresolvedCallExpectationsSig Impl> { + private module UnresolvedCallExpectations implements TestSig { + string getARelevantTag() { result = "unresolved_call" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(location.getFile().getRelativePath()) and + exists(CallNode call | Impl::unresolvedCall(call) | + location = call.getLocation() and + tag = "unresolved_call" and + value = prettyExpr(call.getNode()) and + element = call.toString() + ) + } + } + + import MakeTest<UnresolvedCallExpectations> } diff --git a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected b/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected +++ b/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected b/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected +++ b/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected +++ b/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected +++ b/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected +++ b/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected b/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected +++ b/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql b/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql index af73ca552fc..3c7498bd651 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql +++ b/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.ql @@ -2,11 +2,13 @@ import python import experimental.dataflow.TestUtil.UnresolvedCalls private import semmle.python.dataflow.new.DataFlow -class IgnoreDictMethod extends UnresolvedCallExpectations { - override predicate unresolvedCall(CallNode call) { - super.unresolvedCall(call) and +module IgnoreDictMethod implements UnresolvedCallExpectationsSig { + predicate unresolvedCall(CallNode call) { + DefaultUnresolvedCallExpectations::unresolvedCall(call) and not any(DataFlow::MethodCallNode methodCall | methodCall.getMethodName() in ["get", "setdefault"] ).asCfgNode() = call } } + +import MakeUnresolvedCallExpectations<IgnoreDictMethod> diff --git a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected +++ b/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected b/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected +++ b/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/module-initialization/localFlow.ql b/python/ql/test/experimental/dataflow/module-initialization/localFlow.ql index 635902e7045..8ef3860955d 100644 --- a/python/ql/test/experimental/dataflow/module-initialization/localFlow.ql +++ b/python/ql/test/experimental/dataflow/module-initialization/localFlow.ql @@ -4,12 +4,10 @@ import experimental.dataflow.TestUtil.FlowTest private import semmle.python.dataflow.new.internal.PrintNode private import semmle.python.dataflow.new.internal.DataFlowPrivate as DP -class ImportTimeLocalFlowTest extends FlowTest { - ImportTimeLocalFlowTest() { this = "ImportTimeLocalFlowTest" } +module ImportTimeLocalFlowTest implements FlowTestSig { + string flowTag() { result = "importTimeFlow" } - override string flowTag() { result = "importTimeFlow" } - - override predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { nodeFrom.getLocation().getFile().getBaseName() = "multiphase.py" and // results are displayed next to `nodeTo`, so we need a line to write on nodeTo.getLocation().getStartLine() > 0 and @@ -18,12 +16,10 @@ class ImportTimeLocalFlowTest extends FlowTest { } } -class RuntimeLocalFlowTest extends FlowTest { - RuntimeLocalFlowTest() { this = "RuntimeLocalFlowTest" } +module RuntimeLocalFlowTest implements FlowTestSig { + string flowTag() { result = "runtimeFlow" } - override string flowTag() { result = "runtimeFlow" } - - override predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { nodeFrom.getLocation().getFile().getBaseName() = "multiphase.py" and // results are displayed next to `nodeTo`, so we need a line to write on nodeTo.getLocation().getStartLine() > 0 and @@ -34,3 +30,5 @@ class RuntimeLocalFlowTest extends FlowTest { DP::runtimeJumpStep(nodeFrom, nodeTo) } } + +import MakeFlowTest2<ImportTimeLocalFlowTest, RuntimeLocalFlowTest> diff --git a/python/ql/test/experimental/dataflow/regression/dataflow.ql b/python/ql/test/experimental/dataflow/regression/dataflow.ql index c95b2f2111f..39763fa4814 100644 --- a/python/ql/test/experimental/dataflow/regression/dataflow.ql +++ b/python/ql/test/experimental/dataflow/regression/dataflow.ql @@ -9,5 +9,5 @@ import python import experimental.dataflow.testConfig from DataFlow::Node source, DataFlow::Node sink -where exists(TestConfiguration cfg | cfg.hasFlow(source, sink)) +where TestFlow::flow(source, sink) select source, sink diff --git a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected b/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected +++ b/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/experimental/dataflow/summaries/summaries.ql b/python/ql/test/experimental/dataflow/summaries/summaries.ql index f2c0a522279..d3c0206d41f 100644 --- a/python/ql/test/experimental/dataflow/summaries/summaries.ql +++ b/python/ql/test/experimental/dataflow/summaries/summaries.ql @@ -4,7 +4,7 @@ import python import semmle.python.dataflow.new.FlowSummary -import DataFlow::PathGraph +import TestFlow::PathGraph import semmle.python.dataflow.new.TaintTracking import semmle.python.dataflow.new.internal.FlowSummaryImpl import semmle.python.ApiGraphs @@ -16,6 +16,6 @@ query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) Private::External::invalidSpecComponent(s, c) } -from DataFlow::PathNode source, DataFlow::PathNode sink, TestConfiguration conf -where conf.hasFlowPath(source, sink) +from TestFlow::PathNode source, TestFlow::PathNode sink +where TestFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql index 048d530dd41..46263250a9b 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.ql @@ -1,6 +1,12 @@ import experimental.meta.InlineTaintTest import semmle.python.dataflow.new.BarrierGuards -class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { - override predicate isSanitizer(DataFlow::Node node) { node instanceof StringConstCompareBarrier } +module CustomSanitizerOverridesConfig implements DataFlow::ConfigSig { + predicate isSource = TestTaintTrackingConfig::isSource/1; + + predicate isSink = TestTaintTrackingConfig::isSink/1; + + predicate isBarrier(DataFlow::Node node) { node instanceof StringConstCompareBarrier } } + +import MakeInlineTaintTest<CustomSanitizerOverridesConfig> diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected index fdad063534b..6e4a1c072bc 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected @@ -1,25 +1,26 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures isSanitizer -| TestTaintTrackingConfiguration | test.py:21:39:21:39 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test.py:34:39:34:39 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test.py:52:28:52:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test.py:66:10:66:29 | ControlFlowNode for emulated_escaping() | -| TestTaintTrackingConfiguration | test_logical.py:33:28:33:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:40:28:40:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:48:28:48:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:53:28:53:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:92:28:92:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:103:28:103:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:111:28:111:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:130:28:130:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:137:28:137:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:148:28:148:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:151:28:151:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:158:28:158:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:167:24:167:24 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:176:24:176:24 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:185:24:185:24 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:193:24:193:24 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_reference.py:31:28:31:28 | ControlFlowNode for s | +| test.py:21:39:21:39 | ControlFlowNode for s | +| test.py:34:39:34:39 | ControlFlowNode for s | +| test.py:52:28:52:28 | ControlFlowNode for s | +| test.py:66:10:66:29 | ControlFlowNode for emulated_escaping() | +| test_logical.py:33:28:33:28 | ControlFlowNode for s | +| test_logical.py:40:28:40:28 | ControlFlowNode for s | +| test_logical.py:48:28:48:28 | ControlFlowNode for s | +| test_logical.py:53:28:53:28 | ControlFlowNode for s | +| test_logical.py:92:28:92:28 | ControlFlowNode for s | +| test_logical.py:103:28:103:28 | ControlFlowNode for s | +| test_logical.py:111:28:111:28 | ControlFlowNode for s | +| test_logical.py:130:28:130:28 | ControlFlowNode for s | +| test_logical.py:137:28:137:28 | ControlFlowNode for s | +| test_logical.py:148:28:148:28 | ControlFlowNode for s | +| test_logical.py:151:28:151:28 | ControlFlowNode for s | +| test_logical.py:158:28:158:28 | ControlFlowNode for s | +| test_logical.py:167:24:167:24 | ControlFlowNode for s | +| test_logical.py:176:24:176:24 | ControlFlowNode for s | +| test_logical.py:185:24:185:24 | ControlFlowNode for s | +| test_logical.py:193:24:193:24 | ControlFlowNode for s | +| test_reference.py:31:28:31:28 | ControlFlowNode for s | diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql index 984cf74d036..597f368b02f 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql @@ -12,8 +12,12 @@ predicate isUnsafeCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean bra branch = false } -class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { - override predicate isSanitizer(DataFlow::Node node) { +module CustomSanitizerOverridesConfig implements DataFlow::ConfigSig { + predicate isSource = TestTaintTrackingConfig::isSource/1; + + predicate isSink = TestTaintTrackingConfig::isSink/1; + + predicate isBarrier(DataFlow::Node node) { exists(Call call | call.getFunc().(Name).getId() = "emulated_authentication_check" and call.getArg(0) = node.asExpr() @@ -27,7 +31,9 @@ class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { } } -query predicate isSanitizer(TestTaintTrackingConfiguration conf, DataFlow::Node node) { +import MakeInlineTaintTest<CustomSanitizerOverridesConfig> + +query predicate isSanitizer(DataFlow::Node node) { exists(node.getLocation().getFile().getRelativePath()) and - conf.isSanitizer(node) + CustomSanitizerOverridesConfig::isBarrier(node) } diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/experimental/dataflow/testConfig.qll b/python/ql/test/experimental/dataflow/testConfig.qll index ab5f125d898..887f9e48e8e 100644 --- a/python/ql/test/experimental/dataflow/testConfig.qll +++ b/python/ql/test/experimental/dataflow/testConfig.qll @@ -23,10 +23,8 @@ private import python import semmle.python.dataflow.new.DataFlow -class TestConfiguration extends DataFlow::Configuration { - TestConfiguration() { this = "TestConfiguration" } - - override predicate isSource(DataFlow::Node node) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "SOURCE" or node.(DataFlow::CfgNode).getNode().getNode().(StrConst).getS() = "source" @@ -37,7 +35,7 @@ class TestConfiguration extends DataFlow::Configuration { // No support for complex numbers } - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { exists(DataFlow::CallCfgNode call | call.getFunction().asCfgNode().(NameNode).getId() in ["SINK", "SINK_F"] and (node = call.getArg(_) or node = call.getArgByName(_)) and @@ -45,5 +43,7 @@ class TestConfiguration extends DataFlow::Configuration { ) } - override predicate isBarrierIn(DataFlow::Node node) { this.isSource(node) } + predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } + +module TestFlow = DataFlow::Global<TestConfig>; diff --git a/python/ql/test/experimental/dataflow/testTaintConfig.qll b/python/ql/test/experimental/dataflow/testTaintConfig.qll index 09496895c9a..89e9593c89f 100644 --- a/python/ql/test/experimental/dataflow/testTaintConfig.qll +++ b/python/ql/test/experimental/dataflow/testTaintConfig.qll @@ -24,10 +24,8 @@ private import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -class TestConfiguration extends TaintTracking::Configuration { - TestConfiguration() { this = "TestConfiguration" } - - override predicate isSource(DataFlow::Node node) { +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "SOURCE" or node.(DataFlow::CfgNode).getNode().getNode().(StrConst).getS() = "source" @@ -38,12 +36,14 @@ class TestConfiguration extends TaintTracking::Configuration { // No support for complex numbers } - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { exists(CallNode call | call.getFunction().(NameNode).getId() in ["SINK", "SINK_F"] and node.(DataFlow::CfgNode).getNode() = call.getAnArg() ) } - override predicate isSanitizerIn(DataFlow::Node node) { this.isSource(node) } + predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } + +module TestFlow = TaintTracking::Global<TestConfig>; diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.expected b/python/ql/test/experimental/dataflow/typetracking/tracked.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/typetracking/tracked.expected +++ b/python/ql/test/experimental/dataflow/typetracking/tracked.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.ql b/python/ql/test/experimental/dataflow/typetracking/tracked.ql index c0ed62e258f..b6aa9d268d0 100644 --- a/python/ql/test/experimental/dataflow/typetracking/tracked.ql +++ b/python/ql/test/experimental/dataflow/typetracking/tracked.ql @@ -14,12 +14,10 @@ private DataFlow::TypeTrackingNode tracked(TypeTracker t) { exists(TypeTracker t2 | result = tracked(t2).track(t2, t)) } -class TrackedTest extends InlineExpectationsTest { - TrackedTest() { this = "TrackedTest" } +module TrackedTest implements TestSig { + string getARelevantTag() { result = "tracked" } - override string getARelevantTag() { result = "tracked" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Node e, TypeTracker t | tracked(t).flowsTo(e) and // Module variables have no sensible location, and hence can't be annotated. @@ -54,12 +52,10 @@ private DataFlow::TypeTrackingNode string_type(TypeTracker t) { exists(TypeTracker t2 | result = string_type(t2).track(t2, t)) } -class TrackedIntTest extends InlineExpectationsTest { - TrackedIntTest() { this = "TrackedIntTest" } +module TrackedIntTest implements TestSig { + string getARelevantTag() { result = "int" } - override string getARelevantTag() { result = "int" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Node e, TypeTracker t | int_type(t).flowsTo(e) and tag = "int" and @@ -70,12 +66,10 @@ class TrackedIntTest extends InlineExpectationsTest { } } -class TrackedStringTest extends InlineExpectationsTest { - TrackedStringTest() { this = "TrackedStringTest" } +module TrackedStringTest implements TestSig { + string getARelevantTag() { result = "str" } - override string getARelevantTag() { result = "str" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Node e, TypeTracker t | string_type(t).flowsTo(e) and tag = "str" and @@ -100,12 +94,10 @@ private DataFlow::TypeTrackingNode tracked_self(TypeTracker t) { exists(TypeTracker t2 | result = tracked_self(t2).track(t2, t)) } -class TrackedSelfTest extends InlineExpectationsTest { - TrackedSelfTest() { this = "TrackedSelfTest" } +module TrackedSelfTest implements TestSig { + string getARelevantTag() { result = "tracked_self" } - override string getARelevantTag() { result = "tracked_self" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Node e, TypeTracker t | tracked_self(t).flowsTo(e) and // Module variables have no sensible location, and hence can't be annotated. @@ -161,12 +153,10 @@ private DataFlow::TypeTrackingNode foo_bar_baz(DataFlow::TypeTracker t) { /** Gets a reference to `foo.bar.baz` (fictive attribute on `foo.bar` module). */ DataFlow::Node foo_bar_baz() { foo_bar_baz(DataFlow::TypeTracker::end()).flowsTo(result) } -class TrackedFooBarBaz extends InlineExpectationsTest { - TrackedFooBarBaz() { this = "TrackedFooBarBaz" } +module TrackedFooBarBaz implements TestSig { + string getARelevantTag() { result = "tracked_foo_bar_baz" } - override string getARelevantTag() { result = "tracked_foo_bar_baz" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlow::Node e | e = foo_bar_baz() and // Module variables have no sensible location, and hence can't be annotated. @@ -178,3 +168,5 @@ class TrackedFooBarBaz extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests5<TrackedTest, TrackedIntTest, TrackedStringTest, TrackedSelfTest, TrackedFooBarBaz>> diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected b/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected +++ b/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql b/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql index 68d15822cf6..a1c754e8ee5 100644 --- a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql +++ b/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.ql @@ -7,7 +7,7 @@ module CaptureTest implements TestSig { string getARelevantTag() { result = "captured" } predicate hasActualResult(Location location, string element, string tag, string value) { - exists(DataFlow::Node sink | exists(TestConfiguration cfg | cfg.hasFlowTo(sink)) | + exists(DataFlow::Node sink | TestFlow::flowTo(sink) | location = sink.getLocation() and tag = "captured" and value = "" and diff --git a/python/ql/test/experimental/meta/ConceptsTest.qll b/python/ql/test/experimental/meta/ConceptsTest.qll index 27c8cb99ab4..48803e11fb4 100644 --- a/python/ql/test/experimental/meta/ConceptsTest.qll +++ b/python/ql/test/experimental/meta/ConceptsTest.qll @@ -4,12 +4,10 @@ import semmle.python.Concepts import TestUtilities.InlineExpectationsTest private import semmle.python.dataflow.new.internal.PrintNode -class SystemCommandExecutionTest extends InlineExpectationsTest { - SystemCommandExecutionTest() { this = "SystemCommandExecutionTest" } +module SystemCommandExecutionTest implements TestSig { + string getARelevantTag() { result = "getCommand" } - override string getARelevantTag() { result = "getCommand" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(SystemCommandExecution sce, DataFlow::Node command | command = sce.getCommand() and @@ -21,14 +19,12 @@ class SystemCommandExecutionTest extends InlineExpectationsTest { } } -class DecodingTest extends InlineExpectationsTest { - DecodingTest() { this = "DecodingTest" } - - override string getARelevantTag() { +module DecodingTest implements TestSig { + string getARelevantTag() { result in ["decodeInput", "decodeOutput", "decodeFormat", "decodeMayExecuteInput"] } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Decoding d | exists(DataFlow::Node data | @@ -61,12 +57,10 @@ class DecodingTest extends InlineExpectationsTest { } } -class EncodingTest extends InlineExpectationsTest { - EncodingTest() { this = "EncodingTest" } +module EncodingTest implements TestSig { + string getARelevantTag() { result in ["encodeInput", "encodeOutput", "encodeFormat"] } - override string getARelevantTag() { result in ["encodeInput", "encodeOutput", "encodeFormat"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Encoding e | exists(DataFlow::Node data | @@ -93,12 +87,10 @@ class EncodingTest extends InlineExpectationsTest { } } -class LoggingTest extends InlineExpectationsTest { - LoggingTest() { this = "LoggingTest" } +module LoggingTest implements TestSig { + string getARelevantTag() { result = "loggingInput" } - override string getARelevantTag() { result = "loggingInput" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Logging logging, DataFlow::Node data | location = data.getLocation() and @@ -110,12 +102,10 @@ class LoggingTest extends InlineExpectationsTest { } } -class CodeExecutionTest extends InlineExpectationsTest { - CodeExecutionTest() { this = "CodeExecutionTest" } +module CodeExecutionTest implements TestSig { + string getARelevantTag() { result = "getCode" } - override string getARelevantTag() { result = "getCode" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(CodeExecution ce, DataFlow::Node code | exists(location.getFile().getRelativePath()) and @@ -128,12 +118,10 @@ class CodeExecutionTest extends InlineExpectationsTest { } } -class SqlConstructionTest extends InlineExpectationsTest { - SqlConstructionTest() { this = "SqlConstructionTest" } +module SqlConstructionTest implements TestSig { + string getARelevantTag() { result = "constructedSql" } - override string getARelevantTag() { result = "constructedSql" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(SqlConstruction e, DataFlow::Node sql | exists(location.getFile().getRelativePath()) and @@ -146,12 +134,10 @@ class SqlConstructionTest extends InlineExpectationsTest { } } -class SqlExecutionTest extends InlineExpectationsTest { - SqlExecutionTest() { this = "SqlExecutionTest" } +module SqlExecutionTest implements TestSig { + string getARelevantTag() { result = "getSql" } - override string getARelevantTag() { result = "getSql" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(SqlExecution e, DataFlow::Node sql | exists(location.getFile().getRelativePath()) and @@ -164,12 +150,10 @@ class SqlExecutionTest extends InlineExpectationsTest { } } -class XPathConstructionTest extends InlineExpectationsTest { - XPathConstructionTest() { this = "XPathConstructionTest" } +module XPathConstructionTest implements TestSig { + string getARelevantTag() { result = "constructedXPath" } - override string getARelevantTag() { result = "constructedXPath" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(XML::XPathConstruction e, DataFlow::Node xpath | exists(location.getFile().getRelativePath()) and @@ -182,12 +166,10 @@ class XPathConstructionTest extends InlineExpectationsTest { } } -class XPathExecutionTest extends InlineExpectationsTest { - XPathExecutionTest() { this = "XPathExecutionTest" } +module XPathExecutionTest implements TestSig { + string getARelevantTag() { result = "getXPath" } - override string getARelevantTag() { result = "getXPath" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(XML::XPathExecution e, DataFlow::Node xpath | exists(location.getFile().getRelativePath()) and @@ -200,12 +182,10 @@ class XPathExecutionTest extends InlineExpectationsTest { } } -class EscapingTest extends InlineExpectationsTest { - EscapingTest() { this = "EscapingTest" } +module EscapingTest implements TestSig { + string getARelevantTag() { result in ["escapeInput", "escapeOutput", "escapeKind"] } - override string getARelevantTag() { result in ["escapeInput", "escapeOutput", "escapeKind"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Escaping esc | exists(DataFlow::Node data | @@ -232,12 +212,10 @@ class EscapingTest extends InlineExpectationsTest { } } -class HttpServerRouteSetupTest extends InlineExpectationsTest { - HttpServerRouteSetupTest() { this = "HttpServerRouteSetupTest" } +module HttpServerRouteSetupTest implements TestSig { + string getARelevantTag() { result = "routeSetup" } - override string getARelevantTag() { result = "routeSetup" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Http::Server::RouteSetup setup | location = setup.getLocation() and @@ -253,12 +231,10 @@ class HttpServerRouteSetupTest extends InlineExpectationsTest { } } -class HttpServerRequestHandlerTest extends InlineExpectationsTest { - HttpServerRequestHandlerTest() { this = "HttpServerRequestHandlerTest" } +module HttpServerRequestHandlerTest implements TestSig { + string getARelevantTag() { result in ["requestHandler", "routedParameter"] } - override string getARelevantTag() { result in ["requestHandler", "routedParameter"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and ( exists(Http::Server::RequestHandler handler | @@ -330,12 +306,10 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest { } } -class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest { - HttpServerHttpRedirectResponseTest() { this = "HttpServerHttpRedirectResponseTest" } +module HttpServerHttpRedirectResponseTest implements TestSig { + string getARelevantTag() { result in ["HttpRedirectResponse", "redirectLocation"] } - override string getARelevantTag() { result in ["HttpRedirectResponse", "redirectLocation"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and ( exists(Http::Server::HttpRedirectResponse redirect | @@ -355,14 +329,12 @@ class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest { } } -class HttpServerCookieWriteTest extends InlineExpectationsTest { - HttpServerCookieWriteTest() { this = "HttpServerCookieWriteTest" } - - override string getARelevantTag() { +module HttpServerCookieWriteTest implements TestSig { + string getARelevantTag() { result in ["CookieWrite", "CookieRawHeader", "CookieName", "CookieValue"] } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Http::Server::CookieWrite cookieWrite | location = cookieWrite.getLocation() and @@ -387,12 +359,10 @@ class HttpServerCookieWriteTest extends InlineExpectationsTest { } } -class FileSystemAccessTest extends InlineExpectationsTest { - FileSystemAccessTest() { this = "FileSystemAccessTest" } +module FileSystemAccessTest implements TestSig { + string getARelevantTag() { result = "getAPathArgument" } - override string getARelevantTag() { result = "getAPathArgument" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(FileSystemAccess a, DataFlow::Node path | path = a.getAPathArgument() and @@ -404,12 +374,10 @@ class FileSystemAccessTest extends InlineExpectationsTest { } } -class FileSystemWriteAccessTest extends InlineExpectationsTest { - FileSystemWriteAccessTest() { this = "FileSystemWriteAccessTest" } +module FileSystemWriteAccessTest implements TestSig { + string getARelevantTag() { result = "fileWriteData" } - override string getARelevantTag() { result = "fileWriteData" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(FileSystemWriteAccess write, DataFlow::Node data | data = write.getADataNode() and @@ -421,12 +389,10 @@ class FileSystemWriteAccessTest extends InlineExpectationsTest { } } -class PathNormalizationTest extends InlineExpectationsTest { - PathNormalizationTest() { this = "PathNormalizationTest" } +module PathNormalizationTest implements TestSig { + string getARelevantTag() { result = "pathNormalization" } - override string getARelevantTag() { result = "pathNormalization" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Path::PathNormalization n | location = n.getLocation() and @@ -437,12 +403,10 @@ class PathNormalizationTest extends InlineExpectationsTest { } } -class SafeAccessCheckTest extends InlineExpectationsTest { - SafeAccessCheckTest() { this = "SafeAccessCheckTest" } +module SafeAccessCheckTest implements TestSig { + string getARelevantTag() { result = "SafeAccessCheck" } - override string getARelevantTag() { result = "SafeAccessCheck" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Path::SafeAccessCheck c | location = c.getLocation() and @@ -453,12 +417,10 @@ class SafeAccessCheckTest extends InlineExpectationsTest { } } -class PublicKeyGenerationTest extends InlineExpectationsTest { - PublicKeyGenerationTest() { this = "PublicKeyGenerationTest" } +module PublicKeyGenerationTest implements TestSig { + string getARelevantTag() { result in ["PublicKeyGeneration", "keySize"] } - override string getARelevantTag() { result in ["PublicKeyGeneration", "keySize"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Cryptography::PublicKey::KeyGeneration keyGen | location = keyGen.getLocation() and @@ -475,17 +437,15 @@ class PublicKeyGenerationTest extends InlineExpectationsTest { } } -class CryptographicOperationTest extends InlineExpectationsTest { - CryptographicOperationTest() { this = "CryptographicOperationTest" } - - override string getARelevantTag() { +module CryptographicOperationTest implements TestSig { + string getARelevantTag() { result in [ "CryptographicOperation", "CryptographicOperationInput", "CryptographicOperationAlgorithm", "CryptographicOperationBlockMode" ] } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Cryptography::CryptographicOperation cryptoOperation | location = cryptoOperation.getLocation() and @@ -510,14 +470,12 @@ class CryptographicOperationTest extends InlineExpectationsTest { } } -class HttpClientRequestTest extends InlineExpectationsTest { - HttpClientRequestTest() { this = "HttpClientRequestTest" } - - override string getARelevantTag() { +module HttpClientRequestTest implements TestSig { + string getARelevantTag() { result in ["clientRequestUrlPart", "clientRequestCertValidationDisabled"] } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Http::Client::Request req, DataFlow::Node url | url = req.getAUrlPart() and @@ -538,12 +496,10 @@ class HttpClientRequestTest extends InlineExpectationsTest { } } -class CsrfProtectionSettingTest extends InlineExpectationsTest { - CsrfProtectionSettingTest() { this = "CsrfProtectionSettingTest" } +module CsrfProtectionSettingTest implements TestSig { + string getARelevantTag() { result = "CsrfProtectionSetting" } - override string getARelevantTag() { result = "CsrfProtectionSetting" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Http::Server::CsrfProtectionSetting setting | location = setting.getLocation() and @@ -554,12 +510,10 @@ class CsrfProtectionSettingTest extends InlineExpectationsTest { } } -class CsrfLocalProtectionSettingTest extends InlineExpectationsTest { - CsrfLocalProtectionSettingTest() { this = "CsrfLocalProtectionSettingTest" } +module CsrfLocalProtectionSettingTest implements TestSig { + string getARelevantTag() { result = "CsrfLocalProtection" + ["Enabled", "Disabled"] } - override string getARelevantTag() { result = "CsrfLocalProtection" + ["Enabled", "Disabled"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(Http::Server::CsrfLocalProtectionSetting p | location = p.getLocation() and @@ -572,12 +526,10 @@ class CsrfLocalProtectionSettingTest extends InlineExpectationsTest { } } -class XmlParsingTest extends InlineExpectationsTest { - XmlParsingTest() { this = "XmlParsingTest" } +module XmlParsingTest implements TestSig { + string getARelevantTag() { result = "xmlVuln" } - override string getARelevantTag() { result = "xmlVuln" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(XML::XmlParsing parsing, XML::XmlParsingVulnerabilityKind kind | parsing.vulnerableTo(kind) and @@ -588,3 +540,14 @@ class XmlParsingTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests5<MergeTests5<SystemCommandExecutionTest, DecodingTest, EncodingTest, LoggingTest, + CodeExecutionTest>, + MergeTests5<SqlConstructionTest, SqlExecutionTest, XPathConstructionTest, XPathExecutionTest, + EscapingTest>, + MergeTests4<HttpServerRouteSetupTest, HttpServerRequestHandlerTest, + HttpServerHttpRedirectResponseTest, HttpServerCookieWriteTest>, + MergeTests5<FileSystemAccessTest, FileSystemWriteAccessTest, PathNormalizationTest, + SafeAccessCheckTest, PublicKeyGenerationTest>, + MergeTests5<CryptographicOperationTest, HttpClientRequestTest, CsrfProtectionSettingTest, + CsrfLocalProtectionSettingTest, XmlParsingTest>>> diff --git a/python/ql/test/experimental/meta/InlineTaintTest.qll b/python/ql/test/experimental/meta/InlineTaintTest.qll index 9982ec961d4..24f67bcf2a4 100644 --- a/python/ql/test/experimental/meta/InlineTaintTest.qll +++ b/python/ql/test/experimental/meta/InlineTaintTest.qll @@ -33,10 +33,8 @@ DataFlow::Node shouldNotBeTainted() { // this module allows the configuration to be imported in other `.ql` files without the // top level query predicates of this file coming into scope. module Conf { - class TestTaintTrackingConfiguration extends TaintTracking::Configuration { - TestTaintTrackingConfiguration() { this = "TestTaintTrackingConfiguration" } - - override predicate isSource(DataFlow::Node source) { + module TestTaintTrackingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asCfgNode().(NameNode).getId() in [ "TAINTED_STRING", "TAINTED_BYTES", "TAINTED_LIST", "TAINTED_DICT" ] @@ -50,7 +48,7 @@ module Conf { source instanceof RemoteFlowSource } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { sink = shouldBeTainted() or sink = shouldNotBeTainted() @@ -60,49 +58,53 @@ module Conf { import Conf -class InlineTaintTest extends InlineExpectationsTest { - InlineTaintTest() { this = "InlineTaintTest" } +module MakeInlineTaintTest<DataFlow::ConfigSig Config> { + private module Flow = TaintTracking::Global<Config>; - override string getARelevantTag() { result = "tainted" } + private module InlineTaintTest implements TestSig { + string getARelevantTag() { result = "tainted" } - override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(location.getFile().getRelativePath()) and + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(location.getFile().getRelativePath()) and + exists(DataFlow::Node sink | + Flow::flowTo(sink) and + location = sink.getLocation() and + element = prettyExpr(sink.asExpr()) and + value = "" and + tag = "tainted" + ) + } + } + + import MakeTest<InlineTaintTest> + + query predicate argumentToEnsureNotTaintedNotMarkedAsSpurious( + Location location, string error, string element + ) { + error = "ERROR, you should add `SPURIOUS:` to this annotation" and + location = shouldNotBeTainted().getLocation() and + InlineTaintTest::hasActualResult(location, element, "tainted", _) and + exists(GoodTestExpectation good, ActualTestResult actualResult | + good.matchesActualResult(actualResult) and + actualResult.getLocation() = location and + actualResult.toString() = element + ) + } + + query predicate untaintedArgumentToEnsureTaintedNotMarkedAsMissing( + Location location, string error, string element + ) { + error = "ERROR, you should add `# $ MISSING: tainted` annotation" and exists(DataFlow::Node sink | - any(TestTaintTrackingConfiguration config).hasFlow(_, sink) and - location = sink.getLocation() and + sink = shouldBeTainted() and element = prettyExpr(sink.asExpr()) and - value = "" and - tag = "tainted" + not Flow::flowTo(sink) and + location = sink.getLocation() and + not exists(FalseNegativeTestExpectation missingResult | + missingResult.getTag() = "tainted" and + missingResult.getLocation().getFile() = location.getFile() and + missingResult.getLocation().getStartLine() = location.getStartLine() + ) ) } } - -query predicate argumentToEnsureNotTaintedNotMarkedAsSpurious( - Location location, string error, string element -) { - error = "ERROR, you should add `SPURIOUS:` to this annotation" and - location = shouldNotBeTainted().getLocation() and - any(InlineTaintTest test).hasActualResult(location, element, "tainted", _) and - exists(GoodExpectation good, ActualResult actualResult | - good.matchesActualResult(actualResult) and - actualResult.getLocation() = location and - actualResult.toString() = element - ) -} - -query predicate untaintedArgumentToEnsureTaintedNotMarkedAsMissing( - Location location, string error, string element -) { - error = "ERROR, you should add `# $ MISSING: tainted` annotation" and - exists(DataFlow::Node sink | - sink = shouldBeTainted() and - element = prettyExpr(sink.asExpr()) and - not any(TestTaintTrackingConfiguration config).hasFlow(_, sink) and - location = sink.getLocation() and - not exists(FalseNegativeExpectation missingResult | - missingResult.getTag() = "tainted" and - missingResult.getLocation().getFile() = location.getFile() and - missingResult.getLocation().getStartLine() = location.getStartLine() - ) - ) -} diff --git a/python/ql/test/experimental/meta/MaDTest.qll b/python/ql/test/experimental/meta/MaDTest.qll index a4b5877f5ea..9b6bd59287a 100644 --- a/python/ql/test/experimental/meta/MaDTest.qll +++ b/python/ql/test/experimental/meta/MaDTest.qll @@ -7,16 +7,14 @@ private import semmle.python.Frameworks // this import needs to be public to get the query predicates propagated to the actual test files import TestUtilities.InlineExpectationsTest -class MadSinkTest extends InlineExpectationsTest { - MadSinkTest() { this = "MadSinkTest" } - - override string getARelevantTag() { +module MadSinkTest implements TestSig { + string getARelevantTag() { exists(string kind | exists(ModelOutput::getASinkNode(kind)) | result = "mad-sink[" + kind + "]" ) } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(DataFlow::Node sink, string kind | sink = ModelOutput::getASinkNode(kind).asSink() and @@ -28,14 +26,12 @@ class MadSinkTest extends InlineExpectationsTest { } } -class MadSourceTest extends InlineExpectationsTest { - MadSourceTest() { this = "MadSourceTest" } - - override string getARelevantTag() { +module MadSourceTest implements TestSig { + string getARelevantTag() { exists(string kind | exists(ModelOutput::getASourceNode(kind)) | result = "mad-source__" + kind) } - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(DataFlow::Node source, string kind | source = ModelOutput::getASourceNode(kind).asSource() and @@ -46,3 +42,5 @@ class MadSourceTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests<MadSinkTest, MadSourceTest>> diff --git a/python/ql/test/experimental/meta/debug/InlineTaintTestPaths.ql b/python/ql/test/experimental/meta/debug/InlineTaintTestPaths.ql index 98ad634484e..3f082f21fa4 100644 --- a/python/ql/test/experimental/meta/debug/InlineTaintTestPaths.ql +++ b/python/ql/test/experimental/meta/debug/InlineTaintTestPaths.ql @@ -13,11 +13,9 @@ import semmle.python.dataflow.new.TaintTracking import experimental.meta.InlineTaintTest::Conf module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - any(TestTaintTrackingConfiguration c).isSource(source) - } + predicate isSource(DataFlow::Node source) { TestTaintTrackingConfig::isSource(source) } - predicate isSink(DataFlow::Node source) { any(TestTaintTrackingConfiguration c).isSink(source) } + predicate isSink(DataFlow::Node source) { TestTaintTrackingConfig::isSink(source) } } module Flows = TaintTracking::Global<Config>; diff --git a/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql b/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql index 087787f4fc1..3e2d625de77 100644 --- a/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql +++ b/python/ql/test/experimental/meta/debug/dataflowTestPaths.ql @@ -12,9 +12,9 @@ import semmle.python.dataflow.new.DataFlow import experimental.dataflow.testConfig module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { any(TestConfiguration c).isSource(source) } + predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) } - predicate isSink(DataFlow::Node source) { any(TestConfiguration c).isSink(source) } + predicate isSink(DataFlow::Node source) { TestConfig::isSink(source) } } module Flows = DataFlow::Global<Config>; diff --git a/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected b/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected index 745561a5e65..511dc50d5ca 100644 --- a/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected +++ b/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected @@ -1,7 +1,8 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious | taint_test.py:48:9:48:29 | taint_test.py:48 | ERROR, you should add `SPURIOUS:` to this annotation | should_not_be_tainted | untaintedArgumentToEnsureTaintedNotMarkedAsMissing | taint_test.py:32:9:32:25 | taint_test.py:32 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted | | taint_test.py:37:24:37:40 | taint_test.py:37 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted | -failures +testFailures | taint_test.py:41:20:41:21 | ts | Fixed missing result:tainted= | diff --git a/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.ql b/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.ql +++ b/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/DataflowQueryTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected b/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected +++ b/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected +++ b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.ql index 993da68784e..8fd0d08c56a 100644 --- a/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.ql @@ -1,7 +1,11 @@ import experimental.meta.InlineTaintTest import semmle.python.Concepts -class HtmlSpecialization extends TestTaintTrackingConfiguration { +module HtmlSpecializationConfig implements DataFlow::ConfigSig { + predicate isSource = TestTaintTrackingConfig::isSource/1; + + predicate isSink = TestTaintTrackingConfig::isSink/1; + // TODO: For now, since there is not an `isSanitizingStep` member-predicate part of a // `TaintTracking::Configuration`, we use treat the output is a taint-sanitizer. This // is slightly imprecise, which you can see in the `m_unsafe + SAFE` test-case in @@ -9,5 +13,7 @@ class HtmlSpecialization extends TestTaintTrackingConfiguration { // // However, it is better than `getAnInput()`. Due to use-use flow, that would remove // the taint-flow to `SINK()` in `some_escape(tainted); SINK(tainted)`. - override predicate isSanitizer(DataFlow::Node node) { node = any(HtmlEscaping esc).getOutput() } + predicate isBarrier(DataFlow::Node node) { node = any(HtmlEscaping esc).getOutput() } } + +import MakeInlineTaintTest<HtmlSpecializationConfig> diff --git a/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/rest_framework/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/rest_framework/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/rest_framework/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/rest_framework/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected +++ b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected index 79d760d87f4..4a72c551661 100644 --- a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected +++ b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected @@ -1,3 +1,4 @@ +failures argumentToEnsureNotTaintedNotMarkedAsSpurious untaintedArgumentToEnsureTaintedNotMarkedAsMissing -failures +testFailures diff --git a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.ql index 027ad8667be..8524da5fe7d 100644 --- a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.ql +++ b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.ql @@ -1 +1,2 @@ import experimental.meta.InlineTaintTest +import MakeInlineTaintTest<TestTaintTrackingConfig> diff --git a/python/ql/test/library-tests/regex/SubstructureTests.expected b/python/ql/test/library-tests/regex/SubstructureTests.expected index e69de29bb2d..48de9172b36 100644 --- a/python/ql/test/library-tests/regex/SubstructureTests.expected +++ b/python/ql/test/library-tests/regex/SubstructureTests.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/python/ql/test/library-tests/regex/SubstructureTests.ql b/python/ql/test/library-tests/regex/SubstructureTests.ql index e189c13b15e..f575670e16a 100644 --- a/python/ql/test/library-tests/regex/SubstructureTests.ql +++ b/python/ql/test/library-tests/regex/SubstructureTests.ql @@ -2,12 +2,10 @@ import python import TestUtilities.InlineExpectationsTest private import semmle.python.regex -class CharacterSetTest extends InlineExpectationsTest { - CharacterSetTest() { this = "CharacterSetTest" } +module CharacterSetTest implements TestSig { + string getARelevantTag() { result = "charSet" } - override string getARelevantTag() { result = "charSet" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and location.getFile().getBaseName() = "charSetTest.py" and exists(RegExp re, int start, int end | @@ -20,12 +18,10 @@ class CharacterSetTest extends InlineExpectationsTest { } } -class CharacterRangeTest extends InlineExpectationsTest { - CharacterRangeTest() { this = "CharacterRangeTest" } +module CharacterRangeTest implements TestSig { + string getARelevantTag() { result = "charRange" } - override string getARelevantTag() { result = "charRange" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and location.getFile().getBaseName() = "charRangeTest.py" and exists(RegExp re, int start, int lower_end, int upper_start, int end | @@ -38,12 +34,10 @@ class CharacterRangeTest extends InlineExpectationsTest { } } -class EscapeTest extends InlineExpectationsTest { - EscapeTest() { this = "EscapeTest" } +module EscapeTest implements TestSig { + string getARelevantTag() { result = "escapedCharacter" } - override string getARelevantTag() { result = "escapedCharacter" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and location.getFile().getBaseName() = "escapedCharacterTest.py" and exists(RegExp re, int start, int end | @@ -56,12 +50,10 @@ class EscapeTest extends InlineExpectationsTest { } } -class GroupTest extends InlineExpectationsTest { - GroupTest() { this = "GroupTest" } +module GroupTest implements TestSig { + string getARelevantTag() { result = "group" } - override string getARelevantTag() { result = "group" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and location.getFile().getBaseName() = "groupTest.py" and exists(RegExp re, int start, int end | @@ -73,3 +65,5 @@ class GroupTest extends InlineExpectationsTest { ) } } + +import MakeTest<MergeTests4<CharacterSetTest, CharacterRangeTest, EscapeTest, GroupTest>> diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected +++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected index 3875da4e143..04431311999 100644 --- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected +++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected @@ -1,2 +1,3 @@ missingAnnotationOnSink failures +testFailures From a01169eec2a29e1e8f74844c54232f2c48f1be19 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 14:22:39 +0100 Subject: [PATCH 675/739] add "Dereference" content for PointerContent --- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 2 ++ .../semmle/go/dataflow/ExternalFlow/completetest.ext.yml | 4 ++-- .../library-tests/semmle/go/dataflow/ExternalFlow/test.go | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 0c6ee1c3134..f04ce005794 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -342,6 +342,8 @@ predicate parseContent(string component, DataFlow::Content content) { component = "MapKey" and content instanceof DataFlow::MapKeyContent or component = "MapValue" and content instanceof DataFlow::MapValueContent + or + component = "Dereference" and content instanceof DataFlow::PointerContent } cached diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ext.yml index 4ec8602daaf..47e51e573f0 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/completetest.ext.yml @@ -22,9 +22,9 @@ extensions: - ["github.com/nonexistent/test", "", False, "GetMapKey", "", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] - ["github.com/nonexistent/test", "", False, "SetElement", "", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] - ["github.com/nonexistent/test", "C", False, "Get", "", "", "Argument[-1].Field[github.com/nonexistent/test.C.F]", "ReturnValue", "value", "manual"] - - ["github.com/nonexistent/test", "C", False, "GetThroughPointer", "", "", "Argument[-1].Field[github.com/nonexistent/test.C.F]", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "C", False, "GetThroughPointer", "", "", "Argument[-1].Dereference.Field[github.com/nonexistent/test.C.F]", "ReturnValue", "value", "manual"] - ["github.com/nonexistent/test", "C", False, "Set", "", "", "Argument[0]", "Argument[-1].Field[github.com/nonexistent/test.C.F]", "value", "manual"] - - ["github.com/nonexistent/test", "C", False, "SetThroughPointer", "", "", "Argument[0]", "Argument[-1].Field[github.com/nonexistent/test.C.F]", "value", "manual"] + - ["github.com/nonexistent/test", "C", False, "SetThroughPointer", "", "", "Argument[0]", "Argument[-1].Dereference.Field[github.com/nonexistent/test.C.F]", "value", "manual"] - addsTo: pack: codeql/go-all diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/test.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/test.go index 0d92787b65c..35da086a888 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/test.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlow/test.go @@ -143,10 +143,10 @@ func simpleflow() { cp1 := &test.C{""} cp1.SetThroughPointer(a.Src1().(string)) - b.Sink1(cp1.F) // $ MISSING: hasTaintFlow="selection of F" + b.Sink1(cp1.F) // $ hasTaintFlow="selection of F" cp2 := &test.C{a.Src1().(string)} - b.Sink1(cp2.GetThroughPointer()) // $ MISSING: hasTaintFlow="call to GetThroughPointer" + b.Sink1(cp2.GetThroughPointer()) // $ hasTaintFlow="call to GetThroughPointer" cp3 := &test.C{""} cp3.SetThroughPointer(a.Src1().(string)) From 81142f51fbede42d6ee5607b3546e3f0922c9d17 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Fri, 16 Jun 2023 13:33:41 +0100 Subject: [PATCH 676/739] Kotlin: Handle IrSyntheticBodyKind.ENUM_ENTRIES Generated by Kotlin 1.9 for some of our tests. --- .../src/main/kotlin/KotlinFileExtractor.kt | 11 ++++++----- .../utils/versions/v_1_4_32/SyntheticBodyKind.kt | 6 ++++++ .../utils/versions/v_1_8_0/SyntheticBodyKind.kt | 6 ++++++ java/ql/lib/config/semmlecode.dbscheme | 1 + 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/SyntheticBodyKind.kt create mode 100644 java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/SyntheticBodyKind.kt diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index a3bc20d9eda..8eece83083a 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -1701,12 +1701,13 @@ open class KotlinFileExtractor( private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label<out DbCallable>) { with("synthetic body", b) { - when (b.kind) { - IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1) - IrSyntheticBodyKind.ENUM_VALUEOF -> tw.writeKtSyntheticBody(callable, 2) + val kind = b.kind + when { + kind == IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1) + kind == IrSyntheticBodyKind.ENUM_VALUEOF -> tw.writeKtSyntheticBody(callable, 2) + kind == kind_ENUM_ENTRIES -> tw.writeKtSyntheticBody(callable, 3) else -> { - // TODO: Support IrSyntheticBodyKind.ENUM_ENTRIES - logger.errorElement("Unhandled synthetic body kind " + b.kind.javaClass, b) + logger.errorElement("Unhandled synthetic body kind " + kind, b) } } } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/SyntheticBodyKind.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/SyntheticBodyKind.kt new file mode 100644 index 00000000000..fd3fc1f8e20 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/SyntheticBodyKind.kt @@ -0,0 +1,6 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind + +val kind_ENUM_ENTRIES: IrSyntheticBodyKind? = null + diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/SyntheticBodyKind.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/SyntheticBodyKind.kt new file mode 100644 index 00000000000..d0dbb5b1247 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/SyntheticBodyKind.kt @@ -0,0 +1,6 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind + +val kind_ENUM_ENTRIES: IrSyntheticBodyKind? = IrSyntheticBodyKind.ENUM_ENTRIES + diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index 7cbc85b1f3e..ecfcf050952 100644 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -1219,6 +1219,7 @@ ktSyntheticBody( int kind: int ref // 1: ENUM_VALUES // 2: ENUM_VALUEOF + // 3: ENUM_ENTRIES ) ktLocalFunction( From 0076d8aac1161a8fc736ae158b67beae127bcda2 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Fri, 16 Jun 2023 13:36:31 +0100 Subject: [PATCH 677/739] Java: Add up/downgrade scripts --- .../old.dbscheme | 1256 +++++++++++++++++ .../semmlecode.dbscheme | 1255 ++++++++++++++++ .../upgrade.properties | 2 + .../old.dbscheme | 1255 ++++++++++++++++ .../semmlecode.dbscheme | 1256 +++++++++++++++++ .../upgrade.properties | 2 + 6 files changed, 5026 insertions(+) create mode 100644 java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/old.dbscheme create mode 100644 java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/semmlecode.dbscheme create mode 100644 java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/upgrade.properties create mode 100644 java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme create mode 100644 java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme create mode 100644 java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties diff --git a/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/old.dbscheme b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/old.dbscheme new file mode 100644 index 00000000000..ecfcf050952 --- /dev/null +++ b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/old.dbscheme @@ -0,0 +1,1256 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF + // 3: ENUM_ENTRIES +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/semmlecode.dbscheme b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/semmlecode.dbscheme new file mode 100644 index 00000000000..7cbc85b1f3e --- /dev/null +++ b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/semmlecode.dbscheme @@ -0,0 +1,1255 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/upgrade.properties b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/upgrade.properties new file mode 100644 index 00000000000..5ba64f71d70 --- /dev/null +++ b/java/downgrades/ecfcf050952e54b1155fc89525db84af6ad34aaf/upgrade.properties @@ -0,0 +1,2 @@ +description: Remove ENUM_ENTRIES +compatibility: full diff --git a/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme new file mode 100644 index 00000000000..7cbc85b1f3e --- /dev/null +++ b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/old.dbscheme @@ -0,0 +1,1255 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme new file mode 100644 index 00000000000..ecfcf050952 --- /dev/null +++ b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/semmlecode.dbscheme @@ -0,0 +1,1256 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +compilation_info( + int id : @compilation ref, + string info_key: string ref, + string info_value: string ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@@@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes_or_interfaces( + unique int id: @classorinterface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @classorinterface ref +); + +file_class( + int id: @classorinterface ref +); + +class_object( + unique int id: @classorinterface ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @classorinterface ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isInterface( + unique int id: @classorinterface ref +); + +isRecord( + unique int id: @classorinterface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @classorinterface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @classorinterface ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @classorinterface ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @classorinterface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @classorinterface | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar | @typevariable; + +@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF + // 3: ENUM_ENTRIES +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) + +ktDataClasses( + unique int id: @classorinterface ref +) diff --git a/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties new file mode 100644 index 00000000000..47074bcc8ab --- /dev/null +++ b/java/ql/lib/upgrades/7cbc85b1f3ecda39661ad4806dedbd0973d2c4c0/upgrade.properties @@ -0,0 +1,2 @@ +description: Add ENUM_ENTRIES +compatibility: full From 293f90333d1929bcb1317abf9323896c3bf1d473 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Fri, 16 Jun 2023 17:04:47 +0100 Subject: [PATCH 678/739] Kotlin: Avoid another cause of ConcurrentModificationException with 1.9 --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 8eece83083a..39fd82a77ea 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -5317,7 +5317,10 @@ open class KotlinFileExtractor( private fun extractTypeAccessRecursive(t: IrType, location: Label<out DbLocation>, parent: Label<out DbExprparent>, idx: Int, typeContext: TypeContext = TypeContext.OTHER): Label<out DbExpr> { val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx) if (t is IrSimpleType) { - t.arguments.forEachIndexed { argIdx, arg -> + // From 1.9, the list might change when we call erase, + // so we make a copy that it is safe to iterate over. + val argumentsCopy = t.arguments.toList() + argumentsCopy.forEachIndexed { argIdx, arg -> extractWildcardTypeAccessRecursive(arg, location, typeAccessId, argIdx) } } From 732b14ee3800204db6c9820f33e2cf6a50c8bb95 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Tue, 20 Jun 2023 11:04:03 +0100 Subject: [PATCH 679/739] Update pretty printing predicates --- .../lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll index 41ae6b50ce3..609790659f8 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImplSpecific.qll @@ -106,6 +106,8 @@ private string getContentSpecific(Content c) { c instanceof MapKeyContent and result = "MapKey" or c instanceof MapValueContent and result = "MapValue" + or + c instanceof PointerContent and result = "Dereference" } /** Gets the textual representation of the content in the format used for flow summaries. */ From 04ff89e1feecc7b6240c5d9e6d580cc09ca50f03 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Tue, 20 Jun 2023 11:05:05 +0100 Subject: [PATCH 680/739] Update access path documentation --- .../lib/semmle/code/csharp/dataflow/ExternalFlow.qll | 4 ++-- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 46a19828a81..fbf5217a7f0 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -62,8 +62,8 @@ * in the given range. The range is inclusive at both ends. * - "ReturnValue": Selects the return value of a call to the selected element. * - * For summaries, `input` and `output` may be prefixed by one of the following, - * separated by the "of" keyword: + * For summaries, `input` and `output` may be suffixed by any number of the + * following, separated by ".": * - "Element": Selects an element in a collection. * - "Field[f]": Selects the contents of field `f`. * - "Property[p]": Selects the contents of property `p`. diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index f04ce005794..ab46c9206e8 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -54,6 +54,18 @@ * return value. The return values are zero-indexed * - "ReturnValue[n1..n2]": Similar to "ReturnValue[n]" but selects any * return value in the given range. The range is inclusive at both ends. + * + * For summaries, `input` and `output` may be suffixed by any number of the + * following, separated by ".": + * - "Field[pkg.className.fieldname]": Selects the contents of the field `f` + * which satisfies `f.hasQualifiedName(pkg, className, fieldname)`. + * - "SyntheticField[f]": Selects the contents of the synthetic field `f`. + * - "ArrayElement": Selects an element in an array or slice. + * - "Element": Selects an element in a collection. + * - "MapKey": Selects a key in a map. + * - "MapValue": Selects a value in a map. + * - "Dereference": Selects the value referenced by a pointer. + * * 8. The `kind` column is a tag that can be referenced from QL to determine to * which classes the interpreted elements should be added. For example, for * sources "remote" indicates a default remote flow source, and for summaries From 18b678e69e211d91a704c97567d7a12c9e5ef174 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions@github.com> Date: Tue, 20 Jun 2023 10:20:05 +0000 Subject: [PATCH 681/739] Post-release preparation for codeql-cli-2.13.4 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 2d39cafe571..0065372f811 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.7.3 +version: 0.7.4-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 1aa38f466f6..077b34194fb 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.6.3 +version: 0.6.4-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index d48f3cb1b0a..5f8c63b8ea3 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.5.3 +version: 1.5.4-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index f63efb58811..65153d150f7 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.5.3 +version: 1.5.4-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 833f7eae10b..9ead1290662 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.6.3 +version: 0.6.4-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 0ae9d1d6c03..91cba09b8ac 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.6.3 +version: 0.6.4-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index ce44cff6d9e..0fe9af73882 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.5.3 +version: 0.5.4-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 65c84860754..ad8b0d5db16 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.5.3 +version: 0.5.4-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 8a18f2bdabb..81392376fd1 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.6.3 +version: 0.6.4-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index b52ce1fd59c..b75aea1c0a0 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.6.3 +version: 0.6.4-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index bda9945c1c3..021a8719e54 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.6.3 +version: 0.6.4-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 6df72dd450f..a1a1ed2b4f2 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.6.3 +version: 0.6.4-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 60af5875e10..f07f050124a 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.5.3 +version: 0.5.4-dev groups: shared diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 101ed2a7232..ff2c246a618 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.9.3 +version: 0.9.4-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 3c274ee84a9..7dd13516d8b 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.7.3 +version: 0.7.4-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 2591c99f5cf..d7c154febf3 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.6.3 +version: 0.6.4-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index f98583c5f80..6e1eb058cd4 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.6.3 +version: 0.6.4-dev groups: - ruby - queries diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 63d34ec6329..03c1586d407 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.14 +version: 0.0.15-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index be427812ded..c3fdb224479 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.0.18 +version: 0.0.19-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 9d655dcca3e..7dc19224a82 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.0.11 +version: 0.0.12-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index ca6b6a9c76e..09ae3c23605 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.0.11 +version: 0.0.12-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index b3796de8fa1..65a104d1f01 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.0.18 +version: 0.0.19-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index f48343df59f..5dce17506ce 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.0.11 +version: 0.0.12-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index e379f9bd9e1..ffbf802a8c4 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.0.3 +version: 0.0.4-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 5993dfaefcf..ccce91fd9c1 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.1.1 +version: 0.1.2-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 3393d61d8d6..9fac028053b 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.1.1 +version: 0.1.2-dev groups: - swift - queries From 7837959bdf10790606f5e90e63d8a11f913d1fa0 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 20 Jun 2023 11:58:32 +0200 Subject: [PATCH 682/739] QL: Add query to find Android queries with improper ids --- ql/ql/src/queries/style/AndroidIdPrefix.ql | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 ql/ql/src/queries/style/AndroidIdPrefix.ql diff --git a/ql/ql/src/queries/style/AndroidIdPrefix.ql b/ql/ql/src/queries/style/AndroidIdPrefix.ql new file mode 100644 index 00000000000..46071b08784 --- /dev/null +++ b/ql/ql/src/queries/style/AndroidIdPrefix.ql @@ -0,0 +1,32 @@ +/** + * @name Android query without android @id prefix + * @description Android queries should include the `android` prefix in their `@id`. + * @kind problem + * @problem.severity warning + * @id ql/android-id-prefix + * @precision high + */ + +import ql + +string getIdProperty(QLDoc doc) { + result = any(string id | id = doc.getContents().splitAt("@") and id.matches("id %")) +} + +predicate importsAndroidModule(TopLevel t) { + exists(Import i | t.getAnImport() = i | + i.getImportString().toLowerCase().matches("%android%") + or + exists(TopLevel t2 | + t2.getAModule() = i.getResolvedModule().asModule() and + importsAndroidModule(t2) + ) + ) +} + +from TopLevel t +where + t.getLocation().getFile().getRelativePath().matches("%src/Security/%.ql") and + not getIdProperty(t.getQLDoc()).matches("% java/android/%") and + importsAndroidModule(t) +select t, "This Android query is missing the `android` prefix in its `@id`." From 150854603b147f5e6eb70472ea851de25f09ce1e Mon Sep 17 00:00:00 2001 From: Tiago Pascoal <tspascoal@github.com> Date: Tue, 20 Jun 2023 11:38:27 +0100 Subject: [PATCH 683/739] Single quote was preventing the shell from expanding the BODY variable While this prevents the attack highlighted in the query help it also prevents it from working. Double quotes will allow the expansion of the variable while still preventing the attack --- .../ql/src/Security/CWE-094/examples/comment_issue_good.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-094/examples/comment_issue_good.yml b/javascript/ql/src/Security/CWE-094/examples/comment_issue_good.yml index 22d6554076c..07254a8b204 100644 --- a/javascript/ql/src/Security/CWE-094/examples/comment_issue_good.yml +++ b/javascript/ql/src/Security/CWE-094/examples/comment_issue_good.yml @@ -7,4 +7,4 @@ jobs: - env: BODY: ${{ github.event.issue.body }} run: | - echo '$BODY' \ No newline at end of file + echo "$BODY" From e4e91c7ab08054af8014b4c421205e421cb49d70 Mon Sep 17 00:00:00 2001 From: Philip Ginsbach <ginsbach@github.com> Date: Tue, 20 Jun 2023 12:17:43 +0100 Subject: [PATCH 684/739] mention how instantiation-nested predicates are treated in stratification and evaluation --- docs/codeql/ql-language-reference/ql-language-specification.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 32244023c21..3cd76fc0512 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -2046,6 +2046,8 @@ A valid stratification must include each predicate and type in the QL program th A valid stratification must not include the same predicate in multiple layers. +Each non-abstract predicate has an associated body. For predicates inside *declared modules*, this is the predicate declaration. The body of an *instantiation-nested* predicate is the body of the *underlying nested* predicate where all references and calls have been substituted with the *instantiation-relative* entity or alias. + Formulas, variable declarations and expressions within a predicate body have a *negation polarity* that is positive, negative, or zero. Positive and negative are opposites of each other, while zero is the opposite of itself. The negation polarity of a formula or expression is then determined as follows: - The body of a predicate is positive. From cc320c5e9cc217709bd10b5ac4b0cbe5d94de56d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Wed, 14 Jun 2023 15:44:47 +0100 Subject: [PATCH 685/739] Never skip functionmodel inputs and outputs in path summaries --- go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 277c92703e7..99d22d5c4e8 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -232,7 +232,11 @@ class CastNode extends ExprNode { * Holds if `n` should never be skipped over in the `PathGraph` and in path * explanations. */ -predicate neverSkipInPathGraph(Node n) { none() } +predicate neverSkipInPathGraph(Node n) { + exists(DataFlow::FunctionModel fm | fm.getAnInputNode(_) = n or fm.getAnOutputNode(_) = n) + or + exists(TaintTracking::FunctionModel fm | fm.getAnInputNode(_) = n or fm.getAnOutputNode(_) = n) +} class DataFlowExpr = Expr; From c0fea8538033820f6bfff97fb86c2fde13fa2ea2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Fri, 16 Jun 2023 16:13:11 +0100 Subject: [PATCH 686/739] Accept test changes --- .../CWE-134/DsnInjection.expected | 6 +- .../CWE-134/DsnInjectionLocal.expected | 19 ++++-- go/ql/test/experimental/CWE-918/SSRF.expected | 24 +++++-- .../go/frameworks/Beego/ReflectedXss.expected | 4 +- .../Security/CWE-022/TaintedPath.expected | 4 +- .../Security/CWE-022/ZipSlip.expected | 4 +- .../CWE-078/CommandInjection.expected | 62 ++++++++++++++++--- .../Security/CWE-078/StoredCommand.expected | 7 ++- .../Security/CWE-079/ReflectedXss.expected | 24 +++++-- .../Security/CWE-079/StoredXss.expected | 7 ++- .../Security/CWE-089/SqlInjection.expected | 44 ++++++++++--- .../Security/CWE-327/UnsafeTLS.expected | 22 ++++++- .../InsecureRandomness.expected | 8 ++- .../CWE-352/ConstantOauth2State.expected | 4 +- 14 files changed, 194 insertions(+), 45 deletions(-) diff --git a/go/ql/test/experimental/CWE-134/DsnInjection.expected b/go/ql/test/experimental/CWE-134/DsnInjection.expected index de054067a01..531bdb0ead2 100644 --- a/go/ql/test/experimental/CWE-134/DsnInjection.expected +++ b/go/ql/test/experimental/CWE-134/DsnInjection.expected @@ -1,7 +1,11 @@ edges -| Dsn.go:47:10:47:30 | call to FormValue | Dsn.go:50:29:50:33 | dbDSN | +| Dsn.go:47:10:47:30 | call to FormValue | Dsn.go:49:102:49:105 | name | +| Dsn.go:49:11:49:106 | call to Sprintf | Dsn.go:50:29:50:33 | dbDSN | +| Dsn.go:49:102:49:105 | name | Dsn.go:49:11:49:106 | call to Sprintf | nodes | Dsn.go:47:10:47:30 | call to FormValue | semmle.label | call to FormValue | +| Dsn.go:49:11:49:106 | call to Sprintf | semmle.label | call to Sprintf | +| Dsn.go:49:102:49:105 | name | semmle.label | name | | Dsn.go:50:29:50:33 | dbDSN | semmle.label | dbDSN | subpaths #select diff --git a/go/ql/test/experimental/CWE-134/DsnInjectionLocal.expected b/go/ql/test/experimental/CWE-134/DsnInjectionLocal.expected index de5e959d43f..762c5bf3e04 100644 --- a/go/ql/test/experimental/CWE-134/DsnInjectionLocal.expected +++ b/go/ql/test/experimental/CWE-134/DsnInjectionLocal.expected @@ -1,25 +1,34 @@ edges -| Dsn.go:26:11:26:17 | selection of Args | Dsn.go:29:29:29:33 | dbDSN | +| Dsn.go:26:11:26:17 | selection of Args | Dsn.go:28:102:28:109 | index expression | +| Dsn.go:28:11:28:110 | call to Sprintf | Dsn.go:29:29:29:33 | dbDSN | +| Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | call to Sprintf | | Dsn.go:62:2:62:4 | definition of cfg [pointer] | Dsn.go:63:9:63:11 | cfg [pointer] | | Dsn.go:62:2:62:4 | definition of cfg [pointer] | Dsn.go:67:102:67:104 | cfg [pointer] | | Dsn.go:63:9:63:11 | cfg [pointer] | Dsn.go:63:9:63:11 | implicit dereference | | Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:62:2:62:4 | definition of cfg [pointer] | | Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:63:9:63:11 | implicit dereference | -| Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:68:29:68:33 | dbDSN | -| Dsn.go:63:19:63:25 | selection of Args | Dsn.go:63:9:63:11 | implicit dereference | -| Dsn.go:63:19:63:25 | selection of Args | Dsn.go:68:29:68:33 | dbDSN | +| Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:67:102:67:108 | selection of dsn | +| Dsn.go:63:19:63:25 | selection of Args | Dsn.go:63:19:63:29 | slice expression | +| Dsn.go:63:19:63:29 | slice expression | Dsn.go:63:9:63:11 | implicit dereference | +| Dsn.go:67:11:67:109 | call to Sprintf | Dsn.go:68:29:68:33 | dbDSN | | Dsn.go:67:102:67:104 | cfg [pointer] | Dsn.go:67:102:67:104 | implicit dereference | | Dsn.go:67:102:67:104 | implicit dereference | Dsn.go:63:9:63:11 | implicit dereference | -| Dsn.go:67:102:67:104 | implicit dereference | Dsn.go:68:29:68:33 | dbDSN | +| Dsn.go:67:102:67:104 | implicit dereference | Dsn.go:67:102:67:108 | selection of dsn | +| Dsn.go:67:102:67:108 | selection of dsn | Dsn.go:67:11:67:109 | call to Sprintf | nodes | Dsn.go:26:11:26:17 | selection of Args | semmle.label | selection of Args | +| Dsn.go:28:11:28:110 | call to Sprintf | semmle.label | call to Sprintf | +| Dsn.go:28:102:28:109 | index expression | semmle.label | index expression | | Dsn.go:29:29:29:33 | dbDSN | semmle.label | dbDSN | | Dsn.go:62:2:62:4 | definition of cfg [pointer] | semmle.label | definition of cfg [pointer] | | Dsn.go:63:9:63:11 | cfg [pointer] | semmle.label | cfg [pointer] | | Dsn.go:63:9:63:11 | implicit dereference | semmle.label | implicit dereference | | Dsn.go:63:19:63:25 | selection of Args | semmle.label | selection of Args | +| Dsn.go:63:19:63:29 | slice expression | semmle.label | slice expression | +| Dsn.go:67:11:67:109 | call to Sprintf | semmle.label | call to Sprintf | | Dsn.go:67:102:67:104 | cfg [pointer] | semmle.label | cfg [pointer] | | Dsn.go:67:102:67:104 | implicit dereference | semmle.label | implicit dereference | +| Dsn.go:67:102:67:108 | selection of dsn | semmle.label | selection of dsn | | Dsn.go:68:29:68:33 | dbDSN | semmle.label | dbDSN | subpaths #select diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index 5ba4e98208e..d5a4910ad0d 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -4,17 +4,23 @@ edges | builtin.go:97:21:97:31 | call to Referer | builtin.go:101:36:101:49 | untrustedInput | | builtin.go:111:21:111:31 | call to Referer | builtin.go:114:15:114:28 | untrustedInput | | builtin.go:129:21:129:31 | call to Referer | builtin.go:132:38:132:51 | untrustedInput | -| new-tests.go:26:26:26:30 | &... | new-tests.go:31:11:31:57 | call to Sprintf | -| new-tests.go:26:26:26:30 | &... | new-tests.go:32:11:32:57 | call to Sprintf | -| new-tests.go:26:26:26:30 | &... | new-tests.go:35:12:35:58 | call to Sprintf | +| new-tests.go:26:26:26:30 | &... | new-tests.go:31:48:31:56 | selection of word | +| new-tests.go:26:26:26:30 | &... | new-tests.go:32:48:32:56 | selection of safe | +| new-tests.go:26:26:26:30 | &... | new-tests.go:35:49:35:57 | selection of word | +| new-tests.go:31:48:31:56 | selection of word | new-tests.go:31:11:31:57 | call to Sprintf | +| new-tests.go:32:48:32:56 | selection of safe | new-tests.go:32:11:32:57 | call to Sprintf | +| new-tests.go:35:49:35:57 | selection of word | new-tests.go:35:12:35:58 | call to Sprintf | | new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | | new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | | new-tests.go:62:2:62:39 | ... := ...[0] | new-tests.go:63:17:63:23 | reqBody | | new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | | new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... | -| new-tests.go:63:26:63:30 | &... | new-tests.go:68:11:68:57 | call to Sprintf | -| new-tests.go:63:26:63:30 | &... | new-tests.go:69:11:69:57 | call to Sprintf | -| new-tests.go:63:26:63:30 | &... | new-tests.go:74:12:74:58 | call to Sprintf | +| new-tests.go:63:26:63:30 | &... | new-tests.go:68:48:68:56 | selection of word | +| new-tests.go:63:26:63:30 | &... | new-tests.go:69:48:69:56 | selection of safe | +| new-tests.go:63:26:63:30 | &... | new-tests.go:74:49:74:57 | selection of word | +| new-tests.go:68:48:68:56 | selection of word | new-tests.go:68:11:68:57 | call to Sprintf | +| new-tests.go:69:48:69:56 | selection of safe | new-tests.go:69:11:69:57 | call to Sprintf | +| new-tests.go:74:49:74:57 | selection of word | new-tests.go:74:12:74:58 | call to Sprintf | | new-tests.go:78:18:78:24 | selection of URL | new-tests.go:78:18:78:32 | call to Query | | new-tests.go:78:18:78:32 | call to Query | new-tests.go:78:18:78:46 | call to Get | | new-tests.go:78:18:78:46 | call to Get | new-tests.go:79:11:79:46 | ...+... | @@ -36,8 +42,11 @@ nodes | builtin.go:132:38:132:51 | untrustedInput | semmle.label | untrustedInput | | new-tests.go:26:26:26:30 | &... | semmle.label | &... | | new-tests.go:31:11:31:57 | call to Sprintf | semmle.label | call to Sprintf | +| new-tests.go:31:48:31:56 | selection of word | semmle.label | selection of word | | new-tests.go:32:11:32:57 | call to Sprintf | semmle.label | call to Sprintf | +| new-tests.go:32:48:32:56 | selection of safe | semmle.label | selection of safe | | new-tests.go:35:12:35:58 | call to Sprintf | semmle.label | call to Sprintf | +| new-tests.go:35:49:35:57 | selection of word | semmle.label | selection of word | | new-tests.go:39:18:39:30 | call to Param | semmle.label | call to Param | | new-tests.go:47:11:47:46 | ...+... | semmle.label | ...+... | | new-tests.go:49:18:49:30 | call to Query | semmle.label | call to Query | @@ -47,8 +56,11 @@ nodes | new-tests.go:63:17:63:23 | reqBody | semmle.label | reqBody | | new-tests.go:63:26:63:30 | &... | semmle.label | &... | | new-tests.go:68:11:68:57 | call to Sprintf | semmle.label | call to Sprintf | +| new-tests.go:68:48:68:56 | selection of word | semmle.label | selection of word | | new-tests.go:69:11:69:57 | call to Sprintf | semmle.label | call to Sprintf | +| new-tests.go:69:48:69:56 | selection of safe | semmle.label | selection of safe | | new-tests.go:74:12:74:58 | call to Sprintf | semmle.label | call to Sprintf | +| new-tests.go:74:49:74:57 | selection of word | semmle.label | selection of word | | new-tests.go:78:18:78:24 | selection of URL | semmle.label | selection of URL | | new-tests.go:78:18:78:32 | call to Query | semmle.label | call to Query | | new-tests.go:78:18:78:46 | call to Get | semmle.label | call to Get | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected index 2d29d2b2357..29b131c367a 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Beego/ReflectedXss.expected @@ -47,7 +47,7 @@ edges | test.go:240:15:240:36 | call to GetString | test.go:243:21:243:29 | untrusted | | test.go:253:23:253:44 | call to GetCookie | test.go:253:16:253:45 | type conversion | | test.go:264:62:264:83 | call to GetCookie | test.go:264:55:264:84 | type conversion | -| test.go:269:2:269:40 | ... := ...[0] | test.go:277:21:277:61 | call to GetDisplayString | +| test.go:269:2:269:40 | ... := ...[0] | test.go:277:44:277:60 | selection of Filename | | test.go:269:2:269:40 | ... := ...[0] | test.go:278:38:278:49 | genericFiles | | test.go:269:2:269:40 | ... := ...[0] | test.go:279:37:279:48 | genericFiles | | test.go:269:2:269:40 | ... := ...[0] | test.go:285:4:285:15 | genericFiles | @@ -61,6 +61,7 @@ edges | test.go:269:2:269:40 | ... := ...[0] | test.go:295:39:295:50 | genericFiles | | test.go:269:2:269:40 | ... := ...[0] | test.go:296:40:296:51 | genericFiles | | test.go:269:2:269:40 | ... := ...[0] | test.go:297:39:297:50 | genericFiles | +| test.go:277:44:277:60 | selection of Filename | test.go:277:21:277:61 | call to GetDisplayString | | test.go:278:21:278:53 | call to SliceChunk | test.go:278:21:278:92 | selection of Filename | | test.go:278:38:278:49 | genericFiles | test.go:278:21:278:53 | call to SliceChunk | | test.go:279:21:279:60 | call to SliceDiff | test.go:279:21:279:96 | selection of Filename | @@ -177,6 +178,7 @@ nodes | test.go:264:62:264:83 | call to GetCookie | semmle.label | call to GetCookie | | test.go:269:2:269:40 | ... := ...[0] | semmle.label | ... := ...[0] | | test.go:277:21:277:61 | call to GetDisplayString | semmle.label | call to GetDisplayString | +| test.go:277:44:277:60 | selection of Filename | semmle.label | selection of Filename | | test.go:278:21:278:53 | call to SliceChunk | semmle.label | call to SliceChunk | | test.go:278:21:278:92 | selection of Filename | semmle.label | selection of Filename | | test.go:278:38:278:49 | genericFiles | semmle.label | genericFiles | diff --git a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected index 2e7a965b514..307906f7e9b 100644 --- a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected +++ b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.expected @@ -1,13 +1,15 @@ edges | TaintedPath.go:13:18:13:22 | selection of URL | TaintedPath.go:13:18:13:30 | call to Query | | TaintedPath.go:13:18:13:30 | call to Query | TaintedPath.go:16:29:16:40 | tainted_path | -| TaintedPath.go:13:18:13:30 | call to Query | TaintedPath.go:20:28:20:69 | call to Join | +| TaintedPath.go:13:18:13:30 | call to Query | TaintedPath.go:20:57:20:68 | tainted_path | +| TaintedPath.go:20:57:20:68 | tainted_path | TaintedPath.go:20:28:20:69 | call to Join | | tst.go:14:2:14:39 | ... := ...[1] | tst.go:17:41:17:56 | selection of Filename | nodes | TaintedPath.go:13:18:13:22 | selection of URL | semmle.label | selection of URL | | TaintedPath.go:13:18:13:30 | call to Query | semmle.label | call to Query | | TaintedPath.go:16:29:16:40 | tainted_path | semmle.label | tainted_path | | TaintedPath.go:20:28:20:69 | call to Join | semmle.label | call to Join | +| TaintedPath.go:20:57:20:68 | tainted_path | semmle.label | tainted_path | | tst.go:14:2:14:39 | ... := ...[1] | semmle.label | ... := ...[1] | | tst.go:17:41:17:56 | selection of Filename | semmle.label | selection of Filename | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected index 1c3a46096c2..f10f103c963 100644 --- a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected +++ b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.expected @@ -1,5 +1,6 @@ edges -| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | +| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | +| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | @@ -13,6 +14,7 @@ edges nodes | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | semmle.label | definition of candidate | | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | semmle.label | call to Join | +| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | semmle.label | candidate | | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | semmle.label | ... := ...[0] | | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | semmle.label | selection of Linkname | | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | semmle.label | selection of Name | diff --git a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index cfc49180bba..19c94698899 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -11,25 +11,47 @@ edges | GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:16:36:16:42 | tainted | | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:9:13:9:27 | call to Query | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:14:23:14:33 | slice expression | -| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | -| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | -| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:39:31:39:37 | tainted | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:53:21:53:28 | arrayLit | +| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:68:31:68:37 | tainted | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:80:23:80:29 | tainted | +| SanitizingDoubleDash.go:39:14:39:44 | call to append | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | +| SanitizingDoubleDash.go:39:31:39:37 | tainted | SanitizingDoubleDash.go:39:14:39:44 | call to append | +| SanitizingDoubleDash.go:53:14:53:35 | call to append | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | +| SanitizingDoubleDash.go:53:21:53:28 | arrayLit | SanitizingDoubleDash.go:53:14:53:35 | call to append | +| SanitizingDoubleDash.go:68:14:68:38 | call to append | SanitizingDoubleDash.go:69:21:69:28 | arrayLit | +| SanitizingDoubleDash.go:68:31:68:37 | tainted | SanitizingDoubleDash.go:68:14:68:38 | call to append | +| SanitizingDoubleDash.go:69:14:69:35 | call to append | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | +| SanitizingDoubleDash.go:69:21:69:28 | arrayLit | SanitizingDoubleDash.go:69:14:69:35 | call to append | | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | SanitizingDoubleDash.go:92:13:92:27 | call to Query | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:96:24:96:34 | slice expression | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:101:24:101:34 | slice expression | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:105:30:105:36 | tainted | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | -| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:111:37:111:43 | tainted | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:117:31:117:37 | tainted | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:123:31:123:37 | tainted | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:129:21:129:28 | arrayLit | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:136:31:136:37 | tainted | +| SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:142:31:142:37 | tainted | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:148:30:148:36 | tainted | | SanitizingDoubleDash.go:92:13:92:27 | call to Query | SanitizingDoubleDash.go:152:24:152:30 | tainted | | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | | SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | +| SanitizingDoubleDash.go:111:14:111:44 | call to append | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | +| SanitizingDoubleDash.go:111:37:111:43 | tainted | SanitizingDoubleDash.go:111:14:111:44 | call to append | +| SanitizingDoubleDash.go:117:14:117:44 | call to append | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | +| SanitizingDoubleDash.go:117:31:117:37 | tainted | SanitizingDoubleDash.go:117:14:117:44 | call to append | +| SanitizingDoubleDash.go:123:14:123:38 | call to append | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | +| SanitizingDoubleDash.go:123:31:123:37 | tainted | SanitizingDoubleDash.go:123:14:123:38 | call to append | +| SanitizingDoubleDash.go:129:14:129:35 | call to append | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | +| SanitizingDoubleDash.go:129:21:129:28 | arrayLit | SanitizingDoubleDash.go:129:14:129:35 | call to append | +| SanitizingDoubleDash.go:136:14:136:38 | call to append | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | +| SanitizingDoubleDash.go:136:31:136:37 | tainted | SanitizingDoubleDash.go:136:14:136:38 | call to append | +| SanitizingDoubleDash.go:142:14:142:38 | call to append | SanitizingDoubleDash.go:143:21:143:28 | arrayLit | +| SanitizingDoubleDash.go:142:31:142:37 | tainted | SanitizingDoubleDash.go:142:14:142:38 | call to append | +| SanitizingDoubleDash.go:143:14:143:35 | call to append | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | +| SanitizingDoubleDash.go:143:21:143:28 | arrayLit | SanitizingDoubleDash.go:143:14:143:35 | call to append | nodes | ArgumentInjection.go:9:10:9:16 | selection of URL | semmle.label | selection of URL | | ArgumentInjection.go:9:10:9:24 | call to Query | semmle.label | call to Query | @@ -47,8 +69,16 @@ nodes | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | semmle.label | selection of URL | | SanitizingDoubleDash.go:9:13:9:27 | call to Query | semmle.label | call to Query | | SanitizingDoubleDash.go:14:23:14:33 | slice expression | semmle.label | slice expression | +| SanitizingDoubleDash.go:39:14:39:44 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:39:31:39:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | semmle.label | arrayLit | +| SanitizingDoubleDash.go:53:14:53:35 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:53:21:53:28 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | semmle.label | arrayLit | +| SanitizingDoubleDash.go:68:14:68:38 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:68:31:68:37 | tainted | semmle.label | tainted | +| SanitizingDoubleDash.go:69:14:69:35 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:69:21:69:28 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:70:23:70:30 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:80:23:80:29 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:92:13:92:19 | selection of URL | semmle.label | selection of URL | @@ -58,11 +88,25 @@ nodes | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | semmle.label | slice literal [array] | | SanitizingDoubleDash.go:105:30:105:36 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | semmle.label | arrayLit | +| SanitizingDoubleDash.go:111:14:111:44 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:111:37:111:43 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:112:24:112:31 | arrayLit | semmle.label | arrayLit | +| SanitizingDoubleDash.go:117:14:117:44 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:117:31:117:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:118:24:118:31 | arrayLit | semmle.label | arrayLit | +| SanitizingDoubleDash.go:123:14:123:38 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:123:31:123:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:124:24:124:31 | arrayLit | semmle.label | arrayLit | +| SanitizingDoubleDash.go:129:14:129:35 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:129:21:129:28 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:130:24:130:31 | arrayLit | semmle.label | arrayLit | +| SanitizingDoubleDash.go:136:14:136:38 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:136:31:136:37 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:137:24:137:31 | arrayLit | semmle.label | arrayLit | +| SanitizingDoubleDash.go:142:14:142:38 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:142:31:142:37 | tainted | semmle.label | tainted | +| SanitizingDoubleDash.go:143:14:143:35 | call to append | semmle.label | call to append | +| SanitizingDoubleDash.go:143:21:143:28 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:144:24:144:31 | arrayLit | semmle.label | arrayLit | | SanitizingDoubleDash.go:148:30:148:36 | tainted | semmle.label | tainted | | SanitizingDoubleDash.go:152:24:152:30 | tainted | semmle.label | tainted | diff --git a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected index ea667480966..e0e028fff91 100644 --- a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected +++ b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected @@ -1,7 +1,12 @@ edges -| StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:14:22:14:28 | cmdName | +| StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:13:2:13:5 | rows | +| StoredCommand.go:13:2:13:5 | rows | StoredCommand.go:13:12:13:19 | &... | +| StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:13:12:13:19 | &... | +| StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:14:22:14:28 | cmdName | nodes | StoredCommand.go:11:2:11:27 | ... := ...[0] | semmle.label | ... := ...[0] | +| StoredCommand.go:13:2:13:5 | rows | semmle.label | rows | +| StoredCommand.go:13:12:13:19 | &... | semmle.label | &... | | StoredCommand.go:14:22:14:28 | cmdName | semmle.label | cmdName | subpaths #select diff --git a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index 4f3ee95ffe8..31a8d097158 100644 --- a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -9,19 +9,27 @@ edges | contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | | contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | -| reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:10:28:57 | type conversion | +| reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:50:28:55 | cookie | +| reflectedxsstest.go:28:17:28:56 | call to Sprintf | reflectedxsstest.go:28:10:28:57 | type conversion | +| reflectedxsstest.go:28:50:28:55 | cookie | reflectedxsstest.go:28:17:28:56 | call to Sprintf | | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:32:34:32:37 | file | -| reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:10:34:62 | type conversion | -| reflectedxsstest.go:32:2:32:38 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | +| reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:46:34:60 | selection of Filename | +| reflectedxsstest.go:32:2:32:38 | ... := ...[0] | reflectedxsstest.go:33:49:33:55 | content | | reflectedxsstest.go:32:34:32:37 | file | reflectedxsstest.go:32:2:32:38 | ... := ...[0] | +| reflectedxsstest.go:33:17:33:56 | call to Sprintf | reflectedxsstest.go:33:10:33:57 | type conversion | +| reflectedxsstest.go:33:49:33:55 | content | reflectedxsstest.go:33:17:33:56 | call to Sprintf | +| reflectedxsstest.go:34:17:34:61 | call to Sprintf | reflectedxsstest.go:34:10:34:62 | type conversion | +| reflectedxsstest.go:34:46:34:60 | selection of Filename | reflectedxsstest.go:34:17:34:61 | call to Sprintf | | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:39:16:39:21 | reader | | reflectedxsstest.go:39:2:39:32 | ... := ...[0] | reflectedxsstest.go:40:14:40:17 | part | | reflectedxsstest.go:39:2:39:32 | ... := ...[0] | reflectedxsstest.go:42:2:42:5 | part | | reflectedxsstest.go:39:16:39:21 | reader | reflectedxsstest.go:39:2:39:32 | ... := ...[0] | | reflectedxsstest.go:40:14:40:17 | part | reflectedxsstest.go:40:14:40:28 | call to FileName | -| reflectedxsstest.go:40:14:40:28 | call to FileName | reflectedxsstest.go:44:10:44:55 | type conversion | +| reflectedxsstest.go:40:14:40:28 | call to FileName | reflectedxsstest.go:44:46:44:53 | partName | | reflectedxsstest.go:41:2:41:10 | definition of byteSlice | reflectedxsstest.go:45:10:45:18 | byteSlice | | reflectedxsstest.go:42:2:42:5 | part | reflectedxsstest.go:41:2:41:10 | definition of byteSlice | +| reflectedxsstest.go:44:17:44:54 | call to Sprintf | reflectedxsstest.go:44:10:44:55 | type conversion | +| reflectedxsstest.go:44:46:44:53 | partName | reflectedxsstest.go:44:17:44:54 | call to Sprintf | | reflectedxsstest.go:51:14:51:18 | selection of URL | reflectedxsstest.go:51:14:51:26 | call to Query | | reflectedxsstest.go:51:14:51:26 | call to Query | reflectedxsstest.go:54:11:54:21 | type conversion | | tst.go:14:15:14:20 | selection of Form | tst.go:14:15:14:36 | call to Get | @@ -56,12 +64,18 @@ nodes | contenttype.go:114:50:114:53 | data | semmle.label | data | | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:28:10:28:57 | type conversion | semmle.label | type conversion | +| reflectedxsstest.go:28:17:28:56 | call to Sprintf | semmle.label | call to Sprintf | +| reflectedxsstest.go:28:50:28:55 | cookie | semmle.label | cookie | | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | semmle.label | ... := ...[1] | | reflectedxsstest.go:32:2:32:38 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:32:34:32:37 | file | semmle.label | file | | reflectedxsstest.go:33:10:33:57 | type conversion | semmle.label | type conversion | +| reflectedxsstest.go:33:17:33:56 | call to Sprintf | semmle.label | call to Sprintf | +| reflectedxsstest.go:33:49:33:55 | content | semmle.label | content | | reflectedxsstest.go:34:10:34:62 | type conversion | semmle.label | type conversion | +| reflectedxsstest.go:34:17:34:61 | call to Sprintf | semmle.label | call to Sprintf | +| reflectedxsstest.go:34:46:34:60 | selection of Filename | semmle.label | selection of Filename | | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:39:2:39:32 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:39:16:39:21 | reader | semmle.label | reader | @@ -70,6 +84,8 @@ nodes | reflectedxsstest.go:41:2:41:10 | definition of byteSlice | semmle.label | definition of byteSlice | | reflectedxsstest.go:42:2:42:5 | part | semmle.label | part | | reflectedxsstest.go:44:10:44:55 | type conversion | semmle.label | type conversion | +| reflectedxsstest.go:44:17:44:54 | call to Sprintf | semmle.label | call to Sprintf | +| reflectedxsstest.go:44:46:44:53 | partName | semmle.label | partName | | reflectedxsstest.go:45:10:45:18 | byteSlice | semmle.label | byteSlice | | reflectedxsstest.go:51:14:51:18 | selection of URL | semmle.label | selection of URL | | reflectedxsstest.go:51:14:51:26 | call to Query | semmle.label | call to Query | diff --git a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected index 1e513a5d4a9..f51eda4c93c 100644 --- a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -1,11 +1,16 @@ edges | StoredXss.go:13:21:13:31 | call to Name | StoredXss.go:13:21:13:36 | ...+... | -| stored.go:18:3:18:28 | ... := ...[0] | stored.go:30:22:30:25 | name | +| stored.go:18:3:18:28 | ... := ...[0] | stored.go:25:14:25:17 | rows | +| stored.go:25:14:25:17 | rows | stored.go:25:29:25:33 | &... | +| stored.go:25:29:25:33 | &... | stored.go:25:29:25:33 | &... | +| stored.go:25:29:25:33 | &... | stored.go:30:22:30:25 | name | | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | nodes | StoredXss.go:13:21:13:31 | call to Name | semmle.label | call to Name | | StoredXss.go:13:21:13:36 | ...+... | semmle.label | ...+... | | stored.go:18:3:18:28 | ... := ...[0] | semmle.label | ... := ...[0] | +| stored.go:25:14:25:17 | rows | semmle.label | rows | +| stored.go:25:29:25:33 | &... | semmle.label | &... | | stored.go:30:22:30:25 | name | semmle.label | name | | stored.go:59:30:59:33 | definition of path | semmle.label | definition of path | | stored.go:61:22:61:25 | path | semmle.label | path | diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 93d447e40ab..c1ded7d69f8 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -1,21 +1,30 @@ edges +| SqlInjection.go:10:7:11:30 | call to Sprintf | SqlInjection.go:12:11:12:11 | q | | SqlInjection.go:11:3:11:9 | selection of URL | SqlInjection.go:11:3:11:17 | call to Query | -| SqlInjection.go:11:3:11:17 | call to Query | SqlInjection.go:12:11:12:11 | q | +| SqlInjection.go:11:3:11:17 | call to Query | SqlInjection.go:11:3:11:29 | index expression | +| SqlInjection.go:11:3:11:29 | index expression | SqlInjection.go:10:7:11:30 | call to Sprintf | | issue48.go:17:2:17:33 | ... := ...[0] | issue48.go:18:17:18:17 | b | | issue48.go:17:25:17:32 | selection of Body | issue48.go:17:2:17:33 | ... := ...[0] | | issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... | -| issue48.go:18:20:18:39 | &... | issue48.go:22:11:22:12 | q3 | +| issue48.go:18:20:18:39 | &... | issue48.go:21:3:21:33 | index expression | +| issue48.go:20:8:21:34 | call to Sprintf | issue48.go:22:11:22:12 | q3 | +| issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | call to Sprintf | | issue48.go:27:2:27:34 | ... := ...[0] | issue48.go:28:17:28:18 | b2 | | issue48.go:27:26:27:33 | selection of Body | issue48.go:27:2:27:34 | ... := ...[0] | | issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... | -| issue48.go:28:21:28:41 | &... | issue48.go:32:11:32:12 | q4 | +| issue48.go:28:21:28:41 | &... | issue48.go:31:3:31:31 | selection of Category | +| issue48.go:30:8:31:32 | call to Sprintf | issue48.go:32:11:32:12 | q4 | +| issue48.go:31:3:31:31 | selection of Category | issue48.go:30:8:31:32 | call to Sprintf | | issue48.go:37:17:37:50 | type conversion | issue48.go:37:53:37:73 | &... | | issue48.go:37:24:37:30 | selection of URL | issue48.go:37:24:37:38 | call to Query | | issue48.go:37:24:37:38 | call to Query | issue48.go:37:17:37:50 | type conversion | -| issue48.go:37:53:37:73 | &... | issue48.go:41:11:41:12 | q5 | +| issue48.go:37:53:37:73 | &... | issue48.go:40:3:40:31 | selection of Category | +| issue48.go:39:8:40:32 | call to Sprintf | issue48.go:41:11:41:12 | q5 | +| issue48.go:40:3:40:31 | selection of Category | issue48.go:39:8:40:32 | call to Sprintf | | main.go:10:11:10:16 | selection of Form | main.go:10:11:10:28 | index expression | | main.go:14:63:14:67 | selection of URL | main.go:14:63:14:75 | call to Query | -| main.go:14:63:14:75 | call to Query | main.go:14:11:14:84 | call to Sprintf | +| main.go:14:63:14:75 | call to Query | main.go:14:63:14:83 | index expression | +| main.go:14:63:14:83 | index expression | main.go:14:11:14:84 | call to Sprintf | | main.go:15:63:15:70 | selection of Header | main.go:15:63:15:84 | call to Get | | main.go:15:63:15:84 | call to Get | main.go:15:11:15:85 | call to Sprintf | | main.go:27:17:30:2 | &... [pointer, Category] | main.go:33:3:33:13 | RequestData [pointer, Category] | @@ -23,9 +32,10 @@ edges | main.go:29:13:29:19 | selection of URL | main.go:29:13:29:27 | call to Query | | main.go:29:13:29:27 | call to Query | main.go:29:13:29:39 | index expression | | main.go:29:13:29:39 | index expression | main.go:27:18:30:2 | struct literal [Category] | +| main.go:32:7:33:23 | call to Sprintf | main.go:34:11:34:11 | q | | main.go:33:3:33:13 | RequestData [pointer, Category] | main.go:33:3:33:13 | implicit dereference [Category] | | main.go:33:3:33:13 | implicit dereference [Category] | main.go:33:3:33:22 | selection of Category | -| main.go:33:3:33:22 | selection of Category | main.go:34:11:34:11 | q | +| main.go:33:3:33:22 | selection of Category | main.go:32:7:33:23 | call to Sprintf | | main.go:38:2:38:12 | definition of RequestData [pointer, Category] | main.go:39:2:39:12 | RequestData [pointer, Category] | | main.go:38:2:38:12 | definition of RequestData [pointer, Category] | main.go:42:3:42:13 | RequestData [pointer, Category] | | main.go:39:2:39:12 | RequestData [pointer, Category] | main.go:39:2:39:12 | implicit dereference [Category] | @@ -33,9 +43,10 @@ edges | main.go:39:25:39:31 | selection of URL | main.go:39:25:39:39 | call to Query | | main.go:39:25:39:39 | call to Query | main.go:39:25:39:51 | index expression | | main.go:39:25:39:51 | index expression | main.go:39:2:39:12 | implicit dereference [Category] | +| main.go:41:7:42:23 | call to Sprintf | main.go:43:11:43:11 | q | | main.go:42:3:42:13 | RequestData [pointer, Category] | main.go:42:3:42:13 | implicit dereference [Category] | | main.go:42:3:42:13 | implicit dereference [Category] | main.go:42:3:42:22 | selection of Category | -| main.go:42:3:42:22 | selection of Category | main.go:43:11:43:11 | q | +| main.go:42:3:42:22 | selection of Category | main.go:41:7:42:23 | call to Sprintf | | main.go:47:2:47:12 | definition of RequestData [pointer, Category] | main.go:48:4:48:14 | RequestData [pointer, Category] | | main.go:47:2:47:12 | definition of RequestData [pointer, Category] | main.go:51:3:51:13 | RequestData [pointer, Category] | | main.go:48:3:48:14 | star expression [Category] | main.go:47:2:47:12 | definition of RequestData [pointer, Category] | @@ -43,9 +54,10 @@ edges | main.go:48:28:48:34 | selection of URL | main.go:48:28:48:42 | call to Query | | main.go:48:28:48:42 | call to Query | main.go:48:28:48:54 | index expression | | main.go:48:28:48:54 | index expression | main.go:48:3:48:14 | star expression [Category] | +| main.go:50:7:51:23 | call to Sprintf | main.go:52:11:52:11 | q | | main.go:51:3:51:13 | RequestData [pointer, Category] | main.go:51:3:51:13 | implicit dereference [Category] | | main.go:51:3:51:13 | implicit dereference [Category] | main.go:51:3:51:22 | selection of Category | -| main.go:51:3:51:22 | selection of Category | main.go:52:11:52:11 | q | +| main.go:51:3:51:22 | selection of Category | main.go:50:7:51:23 | call to Sprintf | | main.go:56:2:56:12 | definition of RequestData [pointer, Category] | main.go:57:4:57:14 | RequestData [pointer, Category] | | main.go:56:2:56:12 | definition of RequestData [pointer, Category] | main.go:60:5:60:15 | RequestData [pointer, Category] | | main.go:57:3:57:14 | star expression [Category] | main.go:56:2:56:12 | definition of RequestData [pointer, Category] | @@ -53,7 +65,8 @@ edges | main.go:57:28:57:34 | selection of URL | main.go:57:28:57:42 | call to Query | | main.go:57:28:57:42 | call to Query | main.go:57:28:57:54 | index expression | | main.go:57:28:57:54 | index expression | main.go:57:3:57:14 | star expression [Category] | -| main.go:60:3:60:25 | selection of Category | main.go:61:11:61:11 | q | +| main.go:59:7:60:26 | call to Sprintf | main.go:61:11:61:11 | q | +| main.go:60:3:60:25 | selection of Category | main.go:59:7:60:26 | call to Sprintf | | main.go:60:4:60:15 | star expression [Category] | main.go:60:3:60:25 | selection of Category | | main.go:60:5:60:15 | RequestData [pointer, Category] | main.go:60:4:60:15 | star expression [Category] | | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:57:22:57:29 | pipeline | @@ -71,29 +84,38 @@ edges | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:80:22:80:27 | filter | | mongoDB.go:40:20:40:30 | call to Referer | mongoDB.go:81:18:81:25 | pipeline | nodes +| SqlInjection.go:10:7:11:30 | call to Sprintf | semmle.label | call to Sprintf | | SqlInjection.go:11:3:11:9 | selection of URL | semmle.label | selection of URL | | SqlInjection.go:11:3:11:17 | call to Query | semmle.label | call to Query | +| SqlInjection.go:11:3:11:29 | index expression | semmle.label | index expression | | SqlInjection.go:12:11:12:11 | q | semmle.label | q | | issue48.go:17:2:17:33 | ... := ...[0] | semmle.label | ... := ...[0] | | issue48.go:17:25:17:32 | selection of Body | semmle.label | selection of Body | | issue48.go:18:17:18:17 | b | semmle.label | b | | issue48.go:18:20:18:39 | &... | semmle.label | &... | +| issue48.go:20:8:21:34 | call to Sprintf | semmle.label | call to Sprintf | +| issue48.go:21:3:21:33 | index expression | semmle.label | index expression | | issue48.go:22:11:22:12 | q3 | semmle.label | q3 | | issue48.go:27:2:27:34 | ... := ...[0] | semmle.label | ... := ...[0] | | issue48.go:27:26:27:33 | selection of Body | semmle.label | selection of Body | | issue48.go:28:17:28:18 | b2 | semmle.label | b2 | | issue48.go:28:21:28:41 | &... | semmle.label | &... | +| issue48.go:30:8:31:32 | call to Sprintf | semmle.label | call to Sprintf | +| issue48.go:31:3:31:31 | selection of Category | semmle.label | selection of Category | | issue48.go:32:11:32:12 | q4 | semmle.label | q4 | | issue48.go:37:17:37:50 | type conversion | semmle.label | type conversion | | issue48.go:37:24:37:30 | selection of URL | semmle.label | selection of URL | | issue48.go:37:24:37:38 | call to Query | semmle.label | call to Query | | issue48.go:37:53:37:73 | &... | semmle.label | &... | +| issue48.go:39:8:40:32 | call to Sprintf | semmle.label | call to Sprintf | +| issue48.go:40:3:40:31 | selection of Category | semmle.label | selection of Category | | issue48.go:41:11:41:12 | q5 | semmle.label | q5 | | main.go:10:11:10:16 | selection of Form | semmle.label | selection of Form | | main.go:10:11:10:28 | index expression | semmle.label | index expression | | main.go:14:11:14:84 | call to Sprintf | semmle.label | call to Sprintf | | main.go:14:63:14:67 | selection of URL | semmle.label | selection of URL | | main.go:14:63:14:75 | call to Query | semmle.label | call to Query | +| main.go:14:63:14:83 | index expression | semmle.label | index expression | | main.go:15:11:15:85 | call to Sprintf | semmle.label | call to Sprintf | | main.go:15:63:15:70 | selection of Header | semmle.label | selection of Header | | main.go:15:63:15:84 | call to Get | semmle.label | call to Get | @@ -102,6 +124,7 @@ nodes | main.go:29:13:29:19 | selection of URL | semmle.label | selection of URL | | main.go:29:13:29:27 | call to Query | semmle.label | call to Query | | main.go:29:13:29:39 | index expression | semmle.label | index expression | +| main.go:32:7:33:23 | call to Sprintf | semmle.label | call to Sprintf | | main.go:33:3:33:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:33:3:33:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | | main.go:33:3:33:22 | selection of Category | semmle.label | selection of Category | @@ -112,6 +135,7 @@ nodes | main.go:39:25:39:31 | selection of URL | semmle.label | selection of URL | | main.go:39:25:39:39 | call to Query | semmle.label | call to Query | | main.go:39:25:39:51 | index expression | semmle.label | index expression | +| main.go:41:7:42:23 | call to Sprintf | semmle.label | call to Sprintf | | main.go:42:3:42:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:42:3:42:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | | main.go:42:3:42:22 | selection of Category | semmle.label | selection of Category | @@ -122,6 +146,7 @@ nodes | main.go:48:28:48:34 | selection of URL | semmle.label | selection of URL | | main.go:48:28:48:42 | call to Query | semmle.label | call to Query | | main.go:48:28:48:54 | index expression | semmle.label | index expression | +| main.go:50:7:51:23 | call to Sprintf | semmle.label | call to Sprintf | | main.go:51:3:51:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | | main.go:51:3:51:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] | | main.go:51:3:51:22 | selection of Category | semmle.label | selection of Category | @@ -132,6 +157,7 @@ nodes | main.go:57:28:57:34 | selection of URL | semmle.label | selection of URL | | main.go:57:28:57:42 | call to Query | semmle.label | call to Query | | main.go:57:28:57:54 | index expression | semmle.label | index expression | +| main.go:59:7:60:26 | call to Sprintf | semmle.label | call to Sprintf | | main.go:60:3:60:25 | selection of Category | semmle.label | selection of Category | | main.go:60:4:60:15 | star expression [Category] | semmle.label | star expression [Category] | | main.go:60:5:60:15 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] | diff --git a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected index ba37534511a..e47a4768465 100644 --- a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected +++ b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.expected @@ -14,9 +14,18 @@ edges | UnsafeTLS.go:305:5:305:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:304:18:306:4 | slice literal | | UnsafeTLS.go:313:5:313:45 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:312:18:314:4 | slice literal | | UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:329:25:329:94 | call to append | -| UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites | UnsafeTLS.go:336:26:336:58 | call to append | -| UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites | UnsafeTLS.go:346:25:346:36 | cipherSuites | -| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites | UnsafeTLS.go:355:25:355:36 | cipherSuites | +| UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites | UnsafeTLS.go:336:54:336:57 | selection of ID | +| UnsafeTLS.go:336:54:336:57 | selection of ID | UnsafeTLS.go:336:26:336:58 | call to append | +| UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites | UnsafeTLS.go:344:40:344:43 | selection of ID | +| UnsafeTLS.go:344:19:344:44 | call to append | UnsafeTLS.go:344:26:344:37 | cipherSuites | +| UnsafeTLS.go:344:19:344:44 | call to append | UnsafeTLS.go:346:25:346:36 | cipherSuites | +| UnsafeTLS.go:344:26:344:37 | cipherSuites | UnsafeTLS.go:344:19:344:44 | call to append | +| UnsafeTLS.go:344:40:344:43 | selection of ID | UnsafeTLS.go:344:19:344:44 | call to append | +| UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites | UnsafeTLS.go:353:40:353:51 | selection of ID | +| UnsafeTLS.go:353:19:353:52 | call to append | UnsafeTLS.go:353:26:353:37 | cipherSuites | +| UnsafeTLS.go:353:19:353:52 | call to append | UnsafeTLS.go:355:25:355:36 | cipherSuites | +| UnsafeTLS.go:353:26:353:37 | cipherSuites | UnsafeTLS.go:353:19:353:52 | call to append | +| UnsafeTLS.go:353:40:353:51 | selection of ID | UnsafeTLS.go:353:19:353:52 | call to append | | UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:362:18:364:4 | slice literal | | UnsafeTLS.go:371:5:371:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:370:18:372:4 | slice literal | | UnsafeTLS.go:379:5:379:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | UnsafeTLS.go:378:18:380:4 | slice literal | @@ -94,9 +103,16 @@ nodes | UnsafeTLS.go:329:53:329:93 | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | | UnsafeTLS.go:334:13:334:38 | call to InsecureCipherSuites | semmle.label | call to InsecureCipherSuites | | UnsafeTLS.go:336:26:336:58 | call to append | semmle.label | call to append | +| UnsafeTLS.go:336:54:336:57 | selection of ID | semmle.label | selection of ID | | UnsafeTLS.go:342:13:342:38 | call to InsecureCipherSuites | semmle.label | call to InsecureCipherSuites | +| UnsafeTLS.go:344:19:344:44 | call to append | semmle.label | call to append | +| UnsafeTLS.go:344:26:344:37 | cipherSuites | semmle.label | cipherSuites | +| UnsafeTLS.go:344:40:344:43 | selection of ID | semmle.label | selection of ID | | UnsafeTLS.go:346:25:346:36 | cipherSuites | semmle.label | cipherSuites | | UnsafeTLS.go:351:13:351:38 | call to InsecureCipherSuites | semmle.label | call to InsecureCipherSuites | +| UnsafeTLS.go:353:19:353:52 | call to append | semmle.label | call to append | +| UnsafeTLS.go:353:26:353:37 | cipherSuites | semmle.label | cipherSuites | +| UnsafeTLS.go:353:40:353:51 | selection of ID | semmle.label | selection of ID | | UnsafeTLS.go:355:25:355:36 | cipherSuites | semmle.label | cipherSuites | | UnsafeTLS.go:362:18:364:4 | slice literal | semmle.label | slice literal | | UnsafeTLS.go:363:5:363:47 | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | semmle.label | selection of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected index 59af6f28787..e1e037af120 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.expected @@ -1,6 +1,8 @@ edges -| sample.go:15:24:15:63 | type conversion | sample.go:16:9:16:15 | slice expression | -| sample.go:15:49:15:61 | call to Uint32 | sample.go:15:24:15:63 | type conversion | +| sample.go:15:10:15:64 | call to Sum256 | sample.go:16:9:16:15 | slice expression | +| sample.go:15:24:15:63 | type conversion | sample.go:15:10:15:64 | call to Sum256 | +| sample.go:15:31:15:62 | call to Sprintf | sample.go:15:24:15:63 | type conversion | +| sample.go:15:49:15:61 | call to Uint32 | sample.go:15:31:15:62 | call to Sprintf | | sample.go:16:9:16:15 | slice expression | sample.go:26:25:26:30 | call to Guid | | sample.go:33:2:33:6 | definition of nonce | sample.go:37:25:37:29 | nonce | | sample.go:33:2:33:6 | definition of nonce | sample.go:37:32:37:36 | nonce | @@ -8,7 +10,9 @@ edges | sample.go:35:14:35:19 | random | sample.go:33:2:33:6 | definition of nonce | nodes | InsecureRandomness.go:12:18:12:40 | call to Intn | semmle.label | call to Intn | +| sample.go:15:10:15:64 | call to Sum256 | semmle.label | call to Sum256 | | sample.go:15:24:15:63 | type conversion | semmle.label | type conversion | +| sample.go:15:31:15:62 | call to Sprintf | semmle.label | call to Sprintf | | sample.go:15:49:15:61 | call to Uint32 | semmle.label | call to Uint32 | | sample.go:16:9:16:15 | slice expression | semmle.label | slice expression | | sample.go:26:25:26:30 | call to Guid | semmle.label | call to Guid | diff --git a/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.expected b/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.expected index c21e28717c7..35b84bf249a 100644 --- a/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.expected +++ b/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.expected @@ -17,7 +17,8 @@ edges | ConstantOauth2State.go:210:9:210:42 | call to AuthCodeURL | ConstantOauth2State.go:211:54:211:56 | url | | ConstantOauth2State.go:232:9:232:42 | call to AuthCodeURL | ConstantOauth2State.go:233:28:233:30 | url | | ConstantOauth2State.go:239:17:239:39 | "http://localhost:8080" | ConstantOauth2State.go:249:9:249:12 | conf | -| ConstantOauth2State.go:256:38:256:60 | "http://localhost:8080" | ConstantOauth2State.go:266:9:266:12 | conf | +| ConstantOauth2State.go:256:17:256:67 | call to Sprintf | ConstantOauth2State.go:266:9:266:12 | conf | +| ConstantOauth2State.go:256:38:256:60 | "http://localhost:8080" | ConstantOauth2State.go:256:17:256:67 | call to Sprintf | | ConstantOauth2State.go:272:17:272:21 | "oob" | ConstantOauth2State.go:282:9:282:12 | conf | nodes | ConstantOauth2State.go:20:26:20:32 | "state" | semmle.label | "state" | @@ -46,6 +47,7 @@ nodes | ConstantOauth2State.go:239:17:239:39 | "http://localhost:8080" | semmle.label | "http://localhost:8080" | | ConstantOauth2State.go:249:9:249:12 | conf | semmle.label | conf | | ConstantOauth2State.go:249:26:249:41 | stateStringConst | semmle.label | stateStringConst | +| ConstantOauth2State.go:256:17:256:67 | call to Sprintf | semmle.label | call to Sprintf | | ConstantOauth2State.go:256:38:256:60 | "http://localhost:8080" | semmle.label | "http://localhost:8080" | | ConstantOauth2State.go:266:9:266:12 | conf | semmle.label | conf | | ConstantOauth2State.go:266:26:266:41 | stateStringConst | semmle.label | stateStringConst | From 47d0a6d2e3bf36b6124162e1c21867ad65161791 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Tue, 20 Jun 2023 14:30:43 +0200 Subject: [PATCH 687/739] Python: Restore rest of experimental files --- .../experimental/Security/CWE-074/JinjaBad.py | 19 +++++++++ .../Security/CWE-074/JinjaGood.py | 20 ++++++++++ .../semmle/python/templates/Airspeed.py | 10 +++++ .../templates/AirspeedSSTISinks.expected | 2 + .../python/templates/AirspeedSSTISinks.ql | 5 +++ .../semmle/python/templates/Bottle.py | 17 ++++++++ .../python/templates/BottleSSTISinks.expected | 3 ++ .../python/templates/BottleSSTISinks.ql | 5 +++ .../semmle/python/templates/Chameleon.py | 5 +++ .../templates/ChameleonSSTISinks.expected | 2 + .../python/templates/ChameleonSSTISinks.ql | 5 +++ .../templates/CheetahSSTISinks.expected | 3 ++ .../python/templates/CheetahSSTISinks.ql | 5 +++ .../semmle/python/templates/CheetahSinks.py | 20 ++++++++++ .../templates/ChevronSSTISinks.expected | 2 + .../python/templates/ChevronSSTISinks.ql | 5 +++ .../semmle/python/templates/ChevronSinks.py | 22 +++++++++++ .../python/templates/DjangoSSTISinks.expected | 2 + .../python/templates/DjangoSSTISinks.ql | 5 +++ .../python/templates/DjangoTemplates.py | 39 +++++++++++++++++++ .../semmle/python/templates/Genshi.py | 10 +++++ .../python/templates/GenshiSSTISinks.expected | 3 ++ .../python/templates/GenshiSSTISinks.ql | 5 +++ .../python/templates/Jinja2Templates.py | 17 ++++++++ .../python/templates/JinjaSSTISinks.expected | 4 ++ .../semmle/python/templates/JinjaSSTISinks.ql | 5 +++ .../semmle/python/templates/Mako.py | 5 +++ .../python/templates/MakoSSTISinks.expected | 2 + .../semmle/python/templates/MakoSSTISinks.ql | 5 +++ .../semmle/python/templates/TRender.py | 6 +++ .../templates/TRenderSSTISinks.expected | 2 + .../python/templates/TRenderSSTISinks.ql | 5 +++ .../semmle/python/templates/options | 1 + 33 files changed, 266 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-074/JinjaBad.py create mode 100644 python/ql/src/experimental/Security/CWE-074/JinjaGood.py create mode 100644 python/ql/test/experimental/semmle/python/templates/Airspeed.py create mode 100644 python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/Bottle.py create mode 100644 python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/Chameleon.py create mode 100644 python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/CheetahSinks.py create mode 100644 python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/ChevronSinks.py create mode 100644 python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/DjangoTemplates.py create mode 100644 python/ql/test/experimental/semmle/python/templates/Genshi.py create mode 100644 python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/Jinja2Templates.py create mode 100644 python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/Mako.py create mode 100644 python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/TRender.py create mode 100644 python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.expected create mode 100644 python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.ql create mode 100644 python/ql/test/experimental/semmle/python/templates/options diff --git a/python/ql/src/experimental/Security/CWE-074/JinjaBad.py b/python/ql/src/experimental/Security/CWE-074/JinjaBad.py new file mode 100644 index 00000000000..aaac3ec819e --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-074/JinjaBad.py @@ -0,0 +1,19 @@ +from django.urls import path +from django.http import HttpResponse +from jinja2 import Template as Jinja2_Template +from jinja2 import Environment, DictLoader, escape + + +def a(request): + # Load the template + template = request.GET['template'] + t = Jinja2_Template(template) + name = request.GET['name'] + # Render the template with the context data + html = t.render(name=escape(name)) + return HttpResponse(html) + + +urlpatterns = [ + path('a', a), +] diff --git a/python/ql/src/experimental/Security/CWE-074/JinjaGood.py b/python/ql/src/experimental/Security/CWE-074/JinjaGood.py new file mode 100644 index 00000000000..a1b60561850 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-074/JinjaGood.py @@ -0,0 +1,20 @@ +from django.urls import path +from django.http import HttpResponse +from jinja2 import Template as Jinja2_Template +from jinja2 import Environment, DictLoader, escape + + +def a(request): + # Load the template + template = request.GET['template'] + env = SandboxedEnvironment(undefined=StrictUndefined) + t = env.from_string(template) + name = request.GET['name'] + # Render the template with the context data + html = t.render(name=escape(name)) + return HttpResponse(html) + + +urlpatterns = [ + path('a', a), +] diff --git a/python/ql/test/experimental/semmle/python/templates/Airspeed.py b/python/ql/test/experimental/semmle/python/templates/Airspeed.py new file mode 100644 index 00000000000..a41d70432a0 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/Airspeed.py @@ -0,0 +1,10 @@ +from bottle import Bottle, route, request, redirect, response +import airspeed + + +app = Bottle() + + +@route('/other') +def a(): + return airspeed.Template("sink") diff --git a/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.expected new file mode 100644 index 00000000000..e938211434c --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.expected @@ -0,0 +1,2 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (AirspeedSSTISinks.ql:4,6-14) +| Airspeed.py:10:30:10:35 | argument to airspeed.Template() | diff --git a/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.ql new file mode 100644 index 00000000000..e9c51ef11ad --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/AirspeedSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.Airspeed + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/Bottle.py b/python/ql/test/experimental/semmle/python/templates/Bottle.py new file mode 100644 index 00000000000..f6b2fec090e --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/Bottle.py @@ -0,0 +1,17 @@ +from bottle import Bottle, route, request, redirect, response, SimpleTemplate +from bottle import template as temp + + +app = Bottle() + + +@route('/other') +def a(): + template = "test" + tpl = SimpleTemplate(template) + + +@route('/other2') +def b(): + template = "test" + return temp(template, name='World') diff --git a/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.expected new file mode 100644 index 00000000000..1802708c2de --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.expected @@ -0,0 +1,3 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (BottleSSTISinks.ql:4,6-14) +| Bottle.py:11:26:11:33 | argument to bottle.SimpleTemplate() | +| Bottle.py:17:17:17:24 | argument to bottle.template() | diff --git a/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.ql new file mode 100644 index 00000000000..c0ba59ef957 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/BottleSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.Bottle + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/Chameleon.py b/python/ql/test/experimental/semmle/python/templates/Chameleon.py new file mode 100644 index 00000000000..6d96f0752a9 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/Chameleon.py @@ -0,0 +1,5 @@ +from chameleon import PageTemplate + + +def chameleon(): + template = PageTemplate("sink") diff --git a/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.expected new file mode 100644 index 00000000000..d6a46986f11 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.expected @@ -0,0 +1,2 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (ChameleonSSTISinks.ql:4,6-14) +| Chameleon.py:5:29:5:34 | argument to Chameleon.PageTemplate() | diff --git a/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.ql new file mode 100644 index 00000000000..ee9d41434af --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/ChameleonSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.Chameleon + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.expected new file mode 100644 index 00000000000..3971b25e356 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.expected @@ -0,0 +1,3 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (CheetahSSTISinks.ql:4,6-14) +| CheetahSinks.py:10:21:10:26 | argument to Cheetah.Template.Template() | +| CheetahSinks.py:20:20:20:25 | argument to Cheetah.Template.Template() | diff --git a/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.ql new file mode 100644 index 00000000000..10c6c79a4d5 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/CheetahSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.Cheetah + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/CheetahSinks.py b/python/ql/test/experimental/semmle/python/templates/CheetahSinks.py new file mode 100644 index 00000000000..0bb3364a178 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/CheetahSinks.py @@ -0,0 +1,20 @@ +from bottle import Bottle, route, request, redirect, response, SimpleTemplate +from Cheetah.Template import Template + + +app = Bottle() + + +@route('/other') +def a(): + return Template("sink") + + +class Template3(Template): + title = 'Hello World Example!' + contents = 'Hello World!' + + +@route('/other2') +def b(): + t3 = Template3("sink") diff --git a/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.expected new file mode 100644 index 00000000000..50ebb008209 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.expected @@ -0,0 +1,2 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (ChevronSSTISinks.ql:4,6-14) +| ChevronSinks.py:10:27:10:32 | argument to chevron.render() | diff --git a/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.ql new file mode 100644 index 00000000000..545c1f8f79a --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/ChevronSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.Chevron + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/ChevronSinks.py b/python/ql/test/experimental/semmle/python/templates/ChevronSinks.py new file mode 100644 index 00000000000..26d35708bb6 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/ChevronSinks.py @@ -0,0 +1,22 @@ +from bottle import Bottle, route, request, redirect, response, SimpleTemplate +import chevron + + +app = Bottle() + + +@route('/other') +def a(): + return chevron.render("sink", {"key": "value"}) + + +@route('/other2') +def b(): + sink = { + 'template': "template", + + 'data': { + 'key': 'value' + } + } + return chevron.render(**sink) diff --git a/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.expected new file mode 100644 index 00000000000..a38fdbc323f --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.expected @@ -0,0 +1,2 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (DjangoSSTISinks.ql:4,6-14) +| DjangoTemplates.py:9:18:9:25 | argument to Django.template() | diff --git a/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.ql new file mode 100644 index 00000000000..eecd31aeb87 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/DjangoSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.DjangoTemplate + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/DjangoTemplates.py b/python/ql/test/experimental/semmle/python/templates/DjangoTemplates.py new file mode 100644 index 00000000000..981109bf7dc --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/DjangoTemplates.py @@ -0,0 +1,39 @@ +from django.urls import path +from django.http import HttpResponse +from django.template import Template, Context, Engine, engines + + +def dj(request): + # Load the template + template = request.GET['template'] + t = Template(template) + ctx = Context(locals()) + html = t.render(ctx) + return HttpResponse(html) + + +def djEngine(request): + # Load the template + template = request.GET['template'] + + django_engine = engines['django'] + t = django_engine.from_string(template) + ctx = Context(locals()) + html = t.render(ctx) + return HttpResponse(html) + + +def djEngineJinja(request): + # Load the template + template = request.GET['template'] + + django_engine = engines['jinja'] + t = django_engine.from_string(template) + ctx = Context(locals()) + html = t.render(ctx) + return HttpResponse(html) + + +urlpatterns = [ + path('', dj) +] diff --git a/python/ql/test/experimental/semmle/python/templates/Genshi.py b/python/ql/test/experimental/semmle/python/templates/Genshi.py new file mode 100644 index 00000000000..7c46a2b31dc --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/Genshi.py @@ -0,0 +1,10 @@ + + +def genshi1(): + from genshi.template import MarkupTemplate + tmpl = MarkupTemplate('sink') + + +def genshi2(): + from genshi.template import TextTemplate + tmpl = TextTemplate('sink') \ No newline at end of file diff --git a/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.expected new file mode 100644 index 00000000000..cfc22364413 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.expected @@ -0,0 +1,3 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (GenshiSSTISinks.ql:4,6-14) +| Genshi.py:5:27:5:32 | argument to genshi.template.MarkupTemplate() | +| Genshi.py:10:25:10:30 | argument to genshi.template.TextTemplate() | diff --git a/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.ql new file mode 100644 index 00000000000..f0d87e97ec1 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/GenshiSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.Genshi + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/Jinja2Templates.py b/python/ql/test/experimental/semmle/python/templates/Jinja2Templates.py new file mode 100644 index 00000000000..e52538d4946 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/Jinja2Templates.py @@ -0,0 +1,17 @@ +from jinja2 import Template as Jinja2_Template +from jinja2 import Environment, DictLoader, escape + + +def jinja(): + t = Jinja2_Template("sink") + + +def jinja2(): + random = "esdad" + "asdad" + t = Jinja2_Template(random) + + +def jinja3(): + random = 1234 + t = Jinja2_Template("sink"+random) + diff --git a/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.expected new file mode 100644 index 00000000000..7b91c934947 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.expected @@ -0,0 +1,4 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (JinjaSSTISinks.ql:4,6-14) +| Jinja2Templates.py:6:25:6:30 | argument to jinja2.Template() | +| Jinja2Templates.py:11:25:11:30 | argument to jinja2.Template() | +| Jinja2Templates.py:16:25:16:37 | argument to jinja2.Template() | diff --git a/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.ql new file mode 100644 index 00000000000..ca80d8bc570 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/JinjaSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.Jinja + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/Mako.py b/python/ql/test/experimental/semmle/python/templates/Mako.py new file mode 100644 index 00000000000..3af60b164ea --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/Mako.py @@ -0,0 +1,5 @@ + + +def mako(): + from mako.template import Template + mytemplate = Template("sink") diff --git a/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.expected new file mode 100644 index 00000000000..005e14f218a --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.expected @@ -0,0 +1,2 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (MakoSSTISinks.ql:4,6-14) +| Mako.py:5:27:5:32 | argument to mako.template.Template() | diff --git a/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.ql new file mode 100644 index 00000000000..eed89420c54 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/MakoSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.Mako + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/TRender.py b/python/ql/test/experimental/semmle/python/templates/TRender.py new file mode 100644 index 00000000000..6ed5a799942 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/TRender.py @@ -0,0 +1,6 @@ + + +def trender(): + from trender import TRender + template = '@greet world!' + compiled = TRender(template) diff --git a/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.expected b/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.expected new file mode 100644 index 00000000000..26dea55a6c8 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.expected @@ -0,0 +1,2 @@ +WARNING: Type SSTISink has been deprecated and may be removed in future (TRenderSSTISinks.ql:4,6-14) +| TRender.py:6:24:6:31 | argument to trender.TRender() | diff --git a/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.ql b/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.ql new file mode 100644 index 00000000000..ec3a1bba57f --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/TRenderSSTISinks.ql @@ -0,0 +1,5 @@ +import python +import experimental.semmle.python.templates.TRender + +from SSTISink s +select s diff --git a/python/ql/test/experimental/semmle/python/templates/options b/python/ql/test/experimental/semmle/python/templates/options new file mode 100644 index 00000000000..c3bc9413072 --- /dev/null +++ b/python/ql/test/experimental/semmle/python/templates/options @@ -0,0 +1 @@ +semmle-extractor-options: --lang=3 --max-import-depth=3 -p ../../../../../query-tests/Security/lib/ From 41534803e593dd62eede637b21e579f62d77cbb4 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:41:45 +0200 Subject: [PATCH 688/739] Refactor to use `QueryDoc` Kudos to @erik-krogh for the suggestion. --- ql/ql/src/queries/style/AndroidIdPrefix.ql | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/ql/ql/src/queries/style/AndroidIdPrefix.ql b/ql/ql/src/queries/style/AndroidIdPrefix.ql index 46071b08784..71068cca05d 100644 --- a/ql/ql/src/queries/style/AndroidIdPrefix.ql +++ b/ql/ql/src/queries/style/AndroidIdPrefix.ql @@ -1,6 +1,6 @@ /** * @name Android query without android @id prefix - * @description Android queries should include the `android` prefix in their `@id`. + * @description Android queries should include the `android/` prefix in their `@id`. * @kind problem * @problem.severity warning * @id ql/android-id-prefix @@ -9,10 +9,7 @@ import ql -string getIdProperty(QLDoc doc) { - result = any(string id | id = doc.getContents().splitAt("@") and id.matches("id %")) -} - +/** Holds if `t` transitively imports an Android module. */ predicate importsAndroidModule(TopLevel t) { exists(Import i | t.getAnImport() = i | i.getImportString().toLowerCase().matches("%android%") @@ -24,9 +21,9 @@ predicate importsAndroidModule(TopLevel t) { ) } -from TopLevel t +from QueryDoc d where - t.getLocation().getFile().getRelativePath().matches("%src/Security/%.ql") and - not getIdProperty(t.getQLDoc()).matches("% java/android/%") and - importsAndroidModule(t) -select t, "This Android query is missing the `android` prefix in its `@id`." + d.getLocation().getFile().getRelativePath().matches("%src/Security/%") and + not d.getQueryId().matches("android/%") and + importsAndroidModule(d.getParent()) +select d, "This Android query is missing the `android/` prefix in its `@id`." From 818c312a5680873b85d3c8069542f261d06d2737 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:50:33 +0200 Subject: [PATCH 689/739] Add exception for `java/improper-intent-verification` As suggested by @igfoo. --- ql/ql/src/queries/style/AndroidIdPrefix.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/ql/ql/src/queries/style/AndroidIdPrefix.ql b/ql/ql/src/queries/style/AndroidIdPrefix.ql index 71068cca05d..cb12d008c3e 100644 --- a/ql/ql/src/queries/style/AndroidIdPrefix.ql +++ b/ql/ql/src/queries/style/AndroidIdPrefix.ql @@ -25,5 +25,6 @@ from QueryDoc d where d.getLocation().getFile().getRelativePath().matches("%src/Security/%") and not d.getQueryId().matches("android/%") and + not d.getQueryId() = "improper-intent-verification" and // known badly identified query that sadly we can't fix importsAndroidModule(d.getParent()) select d, "This Android query is missing the `android/` prefix in its `@id`." From 768478103cc4e1b5c44be59c39f39a05a3397cab Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 20 Jun 2023 15:16:37 +0200 Subject: [PATCH 690/739] Add another exception --- ql/ql/src/queries/style/AndroidIdPrefix.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/ql/src/queries/style/AndroidIdPrefix.ql b/ql/ql/src/queries/style/AndroidIdPrefix.ql index cb12d008c3e..eae34e2f899 100644 --- a/ql/ql/src/queries/style/AndroidIdPrefix.ql +++ b/ql/ql/src/queries/style/AndroidIdPrefix.ql @@ -25,6 +25,6 @@ from QueryDoc d where d.getLocation().getFile().getRelativePath().matches("%src/Security/%") and not d.getQueryId().matches("android/%") and - not d.getQueryId() = "improper-intent-verification" and // known badly identified query that sadly we can't fix + not d.getQueryId() = ["improper-intent-verification", "improper-webview-certificate-validation"] and // known badly identified queries that sadly we can't fix importsAndroidModule(d.getParent()) select d, "This Android query is missing the `android/` prefix in its `@id`." From 12c810c63d6c566def7a44ebea3369c43bc8b8c9 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 20 Jun 2023 15:23:08 +0200 Subject: [PATCH 691/739] QL: Add tests for `FieldOnlyUsedInCharPred.ql` --- .../FieldOnlyUsedInCharPred.expected | 2 ++ .../FieldOnlyUsedInCharPred.qll | 29 +++++++++++++++++++ .../FieldOnlyUsedInCharPred.qlref | 1 + 3 files changed, 32 insertions(+) create mode 100644 ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected create mode 100644 ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.qll create mode 100644 ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.qlref diff --git a/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected b/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected new file mode 100644 index 00000000000..1da84706eff --- /dev/null +++ b/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected @@ -0,0 +1,2 @@ +| FieldOnlyUsedInCharPred.qll:2:3:2:12 | FieldDecl | Field is only used in CharPred. | +| FieldOnlyUsedInCharPred.qll:22:3:22:11 | FieldDecl | Field is only used in CharPred. | diff --git a/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.qll b/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.qll new file mode 100644 index 00000000000..edfc8b4576e --- /dev/null +++ b/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.qll @@ -0,0 +1,29 @@ +class C1 extends int { + int field; // BAD + + C1() { + this = field and + this = 0 + } +} + +class C2 extends C1 { + int field2; // GOOD + + C2() { + this = field2 and + this = 0 + } + + int getField() { result = field2 } +} + +class C3 extends int { + C1 field; // GOOD (overridden) + + C3() { this = field } +} + +class C4 extends C3 { + override C2 field; // GOOD (overriding) +} diff --git a/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.qlref b/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.qlref new file mode 100644 index 00000000000..0e77c6ae6fe --- /dev/null +++ b/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.qlref @@ -0,0 +1 @@ +queries/style/FieldOnlyUsedInCharPred.ql From d296256920cf4b4a07575f48270bed7c0170f4ed Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 20 Jun 2023 15:24:09 +0200 Subject: [PATCH 692/739] QL: Exclude overridden fields from `FieldOnlyUsedInCharPred.ql` --- ql/ql/src/queries/style/FieldOnlyUsedInCharPred.ql | 3 ++- .../FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/ql/src/queries/style/FieldOnlyUsedInCharPred.ql b/ql/ql/src/queries/style/FieldOnlyUsedInCharPred.ql index e1f4810d391..3216cc9a6af 100644 --- a/ql/ql/src/queries/style/FieldOnlyUsedInCharPred.ql +++ b/ql/ql/src/queries/style/FieldOnlyUsedInCharPred.ql @@ -21,5 +21,6 @@ where any(PredicateCall call | call.getEnclosingPredicate() = c.getCharPred() and call.getTarget() instanceof NewTypeBranch ).getAnArgument() and - not f.getVarDecl().overrides(_) + not f.getVarDecl().overrides(_) and + not any(FieldDecl other).getVarDecl().overrides(f.getVarDecl()) select f, "Field is only used in CharPred." diff --git a/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected b/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected index 1da84706eff..f41af0cebaf 100644 --- a/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected +++ b/ql/ql/test/queries/style/FieldOnlyUsedInCharPred/FieldOnlyUsedInCharPred.expected @@ -1,2 +1 @@ | FieldOnlyUsedInCharPred.qll:2:3:2:12 | FieldDecl | Field is only used in CharPred. | -| FieldOnlyUsedInCharPred.qll:22:3:22:11 | FieldDecl | Field is only used in CharPred. | From c230c9f79301b90a80c0790ea0861efa8b950712 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 20 Jun 2023 15:30:46 +0200 Subject: [PATCH 693/739] Consider only Java files in importsAndroidModule --- ql/ql/src/queries/style/AndroidIdPrefix.ql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ql/ql/src/queries/style/AndroidIdPrefix.ql b/ql/ql/src/queries/style/AndroidIdPrefix.ql index eae34e2f899..0e6da6f32d2 100644 --- a/ql/ql/src/queries/style/AndroidIdPrefix.ql +++ b/ql/ql/src/queries/style/AndroidIdPrefix.ql @@ -11,6 +11,8 @@ import ql /** Holds if `t` transitively imports an Android module. */ predicate importsAndroidModule(TopLevel t) { + t.getFile() = + any(YAML::QLPack pack | pack.getExtractor() = "java").getADependency*().getAFileInPack() and exists(Import i | t.getAnImport() = i | i.getImportString().toLowerCase().matches("%android%") or From 0baf78f8fa38419044f4c09824b4fe98a927fec9 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <owen-mc@github.com> Date: Tue, 20 Jun 2023 14:33:29 +0100 Subject: [PATCH 694/739] Add change note --- .../lib/change-notes/2023-06-20-function-model-path-nodes.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/lib/change-notes/2023-06-20-function-model-path-nodes.md diff --git a/go/ql/lib/change-notes/2023-06-20-function-model-path-nodes.md b/go/ql/lib/change-notes/2023-06-20-function-model-path-nodes.md new file mode 100644 index 00000000000..5c616481326 --- /dev/null +++ b/go/ql/lib/change-notes/2023-06-20-function-model-path-nodes.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* When a result of path query flows through a function modeled using `DataFlow::FunctionModel` or `TaintTracking::FunctionModel`, the path now includes nodes corresponding to the input and output to the function. This brings it in line with functions modeled using Models-as-Data. From 3c60f52a1bc4d0fcce4b7774b3276b829c946069 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 20 Jun 2023 15:40:41 +0200 Subject: [PATCH 695/739] Update ql/ql/src/queries/style/AndroidIdPrefix.ql Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com> --- ql/ql/src/queries/style/AndroidIdPrefix.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/ql/src/queries/style/AndroidIdPrefix.ql b/ql/ql/src/queries/style/AndroidIdPrefix.ql index 0e6da6f32d2..88b479cc7d4 100644 --- a/ql/ql/src/queries/style/AndroidIdPrefix.ql +++ b/ql/ql/src/queries/style/AndroidIdPrefix.ql @@ -12,7 +12,7 @@ import ql /** Holds if `t` transitively imports an Android module. */ predicate importsAndroidModule(TopLevel t) { t.getFile() = - any(YAML::QLPack pack | pack.getExtractor() = "java").getADependency*().getAFileInPack() and + any(YAML::QLPack pack | pack.getADependency*().getExtractor() = "java").getAFileInPack() and exists(Import i | t.getAnImport() = i | i.getImportString().toLowerCase().matches("%android%") or From 7aec22c1e4f36bdcc720ae8504109d6ba153a71c Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 20 Jun 2023 14:57:23 +0100 Subject: [PATCH 696/739] Ruby: rack - remove MIME modelling --- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 7 +- .../ruby/frameworks/rack/internal/Mime.qll | 1311 ----------------- .../frameworks/rack/Rack.expected | 4 +- .../library-tests/frameworks/rack/Rack.ql | 4 - .../library-tests/frameworks/rack/rack.rb | 2 +- 5 files changed, 5 insertions(+), 1323 deletions(-) delete mode 100644 ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index 74553476d17..4d9342d8805 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -7,9 +7,8 @@ */ module Rack { import rack.internal.App - import rack.internal.Mime - import rack.internal.Response::Public as Response +import rack.internal.Response::Public as Response - /** DEPRECATED: Alias for App::AppCandidate */ - deprecated class AppCandidate = App::AppCandidate; +/** DEPRECATED: Alias for App::AppCandidate */ +deprecated class AppCandidate = App::AppCandidate; } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll deleted file mode 100644 index c7682c25638..00000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Mime.qll +++ /dev/null @@ -1,1311 +0,0 @@ -/** - * Provides modeling for the `Mime` component of the `Rack` library. - */ - -private import codeql.ruby.ApiGraphs -private import codeql.ruby.DataFlow - -private predicate mimetypeMatches(string ext, string mimeType) { - ext = ".123" and mimeType = "application/vnd.lotus-1-2-3" - or - ext = ".3dml" and mimeType = "text/vnd.in3d.3dml" - or - ext = ".3g2" and mimeType = "video/3gpp2" - or - ext = ".3gp" and mimeType = "video/3gpp" - or - ext = ".a" and mimeType = "application/octet-stream" - or - ext = ".acc" and mimeType = "application/vnd.americandynamics.acc" - or - ext = ".ace" and mimeType = "application/x-ace-compressed" - or - ext = ".acu" and mimeType = "application/vnd.acucobol" - or - ext = ".aep" and mimeType = "application/vnd.audiograph" - or - ext = ".afp" and mimeType = "application/vnd.ibm.modcap" - or - ext = ".ai" and mimeType = "application/postscript" - or - ext = ".aif" and mimeType = "audio/x-aiff" - or - ext = ".aiff" and mimeType = "audio/x-aiff" - or - ext = ".ami" and mimeType = "application/vnd.amiga.ami" - or - ext = ".apng" and mimeType = "image/apng" - or - ext = ".appcache" and mimeType = "text/cache-manifest" - or - ext = ".apr" and mimeType = "application/vnd.lotus-approach" - or - ext = ".asc" and mimeType = "application/pgp-signature" - or - ext = ".asf" and mimeType = "video/x-ms-asf" - or - ext = ".asm" and mimeType = "text/x-asm" - or - ext = ".aso" and mimeType = "application/vnd.accpac.simply.aso" - or - ext = ".asx" and mimeType = "video/x-ms-asf" - or - ext = ".atc" and mimeType = "application/vnd.acucorp" - or - ext = ".atom" and mimeType = "application/atom+xml" - or - ext = ".atomcat" and mimeType = "application/atomcat+xml" - or - ext = ".atomsvc" and mimeType = "application/atomsvc+xml" - or - ext = ".atx" and mimeType = "application/vnd.antix.game-component" - or - ext = ".au" and mimeType = "audio/basic" - or - ext = ".avi" and mimeType = "video/x-msvideo" - or - ext = ".avif" and mimeType = "image/avif" - or - ext = ".bat" and mimeType = "application/x-msdownload" - or - ext = ".bcpio" and mimeType = "application/x-bcpio" - or - ext = ".bdm" and mimeType = "application/vnd.syncml.dm+wbxml" - or - ext = ".bh2" and mimeType = "application/vnd.fujitsu.oasysprs" - or - ext = ".bin" and mimeType = "application/octet-stream" - or - ext = ".bmi" and mimeType = "application/vnd.bmi" - or - ext = ".bmp" and mimeType = "image/bmp" - or - ext = ".box" and mimeType = "application/vnd.previewsystems.box" - or - ext = ".btif" and mimeType = "image/prs.btif" - or - ext = ".bz" and mimeType = "application/x-bzip" - or - ext = ".bz2" and mimeType = "application/x-bzip2" - or - ext = ".c" and mimeType = "text/x-c" - or - ext = ".c4g" and mimeType = "application/vnd.clonk.c4group" - or - ext = ".cab" and mimeType = "application/vnd.ms-cab-compressed" - or - ext = ".cc" and mimeType = "text/x-c" - or - ext = ".ccxml" and mimeType = "application/ccxml+xml" - or - ext = ".cdbcmsg" and mimeType = "application/vnd.contact.cmsg" - or - ext = ".cdkey" and mimeType = "application/vnd.mediastation.cdkey" - or - ext = ".cdx" and mimeType = "chemical/x-cdx" - or - ext = ".cdxml" and mimeType = "application/vnd.chemdraw+xml" - or - ext = ".cdy" and mimeType = "application/vnd.cinderella" - or - ext = ".cer" and mimeType = "application/pkix-cert" - or - ext = ".cgm" and mimeType = "image/cgm" - or - ext = ".chat" and mimeType = "application/x-chat" - or - ext = ".chm" and mimeType = "application/vnd.ms-htmlhelp" - or - ext = ".chrt" and mimeType = "application/vnd.kde.kchart" - or - ext = ".cif" and mimeType = "chemical/x-cif" - or - ext = ".cii" and mimeType = "application/vnd.anser-web-certificate-issue-initiation" - or - ext = ".cil" and mimeType = "application/vnd.ms-artgalry" - or - ext = ".cla" and mimeType = "application/vnd.claymore" - or - ext = ".class" and mimeType = "application/octet-stream" - or - ext = ".clkk" and mimeType = "application/vnd.crick.clicker.keyboard" - or - ext = ".clkp" and mimeType = "application/vnd.crick.clicker.palette" - or - ext = ".clkt" and mimeType = "application/vnd.crick.clicker.template" - or - ext = ".clkw" and mimeType = "application/vnd.crick.clicker.wordbank" - or - ext = ".clkx" and mimeType = "application/vnd.crick.clicker" - or - ext = ".clp" and mimeType = "application/x-msclip" - or - ext = ".cmc" and mimeType = "application/vnd.cosmocaller" - or - ext = ".cmdf" and mimeType = "chemical/x-cmdf" - or - ext = ".cml" and mimeType = "chemical/x-cml" - or - ext = ".cmp" and mimeType = "application/vnd.yellowriver-custom-menu" - or - ext = ".cmx" and mimeType = "image/x-cmx" - or - ext = ".com" and mimeType = "application/x-msdownload" - or - ext = ".conf" and mimeType = "text/plain" - or - ext = ".cpio" and mimeType = "application/x-cpio" - or - ext = ".cpp" and mimeType = "text/x-c" - or - ext = ".cpt" and mimeType = "application/mac-compactpro" - or - ext = ".crd" and mimeType = "application/x-mscardfile" - or - ext = ".crl" and mimeType = "application/pkix-crl" - or - ext = ".crt" and mimeType = "application/x-x509-ca-cert" - or - ext = ".csh" and mimeType = "application/x-csh" - or - ext = ".csml" and mimeType = "chemical/x-csml" - or - ext = ".csp" and mimeType = "application/vnd.commonspace" - or - ext = ".css" and mimeType = "text/css" - or - ext = ".csv" and mimeType = "text/csv" - or - ext = ".curl" and mimeType = "application/vnd.curl" - or - ext = ".cww" and mimeType = "application/prs.cww" - or - ext = ".cxx" and mimeType = "text/x-c" - or - ext = ".daf" and mimeType = "application/vnd.mobius.daf" - or - ext = ".davmount" and mimeType = "application/davmount+xml" - or - ext = ".dcr" and mimeType = "application/x-director" - or - ext = ".dd2" and mimeType = "application/vnd.oma.dd2+xml" - or - ext = ".ddd" and mimeType = "application/vnd.fujixerox.ddd" - or - ext = ".deb" and mimeType = "application/x-debian-package" - or - ext = ".der" and mimeType = "application/x-x509-ca-cert" - or - ext = ".dfac" and mimeType = "application/vnd.dreamfactory" - or - ext = ".diff" and mimeType = "text/x-diff" - or - ext = ".dis" and mimeType = "application/vnd.mobius.dis" - or - ext = ".djv" and mimeType = "image/vnd.djvu" - or - ext = ".djvu" and mimeType = "image/vnd.djvu" - or - ext = ".dll" and mimeType = "application/x-msdownload" - or - ext = ".dmg" and mimeType = "application/octet-stream" - or - ext = ".dna" and mimeType = "application/vnd.dna" - or - ext = ".doc" and mimeType = "application/msword" - or - ext = ".docm" and mimeType = "application/vnd.ms-word.document.macroEnabled.12" - or - ext = ".docx" and - mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" - or - ext = ".dot" and mimeType = "application/msword" - or - ext = ".dotm" and mimeType = "application/vnd.ms-word.template.macroEnabled.12" - or - ext = ".dotx" and - mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template" - or - ext = ".dp" and mimeType = "application/vnd.osgi.dp" - or - ext = ".dpg" and mimeType = "application/vnd.dpgraph" - or - ext = ".dsc" and mimeType = "text/prs.lines.tag" - or - ext = ".dtd" and mimeType = "application/xml-dtd" - or - ext = ".dts" and mimeType = "audio/vnd.dts" - or - ext = ".dtshd" and mimeType = "audio/vnd.dts.hd" - or - ext = ".dv" and mimeType = "video/x-dv" - or - ext = ".dvi" and mimeType = "application/x-dvi" - or - ext = ".dwf" and mimeType = "model/vnd.dwf" - or - ext = ".dwg" and mimeType = "image/vnd.dwg" - or - ext = ".dxf" and mimeType = "image/vnd.dxf" - or - ext = ".dxp" and mimeType = "application/vnd.spotfire.dxp" - or - ext = ".ear" and mimeType = "application/java-archive" - or - ext = ".ecelp4800" and mimeType = "audio/vnd.nuera.ecelp4800" - or - ext = ".ecelp7470" and mimeType = "audio/vnd.nuera.ecelp7470" - or - ext = ".ecelp9600" and mimeType = "audio/vnd.nuera.ecelp9600" - or - ext = ".ecma" and mimeType = "application/ecmascript" - or - ext = ".edm" and mimeType = "application/vnd.novadigm.edm" - or - ext = ".edx" and mimeType = "application/vnd.novadigm.edx" - or - ext = ".efif" and mimeType = "application/vnd.picsel" - or - ext = ".ei6" and mimeType = "application/vnd.pg.osasli" - or - ext = ".eml" and mimeType = "message/rfc822" - or - ext = ".eol" and mimeType = "audio/vnd.digital-winds" - or - ext = ".eot" and mimeType = "application/vnd.ms-fontobject" - or - ext = ".eps" and mimeType = "application/postscript" - or - ext = ".es3" and mimeType = "application/vnd.eszigno3+xml" - or - ext = ".esf" and mimeType = "application/vnd.epson.esf" - or - ext = ".etx" and mimeType = "text/x-setext" - or - ext = ".exe" and mimeType = "application/x-msdownload" - or - ext = ".ext" and mimeType = "application/vnd.novadigm.ext" - or - ext = ".ez" and mimeType = "application/andrew-inset" - or - ext = ".ez2" and mimeType = "application/vnd.ezpix-album" - or - ext = ".ez3" and mimeType = "application/vnd.ezpix-package" - or - ext = ".f" and mimeType = "text/x-fortran" - or - ext = ".f77" and mimeType = "text/x-fortran" - or - ext = ".f90" and mimeType = "text/x-fortran" - or - ext = ".fbs" and mimeType = "image/vnd.fastbidsheet" - or - ext = ".fdf" and mimeType = "application/vnd.fdf" - or - ext = ".fe_launch" and mimeType = "application/vnd.denovo.fcselayout-link" - or - ext = ".fg5" and mimeType = "application/vnd.fujitsu.oasysgp" - or - ext = ".fli" and mimeType = "video/x-fli" - or - ext = ".flif" and mimeType = "image/flif" - or - ext = ".flo" and mimeType = "application/vnd.micrografx.flo" - or - ext = ".flv" and mimeType = "video/x-flv" - or - ext = ".flw" and mimeType = "application/vnd.kde.kivio" - or - ext = ".flx" and mimeType = "text/vnd.fmi.flexstor" - or - ext = ".fly" and mimeType = "text/vnd.fly" - or - ext = ".fm" and mimeType = "application/vnd.framemaker" - or - ext = ".fnc" and mimeType = "application/vnd.frogans.fnc" - or - ext = ".for" and mimeType = "text/x-fortran" - or - ext = ".fpx" and mimeType = "image/vnd.fpx" - or - ext = ".fsc" and mimeType = "application/vnd.fsc.weblaunch" - or - ext = ".fst" and mimeType = "image/vnd.fst" - or - ext = ".ftc" and mimeType = "application/vnd.fluxtime.clip" - or - ext = ".fti" and mimeType = "application/vnd.anser-web-funds-transfer-initiation" - or - ext = ".fvt" and mimeType = "video/vnd.fvt" - or - ext = ".fzs" and mimeType = "application/vnd.fuzzysheet" - or - ext = ".g3" and mimeType = "image/g3fax" - or - ext = ".gac" and mimeType = "application/vnd.groove-account" - or - ext = ".gdl" and mimeType = "model/vnd.gdl" - or - ext = ".gem" and mimeType = "application/octet-stream" - or - ext = ".gemspec" and mimeType = "text/x-script.ruby" - or - ext = ".ghf" and mimeType = "application/vnd.groove-help" - or - ext = ".gif" and mimeType = "image/gif" - or - ext = ".gim" and mimeType = "application/vnd.groove-identity-message" - or - ext = ".gmx" and mimeType = "application/vnd.gmx" - or - ext = ".gph" and mimeType = "application/vnd.flographit" - or - ext = ".gqf" and mimeType = "application/vnd.grafeq" - or - ext = ".gram" and mimeType = "application/srgs" - or - ext = ".grv" and mimeType = "application/vnd.groove-injector" - or - ext = ".grxml" and mimeType = "application/srgs+xml" - or - ext = ".gtar" and mimeType = "application/x-gtar" - or - ext = ".gtm" and mimeType = "application/vnd.groove-tool-message" - or - ext = ".gtw" and mimeType = "model/vnd.gtw" - or - ext = ".gv" and mimeType = "text/vnd.graphviz" - or - ext = ".gz" and mimeType = "application/x-gzip" - or - ext = ".h" and mimeType = "text/x-c" - or - ext = ".h261" and mimeType = "video/h261" - or - ext = ".h263" and mimeType = "video/h263" - or - ext = ".h264" and mimeType = "video/h264" - or - ext = ".hbci" and mimeType = "application/vnd.hbci" - or - ext = ".hdf" and mimeType = "application/x-hdf" - or - ext = ".heic" and mimeType = "image/heic" - or - ext = ".heics" and mimeType = "image/heic-sequence" - or - ext = ".heif" and mimeType = "image/heif" - or - ext = ".heifs" and mimeType = "image/heif-sequence" - or - ext = ".hh" and mimeType = "text/x-c" - or - ext = ".hlp" and mimeType = "application/winhlp" - or - ext = ".hpgl" and mimeType = "application/vnd.hp-hpgl" - or - ext = ".hpid" and mimeType = "application/vnd.hp-hpid" - or - ext = ".hps" and mimeType = "application/vnd.hp-hps" - or - ext = ".hqx" and mimeType = "application/mac-binhex40" - or - ext = ".htc" and mimeType = "text/x-component" - or - ext = ".htke" and mimeType = "application/vnd.kenameaapp" - or - ext = ".htm" and mimeType = "text/html" - or - ext = ".html" and mimeType = "text/html" - or - ext = ".hvd" and mimeType = "application/vnd.yamaha.hv-dic" - or - ext = ".hvp" and mimeType = "application/vnd.yamaha.hv-voice" - or - ext = ".hvs" and mimeType = "application/vnd.yamaha.hv-script" - or - ext = ".icc" and mimeType = "application/vnd.iccprofile" - or - ext = ".ice" and mimeType = "x-conference/x-cooltalk" - or - ext = ".ico" and mimeType = "image/vnd.microsoft.icon" - or - ext = ".ics" and mimeType = "text/calendar" - or - ext = ".ief" and mimeType = "image/ief" - or - ext = ".ifb" and mimeType = "text/calendar" - or - ext = ".ifm" and mimeType = "application/vnd.shana.informed.formdata" - or - ext = ".igl" and mimeType = "application/vnd.igloader" - or - ext = ".igs" and mimeType = "model/iges" - or - ext = ".igx" and mimeType = "application/vnd.micrografx.igx" - or - ext = ".iif" and mimeType = "application/vnd.shana.informed.interchange" - or - ext = ".imp" and mimeType = "application/vnd.accpac.simply.imp" - or - ext = ".ims" and mimeType = "application/vnd.ms-ims" - or - ext = ".ipk" and mimeType = "application/vnd.shana.informed.package" - or - ext = ".irm" and mimeType = "application/vnd.ibm.rights-management" - or - ext = ".irp" and mimeType = "application/vnd.irepository.package+xml" - or - ext = ".iso" and mimeType = "application/octet-stream" - or - ext = ".itp" and mimeType = "application/vnd.shana.informed.formtemplate" - or - ext = ".ivp" and mimeType = "application/vnd.immervision-ivp" - or - ext = ".ivu" and mimeType = "application/vnd.immervision-ivu" - or - ext = ".jad" and mimeType = "text/vnd.sun.j2me.app-descriptor" - or - ext = ".jam" and mimeType = "application/vnd.jam" - or - ext = ".jar" and mimeType = "application/java-archive" - or - ext = ".java" and mimeType = "text/x-java-source" - or - ext = ".jisp" and mimeType = "application/vnd.jisp" - or - ext = ".jlt" and mimeType = "application/vnd.hp-jlyt" - or - ext = ".jnlp" and mimeType = "application/x-java-jnlp-file" - or - ext = ".joda" and mimeType = "application/vnd.joost.joda-archive" - or - ext = ".jp2" and mimeType = "image/jp2" - or - ext = ".jpeg" and mimeType = "image/jpeg" - or - ext = ".jpg" and mimeType = "image/jpeg" - or - ext = ".jpgv" and mimeType = "video/jpeg" - or - ext = ".jpm" and mimeType = "video/jpm" - or - ext = ".js" and mimeType = "application/javascript" - or - ext = ".json" and mimeType = "application/json" - or - ext = ".karbon" and mimeType = "application/vnd.kde.karbon" - or - ext = ".kfo" and mimeType = "application/vnd.kde.kformula" - or - ext = ".kia" and mimeType = "application/vnd.kidspiration" - or - ext = ".kml" and mimeType = "application/vnd.google-earth.kml+xml" - or - ext = ".kmz" and mimeType = "application/vnd.google-earth.kmz" - or - ext = ".kne" and mimeType = "application/vnd.kinar" - or - ext = ".kon" and mimeType = "application/vnd.kde.kontour" - or - ext = ".kpr" and mimeType = "application/vnd.kde.kpresenter" - or - ext = ".ksp" and mimeType = "application/vnd.kde.kspread" - or - ext = ".ktz" and mimeType = "application/vnd.kahootz" - or - ext = ".kwd" and mimeType = "application/vnd.kde.kword" - or - ext = ".latex" and mimeType = "application/x-latex" - or - ext = ".lbd" and mimeType = "application/vnd.llamagraphics.life-balance.desktop" - or - ext = ".lbe" and mimeType = "application/vnd.llamagraphics.life-balance.exchange+xml" - or - ext = ".les" and mimeType = "application/vnd.hhe.lesson-player" - or - ext = ".link66" and mimeType = "application/vnd.route66.link66+xml" - or - ext = ".log" and mimeType = "text/plain" - or - ext = ".lostxml" and mimeType = "application/lost+xml" - or - ext = ".lrm" and mimeType = "application/vnd.ms-lrm" - or - ext = ".ltf" and mimeType = "application/vnd.frogans.ltf" - or - ext = ".lvp" and mimeType = "audio/vnd.lucent.voice" - or - ext = ".lwp" and mimeType = "application/vnd.lotus-wordpro" - or - ext = ".m3u" and mimeType = "audio/x-mpegurl" - or - ext = ".m3u8" and mimeType = "application/x-mpegurl" - or - ext = ".m4a" and mimeType = "audio/mp4a-latm" - or - ext = ".m4v" and mimeType = "video/mp4" - or - ext = ".ma" and mimeType = "application/mathematica" - or - ext = ".mag" and mimeType = "application/vnd.ecowin.chart" - or - ext = ".man" and mimeType = "text/troff" - or - ext = ".manifest" and mimeType = "text/cache-manifest" - or - ext = ".mathml" and mimeType = "application/mathml+xml" - or - ext = ".mbk" and mimeType = "application/vnd.mobius.mbk" - or - ext = ".mbox" and mimeType = "application/mbox" - or - ext = ".mc1" and mimeType = "application/vnd.medcalcdata" - or - ext = ".mcd" and mimeType = "application/vnd.mcd" - or - ext = ".mdb" and mimeType = "application/x-msaccess" - or - ext = ".mdi" and mimeType = "image/vnd.ms-modi" - or - ext = ".mdoc" and mimeType = "text/troff" - or - ext = ".me" and mimeType = "text/troff" - or - ext = ".mfm" and mimeType = "application/vnd.mfmp" - or - ext = ".mgz" and mimeType = "application/vnd.proteus.magazine" - or - ext = ".mid" and mimeType = "audio/midi" - or - ext = ".midi" and mimeType = "audio/midi" - or - ext = ".mif" and mimeType = "application/vnd.mif" - or - ext = ".mime" and mimeType = "message/rfc822" - or - ext = ".mj2" and mimeType = "video/mj2" - or - ext = ".mlp" and mimeType = "application/vnd.dolby.mlp" - or - ext = ".mmd" and mimeType = "application/vnd.chipnuts.karaoke-mmd" - or - ext = ".mmf" and mimeType = "application/vnd.smaf" - or - ext = ".mml" and mimeType = "application/mathml+xml" - or - ext = ".mmr" and mimeType = "image/vnd.fujixerox.edmics-mmr" - or - ext = ".mng" and mimeType = "video/x-mng" - or - ext = ".mny" and mimeType = "application/x-msmoney" - or - ext = ".mov" and mimeType = "video/quicktime" - or - ext = ".movie" and mimeType = "video/x-sgi-movie" - or - ext = ".mp3" and mimeType = "audio/mpeg" - or - ext = ".mp4" and mimeType = "video/mp4" - or - ext = ".mp4a" and mimeType = "audio/mp4" - or - ext = ".mp4s" and mimeType = "application/mp4" - or - ext = ".mp4v" and mimeType = "video/mp4" - or - ext = ".mpc" and mimeType = "application/vnd.mophun.certificate" - or - ext = ".mpd" and mimeType = "application/dash+xml" - or - ext = ".mpeg" and mimeType = "video/mpeg" - or - ext = ".mpg" and mimeType = "video/mpeg" - or - ext = ".mpga" and mimeType = "audio/mpeg" - or - ext = ".mpkg" and mimeType = "application/vnd.apple.installer+xml" - or - ext = ".mpm" and mimeType = "application/vnd.blueice.multipass" - or - ext = ".mpn" and mimeType = "application/vnd.mophun.application" - or - ext = ".mpp" and mimeType = "application/vnd.ms-project" - or - ext = ".mpy" and mimeType = "application/vnd.ibm.minipay" - or - ext = ".mqy" and mimeType = "application/vnd.mobius.mqy" - or - ext = ".mrc" and mimeType = "application/marc" - or - ext = ".ms" and mimeType = "text/troff" - or - ext = ".mscml" and mimeType = "application/mediaservercontrol+xml" - or - ext = ".mseq" and mimeType = "application/vnd.mseq" - or - ext = ".msf" and mimeType = "application/vnd.epson.msf" - or - ext = ".msh" and mimeType = "model/mesh" - or - ext = ".msi" and mimeType = "application/x-msdownload" - or - ext = ".msl" and mimeType = "application/vnd.mobius.msl" - or - ext = ".msty" and mimeType = "application/vnd.muvee.style" - or - ext = ".mts" and mimeType = "model/vnd.mts" - or - ext = ".mus" and mimeType = "application/vnd.musician" - or - ext = ".mvb" and mimeType = "application/x-msmediaview" - or - ext = ".mwf" and mimeType = "application/vnd.mfer" - or - ext = ".mxf" and mimeType = "application/mxf" - or - ext = ".mxl" and mimeType = "application/vnd.recordare.musicxml" - or - ext = ".mxml" and mimeType = "application/xv+xml" - or - ext = ".mxs" and mimeType = "application/vnd.triscape.mxs" - or - ext = ".mxu" and mimeType = "video/vnd.mpegurl" - or - ext = ".n" and mimeType = "application/vnd.nokia.n-gage.symbian.install" - or - ext = ".nc" and mimeType = "application/x-netcdf" - or - ext = ".ngdat" and mimeType = "application/vnd.nokia.n-gage.data" - or - ext = ".nlu" and mimeType = "application/vnd.neurolanguage.nlu" - or - ext = ".nml" and mimeType = "application/vnd.enliven" - or - ext = ".nnd" and mimeType = "application/vnd.noblenet-directory" - or - ext = ".nns" and mimeType = "application/vnd.noblenet-sealer" - or - ext = ".nnw" and mimeType = "application/vnd.noblenet-web" - or - ext = ".npx" and mimeType = "image/vnd.net-fpx" - or - ext = ".nsf" and mimeType = "application/vnd.lotus-notes" - or - ext = ".oa2" and mimeType = "application/vnd.fujitsu.oasys2" - or - ext = ".oa3" and mimeType = "application/vnd.fujitsu.oasys3" - or - ext = ".oas" and mimeType = "application/vnd.fujitsu.oasys" - or - ext = ".obd" and mimeType = "application/x-msbinder" - or - ext = ".oda" and mimeType = "application/oda" - or - ext = ".odc" and mimeType = "application/vnd.oasis.opendocument.chart" - or - ext = ".odf" and mimeType = "application/vnd.oasis.opendocument.formula" - or - ext = ".odg" and mimeType = "application/vnd.oasis.opendocument.graphics" - or - ext = ".odi" and mimeType = "application/vnd.oasis.opendocument.image" - or - ext = ".odp" and mimeType = "application/vnd.oasis.opendocument.presentation" - or - ext = ".ods" and mimeType = "application/vnd.oasis.opendocument.spreadsheet" - or - ext = ".odt" and mimeType = "application/vnd.oasis.opendocument.text" - or - ext = ".oga" and mimeType = "audio/ogg" - or - ext = ".ogg" and mimeType = "application/ogg" - or - ext = ".ogv" and mimeType = "video/ogg" - or - ext = ".ogx" and mimeType = "application/ogg" - or - ext = ".org" and mimeType = "application/vnd.lotus-organizer" - or - ext = ".otc" and mimeType = "application/vnd.oasis.opendocument.chart-template" - or - ext = ".otf" and mimeType = "application/vnd.oasis.opendocument.formula-template" - or - ext = ".otg" and mimeType = "application/vnd.oasis.opendocument.graphics-template" - or - ext = ".oth" and mimeType = "application/vnd.oasis.opendocument.text-web" - or - ext = ".oti" and mimeType = "application/vnd.oasis.opendocument.image-template" - or - ext = ".otm" and mimeType = "application/vnd.oasis.opendocument.text-master" - or - ext = ".ots" and mimeType = "application/vnd.oasis.opendocument.spreadsheet-template" - or - ext = ".ott" and mimeType = "application/vnd.oasis.opendocument.text-template" - or - ext = ".oxt" and mimeType = "application/vnd.openofficeorg.extension" - or - ext = ".p" and mimeType = "text/x-pascal" - or - ext = ".p10" and mimeType = "application/pkcs10" - or - ext = ".p12" and mimeType = "application/x-pkcs12" - or - ext = ".p7b" and mimeType = "application/x-pkcs7-certificates" - or - ext = ".p7m" and mimeType = "application/pkcs7-mime" - or - ext = ".p7r" and mimeType = "application/x-pkcs7-certreqresp" - or - ext = ".p7s" and mimeType = "application/pkcs7-signature" - or - ext = ".pas" and mimeType = "text/x-pascal" - or - ext = ".pbd" and mimeType = "application/vnd.powerbuilder6" - or - ext = ".pbm" and mimeType = "image/x-portable-bitmap" - or - ext = ".pcl" and mimeType = "application/vnd.hp-pcl" - or - ext = ".pclxl" and mimeType = "application/vnd.hp-pclxl" - or - ext = ".pcx" and mimeType = "image/x-pcx" - or - ext = ".pdb" and mimeType = "chemical/x-pdb" - or - ext = ".pdf" and mimeType = "application/pdf" - or - ext = ".pem" and mimeType = "application/x-x509-ca-cert" - or - ext = ".pfr" and mimeType = "application/font-tdpfr" - or - ext = ".pgm" and mimeType = "image/x-portable-graymap" - or - ext = ".pgn" and mimeType = "application/x-chess-pgn" - or - ext = ".pgp" and mimeType = "application/pgp-encrypted" - or - ext = ".pic" and mimeType = "image/x-pict" - or - ext = ".pict" and mimeType = "image/pict" - or - ext = ".pkg" and mimeType = "application/octet-stream" - or - ext = ".pki" and mimeType = "application/pkixcmp" - or - ext = ".pkipath" and mimeType = "application/pkix-pkipath" - or - ext = ".pl" and mimeType = "text/x-script.perl" - or - ext = ".plb" and mimeType = "application/vnd.3gpp.pic-bw-large" - or - ext = ".plc" and mimeType = "application/vnd.mobius.plc" - or - ext = ".plf" and mimeType = "application/vnd.pocketlearn" - or - ext = ".pls" and mimeType = "application/pls+xml" - or - ext = ".pm" and mimeType = "text/x-script.perl-module" - or - ext = ".pml" and mimeType = "application/vnd.ctc-posml" - or - ext = ".png" and mimeType = "image/png" - or - ext = ".pnm" and mimeType = "image/x-portable-anymap" - or - ext = ".pntg" and mimeType = "image/x-macpaint" - or - ext = ".portpkg" and mimeType = "application/vnd.macports.portpkg" - or - ext = ".pot" and mimeType = "application/vnd.ms-powerpoint" - or - ext = ".potm" and mimeType = "application/vnd.ms-powerpoint.template.macroEnabled.12" - or - ext = ".potx" and - mimeType = "application/vnd.openxmlformats-officedocument.presentationml.template" - or - ext = ".ppa" and mimeType = "application/vnd.ms-powerpoint" - or - ext = ".ppam" and mimeType = "application/vnd.ms-powerpoint.addin.macroEnabled.12" - or - ext = ".ppd" and mimeType = "application/vnd.cups-ppd" - or - ext = ".ppm" and mimeType = "image/x-portable-pixmap" - or - ext = ".pps" and mimeType = "application/vnd.ms-powerpoint" - or - ext = ".ppsm" and mimeType = "application/vnd.ms-powerpoint.slideshow.macroEnabled.12" - or - ext = ".ppsx" and - mimeType = "application/vnd.openxmlformats-officedocument.presentationml.slideshow" - or - ext = ".ppt" and mimeType = "application/vnd.ms-powerpoint" - or - ext = ".pptm" and mimeType = "application/vnd.ms-powerpoint.presentation.macroEnabled.12" - or - ext = ".pptx" and - mimeType = "application/vnd.openxmlformats-officedocument.presentationml.presentation" - or - ext = ".prc" and mimeType = "application/vnd.palm" - or - ext = ".pre" and mimeType = "application/vnd.lotus-freelance" - or - ext = ".prf" and mimeType = "application/pics-rules" - or - ext = ".ps" and mimeType = "application/postscript" - or - ext = ".psb" and mimeType = "application/vnd.3gpp.pic-bw-small" - or - ext = ".psd" and mimeType = "image/vnd.adobe.photoshop" - or - ext = ".ptid" and mimeType = "application/vnd.pvi.ptid1" - or - ext = ".pub" and mimeType = "application/x-mspublisher" - or - ext = ".pvb" and mimeType = "application/vnd.3gpp.pic-bw-var" - or - ext = ".pwn" and mimeType = "application/vnd.3m.post-it-notes" - or - ext = ".py" and mimeType = "text/x-script.python" - or - ext = ".pya" and mimeType = "audio/vnd.ms-playready.media.pya" - or - ext = ".pyv" and mimeType = "video/vnd.ms-playready.media.pyv" - or - ext = ".qam" and mimeType = "application/vnd.epson.quickanime" - or - ext = ".qbo" and mimeType = "application/vnd.intu.qbo" - or - ext = ".qfx" and mimeType = "application/vnd.intu.qfx" - or - ext = ".qps" and mimeType = "application/vnd.publishare-delta-tree" - or - ext = ".qt" and mimeType = "video/quicktime" - or - ext = ".qtif" and mimeType = "image/x-quicktime" - or - ext = ".qxd" and mimeType = "application/vnd.quark.quarkxpress" - or - ext = ".ra" and mimeType = "audio/x-pn-realaudio" - or - ext = ".rake" and mimeType = "text/x-script.ruby" - or - ext = ".ram" and mimeType = "audio/x-pn-realaudio" - or - ext = ".rar" and mimeType = "application/x-rar-compressed" - or - ext = ".ras" and mimeType = "image/x-cmu-raster" - or - ext = ".rb" and mimeType = "text/x-script.ruby" - or - ext = ".rcprofile" and mimeType = "application/vnd.ipunplugged.rcprofile" - or - ext = ".rdf" and mimeType = "application/rdf+xml" - or - ext = ".rdz" and mimeType = "application/vnd.data-vision.rdz" - or - ext = ".rep" and mimeType = "application/vnd.businessobjects" - or - ext = ".rgb" and mimeType = "image/x-rgb" - or - ext = ".rif" and mimeType = "application/reginfo+xml" - or - ext = ".rl" and mimeType = "application/resource-lists+xml" - or - ext = ".rlc" and mimeType = "image/vnd.fujixerox.edmics-rlc" - or - ext = ".rld" and mimeType = "application/resource-lists-diff+xml" - or - ext = ".rm" and mimeType = "application/vnd.rn-realmedia" - or - ext = ".rmp" and mimeType = "audio/x-pn-realaudio-plugin" - or - ext = ".rms" and mimeType = "application/vnd.jcp.javame.midlet-rms" - or - ext = ".rnc" and mimeType = "application/relax-ng-compact-syntax" - or - ext = ".roff" and mimeType = "text/troff" - or - ext = ".rpm" and mimeType = "application/x-redhat-package-manager" - or - ext = ".rpss" and mimeType = "application/vnd.nokia.radio-presets" - or - ext = ".rpst" and mimeType = "application/vnd.nokia.radio-preset" - or - ext = ".rq" and mimeType = "application/sparql-query" - or - ext = ".rs" and mimeType = "application/rls-services+xml" - or - ext = ".rsd" and mimeType = "application/rsd+xml" - or - ext = ".rss" and mimeType = "application/rss+xml" - or - ext = ".rtf" and mimeType = "application/rtf" - or - ext = ".rtx" and mimeType = "text/richtext" - or - ext = ".ru" and mimeType = "text/x-script.ruby" - or - ext = ".s" and mimeType = "text/x-asm" - or - ext = ".saf" and mimeType = "application/vnd.yamaha.smaf-audio" - or - ext = ".sbml" and mimeType = "application/sbml+xml" - or - ext = ".sc" and mimeType = "application/vnd.ibm.secure-container" - or - ext = ".scd" and mimeType = "application/x-msschedule" - or - ext = ".scm" and mimeType = "application/vnd.lotus-screencam" - or - ext = ".scq" and mimeType = "application/scvp-cv-request" - or - ext = ".scs" and mimeType = "application/scvp-cv-response" - or - ext = ".sdkm" and mimeType = "application/vnd.solent.sdkm+xml" - or - ext = ".sdp" and mimeType = "application/sdp" - or - ext = ".see" and mimeType = "application/vnd.seemail" - or - ext = ".sema" and mimeType = "application/vnd.sema" - or - ext = ".semd" and mimeType = "application/vnd.semd" - or - ext = ".semf" and mimeType = "application/vnd.semf" - or - ext = ".setpay" and mimeType = "application/set-payment-initiation" - or - ext = ".setreg" and mimeType = "application/set-registration-initiation" - or - ext = ".sfd" and mimeType = "application/vnd.hydrostatix.sof-data" - or - ext = ".sfs" and mimeType = "application/vnd.spotfire.sfs" - or - ext = ".sgm" and mimeType = "text/sgml" - or - ext = ".sgml" and mimeType = "text/sgml" - or - ext = ".sh" and mimeType = "application/x-sh" - or - ext = ".shar" and mimeType = "application/x-shar" - or - ext = ".shf" and mimeType = "application/shf+xml" - or - ext = ".sig" and mimeType = "application/pgp-signature" - or - ext = ".sit" and mimeType = "application/x-stuffit" - or - ext = ".sitx" and mimeType = "application/x-stuffitx" - or - ext = ".skp" and mimeType = "application/vnd.koan" - or - ext = ".slt" and mimeType = "application/vnd.epson.salt" - or - ext = ".smi" and mimeType = "application/smil+xml" - or - ext = ".snd" and mimeType = "audio/basic" - or - ext = ".so" and mimeType = "application/octet-stream" - or - ext = ".spf" and mimeType = "application/vnd.yamaha.smaf-phrase" - or - ext = ".spl" and mimeType = "application/x-futuresplash" - or - ext = ".spot" and mimeType = "text/vnd.in3d.spot" - or - ext = ".spp" and mimeType = "application/scvp-vp-response" - or - ext = ".spq" and mimeType = "application/scvp-vp-request" - or - ext = ".src" and mimeType = "application/x-wais-source" - or - ext = ".srt" and mimeType = "text/srt" - or - ext = ".srx" and mimeType = "application/sparql-results+xml" - or - ext = ".sse" and mimeType = "application/vnd.kodak-descriptor" - or - ext = ".ssf" and mimeType = "application/vnd.epson.ssf" - or - ext = ".ssml" and mimeType = "application/ssml+xml" - or - ext = ".stf" and mimeType = "application/vnd.wt.stf" - or - ext = ".stk" and mimeType = "application/hyperstudio" - or - ext = ".str" and mimeType = "application/vnd.pg.format" - or - ext = ".sus" and mimeType = "application/vnd.sus-calendar" - or - ext = ".sv4cpio" and mimeType = "application/x-sv4cpio" - or - ext = ".sv4crc" and mimeType = "application/x-sv4crc" - or - ext = ".svd" and mimeType = "application/vnd.svd" - or - ext = ".svg" and mimeType = "image/svg+xml" - or - ext = ".svgz" and mimeType = "image/svg+xml" - or - ext = ".swf" and mimeType = "application/x-shockwave-flash" - or - ext = ".swi" and mimeType = "application/vnd.arastra.swi" - or - ext = ".t" and mimeType = "text/troff" - or - ext = ".tao" and mimeType = "application/vnd.tao.intent-module-archive" - or - ext = ".tar" and mimeType = "application/x-tar" - or - ext = ".tbz" and mimeType = "application/x-bzip-compressed-tar" - or - ext = ".tcap" and mimeType = "application/vnd.3gpp2.tcap" - or - ext = ".tcl" and mimeType = "application/x-tcl" - or - ext = ".tex" and mimeType = "application/x-tex" - or - ext = ".texi" and mimeType = "application/x-texinfo" - or - ext = ".texinfo" and mimeType = "application/x-texinfo" - or - ext = ".text" and mimeType = "text/plain" - or - ext = ".tif" and mimeType = "image/tiff" - or - ext = ".tiff" and mimeType = "image/tiff" - or - ext = ".tmo" and mimeType = "application/vnd.tmobile-livetv" - or - ext = ".torrent" and mimeType = "application/x-bittorrent" - or - ext = ".tpl" and mimeType = "application/vnd.groove-tool-template" - or - ext = ".tpt" and mimeType = "application/vnd.trid.tpt" - or - ext = ".tr" and mimeType = "text/troff" - or - ext = ".tra" and mimeType = "application/vnd.trueapp" - or - ext = ".trm" and mimeType = "application/x-msterminal" - or - ext = ".ts" and mimeType = "video/mp2t" - or - ext = ".tsv" and mimeType = "text/tab-separated-values" - or - ext = ".ttf" and mimeType = "application/octet-stream" - or - ext = ".twd" and mimeType = "application/vnd.simtech-mindmapper" - or - ext = ".txd" and mimeType = "application/vnd.genomatix.tuxedo" - or - ext = ".txf" and mimeType = "application/vnd.mobius.txf" - or - ext = ".txt" and mimeType = "text/plain" - or - ext = ".ufd" and mimeType = "application/vnd.ufdl" - or - ext = ".umj" and mimeType = "application/vnd.umajin" - or - ext = ".unityweb" and mimeType = "application/vnd.unity" - or - ext = ".uoml" and mimeType = "application/vnd.uoml+xml" - or - ext = ".uri" and mimeType = "text/uri-list" - or - ext = ".ustar" and mimeType = "application/x-ustar" - or - ext = ".utz" and mimeType = "application/vnd.uiq.theme" - or - ext = ".uu" and mimeType = "text/x-uuencode" - or - ext = ".vcd" and mimeType = "application/x-cdlink" - or - ext = ".vcf" and mimeType = "text/x-vcard" - or - ext = ".vcg" and mimeType = "application/vnd.groove-vcard" - or - ext = ".vcs" and mimeType = "text/x-vcalendar" - or - ext = ".vcx" and mimeType = "application/vnd.vcx" - or - ext = ".vis" and mimeType = "application/vnd.visionary" - or - ext = ".viv" and mimeType = "video/vnd.vivo" - or - ext = ".vrml" and mimeType = "model/vrml" - or - ext = ".vsd" and mimeType = "application/vnd.visio" - or - ext = ".vsf" and mimeType = "application/vnd.vsf" - or - ext = ".vtt" and mimeType = "text/vtt" - or - ext = ".vtu" and mimeType = "model/vnd.vtu" - or - ext = ".vxml" and mimeType = "application/voicexml+xml" - or - ext = ".war" and mimeType = "application/java-archive" - or - ext = ".wasm" and mimeType = "application/wasm" - or - ext = ".wav" and mimeType = "audio/x-wav" - or - ext = ".wax" and mimeType = "audio/x-ms-wax" - or - ext = ".wbmp" and mimeType = "image/vnd.wap.wbmp" - or - ext = ".wbs" and mimeType = "application/vnd.criticaltools.wbs+xml" - or - ext = ".wbxml" and mimeType = "application/vnd.wap.wbxml" - or - ext = ".webm" and mimeType = "video/webm" - or - ext = ".webp" and mimeType = "image/webp" - or - ext = ".wm" and mimeType = "video/x-ms-wm" - or - ext = ".wma" and mimeType = "audio/x-ms-wma" - or - ext = ".wmd" and mimeType = "application/x-ms-wmd" - or - ext = ".wmf" and mimeType = "application/x-msmetafile" - or - ext = ".wml" and mimeType = "text/vnd.wap.wml" - or - ext = ".wmlc" and mimeType = "application/vnd.wap.wmlc" - or - ext = ".wmls" and mimeType = "text/vnd.wap.wmlscript" - or - ext = ".wmlsc" and mimeType = "application/vnd.wap.wmlscriptc" - or - ext = ".wmv" and mimeType = "video/x-ms-wmv" - or - ext = ".wmx" and mimeType = "video/x-ms-wmx" - or - ext = ".wmz" and mimeType = "application/x-ms-wmz" - or - ext = ".woff" and mimeType = "application/font-woff" - or - ext = ".woff2" and mimeType = "application/font-woff2" - or - ext = ".wpd" and mimeType = "application/vnd.wordperfect" - or - ext = ".wpl" and mimeType = "application/vnd.ms-wpl" - or - ext = ".wps" and mimeType = "application/vnd.ms-works" - or - ext = ".wqd" and mimeType = "application/vnd.wqd" - or - ext = ".wri" and mimeType = "application/x-mswrite" - or - ext = ".wrl" and mimeType = "model/vrml" - or - ext = ".wsdl" and mimeType = "application/wsdl+xml" - or - ext = ".wspolicy" and mimeType = "application/wspolicy+xml" - or - ext = ".wtb" and mimeType = "application/vnd.webturbo" - or - ext = ".wvx" and mimeType = "video/x-ms-wvx" - or - ext = ".x3d" and mimeType = "application/vnd.hzn-3d-crossword" - or - ext = ".xar" and mimeType = "application/vnd.xara" - or - ext = ".xbd" and mimeType = "application/vnd.fujixerox.docuworks.binder" - or - ext = ".xbm" and mimeType = "image/x-xbitmap" - or - ext = ".xdm" and mimeType = "application/vnd.syncml.dm+xml" - or - ext = ".xdp" and mimeType = "application/vnd.adobe.xdp+xml" - or - ext = ".xdw" and mimeType = "application/vnd.fujixerox.docuworks" - or - ext = ".xenc" and mimeType = "application/xenc+xml" - or - ext = ".xer" and mimeType = "application/patch-ops-error+xml" - or - ext = ".xfdf" and mimeType = "application/vnd.adobe.xfdf" - or - ext = ".xfdl" and mimeType = "application/vnd.xfdl" - or - ext = ".xhtml" and mimeType = "application/xhtml+xml" - or - ext = ".xif" and mimeType = "image/vnd.xiff" - or - ext = ".xla" and mimeType = "application/vnd.ms-excel" - or - ext = ".xlam" and mimeType = "application/vnd.ms-excel.addin.macroEnabled.12" - or - ext = ".xls" and mimeType = "application/vnd.ms-excel" - or - ext = ".xlsb" and mimeType = "application/vnd.ms-excel.sheet.binary.macroEnabled.12" - or - ext = ".xlsx" and mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" - or - ext = ".xlsm" and mimeType = "application/vnd.ms-excel.sheet.macroEnabled.12" - or - ext = ".xlt" and mimeType = "application/vnd.ms-excel" - or - ext = ".xltx" and - mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.template" - or - ext = ".xml" and mimeType = "application/xml" - or - ext = ".xo" and mimeType = "application/vnd.olpc-sugar" - or - ext = ".xop" and mimeType = "application/xop+xml" - or - ext = ".xpm" and mimeType = "image/x-xpixmap" - or - ext = ".xpr" and mimeType = "application/vnd.is-xpr" - or - ext = ".xps" and mimeType = "application/vnd.ms-xpsdocument" - or - ext = ".xpw" and mimeType = "application/vnd.intercon.formnet" - or - ext = ".xsl" and mimeType = "application/xml" - or - ext = ".xslt" and mimeType = "application/xslt+xml" - or - ext = ".xsm" and mimeType = "application/vnd.syncml+xml" - or - ext = ".xspf" and mimeType = "application/xspf+xml" - or - ext = ".xul" and mimeType = "application/vnd.mozilla.xul+xml" - or - ext = ".xwd" and mimeType = "image/x-xwindowdump" - or - ext = ".xyz" and mimeType = "chemical/x-xyz" - or - ext = ".yaml" and mimeType = "text/yaml" - or - ext = ".yml" and mimeType = "text/yaml" - or - ext = ".zaz" and mimeType = "application/vnd.zzazz.deck+xml" - or - ext = ".zip" and mimeType = "application/zip" - or - ext = ".zmm" and mimeType = "application/vnd.handheld-entertainment+xml" -} - -/** - * Provides modeling for the `Mime` component of the `Rack` library. - */ -module Mime { - /** A call to `Rack::Mime.mime_type`. This method maps file extensions to MIME types. */ - class MimetypeCall extends DataFlow::CallNode { - MimetypeCall() { - this = API::getTopLevelMember("Rack").getMember("Mime").getAMethodCall("mime_type") - } - - private string getExtension() { - result = this.getArgument(0).getConstantValue().getStringlikeValue() - } - - /** Gets the canonical MIME type string returned by this call. */ - string getMimetype() { mimetypeMatches(this.getExtension(), result) } - } -} diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index a2671c95cb7..c55afeb7801 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -6,8 +6,6 @@ rackApps | rack.rb:59:1:75:3 | Baz | rack.rb:60:12:60:14 | env | rackResponseContentTypes | rack.rb:8:5:8:38 | call to [] | rack.rb:7:34:7:45 | "text/plain" | -| rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:54 | call to mime_type | -mimetypeCalls -| rack.rb:19:28:19:54 | call to mime_type | application/x-gzip | +| rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:38 | "text/html" | redirectResponses | rack.rb:43:5:43:45 | call to [] | rack.rb:42:30:42:40 | "/foo.html" | diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index e1f1c506994..9b5d0629a9f 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -12,10 +12,6 @@ query predicate rackResponseContentTypes( contentType = resp.getMimetypeOrContentTypeArg() } -query predicate mimetypeCalls(Rack::Mime::MimetypeCall c, string mimetype) { - mimetype = c.getMimetype() -} - query predicate redirectResponses(Rack::Response::RedirectResponse resp, DataFlow::Node location) { location = resp.getRedirectLocation() } diff --git a/ruby/ql/test/library-tests/frameworks/rack/rack.rb b/ruby/ql/test/library-tests/frameworks/rack/rack.rb index c2e2598e5ec..9f743496ad2 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/rack.rb +++ b/ruby/ql/test/library-tests/frameworks/rack/rack.rb @@ -16,7 +16,7 @@ class Proxy def call(the_env) status, headers, body = @app.call(the_env) - headers.content_type = Rack::Mime.mime_type(".gz") + headers.content_type = "text/html" [status, headers, body] end end From 8ef8a0d2f63bd9b4e66fa95a1500b5272bf0e4d6 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Tue, 20 Jun 2023 14:59:13 +0100 Subject: [PATCH 697/739] qlformat --- ruby/ql/lib/codeql/ruby/frameworks/Rack.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll index 4d9342d8805..6963f37a81c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Rack.qll @@ -7,8 +7,8 @@ */ module Rack { import rack.internal.App -import rack.internal.Response::Public as Response + import rack.internal.Response::Public as Response -/** DEPRECATED: Alias for App::AppCandidate */ -deprecated class AppCandidate = App::AppCandidate; + /** DEPRECATED: Alias for App::AppCandidate */ + deprecated class AppCandidate = App::AppCandidate; } From 36cb60c746ec7aac4f5d9bd173658710bee04044 Mon Sep 17 00:00:00 2001 From: Adrien Pessu <7055334+adrienpessu@users.noreply.github.com> Date: Tue, 20 Jun 2023 17:22:56 +0000 Subject: [PATCH 698/739] Add fixed proposition for NodeJS --- .../CWE-798/HardcodedCredentials.qhelp | 4 ++++ .../HardcodedCredentialsHttpRequest.js | 4 ++-- .../HardcodedCredentialsHttpRequestFixed.js | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequestFixed.js diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp index 9f6fb3ddfa0..ee5adb1cb00 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp @@ -33,6 +33,10 @@ <code>username</code> and <code>password</code>, which can be set externally without hard-coding credentials in the source code. </p> + + For example, in a NodeJS environment : + <sample src="examples/HardcodedCredentialsHttpRequestFixed.js"/> + </example> <example> diff --git a/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js index 5890475085d..2732e2e1851 100644 --- a/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js +++ b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js @@ -11,8 +11,8 @@ headers.append('Authorization', 'Basic' + base64.encode(username + ":" + passwor fetch(url, {method:'GET', headers: headers, - //credentials: 'user:passwd' + credentials: `${user}:${passwd}` }) .then(response => response.json()) .then(json => console.log(json)); -//.done(); +.done(); diff --git a/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequestFixed.js b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequestFixed.js new file mode 100644 index 00000000000..5886e14d580 --- /dev/null +++ b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequestFixed.js @@ -0,0 +1,18 @@ +let base64 = require('base-64'); + +let url = 'http://example.org/auth'; +let username = process.env.USERNAME; +let password = process.env.PASSWORD; + +let headers = new Headers(); + +//headers.append('Content-Type', 'text/json'); +headers.append('Authorization', 'Basic' + base64.encode(username + ":" + password)); + +fetch(url, {method:'GET', + headers: headers, + credentials: `${user}:${passwd}` + }) +.then(response => response.json()) +.then(json => console.log(json)); +.done(); From 2a2f6de78c2b8cf2faefb02e3f4361fc6654f10f Mon Sep 17 00:00:00 2001 From: Adrien Pessu <7055334+adrienpessu@users.noreply.github.com> Date: Tue, 20 Jun 2023 17:27:37 +0000 Subject: [PATCH 699/739] fixed text not in a tag --- .../ql/src/Security/CWE-798/HardcodedCredentials.qhelp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp index ee5adb1cb00..60c37eed8c0 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp @@ -34,7 +34,10 @@ credentials in the source code. </p> - For example, in a NodeJS environment : + <p> + For example, in a NodeJS environment : + </p> + <sample src="examples/HardcodedCredentialsHttpRequestFixed.js"/> </example> From 59147ad6742172235f2a66ac5cc7ae20e0c1dc17 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 20 Jun 2023 15:27:39 +0200 Subject: [PATCH 700/739] QL: Add more tests for `MissingOverride.ql` --- .../MissingOverride/MissingOverride.expected | 3 +++ .../queries/style/MissingOverride/Test.qll | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected index 2ef0dd4b1ad..915a92c85f5 100644 --- a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected +++ b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected @@ -1 +1,4 @@ | Test.qll:12:13:12:16 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test | +| Test.qll:18:13:18:16 | ClassPredicate test | Wrong2.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test | +| Test.qll:24:13:24:16 | ClassPredicate test | Correct2.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test | +| Test.qll:36:13:36:16 | ClassPredicate test | Correct4.test overrides $@ but does not have an override annotation. | Test.qll:32:13:32:16 | ClassPredicate test | Super2.test | diff --git a/ql/ql/test/queries/style/MissingOverride/Test.qll b/ql/ql/test/queries/style/MissingOverride/Test.qll index e7f6a2c6b87..82d5199bf9e 100644 --- a/ql/ql/test/queries/style/MissingOverride/Test.qll +++ b/ql/ql/test/queries/style/MissingOverride/Test.qll @@ -11,3 +11,27 @@ class Correct extends Super { class Wrong extends Super { predicate test(int i) { i = 2 } } + +class Mid extends Super { } + +class Wrong2 extends Mid { + predicate test(int i) { i = 2 } +} + +final class SuperFinal = Super; + +class Correct2 extends SuperFinal { + predicate test(int i) { i = 4 } +} + +class Correct3 extends AstNode instanceof SuperFinal { + predicate test(int i) { i = 4 } +} + +final class Super2 extends AstNode { + predicate test(int i) { i = [1 .. 5] } +} + +class Correct4 extends Super2 { + predicate test(int i) { i = 3 } +} From d1184f0b3cb8d4ff262c71410b9ff396a008680f Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 20 Jun 2023 16:18:02 +0200 Subject: [PATCH 701/739] C#: Base the AlertSupression test on stubs. --- csharp/ql/test/query-tests/AlertSuppression/options | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 csharp/ql/test/query-tests/AlertSuppression/options diff --git a/csharp/ql/test/query-tests/AlertSuppression/options b/csharp/ql/test/query-tests/AlertSuppression/options new file mode 100644 index 00000000000..77b22963f5c --- /dev/null +++ b/csharp/ql/test/query-tests/AlertSuppression/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From ada49dbb2ce4a843f300d5245c6bd1832ccadff1 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 21 Jun 2023 08:46:33 +0200 Subject: [PATCH 702/739] C#: Specific language version not needed in options file for API Abuse/NoDisposeCallOnLocalIDisposable. --- .../API Abuse/NoDisposeCallOnLocalIDisposable/options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/options b/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/options index 08e01d88cc1..b8a701342a7 100644 --- a/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/options +++ b/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/options @@ -1 +1 @@ -semmle-extractor-options: --cil /langversion:8.0 /r:System.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Private.Xml.dll /r:System.ComponentModel.Primitives.dll /r:System.IO.Compression.dll /r:System.Runtime.Extensions.dll +semmle-extractor-options: --cil /r:System.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Private.Xml.dll /r:System.ComponentModel.Primitives.dll /r:System.IO.Compression.dll /r:System.Runtime.Extensions.dll From 4546d8f0bff97d28bdd6666aaacb9b1e38404f8f Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 21 Jun 2023 09:10:08 +0200 Subject: [PATCH 703/739] C#: Base API Abuse/UncheckedReturnValue test case on stubs, clean up test and update expected output. --- .../UncheckedReturnValue.cs | 28 ++----------------- .../UncheckedReturnValue.expected | 12 ++++---- .../API Abuse/UncheckedReturnValue/options | 2 ++ 3 files changed, 10 insertions(+), 32 deletions(-) create mode 100644 csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/options diff --git a/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/UncheckedReturnValue.cs b/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/UncheckedReturnValue.cs index f4a4944f4fb..cf290a84bcb 100644 --- a/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/UncheckedReturnValue.cs +++ b/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/UncheckedReturnValue.cs @@ -1,11 +1,6 @@ using System; -class HashSet<T> -{ - public bool Add(T t) - { - return true; - } -} +using System.Text; +using System.Collections.Generic; class C1 { @@ -30,11 +25,6 @@ class C1 } } -class StringBuilder -{ - public StringBuilder Append(string s) { return this; } -} - class C2 { static void Main(string[] args) @@ -59,20 +49,6 @@ class C2 } } -namespace System.IO -{ - public abstract class Stream - { - public abstract int Read(byte[] buffer, int offset, int count); - public virtual int ReadByte() { return 0; } - } - - public class MemoryStream : Stream - { - public override int Read(byte[] buffer, int offset, int count) { return 0; } - } -} - class C3 { static void Main(string[] args) diff --git a/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/UncheckedReturnValue.expected b/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/UncheckedReturnValue.expected index 371205cbc6b..e463ee956eb 100644 --- a/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/UncheckedReturnValue.expected +++ b/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/UncheckedReturnValue.expected @@ -1,8 +1,8 @@ -| UncheckedReturnValue.cs:29:9:29:31 | call to method Add | Result of call to 'Add' is ignored, but 90% of calls to this method have their result used. | -| UncheckedReturnValue.cs:91:9:91:26 | call to method Read | Result of call to 'Read' is ignored, but should always be checked. | -| UncheckedReturnValue.cs:92:9:92:20 | call to method ReadByte | Result of call to 'ReadByte' is ignored, but should always be checked. | -| UncheckedReturnValue.cs:109:9:109:17 | call to method M1<Int32> | Result of call to 'M1<Int32>' is ignored, but 90% of calls to this method have their result used. | -| UncheckedReturnValue.cs:130:9:130:21 | call to method M2<Decimal> | Result of call to 'M2<Decimal>' is ignored, but 90% of calls to this method have their result used. | -| UncheckedReturnValue.cs:142:9:142:20 | call to method M3<C6> | Result of call to 'M3<C6>' is ignored, but 90% of calls to this method have their result used. | +| UncheckedReturnValue.cs:24:9:24:31 | call to method Add | Result of call to 'Add' is ignored, but 90% of calls to this method have their result used. | +| UncheckedReturnValue.cs:67:9:67:26 | call to method Read | Result of call to 'Read' is ignored, but should always be checked. | +| UncheckedReturnValue.cs:68:9:68:20 | call to method ReadByte | Result of call to 'ReadByte' is ignored, but should always be checked. | +| UncheckedReturnValue.cs:85:9:85:17 | call to method M1<Int32> | Result of call to 'M1<Int32>' is ignored, but 90% of calls to this method have their result used. | +| UncheckedReturnValue.cs:106:9:106:21 | call to method M2<Decimal> | Result of call to 'M2<Decimal>' is ignored, but 90% of calls to this method have their result used. | +| UncheckedReturnValue.cs:118:9:118:20 | call to method M3<C6> | Result of call to 'M3<C6>' is ignored, but 90% of calls to this method have their result used. | | UncheckedReturnValueBad.cs:29:9:29:20 | call to method DoPrint | Result of call to 'DoPrint' is ignored, but 90% of calls to this method have their result used. | | UncheckedReturnValueBad.cs:36:13:36:40 | call to method Read | Result of call to 'Read' is ignored, but should always be checked. | diff --git a/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/options b/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/UncheckedReturnValue/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From 0e263fb7444fb58de147ed724692ea7c870d7dff Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 21 Jun 2023 09:28:27 +0200 Subject: [PATCH 704/739] C#: Base API Abuse/DisposeNotCalledOnException test case on stubs. Since the stubs requires C# 11 the language version has been removed from the options (also it doesn't affect the output). --- .../query-tests/API Abuse/DisposeNotCalledOnException/options | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/query-tests/API Abuse/DisposeNotCalledOnException/options b/csharp/ql/test/query-tests/API Abuse/DisposeNotCalledOnException/options index a0b23f3ee8b..7faed1b92ed 100644 --- a/csharp/ql/test/query-tests/API Abuse/DisposeNotCalledOnException/options +++ b/csharp/ql/test/query-tests/API Abuse/DisposeNotCalledOnException/options @@ -1,2 +1,2 @@ -semmle-extractor-options: /r:System.ComponentModel.Primitives.dll /r:${testdir}/../../../resources/assemblies/System.Data.dll /r:System.Data.Common.dll -semmle-extractor-options: /langversion:8.0 +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj From 52323d39906e765eb6bacb69fbacd7725052e33f Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 21 Jun 2023 09:39:18 +0200 Subject: [PATCH 705/739] C#: Base API Abuse/IncorrectCompareToSignature test case on stubs and update expected test output. --- .../IncorrectCompareToSignature.cs | 13 +------------ .../IncorrectCompareToSignature.expected | 2 +- .../API Abuse/IncorrectCompareToSignature/options | 2 ++ 3 files changed, 4 insertions(+), 13 deletions(-) create mode 100644 csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/options diff --git a/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/IncorrectCompareToSignature.cs b/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/IncorrectCompareToSignature.cs index 0ecabd07016..5b5780ed977 100644 --- a/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/IncorrectCompareToSignature.cs +++ b/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/IncorrectCompareToSignature.cs @@ -1,15 +1,4 @@ -namespace System -{ - public interface IComparable - { - int CompareTo(object obj); // GOOD: the very definition of IComparable.CompareTo() - } - - public interface IComparable<in T> - { - int CompareTo(T other); // GOOD: the very definition of IComparable<T>.CompareTo() - } -} +using System; class C1<T> { diff --git a/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/IncorrectCompareToSignature.expected b/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/IncorrectCompareToSignature.expected index 860009bd3e2..419629319a5 100644 --- a/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/IncorrectCompareToSignature.expected +++ b/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/IncorrectCompareToSignature.expected @@ -1,2 +1,2 @@ -| IncorrectCompareToSignature.cs:16:16:16:24 | CompareTo | The parameter of this 'CompareTo' method is of type $@, but $@ does not implement 'IComparable<$@>'. | IncorrectCompareToSignature.cs:14:10:14:10 | T | T | IncorrectCompareToSignature.cs:14:7:14:11 | C1<> | C1<> | IncorrectCompareToSignature.cs:14:10:14:10 | T | T | +| IncorrectCompareToSignature.cs:5:16:5:24 | CompareTo | The parameter of this 'CompareTo' method is of type $@, but $@ does not implement 'IComparable<$@>'. | IncorrectCompareToSignature.cs:3:10:3:10 | T | T | IncorrectCompareToSignature.cs:3:7:3:11 | C1<> | C1<> | IncorrectCompareToSignature.cs:3:10:3:10 | T | T | | IncorrectCompareToSignatureBad.cs:5:16:5:24 | CompareTo | The parameter of this 'CompareTo' method is of type $@, but $@ does not implement 'IComparable<$@>'. | IncorrectCompareToSignatureBad.cs:3:7:3:9 | Bad | Bad | IncorrectCompareToSignatureBad.cs:3:7:3:9 | Bad | Bad | IncorrectCompareToSignatureBad.cs:3:7:3:9 | Bad | Bad | diff --git a/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/options b/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/IncorrectCompareToSignature/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From 82bf27c7b29361e6ab0947fe663d0c0543237272 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 21 Jun 2023 09:52:35 +0200 Subject: [PATCH 706/739] C#: Base the remaining API Abuse query test cases on stubs. --- csharp/ql/test/query-tests/API Abuse/CallToGCCollect/options | 2 ++ .../ql/test/query-tests/API Abuse/CallToObsoleteMethod/options | 2 ++ .../query-tests/API Abuse/ClassDoesNotImplementEquals/options | 2 ++ .../query-tests/API Abuse/ClassImplementsICloneable/options | 2 ++ csharp/ql/test/query-tests/API Abuse/FormatInvalid/options | 3 ++- .../API Abuse/InconsistentEqualsGetHashCode/options | 2 ++ .../query-tests/API Abuse/IncorrectEqualsSignature/options | 2 ++ .../ql/test/query-tests/API Abuse/MissingDisposeCall/options | 3 ++- .../ql/test/query-tests/API Abuse/MissingDisposeMethod/options | 3 ++- .../ql/test/query-tests/API Abuse/NonOverridingMethod/options | 2 ++ .../ql/test/query-tests/API Abuse/NullArgumentToEquals/options | 2 ++ 11 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 csharp/ql/test/query-tests/API Abuse/CallToGCCollect/options create mode 100644 csharp/ql/test/query-tests/API Abuse/CallToObsoleteMethod/options create mode 100644 csharp/ql/test/query-tests/API Abuse/ClassDoesNotImplementEquals/options create mode 100644 csharp/ql/test/query-tests/API Abuse/ClassImplementsICloneable/options create mode 100644 csharp/ql/test/query-tests/API Abuse/InconsistentEqualsGetHashCode/options create mode 100644 csharp/ql/test/query-tests/API Abuse/IncorrectEqualsSignature/options create mode 100644 csharp/ql/test/query-tests/API Abuse/NonOverridingMethod/options create mode 100644 csharp/ql/test/query-tests/API Abuse/NullArgumentToEquals/options diff --git a/csharp/ql/test/query-tests/API Abuse/CallToGCCollect/options b/csharp/ql/test/query-tests/API Abuse/CallToGCCollect/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/CallToGCCollect/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/CallToObsoleteMethod/options b/csharp/ql/test/query-tests/API Abuse/CallToObsoleteMethod/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/CallToObsoleteMethod/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/ClassDoesNotImplementEquals/options b/csharp/ql/test/query-tests/API Abuse/ClassDoesNotImplementEquals/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/ClassDoesNotImplementEquals/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/ClassImplementsICloneable/options b/csharp/ql/test/query-tests/API Abuse/ClassImplementsICloneable/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/ClassImplementsICloneable/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/options b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/options index ea0639b2d0a..75c39b4541b 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/options +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/options @@ -1 +1,2 @@ -semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.Diagnostics.TraceSource.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/InconsistentEqualsGetHashCode/options b/csharp/ql/test/query-tests/API Abuse/InconsistentEqualsGetHashCode/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/InconsistentEqualsGetHashCode/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/IncorrectEqualsSignature/options b/csharp/ql/test/query-tests/API Abuse/IncorrectEqualsSignature/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/IncorrectEqualsSignature/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/MissingDisposeCall/options b/csharp/ql/test/query-tests/API Abuse/MissingDisposeCall/options index 2d3e53846e4..75c39b4541b 100644 --- a/csharp/ql/test/query-tests/API Abuse/MissingDisposeCall/options +++ b/csharp/ql/test/query-tests/API Abuse/MissingDisposeCall/options @@ -1 +1,2 @@ -semmle-extractor-options: /r:System.ComponentModel.Primitives.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/MissingDisposeMethod/options b/csharp/ql/test/query-tests/API Abuse/MissingDisposeMethod/options index 2d3e53846e4..75c39b4541b 100644 --- a/csharp/ql/test/query-tests/API Abuse/MissingDisposeMethod/options +++ b/csharp/ql/test/query-tests/API Abuse/MissingDisposeMethod/options @@ -1 +1,2 @@ -semmle-extractor-options: /r:System.ComponentModel.Primitives.dll +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/NonOverridingMethod/options b/csharp/ql/test/query-tests/API Abuse/NonOverridingMethod/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/NonOverridingMethod/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj diff --git a/csharp/ql/test/query-tests/API Abuse/NullArgumentToEquals/options b/csharp/ql/test/query-tests/API Abuse/NullArgumentToEquals/options new file mode 100644 index 00000000000..75c39b4541b --- /dev/null +++ b/csharp/ql/test/query-tests/API Abuse/NullArgumentToEquals/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj From e85987bfc5f4f8b975634dc4ce0360a22e3c3d76 Mon Sep 17 00:00:00 2001 From: Adrien Pessu <7055334+adrienpessu@users.noreply.github.com> Date: Wed, 21 Jun 2023 07:59:24 +0000 Subject: [PATCH 707/739] remove useless phrase --- javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp index 60c37eed8c0..d3689155c00 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp @@ -34,10 +34,6 @@ credentials in the source code. </p> - <p> - For example, in a NodeJS environment : - </p> - <sample src="examples/HardcodedCredentialsHttpRequestFixed.js"/> </example> From 7dfb404fd758d3633d7af1479aa1c020b1c26904 Mon Sep 17 00:00:00 2001 From: Adrien Pessu <7055334+adrienpessu@users.noreply.github.com> Date: Wed, 21 Jun 2023 08:11:39 +0000 Subject: [PATCH 708/739] clean examples --- .../examples/HardcodedCredentialsHttpRequest.js | 10 +++++----- .../examples/HardcodedCredentialsHttpRequestFixed.js | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js index 2732e2e1851..097e9f7b1a6 100644 --- a/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js +++ b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequest.js @@ -6,13 +6,13 @@ let password = 'passwd'; let headers = new Headers(); -//headers.append('Content-Type', 'text/json'); +headers.append('Content-Type', 'text/json'); headers.append('Authorization', 'Basic' + base64.encode(username + ":" + password)); -fetch(url, {method:'GET', - headers: headers, - credentials: `${user}:${passwd}` +fetch(url, { + method:'GET', + headers: headers }) .then(response => response.json()) -.then(json => console.log(json)); +.then(json => console.log(json)) .done(); diff --git a/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequestFixed.js b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequestFixed.js index 5886e14d580..1747d460dde 100644 --- a/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequestFixed.js +++ b/javascript/ql/src/Security/CWE-798/examples/HardcodedCredentialsHttpRequestFixed.js @@ -6,13 +6,13 @@ let password = process.env.PASSWORD; let headers = new Headers(); -//headers.append('Content-Type', 'text/json'); +headers.append('Content-Type', 'text/json'); headers.append('Authorization', 'Basic' + base64.encode(username + ":" + password)); -fetch(url, {method:'GET', - headers: headers, - credentials: `${user}:${passwd}` - }) +fetch(url, { + method:'GET', + headers: headers + }) .then(response => response.json()) -.then(json => console.log(json)); +.then(json => console.log(json)) .done(); From 34e50de76dfaaafeb74100c39e3ca8a136e09b8d Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 21 Jun 2023 10:39:52 +0200 Subject: [PATCH 709/739] C#: Only use the dll's that are strictly needed in the API Abuse/NoDisposeCallOnLocalIDisposable test case. --- .../API Abuse/NoDisposeCallOnLocalIDisposable/options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/options b/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/options index b8a701342a7..a02c94f4258 100644 --- a/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/options +++ b/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/options @@ -1 +1 @@ -semmle-extractor-options: --cil /r:System.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Private.Xml.dll /r:System.ComponentModel.Primitives.dll /r:System.IO.Compression.dll /r:System.Runtime.Extensions.dll +semmle-extractor-options: --cil /r:System.Private.Xml.dll /r:System.IO.Compression.dll From 0edd80001b7d8c3b5bdd054b295792398b2ea9fe Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Wed, 21 Jun 2023 09:32:29 +0200 Subject: [PATCH 710/739] QL: Add tests for `AbstractClassImport.ql` --- .../AbstractClassImport.expected | 2 ++ .../AbstractClassImport.qlref | 1 + .../AbstractClassImportTest1.qll | 4 ++++ .../AbstractClassImportTest2.qll | 8 ++++++++ .../AbstractClassImportTest3.qll | 18 ++++++++++++++++++ .../AbstractClassImportTestQuery.expected | 0 .../AbstractClassImportTestQuery.ql | 6 ++++++ 7 files changed, 39 insertions(+) create mode 100644 ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.expected create mode 100644 ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.qlref create mode 100644 ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest1.qll create mode 100644 ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest2.qll create mode 100644 ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest3.qll create mode 100644 ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTestQuery.expected create mode 100644 ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTestQuery.ql diff --git a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.expected b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.expected new file mode 100644 index 00000000000..d2dc19e467d --- /dev/null +++ b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.expected @@ -0,0 +1,2 @@ +| AbstractClassImportTest1.qll:4:16:4:19 | Class Base | This abstract class imports its subclass $@ but doesn't import 4 other subclasses, such as $@. | AbstractClassImportTest2.qll:4:7:4:11 | Class Sub21 | Sub21 | AbstractClassImportTest3.qll:12:7:12:11 | Class Sub33 | Sub33 | +| AbstractClassImportTest1.qll:4:16:4:19 | Class Base | This abstract class imports its subclass $@ but doesn't import 4 other subclasses, such as $@. | AbstractClassImportTest2.qll:8:7:8:11 | Class Sub22 | Sub22 | AbstractClassImportTest3.qll:12:7:12:11 | Class Sub33 | Sub33 | diff --git a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.qlref b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.qlref new file mode 100644 index 00000000000..4d7907c36ef --- /dev/null +++ b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.qlref @@ -0,0 +1 @@ +queries/performance/AbstractClassImport.ql \ No newline at end of file diff --git a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest1.qll b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest1.qll new file mode 100644 index 00000000000..ce7f7c4ea68 --- /dev/null +++ b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest1.qll @@ -0,0 +1,4 @@ +import ql +import AbstractClassImportTest2 + +abstract class Base extends AstNode { } diff --git a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest2.qll b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest2.qll new file mode 100644 index 00000000000..df29a5c18de --- /dev/null +++ b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest2.qll @@ -0,0 +1,8 @@ +import ql +import AbstractClassImportTest1 + +class Sub21 extends Base { + Sub21() { this instanceof TopLevel } +} + +class Sub22 extends Base instanceof Comment { } diff --git a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest3.qll b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest3.qll new file mode 100644 index 00000000000..d2917d9aeb4 --- /dev/null +++ b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTest3.qll @@ -0,0 +1,18 @@ +import ql +import AbstractClassImportTest1 + +class Sub31 extends Base { + Sub31() { this instanceof Comment } +} + +class Sub32 extends Base instanceof Comment { } + +final class BaseFinal = Base; + +class Sub33 extends BaseFinal instanceof Comment { } + +abstract class Sub34 extends Base { } + +final class Sub34Final = Sub34; + +class Sub35 extends Sub34Final instanceof Comment { } diff --git a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTestQuery.expected b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTestQuery.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTestQuery.ql b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTestQuery.ql new file mode 100644 index 00000000000..f15c7fafb43 --- /dev/null +++ b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImportTestQuery.ql @@ -0,0 +1,6 @@ +import ql +import AbstractClassImportTest3 + +from AstNode n +where none() +select n From e6e966bd229df063892670eb3114e231f3655d3b Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 20 Jun 2023 15:44:34 +0200 Subject: [PATCH 711/739] QL: Model `final extends` --- ql/ql/src/codeql_ql/ast/Ast.qll | 5 ++ ql/ql/src/codeql_ql/ast/internal/Type.qll | 59 +++++++++++++++---- .../performance/AbstractClassImport.ql | 5 +- .../AbstractClassImport.expected | 6 +- .../MissingOverride/MissingOverride.expected | 2 - 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index 616438da756..19cf38c3f1c 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -611,6 +611,8 @@ class ClassPredicate extends TClassPredicate, Predicate { predicate overrides(ClassPredicate other) { predOverrides(this, other) } + predicate shadows(ClassPredicate other) { predShadows(this, other) } + override TypeExpr getReturnTypeExpr() { toQL(result) = pred.getReturnType() } override AstNode getAChild(string pred_name) { @@ -878,6 +880,9 @@ class Module extends TModule, ModuleDeclaration { class ModuleMember extends TModuleMember, AstNode { /** Holds if this member is declared as `private`. */ predicate isPrivate() { this.hasAnnotation("private") } + + /** Holds if this member is declared as `final`. */ + predicate isFinal() { this.hasAnnotation("final") } } /** A declaration. E.g. a class, type, predicate, newtype... */ diff --git a/ql/ql/src/codeql_ql/ast/internal/Type.qll b/ql/ql/src/codeql_ql/ast/internal/Type.qll index c1aaf84d8c2..2053c657904 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Type.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Type.qll @@ -21,7 +21,7 @@ private newtype TType = private predicate primTypeName(string s) { s = ["int", "float", "string", "boolean", "date"] } private predicate isActualClass(Class c) { - not exists(c.getAliasType()) and + (not exists(c.getAliasType()) or c.isFinal()) and not exists(c.getUnionMember()) } @@ -36,6 +36,10 @@ class Type extends TType { /** * Gets a supertype of this type. This follows the user-visible type hierarchy, * and doesn't include internal types like the characteristic and domain types of classes. + * + * For supertypes that are `final` aliases, this returns the alias itself, and for + * types that are `final` aliases, this returns the supertypes of the type that is + * being aliased. */ Type getASuperType() { none() } @@ -94,9 +98,23 @@ class ClassType extends Type, TClass { override Class getDeclaration() { result = decl } - override Type getASuperType() { result = decl.getASuperType().getResolvedType() } + override Type getASuperType() { + result = decl.getASuperType().getResolvedType() + or + exists(ClassType alias | + this.isFinalAlias(alias) and + result = alias.getASuperType() + ) + } - Type getAnInstanceofType() { result = decl.getAnInstanceofType().getResolvedType() } + Type getAnInstanceofType() { + result = decl.getAnInstanceofType().getResolvedType() + or + exists(ClassType alias | + this.isFinalAlias(alias) and + result = alias.getAnInstanceofType() + ) + } override Type getAnInternalSuperType() { result.(ClassCharType).getClassType() = this @@ -110,6 +128,12 @@ class ClassType extends Type, TClass { other.getDeclaringType().getASuperType+() = result.getDeclaringType() ) } + + /** Holds if this class is a `final` alias of `c`. */ + predicate isFinalAlias(ClassType c) { + decl.isFinal() and + decl.getAliasType().getResolvedType() = c + } } class FileType extends Type, TFile { @@ -136,23 +160,37 @@ private PredicateOrBuiltin declaredPred(Type ty, string name, int arity) { result.getDeclaringType() = ty and result.getName() = name and result.getArity() = arity + or + exists(ClassType alias | + ty.(ClassType).isFinalAlias(alias) and + result = declaredPred(alias, name, arity) + ) } pragma[nomagic] -private PredicateOrBuiltin classPredCandidate(Type ty, string name, int arity) { - result = declaredPred(ty, name, arity) +private PredicateOrBuiltin classPredCandidate(Type ty, string name, int arity, boolean isFinal) { + result = declaredPred(ty, name, arity) and + if ty.(ClassType).getDeclaration().isFinal() then isFinal = true else isFinal = false or not exists(declaredPred(ty, name, arity)) and - result = inherClassPredCandidate(ty, name, arity) + result = inherClassPredCandidate(ty, name, arity, isFinal) } -private PredicateOrBuiltin inherClassPredCandidate(Type ty, string name, int arity) { - result = classPredCandidate(ty.getAnInternalSuperType(), name, arity) and +private PredicateOrBuiltin classPredCandidate(Type ty, string name, int arity) { + result = classPredCandidate(ty, name, arity, _) +} + +private PredicateOrBuiltin inherClassPredCandidate(Type ty, string name, int arity, boolean isFinal) { + result = classPredCandidate(ty.getAnInternalSuperType(), name, arity, isFinal) and not result.isPrivate() } predicate predOverrides(ClassPredicate sub, ClassPredicate sup) { - sup = inherClassPredCandidate(sub.getDeclaringType(), sub.getName(), sub.getArity()) + sup = inherClassPredCandidate(sub.getDeclaringType(), sub.getName(), sub.getArity(), false) +} + +predicate predShadows(ClassPredicate sub, ClassPredicate sup) { + sup = inherClassPredCandidate(sub.getDeclaringType(), sub.getName(), sub.getArity(), true) } private VarDecl declaredField(ClassType ty, string name) { @@ -376,7 +414,8 @@ private predicate defines(FileOrModule m, string name, Type t, boolean public) { exists(Class ty | t = ty.getAliasType().getResolvedType() | getEnclosingModule(ty) = m and ty.getName() = name and - public = getPublicBool(ty) + public = getPublicBool(ty) and + not ty.isFinal() ) or exists(Import im | diff --git a/ql/ql/src/queries/performance/AbstractClassImport.ql b/ql/ql/src/queries/performance/AbstractClassImport.ql index abd00689909..24e05860f0a 100644 --- a/ql/ql/src/queries/performance/AbstractClassImport.ql +++ b/ql/ql/src/queries/performance/AbstractClassImport.ql @@ -38,14 +38,15 @@ Class getASubclassOfAbstract(Class ab) { /** Gets a non-abstract subclass of `ab` that contributes to the extent of `ab`. */ Class concreteExternalSubclass(Class ab) { - ab.isAbstract() and not result.isAbstract() and result = getASubclassOfAbstract+(ab) and // Heuristic: An abstract class with subclasses in the same file and no other // imported subclasses is likely intentional. result.getLocation().getFile() != ab.getLocation().getFile() and // Exclude subclasses in tests and libraries that are only used in tests. - liveNonTestFile(result.getLocation().getFile()) + liveNonTestFile(result.getLocation().getFile()) and + // exclude `final` aliases + not result.getType().isFinalAlias(_) } /** Holds if there is a bidirectional import between the abstract class `ab` and its subclass `sub` */ diff --git a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.expected b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.expected index d2dc19e467d..952a49efc65 100644 --- a/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.expected +++ b/ql/ql/test/queries/performance/AbstractClassImport/AbstractClassImport.expected @@ -1,2 +1,4 @@ -| AbstractClassImportTest1.qll:4:16:4:19 | Class Base | This abstract class imports its subclass $@ but doesn't import 4 other subclasses, such as $@. | AbstractClassImportTest2.qll:4:7:4:11 | Class Sub21 | Sub21 | AbstractClassImportTest3.qll:12:7:12:11 | Class Sub33 | Sub33 | -| AbstractClassImportTest1.qll:4:16:4:19 | Class Base | This abstract class imports its subclass $@ but doesn't import 4 other subclasses, such as $@. | AbstractClassImportTest2.qll:8:7:8:11 | Class Sub22 | Sub22 | AbstractClassImportTest3.qll:12:7:12:11 | Class Sub33 | Sub33 | +| AbstractClassImportTest1.qll:4:16:4:19 | Class Base | This abstract class doesn't import its subclass $@ but imports 2 other subclasses, such as $@. | AbstractClassImportTest3.qll:4:7:4:11 | Class Sub31 | Sub31 | AbstractClassImportTest2.qll:4:7:4:11 | Class Sub21 | Sub21 | +| AbstractClassImportTest1.qll:4:16:4:19 | Class Base | This abstract class doesn't import its subclass $@ but imports 2 other subclasses, such as $@. | AbstractClassImportTest3.qll:8:7:8:11 | Class Sub32 | Sub32 | AbstractClassImportTest2.qll:4:7:4:11 | Class Sub21 | Sub21 | +| AbstractClassImportTest1.qll:4:16:4:19 | Class Base | This abstract class imports its subclass $@ but doesn't import 2 other subclasses, such as $@. | AbstractClassImportTest2.qll:4:7:4:11 | Class Sub21 | Sub21 | AbstractClassImportTest3.qll:4:7:4:11 | Class Sub31 | Sub31 | +| AbstractClassImportTest1.qll:4:16:4:19 | Class Base | This abstract class imports its subclass $@ but doesn't import 2 other subclasses, such as $@. | AbstractClassImportTest2.qll:8:7:8:11 | Class Sub22 | Sub22 | AbstractClassImportTest3.qll:4:7:4:11 | Class Sub31 | Sub31 | diff --git a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected index 915a92c85f5..d64a6ed1544 100644 --- a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected +++ b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected @@ -1,4 +1,2 @@ | Test.qll:12:13:12:16 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test | | Test.qll:18:13:18:16 | ClassPredicate test | Wrong2.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test | -| Test.qll:24:13:24:16 | ClassPredicate test | Correct2.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test | -| Test.qll:36:13:36:16 | ClassPredicate test | Correct4.test overrides $@ but does not have an override annotation. | Test.qll:32:13:32:16 | ClassPredicate test | Super2.test | From 27ee4241e815f1e78e50f78d1135fd78d82c360f Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 21 Jun 2023 10:45:08 +0200 Subject: [PATCH 712/739] C#: Remove unused test assemblies. --- .../test/resources/assemblies/System.Data.dll | Bin 200192 -> 0 bytes .../System.Web.ApplicationServices.dll | Bin 13824 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 csharp/ql/test/resources/assemblies/System.Data.dll delete mode 100644 csharp/ql/test/resources/assemblies/System.Web.ApplicationServices.dll diff --git a/csharp/ql/test/resources/assemblies/System.Data.dll b/csharp/ql/test/resources/assemblies/System.Data.dll deleted file mode 100644 index 070caaa81f33de941a876f4e9eb1ca0b1dd614b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200192 zcmeF)2Yggj*C_nG&zy5e!ptO-GARQ{lTHXF6zQRg^d1ZldM}}q&<P2l*8mEFC=yTs zg+LTh&=91F0xC#REQlzGpa=?h*IH-I&QL7xead(5@4NW8=KS~C?d&;iCc&pww?)Dx zgwWyNKmHIR2VU_{1B!ngra{{I*qctV!~bZp9NF?{v5o@=jV?NJ)QAD2dJQYur`Pb| zBgPc%-LL4VvBQfF8eX(<n+`>Xjp*Ai+TjQ&$z8W?B1B7R6SuD#UwTLTLKH7rP{s&h z!puyov}sA$E(+TXaJC|dwl!<sSb+1VKhq!&<@m=Y8qC6~_`m#DCKkb;pG(+88{B|? zZ&B9>pFfE<VF#XqdWC$7|8}#e5Pm+D{J_n996hGrgfZZjI`0?mE6>|o4VolIj~YFy z4;0YcV2-q-e(>t^rvc19dQ`umBcLMARluC7FZ)CF;(VIXW*J;p_=9uPgdwK2g?&A) z34bch4_#sZr{(icw~A<GV9f){d0zuUlmG00W;yF0sG5dNpq`0=UTF(5@7RR5kjs7O zZ9zrea@FY+ICyX#fA*Tr^Zd)#hlj`??60@(Yxyv|drzIfENAl)cxyg#-@QqA^={@* zf=aMkXqv(M_GhoO;85=$y;`IBMjBKVcy|Q~ytBq4EAM^vDu2G-jJG*Y-FqxRgZvua z);_QK$@~ti^#69u@5sC5vqU~`kasWtWH!FzTOE13xjzH)?u54|tNQ)b?yuvUdw3fL z`sar;G{3)ZQhxB}A1Lvz4Zc1+1D~?{+F3R8+fwKGd~oaGjvwsc!Qmh5;ZcU=nUjB> zf#$OQ>AF2IEuWpG{kbpP2XD>%*GJ9ougV@8+S`?t@XFhTw-l|KdXx9Rsx)l;c_zQZ zhpOG*=uv|8^*Mi_11Pxv((cnKZ9?$AdUwG4>QmLHU)cQ3VO{a*)#~7Z=+ngmnSX^a z^drwY=#vI~AUrVCUu6Goy7%Yv7oG;r=l#{J;k{Y!9DSO2i+rkBZB)d}gFBtyN>%gS zc+?zJ9{Z#Ayg}Pm)@Kr`jyD5S@ZK%F-E$pp2R=2dM&3kzecFP0e|D>+^89AJ>wor8 z@lVSS<8uv+`e(1+vn79?Fa@X&kFwP6AH8~K?ehwoK7tPaZo=LLwi^00{|9aVu5a&7 zLa+aZ-n?(%Jbw0}*MCpf_fOQTe=z4idwad*w7T9S@b8w3@~}hy`~ZL%{^fyUy`3ul zgB==Bz&if!dsQ9$dpGhg2LIlE|Ha<^51rOO+^c^ydpHp2$o#WcHJ11C^j8HuqI&tC zcdB}a4eW+SRWH8T|MWHw`kx-=KidEQ9sBV2vxMVlK40qT^^uFlhl-W+9<5yHiIF0J zzsWdXKr533y`3#5goJA*eifr>q5!7Na_-O|NjFaD2Pfw3=#fMID~12TuK$&3J+kfp zO>_N!JK#NhAGs3$wZi||F#~7#ea{(x=l|Mn{MkVNv)%i%Uj9ER|EE*`i}%3$0RCsM z^wkTrzwg!BStxzv1INQlf%B}ch2kG~nPK=e`v3GlUx`0kZ*MuQ`@?rmF2Q%;{(l~R zmwZdSeg56+ePi-i&}IRDMd#b)166T0P&3O3N5ccv9$<0JUFHIQOZ4ytHO1l|F%Rva z$E$dJSzY{%yhm>Ue+BiIuU3!L^P>W!|GF6W*XrZp=#%l;e7N3UlyLX3$F+EG=oMN# zYFb?OS99_mi>gD{3EcI4uihcNuiia)@YU+jTk4}n%mRzN|9ETOSB<*KFM+vD<hjx7 zeRJWu|F$x3N8Z<ecmLic;@$Jot%tUw1Dp<97##iw`<=!6{m9q<(G-0a+&iW<N^#xY z(ZIp28q_I_{O8};TFvh7#47tgIl?Y^uLzHP_3l;vVP}<i+x^A9J*o<K1F6Knxdzfg zLOt(ySZbh$%AlYhcJ@Dgg&t{;|4ztXK$z$BN9=t5G}NxD4Q@<Ttit^6R3+HJQr~}k z){5Fj!}Ewcw9FnJo_UDLGk``r?wenJkC5t;p90-?%+Lh#1El}%=90h94{YW40$cf@ zT0SM#rnkT+3u8ZgOThi`ZSlx$Zx!g_&#w5s?e6O{AJ&pRSdsdMj{oMe4b7+~hx~1I zHGJfC4?3pu2b%vWtvOQfYNEUc(A8gF=<aW%TK|h1FsjdG9y)udz#8CD#rYHWxv>1r z!xr@O(AC8n^}l{S;ptnW|F^CV4?kL}5|{|R$G(r5RPax)Al?hZ{Z|s}{j&}{SpEOh z<>8^jGymxL4_y`hY{dK>&foH>n?J9=xg>bo{3ovf`IGtcbD!&2JM-^~k2;^B??)Bq z&+%V4&7tG}-=E-gK>42C|MbMZ|AfZ(gRZg*`3r7(g*T7-|LZ`tya%@T^^wQagGU{_ zfs1%NdcAKv)q}T|RggayRpG&A*3NjV|H+K3O1@RS<2?B4?Z`WfWfi^E|Ek)3llC1G zw^dJS<B@Z_?;U}v-iG(}t-AQ@4Vd$N-R1Z3=q>M9kL;EA!KY7}oll!bZ(5x}Gw(gd z`_Pa-2Q{8g57ar2aQ{+Twey$s{zj^=M{cMK@^riP5rkf8nE$QdZS=^&9$Bb9s8Unj zi-&drmTNJeGJpB%+X-zyFeY9ymhcx{`Rkp(1=V4w{IfEDRUhc+Z|Qx5|F)v4;BE1D zuT}%PY%S$A`McNr9fHRBd&^rsd#on&s7l@gRaJrw?_}@a^sV8$4Yil?>fb*ot}~SQ zJkQbueB1Jj?yL8}EUoHP2%XW_<5c~ji9`0GGT*WO``fqx|LQ;1tYP20Yy80SF#om! z^pjte*2%kG|E<^m{`&v(5n&DL23lWN`>wBdX=w3$-$_X1zaRJE;dS<%g-_M|ijUg* zCly6phZb>CNct%}{@sOf)uLmftHxBVTnmc~F%)9g15%WLUw+Dk*MZLnQKG|`QG<pL z7>zY5^w#LFM3m^%LBzmz5R{c@*6GQ{@Y(>pawIrz=!o7}8UDb}^<|fyJ8b^=7e;=Q zRfQW0U~?DzTNyTXLxlr@LUf0Jw?P>!k;sN}C;T;u;;<bG|CWG%pM`(>Ls=6;h)Bp| zAFxUP3h`b;H2&q4YSHPVOc7u1tE7VB_$Vy-H2Qc`Q>0h=x}z!HipIFDBF0-4Fuq<M z<1vcKls#1rOA3_R2mSm~9%EQV?6YYlj0Y($D?bpnbIV~|RTpDmG{%n67gm}gGY#W+ z6)`sK@Zls=Os#<N<FZ)NrTp=x0U~tH!8lWFh4KJ#DC}TdfT*8=v3)4U<|Ag;4G^Oi zV4Zu7lBFpo_fD1pVq|YDk<D<A1nienl#glO&?z!1wr>c%&BBsF<*_8Q9F|muJ#~sJ z(O9w$>Nv%b0a*Utg2j_f@paEL?M!iL5ylJMvF#>k<rGt?hoW<^=9iCS`Fj(veCKG4 zA5cI0R^s-$N?0d58Rt{F48{esF;1+9@oECLy*LqT_Ai5R5zVSfCCsKQ$9QDK;>k|o zpNQF-Nf_OoFa{09*qTauQ2eknj`c(g_IVk$onquHjL-Ygc7KfHVQvA!R_RtdSi_39 z+BwDMP;Au|_BTN6jKcC0+EQ4_mV*z*ImIv4u+?*IvCfhxT!$3{aaOrK^Pp|Lve?_+ z$FY8B+EQtXxLAB2I}gTpq?^F^F}Kw@GeC5hg>_aYVgIX!;<ycGUx9gk7kmZkJU<0X zTJ?ExV1S4!f&J8+fusCb7WYNadN!h!*;5?Ld(_7`+=20CM_ivN3vixa#ba#01mo|t zN&}$W6bVsSrz@?%7J8?mY4v*1yE8Bf`x!%Zc8`2<peY`M_tX?^p*%o5Q5cV?3_7CT znvVNbYYIlaImR8Z4yKqn1y`fYf-BG}uU>eHDPCw6A8U#krSK@)+Z%g(zYQMS&z8aU z=|kJUL}IxV;VDirnr6~pEY(f;TUr=9)w-}USj_0qdX!rn={Ons`D_L5#V|So%ToN2 zVkotZO~>9Ymc+AcPg#tsDK3r15vP|;ALSH9Xs@H^;F`>XbHNlFM&b;c_Fb^Z6l>dH z&4dh`=eLz``&hz2XcgW6HQ2``aDJJh7rnDFtI`_a)ub3*RPbsk;X0(l89SD?C6pH} zlwex}3KFQ*!%#ZwSV@$f)$VCj5bNbKs8G;!_;=3S1ly~^L%ASPpi6>HNRNmVvS^T4 z+C9Nm2XfIgN|WXZwhN#tq$3j(Y<EG4H2T&72{sAs`hkMPu})SmgQ%AYFuDVBQ>fkG zcGh?^X!NhS=1R)VUSj38Q=e5k;5<Fz67|`?FXl?3V6Gw=M=vS9qnh8*=q1GuRC5XK zLrHOsazD}DmV|9wr8%v!&vGc}r4Nl)2?cvQJ`MM;l6ahI?ktWqD~Y94vsudo+Xh*U zb+$r+?ITbowL21l?W&2D&@M=%(9B{*Ne##AG7#4#R+Iq+361tPR#YIp#5J2z&DmVD zIpsd;m0&BQ$BLF3&a)uQ^MZ&KqezAOSvpMZ?$Q3mirbX?z7DQZJytf1hth4bSdiEV z@1{f66E2vM5LM_1sV6)(-1lk;_)d3Yb!0t8xy2wq*-ezN;arx|th<TQ)XONEbvF@B zxq)yj6@^}^*q(=Dw^~g&3P6oX-ErSR%}H~HSZYH`8f2*}DYCPrex$Cj64-7qX_d=T z5-HnZX%1;@S4+>4cJT<CNYi+P*GT8!$ihB%*>K-S(ox<`?52GfR|?mxn|OzE^Eh{a zbdT5NFzx%$hIoW@6UV5}jWw{(-mG%8x4p$lSa~51)4ADOoS}9l>1^zWf?V0hv6n$8 zSlt^F@VFk%HDBtFN6&C^p4#1Ok2QyjFKI4s)67Pp;N7fAxl!UG<*vX8b;NiSyzeLI z{2MPWQ_U{%*vokFJt=t{Y7z=o;zc-f!n7Hz(=@^iag}m~Y2Rmv>(s7pA#688+$3d% zq0(8=B~Wu%->0JHvjXU-TSN*HyXYFSjdL^TEZ!z=L!UvSE$8mi2!WjYgS3j)Y@4v@ zIO{iPW;<DBVAg(erzoJ~74y(Yd^dNBf>g6E?a@x*gj|qlKu7CN5vJn`ei4fE+$l<s zcFaWWM!^U=jj)$<6=-kwiqcfG8|i(}^Ki@;j>;Y@#1YKF%D?e+_Sie}h$y4`gWg?{ zJ+`oRM3g7hYlb=se;XKcyJAqs#cXPKXk7N#SH&mdebTt8mc9ZBF>Olr*fo&*o!UKD z9NV2|)vk~FT9h!b&k`QgcVdKr>-lw~?6Hf*6|sSGPdhMoMeHM)5_MI4O{yVK*Tv%| z_VO0#rsz+4FB5aWiH#=i-wU*V_ryg@3AnfS#CKG)KaGA*{6Na6h3zz1q5!s=L^b_o z-vYS0LqHDcF9#IBcctQ>?6Dg_L#Sp`nDwh7K#nYc?@@di-1h*P0)nHpC9JjPWG!!H zX%gl7b8a$e=~Gs23hB!hmZp;0aBdo@6t|mBn#GzyYRx0eB#q*BsU!#IW|5xd5z<K8 zxn?@45^FZeWMz=@c)U5J5!~loQZ#EG=`z=xPx_5}SwPywH5ZaT<=i6D+dQ+yu)0Fb znB&P<Bb;&x<b-%;fG0yr7YcIYT$ppoOv;__iwa}ap<E;>NIbK`lkuu3!kSpqQVxx` zq?0G3l~zRVr(SkV!Cs2U6O<di(v#6uFAbUw@1}Dswkspg)BAp|jVGh19?R-o!IM!E z^c5W;=X-lHvb0$F4Jo=0s=B;H>Q1U5zb`Nyj->$5tD>g7O5>#ldNS;KP5Bck2XaB6 zs(!fd^XlNtYRYz?An{FCPe!O-mn6g%%GH(Wlq&`+5urC=>Gg4h2J$@RZV&Nf6oT9Z zKRl9idU-O+fC~6a87fZ3S~XjOg2d|OmRkAa`S9{^OYx*Voh|htT}bd`)P!D!P`kAg zJsEdlyzw9*2GBd!Ku+?<@p>m)xoMR9uqW<O1DQ%%7K-Y~YV$ZMkrX6;ALPkstoLP2 zhS8gYc2l2cCt#m_<(JgUy#9EE^pzJuL82DSWhm6VOu1h;_XFixz+6T`?i%Il47A$) zLb-VzJsF9RyG<%Ka!R8ZkQRV_He4{J(W@|?LE7s`(Cv_OkS6s>(1SqLNE^B)=%JwI zq(hL40QD#34N1@ofs#pmdnM>)K&wcnMkMGs!aD)D@=p)9^d4zhXG;f3X-_BUHKE-{ z)UMjf1idThW75!x3Hn{pPo4w8$KU}8a4+a5zaqWWAVFUPxo-oe!ybJ+2K$`F8cSLL z!o6KQC_!(mFJZNW(VK$;3gXPBwMo#6f+~|LS4hxHf@&1Rc78DWP*81<5O4R#(U-`& zlnYNz&__b9A?0iXtz1*eRfY9@RV<M$NI@MF^hAA^e2Qv*TmomkOLnB(ImdWd`E#sA zea6GepOX_Pm)&(dto%7SkMu3%B0!r+pAH!hD}PSzB(3Z<9#;OGJVE==fB1M9{hYi- z+SJ+7J<{^0$HQ8mlct@Hf|cW8t<T8-Qrg7vu-4~gFi41}28@TjJulsMT;1zqu$S{P zinM_A4G4RAeb9JV-Ak-~FkW*|T|2JsqBi4UbuY=jq!ty%!|Gm=gQ#6G7;h+O2#xny ze;n_U97egy$>U*lFUcgz6&+~h#!;?X$MLY9mt->KdX^jy>v>5|Cq3D2ZV&jZrh(v0 zy)$HPkJmIE1@jzGb8e4p&_>d@PL^IH<<+qCDJhO~-`Mf$cEVxx65v2h?PIAHDXXic z1P6|H6mqW$U7JX`gE0Cno33R!rWXwrBihXE(MdD3^PnIRUSV#JgP<R&=G<O5x}p6> z+Tg-o3@yfq<6RnIsf!awIKzr}VlNp_&+Ty(+9f*iJvueUs@ab;ffS&DpxsM@aD-S^ zo6eS|Q=i}V!*;RSI%+p}w59cwGy7Y5iF#?b(o&Wa-&<SE+#XG2toAzPN_DjQ+~LHd z=gVREKE!H!Nb5_XYNKE-btca3aaYu5wMw>hh(_Pg97m|HeL~73wFP0HrKV#qJy6Aj zxE&NZY>nv4Ip-|Y0MPUBboh0($YDYZp_)M=p?l;oha94vf?k5e?M0EpUWMFeG?&+1 zmOdwKj*cAG1Zq|Z#OI|06)e>a#CBtBR?U`yxbK_GMh;u8578D<PL{B8nUpJ9-fFj& z)Tg4Q^;EOrVyosRQgyDmg`|^)YHvY1A#TwA4b|R<oDh$9!2KHmGR?ViUO?w*w?h{~ zJX3sOfVU*K>ryC5n~gCd5u>pJ<ALcIH&Xe^B}-NPTBTM%`N>%rKVGy#l?RM}7D`sN z##mzXv#R{tW^17&GXP_FZH&Ly!PvS6#-AbUoylqQ1t_T(j<Hh%jKe9GnT^{u%3|zN z1LLB4FQ`^pfsIfyq#(w3{V;w@F$bcz=fpWLLwVY4jAI<odrJ%ATpW6-rL|Vf>J` zpEb4y7~=Ek+f^N{z)r|kPsKQ-AjYn9Fg9+0@l0`yI%RYGcB)prYwd>ePwQelu>xb4 zW*85}VBEYM<GRuq_Y}vNEHK8VW9(5MV<Qj7;SP)*iLoQqIZbivEG$W*-Ud<4wNGHl z85;2*_4y6ebW?nm;%pu3^k}qO&9nQ|y--ruj`1mq#ZBD)APVEWc^FUm?N#+tSL}z9 zaqj)9q{Qe$P*RQJ6Y~$L@+V@BLHU>rjH{brTsG&J%2pV05=u&z!Z@z(NmYK@JPjqs zmSe0i0%OTir&V_JqVrHPk>V7J?^HgovLW`bAUnAM#yAsWp8$+0WxrB&Ziilik~76I z&YX>LYuqK3JtnU}$v%kQ<L8e5btw5R^tviJvEo-K>Cxy{Rr1;FJ5X|B1;)YY7|Zv< zxUMwDJ;gC53yiUp?NJ}M%gn-fB@E*|>LD)^w{In4d}a~Gg4EB2dbmB3`uUD(K1VfE z0<ipJs(FyI>!|H-R3|76vwQnt{E+4rLA{w7Skj}>9X0<pb!9<3%P>}*kMZa%jFDwz zLGL>Bt7k&VUKhqQ#WBvDW~yxQDg~irXaL3^XJWjuq@c?7NDP7!dt;10W?;M~F<#Oz zZlmoD5WQpB8;4OHi~(9$!RjJ6E(&7z(vQ(L#!ri5>{|t6r$mfem68y5R>qhchp|&) zN!6$Sg0j$Cs=&Co6voCSFm4IPxVJ9GGsVkNKhe|=#@slJ<C5kDR2Pk7F#5SLPH0gT z%3DNW)T&g6xU(|G+&GL{mD*H-F*golr$lSJ0cD#|7GrK4#!iVCwJI&B9Aj=A#!iVC zwJL3>9Aj=A#!iVCwJIH{9Aj=A#!iVCwJPycjxje5W2Z!n{tIyCsRHBTQWzVTz_=wC z<KDU$bK`mxtR|L(^ik_puwQ>znR|^e-ssz3l@D7n1WG!W9imFM)EfyUJrXg#0NdVo zb8zffC>cZXl;2oYem)=>%2R?d9`?i72e!SfewZ{BN}A2Ym^K^Z;i(uOTZM5`3dU9S zF!t&=751)bXez|LllnmXcr3=jsTfyK$@KBKoiPn#H!3+qb-Ingk{4<F)KuJ_OWA!h z`#{gliryc+b9=)-1G2AC9Jd0u>(|LpGk?Q>0c97ck^z28p=9h}j5W$)+?<H9!U&8{ z2Vkr^A7gn3#>MS0HVMc0!4!-?KaMeaCB|!^7=x*P)NI^7QyOE_o){y`ELG!{%UB5| zPwE(pmd1FCN^1AO?X9ygmL7!h8!A8E6u0{<!q~LuO4U!j@HJ5KVlc+0J=ef0RSjLQ zvadGS2<4*+VH`LD<2ovtn}pkQsC)y())bFW%%nJP8P>T=u`R_<DgHs(pDC7iV4bP7 z?aaXK&{7z8Qb`}HyfBswqPEv4#!-0}non2S&Z2(arR~cQtBVa2@Ez|r8KZUNSjUNV zgw&>^#rHVDqoTSv*Z|`>imhkhc3KIH?Wev1al-_RKTgMZbOy#b5g7YT#<+J9#?o$# zuF)84)Ak=>xa}E*v2F^+W~msbkH^@L>U5`)Lu0X|AoU}r;r3Hh@;QxlGYLyN=ol|h zZ>OlF+ZZgF+Y{q%swrsnt&|-}bNhzo@FTU_H<S9IaorHTNB(ECUxRf%u>xb4W*Ac? z#`3)|ZeEUYU1^M&6bBW@?PZA=d(_9+$V1z!Fjg3W@dK(e+=1Ie>tbx&4`Y*_7?03c zq1699>SwNw<yr>DLDbuKG^^hz9;cW`@dCx`6hEYXBB&pe+RnE6p%Mck9@RS`{_h<L z{%{QBuhMRq8$9(v9Gs4^d@qdfyay4U_aMSE9z=M?gLowj<GtA!ZzW=UW)a4@I>v(3 z_Ch_}9!YJ#qnaO69eC1%@^#eeH!9!T4@*9z(IcR(cUJQpd!gJuALGfwc*H*24r4dE z`n^bJfi?<D3QWOR7OsA9zo>@s*B%&i=!)8g&Wp>G?cEy7U$A4GM`yv8!*F|jDU2Ub zt0_^qomdy+swx;iejKB%9>y{e7zOoUP@N~JzM%M2IA*``$N26tj8&Io^iV4&#lCb_ z=Ft52%);y+G|w++^cpnEbF^KgBxYCB+}@{>c`oX$C&ukmQffMGpDvRBZg#4>A66{0 zA;u6p#-=?no($Np)^<~sLr}7oV$+_7pojQ4?5ERX7z-7~_&dcRRI<80mRM_Rty@|E zmi$QT*)S8gt<`8nD>jK%Y(NVvm$cWjsib%TESZsrQKz1#z`Yypdi3s8pzUXBV#zO+ zF}7-h@%0Rh&osk0WCg~TY20Bx$MBA!$6$}%8i?_2+CEbpx8H|t?-6yT_(>><Gf%3L z;Z;sUNz<MfulZx_Q+b|x&OB56Jk>w1>ObfC3QB&>#CRYU<G^kht1ZJ=p*hCJRMN3H zZVxDh@tYWoFH_smwEeS&B_D)f>=lWze?N=^24SqZ1Y;`IKSN_prLk(v!ty<BF&3av z)-J_uH;o(nIBipTIU4;*8vPiJIFfqnPTO}S)-2No;|`jG*$lU1X(lacCZW_@2bxbw znoo_gSm$M$!-WjoUP66drWx+088)Tt$27yIX(oZRGR0|zji}FPDsMnDjHel%p;@I+ zZ-Z$29Ia17n&G=N!%&)G7n)(WemMGQ>a7ROuoBI1EscJh=2mq+)+z76*oVsBrSix! zUlnXy6uv?cX%Tlux`h;7l`a*OBGHmx&9tipHPMHZC-#Qj0QF~8&bVFBCI+$UglcwE z3?=1?nj`$}1;hx>6*OITKQW4wCe|;Bu=|U#ocpmzQG0-xz_}I~rR@bp3g?=cmF#vg zS*g0+A*L$1gi}mc$`OHLCMlKnC`in;a{lSX;^Et<1*~U^xj>6ZX?|-**R{KZ^(W6U zE}{`=Ddlqg%fr6AL?$U!ytK+KTw*0@mKc+E33AVn@<hfH@gi8PA<d-GgT)3?n%~VP z&F#S=OR2RzM7&JO_3N>qqdin?;oOh{-9Xz|(?Mb4bxY#3*~{)0JCp|4!^JM8k@hI@ zrc$!Ku-K!NYA-7Gvc7aLvX>C=vO=q_u$L73SyvL>;&E|+rA=C6e_R}5rS@EJFC~t! zo`~ISFC&gAZL^mZ$5|7r_Oh1~CzV{Hy!eE*ELDmM;*=#?rHbMU624=NWJPgF<y`Qa zBG;6%?J?q(k{f<wMidk92ajDB$WLjHy{ZUO+Ha2)5lSD}Yl@<l{F=mNi8`VLt5cjE z^f+rlMwX~6%COdD*g@r3eg!_W*Ao?4MG7>8-v+6~8kqQ*y}qcznv&R1)ECuQiBHFi z2BHRQ=+iDxEmEF;qnhXK4MiPRr<z}b>T%6dkHw2P(U2AUm<!a1)uF`q_C}&9E3rf! z*+?{J)eQT|-dH@vdNS-Ls1@sr$|pn<(U$d7<))zati7${MN`p<b*!}u)P;rTN;A=o z<*8RrHWS@hW$Q`NO!Q>!366*V8g_5i;b0f2FROq3a`H(rfHiJeym(R!W=&t_0u5ya zt;iBB#0Xa56?RaPw;i0RPl++C@>R0LQ(`=;dKEipB59V`73UT$MG7fZG^~P}Ov;s6 z)$iC_im6<4Np+WKC8m?oL|6kUT8o(^>kMxr(ySaDbv8#EvA~jFjplYod$E{R0#>)Z zSjLKl)om{_S!0&C93Ak$6*lX-tCS~4gcovj;#{5_9A3iFMJX{n#__aRMZH+pmjv-V z_j$8P4M&1_QK_z@yVyvwt}i{rX3pXDrH6Qhh1Zv!Vv8lXzStd!;x(m4pzTU^9lgX( zr6(P|#T!cP9eu@HtS{XOjsfCrR%q2ej)7ty3$HJO#Ct5fz6=t1tkj-^9D~LCtS4fV z97DxnrET_M;se&is*N1O#fM5RF+v<?;q_&tIBAKlFG=Do$-2HIiLX`8B}R)Ml(Ow( z#Lr6O9pl6urD=|dLNAVQ1zv6DI3^3b(sIW%5vugOBUKbq+Ul4mN|N&Y>rC41SRzWZ z+RfbuD#!W_j^rhxA`9=gOGFIGx;rfqRXJDGo+Xxu>a6l`XIvs`vWCD2OGRzg<hchx z^;q9THnJ}j4OyGuin3HRX1xhll%=96$-2ia6U|Ap1fCtsL<<(49m_>as~z3(GDRD! z9j$dH9j!v-Ic_#N>hRSG#|qJfYNq+&F}PC1v+x*PC7!nWl<*z0;~CLI=}X6I(aWj{ z$LAHtbE1#R-EgcG{gv)I){8+(e$JP~P^D1kCNYAPD`lxGj#otz=e~3ob8Zo%S)o<S zIJb&%EIeAbi3uz`TDOT5QkqEZ8SQ+H_cqrU1n<~(F_~*V5nJ84T})HjX5S%Zl5*v1 z1?o7n#Vl6K>UEquMLH=>Ossmvu}fqqx#0grVlE4h>o>%FZs!mC@TOQunguK0$hljr zuxk2==~?jmMbEHqHhI$dmRQ3&*tCsvk65d6ot^K9^-7<LePV;Ec~-nDHmY0?XRg?+ z)X$kGUR5;*I}eDhDmT)3P`u7+w|u<wu*hchTs{f3ixn{<9)73mP1fThT%fmDUzeHT zJSyH{;S<?W@vbE?d9+&`6}hZc>8L!`0@C}e&C@V<h*hI3>If^1YJR{vJu@A~`$%b_ z^8;~GX_fOs_|BTnesOx{I_F2?GuCgzH#tv;b4pvCC&d>^-Nnb^E7p$TyB(j1i>zZy zb~rx~-zn{Oeky)Y%5|O=KPnw^ekQK7%A}?{&x&7^7CO&~TS}{(pNrp>);Yfr_gGz8 zA9sE!WC?2@vf}zUz7o39Dd*RsfYKMviy}a2js08UVD*8Oza#=#f0!s2%YVc-&PyUh z=?CX!5vEiPev3Gq^|hZ{TosX|RIxR#k>jfHaPI7q>&_oVVWnHnYvM7Ib;r9dN?SQN z=0)IjQOS~@tG!>~&!P$o@3249x#_*bdWCmbN8nA);T<+K@RkzZVeg1opYiUBx}-e6 zujiJN@H;|0!p$bd0`H1Omf*T{-FZ(mQ7RqyhiJ~iYlx67SlXl;pjJxJ@blibq&&Q$ zNKLlqTx!p1fx7I-x*Aj`(3D-2N(UB@-MHPXk=3Q2?9RC-V&ek+WFl)#YV$yU*_$=7 z>UC#9*_VY^6uazCvR2n2hg&(nTZ`KSI%E>-h4d`pkYiZ07Nf?qZZ`Q8l*~HV^ep`5 z+a#6i=M0ilRc^4;C8x9SJqnSjtd!QB0z+gv>4JZS;qf9w&S9lD=?<Dty68X7uUlZK zT*#UO3X_X1NxT-g<x&=23*2%!DNTef=@safE0qQXhRbJ_Mg>O7=aeP}M#<+{c-1H* zUm#tSc-1H*H<0qgn3Nl!ES6tbIaye~Ou8T&jO#55%Pp*zipGOpW3_<KqJ`xSR`a0) zLAzK#&lwJSll9iBF`zvxEh!namo;m~boi~m_mt8>d92?@FBXr<gGwtvM_AVeJ}-*O zV<hWye=+$f$$CO6CO=o29#}$tt7^JLDfy!%zp?PNU0PmerNh&9Y56nD5B9H&{FM~} zpS8=#+pLQH<^`6OcUT2xW{I-$4_1+xc91MdS1I~bUQX&PysMRy1xOeD7sFFfIcfc$ zAEo(qh*%O>PCB?|kBF6^Ko))qDKCRr_$j2k3}xZxjtVlIg`Ybr$VirB^4h?PvJh*3 z>WiSqSf^4qgNl*z{0D@+78or{vSx<u0+q7l*SPH4ft6%gR;#kPpz@>({++sHi5MA8 zO7n{yb2u<YRwiBaA8!8$RFyRaR9VJy&3FAz1y+$YSjRzCWi3l|Z>%P3TkT|x*=|uy z*5w>tiK@x^AU}~OuNS{su$qkH-193?O;{UyeI8g%Hdp!v^b{#otPQ&w7%N*V{T5h5 zwj*7Xm0-M@vIDnE8hy23P1#w=7F1KllQQ9NF9ZbDk_n`|hQWFx`Go92%9ZP)UKe#_ zFB04zY>i|c*@u)So^BK`>dF4B4>i;vR@c#4prJ}3LG|Pa);=vVsJ={6Djw8Oj#erk z)JTq1suI*hjwj{HwrOtBOim=Fil^<hgPO@nT(g<kB<M*wg_I|oneBsG%4sUsJE*Ok z!D<pdJg9?ART>-AQKl(fD%eHNR+<*nRnAdL59%i8DJ>4_E*B`R2<jmhk*v?Kz2p+s z_;yzuz2!2}e%UZ`aZn$bNtz|_3BIpfNlFv<;+_xcC!bZ?9MoSvr?fL@pnP8GouEPT zMWw?*L*z!K<3U5^W~H-1!{w_=-vo`2+gLAZmF!9Kb*1X|QF4b8d>)fKm2$)wnM2Bz z2cmMsSotO?PvUdPIQbUq3cN?-<l9^`dU6(MAM2?xs9e$oxoW{HpaZNR+v}i1tdns$ zpd&1^(K}+i{D71uVj5MlPmmuf{S-7&9#{H3C`F!B(p;0|CrU0cMV?Z!yQa#|l-?23 z<yoar*9>`{^*XFls{BH!h-;SoQt9`gbosSXv}?A!sN@oJ<RztguDSBE(mP_l{6VRu zYk|CKi9We4k~c|tqD+Yd*CKgaX}oKdyrXKm#Pd>r9Iw!Me&2VG7wcsKl65CpF9S)| zon*ZXS2>q>Q9h<rO>B^*EzzB1qb$e5JIO{_f#rd#aF(pZDm-baD@#^k{W@bMD3*nv znX_a~R@{;{(5^P?4t$@LCF`+*+qggtSonR`CfSIEcbQGHDapFaY?4oM4(~FXWJ?y_ zWj4vytf?!@$<4AIYw1cUHp>nyyaT-~JG1Z(^s?;AY6koFihP=d_oG*24;J2!UXh8c z4w<_hugX5G-kAxYek{B@ZIJ_6cz4<&2eS^$T;tj*hmrE=ezaANWa0g2s~knL?nm3? zSZ=qeaJ<+iC$M%Ec7c*v)e5Y4y(TBInu1=JQ&<;b*SogMX{?_?JLC+Kbyv%lsVuy! z?UZR;vzA|$YnPnOY7WYgb6CBqXSv>x^H@osH{}9WlY&{U-EtADBj_!;gjKwDmTQk( z#;O8(TV}Fs0b5+}$d#;6&|dirE34)f*FL$L^(N?D`5eo>G~4x_T*oQ|%9ZOa(cO2y ze36t#ci;W;CC)9kxy62&#lm~>ez}=zUN7FrzF)q|xhXMkx%SI#tmjuWvLBG!S$JnY zAa{cNM6N6tin%u^mq&Ns19CUl%z*I@$UUs2(O7e@(z~t$@;y=}{O))_(EBovbI$1p zT?gesl67Z3C=ZizW%lFW+YieRSWm$9^RWDg+i6R$I}ghftY+ph*Ae-#(kHH?@>3Gt zDZg+XlczbCy5x%MxIC-$i|eHPoYf?JanL97g3=$ZPvuuiD}qkTZ&=lrx*TWaC6J$( zCB`l{gU`zEDVHld_H_iGlUGUm<<kX1gU`!rtbppF!Jo_PTob?R`a=H9+SR;~<AS`& z>gE>}{H46bO06Ch{FVHT)xTg=@YnJVt4Zys;BVwTR+)gJ!55_{g;&g6d8}s9;BTeI zs<gCp@Fl5}tb6fyvVhXgpvy8q>2T2Z(xG%V=m#0Z!h7l!8LU*@epQAlxx|mst&}6K z$q15lPyI<oaSrdP*JUA6p2U0Vby<XSM`s;$U6;j_RynWBl1kCRH)Lt0>cPLrawO}1 zdrMYi;r;fOjA7yZ_Li)|!u#!QS&d|U&;FaNL9*_?zsXuk4TFD|wUvGfx-07{JsJFm ztgrNYkft?M>KJU(8YyWmLu;ax5L`fOrsNU<+LKC0MM3Q;CA-U^wNe@o9H_NXdPf9n z?UY6ahiDy?LS126C#4C&;aV3K-tD8bc%_EH9_?wR--8Nk-IY297twkuxkOQ|m(o#D zOzWfcjwqq^QyLjuQX60i?)Hm=N@*i3`QdkKrL|Ekyy}<M#<GkM6dt+W?@_$M?@?w3 zm*pIOk1{v7yb^woQc0UYy;$EY#AwsF&zntF1;=PJmDUDV*3y(V1Xs~ANY>9Ss%i5$ zhu;}j(-yGsJL6bw5zAA(o4vZWgjEGpLtADEzME-euc@t2S{zhUTcxx%xR$nBX+!W6 z+FI6^?pK2AXwS1kt8NdjtG&p=t9L!^B^G`!Tu<Ai^hR)f?G;vP&v$|wYFk)O#2yH4 zq`juJ&E8nsp>#C3iMES1vFhTWX4)G{@Ut^*w^B9nq_&5J-{L%_y<-X9+w0Dj+5t;` z_#I2D``$mV@clax+(x})gTv1Rw^PFRuakC2^|?5xvvyqRmEbPgXQVv8!SM6HuG%@) zRrrpqtM&z}P->Rws(r;;6o9(O!f%bbYTqgKbH-~wux<sElijo*Er~v*-J+ZJ6YI%l zUpTvIKeOJ6`7Zcr?N`=`aaV&AwBJ}od)*4|rQKysoq9L8w<b#Cv79GfD6-W#K(nzn z7cUSpP%~L=>pMdRY5uJ0p0JR?nw^E;v<=Y$SzAg*g$&VxS%qd53mK|~vHCblg$&ao zSb?%)$Z*ZWYA&jTjL?d(j*1!~Beh~IQEaO-Nh`?;Xt2#bN-NEp4&#m1%6W5@KNVxN zimYqn>V%BdVpwm$IXzCR%3AWoR_8daI_m>yH(sm7>Oa0t$ONqpt4iD#&WT!m){fa( zB3X-L#hIukB<oo}S!<=VI4D``q!bsDqII|ASEOu~n5reRqRZMry;=9*d&Oy5KbC#A z9W;P-9=>Iqt_@~=zt|2M%9=huOU%$lurlY{K}n>G{`fuZOl=J3BH`Pnnc8^H;kQOJ zwPaGN-_>TQ$z1bhlU5-!wP_^yPG?BGNY!St#tw0TW^ql&kPacUwArkpL*hYmSPkdL zi!^OMtHpd5Xd&r>|IaXby0(P1XWj|Wa@MY@m|Mwe4L|cv*Pdl%!?}{KJ;$02->}Zs z*0IjO3eM49VC{xAo1?wNY6X4H(KfL@EQorAwI%*b&{kIYXU2eDXC<`7n%S&t)loSt zzdEShtWAUCL2t9p42Dmi+Fq7(>LoE(dyloGb`~g)6;TUykd#Jupt;%+*0hMlL36ba zNY*EYdD@38{KPO{JI?yGKw`)O?If#!Ut-8Y?GsX-oU(X8$Rh2um7^!|McNrsDqT?) zY3E3}@OP+(Le0;)CVmIMM7uyr6Y#ex#4_zGtEQM#+AfxB-*8R*t}9dfmXs&Qq>Ks4 z)Gl+ot3g-A3hjzgosgB<HP*$MDIu%08%i@mp3!cSE=s(<JgeO%<;pUCb3&fgerHAb zEeTnp-6f@ppPRYGbJ`y)d|G=>lV$Mgc0sN&uYz>eNw`<7)lAkt_{Msz=Fch?dsVE{ z;MaJlUDW)u;(5)<`k+cv@q!k_N`bq~i&`-2>7}>C1})U9#V5o|S~%<F`G0^SS%-uC zWtLXRn}c?nwIZwz^WEZQttji%e3yJ#E6%Dq#4TRYO0wP`9U))QO0y0XD=uHv%8}AU z8~C~Q7OkSvs*o*OjMCcRZCX{O=R;o8s*_U1(xvd5R9a0^u3Wm*4tm0>N#BQLYjH}K z3TA69EYa`6?bKSa8pCgZ?bO<^mez_FyR`PKUA0`Gj;uu!HizVBT}T)F_rp~xN9)GI zD?^UforPD194(QBSB4y|4-2mhIa+@fUKw(<K`gv7yrB(Y;gw;xHk^f5hTU2c3$F~j zwJ|KbGVIpIv+&BWTT5o)m0`CwnT1z|-P$x3UKw_4Gg)|L*sZ0JF8brSxm%mf!gKR2 zZ4N0-7)!Q=?9t|vawQ(uZ)*!#=iqF7M_Wv~Ap61DxKCTkss(4qds-$7kMj4lRV+Np zbG2t#c$DXA&#~|*->*H-!lOJ-dx3>V`TN=i79QmXwT&!1$`5Iqyn>_ru=WZIkMhIX z78V}mN43|yIcRrG+s?wH{6j69g-7y-S`G`3<d3x7q+Iz7?E7(T56OCJKB?^|rTO6< z@1*uV3-5R*wL>ht$9=3FW#OIcW9>s0-nl;3j<fL2^@;W|3-4T?XrHq1&h@GG84K@R zpK51W_!;4p_BqL#*(vQ?QXbuJPidFA<^VW8Pia?37yUyVsB2vFW|N$dQ`!yI!KQmd zPHVrY+`*7D+AWp)FyyTEo64OEIj`L%UGzT-XUFH7D2vyuixRKbpKBTke<$PfkPDj5 zIlP*Fr4_JpbWVSz1uD73S6aAIw*71EF{Mi(7q!xs=o$JutsH9-{CxU5tpcn5ymIog zR>_iZr4A3etW{R37WlnZm6X>2f5LG^i?wnzmmjsdB<q{fAGIbb=Mq0@t(3Cu*R@Vc zZt=6$-KX8pT0fO@iJRImrEL4J+E^tw{I{zn`?R~Q%~Cm+_+6W?lx@GGEmyh`a!*@h z$<GBp@e{UntRnC|t+1_Uy$?r-v~6H5oA!H%v}Li@PLrY1wwd+KxbaTShVP#DGo@Gf znZz$t=Nx{f3<@=s@H0t(?NzH6SivHp1#Q_%r9vIHJxb#pfwuiha~#38qe?NMVYZKz z8if|Nog?M>7bw&zw506|R-r=OKwq*7!*5nSZu^FH-jf*mxa|__il;y5GOH}qEM>dG z`VQ8ml<k@&deSLnyTQ3^=%tkHCMy?uDP_B5iGH$N+V(pOf3jSLRsue~IEp+8KV4Od zc@loQsx+>7yeO-b-rVJ*n@##T%c<PKrh}d3y)sUl!$K=6;V0TkN|T-(8ychZMC>+u zWu;}Q@SC?@IWDxH6k1j3xArr9RH%JMXf>6q)_$Rn4vx<ZjrHb?igBxbv`SkaT3zLm zro9?kQz^2{>U=q#E3qTAmN)0vRN_q^)sEj6`h?0o8Gpb>rK7S$ZI$Z?KdH}G|DrA* z;p)~=HF0(G^=+$8fpt~xcB>CU^K~=kgs7)-qH<Fo;k!~_<?vl;;FW>zL!1(>d?O`X z`Nm#3@N;+*CH$<NFZ?{MWZ>uNeBmd>eBmd)eBmcPB?o@C&li4v_f<b<Q}5^oenxMm zgrCuyE8%DKCzbFsdTS;8jNV46rhYQCqY{2%@1%sE*gGrXC-yE%_=&x%5`IRHSHjQe z-IVY%`qN7I89hM>Kcjb7!q4bEl<+fpPbK_}o~VSMwR<VyXYJlf_*uJ;5`Nb1>y;yG zQM~A<l(Wd?qpl0f$^I%gWTB-0UM^li^BlWNo(UbGa)(QP;iCp!FNO|Ox&B>$@KJ?n zH$n%g+)Ev9`{-zgKYX+^)C?P}Y90=?=gWAip<4{`=8W$Lg@om+B>Y4yU$MO-eR8qA zAM;U6uM=XZ>g9*W-T88yfhTH}b6kTb>U{kK>oUyS&hc8Qc#*F*WlD!B8QC3ghx)35 zPwwqfE-~EO3!NP!ls<IEhUE)Cb16BB2m0h3Z31iO*L3s^iVYj-?ZvS;sJ4$zK)WQB z6OhYSe;99+$}M%)_ECuzabcrXu62u!GG9Bx<HE+M+_~_MGGEiGmXl*uE~Bax`NAV) zoXQPs*fdPZC<C8w^R=iR>K@&XtZ#qD+01fy3|h}G<7`e6=3HWe&8?JepJ*$h<Q6Hm zQY7oiF~wHa%K71wV~VW;$$D~3u~j1F`s3e_NwHPo96kZ2*kVa}^aPk<tHHu&zR9*H zNY*?j+u}&pJSW>)sGLhowY68uwokKlQ*w(Lw%$JNX4nR+9DEmK8>N(OpQToC_=J{W z=}JQ*<3+wEN4k9E54qW@W+deDg?EGumBTy29IxO$-9Bud65bycDCI?V3tOm!cZ)?z zc(+(=OIEY)6}H4S!;;@mv*N`v+bkA7>o22r-sdx~@cC?DSSIK2`D|p^N+o<gTWy=I zMsSNYwnZds<=5C&s+>!#wXIXiwy(2gDY?aZ+cuwe>uotI2fssL+pCmq-(Y*6WPK*t zX!}s*++w5c6v-NWqwNb)9{eWl39-rcl~2u0w(osvZnE7_IrvGv?RTYY`ztnEc|7K= zBWsJTAjukGi!DUu;AiDFk5ab%HCqX#DPh}f<t_Q;!Br~T7R^c_VgKHh&sM8DB0Mc@ zm(t+y1z~R};mYr^RaPTN@wTlN_Zb48P~PF1G;4=f_-?Ka+oyUN9R6b1drH{n0b3o_ zr(3*lYfQ5C_I+DRm2-(hwvI~K_QSRWCHReNTVJ1cM{Pq@&ISKf*D*@j_7827l-%OD zEtQlhYL$6C?6@tBRle}sVISKvd}@AbTdb59_Ni?Z$(rXW+w&^t5}(;NDP`Nw*j}^b zHy5ri=WIJj)@QYIww<bGBgf~qx0Q~DePPQ}N^pE>`#|Yr*jKhsl+K2IV>_?(RoJ(- zi%Q>zUAA3Sx)Jt+?WWS5upe#rNO}JFx#PM`R-mKKFDWw%{!6hsDUUu)T(=dlM4uS0 z+X7hliQ$ILVYQ>rn>TD>Bx_x6*b1whOZ;McTq)arla2y>x)>gpC2rX&s+=1XtK<UJ zRm!&Cwlz`G-M`zKli)jC=;e;>DJutm6Y{&@JGR!WBX!}os%`DOxtIX=U0X*|Cj8_s z5Y)xWiPk+m?mukZNEc=6o>zs?yK~K#QsGy7^+eW~l;Uoi-iKuUj;^8iXW_b-`XH`( zrew6+)Q7TqH!JQgppRhPXi(hkua9CSL9U=amgV2DxZ9ym@aAB=Kt08h-?(mpZkIlV zwQ*%}cZfcnm7HF~9j2!$)pxt~bXHFoAzYusx(1_1>hoE{)0?|J`XbhL=(CW%)SH8L zMf6OT2{S9IuOeNL_!IZy`f3*b#J#xw91DNqUP50-N)wG7ZQUjH7f9C6-%IK*Svfd* z?4qQ;NlA*w^;azUb*dZ}R!ZN>>QXvOl+s@(S?_x(J)3hq;M;>zdJgMm3~DziQ%rVr zc9+uMwsP=J_jZ@j_mQl3x~!hdHOHiMc9+u+kgWH%f_{jF?`=i>DA&aIwxa$at9P@` z?r8l4t0nXjqkqCmf?O5-G%FEu)%3I89H_efIcsXhAa_muOG|#EVb-<uZ&*2ro!zzd zORSA6JG<-Z-?R2ZuD*Vim7G4x-BABYX`(w$|5<5<yOI8@(p-0A{Wqm$?k4(Or8VxR zx~Pa(hD^WY^q1VtbeqyvcXQoT%5gub`z!5px6tjZ)}=?epV9+aJz*tU>cOmQ4LZA9 z>tU?n>4)5H^$6B>*uQqV$D4z89rPkBvteg<C%qVJ%Dh4DE_zAUBv?WCuhX(RR~hAw z*UMQFAHgbh(<`!4OMm1}&|^r}k=$Lc%EBYLyB^EJBe{oOgOn!L#+-8Z)SqA#u74g> zmsP;?HK+mW2XPtH$Xiof12tu>7dJsqvNmPj0kvec@Mz&Z^){?wwfsQsN!FRuQ}0B| z6#a*FhIU=8ns6R<l)dz)N!HoXTkm1z{BFj?h4t2Zal6x|GrYInmo?7e4DYKCVC_zH zhWFP8TkYUni3%U64<lLU${>9t*OXz-@WJ|M)|ixH;Y0OtB<su>u1{p)nKMG4#5M8E z8KF;Q^=?)ye55{ub)!MC@KO3KRubgK=(Ab=4U2`3)912kx}4z?^aZTUna=QJeKBkC z3TOBveHkkWW;R7%!J3*;F?^c-j3v05I>V>yYgnUUC1&dDSUIo~v-B5O3tKqD)Ag5F z8&?(!&(Jrq_Cw9N`YWvD^y=aB^{q<v!x!kUD>V&YsAns+316h=D0K~AtnXIp6~07& zTWN6kQhlG&=<sEFuF|CN<@y1oS>c)bAy!XV!4>*Z)-_n&Rr-gl;pq#)pVd#Ww!<E+ z)<5y)pxtx&X_g5qzfM2PS_*5uUjLl60M`0N{Y%y)SlyTOZ&+<RIKwyUmn@0Y(#yj) z>EE-WXF0<+>sLwE`S*(c6ARD3SM(b!JpW$Re<7ubqRm!^Z_#hD@ci4N|IWhmZ;O79 zh3DTET}IQhjVKJ~-xghG;rX{kFTld{Z;Kwl!t-y7?qK2hw?z*kS?AvtJ%ohkpA&L! zt0p}KZPSY=>F#ZMDW&z{uj$cBmF%zU)h+p5>KowRuGb=2=k0dA4(Dz**%ZEAug^Nz zbW8XSy&>yJ-Oubh^~NkuJybJNreD9f9pO9m7M!~g_9mzm>w`vnL2X&5;djq>>g`!K z;R$J%-ieec@J!vMceMoffV}V={b{9R;cw_Ytac*KJQe<?-izg`*HFBz_hD^?zZ?IK z-j8&l;kWSjE#A=wSfVG0efnS)zVG|=p)7pg-_?hc(!@(EE`-0QC$Un>ehV6HiB|rA zo}zRu{D3}F>1O!*`dmw})_21X>I+ELS|8LGbM9snE#jcQjCHVSfrvwTCJWd4h`x%2 zYkfptO~SQyL>$rAat_z}h`ye6Gv+R6gH@B(^N60s?UK_&B97`WD;0|PK;L4ugY|qo z;+Xy#3)l06zMX~Zc~Z|NS?hUH-(`u`^Ar6|7Ov+f`dchq&rkKYNofL)>r?tZR!Z6E zh*SD|mS8<=M4Z+0l<GyC(+?^&j`&<ZqV!b6m-;cKP7#;%<4TDUKk6S_@{=j$<W2n) z$y)iF`WeoBmyEgdteY`IB5vvzNcfbV1p3;_!To4*#4Y_>l6612tzYJvV^UHhe$%gz ztUJ&h{Td7JKzH>UToaG$yZTL5?`EkH_w?JW8x2w;gmH(J1Ub$4gXP~aH9|MEO7u)5 zl3+a3Ff75HBq_qr@MCRUnHmvb6l5i*FN&}mPNh{54#UOj2_ra-P}VgVJ;(@W4NqSm z5o|=UwnLvGMqzIb+JzZKStiUZ+$h0n+aW0;(kNvKuDdTsc#N{F=vhe-g^UU$>$+RS zsKmnKrHE0Pg~!WdMpcq^yc9L6ldS7tQKOcXgX87(h@wUvr9Ba)jrvM?5#^0IrK1rQ zj3!D_R5Y3^H5AdtQ<nT*um!j)8Le3ZZO0=j8SO~c(NoFj$hmjm$-k1(g@xZ^Rx-M= z@SDp@Mt9cDm`|aXL{g@BIq4jz59_pfF(St3&#D)3J)(*+h}E;kxrkU}C@Bq&!MhRF zjS(d47_4E8;+j{(^~jpWSe6XC7*X4pz#5Yh7+KdyAz8;~ePaseejj!&qJc4;b9l5i zG*UT-M{7ePoz=TpU}T&zhjpVtU}R%sJ}U`wO^rn?|Av8)&5fn3#VamGv@kNgHDN9- zja8Q5*u5Ch+E~q6*y3VDTVpM2<I2Fu_QrZva=It7qp?A$WMn5JOQ~XHXX9n1>XBWH zElTwxyBe=4HIIxpcCdQFth*VzSl3{W5{x%l!_(VD_AvG+b&c$4>{aR&nP|MHG&r)C zk*72|vbS+iX;Ne#<A~C%$iBug)^^yxe#UWc4(2kz_?TtF3Jx+(u@=Az4l&NK+IF}Y zG0Zs6if?x=VuW$Q5}a}KB1aluvsw*X8kuB#%c|m96FJ(r%(~rdW8_%l3M+cn#fWjn zHIj91PB3n;@Z6kW{KCR>bE5GpDNR)LY>P}beq-SiQnGQEg`ZcF4H08K1>qA?vSDN4 z6H>BavhWEh+3;uK6H>AP|4AhHlP2&9DcJ~Q;S*A_5zN9nNwN_}vaSrtMg$3-AWE-+ znR%?5aGf|BG07-Gvd-ekMlmY~pHQ|%PBuz%yVK?lP-!a%XWZV%sYW@g9ep=5&8WyV zW!R3$=|&7|Ov-`CnMPHTb&kz4s<ZH{N;7J4O+2g8j5@5|%??DS8}(T?8XSnsFydHA zkeh2XVfi;a5INsy&RV=;N901|DQ`^}eX-Hn5}Z{#B9|KNSPNV1h+J-TWNln|AaaG# zg_WFsB65|{P3dgpGe&o%uOgo{5?MWAE~||`tZOjO=ZyZW;psm_t}_NH{Sx`SF;wYZ z<a%R-Qh}%!j8RHKQ7;-}l_H}y7!#C=N4;dED3y=eXiQ;khkeL0rh9WRv&}{-%Y;>W z#Ykr@fK}RJ%we_dup@GtF`pIRu1eJF#v)5_=G2bbZY*U*&)N~W!^k9A=fh586${UY zoyM~)JRf!$Ye?2-gdAfX3(tTY;{_IeV#qOGV&NH(V{G!~;0(wyUSZ)GkYj9R;Te!) zyw1WiAjimN;Te!)<dCd0AjjBk<=~i)i^?(HQ)(Ht+c<31^s5X%0pDwUz<RSD>Lb>d z3sEOogUX^lW#QB4UgI-Tn%}8H@sK;mxgFgw_XTTTw}z1Wl2sFaqPfrbhSeN?(!0<2 zmXzkFFAi|OYh32sUa0x5afS5})O^?Y(NcrDX1A#KjO(m%WxGYaZ~Q{arQcyaYW!;D zM3gx&>I369R$|#0$1&p$*Yt~p-&-?ER>tc~o|sV=Rf-j7j)?lusKA;RQ%;^RDzWy} z8y|JTsKUZ0<ByGMtdz1-qdqaJvzEtnl&6iFB>dTg?*7cEt&|>h#;B*XAnL5qP{}2} zH5!wwtJEc<nU#a9)S9SEMhi=DU3vl3%Bo4%rSFWkq)hm}d~?)gqXWsh68&IwX5p3S ziV@E>@k(^XNMQADwmIsm(UWzf!RDxIMsHRU<gOe2SpE$+NBwLJ^yXl^o5m1Jej8VA zj=E(GXC<fajQY(;QhF!qcVmpw`%!m{@vNRO!d)Yobqz-U!<ft(p8ipkG^eq)!w8x= z)0=~Kx|zl@VP>Y8VF}LZ&!YUyc_iyB_BR)@@GSN>7qjpz4ltLJ(nOQx0q%lkCJR6R z6*O0|@Qf>Ht|nP$TtRcKm4kQsLR3L>J;{3i?B)h52k+m-D7%?O!p|0$K`*n$IW9*z z%`L3miI<~-%-5`T@J`>13O09;tY^Lua~Ic?VV9#q%{N(NQtn2%%{?UReUC8rvhaP6 zG~eTz_`XM)d92>e?nXtK2U#~7+>I(^9$_Uxu84Vz<=^mbR8jLdtETI6RB`iTR_4sh zQ6<e&ti>xXN0l<qu##YAWz6%esTuyBa^?j~aId-?Ro?uXH5yi;qWLW=2Uenzd6~7a z#pS5V<`ve)m3O16n%7wSp=PXkgO!{f?5SbiRPuOgnzxlodTN<>lq!0jF#k}h=BaIJ z@Sk6_zIm?esbd;SO+9r@KczMv_`e=d>guU)I$1qo%^H|4)-_nqI5U(rJiV8vu^Fy3 z*we&}Vr_>#YHAkt=Af76W>J<2E8oH_!CDGy-O?<@S^#U^+APbO1gqQDtiWp9;c`?v zvl1)5oxi7pS;Z2Z9Z8;!W-Kdu*5#;9W=)cHu5>YLv+!K$V%BBhxzg3FPqOZK@n#$g z?|AWM6Bgd_;?3qPd;*L&pYrD5ju&sXX5k$#-fYLhJ6^omk%f1>c(V%&&%b!H8_7EV z;?3?P{8sF8RJ@sJ)r7NAil@y!B<pNUF#B6MI2+5!1alC#J8e$zB$z{4;~Wz_J<JiT z-H8)CiRLJ)9h{A+p5EqIl65xrF(+_M88*Sw*GyrJNtx^EZ%!duXX8L~It$OnL1rq~ z#Itdbna=9nY_4apIfr$l!CcQ!b3Q8xa>LC<EdPdcJtNJfteUO~o>68dD|6-q&lqzR zYw?N+o^j@CRuar?g1MG8HDiS**<5c4&c+Fz6mtV>G_1sAGmDi2D>2o4nYFOR1kZGH z3v1)bxt^KkYpnfHbC$V-m7KoLlWy)(+88<8d{b$YC&S#M^txw`xmW28&s_68rFT8^ z%si#Tp84iMrIVfo<`Gs;Sfz#LG1fI$!Nulr*6{Rmo~7o;N*6uL%u`A~dX}4KSleNb zGR^be9Q3);yudPH<)1OXW-W!aUTuEMS^#VPoOziw308NVd4<)s!vxRs<~3G)yA_@n z%o~>AY`p1t(Y(ouo;AU<!Mshf&c==A9TuLA8_jzxJR7r2Q5COQ*4enpw6XAP++><8 zJR3Ke{wzEjH<|FClcjd}G`h(QWZ~Jk$qZ)U*|^CJW8vAj$&6s(*|^E{kgT(DlUam> zXX6CVCbO7T6VAql;$^cW$vPWfF-u!HI2%8+zhai-cBjp|o>$C@tZ|OJo-Jk!Yj@&Z z&o;BF)eg=^|3a^u)k)UbxZSM9HD%ac&knN=YfMT|p`B)Zl65xbm~kvT8{aUSa7{cL z-!PlAdN&Iy^rra~>qdj1LT{O^SxJz4+ib`3Zx~c)ui24R({<PLuGxi^IrFY3*X+hx zyyC7W&+N`hf|<Q<CbFhx6e@Jc>|+Ve#=D-wW`EXbSc#+NAXW~n#4&RyYhjDKo{!8C ztc@#!3Y{=VvGzmFkIk{H<n+f2eQHiniY|1@Oi`*)=(IUSsX?L7%;`$a3Y{@imD(0M zYo;s37dmIoVfBP{Id9HqU4u3I!d%1}p5D9Am*!HXA%(s&GnK{^`r2HjG`Y|>=4#e< z*rSW)T5k?UxMZ$pnXvMg%?+%ju+~4AS*!)H)>qA!S(9LOubEp|Z9Clc{A9kyif>n_ z&<%5kB{&;X3;k^FVnxro>-oielVqKZznXhkcsBlOzQe+^@s_!dWSxz-&0H3qjknDM z|BJo*j<2F<8^%8;ZD;Et5PEv=v;Y!9mo6QFP^2R*6p=2{LzCWnhe(&If`}TUpmgad z1Qit&K@bEf?_4w2nX@6r8@ccM`91IN^X8BJ?009j@9fTAvuA>W(s<wJ5DH4;eV@Z9 zD2?}hj=6HOC*^&glPD;S_kB*Ipfuk1IfsJMc;DwDmne<*eJ*i9X?#@tzRwkrla<D- zB7gdPFLk)cL!Td|9ORMDb*XCPvCj=IQEs33+!AT5+@2}&#ODqd)M=;qKk>OI(pcG? z@9$6^i23*%iih$Db2<u6@%L2Nzd&by@V>Il-&^tI5@l0Sd{9s}siI;|D4SF<P@QTo z^H&uo>UPy-{<@MM)t{xAN<oxbZJEDQDT10ge~Q1aQrwl3t-XK}D8x$K6#s%s2x@x0 zDgK3(aMbz*%lwNfQK(@PHux7;Vx@NY`zr}j`}_lxl2V`g2P$Qxj`#;D<)qH|2P+k% zF8hZlDX8{rA3~KXsGDs6!j<Z%J`;ZMk5p<(-Sm%A>PX%9k5=kSc?85L4W;yeSfz=S zUqGDF9JPb(U%b-NmB!YdsI*4;up?MfX@{D|j$mn}1FCVeDgH@HXH;sF;sNE9ZbGaa zg$I;ZdY}@=Pw{_2>CGj|QL@q(1?4DN>5qbPR8bkgl}>6^Ia4G>8H9qEV~R2qRh9LY zm!iCZ`jnhEQk0P>h)1R<V^C23Qk3y1D1Rx+L==?26lDqu%3q2y&6SgtzZ7LA3Z9KA z${ZAwzZ7LY3d&!KvWQERzZ7MuNMj|g5J^$iO0i#9D4V5r8I_b>QiVtr<pU{Srcb4I z8C8|TQiqFFSB^==1=LVZa*2}qqH<cKv65Oc;6>#e7nIZ_ri&ttmDH*MwUkR@K3-C5 zD_1b5qhL}%9p!t}>%(gY)Kh-s5+(H|<vI#VY6Im4=7f^kK)HqLRJ(RSL*)+YcGcPe zjg@<-{w%Gj@&Kh)s~yl>d4!rdKPjMvLduH!M1QvSR*I((E2&8VtrZ{C^m<7FZ50)@ zenIVkR}|JcKHOhe>v6My4vJH%Z9qpQzf{+NPD(+k-T|GJBB=Ik%epAVQ8(FEcT)mU zeI^VH=&poFy&2F$3747>&{K($ni0@TiIrLy&|686S{0C{l$6>S&_^kQ+QIgruTsvH z#<r!uQUT?|j?w@n1vQNwrGZKnRO4nz0fUw5sMIFg1BNO!g;;6a8!$|%gGwBq6fj(= z&m~IZ2&EwkO5+HnF$zlKn@UqI@l+eByo`cUHBxDXf>Je7X@i1NHBxy61*K}F($STZ zm8y|S7ZjALk;<zmc*c!XdZM6Ija1UOM5!97^b={URDB#UQW+riWxyC^kkpxgbY-a2 zw*ga>H>B8C<H|^>n*p<wF;aH}<|yNZ=!*7F0_H0dQ3u-3a?V$#aEUTDUzvt!v5r{B zd}Su8)tlad^OZTMyCqY}d}Tftls}!NEfQ($yKP!{p|TXy`n*{<aG|mS(;Bu94qT+H z<`OmB#mYL&xo(^uxI}py_4@Frz-7uNE>SjDC|glbHdiX!xzfpkL0X}e$}ZGKu6Mb_ zcNZ&_y{JyLqXJhc`%$;6Mg^`>K0@_pY3r0slv*t+FhlvwmBzMZgK|iSl~g@&lX4if zenC{=7UdXf*n~2H+mw@1DS_`Or=@BJZdcApH4NOLT$E}VxKp_#)gf?~az&~~;BMu6 zsn-JcC_hRK4}4d-E;TOjJ>`bf)WG+ZTT=4^_bPW#?b+V$Q|_T|vLmryd4TFOVQJt2 z<q>KJ+rN(#Qcm1^`mp&vQ9MyT>?nPz_;865_nD%ipu~Nquzz~Q{<0lV;yzbQE>YqR zD)~@Q;tnbWP;Z8=2|TD2LP7aEs1!v(`8%liqu@)}gGvwzO5;H#)HNR~jR%zo6qLq; zN;C>e<3S}31y8(#N+OpijR%!dB8@-e4k{I-e91wjn$#}ikWyEw5cyJR!X>`j{!&Sm zX};u$(ot%caa8Fcl|+s!{iQYpo>YcPy%Ts^8O<g7dc3HNlN#*%y)r@OEJS`$rc1G2 z#+3O|?~)tJaxPKAe^pj-!S^;F2L7t76*<{6HI@9TWC)R8I)2L1Hj145dz)XCEnMPE z-&Ec~!I{3P>_EYpzNPHq62HFqP5C5;j_1&&9Qq}P{>&k@JX}kzWfsn%h#V@DL)CJq zQ4Y1sp<X#OG>0bS(A*qaokQ>B(1$s6IEOCe&`&u8`|A32$#04f{1W7gz&lbs3!e<U zD+Rv<d7#{rOUVxWQ+XowW8gzYc>$IKN6?o%QJhl02NGIXh?1mOhX*Z&vXUIcgZiUt z%!qY((jZjJ84lt}Lr{H&JPP!p;V3mQm3Yx8RA`_tQw(Zk`3&Ms<59EA8%&9)_@3;m ze_9Ha($hhFXc^QK>KUZavM68GGl<giLcFIKl~&-&cJyGsoK<N>OskTn1*x=>RG)kr zts*rupH8bu`34!ZhSX7Ci`GPS@GctUq;;f1gYwb(Qi(zNX+x><K?P_NsTx5AX>+Oi zL4{~bsh5L_(AH9&f{N32QfWZ}w1d>3pg`JLh~JljX)meDMS|%7sh_P-I$Y{zKsX&M zl|&-x6d`(<{YE;PPD9;gzmblnGf?lc|N0X{XQPf*agZ1~7X`nqj-?Aw@Z0KGx(M|e zn=g(oMU7+g#nI(l;+J3XbUmistvMzro^B9gHHb+;33Rj6te`}?O=?k4NxDO7RZwZV zTWUj45`7N^y}gyAdr=;5Y!50&_oK$Oe=n#!J%CCs`*BbO`U$Gc)Pq6E^i$N(GRK2b z=w~SCwXG68$R+lnGCj_fMW6I#{aDklgvc@LY*1x-2DQ5LH%#YIU$y#<>1&i{mupOy zQ9ty$$@DGCr{7(stElTe9y0xe+SAA*xHA2jE8B6Qz%WvU{>mlpidE?!QhIPz>Zsr< z@A-qPQH?8$9qVGjHK>7FIX^787In&;iKG@Sf@ymig$389#bp}nVVj0w+P%3kEG-h1 ze_l**JsM-n*?^X^<!nHcY&jd#^0u7KXcb$|X0*C3XA4@B3!bTkNGgT>VXfTWuy(g# z?QLlT+cMkJm!*73d)iK_bZ`gSRVq2S6HSw<8Qhf)6r#;jng#cuL%6ai{OY?09gc!u zefOXvQ1Gkoo^%une)ZjxjzPh%zI)N}DEQTPFFJuMomOp?8r+*sMs;hI9oU<`#g$3N zvg;*{PDjmY)jl|l&P0`N(Ji<SorC(hS#PHKsK?D-V_L|SMK7@a68h35s9VJhre$2| z^kJi+!Tsn;l-YPB(`wYW(=teZx(@Ytn!%KTiXW98{2JYeTG#9?rY)$$&1Nxe<I1A& zd-MTx2MT_VK7j7RoCEZQ!LQRjsL4zN>3c#|gBGj^9z^#^tz-HSRkG8H;34#5sdY@B zN^J`sMn9L@7d(P~fojR-dy^iKTE}#pD~rHy<44hxB8|PhWCo9-r@1o83ReC`(Q}w~ zy~iPzb`jH{m$6aw8%#46bT2lVW}|{S9Sa^qzeCmNbS`)-{Q>8Dz2lYOar7E0(ED2O zc=`)h7J=X5PoOtZW4#{)PoTHC(n;A)J|Pq7T`7a<KB~O8U&ti-P%4P&iBx>ZWa^O& zB`2Mf_f83Ui+Xcq5%@*_R7z30cfF9QRL7icJAE2BjasOB-Yr6=QD3Q!Onx{Y^aL=S z7Q(bQr-O=cWjijjU-3?-#YGw~#nWk+RNs*4G>$8amTEF6WCl${)ok(xQ%Te+_8*95 z(lV$$>^~6Aq-D9%>HJ<}LuSzzQ0sg3WlDC<$NK4>O)H_cvwpf~(<-O}bJ?${X?0ZC zTwkUaQN!5!=F-}zX>5ISX<e>Na<~1Yka@H|*F4f;)Vz>Iv;kK->FCT1UQ8QHEe%;r zo1s?c%M4yZTSzSpSwd5}GRctOt=3Z7R;nFYM%$xCblGYxr=3vm6<HIqf_CLfCu^<D z;FYwy)Y6cZv=`=l&ABOL745^7MV57KM^@ARn0CDDu8=i!0H$qWX=~{qF7YH;N8gn4 zCF^Lq)V`4Qbea(Ttad7So6ba?sqM=&8+FBdX|WA-9@jiNtwv_Z2D%WnrN$wq#i&y1 z@sN#l8LGW{ifIMv!(rz`Hqq5w?0&}jnAk+up`ee6O*8`qeN1eo8@bZy)yhAGY^GaK zzgPa1X&dH*{wKE39jHNmpxs=Vw84VAAzSEsIN$D387yrd>cS|4X+LTit0!-zA8}>T znhjIQR+@=|J}tJ=&oJjyHG`!cLakN}rY}*)yjkDv^eAe2p@$*c=yB9?rg!K`u1pfr z+%t4LJuTA6uI6tA@1W<TjL;qQqEx}qo%E7aQ0Q)Yg)56d9~yh;cU<!b>xw$`U3yij zROnv%BWlO+@}VElYp6~&Dl+}dmBnk@`{@m?bXM=l4Bk&~ab=Rj=GmbA^bQK{k^AXg z%=u#T>Y*RfKe)0;R`a@{2j~M-vS$tBBl<{cdH#<msmP!9B-yiZ=*QF(1-*M@Qg4*Q zyH#i=rCjsK%#j^KKcyO1Iyu?D5c}T;2I@fnKA~CE$tCVfSv0>$<M*X3T1?89%@-;} zyH9>S^fMZPdUNtHrYO|tpj7fXjYZ96|DEr18jsqRoIwuK5~wed4W?44dm*Xh5KTfE zq3oCWv>ZxrGCK4NS^*W<WCBw~RP&T+p<mL<sD3GPn5v?_NY5aLX${n+bc3lT>Lu2@ zz!6#p)#)t<IYR59idKtt9Hk9VrK>r}QQ8O<z~1<d(Wa=9?2YdjZI1Fv%^=5VOH{E` zgDDmDexX!yg0@8+Ddfxa3JOZxN!k%L-p`k*GwP?eSnqkX8|wGBSnqkXJL)j2m7Joz zP-j`K<P=RqecnBloTmLy7rXm1y@oO>vHtStKvYmA)?XeSjJmae^?OH$q3A+`=?$(d zdW`kGc#e)lL0=!|=ol3A^>Ln#Lp2|_IP@Z&z?DvCu{+U4IvMpgs}EkJZ=t%dyT;da zI_h=ycKtP-iF%QxeM9G<nzOWT=seV8_TMfp(S@kuV+^LnsGoXgkjr!#%8_O;tw3F! zpGvanYSjJtzD#RTa0k0WGf<n^`mWFos2_Y&$+vVf>W(k#gO6@S1$W3G-_h-;7djYB zJ5g<XSB8F1_n=<$UC;C$>Q(mMf0gb-4Pfv6SLuG#b=F_y5A-9{pN$QsPf%0Krjj3N z7HUmdU#8DdHDAdfKhZBx-Cr@74x`qx-?(3+$502@o#+}pfhx-G*VpMOR0;NfbFb4g zsFsdY@-sb;>g4ccx`-;~mqC7^mr!wj22(ay7X5zE;?NuPJ4`FXmU4ssfU3!sa)bUP zauRq?{gqxv)t<N1_?6z^$|O;*Zwb9gZ(`ceGE0qH^fv0Nq@~7h^e*a)QoBNL(}!H} z)ZQ2RJM~K8wLJQRZ)WH{s-W((r_4R73GsW~J(^$Y5X)Iis&w!lG*l{yJfN{cG?dkC z9?}F<Bj=&ehqMH$3#;2aqNPzY^BoF(M3Yb_*?f;_c@$x3k7)(2Y}VXew%`+*f=Xh2 zGd-b|QFU40Ohm1Q8pQfvB5DoPyKFv(S_}0(o6n)vLDgq{GkK`>QA1eYOde_jt}N=$ zu6a+jF{&iH<~`M>T<NqMdyaXjFQaB#heEy7mZ){w@lbCy6}5}WM{R?;ntV1?QQM*J zGEucXS0<@a=~Aewc0$!--)3uS7u4>_S3@=RRn(W0?}b`wPgH5v+eUsh4RxRg4a=|g zLm7I$Fh6xDs$%&<q_8?1^_f;Ytgt!)rB)0LE256%5>LFM>KIImVe=JL$8m|cMp5-G zu5tX$w5U3rOY|IHRGo!_-sOs_b5YQ9d{K1)3VO3EsxC%B&vQl9Wl~+OV(Lm1^mJET zU4weWmRVd~FT`sX#nrb_by**E#nnwH=%dbG-HL)f>H^g5DCnauRNaMwKI+2McTvzQ zU9`Fv1-;V6sQZN+!4qP_V%3i@4f?2yQ!`P}M_s)784CKWN>C4>pvSrd^)TwPSIMwM z^%$ylsVZS5)srab&90Ps8U?-Cl~&K8pf|fR>O~avW|yR1LP2kKWz{Pv=*_O2`aKGI zvn#Luh=LyHUr?{R(pYbH71SFj=y5(-y@i5)1S_g{gdE%F*9xns-a{qSZV;BDK0v)) zvUyk~^$}|Cpf+KZRrasd*<Y69)sdaTs;Hi*w?cb_RaJdZu~qtoRZ~?|f#QS1s;dU7 zf%#@w4b_RdN5+S}sOCpSlefZZss&M-$?ULNY7x}Vd5gkotHn_*imwc-qXwdeR>%me ztA?N!vwg3phNEh;p8V>oQK$+vwuZf=#tM-?YwQkdpeCT8Kfs1+Nz|}TAA~hh%iw&& zYG;NuR?A@;^cC1dt$>2Q0-LHSm@}=@7h%oRDqQ2qqO=oX&DH9d6Z#Q+S*?k>?R7S+ zg<1y%{W-Q$>!SvEe;?LLZHR*29aGgNsMB8Gho!2`xw0L>tnbCvYD+Hh=GI1SFVqSm zW^L40r4EI*QTs~W3Tvwl7NX4uWRUjiFw}DPv}mu6Kt&gR5Y}EDi7Ly~K^-kbCd@q) z+EE?LHLt2M)e+uFO_%Zs@2pNjZSCL)@2b8f<rCgboz5lhJ>Av$T<Nsu=;{T#tBX)| zJH|S?t4mR1S*^0Wx&l?1r>#cCvA4SJ>N-?X8t83QFIMC1u5Lm#iiS08<q|D^-PP?} zu5EdrOZ<m|?&=3P-`$!<cz5*xm-rt6J=9N7&=YtMHA~FLd%EkPelF%C<JuPp@1-8X zG`NSPsfW45`qI=>A}8PXH1#YB-k{Ue3#d7x{KM1KZ%}Yt($s7e9EmjbI}{v=H1!7* z9Emjb8dnyDBax>5f@yFh($t$GjrV+<rv4_x|6_Px^>;3@oqg3uI3H|FUzJoAbqzQx zeN|5stf8;!!zGR`%gO#+ZCNfsTUKaze@ufu>SDtONI_fHU{w{%WHpu-!iT87xQ6-d zYlaV3{p9-UGZjYphBaX-Cg)?l7^<OCEm>NuRQvD|YH6wN;iJ@Kso~+1)#_3+!{@8@ zq<UJ5)uux1YYOkcrRvM5ZS5C_FI8J|Wl`wmcA4551-;xZQ`@4Tm)qrPdld9?yIk$a zl};5_r(L0TL4~k7?FzLU=7b(_SE@Zw<yb^_rP>Q~uJev{tWx`+c6d9;DzzW#c6zL1 zwK@RxINd>3s{^^RDD<PdMje8JestHU!?>=h@Eh>8>If9{Ww}-ziGp8*uT#gMpfAgH z>Nu_}3Vm6wS0|vLFU$4nBowqCWvFkVp#3OAore03y(7G>&P0(H45ryA=(l%+Iu8Z? z_HIxYaHZ3q!d8WER2QS}g=H`;MU5_Xl5A2}pr)}teK)DAP?K0Y<z{s)Y94E++^nug zeazCfs2flxSlSkK6IT{%D?drLs#{UePw-at9n5){mA`H3PSh_f;<8QMjrx(r3*J%R zLwT`d{f@d9RfzqM)a~kiRI-OJ(*dq5k`P{q>`*@zX~df=lS|a=cBr3W&PmCsEaxFE zQEqprCqx?m&)7TEQz&@9-JzaEL9d=W)C(x+4}ORG4Ocqr32tln4mBHfu-5MIo$9wT zZGZS~^{Pz!G<=WxBUcuM{y*PSuZuL+?sPc(J@tl2W4b}!S8vI*)8Tv7J5ra!KTz*U zT@OE?K9IT>o~b_K$|6?^JqgcJpJ3XRLOv0nsg5fAzC>OxbuavL)r%{OzjGZ@eK5`A z4J+c1s$v@aukSBZLu#q<rRqdMzx9VzUz~4T`+^Zi)dH9X_wwUvA+Ah9dj>`vSBpwT zM4V9lalYiT@ewE0Ae=9`><#jj8Y;ETIHg8l&N5SXho4rXFs;ngi{z{tgK0y{l!-X6 z#$npfGPTGBH30?flo!<!QoiJCwG>w-DcCbP;v2P$RP~6<YFRF*GgKp2)Jj6skHuKN zRjZ-`S&ZddwL0o1J#T!M<6iC(+{^1lT$Ok4o`su6{3r$Y@}Je3a(x{leo>p?GG~~X z!MAcO(<NAD--z3CDLo4hj`&>)mU&-oZd>L9wF6fs^<eLRkJZko{OtYjvD($Pz9(vT z)DrVh=#w04Cz^Ox!P>`1cu4guJT<~g3f4}wo_r~yjH%jdxJ+o(Q?-Fyq8(4whHzz3 z=(ktZh6@qsw^!9hh@AZQzN$77)1Vh$O&iUXPG(eQ|L0B{i|SF@m+0DfF0pn)o60qh zJ}$60!q8@LWs&W#)i4ZgwwRB<_Z!+`sg*3}Y9Si(W-4)N>re@A`Z8spf>}H(pSBSd z&*EA6w9TkY&s5^8Z9^UR^kv#E#MhT!dtb_z<kvoy%7`eS9g^A>QBXU<CE8kxXs1xn z)>=e6gMzl!qS|>Bw6zx1E~22VwU~AZ1#PXxv}`VDYuy`BT>B2yt<^_NSGmMF^4ESs zL0hZ8b{z$6tpVB%6tuMlXtz+%)*7JQ<`QkKf!bXZw6z9me{iMK_)(un1ZjVw)-^lA z^cZ!x*;h=YDqMG>%`{l^L_wQru;wkq+bKgdg)5!4Q(lM&(KIg6P8p(^n0CEKHcQKg zX%K@C(ek69^)XZ{$R*kv!?YqeU)fGSM1*O@rG8-w#GKGl7_Nn&pv5m-3&Why;uo$( zaAi9lbSzphT#J?pVv0jSYhZ+yDCXl=NQ72S>i38Ut+Ehn)q5BbsZ~R*@AW%V4KC3F z7p2wYf)+TB$T+RG$jMsZE=0s@^`z9uc&!0yb-oJ`30h+*H8MeK#wA+d615gm?MMkN z6$LGDCAGFV-&*TJL@BMklp0w|>%=8m*-C3&F>P7be350e?p&D!+T6-&JuxS=xs}t> zFy|JQv%J<%h#!{<+7KyUQb8Lf=HqQ($=X;Hw1FjS<5AECR#BUXf_AQo+7uK--79L- zxYFsmPN12X2CY{WwK*tgy{f3q$DGp(6^X2<EkrG6O3@Z`i8iT9+A@*G+N6#|RMu8X z1w~fY)^Le-rz+YyRA=^mR#hzna~@;Iv#Pd{OSB(V)wZDE+O4W>!<^85R88B?CEAaw zYdbM*ZIS568rmLAgVv;)+WS(=^VifqkZK%SOFMvq)}%Vx$6WJB?;7Pp>u8x=>11y- zq-Al5dR86nph)BAsE&4Aiv8b5?VJ#WV_jFfh=LZ5y4p9WZmd>WPs>IPV71D6+P7S+ zR>|5J>T6d~(8lnR_9F_~7#eEValY8sVjT^&8>p1m9HgOk69w`4M%rx@#OE7nzoX#1 zH`e|@?daso^ngp$keX-@Q4p1GqCMdfQR$|dqZ(m<Sp=fe%``6*#G#vO8kdMcw9xWP zm5ywo6_d({XsLxtC6QDuR)|HHFGRG_5>Sntr6b#DB~V>hxoxYJM$ODuI<l>nggVLQ zYp0b*5ti0YtH33q%dcoDD2Oh<qOoo+*k85^(dG79H55db+iNvY5MAz|)j~mZxr0^* z1<~b>T748mmpf_=xFCXjA)=Gk7&Y4}9ob21idv^ti0rI2N9|(jqP0L>O|BZ*RcnR1 z%hXL{-HounOaf8jSG9I1h!XeGI*6Pkp?dAezFKFgMv<>+-7qIaf?wCVqaYGIQ0vJh zuH->l8keX+4AKU2iD>U2Z3qgYy@RyjD2VnB(%wWtw0Dp;8U@kbLE1Q}uGU~}0t%wN zL$t{#i1rTArV8<B?+|S|3ZlJ3v{@*K_72tNq9EEkOk040XzxgEF$$u+qqJpQ>Es2k z7Lnt%m6!&x-*jya3Sz$#wDnw>WMap5krTBIm<F-mN!n%<#C|7h+fY!~pQ7zRLF{*m zwi^ZU-M6&&P!Qjps_jETe0Q4mAqwKV)3uLL5Z|4leTstk?o91-6vTIDX<wiqYCBsy zf`VA(Z0$H#I)Uiq9PKMigXrX3?F<T{lk>FmD2PDL*S<zU%yEHs83j?s1=_b<q7*OC zt_zW&V`>-+v>ROW$oPI;A{S`4P_z4`MK09taEWVaq4rSBM<Ft_P<w*v*C*DoQ1hq` z*L6CNL@m_3QPra%C*=}RqlKEz<yvL|E)kPks1?Hb?$#W@)?SoL#N-xf{wRpaEz*L- zd^{$%NDC43v6$Sj$R%1Brop*grbTjz^)1s9xw5Dq`>n|`t(2IL&KWf}a+#JS(s;yd znO4p=-wLg=NaJ6FuF$HX;A_wo+KVXo8gzwL8wFp3uF&eC;A_woS_2e(|G7eIjDqh! zS7^<+#CERK+Hj@w?Odt7f`aW_sdYrbd044+K|zFWrS>Y9IMypQI47<MolEczG%0d5 zra^>mX5?Bacn5l0>nWDWpN1Q>*QAz5ZqSBFt&iNKjgi_GxmBAi^-1J=+AOKlk)LRb zq<UJPX{)$IH0_|a76s9?gW7r&MAHsw8&D8UJEUzwLB#9}Z7T{QW?yLUaHZ3oVV5Jn z)OMmi4!g><8*@Tb?6CG83Zi0%wY^*-Dt1KMkAkS!5$ym9qGCt2Pf!pQJF0!kC8A=- zw9iox6+5OKLP1pQxONx?QL*FNQ4~bQPG~1k5EVP2eT9Ok*h%dS3Zh~swR0$lQhlXe zbj`=2R9|V|2=R#0DeW>B`-Ug15ILn?;S$e>Q`+~K6Cz5dv>&;|Rd-6eDbjdE>6CUG z1reoF+FcYxlul{)Q4mo&r9I?=h|({Sr?e-igSGBNp4J>S#GT=8&4-a^H80e`TAoqo zG#@SzQM#b1B8|n6^r#D(A<}q6>7wS8X?{^(Yx$)Dqb_L$rDCG4Xho#TMqSm4bBT!3 zk6HkxT`5#4>L)D-^?IqYQP;Fk%n7adKWpKb=J7_&sGqecOoNEhFIueBQsah}fP#q9 zuUZM5Z(RGAqHbxWFb(cRx3wfL5mCCWm6wW$xT7WGe92{Bj{04zg!4f}>8@5)YMXIS ztARPoOuZBNhgK8QAfog@tBq+x%e0MpsMW<Zh$ubM>Z2f{^jK>k#eOrQHR2KxC89Tx zsvhB?H{%k|4lli}lpgG*ca_Q??5+0^;%^~}-X8_EQAHoXl||sYbgB=M^Cc3hkF?FF z>SJv4sropa558H~^a*ml4iTC@8*|PuFGN_n{a)u1-0M0=<-;_%*Y%3ZF9r9yLi#-0 zG7IagxJ0z6xV{zz(Wc`1dfWQ^^$n;cX6Z=(9BU7dYv@~eXjG6?&%&dlLZo2r5&9;v z6n>|T)OT`;(io}l!!<yZBU1m6OT;xI^^dtk>?u<JROBR&Yad}bKbH!MjMTpnIeA<v zN<Yjc`k{-`k763crK0uYVm`ht(fT<l_6rg{TWWe#jQ*3<{HQqn7MF<dB<goi5aCJG z@1h{WQ$oLwf(TCu{ZAA`cuMMzQ4rxNsgoDQU88ENRZ*pMPgJ*78BE?>;z*R%DGDMy zrF9Jj5uP%-iGm1E89g5gB0OdE{9Gc!lcX0!L4+qsFU$oIo~==3^<t=X&2}*bpbj_N z%M^t3!B_F+^iUK;c*^PFLOjA#UXSDwF`e>y3|Bh2-s9t_@_Ia`!FzFeJrM;lofq^{ zTq34ZK~KW@%69rZs)Al#>IhRZ=7g9|vR(-VF`Z<+3g(2EPO@H&OFR*h^%q4NKkv!< zOH!w!lJ(|7EN=64R7JfdYJIQMOsQNVZj++7;exo$w^3E~b|NQ>+gyvPrgxCK$<!IO zI^VUZ>UuY+n@l~pMBJu^-dn02c~S3+g1Ajh{WY9#t#vJ`mOfDGCesiu5x1$W5684+ zUGGKJ(ck0}ahrPjD9j0QoBH}#%(;c-d`V9i;>V?-K26G(G}Pyb`FPx>k-iWGahpc^ zVv&<V+@`U<45iF)kjDB7%n4DPCi-d=L>8Lp>oDiZ-k`TJ4Wc+r^i3#;;xy5>V$SJ> zo<ud#-$5;BYO3$x5>cFH`ficNqBy&vn(OaL`9wF@_i>3R&dd6K6hv`a=m#+8F?MuY z=$~+jC{7DK3k6qe3;lD<2~nJu`XMe6#c8E~iGsLIs(w^zdHz)WgjD0u*7_+F#BJK@ zXShV%rmcRCOI)pO^^08MdDK?_PRf_f_p=a%BiK&=74=PTU#45Avh7pJEBYN&rS`r| zcezBQroDb21(BK#`kyF>)O6Ax3-NZRPCBUxcd0A_QI$@*Cko;yopm1+#8JBF2AA0C zZn~e8GrF7ZFEu^tRXtoPiS*Fpg;*TrT2wE+1geqK8Qn`Sh3dk}QExp7H8Y<xy0=~q zb&}1OrdL1_mX@Yh<Pvd|K6+&o#8LX_RZ$Q}>8sa3K^UK0gzlzw_06vR>b>Ge<$ zN9nIOKtUX(zut%o;waamUelYRW?Rna*YxJ7by}h50eTD6E~eM@R;a7V0nr2X)~LHo zgY>psB91axZ;ygF%5c3C3SuQA^)4ugm5kE6afxebwBCbDJa0$q{kcS}WVHS|3SuRr z^}#5Jm5kPhp&(W=S|5ReSjlL8lvG!1j6N0xv68WRx)6_!jMXP{iD&UxeKMxiWwDZR z`cxFeO2+FmP!KCg*Jq<3Rx(AOhk{tiTlzv2L`P=oOSsa>(kP|CEPXkqL9Ar9z6u4= zkvaNW6huen>KQ1gx6acyq98glPv3%q=*WEi9TY@I7U(-s5FJ^l??FLyWRd<p3Zf&6 z^$$=G9a*9uKtXh5ss0HHq9e=nEEGgXmgxt%(n(fmX4rE5OH704$O`=^3Zf$`^%E$F zj;zv8p&&Z4T0e_|=*VjQ0++Z7R_ot#rSmAqYW*q-q8zLBpHT3wy;}bn1yPRG`mbE# z&3m=}8<%UD54c2>W3~PW=et`oJbJZGYQa53L^;;zo+yZNtkHeA#D7^|qf;*UFY9s9 z>vRp%;2dS>CYM-WhF(zQWO0q8=nTCGm-tF3LoY7GqZ}D}fNj1FdW1;hQH~9IGzy{| z8}v97L^(F-i71G2Y|z;&D8COvlw*UQgn}r?2E9BAq8uCaWG=Ct8};g3>3lmk>NQai z*Vw4n!TI1lbtBfA`Tf&$32OJr(VJzBx@Y0)(OadUe!WAlFP6!l;XCzaQjMc`>TRT2 zMeo)-OLdHXPwyr5dh{py0I3PlhxOr7J+0&VSS}ICIH{+jAd+!XpNN7;##j0j6htz< z(x;*zl5t9(fr3cJDSZ|fYu^l?8GTxxi)s))pJ_hkgh<92eGv*G8E5n*Tq2TjR$q>S zNXA)xB?=-L=kzrwh-948*KvtR#(Dj16ht!4>l;xJ$+)0zK|v(rg1!v}k&KJ_4irQ( zF6z5b5Xtyje-{OjjIZ_gQ4q=aM*qMyAG?gc(LWU8k&H|FM_lQoHTyQ^lKu%-HvjeE zB|Qss!WD8!KgcDntV{ZFk;Wq#m-Met5XrctpFu$+<C1<J1(A$P`qx|#$ygSBNxzIb zSZi(cW&Mgw+Z=sG|6Zo;jQ&>tflEX(zSpmbG#0zq7yZ5di%8><jH~)hnf7V)5BhDX zqtQR<ccsop|E%Aax*B~`f5;^w8Nca|G3`pB8_~CQQX9%&I{P-}YV;l5lS{Px+||7? z&Et)`(RX!<X%NY{r|VKnjX!h?1(A&VdOn<QT>D4Sf9m-$4emCN^nzR>lJQ6{A{7zw zSTBzAC71Pyd7=m6d=SYXMu^ll!(oJD&N5TiMtc~Mm<EvyFC!Y$hL$m7e2iF3gGh#A z#G@dRL5)NyU!oc%xkMyGGfGQUk1&iRE>Q=wj7m~^uw~Se${*}B8gYr=)cYDuP!PND zGn&hsiNw!nhiMR>C}?z$X&oX88oh<+4D(u4Q3KA9D;Db#+`;@}iennYC;Vdqq~Hz~ zV)V5wGt?N)CE^p2#+xXJPedA{Z0n0M#-f&(&S+Lqx2-)|uAy(?*qB(Uo`p-t#7n{2 zOB&<(QbegLWlY6o^0#th2A6mbFJ;W;5)p|~#ylY&btq*l5IOnRFr|z|m<CaY(#8@l z(Gx&vV~teRn9{~3u5@~`S_Ua&Y(@QA&0u;5^&R^?P?E6|<-v9?$=Hp`>XSjr8t<Vl z_c56EqRzCg9aGNOkGj^n0n-7lt7>-BH~h*QpP(Kz9mDh~%D?F(zZZ<pQAtgwGacf} zQo9VyAQg<msBr@grlVZh>bAl2{F03mT<P@S;N~&O#wpaOKCPL~pr$cZG|q8lR!bb- zF($>hDCD@n=1Vay3Gw5ZVq|k=ITETb@vCHfhdC3fzZz57_(5twObz3j)EhB1jbCuS zg&wQ?>KZpOZK21+nEJ+TsrfODjJue#|ESG=O^y3p<A^aNgETcBV$S7#*2FY59&@FW z;%y3%W(KJP*IkxFXa9k=nc<0g)EeZ&mFf6(Fi6F;qR~tIni&R{D5=d2KdB_r-0<hR zss`3gB`u5~RLQ!&Od%+ER<$(3QShv4X+(0RlXshLjA>=WaLr?SH>Qmd&n2EK9gGrO zq9)hDC@tpWHHZ#IGMA{ybucQ4H1@RkET)4|6?L%Ik(iD~b(wZLrn6B~rhOgL#i-3C z>U`addMK##bu${E_ONGFH={ACA$wMJGn%1xu{VuwMhn!$S{KQyMk`bt``Vy~(FPUI z-eG$h?YOQw;OorZMhC8R_B{GNCe7%Kf^RPS8eOG+iRov&it|BCyuZ-{1<#KDMsKO5 z#%o4j6g)cy82!1Rruuu#Kw|*vjk>2}1{;I8=8=U>AIA(ahN7z1(PM`jZ*X08z*A<l zF%kvOj?u;#scps>V?0+nsa|)RG1i!fDl_#+%s68*=7c9ny73mK4J{KCJJFbiY49YO zWXwRplVq|nOUjo_G3Ib(J6`um^Lxvfk7`+Wpx-oO5tq0=ryHxJlE`#pgH&YfOk=wc z?K7lg>>Ohk*Hsn%GyNRnT@?Ih`Z>n?DEQCxbBzyB@So}D8Xt0HtIgT}x1VQx%$3fL zV7b_N#;2(2b*jcLFg{0hXxb!psquxFkJp!$8%Marb-mm;E^_kgdbx3qOI+8>jf*0U zUDs`5mm8N*2WxeTU14O)w4Sl6jPGPx|Jc>WRW5N|uQh%`!F9dX_!$M)^;+Xs6kOM9 zjo(mkU9UBMN5OTy&bWtq{9;!t!+3ytQnRP^w(*clT-O_oCtPq{4~^Yqc+`b^PdfjW zc#GjBH9B^y;lp*+0oV05gQDQN-e%}hOO1C73kBEpb|W7bT-TFgcN+OoSw(xs?luZy zPPlgW7)7||k>O2e#qKeRV;Wq^dyPP;ZN@$$ge#p)E4t12zz9c`nc69KzY&Q!;YvPW zL}S{}GAm*~HexXiuH;XQcoba8nMR_NFZt9c$(8MR$){<-ETar+RngW3KR3#8iKp*D z{_JP>YZLm#aSI~(Zb2mfkjx2@e77Ky|AkD0Nd6Z_WxfXZR`a`{FO6!bZY)~=CFaaD zp<kTCQV_{^3nKYPWEw>B-GWHIOIarLi*r=29U}QhjT*SV_)*=0j~TVNvehRoulgM` z>Y^I8`kARds^F;Ge#ec5sOin_Gc`f&ZuW$!85jH7j%~{cqXp_P+m;h@?a&@@QVQAw zq`aYLny*}Y<PCk%d}Xu}OJVH+Ah>ebS3=&<0`Qg5hNopZpih}ou4Q^dpE75RS8%?u z-s@w}7#+E?9MHqe8KVoPmF=`G_N?)$)Ro|~Mo(0E@7=NIj5Mi_nEFXw3qEfQkUA23 zQLY`@7``?JVVdrJG4^X?C>ML$v;JnjmN}vQ;Tz)(o|f(Ssz-r>-xwoN@J;DA#u%v} zrtw_jio9e@<;qf_7nw`O3>5StbIF*6f?i}U8*@?6i_B$XJ}SA*_p#Z=B2<Gm*O-=Y zK@T%GgRU6MQR{o{3b|se#GI?<uwTj>Yf#X`%(uom6!b9jo$)pbdYJjn*ocB2X1+JJ zprD7D?~QF-=`><6`=z|G166J?`=z`*)6o0O55_K@CL)5@jXfeKYeP93^t184)XmtR zjSo<(^PLU)#W)~!Gxis`Oz3^)hE46ruTs#4a?|*P&zI?d-e+zZS-6z7tjDw8jDu1) zV}CQg#GKIk%x&W+SC#{MpSfe4Kuz%|M1D8E;u=T3>KYpMyIdc9C41L6jX9yU<(_d) z<m6AFKQJdN#jH0Nx1dGk4<lR5r$UR$eVG&5P~3txl>5eaJZGi~J-)cppbf<>XhXSg z{D8~6Ug%!zed8z8pG*(rRzvSBe;U_$S~_b(=^gygxFO{k`p~s4-p~WfBPnP@d2HOm zoX~^ZW4TP|N#(I|N372Qy`?-h?xLWb<cV=#YI*)A#zU#bp~QT`mFchwKaTY<#eE{n z8(K{~O-DU&I&pY=$9bAwTv-n2NyXDtxUwCKo8R~IGBv6Af?lSH+RbA3-ex{7QMd6n zi%7Bl9L-=M*3VQ1@iD_tVaWzl1PacdVn(Cj{3&KESC;x6i=|UD0R_<*YL?`>szNk| znq@EzzL}+FITW<SsOAeOXo=Cyid>?up_`RaP}k7SYN#_cQyr`k7`36+D-Oe~#g(N( zzYdmJmka6)JuS<u&oz%UOVi`>nGK};;tH6J#C*KYP}pq3HJ(%&&3>nEHp4V%2P$l~ zK(%Tg7+1th<;rwG4-iGoHkbx&M8(WkP|yQJakC>=wxcVnYxtX;QSbY_;s`XmqP`t| zn*^KPQQi7=afFz?P&Z1~A|YlPssgKrgqr<ORR?t<q2>V8Iu<(&H3y;Uv0iIJ&7r6| zy}L8Lfx0uf57S80zJ;$djX`<zAI3BuHGa%!5@t@6n!q##_2+<@B;1@PHJ@oF>Sp(q zB*L7-CF-V;=6oRsw4FtoOS!}oA=+FkwJRjr+{~5E+Q-fY#hBYrjhqp2G3Iuz@w8`J zd|a%#3pFOK6w@Be*@fLd<IML_GxJ5n#hLq1C)qON%@0w8rNx^caf!CG1Tzx_ZD$E) z77E(V63v4sXgf<Zzd%9TSqbw93fj&}n8#4ic2?3niGsGXlIAI{EERgVC}o~SK@S(D z%=28(u68!4wD~n^wiOXq+PuV->42Up%9vMB&{IW{`5g+rK~6G%KtbEt3+6Q;5m_*Q z#x&@+qLTS57yH#B#2L)rxY++ztzJH^viUpaOsHNpuDbb$Olufd$NW?3v;6hU$1>;3 zarI3{eYj_3ve-q3xQ3<|7c8?+Tr*SQ$|4Y-XkluYbD_uJxK^f#Ia#zKuAP}rYEE1S zvw+OGEUuGT2nD@ubTf;hptp_gW++z{fw)F5GXm3~?~Pt&6bf1qdzmpPXhrO8#&L;w zL7JI}Y0&pZnpu)7ofM7U9G7O6!L*{$JLCG8<+!p~+7iEhW(AqEVO)PRMe4Ks1I#L1 z;+lWmtSz-a?sc<~)TeO+&6ZMn@F26jRQ}+>=Br$+bmY$<L(QJ33i%DD-dtHMCQvMR znAu0n$J@0>nEgZ=|5|H=Ie;s(n(p^y+z4|JrZuQ>f@uiqhw<m)-ZY1!3YEPQH`08Q z>#C!io<T;LqcQE}8b8I2GRL9L)jh{FfeZFFk&HHHaEYxRW6nmwR*x~~qTner)?9#s zr_5M$5o%M~uW{qdrKr!+erH;aIy@qkj5k-IvPbwbtq~&C*i$XtT#x#F1ZV@7I1lNr z=dIbZGW$=tQqV%|7PJt%1uevGK?|{6U9AanDbPYZ(cI40m!-nj^b^fpLJp`;Of>g! zU3I*{^&VFylflxU6tOoq@4Bq@c#;&f9#58n*5fHs(0V*W3R;h6ntS;&;Y<5=k@I94 zv?b4%g4W{&=6+l|d}+T>ra@csA}MG~UMvOg#Y?21EqRIg5w7pD*TcA_W+qpb1NvN9 zW`2f(K37)A`JmN#r4+O}uabgR=hafs>byn@TAkNQL96pRDQI<GZyv(+L7yub=3$h^ zT9)57kD;K?l?~=e6tquoG*6?T-;s@Snb2Cj$vlT?(C^4*nFg)ZTcn`1daD$)R&O&e z^7+!qZ7&-Cj(G`}0)2~YmpP#&d#8B?a}My%AHUQ59&<uZBRgeIXyx8z{)jnGd*zSc zWnRae(C^4D^9ENo?{{Rkd5cS2^Lt!NG2tqA3$A3lx?1nLa`J2NJt?>b-<N`GaIX|x zg9oJG8vMw-&)0s{@dE1uB}=BkHTannT!WvR4|&c^2V8>(Wg1+Ahos;d{6Y$@x-X^R zS~@HR*U}LwxR#De!L@Wu3a+K&QgAJukb-OJq!e5QUrE7vKP3g{{j?OE_cP`bJP%M? zJ8OEp1Z6tg0kyTWrZ);|YiCW0g4)_yQ%6B<?W}2`ptg3_^hH5!?X2mCg4)_Sv#`_z zreY|lt(`Xmq~<dPqoB5S!3^UPSI9-V5AeI>i)I{8gZBq5=%QIhs(Ad@W<{x^zL(4z zQep9z&H7wd)t4rpBv;IaLXPn>GMJj6en~IH)Qn54{fgN}s)pl=*;$Icm7Be!b{XHB z1Eg*S{9q23Dnx#A?Sl!ud$<Ly_-;Wf{xz8sTJhb2R{ZNS4O;Qtf|mN9Wg4{9|7?!s zYtQ06ar|PYqoAe!7jq&CTIz3@Q&7-Se?u+>dgAz13R>#jg4U0lG7VZk+=7<+TQUt= z>Tj7-aShN?|C>1j1ugZznX|aERUg)4$Zc~jsubJK+va@KLbjcE%tfdJY&-ABH9!mh z?^4jChLkt-esR}a!siob^RCPZZ;E%#H9Rd#g*U~!=6V#oDc&_VprGCUuDO{D+U)}) z?wZ?B2Wurq+%vb!w1|lN<}R65J>r2}AM|PQ(A>k*vQ>yfKQ!M*K^*##xet}f-b|mE zAEH{bH&bFkIfbV$w6AzbL5qr~6vUdnq#)L8*HXh<ra`RPM+%;s6qV@>y;0Z|5uwVQ z5M9=6VzF!~h#(tM5Hq%<AZF~e$(Q6qWqLy&6TUW8k0@Y$#P?l92nt#Uxw0I=(Q)ww ztuMLek<JUs#22xSN~OdXwN6OA7+=gfg}OAbetdE3ESFejaqBXdSY~nSTP|^h1X|Zc znhL%22U<5UC&X9+ty?JgVkywNgMu%X0<C)}_+ly0dVqp2mIAFuDCng>&>{`^*>pfG zHqi1!!S_pnmJb(fr$K@&ONe$^m_dRqUoNqo!B$aBgSdCF>j?5lw@X<j^c)dv`SYCF zYDBB6elpD)`jH5>f_R#!^95TWT%ykB&I#@4Ay$}JAKS7H5g}Hb5c~F^Y{3XC5jAJj zp9LbUQmEyl9DWg285Gn%Bdv0%*Jt^fkyZs%71qyeq?Ll28__sE(yD@5Hns&*b=2Eq z+cLd~+Eu=De3VsNi1?1{lP}7uE0yGow(1M<t&X*tab>E|*GHn&0tH_;BwDRRPQFJa ztTw16CVPXn+M!_oN?ILIuzw}3PAJ%;QdU<K>_aK5I|}xpl+_Cb`%ubCL%}|jmZhV* zPY;`h$MlOYWA)=X#Wxa3))1~N{(W7NHO!V)&KkotkDA4fhm^C%qy7jT9AD0wh)SF} zf@umWe&JZAX<TsCO=6nIm8C+Bth}`l1vRqr))J|%)(h5hAxB;IR#3rOg@PJcvb7ck zHL{9U1`29qRjrLEsF78(wxFO6R?B(^1$D66)=t-a6Jo;ZSbI=V2ditnkAgZ_J?jG$ z)WPao2T)K4d&&9)1$D3nRu&5CU=6K<D5!%qvc5z?9jvi+6a{s#Ce{fQ)WMosr%=!r zVl(S33i?89Ze2h@Ux+VT-=Lr`#1>XI3i?89X?=%+z7ShkKcJv5#8m4V3i?89ZT*5; z#`dp`brS_WBeu0}qo8NRcGg`K^o;n5bsq&iBeu65qWXKzjPGDQK|w!>9W9TB;=Tm^ zBzCgAQP59fXN#hspTsVfj)Hy?yIK|s`bq3&`J$k1`l{uJf?peVw+f@6rrN_QhJu=E zPb&ZgHPv2LFsga&1@XPDP}FB7m&Nz7!ci9ot%>hvMWUiRZiydgMWZH;+!;UEibcI2 zx<CF6D;`yPLRS2nRwAlmbq5(`l|;3vawLAVRT@>b`04nuRuU>={Kfe3RykBJ^Gf^# z>jhL1$F=xLRx+vysa#}=m4Z4=ZpKfwDx*G}e>Z-*RTWjS_T%`OR&~_Ql0FHutrt<B z4YCsETD4FEMixq#Z`DC94h>9LXw^f#P$e>9vGo!vxOig1QmY}Vm02!fxz!lu>8PBr z(rSuIBDE4$Tg_4Lk%kFttrn;Q^I9aVw_2e(7k?$;ZL2jZy+XHyjaFM!jT(ItHe0Wt zmL&gdZM8bMa@HP{@Q&39b*9usvcu|v>c`IeF6&h;d^faua*5~k9_uwB`b(t@vd0>T zdQ!<?8jOOP@w?VA6x590wcbGOV^PibtdXeCSyb~qYcwjXUaaGNYaFU!JqLN;N=NN3 z9P8L?O+tNL*g^JMQ-s((vJly4&BnCXN57e{&zgrCJ9-?`0@R3rRPuqf7&SY<muV?# zi&qBOZ>>Om?8W-Kw^pG_voFp*wAP}kviQq~)_T-g|5S3o+JMUT_hs6Inl*Y#!bjFt z)cVmgnchLY)jE}YZ0$s?Xzk0iTZrvZ%kWRE{Zb1OKDDx>)+Kyl9g*6WaMU_2bs*u4 z^^MfQg!9%_sj~^$)(xp^2|rnPr92XUw;oG56CYSUjo{t`=RGvh(`iX1BvNM~smh7I z&OoWUiGI#Vsh1OrI1`0vP4-_WgPo;N@Xi(NOhWCL%j#0j@~Cy*=Z#=zGS@s>bM~u= z!OlvUR=hH#RYk#(4|di-K@W$)&RQsVlL~g$MIGwWi!J3PRB+W;N3gRI3VIw2b~Z)% zhFxcCco_w~3I;n{q1v(dOR%#I3VH_&cD{mw{s4oW9Z}E&V6d}`5GgvnKU@2&QiBph zoIRz6Cx$xHq{bwMIr~XXNDOxlkeZel;T$A2KQYodRBA<Hl=BU#w-ckCBc-+{#yH1F z?M;kzj+e?zjB`$uI-D5qoFa8PF~K=a>QZ8&bEedfi6xwKq;4gabk3K0kXXvONXoNB zY3EWYqeL0!3aNr6lANoh0!x&2u9J!?QO^0cRLK(Motva8lz73pRjP7{3eN3PwM!&B zcS)5lP|^9W)Jr8&oO`8G9hIE>rJ9te?EFZo9jW5Xlxk6;s`E3hd1QU5_9d!04~aB> z@2TNDAw-8(&mc9Nr%-dM8%$?Vm-}Uq7oF!(H`v?6i_VLvwd`xxn$An8oz)DcY%Wp9 ztmXU()4GhwAhn!73z2=S5B6Hl8>p;&ua>CoyeZYEL>=dEQmpSH=N;5&vk<B0yo)+8 z>(vtVoPVGkQ(rAn-}yj@@83&KkH-97K%vCF<n%_tz3wHaBE)kxa5^z<)#Oytz?mPl zX|gYq9}1Sz&{-G-OKIpVidvVRN*X!+QSYR)UspN<xx|rZ?2N>;66_77u`>o$)oWmh z#?E+DNVDNgC4@-pI+v}+&eB3`J4csj;!MVzo5xKo(bQQ9b!#B|zSUV3Wezf!s-uPv zXJ4&4YocZiH<)UpmUPJ=&7Jj7JGvN5FQKZkH^rBojZjS&8ca=4msw1wg|j*8CX4B` zaJE3fQEKT-MZr;O>1-p!_o0=uGp4~lq&mBy%Cq)|RA&!VUCm(Xg@UJcYiA!6JhfXp z`=MZ4+BgTGU|ZTa2clqG+B%1zU|ZTchoS1TXKFj=2visLOl{{R#6dnuhhgUqFg!Mg z5D(%P1mDA_IbcdeC=4$bgyBJN7*6W%p6<u~XRU+$#(p2}AQL;mFofq{&d2rAFl8iP zem%Bi*V4pvF`PTaHQj^2*D9W5`aJiPy?n|BHWc%Ekk8+EI?rxCWepoTNUO0hbT89E zM$d&k5^ERJH-|i(N2E4pN5F$Ln+d5y$H8!WA(&FM9gGiR$3zT0$lS1;<DR5HKPHez zq>3qC<cA2zY2V-f#`p{J7&=HwRaj%S*{~(zc-q&vdpt~U?hAS5c7btm2HoSH1o{y6 zB9PNTKAZ@{yv`jgKj)DV`zwwEjC&GzCOi09bMWnPT?6*>VqcCJ7gt?g=LOD=>%4ry zkNHx5o%Cd1nL5bRQ@lu7epQI+Bly+QfL|?7Psy3{r9jyJDh1$Zd>TNAHz~r#eaN2I z2~o&8Hl(DS;a;Q24>`Sf9&et<2lLp^g8h8ub!=geJc!sM*k%tRws~R`SR))C4`Scz zr>D5~MNGHv_0v;aImMFOjDY34*OIdYiRp0M9Hb<_>cr5VU+j^XGLT(kuJaCO)&t9e z7=M@5W7+=$;dcfYx>CisNVS(caSX-PB~tB2Rjd()9z>*y?G$HOOc7U?Sfg0-v&{7@ zdF;#2y?0_=VtVPmuD$jkVqENz7#Cak(=5mXLk~O`qC|h)9H##}r5KjuAj1a3a1p=L z4&wK^iXCBH;@sKGrah0CS8Pe=k+1|YMa<QJFByie^Voh7<bk1UN+7>-@;YlTOosgS zvnHkt=nB)l+5N;prVersC-M7OW7~b(J?;sGm*tP<cYFI9|NZf*tn9NMBW&vx&%1Jb z+d}yB&Yo%?7kQwc6c3Wdo=pw{^SZ`Iv3rhd+&<mD1Tnot8`!~)d`s+8>UV?tPwwer zN_Bp&Vdz0#8~{srsVQuOct*oeOczsf=6S0a<b+|)>EdoC%81AVcNliQ*glG(2f4uO z53rrC{S{MSe_0HP?{!{z#B#*EBENe%VrdT2r>AROIoBwr!_c)2x!0IGkA2HW_l70g z^N1<-<>Zw|+-c9{hvN+O3NNy{KRib^vSs>^ChXa&kbVW=IZ}_6CY2oL#|NI9q8{SO z^Lz39-aNk#&#&<O6!ZVd>nHXrq%A+HFl5hqw*3Eo4dmZ1Q@NJ_H3ttewij%FUL{N1 zf85uD2Z3_oy2eBqff6C^cpl^pcFnuSMb4+M>c6_eeR(ZcJj+CVNeso6FYeg(>3=_- z*Y%v&bg_33D`NkjjtxCX%Cwy0o+O6fc|=Zet=g~QFZq2QrnpLhd)$+VRQna~p5n?6 zsbbuf-+ujz{4m9p-#zZi|4)~nd;4=QA@?@q&U3m59IJoli7D=8qAdS?X|mt_?D@sL zH?LIt(^llkU4HYLS3G%V@Y=%j?V~t8;)#~R-yOvMigEYQgEW~9_p$u!S?ooMvf7$A zX;m4H?LW(7&;L)xb8nTX!?@S(s?~@o;)ub}gA8T&5KrP{rN)c+#K1P^zT1c?6WBif zRjQZ{Lsv~EuO-;0yWgsE)}qB(ga4}QAbt6{6Sb_|L;DiMUB$k9F%C=1xm9BM_S)C) zsjx0l6BBC@sZ;rzQIXM*DuxQL103Y_3j1{k(>;lp-qjECi#mgSd&GKkZ;!|$&WP9x z`+nK4fBVw@{k^mAmwk=7*J9s7am~2bF5Z7#M_3#adu`c14iN)a+~DKxImbQ8F@Chg zl3}l1S49<e1|8&eR+?P#hsL(LW$swSzmp2(-2?0Y_T%t;caOZ@QX$5Y^ZiszvA>6k zDfYK)c(ZoBHJ9>-+R?+}P&+!wh7MxS4>`T~`?WWLoIX6Kf;sK`CC0@yZ=as~T78kd zn|P2e{0#-h9XZCu6#EkFb><3TkUw{cu;;grPYQ<oFmzp4?kQrrgTQ}_az#tTxO>Rr zHWS=;<92M^bvL%>Y4R`gxYpvH>z_;!_hkFL;+`y~*!MTD@!!&5A4TfyYA}8!&^;xu zx$M*bzAV_w=HKW1`&9cHb6+{vS<J_SRODL@<BlBTVv4w{JRT3J&sWy|ehZ&H_1Sag zzVl3thCMyQhR?efVQ)SEy!I^@cUpTS(4Lxm%f-9xJ^n5>i}i%zilK>dzv(c=z6AT7 zTttBFsiMv=;yGh@?Hc0JBF^bS#1v5j6gl1Fo;gy*Tq0FOw(ax6)7F)L26=i5bMK>l zo9(p)am7|)PaF@@Z4oTTem&c#+s8#75zVkq|4)uP2rNwuUEB8b^8Y^7HJAO}C$GKx z`|1CgJ$<&V{p)?SAB}%H?m7;Cz2v-7?bCCw(UmH$H2V>@uSFbH`;@%K^E&?a{36eP z=3Kb8-@g2($Di+f<+bG8$MD&w{QWZXN`02;IrmYVP5W`k>&(Ktp6gyA=IYF96s)a~ z4PEsX`}wk;Uy%ov;7L6BJL3?3=NEbG_tHr$CgzH;<u#XmOLA|6xLW>uYZptlhQnUp z8wOi@o7d0bzlnO1YWxoN^b{|W&SQNoN<!^4*7vXG%AH3c5zm~n7|$urW9m#;zWoT; z&###NpDI&gUH0X}xcxf+t7}qh!_#y9RZfvdti^t<iYfMMwQW5(BR>>|v#_f)yb<JM zPf2gW9-Hi#vyEbJ5SQ4{L2~D;JH~y)zTh=&`_X%;y=#wLTL@D;NIN!{Cn?2`yvXzP zTpk2|b?r&|@wii7`zz)WOZZQn7x84zYmHA&x1X=P#$EgVJoDzf=RCcHyq0XA?rMb> zM}B7qI3r^GNNd-4&b8RD4SUYq*Pi{X<+W`h&;ORQV?Q$X@x0DmUeoRK{?l>S8L=NR z`!U~J3Cc)ub}#ZIXL(HN=_y{k<-(gxPjZ(&`?-Moya#{2coKMCc=4|hSj#()+Wmd1 zh^H-{2uof((UT3I&hL71IqSIBo;#0yd*Hv*J4kCU*s6hS=t-7(!&a?g?-Abo+X)|1 zwJh9cASWfSu{(*%-`q7an2qb?AiuYW`<Q*n_G9?py3%rA19_eCoaM;AZT4}o7xptQ zw%nd4ukpP0-JbuybsYY^y|!=R-;L)!+RrlO@3-yQ&da~vD*IagRVlVF?f;!$_fz#* z&Za$&{g~Uw?Roy+`L!RJe>(o}A3ggTbDx*Irr77QkN?yB_IdLf&%KZTy!_hly}3)Y zJ=I?J?c*ZP|CYMYKRwQQ<+o4I>-ay*^nZ0ma>wOzPs!^n<Td?&``O9sxY>{S-;d|D zglC!lug*xM2{pP|Z$gc(A*<Ip$kS82$cch~JsqN{-n@4DS97^jeQ*h4`7re0YhnL6 zSdM%0Z4k%7wO_DRdB4m5PoMX{KS$4=>e@T|_QQD2eSbRDHJ824nY-+WmeU2SW-i)Z zT`jO81}>uOog*OCJ?=>^k9SX5Qvj}n^{+wQ{tebj>rEiPPmVmDd7l5?cU<<8F7CAU z$k_9>8I|Pi{xI|)hxpY#q&e*M5dQ4}48`=E*PDGya*vC1A-*IOZTg~Z%gNu-M5=q} zL3Z)h7W<cnVoL6L-OFL|96pzrBF1wsb6yqL{;O>0AY$BL-xxc{0``9Anl8r0^xXR* zrik{DSueo6=V!ybKeM50+`ddPJ@+zmf5QOF%o!sUYY}g<_rqcNVjPAZq%nJ=6z7Gt z?ea4v+D63}znl4+^|@Mbm7eFN#y%y1w?Nsa{I~P0m;qZ0Lk}XZG50uo_vhEx(^I_2 z$rP9?ue0!c)8W?&9%K|R%YQxYNyL#9LwlZ_5d+vZ5j}9{cU`^W3Up6rzj<LT*Ev%~ z9x<fs3(sfU(@_3pT_twCvHK6Z=XjCHQ84dL7RqG*iE*HNc%NVAlY(K282^bq#awwr z{-IrAidg$_K5j4R`S}u_?>G<Vt@EvU6b^<S<ZKYEOAKT9HjDcSti_Y$vt7@9`M9`F z#4#6Fh#0=W_XvjUYgPVTx;Tb=N5b;O_CMb?Ki^zS_}0QOXZd};r9IzVVjEiU7@B)~ z9Ars;54lxdKCp$e`PSy=SIg(TJl<{v$4!iP<oEgK+lIX65?300bLhdZQrC5RraY`S zujy~GtI>l*u)8Ar!nP~yMWpV*t`qUA2m89j*CX(x&iyS)-d`cQze0JIJh_)_pW-Ul z?q%9j|7tw<*4n>>dG_V})11$~7JJSyJbvz8mur9RcQBDE&NU3#Z$nsl^d!C5HJ0<v zCi2+tGdD{@p4?N!6VU#ww2#}re|x^#j`(uEF}pjld%hoR1Kce=NCp11b&q=z@kRI3 zQ@jX#C+SUU7K6GUwBxYv^I1C%<uwYGK;Io2KELvs7v^GL>9e^MJ{RS4sl=bvF2uY# zG1=YHAg_23Vv=Bf_shLBsAIUc-(EWYza1B6&|bHJEzf&9#eVtOjz5g&JpS$}Ui^sV zT$;FU#ZW9QuOnc;mh9tVo5gn8=M_`z`(hur=d>@up2xmDkt!SqG1v25z2bLOP?~by zQU9|`v+vjQEg7HS{OP|h1orwH&%e7rh&4V-jnTes&ps};=jpncs}>}d^Y7HML>)}j ztYGM>@!D%yP}g!z&#T5FYEWV*wkmgB=w*H+q5kh6x$8x_m+Y<^<Xu<!tGa}{7V$q* zbI7Y!kk@qawcZ5&&G}_^FLe;{-7-vZl`?S*McEY3-;}D5>K^7@6L|JKV)^d;_T{^N z8J$<EnErQLnDaLa@ceQu(|!lDkK3P;;{EaYO0kH9h+ne1$8+A9;khZM<o#r9TnAb_ zFE(&J-CTF?-1GkHC!;Gq16$=<FD&0R{n_sc&yrJ|7Z|$Aj(8&2@9OsDi0PNuwz>8Z z#&aGq_muyepJln@65=?BScDkQtK>f4)tJ}P?8pE4mOPoiw~9OM|Ku~s9s&5@@bnQ! zQapXcF%eU8KZBm{x#NBk<$O#1-}!v8UsvKy$9^>2Z${!>FYo7wJLj|H`Kvca_Y(e9 zs@THZ`R#9ZB2_#ua*zLKpB>_9C7vBHp7T!F-S+J0na5jIUeAu)^FI5t!@VV5<Vzk6 z7F%dP<NyBn^F2FYzg*7__de#H^8c@A2h>{sDyIE^*ZU6qkLR2<&u71i#64F0I!x4T zp-$^bvN}S%_bc`_sW-{@8Z2Mba$&lIz;ALrcpgulhkf13^N1z5e{sg*8@wI@%k<*; zUCR;E#nQyqifs_>7t?v^u<wOfyQqDA)fBeDozs(Vn-}l<$eW1N+@(N7EyP@6$+`37 zo+5I(*X61ei#wZr3+**w`?$z6dI%gbSdJ$t&<wWUJ_Yv6i|>UuPxZmQaIf7##4&*_ zbkzy%<Mu5Pdm;AM{>wq}`@xu^u!OU0=pgQKPrf}luOhM6Vr#{?IR0=hy!dvyj<z`O zc^!FJi)&qCJ98iB+*3qO_ZI&1BQN$bfFF5S4r~2kL$T$qJr&y~a@voleLVNE6?55t zTPJ>DXV3Y3<L+2N&d8^Gdfx3jBF{fvuc!gS9nTfp5v@Gp&hYoGJa_VF<@t6poN;>; zBKKC=V-Dh%m3g(f__MF*9oXtB=IYMwKdv(<mh7(Mxk|@hPjRIV>;k0#@_1ro?CB|9 zM65+DCxzu_J?o8zp?k@$UrCFr7pA+GZ_krg??Cnz6MLOJ_py4GDI(UL*V{^7({tbd z;hxXh$k_edi-`CJmhPvfd-E0+A8f%CdED_3*L_~Z48@fxo*MS$L#j6}0j7KK^?LH> zi>sfX+)opjOKh8KUa@xfv&OY{F|T-bh*UAJ*q&!^_c=Be&N~d*FHCt`60Fg+h4#I^ z#ru?791p2^y{qP~b@ZMD`S<Z<+K2YH+T7QGh~YpT(m}*|d^+0WLDUIwHsMQhFY+QA zcl{RIo%31p<cuu2=gmFcb=Ug4JUQnQ+i%Y=o~`yN_VK??b*<OlP9)|M?;2t)Prso& z%bU@&<oQ?cM^CT!ukz>KLi^iOUiT3DmnYf0ZkBrrv^u$ZZ?J!%Bz`*#Q#?p0|Dr7S zHTLgJ$^A^v9mRT<JYpOEzQ!e%BbG1ni*cClx+jb2_MG-q$nVNolRdvY$oUyicAlg{ z`4V3U?3@MTNg*)&KkU7EcvMC9@L%_KI=v<Vlr^X*BE|&~5K&MG3BevgmVknQ&?HT0 z$wn5IQAQC_GcJhBprejBZlJjD<A#G<6jVe<9UR3$M>9GuqmDXm@8_Jly(GYl-{<@L zJ<t2c3r{}h)Tz34Yp=Rhx4U-^WBdDgS7rL+?nd40QkAu0Y96uQw()bW%8tRli&er5 z-u|09&hm-H_JW;znb_NZSHtechwSfj*maoHU9$V>&)0XIw*Ot6|M~8_9z#-h?C6_n z6}H4|$y@zDl}!7qetyVI{5C!9<H`8`Kl|>>C%Xo-d&>VtmsXlOug~Z{({R4btsCjZ ze)9&a#9T8_&w8@M$R1IS_qoem+x;3(uErD4c!Il#=fq>BM`y<%mK?p-uh-`4wS4Al zr!?4*k`lkBB-bQ)jtl5pzCp7<_kVVdIXnCYfBWzuy>D3W8`1klcY9yCm*0D%c;~xh zd~-F<fW{frI77RLQ{L&yF~8z11;2TRal3t)boBjsaqe6KV#zW0?%gr|jD7dD_P=Rq z|94%>n^C&L+&NXUmgf7nS+}RY>(Z_+ti^KYtE}Z#-o$fE*A>Fug~_)6w~)Qep-wMT z#NRmnCOU;C!QT@8mh!iZzZz#BZ2Mr_2irc__Q7_5d7r-@_)GHF#^2}sE#Yq|f8RR& z@$Zj+fBgI7-yhpS*bc%r1UW=y(m4|SNc1BKH_W_ehMCUp(fkePZ-jZ(9An-v$D)rU z+(^QWMvhjQbmp5I`P<i>PkO4+tI?~`YtU=ZYtU=aYe{o0dL4QldL8-#^aX@jfZl-K zfZl-Kh~9|ah~A9ejNXjC5Pc!~Li9!Gi_jOLFGgRCz8HN8`V#ad=x3mxfqn-1QuL+h zOVO91FGF5Oo^CJ`-P=suy@S7d$m>1kGydZ4y=J?)m$JB*Fb|U72g&afl*1F|Oa9{S z^X5bIJburkZ!#a7P3W7@UnGtfiQ`4|SGevKuKP3B{h90jjO~5?KH#s7aBYNZL;sj? z9~15i!hJ!wFR=ZH|4+pF6S{HUcZ~A`e@XscHjdNDah$m8Vt28-*j;B&$LD-#d`@TA zPi%f<F8;ar=Q_*K4|M|0t0v%l#$VhGI#0S`{KC$56L#L?ud^E=Oawj8>F0EI-Y}h= zFHINX=t8(I+@p*0mf6GE;&$b)hx3i;!8QE|A2Q$9JEk+tHT%M-DT1BN;mV_w#mbm+ zqH>xtu1qQyD3>Ug!EUBSxeE3&SHY-R2lq2~tNlrMpxFWkm^an(F6?YRS4*)YF~neJ z`jjxPOv0#Hp!yQ!GC0KCt@ekN5;Dr~kbYl(v|d%LEK@r4vhVr1=)>Lb>nE9`U^m*( z#M)`_U!!N5X>K*YWjf7$h2OxO<}T#7OQ*R_{ATGix6cK&@WZQ`-~fJ`beelNzey@Q z5B6_brCberC$Bem6LV)H>4B<0scdx@oxIkxx{qAE-n{7^?Yjs5IO-udu;dAImGArd zXN;7?X0r}GYFd5rdy%a^`Mt+2uKcd#7FT{xato<_9k%jYk6U~{o`=Qv_9|h$gz<gB zZ&+{fZJG90c;auH;F%M|vd59agGa12@A_Wm2<ly*JHInL;>-`>!^6dX+);#a<+mZX zxbiEITU`0|$1Se>UgH*5ewlHLE5FFN#g$)T+~WJyW#0%_kwV{37ySf3=@fFd_+C`| z!i%~Q=T8@PcHZ@!GQXSo+}GCF!};9z(Z2gRtv>nP%vPWLg5<Y8`Q=Ed>k&@R9Lc-m z>ylIAOml)q@Oyzd@+;EU=X|lpFU^xV|J;vzX_$~-LUva6gq_X4sviZ%ImK#;!2xC> z?51sCvg7#wHF_FsEjtyynJbh$I{p>)mFSYYHf@vBNKZHOr1D#3Pi-?XYKQbFi%1D6 zRNt#qkL$gX%5`d4rD?cIEiD>DkT)nVa)P|`cq!b|tcE>Q?`^I@?_;iq`<t8Lfg17< za~t{)^&MvJLLZ^_Qswa)eyq74`((Xps>U`$?X&f&N{wNjhOgH!P3pVY{DG^^&@`N- zVb0Mo=W7fX>a~|EuT<Y_)OU@>aHGbsUej}zd4hQEGf%;XOe@@=A)nGP&uQ8=X*_Qz z-!d-}X1m7up2qf}rr~3~?`LK!zF+FK->bzq5<bU~atk_=)2Jh*)X9+&+tYai_Hh0J zdpm!HeVh;A{?5nnKu1dN5a)9^(D@e};(P~(ImV?VX#hbp(h0*-rvM)BNXd_N_C%lH z^n{b0z2Q`+FPz~V2xmKo!b)cltk&@L&XMR%j+DS+X9W5gPBA>oDTC)YC%_9GsqsrR z7gs8;(Oj(29IaJ-z1r{6eBGz^N0l4Y_bK(=q<mS!ysEx$sPA^Qzo(WD)$*~H$(MTH zZ`AU=BkjkyQj$5Y)KpaUPOi2_SIV}BD`ne9xxe}zqWVD9hbc#B_)_KZY8k6xCTI+k z-3jD(sw=fK!<~XY+dTzVx>8f~T&byQS8Au;mD*`?rFIs(Qafk3QafkyQXb{zO6{EQ zO1)g@O1)g-N{w9Z&VpCEQZLuI(u3BxQad-gQafwiO1R#YI=#!4n!3-G_VbV{b^53) zwf2;z?Kw^DCQbj#nwM8K7jLP3yXx<${X-4&nd)Dv{*8wDUc==0r1XM5$#2vrdF<qq zGThUr<>}Lw>60?wU+o8~eu!Q*!<QsIvwgL&Qtk76QYO_Jvfd}TZqks4<j7qH=14q4 zawPr{s*hCr@v4tieS-Q<RegrqXXi)@oR=f%saD^5^=(q$Gje1cI7{v4sQvsLx$lMQ zdr6L@=kgrM-IY13oqY3ZPNSP|-pKhqd@JWkVt!9!{!qhztnqxN@qDBFUhO&lzY#L% zm-31FB_*Bw+JF7h5_<Th#(VoEcYXZQ9`^T3OE}OkDLKS1ZDXKc>U4--(lg92ZDWLA z%66n*T1cs1%IA2$<aDfG%4f3PajM#9=pAQk_)5LwJPlK=vDIs;nlwF&H4SHIJm=`O z=d0yHwOpzCHG1tDjq^smYOThwUgN(@<G;@@ZSNtC|53lRzzv$Or~J}BpVJ&|@=Hs8 z*)J{gRn6}kddIi?A7R<9W%8cp^h3Y2+mE#bKJ&{c_oe3g8~<n6zt>VSxiaqM<Vqh2 z=1T8~=1RZllq>yWyYju<uh2itm9qUfS4#4;+<#;FGFM9Sn_Q`j?{j~`VgflnVhe;| zFd!u#4QSgA=vWbu8tD;`meV_sPnbRdt+jyE?12HPokIe9U>_Lh0fz+kg2Mv)!4ZM} zaAZJgzce5<b$mc-d2B#RY(hZNJUO7FZb0%fBX9`eX9o_4l>uod^8!QBs{_MfePATK zF(55xt;V)q({Pu@e_ue#_90FAqXEg|hJfVyDNXHjnu|>VDUFvk=2rt!0&i&g-_l%f z*R;K-Dfv)S^>ILI=QB;`mjNl;ZvxT+zt{Aepwx9RDEW#8FQUJ63XUd)Zv-X3Zv~}% zwqvK)1f?WD)R3R4<xADSQTrJoN#|K133*OPVmm)1;V%qHJeR9}rTVT>-l&$f8ghMT z0(ZPmEf1;hhLDu`Q=uvFxzH(aQ)m`^IVA1s)len+8=)k8D^v@&hZ^B~p~djSkhFo1 zLrdXjp|jzaq4VH3A<60YA*p>6z7XbwW$q4!SD{D4zk!{?SHnHSYhaJ?O|W<PR@f&j zWw?L%PV@uA_rXKL55s}s$KjChMmQ||92^mrb~rM;8J31$fyaksei<8n9eqMrW|qle zX*pBFZ(*4ceizOTOG~Q^{|(Ly>$n&G2)#c18Egtm`&k_R3Z4=EH#{r+6FeuJlS4U& zL-4||^s-CB`RJF2_kdT1d%$bLd%-o~{osw^{%~#h5V$^kIJ_%76y6t>S?{6naP&vR zBjJXyw8N*uqtTxW{{n6bOD}slJRbek@MQQ#cp7{wEH%D8EOq@}_*5((hAZI5;p^EA zFy;}~Rs)a`^Si+!_b|7pEHrni>}wuSd9c}{a<KVS<#11yn4BSU-3gv7H+!mky60bE zj#2k~bG*t%GsTlPdeT2su0P#N$8u9~q_{6IXREx-tX6roxmM*3Ubx#xUkTwhnh%fV zbsO^$;gZNNkQ{WHt%O^LEX2LTbNd`)wwVKu6S>2TIIb`9I}=ywbLOjzIA<SMguSnG z*Wj4S)klgv*!k5_707MoHzP&v;jBJVWW>2y-G#V$HaCNv+!-w@_n5H}De;Sx_(evX zJBwS9!<{}e+K`fNkrKa;9l>qpiBTdW&K8wB%v&WP+{2wwGek-_kvq%{Gx{Pm{YXte za+~p$iap}wmlh$1JI~D!Dc6-CC43CI!+bKM0x9K`L~8jVC0q+q%5fdC#OXP62U4zU z^Xwu|aAubKeD?YfQm!vT_N5$3ka{1a#1lhG_zL7U(|5GUt<DgY+nhhD+~Jg$iTxvI zc3BcB@rab`HX;k%g=Hf9x;G!W1L<?lEEBoST%uCyL);PPI(18Zi2EbwmN6wcHa#Mx zoJ2;PC)9qhyZXo*JpXk_%{Nl->)AIVea?%=i<I&exz*XB?ugS6YsD?s?NIyazi2~B z`hDy;N1V<lh?H{fi){4u8C!ys@(~$v){IRerTj{ACH@1C6B%(H9=9AR;dXekZ@{{5 zV1N{RD^l*$hLr0=A)AgOq_$tro%CdjCtHyczRi=Nu;lla!F`eC)W1kgFLI;VbYc;5 zxU=8P7*gvKDdm&&+#<!jPUS6wLlGNJq}Yp8-ZD7m$)x8mQv6#y_d2ActJQP2c`_8W z@%2S+H2ufNkR{I8nH5MWFOihj_!gw3Po$;?sqv}*l$ou_9p=<i+mMo<5bys;_@XQ+ z*Hz$_@)h}!^W21_NWzJf{;}M%-{8rONC_`e!te0hBE{{?_sSC~?h;Q{c=85MZuI01 zPx=aM_`aS@BBfrJd+rv`eS_y-=eb)|QjSPTZyQqb8Dhs<WM8DDqsVi|JlP_4{MR9e zJLjFc!Lzq|_U)d#Xb%Z@$EhMEevv!OeW%7edka$A)1J0mN|4f?HX;k%HzrhYTJLjy zQn}UHbE3El$=5ohq;I48-!#$3*}jyk$Zh5Ub?-3GOf14J;YyG`r_UsjTb+R_w>eKw zih2GONVz`gxtB{g-^_B6moa~c+~%8G-s1W1KuUO#GA@L8b4%{C1G&RoQr?Cf?!0xX zkJBJc7c%0!ST1f2k38LX*We=LaK|?*=DFp3NbD`1T!Sp9zpX<`xDB4W5AXMhy#y)c zBXX<r=46plKFig9)5IH)a(|KAO!X9zQV$|`m|srWh?H^>xz%}9-P@e`C+)y3*Ol-o z+?14bm+&hPJB<J23Z&RYO1?zu_=uExyMf<>kaUUM>Xe);Qqr|U?bO#^_Ii=q%xfo$ z++p55xi3=EBXX-VY^um@&Wlq^kaEA}o@_-*dAE5o#Mza&W1g%)?l4u;mLv5#q@+{a zlFp4tN#{B~K`G_E1G&Tee%gD;>Fj5;d3IkPdwpNz4)ejZ63;C%;v95}NR7|4_ubdV zTY}W`@np$<*1ZE+=$1_1(U<(u&TrV?+BYH#-P5M;P`PS)-+tm=HC?^|N91x(wjeJf zpBvTv(DWTD-<e)?fVC$*c@9$YQCVc=d!8&k$hy}drMyJSIM#~P@edhs_MRnfX(yqB zrQIDiTcq}1r1ocI#F;pI9a7^#%6KF0+bB<wGC#C>{vzc*ZAb|hI>h$-BBWd|Qv74c z;m(YB(zA;cyGV(z#j}ePyGXIGLrS_@J%5qnFH-#5JiAD-ixhk4P<wxoVizg)BF`>T z>@iO!k#e6FPp<Q1t4hXEB<sSs$a^UVky36VAHm&*)cXwZ?u!(6ktbtnXFch;*Lkv4 z?Zof7+dQ{OjqfliSIQBo=|yhzT{$O)l=~;uedipJ;%-s*({n_Md!4%fI!9#0`9`It zTkW4$w0hy%)a|bnDgL2>UOtc;efw96J7wQ!j;<_H`x7d~9#i+9Dn*JrsqW7zMT)yc z-Ts6~aj#SNUI~%nZdLc-gvgY8hbc|8seP47v4;+q^!zR%Qrt!AzBM5-<(BJWYTuwz z?Bd>GUP~m^e!yIjVsBITadSnAJ2Xh*pEg&d#;5M;xka8krtUN6iWL8(y04upQrs=- zeqgT1lzWGHVeUG$_pA~r_6<l`$F{2dpem6sNW1d<+tfa+N~DAj4VHA3SBVsNk-Fzs zi4=EC-HWS4iaV+9mMW3rZc+E|t3-->ow}c?5-ILhb^o<Wq`2GE{auwvafgP;{e$yF ziaVz6!g(Uay$&h;M`Xk~Y+kG97AfvF&n;5i>yGfkBh`PHwC`I6xA1uu88=#ynhvD4 z|KZji%aSrrwusxuc<0I32rqreOPlW+oJ2}|BBlSdcy5t8|9b9qp1Tz(_Z8XbJ2KgN zjF%pyT;JxoMT&dfagq=2kBm6CCq-(ykutuvdG63in_rPKzP2DGT_R=N6e;7YNFDc( zQXZ{HEe~~bf253~p<)|fkxIq~WW?EUnn)R+L`phD%J>vRN_vx?Y(aj(`e$91)cmQN z`PT~<8YT5UI3ZHwQ}-M5i;yy&h!lH^+CP{tGUeW3zMsEN?Zc`>ioI3c)l)>K+&j#e z>Neccend)p2$gu{g%o#@=N2jMR?jU`+s|m}-<MX0%Di$zO8lWQ87b`{hFjW8(vzX% zJ%6Os_d2AMw@4|ER?jU`+@YBD7pe0Ma-(^ny2!JO)Op6UhkhaXU>%8!I7iorlyt?A z(mq6rJBgJ1i<I`!hLm)Ol=dM~+J{KJ?+G@aMMw!JQqmVg>O70o`AjA43>k68)ryq% zAyV!uQrgElWQmig6RG+3WE)b`;kiR&z5F93T#@G%srUEXG0&YuZuGr&vPiw3x@+rN zJa-#X>m8}}KF+#BNUe9zUF5l2J-0~lPfoD$u0sxY7S)NA`-qhKZbM3ahbCIN4ypb~ zsqfe%n;(&q{-oy?sqS*Ge|mDAO2#Lo#M6cx?p$3Lnk@2}x+0{ES4pIfXGk3%JlTqr z@)RlYw|Q=n;tox*{vyTw9#Yq>>gKunBpY9mCo7TSpF~Q$BIUXk&n;5i>pZte^*`Ch z(}I+Iv?8TFiqw1|wce3hKS;SQIn}!lQre}srCo}YcG=?ji<I!8X<mMi5|6mWUWAl( z8dLdMT~ht`s&7&E{`KpSa(|H$zE%C{51tI2BJu52UxbwMj;Y&9Y2V_Oe2CQb8B*d4 zO}DZrOKN&>OFqOd`G_Iq`lJ`G#gpqi+3LwQPbO#Bcw4fhrrUG3BE{Y2xkZY*Wv28y z+AC7?i_~zlth)`Fa!Yzbv!&c(^&-Vxgp}(<YWk6yex$DZJ=unoauO-?o=A-^F7Y+g zCy`P=BE{Z<lz2tT{nvSJktw&_r`5BI6uU^Vw|RDvntsn7n`7e@DRz+(e#2aA-|opZ z%dLCEccj~m3^U)0Tt95hevXEpU1a6<fg*1i+-HzuKH{`<q$f9U953;XJSrpmy5}8r z)>s>U!(?kWQ>=UBOe<%5a?Kp;--iueiASVd-)FAK!;hY=^7*6JEVtKf@T6(6;m^vF zdfyA>y32=eP<il(HJ3Wf8()mrewn>~<mL9d*`7ShlWVT<;`d~qtGw`@<n;%ee@~9| z<c904{l;4z9Uo@@!Hee+Nypj8jC@q&UdQsHh0UKQ&)Q(!v!C?rf3$MVMk_aXa=Ry= zdd9}T{RQi9UKV-F;5DyU_l<wD{(b&t-9eMfsc|mvtla3&<voVua&yhgZd-1^^vO9Z zkZZ>I2L^M^l7KK76;A9VY~CXl$~CVkw{-hdbmiziqQ{iuloORxl+%<mm2u?}{UrQR z%43vMl+%<mm2u^3{q*h!3;PWm7<A2)L2bFNx&FvD(wrDRFc{*^&wSpf?#yQ_dhwoZ zA@B0;V*+MBEC+Ck(%*D7*O_kSHq+hQ!8<wkn4ac-LTxg=c{6Y?^8umTOds<jSNNU2 z#+dg5Pj}$jAPv;4j;?@jh7N=?149TC9V)c;89@eHbM8>#yohkjaN$AWbKsU?!ox4S z1lssd94dFQ*B%;lTw^SIgn~X}Rz;e)%gx<B#NHb2ge5Y(2OQD88q3YyrlPlo&rth0 z@aAqC)UsVIAHwTvpCbNF-K&Y3&rniAA!<DWqvSlFTzAqkI>dA_11O`TD4*e!;4zd< znc3T%M2M43A5%@JI@8xQntrB<5<Q&~{Vi`5t~Uo!mIs@M%|Ons2Jt55VDk*`Gd*XH zFs)`N<$EN1FvECv@+kAVIhr>vhx0Dn2=hL7XyYB$kIhK)i791#8*Tn&V&-deiuu;e zU|(kr!%T(w!6bR9cfN6WkJZont6|<*jq<K)SKd?IOWsfAz0?DpCUX$)qz>U-)S<kC zI*fNukLI1z5xi@9Ebo|(<lWLT-YtzeYs`4(diul-y!Ue(!_9hA;oQMHws)CdI(M5J zoO{eo&b{Ui=YI2`^8j!9J!qbE9x_im5A#mbBW4Tlo4)F7Fn@QR<c&i{4CiU{rSq)$ zm-8I&@wS?OJJ0jZ=nE#ud#53Hv+2aUr`_F`%s%cG)1P-w4|cbj!`#<+Pw~&@2zQ$) zcHc6`yMHk;_ighFce^>k-C@S@KI#PbZ)Q60q|R_ZG!?v;TIK%T)VUv-g}j&gOZOkV zss1VN(0pOecE2<iyI-3t+;7cq-0yg2=0|h2`x9@<80Ti!aqi@O)O%f@^QfESJkL9* zueiC+n{L2)k9SQ!aYN3hyl?u28*#pK^PC^u&dyJ67boiL=5+OSce?p{INg1PPNA>2 z)7Q7ZbC9o}Gr)I%bGWa+Gt_sWbBwRZ8SgvDndCdzDfb=XO!gh>oa`ImoZ>soiPP>D zoqI967r)#0GI&GdYWQi-YvCBRZ!Y^i`sT8=@VSfcfYV0Z2k&bU?iY9no;_PwKV4$@ z?XXAT{Cz~fu<sw?xUSE^uMXcV`uNOUN{`)w<<>pKGGwIat(S{lvsz-dX&669^rvI5 z!J{;Wqb~b1`sT8Cl<z~Es*z`Wgg)hh&*6_fB>gsDHb;j=C7wDBv+RPe(c3hSk83(N zm;HccbD3`-@BJ^6kekaw=$p$5l--rRm3@^5!ip;ngGF_c=G>wo=r+x<@}tmgIvXyO zd~Gf}7E9#PQh3XG5`W7odlwtC#A(Cde&R3Comz?W($ewhS8ECM*4jBdF&WE#%jH^| zFPqvcG<S1)oPw_{Pg{}`m(IrW);S5dw(ER2v1kG8eX_)GO4B0rPiM-#>|OTJ@Egup zihb<zv!N}+GEI56th(FzzN@dy)aD5qk4?ilzma;eX*lMb^N2G$4U_hkyW4WJ`e<zr zo69aF<mR$Vl~+Pr%eItiwdDl0Z2O!edAU5?u{^s)Bt3(Q#NO$A;ip>Wzr9FwTQ7TQ zdD_zZ=NKEqb=+&od`Z>*^KU{gxLEXOw1ls?P}=aNgC*oa+DacSl^VQ5>vW~Yzqk6{ z7?Chbr`?9{cURpF_nsh@M}`Vt8!kNkG>Q37zj_ega<#lOOzgHaY{@@zl!Uo_@neKp zbAjaO|BsZ|GO?wxbKY%wY>Ca+TzAitbZ#!&NUAoMy`X#rZrAd$byT9Yv!Ax!P1+wj zFME?Pjf<q$^y&Q$+@SsO^TPMg4^{mi8q(hJIkhi~NeNtVyl``w^pqbb{T&XQB;V*- zu=rna(Ei`UkEXfoMjqWu%eGJEsvpKlpYjiqy0bCZ_G8<OZ6~%ZZ7$37#}_Y=7?!V; zGJk3RATjrwmIqtT+5>Ky+!MaE=RUCNXbBm)L_+rIFM5}ve%LDu4uUs#66Pq^=8Jy% zF9yPKJ%ld}k*jRX)x|@w>|D;a<=e7tSbQ{LUg#-z*-L42^wkQn*m8URK)L&w%I;bV zD|OtqrQQ6SOdDIPBe~_~vXNXhQG1qu&}j5&hf4~l_m}WC%p9#vztUR#gCtBOA>mW; z`~rRAu`(l+DxVrP9?REVr@$Xerb8QlBoRkXT{RcI{Z;d^*sJ`5B&7dzDJvWPAHNjc zKWG8=TYPf&Sk5A7eK%?fv&-2(=!~?lf6&?JN90Pr9zRz2x0S*g9V=`a{;A{b)2B!- z#%db~u9CaFrn<e0f6%#EabB3EXVU2(Br&AIXQ$y3!rwRRa`@CN8Mkei0ghaI)~|kx z-9Jd`)Y_jKwI*#jTHDNYZEp>WZ^nLrj-soNlw6EFO=9@B_Lr^4iEjJO`KoU&TTggj zy@Y&Z#J%XdYUdAQUpw^)IR2!k;Q^ChfM03PdV9habXQBP<*e7yH%<Nvw0$8qaR>S% zIwyWVUrq-e&^f*T6_S@r)xK?v=zsG|>D^QEDXa*61vmckTbSLO0>=dhrTSFMo^sX1 zEAz3ubC#t4ZY_t{iDI`s?v{|)U-gUS>|gIm$g6aIf9YtkciK<v`%UbH{gDxU;Er>} zK3Dt5&|)d8AzG??PZRqq-6Xud@3$9<rHkfz`#iDtJw_P4O6;%dm~VUHf^!Za=G(QM zEY=iGRqk`Pg!I=4e^@Qo+Vuari|8X}i+y3|L%4R4*5gk)U#vYse5+3t->0-E4%Yn6 zb;N$yo?>rYBzKId<=0&Xq5q&IP+2ex{pL=>9Oc_O{`AqYXr+!$`>AD!rf_Y(gzPs> zYX9fYu#T4A)J923_gqO;?J^k?#>J&PZ`CrKsCxAQ;#*cDY}4B8QY0bMYb5TTJ-gX> zY&+?^Y&5<$&i@>n4QcOd?{dQI6S%f*&x!D_{Z5AW&656=J!|yS61H>4gMLZ*FU}L5 zuJcItNMc89+oy7LzP9sAc>kHi{5xHvzN!83Pf9!Qe6D#9YHY{4QUW&Dw&k>+RV#>R zbJ=Ooj`{mtEM;35l96P+)?+uVHLKhDvc1*LAcOZ@z_l;_O72pj?fEsI=)3CaiwL>9 zp5AiSQhYZ}UJh;V{(gQ7dUg-B^PTM@jTLg2?EYx&i?kfFd&kHIDO=m-?NyZpD~b8$ zPQo1J?%L|wd<pYEZJ)M1G}X#|ZL26dFjEVg%dQ~K?6%jVtAy;l>>BLZdUm_YZa=o= zyw>;kg#Y<%#<q>!w}iFCwz=$1Xj_6UE6ep-N~xA0Wzuh2rZ#O$*j0@`K*-(K_@nr4 zn*2wYs`2O0cUR+ot?pRk)>1r6?AbM5S@0t9+}uf+quhP{N|>KtzyGafUnREen(e%7 z8y4FJtZrl2xi)9*|1Kf_zpKp;h;4J(C(zdBdM$@k4N9*2P0Q4dt-)TpLd!i+Mu7Kf zg?*-fMab+m@cGSRZ&@TO;ey5A;hVi?PK~b4V7Yq`W|zj!&oalB${M?2aRDK-*O>?F z$}<&PSB<Ure~qoH#<r_=D65Ozw?kQVJb1FKx8FWf*4wknWxc&g*C9KvG$u~(OG>_< ze<0j>y>av+DWBc7VY{Np9<}=GYQcuzxo>8->g<yIbLjx?Zs+34g2CwL)*J<I?j(AS za(8V$HUCP;W4cIcEo~ZJs5w?*(DD4|_X|5O@BCad``7Xuv~z3!`R)9jn9SM>y9@u@ z2v$nUH<z6NZJW2x%k#8V*j4B}T|xDmmT3>R<-e)5zh2iW_Q}ycsbxQ1Ue#|BG5=xt zRQUXnr@~ZklIJXYl?}gh$j-fF&6(4;lB-HrodyS9RS$PAF`qso*b#n{u9Qyyh0G4) zdI;}cwvek<?<FJNGdWUsrMgbDPY|~)I|JVvPZ8hcx~jJ&|KJr8@<G4M>9NbsCX9Vn zvR7rVH{Py17vKGLf6T5i{@PD=)$AH0t~(n$uP(0CapRx5&VQ&_?ln)>pEmx3E|BzC z{r+=BAFQjm(wqyqSHJR0Vg8CMVdsT%?Qc%k)K&^l()#*xu;kswU_*}69T;0y*}n5A znIOCNe8U@i)bbtwKK=(y4LkpxOf8g?0Kegvv0>0$&7OBBa}9Jk3kYDz<MS7tOg`jW zi`Wehno&*|O9^z@2ajMWb)r~CLzf-#JS>mM=Y7nhkYE2c1y~+)I$?Pny6mTS#`1*I z1<MBLviH3QX&45B>?H4r{g06Eec=ucyWw52Z*;n0e+s(njd#aB0tVT2?t%Ro=(1Pd z6Z^3+XrAR8DLR?wplgmJ6%IS-h1gr2-q@dqt|_K$95V_A%?r-n*f&Afl(3ucu-m>5 z_RUTo>@Px>z4v{wm%$*r)B9l`1YI+R9e>9h4})f~yFd0J&}E;#ANF6sp!uD90QT#k z%coBIV;>9UQ=123zaF|~947@q^H=vEEIXiUPUOtMG2>y-+!Qzj`^}JFhcky_p9q7d zAUFVfC+M0<<}fVP!GTz6Am2d7w;4EmD*ABjU-L-U$$SGj8R7(j?^c9C^KEbl_J2c{ zQ;Z|9ObQLfQVv}+mHKhaG>APsOzhA#aq1^%E)E}!WhHbuix^JG3Mii$8i9QkbWJ5S z6Ev$M$6~n>y5=<MBxs(GjKuN+bj^HfgU<s+Mq$|uUCvTUuv```#d0}x&H2<o&?NH8 zu*`)n-?K0V{+g0@`RvUJ@Ip$_H5XB4j=31RW+mn1noB4N*Q_Gn{LUx2ba;35Wb~`Z znadf?ba<bc3GX+v@O=Qf=0S4l@_FtGEDuB1{J|vPBc=+=qtG>varWYx$H{@ixz2p_ z4fHU_JPBR%N6v#>&P^A<zjH3+a%SBOKR1iuKg|;8I;TS)XD}|G@IDjzIg4=&-+zG~ zaF(M7A*WK#3K(|IgAu0%Mx6^_k#iAY4uURc;VaP(fv!2!Sp^3;mti>!@|z^i74UFp zH5}wz1qVA<<2wYp<_PCn^r4Vm$ypG+64Dbn4{|vzx&g~@=yGaw6Z$dG<@D$l^y8q* zDbhMv%(;=v=h<(E*Eo0Ldo6U$@0`2gb(|i#hR=M%>p4Ag&F?uoayeOggpfBvmlLMP z;LV&Rx#kv5l3cTvvn0o?gRZ%iGbM-5&OeR5p0g##+zwsNq*~#foGv+hD*pxayPeJG z_dwU&>%4@1AEcI@E${(nE0zZ#wd}kGA9h~H@(0Lw@VIZn12}_nIhpzkJk)&$4shRv zhj9)?d2$lP2*5cMy_Hia*No>3iXO@d6yIXV85F(J{T!CNU%<)kSFoA$D2J1(uhAEA zF2%27LDwwde2VYfg|0c>{Q><9=$fURSGk;MIh;?P$yt@l$(A23<DAOnge&AYW;t~E zym$nC1$521oLD*LJV@Vh3t$W9SM(Qm4|svw6<+9eC(K3A<&>-^T<I3VOWeKSDt8}v zsk<+{%<T&==bKYp&eHnB-?&9^wR<ozTnXt-?xFCv?qTq1_i%WPI~d<<p=&m~N1(q5 zUGtKAB>KzH<=Zrlg0Hy4;a2w;_^Nvxe9bL}e{xIU>+Wd6zX4soF=Pz<vm1lk+!Nqi z?l|}tcRYOCoe1A?%i(r+3Vhc+8UEYldoRp)&^6z?)8P;9Oe{Y_*ZkzpLN~ry=#DRr z?m~K{uLAmg37G4vf&m}jTEi#Z=MyFb>5sk|^a!Ls`s!ewZvpJ;YsB6Sx~99Y86N0c zgrx|&<{;k^c(CtuEQdf^mv1Q?<~tM1QIH<zTLy>wmSY(Knd5vb;IY2*;BmedIMR0k zzQxcrrMyqVw<JQ>l=)VokAbc^-nR-p25FzZ%g`r4+NbXd^huER>01q_`mVw<4Z7wO z-__{Tp=)ONu7xvw*I_vox@MN|di2?lxxjY=`W)z*3g1oWmC!W_-!15KA!EL89h}c6 z`x)DPx5EX#J7I(GZrJF%7yg=W3vkQ@ke2Ct5d9)Z%k({rz7o<heUG58g0xKEWAHNH z6Id>Xv`pWV=)ZxCHolGM*Fi=b-_!7V-?Q-dzE-%-_X57RLYMcDHlweHuDRX!68asG zk;JzJ{VvEz;@gUT4`d|qy@q}tWF+yuj{X2-zVN*XAM$O38~Dxx*F5Qa2maCbF5Kwb z0iW`{4`1?q0AKdCaqSjJ`}ci>z7^8`eg8mz4brxKpTfWRK8IiXzJTBOzJfpczJ`0` zd<*x^`3~-r^8@UY^Aqf!<G8LlB*zC2&GEwlIRSWBP6(cu6M^G%^5BG=0yr_JGn|yO z2W-jd3V)r`9d63$2{-2y!WVP)avk#$B;`5#z%4oZ!dG(o!mT;|;Hx?P3G*7H=jIf_ zzvUbZKgc;0ewcF@zHN}%Fz0aiQO;oaan2F&A2~<DPjZfej(<3G{l`F`|2UZAFNQ__ z5_ph*G(6Zp1|H&%!9)3G0`lk|2M_a)hxPu6aDl%Z-r}DE*ZNO}>-^K;t^VooHvdex zo^K$a-u-dXb_b;1{T1kULF(O~fcN;Tu-pq>^Rzz+pYhL!@B3@u-~4s(fZPSJe{LhJ z%58@8au>nda+kpMxu?TVa+ktSbI*ha1(v~s1Iytdffex3z<F>$pamWlxBxZ=E`m*g zm9ROm3jQ{587a9MGP(w?K))8!+5@ZMb%Cp}tbw%lz}4u#hs>>kYte6ntXKlqp+62? z^F-i!^bL@<8n^-dkC3(+xC#9!NKON{z*ht7;J*U5!LI|i<NFPC&9{L&(f<uy^IhO> z^zR{~Yv5k=A0eY_;C^%yydT{OJ_z05!&rQfnhidJ?uU%A!N<@8kTEv+1bPTE#s;5+ zk>ExwQOFn@d>TC;vTg}Ji#`;xZV9%c4}+{*f-j&S4H-p)o6$!=M$zC)=*L1v(cl*J zk&xLrxD|a0bj?Y@*Wk&)*Rf26u9+5m6a5tEn(4u9a7OSiSY|@koEm%w&I-PZWj16~ z4DNt)g73qM;0LfW*oJQc@=NByk6=~sA8=mqQ<w~Xj_+xZaWeP?Yzcma<=2q;I`}pE zg^=}a@LTkYA@g<cJM>E+^L6kC^h+V5V(=&Q%ORs;(D5-ULgwqB5B*BWd>!<o{}wV| z2LtHWK-XLw459xH(xQS9^fizc70g5bJ)}hi3(#+btk!~^(Qk(IwcsA;Yax9t*cJU& zNG}L>M_&)=Yr&rIj$k2{JE3dt3ho8(4(@~H9>^FQ+!y^m$QT>!i~ay)j1Bffe+aT# z3-(9<17uAeEJA-2(!zrWqdyL5;lV@EH$Yl=@G$g0LRxt6aP+4jJvulT{Tb+*XM;ze zKL=gY8axvHdFYxKf=8imf{cg3;pi_yM)Ke>=r2RY!=QXj{}sr17%WDA6|#~EmcT#p z9T<*z9kM<Nj)B{QG5CJ)1nhr<jFZ7}=pRDYv<1hb{~a<;1}CC_3>hbb<>;S4Mv~wZ z^v@vA6v30x{|R05MQ|GWm(Vp|1*fC`3(}`TGhvADy`WEp;xH1bfYDF_=7p+YKHq`i znu5@L*eO&4Cxq(Y#LxnG3g3!B`wun48KFgRW@rgKHFP?h#W!TQW_IXI7!NIjm7(P@ z5n2J~@|_v9`A`e24qX6iLKnf>&`MYrS_SJvm%#<0D_}!tHEaxB1)D-w!^NR%;gZmG z@Ry<M;j+*T@a)h{aCzt!ctL0#`MnU*Q$n|)UkvFfq1(|ff%KHno#>ZBdP?YS^vfYV zC3G+PZy-G-bU*r)ke(8H5dF81o)UT({TfJ52|a@TJ4jCnJ%+vp(o;fDp#L7yQ$kOo z-w5d`p^fM_LwZW+Y4o*_o)UT%{Z>d%3ALiHhxC-t3+Q)1W~I<(^t&KECG-;dJ&>Lf z+Jb%`q^E?oqCWs#^JwTb_*m$5_;~0|_(W(M+z|Q;VV;DnOhWIVZ-lH&Lhr&Ip&eM> zgS5=h`|zXC2k`Sy8}@%fT36^J^e-Xn>d-&nccD+=_o2_BFZ=}z@XaDTw?f)m_-phq zq`if|MUO&upTggvcY&;A!atzz30XPwO(d+GAuH#wlf(D=L)Y{S`_Owqc9z0^*gG7+ zvKM3(#CMiBW*_MC-6|2dZ#WOje$X|2!v*O3L)Q!qcSb)F@;k<SuZd$$fG*#s(iM&i zcZVm2d&2SILO6l%JE8rD_kr`m`w~70S<{C5qR)r4=Wsvt8c2KQJ5gxQ;UX;ckoFut z7`*|~p2LTtH$k51!iS-s33;aD+f(>fa!7j)4@O@Od8P{=fxZIrOcy>9{XEDsUHB;U z7RYLi?^$8x3|Tpck3qi(vRViq2d@qn!)wAN@LIlqh1EiM47@HJgKNSk!0W@~;8T1T z3*%vUB77!X4xbHAfzO9ehA;5#EUXE`)8XduO!!K87Tg++!?*d47Dl#k0&Wji!FR(+ z_(^y^>G>48=Cg1O`sa|{k8mCO7tl3dh8LiJ1zBT+8_~aptaZc9=-)zGT6huqcaWAA zUV{DuWF;Iv9sMWB>%Nht=niC!5jhjx2U%l8mZAG0EikeiMk6a=UgSKOA8COFkqZdZ z3DPnn7om57w9Lp#I3%(P%Mp-gw8&-XM?rQ%B3Hmsk=0mAAWvbDtI$V7T2$m}I4*K6 zJTY<|oEo_v-)WGsG;#y_bjVm5xe0wHWGs!`f<6l}mPXd0$02Kp$ZfD9ayynv$haE0 z6MZgZT#eif=SA+tl7zI+$o=T^A){sFLG;rh&r^|y(N{vAry`G_uYx>JMIM8fMV^3{ zN1lXNL^i_TM4pDXMV=+(ddRpGX+^&SGA>14K)(wzE=4xOKSW-_@(5%UifloD3^EEu zwxT})8HFORp+5;3g(9z`Z-lhK$eZX-Lt0>D8~U@*HP1!<g5C;Qi$>mouSMR4e~RpY zuSed8Z$v(TZ${eSpCcc^ZzKPJ|BieLzl(ehzmI$Ye~NqsP4sK%M8Ab@^g9@c{s4o~ zpWq%*$IrfZ)Cc#C`u&U~kdY)BK;Iv-M-&aA9{^eTM<eJ5LY`BidFTg0R`}5Z^g|#k z{Ag$N0gx4bbPx1_kR7>bSM))U9l2<C^dXRyZL}x)P{_(QT8KUjvI7v^3mzBU2ab&H z3yY(D;izao!jwSTVYEN`Xvl6rv<Oy54~7lVL$NnPX4U9n=*^HFr|9AEjObvvG<pPF z9z7D@bD(QhM2|v07rN%W=y3G&A#2p=G3dXB%)HU#&@Y6{ywPIxiy<>_v;_SU$jloZ z4KIz3f$O3%?6*Q%SM&t*^^m8n=s0+9bUc>(AoE&uBKiZ66=1X+J`|k-AC8_3{}7!9 zABj#U%%hN5FFF(baY##u&Vt*baV&2^o~EM}=x;;Dt7roLEm{RXh$gXr2w8na=cE4} zG6P0y;K$KA_>brU_(`-8ej05i%x94KF}eu-pO6tIZwY!7GQ#AYj-C%0Ve*!ucY=&C zd1s<`fwZ)|W$1fC=Dxh;uv^{=EZw1NdgPsl-V<`dlGg$Y^De;B8@gt%yo=!8c`LE( z1DX5sR-x|;U9(@_W$1k&yGeOhpbv+PT6wF{kAbwMysOZUgS4f*tI>-gZ7J_s^b$y0 z%DWDIG^8!%U5`Enva^(T19}Xy4$Qj={Zz<0Fz*&PJ8vC~=iLV9<lPP{^6rF{d3VFp z^X?`58IbmtcR%{CAUm9S55lwZ9)`>E9)V})J%;ac$ZVMR1YD8#Bs@27BRntfX?)Lz zw8p$=;jMYCSZ;$ncjvu;emmreBX2YMoscJvyqD1LhP1c5E$H_`P66_^qTdhMAI^IX z{Xs~3%X=ODVMu$+dlUT;$oQ7G4gE35+9~fZ=<h*hy1aMLKZne8dGDfs0h#IYcA$R+ znd$Q0NB<f!I^}%;zt3xfKjeJ`f6V&_{3-8KX!1XYPW~6r&HoA>p8qu*l>aRpoc|r1 zng0WvoBtDWRzc>1d?%N=05TWk`_Sh@#({i4dJSZ)k{>{?gRH&tL+A@2qeOlLy%91> z<maI`L)R?KFF;=eS&ip+MqdJ%U-I`rKOHiL<ab413R&UgcSk=HQjhsP;qv@KcuxLa za7F$;@Z9`;33DD~Rg>Qry#=zW$?pd*$nTHkLdd9+Uxa=!Wc0{C7~Y$ID7-)aF!(_J z;qbxy!SJE{BjDrtN5UuakK(EgkY~XB;qZ_7$H0yG$HAxai{aDxC4_kfvgXMj4PVF~ zgJlzBwUZx1e-ZM;mwy8K%aA9&{BiJ={PA#W{zUArLguFYa=0yj3VbX7WcZi-Y4Gj* z>2Q1gO!#j8Ecn;_I2>G1!L>smV}3ybeJEtiFQ`Hv2HDLhNTMGN+07`Jk3Is@e+z2R zkAw8zf;#kKNdGNZfL;RWzXgrxqappbpc#D(r2iHyLXSaK!UapvPk=n%6`T%d6fA`^ z3(kb67A%9a3YNp!1uI~@;5;~|paoVGTmUNzE`o`Im2hssDp*x;8Jt&e1xyyKhNl%= z1?LxB4XX>Tg_jgu$9-2p=7oam(JzCnKniX^zXI|sR&WzsQ*aBG>mg571?$jnggjLh z+=hNL<f*FQcJ#H7aiHK%cw52UaDBnO@Xmt!;avp}66S75-!FI={a#4lFL(s~en?v? zcntkPNLwm+0{vk~-!FI){SnA4Q?L;}Uhp)QCm^euf@jg6gtW1OR`iXKHdgQg`qPkA zO~GdLXJIeX&7H=nc@K9w9OTY~L)=+#s2hjF+zNQKn}8$SDtN4$gd_Rgf?j46zf#c4 zl)81W%v}JF=eGw6IU8CEe{|1;#<vW*zU45-w}Lb6df!r*pK~Vcl(P(W$ypBf%voVL zqxN3}yZBeaJ^ia-H~(d@hyM!L%fA}-_Fo0}_FoPA_^*Zg`LBcf`>%%w_-}v*`fq{< z`EP-T_}9S!{@dU{|Lt&)|4ul>e>WWJzZcH)-w#joKM1S+55rpjBe3587;NxA0h|0! z!iD~gaIybs_)Gt@@C<(|{FVO&c$R-NJlp>gJjcHUp6lNV&-cH^dHaq2*Wu0Nu|K=P zE8(r=u|GS&m%%&8V}EviSHpYAV}ElWdF*c<Admg|7TfFKAIM{W^C)@jZyqO){rN`Q zTi_qbV}J9a|4sO^e;a&-9QEgo=m+7S$Wedu207|){!EVgo43eOfAcmu>d$xF^8Ik; zujHt|d5;|RXFs_Wen^h`o4=Ez{(S50R`?0In9si7GI&XFIlMHuf|K$uu~f6evmAbd zrH0*-WpH6=Ib0lC!P_2x2)zp*#a_#9z;d_&d!6|^_By`VbQ$~vdmZ0zx`OlS5#eR< z*zj^VGQ7ex@co_3;2*Ix@SM1U)9itfWpGerIUEvM!Dk*DB0D(W{sZ=AR{qQ3<JcFn z;#~#@Mwi1u(G{G2--TrnE4}6LJ}isPpuA;pNZxWdG;alG<F{g2!VJC~-ht%|b4dO& zI3RyH9GJhtEH$@cS!&i}S!(XUvdnyjWtsUWmSyHkEZ3O{1@D_1=(!*8$=1qFZG5&h z+PRHSWd5o1q`*Dqjn0$dpF5uf-|9RSzTNp0xV`fX_}9*-!uLAQhT$%4=3eugF8|DZ z&}`~*5$^}Q*kvWB{tbJy@v9nh_8by;-c;^66wckVjZbwx4_`FFu9E^UnsC?2FxvGb znBR3O?9}xX*rn?XxM$Z>VYjZc;lQqK<`r{g*Nfn9yRPKZpq;w4nfJ{n@B=fUdmEn# zJ*)eqK$|(c`($`d_mkkc-KWCyyPpDo-F*hUu=}a-;_kEIja>DyaeG_@b9$`glcWoK zw8`gqd)}P;lR33#n|$=G=S8r-=StYna}{jrc^O>T^9s1Q=W6)No|ohr=Zv10!drV@ z4%hd*GS_h)@A<oc<2*w=uJb42ah*4a$94WpJg)N=@wm?0#N#^KiN|&R+H-Bdb>8cF zE9}&3J?zr!E;gWt_UZ$N_1X^}-D`h1qSpcN*j@+1>Rtn3ZLcA)zSmG5!#?g+20!U_ zJp8QJiGf@vTzC<0PDBe=!u-OYV5dUI$#o7ad=vekLLd4eg?>1oFaQS@hTx#WZTJo; zoC${(&Vs`V<M8Oh3OJ%L0go-Lf+Gu)a8%)ZSXx*E%L?n@@r4WEFA5uZW23TgQXt^W zEu0MJ6`ll7E1U|e3r~Tyg)?A%;i<5pa5lW7u#LAmPVN2A+=%m=-ZOc(<I3K%;BR}! z;WfQ0;O}}T;F{i5@b|rw@W$Tr;my5k;M(4G@Ydc7;QHQ;hTlNxJtxrF`B(2s_)YJ* z@ZY`X1-dxh_PWA!aeC~v8ur@j`P?o}@4YtV_HgR=stxpW=Is5?+?=y`JI~mEoZ9d` z{xkTjYRV$^)0|p$wztVQ<a7-8N?Au+qjO?IN84%6(xqaPf5&v;iwO94oG1JDw(cTN z9&F|0c;o!phnv{gWMdPuGTy`om8QgMn+6Xulk3VCR9kgSqA9JHXX%sc(*9P#(<&u( zwF?ssO^JrtgG{V6S<#fNtBp4-!6o+?WJ=>riOI>D#2_;&DIVo@4NZg0{KOI)V6Y~F z&$_1)ftpSPdO8srgj-sFtJp+fky{PXm<}JBjtMm#6M8x(YbOS4w91Hab(PK4iDOMw zqG{IHl31xKC)YL1Z)}Q7p0G6H)!rh3r!*!SJWo%pjn^a^>*E!PDU)KRd`V+dqGmvB zyctzKc@nRdEsR$;CuYq`c}%UT9#CE}FHsXWlM?YtPmR^iO*BkiQlH2eDyo|+6Q1|z z#n~=$Nh!xC$LCb10>r9n>l#vyl7<A8;9YuhLo%&P^0~kDDXFWjPH6RwUsRi{t@6T4 zrvF=*#s4Lay6gxiCFV9H8s~Y@mnEyc`)l^ocQTsJj8h9F<0Q)&M`=S{y%(JZ^Yr3s zTBWDcN*kLRnk$+-w^u8~F`zurkc?L+f2p-RASThKER^Q}?&MwL6|=M>TVIV<cyUP; zXroa@E?ZDNF3}WMXH7~OU0XS}E?%j|QHiQ#ZQ4~uLDNOjSEmvojZcjdKw6kOq*~IB z=9JY-%B1GnCc0e5taZ%S_&KLh;Tm059tOn3GAU6}*H9_BPv3j=!bGigRZ3QEA&6pI zxP%)pzB*Al$J8`(admP|d#}nl73QRP!->r`WUV6QmuYs5+^tr<B&V^)(ggKaldNUL zBDiF@qfI(YapRKO3hC%&$wYPKNz%EjiNK>yY_6`huJQGWTC0s-oTzA)E)cJdH?%XA z&apX<S0>tf$bCAPXeQZKZLJJpi3SEk8|jIO#Z8kEjm_0f?QU{nUG2o?M8gtmY^*R- znkux}#47FBQ%AxQI3&YkQ;zDClBiD9cp<ZgB71E~b&@Kgt=HO)>;=?esnSR*!9r1u zCK3XUT7r`XDH);n)iX-S5TZ`0f|7Wx>e^0Klg4VY>pP}{&bWAeJtIb@DhCu-b_j=G zb4~4k44ApRae&TK*|D_q%uF-cL3ZxU#gz-=wG|1Hl4v4DD3Yz><|bydiUuu%@&r~X z>Yc6e%F0<b*(LMhwN-@UlDdV74#x4d?E`t2d1L9$mv->b0?gzt6<%ZQ5Y)R*dYn#$ zos_87!E5JOBrP)Ir$Txe$Tp3y&346VD-(;e4HCnox<wr#$g+&D&2ki1H_(=rq(aNZ z6BwLXAEa$w5;~e=C)PD3=Pv1Jo>E)kl|7?Dobk5O5U{*HQIVXR#4)9|F|AX{Oybrq z^-Q`NOX}(+m?VVZILqQCqk}PXg|>ffv!iJ$OX_75)_yBPx{QA%lA6)A(qU`^vbFPb zLQCA`vZ|1QtuZ@}ovo$GMtcj%!nj03RiZ4Olv{ck$Tr0qDUM`St(1$*2#L8#(WTQN zBm&#msuS^sObqR8<7?YFC8e>(QA?T<;~N+Oxk$Q7d&}s>^-1xWlvvQL%IJoMx`xK_ z6&1}5VlUTuw^`I!V{vsd-iT%+E~%~)hg7;Ml0@ogN<9UP-OFN@MH^endrEDCG<*UU zvus(IDCO=IO?3@RSkWb_8q`PbW2dsl;<<D2CiIv@)2Mipw55(dT+gJJ2`L52TBV8U zN-p%0SIQXNK6xpNCNJfX&{Cf|%#_sC)VI587e3y&DnaXN8J=m(iRu9{)&!LduF@$7 z#2RJ!Oj3SESX;zi_*mmumVFKJ>hk9LdK-oGqqIW;pGZ!LT58x+Ypq3weo|GFY!ZKQ z(Jj+%T7zBKdkYq?pklSjCS6zI_9`;lWK)-Ik-4|LuDPKiL3^lVsdiGLp^;v9VqHUx ztj~xio$J&}m5CxV=t=3Y7MRyiSNn59d*zdTMRi4zMq0}X9jQwhyT}>Sj9VX2R2!pf zJ5?ET7(!Cklu2b>J<GYKMajlQajnciGSA9tfDZ4?))ZkJT?$-^SM<p&8q$tf>70~Z z6O(e-^?a5mE31@WV?##O!c2Kcc1O|oQf|3xw!7V|ZdXFZmGOES%>disQWyS*fO3zY z9as|3J}~9l-q7JznT5>&TLeENNwzosjDV8%pB-4z-aasCZ*Ryn?extTRHxOfB{Q`w zO+QuG<%}*Btl?~X=uiUL0VTmdJFq0Uec;BQd!JY>bIH$5(9aGm32Gmh5^Qg%@XEkj zu+xjA6J-X0-4Byx44GayEwPG<L}TL#YMeNBa<XE6;{=`z8SDu*Cs|DwRkem^(Ud-S zQe88?jKPKu&f;($BXY7r*I6t9=3(cVPK4CMgu1%wQLNGDGf)$C60>A*7v_2yKq=6L ziAvV*j5d-$I}e%E^M_1Aa@Q=cvSdRePZLee4b13X@W!Ti12zq9XD*wTcw^%ti9u74 za@Zx=gp{*3v55RLDW@%xjpFL+x<#X^<F)hCW{G4M=J?JbNpSiqqEG7`Cg-%hK9v^s zf;7G5&2t(n8j^Do#_nG5q*N}uD4MGiQ+q0Qe#*G?89d`#!lapTRkU+S7Ik@(6<}Vn zy0U{!M#T=MdKOHzO&yF)vM|d;wYa7_<EV)zYcno8&dLK&#zt|;{!U}YLUoeDjN6WJ z<+PO~g`k@po^E$GJcl<##Jqq^o(q$#)pX;+3nCe(Z#Buokg?IGo#Lkth$(-m@pcA# z!DyO)(-JmsSO!WoJZ*I}&8=hd*4nc3xT?~KJ*UK+<)j33(eL#tFOWX@WnFJ)gi02H zS+VS7w1!L|`k2msrX=22!Na>LO-iZA+VA*y<2-34nmS#psw*L@R@J;mds%*^a-chy zYVh)qF%ViG{?ozjl7ZUD>?)<N+?`))tHax*+xcQv%C(6TB}Lp%<=iQ?Non4uMo=r5 z+|bMlj_y+vukz}F<*?|?oUCGLlU@g)g2jANGO@_^2+v@jVP=)qN&8LP(${+4Sr@mn zoRC=JJsW$MPH0HTo{<eN4Q(9bu-sVI#%$HqrQGQSV#dT4ss@$IO5{nRwrMO+;mvZn zR6<8vab@Ksc}mx~b#-lrywu_|+cds5+eN=<N_c@KVLW>4GiU0`v|FFGc!(+I`Ke-_ z^!}5RP4mVk=O<(rg>_>cnr@bO`YvYg3GoKTE?HH{22>(7n@P7|<4sornIMw)pAk%o z!v>pU1=THk@{{YRfC_8!cHOLFT(UM<(_G^@;)^qmSYugoaiUVLOUmNg1}UyQjh2-T zZWT$K-JjC>@Kn1|Wg0be5<~}04PmvCd5MboG?P@LYMeD{i5F;0qA6?9ZG&U8oyIyP zMky=ns!VGvdouxaKO|v?b?w0==}}&tb|A6gwd{1L@Z4Ft9r&!BM?2m8v98H=R?47k zH64<zno47N!p<0)c^&ss2Hj;DKewH&U0czJcHS(bFh(tDca@Yt`aW`F8V^0iCM2e# zhP2amjaJKmNAZPhBv?<`CRI&hh&862QaD-8WX6Zbt{Nsqd->>E+0wN-`xQLPt1bg= zleIRs+g-D^^dKkcBWE4PMol$?UAtiN?Ag&KX)aC3zK0w$okX*hOC{+$TlE>Pw5~aI zOV(J{K^e+|%Q`04WrAe<)1Cw@XPxJzI_<Dgcs{o2OsXT0v=LRTt+?L0#GKN#@w9X3 z1(GvwV&iB^vy|m*)?JcG;$w?I_7~J?^PYBA>V8E!U@@!Vde)7y_n!{FlQG^gl&zjw zvOF;*&2th~(}reM79MQ1vZVCF&@!v*s;pxy^FXy{*G)C6mr`NuSk=|0ycp)~R;D$K zOVrFsG+14hBwn!QhQ>Nimz-;oB+shooTi%gGHX0ON&95XUSgfH;Us&K)+MVmn>)Qs z4<VQlVwLKoxlL?lLqN70)gZUzm?25mBjxs4Ks_W0yY!GN<eZD;Nr&J&TP3U(YC6h{ zt0Fy&sVDn;arP6kMl*X&W&~4ryXCCcRM>c|)#PU)w~b~O9@#^TMo7O;4KeC&lK!lk zmr?7G2+5yy%uOkpKi0h(UV_LXSRG@$Q_Pf``eqVKd&`AWDx1=7xi;G^$(%z?rs5iH z&p6n;oE)!Gqprejt5mm6RjO6g>C#;b$F6A9EVsyZYQbh1G(v688r&<WtN;}mPf0#K zyxLprrsMBulW?j1{B)pphEx|(Ulw(>jd4A-RkvI&1Ef9`krM9&Asy51{1)%#8gh^w zMe5-qeXsOdC4GnXmNAK@_68b{UH|9>Qi2Td)U!IhIZ)=7>>bb&79VvrQuB=HJR#Pz zs+Gr^l4>3y^};$m$yBveW<;$i5-Zz?Y9+KvDIX2txuuG;-CiAP*n00tN;U*p%-7l& z{-<e7<t2Ul%+g0qwvnY)Lu#r>FOF=8_`<}5I@a#$+Rgo?bSia^n5>G_z>?kKCOJ4M z9VLCSRz`2R<4#8Dpz3R9DJqS}JzW6uYJ#1_I@)yB>S!z-C9|+8XUkUhFZ4OdZk?uG zBv9tslxKN+C%$Pf6j|M*-S}zjk`+1NHsfm(oCg7~R5B}`0lN0l9z7vhPXKl&RI&j? zQK^S2=^ml37%i_Mwc?a;joOo}pT1LZLcBJfjzJQr4k^>LBh^d1W2%a@$BB%&oKvJO zs!S<TO{H@(5m{BNx*kq@WL&a`WEaco$vVTkUM`Z-&BT^*=|vf5V>(zW!QNFG&eJQi z(!w@#CMhY0O-agCmr|M;zP$q|y@skw-6d5ldSIXOBw6j;8HeP^+YU|NJ=;ypQyVMQ zO9uow{b`uXzL6JNw@*}0R3;fYWX!RlIjf|BN-gVa1FCt8?yLag8mrVL3$~O_YO}X4 z)W4F$lGLm!aq6>yC^S&-C_^5s?Cy+Sp>>ryAySJziptTvy2u$z236CoRK~{Y#9}qZ zINq#f6Hhi|mZ+sk?#II$qpZq>$+~8q=y33OT*4bc#y-WUDi5x+rf}ffAg^nrcHL~3 zNv-8Ly~9hAZP#|*?oq}qxy-oikdO|nRZ$z)jm*qsBo*Lo@v%FTFcX{WI9G~Ql5JUK zHK<X_MmowI31Oed(@ycrDv;C+mG+m;_@De2?>yP1udPhoQ*IJ#v=72|%*?nr+9``y zlQ0{|>Ux-&9*8o}K?AHxeZ(8MWYIh}&}gW15K}se`|87wN{LPPaO{*=!V;ANVb9s# ze>Yy3Yc-5qZrAa)yc$cJ8+cB!j|_Iy*G2uVeC?=j#<8B{hK+ibQDxJ{D><S_?Bx^3 z>c)w6NXyms!Iq3QkG37Gfn#)86K2AWZ%Fd06Q_@QO<g+|`{gysM%`>sU)r?y`ic#0 zM=kY|G<f?y*3UNnrp%3G2T+4bg|>6Zb3xib3T?2)biBIBZI5tlS;-E!=Z=+gcxp2( zinK4a$m6JP{>lE2RWyn5TI<lgAgfBhW!7p)JzZ2X1GCr7i%3RJ3o|Z;7W<HpF|{Ao zGWIF5%R>v1vX-68j89tAt+%wxoS0~4#mJjWc6YQfwWF2^QJ!dG6swXm-Aai!<0FfT zovo#bIn7m7?L*3$L=B@DFWeN%5H&Yh)vVhCnaDb{l#Itt&+Hj5iqLzy&)A9^8+k^o zUNSk^l$}=Ta@FxAvIfe8rDWwHGHX_9=a(ME+F7%%D6Xn%NJyv11Q<W3k*PP^;ysk< zgpvt2ne(AJb&F%X43IIBA88e=2`Fc8hRFD)awcn?-FnI%DyQSJP>WaZ6snxGa-zlN zW?e1So<32}+(ZYUc%}ztd~~U?OAluFUD+vJ`})}~J>{&4<AYuK)u;P^=I+PWHOg|K zi7g7Uma%h_GDf@h#!|XE>%Y{qLAwi5rMOGa)b!NoHLJ;WnLBy)Xm=no=Jd2e>hzc; z<3-vgGq6?h{$ILl+t!?Ik!hOhpyRSi$pp0hA>+=ZTc7cZ<+YiNulEWqX`t|$l8G!Y zJ=K$g8uo><%w^T_sw}6MyVB}vZ^5fO+7seU^Rfa-<79_W3R@mP7ps=#uOp_e|5@uV zv4;<pCFm?DGHFfagv83zSjHpM78r9fW~pKpZ&{X947|&=gaV$I<yA7aTvAEt)Mi<| z-0AzOnTV;nNp*Eu!BQuYUNJ6_cP}!*$ymImxS=7wBx6gTex;I>?G>*aUt66O*w%e} zTk1OP_q96(mP6^RV<T;r98Wi81@vC+O${6!e03Jk)9zF|$fU4zPO8nO7U0qrQ<={S zXSbDh_F(o;ot<-lATt*)=ZZ*ec8V_RL5|MRbS-FANv)X5<xMh{pz%sobY@gd_hnTZ zqfdjX(ky5UDQn84(%zBx@tW-&t)_Rh>H_tW$yi5XowBXQ4LX*C^^m}lX?YVZb5VN> z7wdyb<_bxUb&ZQJ7DqYn9$5oRZaE*yge5oDp$mwVgE-S3`uciV0~4LR$80EOtJsr& zt50rN!X;Lxh^!)s&z^cT!|e<t&jwwnQOgA~El`7YL6dff4`+*%phn`UdTitA@>-nw zvks=)r<TF0ma|!5>~pRzm}D`}Ya5MhCg33%Z*Solrd<em1tb-E?u0t;I!P1D@02sW z2a;O)r(PJgPdBMWc;=A<|Ezb0y-@mkv%Juo3EzI-Df`Vk9qc+rzx&{l;OtApEiFS! zK$YF*!8?Nc&w*@#=vkcx6n9nw)Z1jc#a~}~OeZ4a5<mNpkg-Wcb+qX{lC|<uOF9-> zXxi<iA?=npNJH99b?^p+UdklF3+*zqq*Fg3UNN7ZkSe1rrx$P9i#Sy;pI6sh%{xJM z#N?5(!+VG(=DpvTc@@j>W)NHVQV#--a(U;3jg+~WCeX1-d1rMdHK1muEtykO*G-<s zW`ew?X^I;wSow-3YYtDf<CWK*v|milY}}^IQeL|-%ZQo^q9a_&!FX&}-*PiKxV8nX zk9T5f*y(L`v9^0%J?qNscg@>h-O*>KSJP9m@Oahn=Gi8FJ2o9)Qk++<Qj<*DI=*%% zQ@W$<zPEYx>>bQYa(>1|(yVsAaI${ngoU&A1&J!tdeWw{1g{T^ADcibOA<`PxFt?$ z@1jd}rgX87)_28u8#)nZ-n9N5ZS6izVcUs3T6vpN@>x22@|`m1(M!sq8OlDR;8Zu| zCyBAU;<k~<5pUXWH`mCkwVBUs*wMV5MIvn<MiSWGA~Se%^?X^owfC5_ORF^F$@)Ai zFR4p0d9Ap;G5a-j3H0BqTOR)hq^g@|DpueBgA23UO4h~t1|2mjF%>gwd8)2vJbjGL z?w+GO+aYmEc}dFfkf&}+$m?w01yaKQEsVs&<elC#(bU+g>0p$QquBb;&6!<ZvU}eS zgY7P^mXz;guIQLB%Ep$L6pYoRRIFC1FAqp*N>YpElU?#QH+z_j3i1x8cuCfF<0Y+! z5l1I33F@_-Y?BT`=>Vzp64tv`cYNAkn>OjSY1jX-&80qzBroJk{6F(@DTq|F{hvpX zZt*|=t^=~~n7WKzkW^7IW!uJ@H6Ua@^pf(EO0xZZXFrAn9th-h_x~6o)p&Oos6xl0 zoulv2UyOZySc;qvLDV56gWjNCLjU6>1#MFuOx|0^I_Asn`Q$pQmdL<l)zORDQyC{8 zB_ZljZ2x<@>^`Ygo-mte!Od0kOj&hv<GfU@^DH`GsyuF+T|9!D8a7}P4ZKaKA&83j z_3Y{7WF@+!e{7<*3N<t6=u*(LY6k6#T%JX$!&_H+7Ah($G)t<ikQtXg1k2lMvXhoE z*QA42+jP|MBr(s7Vm8#&mGXkgJeFAeaE10%*%X+=`p)oHm{oYc#VR_k^X}Mu_9odB z(U+)sbX*i)(r9(b3@dd$r}ux_`}*KGkMq7g5CD%52oYz=mTbT|CvrojGz^m9mnW)8 z3KWTi5^0l^mDH|vJRAg6AOPb4ne5Q@-2q9gL`tMYN~A<ioYqa1R!!KcI#p(riIUPC zx@BhE8F@yUp=PKVdd8hmrksvE)gPLqzu)iKecyc#cL0^hszL`J`|dvb?C!H)&p!L? z*Mp9S*c~Tl@wqPq1^|=FX={;KuHZ@noN9!rlkF~bl~b$j3c`*zELv(O5*Eh13&n(B z!G(=MDORuoC0I%8k$DJzo)#N%1BB!>L86g2U|F*cF2)Es5*$O)asV@`7U1!fm~&yh zJp?@nao3Xw%7c~Zu(JnuHL}lobnIf)E|{Rq_scR~A&>3(O&*E!h)&O;OgzsEqV&*F zj8)~SIru;ToX1H;v@|#%;Nqfy#3@x|;s@!fQkv0{OB0Oq&j7;A^dJN+#CIHfIgiXA z_!9Q;I6x0$6p2C1xMyvcWZT)Xc}$V5@!05<^+01RSCYI?wUO>sFx~>4uxd-Yp4`+* zCwD`+sc9^?;Akeg4mR6jvZ%mEW+<Am!-#^&=?jnSZD`zMw^;6hcw#}@`8AE??a;#U zX-s?;>>#!11D#kF(ZOmF7`s`Pq~4c8YSqrzu?egTRG<Zzw=IPVZX0D+cp*)Nmev76 zwo(zqmjW1QXiem$VG^ifUwMWf%z@hm-$4kerWgd>1q?ue6B`vYgdCss82o5lpu7)O zgce$@*y(yf;;KVzDxc<I4eVY=N{=suwnyPR9o}Mp^;S(JREUtCFsI-a2QC(P*A(_R z3(OpNT>FepO-vkwax)Z%T2yA{0ouGAI>aT5ETR$aCl9M)GU8+eX@i;VKX&(kHsy0^ zBa?a>LD2TZv}JrFT~Ca&YDQV6E0GaxIt5D8kdU+zyIqEx<6b?}E3rdugp99>5oNv^ zZ`A_en6ffU?FyhZcDn*-#!gEzWNB55C`(Ovu9BS2-Z%XK7M2$#ljcfgI8HLS33OL1 z&@P_xifSAZot-&z%1+dHyD6Y;Z1H`5zjqx|zYng1*n*vU1Z#G<iN_g6#yv|o$uvV& zn%H@E1B=0s91l(5YJwS@RN=T{Bgb)^B$$D;)C^&Tl3`;E69!8oc4Pj=fU5T@ue@-_ zurJ!qBp~(5gEl5R6cpCueR&+7rJZUfvq{NhRz_qkfcaqUdY6uwvTJ~T(-V4O-f5Gn z$71kU>tNg}5_()UcG#{(o9V0HL0M%gS07)55M+udrAQzOR3iPA&`3&(LnCvjpEzU& zlHIfK(PGA)RhIxEuuzm-vTNUm8_z@y84VJv_rij11$9PtZ)Gqy54m*yObW0vE1NGg z@w2GqmFGzl#tSLSALdvcjg@tcsBCsAD%O=k0{)aq3c#Epb<8Dr=r25w#Z4cMt5C`5 z6yAemOOloO1E&{kceqe+bBxY4SsQ4Lg9fS%hpXXab|$Wd2%*96qivIzO$Anq;vR~% zt0AoAe-CoK7S1)G*m6y}!)i5>?wX!0`3;aO^GyzbPO@5foOxf(8*A>XdGDWkU=0k_ z-x@f_r)GEw#A*rM!`0r^5Z3a)8&dz7)glm~Yhu}4XSH}xzpEpG7yGRrV*JK%1B6|* z2_lvo{MqZ-1C4_OC_}A;ik)k>cEH0CpI}wfP}I=XMb|foCTQSdyvRvW2<$I{j8!AY zLv{y*BEdx?^V9)?XOO<gIU#*+1Q@GE4wCIR1VvCru@Y(vHDQ7pp>ud_0j{JpjioC? zwy`hTS7Vn+L<mPRyJ*~4e9uUPX5_>GZu61=5CI|hH*dXhbIGn6m0i4BRi&2!_~D~j zEcFXb+EpHOkl;o*Wcf}*tL4~bBh?l$tX!zeBw(eW?Hn06>trRAY2h-faMD7#jotLm zp63@z6Np$|J4gi+mnwzU48urvg4&9ExHF7M><8hzMk2o?fO&tu31X915-5Q6&}cVT z7^<Niu-$Wt+t<^<>DiN9#k2%H&~FUMPK84>n4mU!s1&r3O6}ur?!XLp{_(`V&u%NY zc561_9yIAtvfF;o7JW4E64=ieSNfWq)7F~>YA8)XtJ<3HQ(=BQu|B4ixyX8)D(TX) zDEx81eao`1ik$tj_YZyFJ5lXeI@YE-7L~692H`1QbR?>`hoaS7Hx@hE;4>4~fF|yo zt{>wLiIZ_C#*&4I*JW^|Q;P#>t7<kBc~p#YU}hRyK*2MySi_C0<FO}J2r%MS=ArtG z!5Cy$z`(9zloe$W6#qk_DMmF4V#q>N451@bCcNbBqRWBOwNtdE;Gb-IiePONA!&Hu zisB&FJXd<8O?RaqN}=V#XcRAlw_F_*F_vf(dSEmWnCzRXT}*^@b_(q^^40w#$y_1w zuvXN{$F_zBy>b*pgIWtXvf4Hte*r^MC5)pPhVacGvHg%E-rJBw5cUtW^aMLa>*YNN zQ3&5|nnyn?H{M4z<aM;TLyP*_B&oFnvJl$@_Ut8!E>IqUR`d<yD~QrB_cn8$sBe(! zHdui_dGgv|#c{2U8R8?KiBc6OOlYtM6?q$1iU4X@u^Vk6a_WFZ?1p+%dz%ybxv-d| z7cMwT0HHF#lQL*lMOkP$jYo9rYPm2d+C_78CCxeo&4mt-g4(o`jCjQknj~@!0Z5g4 zbrLA)=Luvyu~ls&wO9CrE!5tLOxRh!1Wv(fB~*H$m0%(#A%&B;FiK+ORObjCO4Qp( zx+DVZPn_Z{abDJFh7r%U{CR}LF{h1yfD(lZ9=w;-G(r;6nm|n}9!<VFU(y7_95}?s zB+y(YAWtqtNi>0kh1=3XUhedE_Hta-jP+3ZsDVdL^18$mTn^GL38{={p#D<LW*?~c z<|P5{JBh{<hq-5#OC?$}iNSsb#zc6xRhkCoTL6yP)sHFI4!`i`ow1pc<{Uhz5cw~f zkgX%vDH!?S)G-V2XOvRl0d7M@_e~+pKgh=F?qUpGzy=T=z=L#};vVo~MGD~<krt)Y zVX2!ZcyVAqozA6RQ(zC!G=&<1Zg`<|TBA)0WOj68^Rdc;Kff~@h4HcDFnStfEV&hx zbn_CN*iY1;1^KZk^%~s|s2yr5pGm=9u*Gtz*94|s&{ApNc?w}u41*sV-FQ0gTYup# zO&DV`t4r2xTKf3?6TY`;PymlZj_#=};NGqW$Byzi(ez@{_SZm($21Nch!{*IJrs^j z50n{kvWz>K{DN)(HlGy?@Fa%2OY;v_<^xz`I`$CbG6(Jn;OW9+JRDiVsm6e#gJ3*! zxxz;!S+#lJD887bKRAQC%yFHPlorQl9oChnP@4!1N5Zy)gn-43bTG$wJa-0IVslkp zf28{0tWOpntK2q{DwWh9hx2f~hTO(1kRh9z8Z16LAP6rPz$Ox3xB^MuQ~Q<^T4jBi zRcI8dlokD19l=RQEBF+N{`t!MESI+(Z+AgEtIR1MnY&(&Eda_`RzmHlIEw$&oa3?x z&f>ww;e@9O=Nxn^TuJelXdaoT1I--!Xt0P3XRG4oAc&*i*rMak(2xe!aoZ2nXrH4h z)dihufC_jJntytthwJNi|L~?GKv_CaQR6NWSr6k{UGMbQ_wjmg<L(mc&?n*cafDm_ z1VcI*H^tp3h-o?^0O~n%jbk)nhezauswH`MnOEt0yT#%iad(TRrk*&DgyV}@fTmtq zP>KU>f)5v?rBGxt<De?l2UtjKrqlG`dCL^b8B(wgR;ke>j^^9#AWn>P_pqU&l$se@ zba+-rm{-F^Cs-5bPF(C5lJg6TiMv(uRi27A>bzJh(S83S?i*xVk!YI%S*?*HLUj=E z6m<sDBqSS`4CoeZka)9xA^z6BN~pD0Igy345#FN%wcHF5l2=p34U#^SC;b=gAz?yC zr*XJza#n?alO8M!*7{gAxn<+{EH)tlOs3HSOl-eX2}os)W2u|I`xkN3^E|eQp&(1R zw%xmDCngZ(*o=3cG%N-n*_>zJEqo&=oSlil)NkN)pO>1wvPk?Y*d_f22R6e2d2!}T zO~>0ovnn(llI#S0<UV16G7uiPi2z_!5X{0x)<bAAICh5{L_@2ie5zx&9F|vl<A@!G zK%5+GiHA`u3XK6Fj-<ki5<`rd5lbaJE-5F#K?cOr<kt6$ADS9SN6NgKJ>wHyW}bno z&4=tZg<+F#<7El?<>^d>$(YYEmj`&WbSOQJfBt^LOjst^&JQWJ_2Nl$j4jZfXQT7C z4Q7CBk;c(lgh)k-7M{Kfw(!XmVvtHheZ{5N>=zYdvlmm-D5N1blLby!Opd1X8`4Pv z81u-4NXBz*+km)aC+2Yg10uSUpe|l<7w)aYsVxX_^9%GLqiBXDamBmyAdO+eU8|df zLUYB-H;51!rpRAyvnqF}GL5$F*#PvO=yquBvWNl5mes3KMa!%wY|t+V1<}k$hVGj{ zSR<+HU~*@D3Trd68=sHRBJCS@aYR0`V=hUVEK%z$XZB4%5?A@gZj9~P9yjkeuzRZw z=ic#UzA-d!CqPp%En5|l_Cseg&|Vm(O~o~1lg4)zLaoHoU|_HeF##V5eVahnNQrGw z@zMC0vypn&ge9(qvCnQ+S94~&2yT)QyM40>-s-}!KO0Hxwz`iYXv?v)<P&E529rlG zQlV?AmAWxe#(=_OIJSu~^=VTm?fO+3@Dy(r0joW(OO8`G8dJ8Lxhb?0QFRxz0Y|XT zFz*gmCKk;0S)TtkE6aLxp8HAFLcNtx-C}~}nHikc^}IqTt>AZ0mFH)xvl9zLC@E|s zMRZ&#W2}tITh*?yN6b8q&VCu*m|Q`Af$S)a#nIB#yt{AKLZQaP5r_Si$r5hi@m#6} zoR|2RfEO^CE~3S(8r7nqHxo%4uY)*dFt`6qf_gGUhYcM_zD>okZ6ve7A=$1Cl|&l4 z8l|_QIhu{$b_&?sJYB<5F_%A=lLC&+q;}MUVI2&+u^=0!v7+f<H~eD7hV>)fhaIQ2 zPZEnoaV$id#)y7z4$lP4QK6XQ`SLxeLM-pXtwS5B)0!??3Arcz{qk@GVM!QTip7MQ zVZ`&HvxqBzWB$HXre}peqx)CswqeGWlOr^Xd?sZND=<8tSP8eCWvR>ookn`!D{tY8 zl1Um_qyUNbZf23;;(ZKJ@aT+o4CQnyQM+j`*a~HwpF`Ze2q6ol!15id2G<Zp-FB_I z9p|zOIk1A*LSk?dTY`=aaR>1s0&!!Ai*8Ifgsm|S2bR%9G-bi*a9ruZ+q|tIRQ*kJ zRk!bC)k&s`-Uz~;a`1x6L%LE4Dh@mw1Q4>xG0eMt;g3$0a8}4rENb2_WawaPdUc?R zBSxpO8y_b-s%SD4S;19!34c{3sa8d1hl}Sy7)mn>@kt%vf-klw+8vI<^*&)Uf|i82 zamGj0<Q+u3#D6|qFJBG&O|3yzL-kSB$R#<Dt&4{skn(bM_<w2oi{Un-DxN>W#1E<j z>@l3ioGlb+1n{*GL5_guOK>sSxypOgs$}@V&D}?_o1F?9pn|vEs2f~p-N8D+4Lfs* zGo7O)lQ0!Jb=tf#$u}m<%}~X9Dlvli0%XCZr%r~(q@kAX3+Zwb_u4^PHEee0C?qpz z+DbjJ>8(wxDIU5&X`#wD<}{Vy?K8%laG8~!K(qqqIWl-)oM;7)_6{2&*eWIuanQ1Q zkB^489!Bx_W&M_EWc<)rY{OK$z{rLrTD^;k;z&EqW?_0AZIDAd#0aX{f-2E2>If+D zMJv{iR`ch)K}%xTS;6T?X!A^g(un~Pw_U|&N%MX@brx$(XLMH>AgsHL_GC1y))*n} z{IEqAY(S!M)y;b$IU%LF-L-2($;Jv5moxzp2nv4NK_bF&JtFp}QlH1`Qv_;uBlG5W z%=Y33yaZ?#=2^m+B5AG!@53yhRbh23y~f{rF+5U$mj{sZWdH}2zV`(?2m+diz}wpp z%G(~|dR7&a*zw9~e0>L2oyJpvA@w7_O=J}`(wIfHK|Kp=)kl-K!Lzd13(*||O-aXy zn2|?^VOB#Vkxj_fZxb4b!7_-pw^W1hRCUc-rG4`cqz%c~swr&bfz|;LF4iXr+^kFz zP~#Y|W2KOJfF-qpTjVRy+bEFIG@8{wNg^#hkV<QKlhR1Bu-vS4ttcdo$Oll*=bC*O z2H9%{XNn^zcM?)Vd1O4I0%?XzN#IwcQlgl&no+7FQVNO0-vTw#4hc7HQ0aj<f8p5O z@nLD>dt6M?O;v6ou~~z|J%M=q38R^}_}-Y@-hy6Og}?3&4%^v+gydHu!CSCe0l_Ca zMT!=iJyu%f%^*5++JX~vmAeHKHt^4470qlaF7P6rAWS-2TEpSs6lXoy(9{|u6223> zWB~D9)F`wDWp-^MtM~&w-kVp?2b^e_R=2eADEP9ZF=Qs=cGbnBcvX+i1YB{&;AlSi zf`G|_cfcu&1tpmcYn4M-qtv!ktf@oogd?iHomA{9FFU$yYo$>hp&E~}7xvB}_Uz3< zsYjZ(6gKa-^rG3I`)Nl8<W25N435ys(!GjF1{lQD>s7Z>7(p}As^bwHolV9Xqd2Pt zu;$bZYsyBmcQk%koVLBi;tF>3(n_#fFVyfEgTN8|pc<fACs&A8;*@P1PJ<+qJk&~n zB3RfY89-&Mq6d2$X}DQg*tGjGD*UVz-5iejT@iLxTY1pRaPuhkO|b=mtInda;{TxJ z1GwjrNMr{*0h;Brc>9~TJXpg{xf&`dvldx(Wz9f?G*iVDR`ZqPwo{oC9W2^62^Goq z<3w<cdMUf6?X_qdjM<K`5`GcEnsm&ZjZqU9VIaq3@DT)BJ6r-70ho?-E!N_^)kX;_ zU#w9wyUk<cks0PY3cDr}(}LXNgMc`1n?@zrc?zcI4>?rEe+Jj>+x{woMG}fZa%?)s zCx2QAV@eXjC4zJCv-nL(nL3GQ?Y9YM1(03P$8ijA?1Hi4atjYAX<wF`;N>M_ygTaw z^lG(8-uH?ZQ_u>n9Hsn(0+t)tAHq%nK1C|eDhO%onMm!Xx2@v2M8pS*b<S=Sr%2%( zw-0l~$FX$#nI)he5nkd5&6M0Bp1ii3L`W_OQ+Ets;DFq@%iJ|RA?5tVoGcis0TWDB zMw9yhv>n<3m7=i-T7b(M=;Qd5attU(kq2I#uF|5hgWMU;dFQa~ZRhFG+M(aBayJWx zrA2IKQA?pj2`fqQRuekCgMzXlLMo#KBY95cdnd<cLHX{bEXN+4n!_-NwF#6M#54iz z>@RMAW(2kwNmdpT`iATWwIqZlW=Qt#n(Xroh1oC<r&2v_#K;0A3iqWM)T7AbL82v0 zIvMHw>+ZI4vTp%%BeGIhP_h`KRUC*0_ZoZst9Ou42IBom9>n5m0v(IDL3y-<>)7@% z51p_ykY^owB**p^f3(9V53<no$_rZOOB{*n&ellK2KoM*cZ^Ygm@c5WDg}A(2O6rA zCCq5iYCQ<oG0ZG@`)Fn6jJM9}Sre!I5c~akU?{`wAy+4%+BOZN3u5BVl0={9W?z*d zNY%Dg>^Sh2aq0?jf3m}7#Z>o*e0%L9Z7gNY&4PpcNht6Lc7ItCE>SejA2hOw+71yR zOh9LIWfc2HkBsg&#Uq_TeB))sbTesVH0lT5x=`Y~m}>G>kA$50P2b=%fZ?D0J_BQ9 zN3`cd-rh<|ycN3vr^mhhplB6S^AOMj>SKuQ7>NVVTJ+}O9oVkMu8qEq9m8hFa+=u> zV4D@%g+J;qtL>m7ko1mK1x&h3mQhCX$&d-T40jF4j5-a#!b)AoE1(n^Jv@c?z0m{t z%(p#fh_9$)UBhD>Dlx6dLp!s;O)R|6UUo*00T~?+DpbF5hMK@EfCXw-3%jv>yxPr% z2v>^i_IjH4xJTQ@I8NarH+{nM_Gsq30ScT5yL)tEIB|yK!3n^h1(uE;djNS;H1rF2 z`2tf0T+f-5ADb$*Y^E6WJ>L&qdhFERlVSr0Kcq|>JVPrEZuCE0b{^bl4M*^jI!n*T zq58m{$uV4Bq37Y%LNhxgaX>KZHul2Nz(R;+q)u{;)O8nL{p6NbROCZb*g!2i7#1@* zI$Oqa5&Y;5_Jk)%YeiBuLc0mfPiFC!FQ;>U9%rn@Mh3o*%w4tP{t_tpMNe9hA0ePx zT>AKxhaSU9FCQ*29F~bjd|{i-#7q=-tbg%U6QDr}L1m@T5<r`d(N5g(jnh(wSjBBC zZq9$v&LMe$RxesuA#mWuKo@~AvLv@RWN@trv&iK%x`ftfkWA->(7Y{zm^F}Cf`&+& z?x{|l{)+o1sIg+hGR<!q!e%C^8wH*^kYzGk-Hc^W*6~VcS%jkp@IDc2riEI>9h)i5 zRVQg_v9=gx8hi1fl3N>(xlM4@jO<PrYe?QsvDElV72RZh0mF4w-&RCuCB>u?cVdph ziRznkK}9M{60kj!HVH@Aq)XeeeKSkqS^>O<copUviO}YnGyujBh-xWGJUe3jQ#P`B zt)Haws>D^Uuf^)U&vGJCg}}k0QsKywE<};L@SS1<M<bVzHT#lRo7~dRmj1XVB~0DL zFPqizG*f1)vs0mpHztwn(|ZxCjh8)btH4wn&MsP<!Oo<(M>)6|Q|zWcxFxsj#wbl7 zv^8!!$e=MKk1g%T4s%@d6NhdACbn%tiHOVqL`g|+pfVFiSdfU~*nKC3<|05N+yG)e zJz@Y6D=1?EjA+fU1yAAF45s^#NMYL4AA`k16%Oj5<8%9%(?uMvd}>@SBgG1ezD7sv zrn)Q?B{9m{stQ^c6tk{4!w`@FsGKrC#x1=ZM0w;sfFat4Clmw7F!h#40HOVRrAvU6 zLz01uwdVsk1P6__>I8S+!PchLN8Q8(ylccIy^`pN&mv14^x>dSF5m~wCZ}ePk+-be z&?t*GG|Hx!On#G_x2@x*OB~RtE?5{OgE2z(hnO5g03d?+WwU1Dw2%9*7x(}<2%U_H zN0hCI1MP}7(9<5VZ#sc&1FHE&jyZ`c0%H#B#S%Jg@=Y7}B5Ce~(xMw87#d~<<nNdE z2qbnMh|CZ!G;%ZJr<DO|udk^t$MHHi*8h+cS69t$GL6|y(7ERLY+NyP+Ye!bwL!2Q z0+T!`qGNDbs&hkO{hH0@E@nsBnQG9Ss(Z7R_zsF$r<9Qcc;I_3em#!&K}}4Zwyo^J z!2<Jewn}gHVZHnvpv2Ybt|&n44hO+3nK}EcB;y#i^(SO_M^l0xnk4Amq)-WZw@=W! zuw>+L1u#~gH4a%{hA3_>hUK;kbInxkYt6^(C6=JQ!Y6KqD{>)`;P$#R99konHCcd3 zUwCN)aw85}nGi}l7z&>jp%qcgpP9oBcB|`*CK+m3dA9QMh^@S=rDS6ot1>b2K4_F= zx5^DC64lGSB8ZqqeFT`o9o`A@Txxv~$mvx{C}R|dZcSn*PwdAcyEf@0FFJd!7GBno zjwW%a2`4Vw4#gLFL>|X+Iaqs%BVo;vBu*YTgnNlXfVMc6>jcjPPSCDo#FS;D>d*GW zs`kSOYMD0)&F9`bEc@Q!PqTSfv}sPc@~1KnPo2bz*Jo5MO(1F^PGgR`fNOkaKC@T> zR(y^t0cvsBZ!6K3onU7!n|CptA;AFw)n?P^0AL6_6*6^d@f1!*m!KCh%9>#)7_FMp zANH{sh?zLK3m4SxobI=KASrO+Fc-J>hjIS_?8~f-Cty}Jr=Lw=uDY7q7D<uV&w<TB z;hBNiwY6gt2Tsj-^0N?z;~SASYQ=kh0Mpt5`tYjWQZH*3k9lMgC~0k30b`AM>{`Lm ze8TWO#Oc60!Dmi0Vdg>x9e#eQ`~U2I^2gm>e?0TM%LAAG;6J&}VlJ2Og3-T`)(#qd z>xwS7zSx<|<41m<k@*Fgm9An(uCK3~VQPOx{2m$u2Ka$K^_vkzAHaQmT}4-@Z<V=2 z<{p`M0B@jB`<@*8HWYJ(`o6(J{eawKa*xq1wE7*0u0vi^GQY%B3bm*8sW0-=U;nlU z>j3HiQXT;19l87f@cZk3rBFWrI8VP05nHI=u>mOf0AYQxBM+PR_(4Lz9qW+^5JC#_ zKmz*55Hs@haiigTilg?I{k8uoG8#`Kfm|0UK-wKLU7_(O`Tz1SK7a46BbOh}pZoL| zzuN!Zo=<IJh481-KCUwt9Gykl2=DBmLDbGX4F`AUI@<Qi*-aS2buyOD4-)oMG`eWO z({+BB#z$zZr?G)X4~-jW^wQW!qmRaoG(JS5pGJYk2WZ?x<7OJS(r};%3Fc^QqTzC# ze}kXSAEWQbX#6;hkJ1>V;c7JYIyZE;JBHuSxWn#??oM~Webya!W9}~e-|6<jegN=e z_#T1J0r$}?`aSMo#{0Ic_c3=A-bWGgh`Sdtjw=4nzb0w7kc<HuH5zpqzd+*`Y5Wq6 zLp1)9#<yww4;o7}ewoHa8W(8%3XT6xqXDDmxGTAnZrW8)D=2`@3HtmojekPpaT+ht z_^&iZX#6gXe?#L}Y5Xf1%QPOQQK9iiG=7`L&(OGo#$z;oi^iYP_zN1_X?&f=H)%Xd z<M(MCr14K_+)m@)(|DG~12oRjc!tJd8lR@|>olIG@#i$o)7U}d_h@{L#vjo5H5&h# z#%(mlXncXjKc?~TX#86m&(Zip81+vLb<~zUw+tMA2x4Z~8G?fy<#x|dZYiGPE6CGR zC$|*u<w5w_nL9>?hWWdtcqayHoV>qd#-2~zQarkN5*mHTIl6}Tj+47~m3EYO?A*F% z`$%PY_nw<`$2&H04Gu9SXY_OLYucV3%GGMCm0g=BIp5WCy9woXBUO2P^~K+Bm#aPd zejx29I*xbTa10weAWTpP-;&ZNhjL$Ctqjw)2!SqHT7OrIu#h|6*GUcD1|FZ%9=X~d zp#a|({o>;Yz>n4g_Kz_~pXUnt0p9&{8BXO++7>K}T)&|7;ncl^YvHM)|c@Kv~X zwMM)2c54j`uJ+CMOTl~uwf4al3+-5a&eeYB{m@@O2nzcTgxd$h>wLM6?)<v${$BiV z!v9V9zXksT_&<#Q`|&@H|GAFtj?V7>+BayNgHi9LaSM$B8bumgXpGR<OJkJAaT@p0 z_&kmKX^hi2P2({dPtbUV2BWV(M?+~mPuoj0&UbWo@q2;BMH(;Dc!kC#8kcEYp>dVQ zn;qSK_%`x1CTYykSfIg#8(-_}E;JsYjfpf~q`{DlH)*^D-=(9lEs5yYX?u*Y7ic5i z67iOqk!41|e3nLy#xe~Oy?maMdttg0a_cm#g|Bqvi|Y!tdY|O@LhTp&Am$co4;Q`y z8J2K4>xDydJ}T!Sz)j?R+&)isQ4BuBNY66TBIgQ)q9p#>w+-i8O1Q|>ihYGG9UHu* zu*GbHfZZS%Z1`iS!9o$CItoQf>PWhS5XPMsC@)Z7q4r&R;rl(ru5aHBn6nVjhgPtz z=z2gPY>X2hQd|2TsO_I4QT=m9;s0Xj!lA+zOblFM3ynjP+i&Tn^j;Y5Ep`^_U9c4D z8~pU33lS8yD7#ybT@>w>e6gdjg=sTivS@~cEWsaMmJNl;6PpxoVJVPeSUP$LvO-Wc z%-XTBn8zdvKZE#1QFYTLJMyF0k*f=;iAPA)UQxBTkM!(i#67fFWTJF03EZnRdyq4; zsSft~<eA}M@30Elt4!>*Oel$bVXw-s-mh4X!W>}rVS=<}0C;fpkHa~T?;qz}2*rfT zLiu$J^bz6)F*`zCv()?VM{^rQ9e}nDeHoMxW`m#paUg?c#MGCE7jc<GeB=cbq!|!9 z`p4lyp)2VQ1RzzSAaB)mh&f?s`}Q9u6^Ds8P&ghc{5UHd=@t%IlA^d{khvpmD(FK* z$g`g?K7ddgPcbrP0CU9?>PSx+wKaTMpg<A1_^8?onmuZMTYE-T`LKn47%>$_0Rgun z1Rpu>Gsk_xebjItrK9#WbNqsRHVgJdo=HA2SU7t_u>%~?k^@k7&Y=s_{rBe`$bGy} zN3YIxz{w2N9v@^4!1ClEnlmaexSt;ELtS-PRK4s$waehYNaIGdXmb>5=apvS>3hT> zHgyyrXc<wtO_MEv2m+9Lu5ecFvviBhXF!Q)rv(f;0G|xNCjmr0V3I6;BCMwa*3$sm zY#ot&!;0wZ0@S|_0P7XuzG09>*lx5!xVcdOePs1}eR9{op13zMMB*~v#l-#L;s*59 zLj4a5_5V<)|Hnf8KNsqM(qI46LjBJ_Qq05STP^)q=eud#M&t7;5Gxi{d!e>0%4?6I zM-3SNKHJZBfg&}Z%a%!2NLn?h4P>xzXm9|ftuMS){AbxF*`V=3pI}$c6^3OVw+L(Y zc?1yvudfdks4qrg78)wWw_}!Thd}kO8%QO~(MCn<{T96+%UB?2f@&K*pRLtGzdNfg zc9t!#aMm<VXiy*wPGr8L&kqj5%L|q_7~*>*iSH4{2hP!z-%#x8$@dI)<@0c^3(j?U z=DffDs(oIg=SCF<h8Ea+4gNaq-82-uhs5Ov2f#$pVEg(|7623`$pc_#iTO{Vkz-9x zvRnoV^?rDvH9dvTU||y6gdgK71BFHx1L6bZ!r2aXw{?ge7Io!kJv%w8?>7r))jQ7? zYTraKn9@+?6Q?@wAmJKaFl3_IR6S?O%)l?ctK@7bMWMZv6xvHHG@)vgBFE$SjDa`| zK>fWCsrXl14-ki>06}j1d)a<yf_JGE;ln)DE_#vUB69>mjRfE$2iO4}XzdUzZesZs zrZIk@(!rtXpYLWHuf0Ol+Bu=t&MDkp3&&9^C(a87go<+gj3Y-AS$%^@_{ecd=354O zOOZTgk)T@v`AwOZRm_+BH!-dOvC+36Z_4lc7WVs)GawEiCkFlwGg;qcnZ(z6m>MeT z{<cuQ_1i-E_7C){oZ&l}_)Z32K<5(Z9HBQjvPy80LgUu;4t)S$BLyNC`r;OKC{z`C zHMkQc56Kz=bA(r4q`y2MRIrQ&p|Es=T{k!|&*$t9k>+6&=$wH#Ml?Q-F=D+#2*3c4 z&&vS7GH507atMQ9tS3ZsPMC5#3@@qs`QULOSS|+3E5ULpSS|<4m0-CVEN^y`f^!}A zv9|TR>g9sWi!#-A>a2Xo=`yd#yejie(fxdXoqtC6^C2q)DXrLY4ymCS5)aD*Ff0$S zSRP=pJiuakfW`6vi{$|p%fs_s%ER-P2W#h;iGY7Wp6$r>bagrOju%LAgUklp7lZ+l z)CcVOVrP#Soig?uoH_4AU9UslP*`uW%GV*{br$hDMf{?2`DUR`3ryfyWMGpPjqyuF z@G9vc^IXT3f(?*OxnPh7vsv$L8&j+JV*OQ>=Xp${`Wv@f5uXo5OsEonHCO<7QxI5Q zRjHiE*t0&@)zzVdkSkaR$)7>aYsg9ts~B$3(t1rnFJP*s6llR;k6UM!Jcm6r%?OeY zq!2NLwx;`91hLu$j@2A2R&y6NhA`G5;9>O-i`73YR{yYA{loH_a(1D|K7AY52LZmY zF|p+p?<K&%Z8nO?i)du{vn*T;bQ2_8SlBo>Ms6!fco=c8SQcS1Dq%4yVKFLUF)CrX zD)KH`7U8~VZpd4lw{-P4KC!Xb<!$|qtvzsI+QhMzT#IzV36_&52u!l4r@yg-EQoHa zz}NeVH{|l&-Cf~_-Sl<KV!~5i#)Mm0gylI|UXLJ_NqD_3@?P#^o9ITVb*qS8L0<7^ zQN9vNjUdGoTddjvu~LGCImU!OLAAnyhZPnqR#>oD!+^!;f#rG8^GdgU`jj*(lz&Fe zr9cfqq9(Q&HGq(ae1u_X!^6^s#nOhw(uU>v5Zx<E{ZigOM#N>%k3S>gav*{rg^Ddk z1Rz!<u#lRb2-S#yhY<mb5dn)40gII%ESE&aWo!4BjhZXS2>y(kD}fq<L=7xP1T01b zEY{-DK@%KH9bVQiuUMmn+lYY0h=9e48WzhgEY=;b^n?Vjh|DW$Nxf)Ey`t(W@`yhp z^lBiKAccd)2!(}()EjwNk-)>KfyJ@{i;)G3kp+v91&fh!wKqg>{qd^$9~#6<gI$zF z&4%fGm$&Bgz2wV6$mcQELnZ(pN1r8(!$*S)val-;Z=%e6r8TfD`jX|(2F7!#ACWA7 zuvj)=IWO8^vHZYdRRhb*!OL<8h~*F#%ONaQeXuZVn21^By=mj%d5$uDeb9$c0|IHY z(AWpj1w&z@Q-k2s6jmWXzY)Zx#v7jTKxTPC^Pt8H(6$wpByRP=s@&UbYDp}pu)LYE z6fmEnu-7;M049%S>2Hh~5Hhp@VF7TxVV>oz3Ly{{iFq5mdjdEFhivNO#FV))h7v9` zYN!%^@JIQPZvT~{pi%4dZpoEG0G%j<8tKkkFn!@<M9kW<B+}(gvP%YDzD0J4{>#I% zk1F94{f(bvNPJiT_}G*UwV)u4FQCZ`cA?-oF@aRsc)?~AjTca!C~<*cg%T6dnh7LP zvutS}QhN6r=zcnuZj)o_HaVP3jubgWq)&Z;uzDAZwvOQh(l3hEZ2g;9@b#{K<*)G^ zF&l3yHx~h>rS>!|#9H3mzX`MRn+uJKIZ*C56mxRtVOQ9Ts>qA|n|g}QFdG+pJyM|o zcoG902(>ZtOyfflpw4{^wWkxL+SBk*t{NARUjNdYbl{`JFF@%8(nisu>Zd8hq7t72 z0!+y1XpyK*W@)(>e~M+<nsK3V9-V-~6vE(xtpOdKuy$ZMAGtWy0sTbdOF4ETpj!Ip z=~%wc9N$;8_hbG-3u>_5%i@-W3LDt^ATzOo&lehtT@KaXhg5P#q*Za_j79bpw%W7O z5`pvs$Z;=dF**v3XGKIECN$v;fR7xf&2d_e7tQe^k?Y?RXwE?T6dE^UV$;#LDdc~V zh>b;}Seb$3O>!;Wf)8fH-`@n)!tyk98@2DFcniy&0?b7K(p`InqU*Yj{HFY-Ff(4B zR!qxGy1(&czHc~Z&FG_!4X1lJmxGO-5JvPlXP@W!p&+i$iv~Pzp9}W6XrGtu^NM{i zI5V=#_PJu8tM+-5AMiVUAobH#ds2Rl+s*ZK9<#ZQ{!P8UwRe!p(9}C%C+kNsNs9{0 zG}=l>A1W0SNkxt_FwXJ{VnVrIVt)r)y^^riE9{5lr&yf8N(I&_R7aXZdHY*p5?Ec) zK*MjL*h7{+jzMQ{M^_gVx&t>CHzpuKsLjG~23|r$l7oWa5Cx|>_+ck!^k8~#n^Ti( zG*9dNZ^I&1{5GROeZs8>p;Zr7W2$dc9gRj){}_50nJMD~Z$&)ft#7MHmq-1F1o=cs zgwe1(s;r{t@;gvi>I~(ygjItL1AXk)X}j}Cy$Mn;kv#OK1bP#p9NU(PHtZ?KeTAiA z<GM@3g{4PWJxjyN!IF6S(zHO27|8rL3&dVlSo&!)lBJ*S_nl+6fV<U=mo_6%VQDjX z4K)fO+WW*39`P*UETrl|D>C6Dz*$RcnR0z$dH_X)T~ud@gM_TyHs>+)!v+1Ra`e;k z9QDm?X;jT@>5wmj<4GAv`%Y*d7QCz-;cM*(mb4wkAm5Ix5dllG!_s4<60s=dN#A;w zCe7(v&(fswI$2nn6#JWGvTQv|vgO%&yj86ScGMf2jUocWL<DR$_#)!Gfsye^pR?0R z&Q3>lo@hOnY5|Jkf5unyGliu$R7=k=2Y}1*9hq+!$oww~^sFlQ*-*jX6!4o?!B5EX zg!24EsAeDSOUn8isAh|kSV)a?0(`!&Fwcbwd(JBCoX^&aNw!{0GSI(t)mPZnP+?bB zR+vE93cKnn>?%`6EK2!esIZIX3>9`!R9`GCT~vi#M1@^dg~?_WW>%}Pi%EqsB2*Y6 zP=$#PqrwPAejx{_Ctpf(b}8fx{X5}<OX7nT<Si7gwCUtnCS9=+fIDlbU3v@hIQj>c z2QNc!p*|uhurp89CV}7+LCZ-jN|0wEO4dIQhsE>~VOxm)J!nY#To+cf`hpWEg{8n3 zm)<sKC@8Wj_);^j_Uic?@OvHF_uGYK2L`$21FjqK!;Tb~^cEzeq?f=?DSM-Bzs**( z>{Q_7s#`W;mao;$5Q1LP)-o(cT3>lsik8#UwA@LWmOBGYz*Ak|yU}5+#ve5Kh+hQI z*90oHz2(h`e6_qek<cjPCBhaQ9O^8PmKY(%qH-t@K!Bp=2Yi3pKH`pz19=EJg~p#^ z2y)=rv=9wcG7v*`qLLwOBAQK5grPoBZJ3Ujg`&kKvA=1ksK5<TQGh@T!a9Z$gf8?7 z)IZ!Pwou*h=<DAExi$c}f`!nme6$L0^U-6$p>PQP{GgPKFpLqTPg3-<IU3($=V*KZ zf67AxTX!*-e@pFD`GH`61B4d|x{zQtcv%*DHD7Av5r|bo0vhsVxYrE~3>3aXcD{UH zVfm)@W;p}~13+J=(>?%n1j%uAaS?2(P?IrI8{ZYFjaNAmEI%vrd76#atZgoT0|<rX zZ=jwr!fUpghxCuhtk+%wy3V^%lq3<1<yHGOp7ie56ndk~UJrX+u5Ot<9`>C7ikBgt z=jDdb=D#m`|MUKP!GFaefd8_0zv91_{1?jxqU(zPUiIHM^@RXu?#At`j^!H51RptG zG6&XSFwKSh(gB%m0kva7QCHWETz>%^YEStD0jsBvt1uLJ4BqeYpe=@e<|TCL4;6b2 zA%PfXFST|ID7@l^)M5TT-XF5rChrSt@B?2!SVXTq3uf&Li398rF<;PT3~YNrm+FAg z#f7dx=m%k6M}_p@y1{j5w2-4IO49;;!#P==r;Y*bqW%H}YFaSXyeO~p)H)FP0<{jb zT%^{4mY4A-3$$;q$a0BV2YOwmfK3b3Jy&Fbf(2t1AW%O*-;KTlVG(Qx5NM-crKRyC zCjf*%)kIzM#*K2l4zUQX?rs=8+zQ{@EA-nj8(Z(dKfXb^h&@z2qR`M_Ev-fW@_DQ8 zWmW!i=Vt8BS-08sb-{w2H89V1ZPv~jngZ9p4TKK-_W+68T7ZOYEwIl4IDr2=!)>8) zh=H-^geC)H)ko+TXx1Mg9Gf|4!WYu(mi3!$<3=Z3`EEG4djs}9+PQB7aSSl6`)M3z zP;7c21y2z`T<rL#`xzziFre7L059xZpn0FbkJ7Atjh?${+(zT`j15b<G?^Y3Rq4Qr zDnep)mEr$N;qQ?71DdsG*8``9rO<ADK{cI5#CH)d)*u=1xJ+iB>x&48^+njRfJn$* zA`(!*`XJ3qGT)NtWAq#l;QJ`vE&&;9q4phQxQpeDb_`ojR~`|+Km;t!5aDt9t%D!d zSm^hn0>4VAvQ>W#F>Vy_b=bP`ub82fBV8{s5Sj|2YAiEnQ25XTS{8zs5*V?}Lo!*) z1t?T#I+-M#S_a}@Ky=g*<gsp;&#DLLeV$0mtRha#X`YrzqB#{OWR7;I0cbuaiZD^6 z<C46u%4BMo9n!?qjbvjkrB5F-v{Zx-CK)oPWj-Qvx6I8%<-~wU%oas=f*@JzqsoOa zO#ko5d_(3pWj-M!h^h2G2a|#%!$Ho|hrubP!GGC6Mjb>X!5q<+G0WDc4|Uali#*Ws zd7OjcdI{YGE5=dbVU|erQHxyVhM|wBoy;-@JDShaY`n&BVE8m&LS?8YHx`Jkx&~X2 z-*P_Z^4MGI94sBObme&1<HI?3GtS}77RPZD#`NqQuM8<JR7$6u8_c;|HkWTN@;a5- z#cEM#rNxCwUY6!=$~o-e#@%+OhIra{XncCwxf^q?XJlyC(6-@`okPRUZO*x$P%s|l zo}DR%tGkQ1>TMo3dd@GFx#J!zJ?FYAGoLtd%(>p2Tkp5zJ9kgcjm4=jDQv3dj!#?+ zgNrqyP5O5XH~)-e0nXLGm~-`?3lZw9SvG=g7Gz|%LhcC>>>S=^QJMdaZ9BG)Y~8*U zFvFmY|GUPwPLy`+Dvy*Z<9jBCOWU_qc8`=w!xN>-#Q5-dWlv@I#Q4rqrM!D$_pXVP z!`pZ5+*#heeWbi+&z@~tD<`*YKUvwer!>B2e8+gXymfpW_HEmDZr#3Z>+rTc!^0<c zZQEX+*t2_h&yHOa<&nzPUAwjp@17{{9Nx8S*T}>+#J_#paAnW7N@;jUrCb@Q?B2Gu zJY3p=3)go~Y~4AsqdZa`F7Mf1-dZ||BzNx^-??pDxm4P@V;hp2D2?yjKE7)N(1~s1 zl^qjXcU5*&N)y9KYY%+3?c7@4UD~>BWc$t?TX%08-Z@?#-m`uC$jJB((76YvN9vzP z0pIHj_;VGUvPjNQpnCqHbpLLp`%!jTY{~xId}$8nH<QOeaj`8<G3L-E(WCWqrPo^= zx;cK>>(&3qbMBw16P>AsD-O|(l0yo`$x^j=vQn7=KfvK@T+>z=A1W3n7Z&C|^~p~@ zFgtWAc}S%^d+L)DU!I<tdGM2;ra3i!$JUW;!`qNr?e}u7_Ed5_G(8Wo`Svym;9jXB z9#Si|3X=xck&GeaymEUH_c9p&n4N!z1foD{-vNQ&zJ|n#xIJc}vZc5mxARs?GsP0` zN!pLAJRUq+s#f`w!uupgs9>x6+Ox>o@8jh7=3}_FeCB~-a@?QCMYa^}&bgxQD_@Ov zfA(A#MO{l&@30csN`4EJKBnWxX%(;8LYnc@pzmJmxB$Zbe2s+u?k!`D1m2Z){v>kp zt9oNBIUl!n3FD6Rv{W~z)_1Rf{~O5qvnH~d(s>uk_lKX4N0E<T%3dSBX7Q5y`j@^o zNA}_b?nC*zur+k3r$NrIkM3uzX=$!aP;-DZ?7LUv-v()av4XUwlzg54?V0Ub3A`J9 z>eD&*sir&jisfmH2E{MqCS(krMZ0Ncyf}sNqByZg2^TPoAJxi`b05gLKAeQ}H_VYK zJ9k^o{aBDnQF*usF8ITS+ZJ))%DD|VBF)=JocmzT_2Wj5%p(Bf5WWg1<lju6I=lB+ zxK6=DbaO?K<FdjK2`{9ao!?Sy6*@gCyHzJ;uj#Dp@b-xv6T2q1ZXMqNIk>bKvNvD) zGDf8#Ps<5iB^DCT;-tx5`w88qRBc9Lm!DWk*Vm(rex+3|GiAgsWWfS$t%9T!{{1VM zdLIhn*IVT(QxH}NKLQP<Kj(VGZU4Thpu^Q3U9*JPR6@Y(wXyu8ocmbloa9d-ztu@x zzLjz)&f<0D7I+cZT<y2sQQ=+x%xF{2-N5Do4Td$b+9N2XUu<7W_a0Mc1b*P;KRgZ% z`Qg_<&BND1&2dbJPR^d@X!OG*h^io8Uf6<^bDIw8wq};!vGOEtJ=etcZ@$VIF3T3z zyy4k}nFlbyI0yc=!R~+45L@p?=6<<-=KO%f<P_?9?aCj@xq>f7<uepyeIv@}@iogw zVSWUL1FAQV&Q_;%g`}SIhJb~O0wC|VFC*Vwc{k#F(O=(zEMu3fUaxJs_5|wXSFfpF z?k>%g9^m!mcF))klY3obk0Qrmivjb}bnAMpq_5`Ozwj~yRs-gur$O4jL%pSF0a7{p z+GheyclAIb0q3jzPWwg@4FIeTj4^zG;zxkh)gk)Uo?NqFTHSemy|&e#&$$!fro2Qq zUTveherL+@+G8l~U)D>mUbIObJ$?sjgyK=D6N-3#!S|8OtgUtQ&_@IzUhI!+c2G!M zBcE!%8~=K(`x~)_2?6Q8s-9<c4s#!<T(D@08;o?fXLv;kSI=x1o0-JjUsxp3dZ^vA zU)?t`f!nJAyB3L>ix75Y_<J!XQA&=U*)siz+M(WCcJAk}z!Vw@XL`vRiEPQ+E4H?< ze-SSuROVOliYA9FSB!D~jR%y?Z=fTrGQEZ{g~Uml*OtB)<x~4j5cODlUbup&_h=@B z<sJLEJ?CyKO;jd!V#W0nBRh8O`oze{uF@w;TSs<(V)yn^8Mj_<A0Iin$GJOlZg<<7 z#I@R(6+x}YGEN*(ZPl+)`LRC<tT%10M-^i2akPn5REB61TFQA3yD{c!d5llGH+^NF z6*YmT@HRlU$9jTWdPc3F#`U9LTeUkVruVv+J_WK?(OrfbiO717`e}2gi>e~&C{{Cx zGcIn)2CEl07Pa2PhIT{Fb&vARN31{Gn{%Iu84B0$hG-xM{z<N;M%Lah&h*-oHzpF* z<$E#^aB+GSbqJeSma6xtg?%dLcC@U8q(O<W#1)nFXwH2)4$5{kJ0ro-)cpS4?v;=z zlKnY%N1I5b8;awI0Z|n1U?!H0;d)=Jf~Z+*DQZIYOhwHc(Qa=gk!H{+xb9s$HllH} z&`SAsMQqoAmV?SR{edHOehhP}55+CVw-nA*4D0@!JNok;!#K&idc$U`Wmdj)PXeOW z`Ek(sk(f?$9%|sR5r_}sU;{dSek$iao<Z_&rj(`^D@_qXcH@24&OvrNky++#akZuu z9)fTm73OBwwp^LMxp2MC$~I#sX<XiEj+;sw&H2PYjLGVY^=rJ?+;LkRYUC$#?#G*P z#d6k)l<)G+;a#+U&ezfKtfk`QX4(^*;`r!gZM%-?Pwh9_5ADZ3b2zMtr!zvnm2|yU z=n8h=r5cvJFS2W#f}BL>_43E{T39Q1lFg#2GS<A^cv2mU7PY6Yy^V!ZGhTbWmK`_C z@L@c>OUT6>|0<=H6C-fZ7Gwu<?nC?dQYo({=caeevdVaBTPuoOfrK`&RGu6?$=AAP zw6IwFzd3i-cY6Px$Pjd;r>dbp6P2-t0uBtqZ$E$M*U&d@a{2$YwT2s+@cP~)P7L_6 zbq+g}Z#7x6m_962^tyCg!%cf@Q4i)p6SS0b|1t#&+D6wZ-Wb}gZMedFF?fwryN7?W zoNxkcxT;nbezJ&nhqz0(h?o1YdH2huGgb2ueu^IUR4MA{xl4Cz&fVlm6PV3s9-C+F z0EG7`hKKSTS62b#BXvdZi8kjmZjY%Zhahatn!{7kda-kdbM9bh9)L@+Ha&#`UPZ+g zv}6_s5)J#sxO(m@!8uOk{4<Ga`gfJ4rtuuwd=V3c1w6Q8`SI^P7w<&k)3aDaKbmtt z`?n#;N95y)h`J@`K9Ii5gO*`WH8>SCpN=c~mlD%5#jduEc#o}k6q^o;$M6<4PI(dp zb#?^eX_cUv-G`U|9;zhIGU2oela=qW#gj99!N_uNx%Lky6~kjn?(UpB^p10#eSRs* zGIg#;OXUYE3!ZvuZ~XRgJAs3JkX1ZBl@tfh$ILplCT4N}^lbS-upppK%|flrnk8IZ ziP3+ylJGanYxDqO(LVv?+)w1(N98f6*YiBVV@FX?cr=d8(YcT0+z0iXfW7K`C-xrN z(-tUo79xjdzlsnZ&@g(igMYp_HfnWa4(ws%o0qob@pH5D55mn<gm$g_G4^}8AaKuC z!&|yO`1fxg-eS(p`L>3f#>=8MEGG@=-CYb_W6cjQxQF4(s|u6HIj`4>s6$Yw{dTM7 zWlL)-izJLg*SGw{eN+@-yoAJ!F-Hy`D30z2x0-)w3eu5tKa+C@Vul&1J<)z!D+i}5 zqbEZQNhAN;M-|lJQB=EgZhIT5lA}{YdZXB$y-!BYnVg#n@fGL%qi1a-l5lbf=Vgjm zQJI{5=jWx?T7Z|L)o)KQed~{WXIxn%*;aPFGASsA_^z7vJ+2$AV!+0re&W_lD~DQI zDqs%PHwYQZsuRi5Kjq51r!=MU8aRqevuN}DS)rrysJ2Zo#@vEPGs+VV)KDjTneXtd z&9^MtZfF9r)d1%lPJB2f7QJ->GqZ&wb14Z>^_=)<jFjlIN2hQkF-2Sv8)a$CiT#Yq zpL15W-X{j0y370w+-5U(0(a70%y=h`%@Lk+c(Qwbbb9)3Jkjd(oLQw}$FG6^Hy=kF z&B-M3{DbB1O9?>L08;VJU@c3rY1DDFeg&L(hwy*j-gWMov{}K<R|4<FJBVL|$u|;@ zxiP$Hcn{oTFz<q$KY!Z!zyF%gFs^r<aQ*fA@cp!W@%SFTc5{FS;4_N<9AYiGdBiiN zcMHedjGJ(nz2N6Ig*p!35};N1m)rvIX5q4*bDeJ^(i~`70M-=X544Es72yoK@H>Jx z5>W<jH%cjow;pG)MduXWOq@Y15JwOj9-f800_YH^WU3|D#z6t5?(VSrU=nUlw4Fgo zloSW)x?2>^qAQIfj)(9+4ai)QMp1DSpJh%OLheU_TXkjSWe!+rUe}^&r@JAF=U&7! zkC@W%BcOj5{<k6LBW@>bECGi#9;VMyXMX4LErHrJH*2MPue%lD4<qaY3dz!(L;0~b z9&nS0756wGN4KLitfooRB4{f{<x~P>0ob#mnsiyY9P#n6W=U5lC%RZ;YuD8zS`ik8 z5YH@XV-b`rM7fLWDzpQ(t|D^8HunHRlwei>v6jiU$hI-><64A`bbLzXpG~K^7TVRp uZd|UB!;7O;{IbpQ1<x}ouWT(c{BZKmQi^_x>$DJeh~4!cetzUi;Qs-Y^Rin2 diff --git a/csharp/ql/test/resources/assemblies/System.Web.ApplicationServices.dll b/csharp/ql/test/resources/assemblies/System.Web.ApplicationServices.dll deleted file mode 100644 index 85db5a3a7e4fe011cddeafc11f79a488f966ea34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13824 zcmeHNdz2hymA_Th-P7~vo@59yzyvA;Nq{i+%=El~kW6MKVPJ-Yc?B?%)O1(R^rok} zsqRiPAktZo$H^)P7~qHsvaYhLEJRR2S>u8Ok;S72%mLlQqM)+s;ywV^MPPsT)}w2Z zfcpo><DO&9)UErw->v)I?|%1tR8<dOd?RT@6vFxT+eBZ-m5;ST-<?!Y96#aVI6YAN z)UvNDLr*Omo6Z*Xf}NkTjTt><SXREIPnx=2w)Cu}_ir54XYy&YB^IkY$u+%cfM`h3 z=+V+sPkXh!Kqu<;N`hz=BvD6t_IbGKIJe;>S|GgY_{{?LUyeILA?HJ*wI5|w{;ytL z$RZrSK9^`CGuw!6^Np~;Jt{;EV80K&W>5Bix$3^_q8$Z3Cvaa&$=p=}?mrC#WztsH zZy-5zc-3MT?G%vswhc@KXA922u@>FcVw<@<6xmm*;AC4#oPlF4(YgQ>R_D0lVBb^< zQ(+m=3oD6gMOr1B(Edslz9V<Mx^gK|-Kl@*TDR!3$RAXKk>lA|1b?`}`Ip;HV6oT` zsJm6lRm7fd00h{8IY;rGC_M0N`YP;=7;qTRNn8;-*Q-EXU{Q3UTeNQU+;s{m5<l*% z9m$qNOM9ZdwTDGv%7MO&d|mz#qOpZU&o+V|E!kOXs>m9vPzR^!^6^nhfala+zF~Z@ zAJ?_Och&%}%jGA5`9K;do3}ooNq_#2(oTyZfV>@N9OojOJ8)KTLYLqtp;|i0#jMLG z55tpjwz`;QtWWezlzC3fMKx3#p_fCu8tSPg#*%@Whavf0gy|_l9}P3VPUu#l2SmO= z__@&Q4H5cinCVrKgP<>jnVwq1^b(=J4}A^%lQm2)i7>r8GS?WP^--p!IMWRx`McV3 zEJ9xhGrc9m@)csOrk4F2u4DRm-N!+-My5ZFlw)<YQ+uf{LYX+1{vKY{(NAkx@;;3v z|5W=4SX<x7{34b43mceDg;;Wj-1Vl!VS9`vKM{Jbl-eS<#m;Q#pbXVxBzBw;3c}bN z-`7}Xo)mon_0;WaoJB7=DDI-DXby{J9OHdAa-gw(U*q-E1f(bn=-JwRjh_VifLOT+ zWgi1-CuP|JdJScaHi?xslzka!i&#-zE8E1%2V?shA41uTpraz6s`(BOyn~<nlx?+T zpq&(noJfW`QMoFb2EC$@>5D4UgY`^zi2PY%J|m@@>zIF9bk1#H{<#=a13I3y=j)~+ zv54u#pq^Zz93(N&O*#kenk9C_V#Mb{L01D6RE4(rWer#ZrhPQ4hN$49iW;F^4vOBU zT%*>|<$~tcuAu_Z6~5+T%!VHo<kV10AM?u^sGdIQqgl0qKJ9BRmJvoc=3*6fkILhX zkGa?_(5s@W<2R@n=5ox%7Da>TKVvrs%I=$o{-q{Z*4!9GXT)y}+}BXMCxAi?!5VIo z`aZ97_18o-<ql|m!9~Xc$>NE!x$vv>IhE%IKIXzN)!(D??7_!e_|p3O)g^R~&gd~E zrR-OQ1)2+gxc+f<8GT6vk10izEvLWt(NikVHGIs4ABi4Rd6wa0F8r2yP(9TFKz|*3 zL2dET8QRS%&qaL9g$I>?4WRq$f1~pJ#>ZUv{`%L|4hI1JZS+mGi}vX(cuYwus@Cn7 zjl+se!;s8{udR=2XZmHC`j~c>k1nb|N?T12=qzw@a1DLaLDAnvkI~l9w*<}61f8I* zrEfcBw7>3Tt(P7Z#JRMX`shig45&rxqo)PU)!rB1qi&*uF8XG?0VDQV7yVKj)GnYO zyJ#}HN4<cacTq0dKo`&pF4{#ms3Y{Ei>}2;8KIxK=oiSkQF_@$y2j{NE?N~D)JEwQ z7xjiV0{y#-q9_}q|8mjS;ma7k?xOE%8-f1YMOUM2oZfKJRNWqRoZfQL7cm~jF(VO< zx!RG&3225~G$&;>4pLsFqfl1oqL=DFr*5X0iw2cF>czCcM{fch<)U$veUKLW=uMzw z97H$O>`}K+vs-p;{S81T2y%LJ3#}0J^V;vnZ${avF1icx+(M^2n&|0^wJov=6aBpQ zNAU^mL)7k+q2FUb9WHvlZZTa#T`t;Rw@tf*dIbGkNjFSu+vqH}>@RB?uoXSqMSs({ zm<(ChiGHHoRksR=4^6Vp(s*acXikZ#CC&6vRJ~lA^3hw$b=r1XCpMj|<6Q<H&b(Ab zJTLhu+!eb)n{gB|9y(B#_t9GQakb#13)NdS+eeFIpV3M_x~u-~0Gd|s*2;d_dFoLb z?>_jL3!jMkb~ylOVLYl`M&~+_!05O~yPQTG6ir~x`Us7?=uGTDK0=#a)K+_+b|qcx zqQTk+fws8lA@p>Gwz}vWv<GO?MVxgNG985azM)lU#x1)*`$ugzJX7eoI^Opz!gQ_B z>xxHJIu&w-z95pIPLMxb|HIg=DHNn}jqSgTx-_~<tT~b!z-#nj)Dof-8~CoE{Cn7* zh3H0<hAD~C2<?T18rs{aV&~S5rADDA#DC|mQ-x=n3Ncmbpz!|ye^ly3>omH)Mup8i zQrErjAZJZgG&NV#vEL_m?UmBg(IU@Vhi7jUx>4F5)PD^dN`-z<U)6U!Y!VA6ihM|H zt_4--A?T~br5akw5n#(<i9>{*K&ue}v@}Y;1z$^VK(mhi8MK}zLj0_BC-@jOgP-3E z!5(q=mtjYBd&G$t_l4&61;<>G$SdNH*NULGPAh_v8F;1A1JW0#p>?VolPa%KJz5kZ z)>P;op^iTnV1KRB22h1|O5B*Lqz8EJH7D|(juUN1|8NT&e^v59qsJxM!8l~_4Do41 z@$)$C1_e(EHum1jKpW^3p{+uDg!T#@6ncTsi-a0NvqCQgT}ZRS?*?5=*9-jws6uyv z9!vL#<lCS+{Q&f2dQK!i0d1gKg(b^C8>mOwkNI&o_$1v9x|se$G#3hgiqK<(UMlo@ zp;2VVZ*VrytDp<$cc6>tEzl*TDN$;sD5y>`(37YMbS1qHbQLv&CQx@2kJ%@Ko+bQR z(eD?XA(3nXzk<F3+Jd}$TWg`CC>&~`<0uZgoK68fjW&R`3q6za;QNH0M^}O$75NA0 zi{MlA70~UpAGAmZKra`|SJ8?{3+<uxpf}SH=%;8L^lo}R(nsH*<7!euuM&E<&_{*7 zNKcYg^P=#Y!kWt!mMj;(PiRW$RYLDpeoVV+_Qzk8Hb&?)B|=N-Nl;87)Tyk*s8BEi zsTh4R#1W4~h+;ir*nn(_$y4MV$`crQx2aEoUKjrX=#nVY*JD2feL(1oHO%XcOgG1$ z16@$d`q2i~+$;KTM4t!0KhE-3w3k4ih%Sm#$_xm9C+AjG8&Lcb@P*9pC{j`hDJ zo?O%TOYpxI{+T$}`+2eRM)Vc%&&Rpc@p+BZK3w}MB#+dy{c9Aq<J>#0{Z5P0F^Iqd zIu=w#G&Il{<|d3sP?Z`H9WJj0U5Myl9z(f`+-L+{1er=l1F3jmKN|FX_*0RSY&C)0 zQK<t_SEv(Ir7k)Fv>WkNs0UP~Gmu#doe8QUGv5!onpS|Gjj^iG8c>ziBJWh{rPCo< z2dX0LJ^<Q}r+k$LkdG>@M?IKlP=ktnWe?~Gtg6V#)u3arq+(Cf3k#E=Dp|0hV4u(j zz5p8vT?(p_4I3&lb`Z2g=Yj5^VYL3Mupg@M9OoRIL&J0%=2K6?@-rdhBPi>qS$U}e z@p`;&G<W9h?QMxFpG?qM!})YMXP!+vj9l5=x|Pyq&McX|x!j1EGfHN<-zXWh!7Oc@ z{0lQx5;Rjx<?UP+tx2cp9HTgGrfIxr+9M{b01Q|ud$z#blv&z3SnMs}h35{y;(VB` zmN<%|vsP-_&Rf~bpgd!irt^-8O-8W@=hI|bDZCv``*_fT-`Oh8=c;_)v|&w|zN(Q< zZ=GOeql7m_zSuTr;M$Q&Hd;qeM<o1PM@+QGNByQW+Q)7Xd~BIJeZJtehnqcGGD_uQ zAKFF5Dm!e>OqzCaI$QAW>dVg*;QM4Ymo3er+f2%tQ$}j`oy%v;V$ql~(I069D!<*N zb>>voa{0jlt2|@c#$?W<5~99yqqQktC`+%8<RR>{O=N(u{gM^J4i>qu2Q2~XvsRj6 z(ZvW)5ZW+vJ`zvz09laBrqF`CB{EKiLuDL~O~{pO+O$Q96UPT!%I2lS?Rp>gmmTw_ zFDZMfzL)D}<yJ1R*e#^9IhJ+(8!T?La#_nHF7^Rhbbgt;Vq=C4dphh&U%6Py&kW@a zI6F35Fe!DYz-!7nqv*t7$SC?5<K!m~F!ba*$hjK6XDE+;6HSiVd<oxMEf>eQ;}B-K zAr%Bwd#UaDG7o2`?xB1Ydpf<TQg#PYZC<tWgk1AH!EiZOLKhcHoG(*soRc=2Gwltg zg;c|o&|AWr+Q~AC#;qNuoy}x90Xh4tB|bOK>FXmp-z=AG12a=GU$#?baR>vvJWr$F zoGedGvBm0LaA6`_%+8bb7K<2Px!JL7DX7Z5xIS<1G;B;V>+SqZ)rxn=dbDN&d4TX9 zUN~rF^7f3x-pC!MHH!A<FnG~g3++gi4%aYKWg8*iWZE;?;*sm<H;XAdTj2h!IxuLJ zIHhw%x20qGYFWRTG0-p0gi;j;v$rbsn(5xuo68!-YU!x!-w2kBfY?>;&*cVZ3VFLU zY8rNGdXrI_4k$U9AhF@4WtVV)ax6J{%#d~|Yvj-|HpY^f?gNitS3U6j!^ldPQ>AJ_ zHDse^K<w%F<qNZRc4|6M)HgKBKB0wHKssV(OdHFL>D^ha!jte_hBaF)7%5vN%pxN9 zCg^IZtgJL5>kJi;uA^AqXe{r1vY^pfG<2qAvpLyvPQJ)%lT1K7KaJ&wjZ$iw%o!t_ z^S}|JEYs_7)*3M{EobfO@;GE#Q>AI@En->aNKP85?UeEu9_IrVj}>nP88I<7P53JY z`wT=OCu_FLy1gTPBZ($U(U7?VYGRH3lp6+wbEjwr`17*^S>N@yIBsPxEt`&fgR_G0 zJiTt#5e24iM_`KeK;Qz)$f#-W$YO42N#`7=1`%C1$XE!=GvcY&V)TK;XvCbt!e<Zc zD%e;vF|<T$J(^Rt&A_OZ#vMT%@CAcAlbtHtlHXqM9#QC~O$%H`&Sx)k?{LQ$Ppt66 zwT!gPVROZj!M;2Og~JDS3GPC9#6n)Vj#%KuVPIFvlqrR>7AEQ{tXAOc2G~-y)a~F4 z$|e%m4Vq`t7X~&yzN}z48#-U$HnZwvu_e&X79PH1d72j~?iRQU(wD=8<3(y-s9U@h zn0UM5gKDdMQNfKLdf38xPE{3m7wC_YfgPq*I>)fmn3>2c<hamyA&n_s*lM)M**iH3 z7QR4l7q)6&Akv;aEMoQXuv~eV3>MEfcM8h-T$$^0!{2KacLL4d?|PB#wbE{RaKs&6 z8t5fg-|Hh68cr=<zy@qP4-ecuWC=W)5I`*{mbu;9pEaf|p4?JJD&<SOgyRt+UG&O% z@;ky9_KLlMBCA}!fGm(9erU0?!kG49<=%b)UBTM}OtHLuF0#kHc+lavyYn+gxyTE@ zBg6xaNXGIGw%z?~(VwD=eg=4XFX_>1<6E@bcyG~csV-4|Ss>qCZ=^n%eF78u`B>|7 z1w7C2hCQ1?PxJNxuF_~Zg~_f+{&F*B*y!k@W5L+vrikYp)XbRzin%=lyRt>F)l77f z)_ERrpGD@)mPk%)ZUQ%WX59kk8IkhxsEEPpY-V_~fHhex9lG9NH%o)Pygp%5hfNA$ z`sEAfD!Ow9Bh6WWTt4MqopLO@qREeqBl)}o28+CzHPai*CCUbPp6ZPm^gZvs_?IOq z_sX`shPd(BjK`Y%PFbu6F&pf{G{dylwvAabgvwp+oWXr|o;mA{M{kIDVt?g3w7{El zJViul#5B@)44L(khew7NNKfWtdEh7QyI*}_V#RBNd*4WX>)+0}Ri}`yC~6pFVT{>0 zlc=VXBC=tj9};TT=&I6GxhooB?aCw3uU)of;+W(M*GKPLv-Qe_Kdd{Wawq@JAygr{ z1+_)+`jhd<Xm2aOX~1W9dhqu*{zAQS>e}OXo^iwT*LOd$^cnSG^C5ldwu{c*``At9 z@z>q)?KO*z{?&tPzO=CQ-ukE8zw^qrWmBi$y5yIwU%dB`*qt>Wc>l9kJe)t!_~u0) zf96LWFAeql)j(g(%P*dJ^~sA?-+SP-y;tRLed4zpHvR0@E$N>w`Ru^+uWmo}w5APT ze$+hewMV1j58V^OD_jcUO*4feO!x&zD9nVN4e<+*5Z*gch~Jxp@XpqGMH0eWW2$_n zMX6l<F5}dXeRb^mBW;!Ly$D&QyF2;S{8JVDt<w9D#n?Kmwwy<nRr;p#B%XeeC1ZFF zw^mPfbr~J0j?UJe_N1BU?m1c+Qx}YG&lX?_&qU5+vQoLFMY;0b+^f13-1WYvo-KrD z4dWIDCN_usdPh+sQ7y8N&qX-9qntxmEUfH~fQdKFN@hhvIzdIpHyE8%oFZ7nWlbw1 zx~9hC@ftnEmv~%{HtE8s%?lQCE-no(4Tp7AjjJ%uU}1Ny9%?!%9*r)DMs=;}Bxaz2 zyHIPB-mJ<ct|Hgtaj7K%R&`iiY%$-o1p08Hay@7M(xxTRWAzyBXoewGU0At2_#Z|S zDz`gB<90NmnGNW0oA1<7JvCMCfoY|A2{*mDDbWBYEBAwGsyx{2RCK?n$Ct97OHm8r zvXngmk1(KWxJ*vanr59_4v6Igp_LrLm5AU<L~tb{2*IN8N^V3LY~^+cn;GkI6u|~a z<v^GRC0?=P{UIO6Ds=R4-pcD~-lpdZJf-R-%!EWs6<V?~b&5V=*x7u!sEe9W##=Wm zEVM$Q6W!E%hviwe*wm;{U9zRCr7e-{Y)KHURA{+a;`uvo>E1)Sj{TaAR|7U4+b}Zl zok^jvX`PN=X%W6<)VM=OT<5V#w0ny}yC<qX1P0OSM4~O3;3L^BmmUWt5}k=Q5xC_Y zZ5{2&*7jD`6ghKzcBNZ0Mn_jFX_)DrOu}eyGrN<9k;oWkCY?x|J!W?%-D#Mq?o4-A zW-`&<)!CWqZcnCqdV1Pg&B?a*NwcfRNcW^W(y3HyIt{+9y|cBwtu@islSoW<wY8@* zJ>7|(j;>59X|{HCwI;eVsm?@KS64FA2K()83A3loG!h+V%1oNwZLO(<(ShgB?o4ZE zvLlsDB~m@@sa9hWRd#ozJKNe)hSAy4hUzj#y0bmqm4r0YmNq*wtzBk^X=D<ps|O`* zovo>EqqQyB-r3RG-InM~rxHEw?a5@i1Ag}4w;#uIo{XuBH`_)5`wM?lKgO>Diwe>R z2d9yAM&+}jKECU)*~ocfKhiVddpZpr_bv~g?CMGIkK1$Hp_AyKwZ5FoiGRw7Lc_s) z@}}*!L#J)`O;aG_+-W<}p6SSRWm;R)9mp92-%J$>$s;DdaPh#yup3ij*jDCu%G<C4 zUZjqxwS(3)CU$-${wH;Kzg+U1T6CVr;U~1r>s1`&yx+t+GHlgsyp|X?vKGmjXqwL4 zfa15`4;zP86EyYzj8~*FOR#sC@3_<XnEwuwv)(y4FWg3SR)~>voE1ufnZS3Vt)K(= zYBY*(KO5<M;6c#!;Q4qY^qaSMt5rjM^IJ9Eb&Zrd+ZkuBcLlig<5XbPz*nX9l*KPr zOxUz2<NiM7B(XJyQUlT=$_;#T%A(YAjocTy1G^>#K4DXi61)*Pf~8%elfd^j=P!wG zT!;aF$;02)@P!t?jhsQ<7OY@Rfwfs&OOVXqC)%5Foy4^l-@yv-A&YOfRX;{iYU3Li zOYvz0dTHq7#J?eY^YiQ%qz$u(m?3qs!mzX?kJQ6ABiO)OZb%BgFS_`^`UKzDS1(Ha zQddgaT!2<JChwK+o%ohnt#1PL*=Sw0o+Mh@g|iKjOycWhi$s*rckCzkBFE3h)j+GN zt$wfko4^-Tg@#bal+?hzSm56vz{e??M(tSS(I=-Mx=x0%?`5<>55(Poqy+7}w2u44 ziStI+4rdhm@5P-FXUcn*Bhz?NQSh5U8$P7rO$z>0qZP~%FHbr9b+nwv1m42pIt7n( zcjWL`;oP-dTV-(U?-|mc^XoaZSKp~myYcm3LH-x<$75m=5t)^^&d&<IKjEJo%|9Q1 av<R%_-$4<r^?vI5N2~bH75ynh;C}(C>4i=J From 8015c3cf28e80b40bdcc4fb0f96b8a7754dcf63e Mon Sep 17 00:00:00 2001 From: Kasper Svendsen <kaspersv@github.com> Date: Tue, 20 Jun 2023 13:01:01 +0200 Subject: [PATCH 713/739] QL language ref: explain implicit this receivers --- .../codeql/ql-language-reference/formulas.rst | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/codeql/ql-language-reference/formulas.rst b/docs/codeql/ql-language-reference/formulas.rst index cdc8c297b7d..8745217decc 100644 --- a/docs/codeql/ql-language-reference/formulas.rst +++ b/docs/codeql/ql-language-reference/formulas.rst @@ -164,6 +164,38 @@ If the call resolves to a predicate without result, then the call is a formula. It is also possible to call a predicate with result. This kind of call is an expression in QL, instead of a formula. For more information, see ":ref:`calls-with-result`." +Member predicates only apply to members of a particular class and calls to +member predicates have a receiver of a matching type. Syntactically, if a call +contains a dot, then the expression before the dot specifies the receiver of +the call. For instance, ``x`` is the receiver for the call ``x.isEven()``. + +For calls to member predicates of the enclosing class on the member itself +(i.e., the value of ``this``), the receiver may be omitted syntactically. In +this case we say the call has an implicit this receiver. For instance, in the +following example the ``isEven()`` call in ``isOdd()`` is a member predicate +call with an implicit this receiver and the call is equivalent to +``this.isEven()``: + +.. code-block:: ql + + class OneTwoThree extends int { + OneTwoThree() { this = 1 or this = 2 or this = 3 } + + predicate isEven() { this = 2 } + + predicate isOdd() { not isEven() } + } + +Use of implicit this receivers can make it harder to spot predicates that introduce +cartesian products by failing to relate the implicit ``this`` variable with +other variables, which can negatively affect query performance. For more +information on cartesian products, see ":ref:`Troubleshooting query performance +<troubleshooting-query-performance>`". + +It is possible to enable warnings about implicit this receivers for `CodeQL packs +<https://docs.github.com/en/code-security/codeql-cli/codeql-cli-reference/about-codeql-packs#warnonimplicitthis>`__ +through the ``warnOnImplicitThis`` property. + .. _parenthesized-formulas: Parenthesized formulas From e332a4348d464d33a81695c36ca07c0add5d907a Mon Sep 17 00:00:00 2001 From: Adrien Pessu <7055334+adrienpessu@users.noreply.github.com> Date: Wed, 21 Jun 2023 12:55:33 +0100 Subject: [PATCH 714/739] Update javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com> --- javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp index d3689155c00..adcd6fc4715 100644 --- a/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp +++ b/javascript/ql/src/Security/CWE-798/HardcodedCredentials.qhelp @@ -23,7 +23,7 @@ <example> <p> - The following code example connects to an HTTP request using an hard-codes authentication header + The following code example connects to an HTTP request using an hard-codes authentication header: </p> <sample src="examples/HardcodedCredentialsHttpRequest.js"/> From 6d3f9fc67ef9a3d86545cdf5dc8f278ad28e1a93 Mon Sep 17 00:00:00 2001 From: Kasper Svendsen <kaspersv@github.com> Date: Wed, 21 Jun 2023 13:59:49 +0200 Subject: [PATCH 715/739] Polish QL language spec "Call with results" section --- .../ql-language-specification.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 71dcbdce571..04d58626474 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -1236,15 +1236,15 @@ The type environment for the arguments is the same as for the call. A valid call with results *resolves* to a set of predicates. The ways a call can resolve are as follows: -- If the call has no receiver and the predicate name is a simple identifier, then the predicate is resolved by looking up its name and arity in the visible member-predicate environment of the enclosing class. +- If the call has no receiver and the predicate reference is a simple identifier, then the call is resolved by looking up the predicate reference and arity in the visible predicate environment of the enclosing class. -- If the call has no receiver and the predicate name is a simple identifier, then the predicate is resolved by looking up its name and arity in the visible predicate environment of the enclosing module. +- If the call has no receiver and the predicate reference is a simple identifier, then the call is resolved by looking up the predicate reference and arity in the visible predicate environment of the enclosing module. -- If the call has no receiver and the predicate name is a selection identifier, then the qualifier is resolved as a module (see "`Module resolution <#module-resolution>`__"). The identifier is then resolved in the exported predicate environment of the qualifier module. +- If the call has no receiver and the predicate reference is a selection identifier, then the qualifier is resolved as a module (see "`Module resolution <#module-resolution>`__") and the call is resolved by looking up the identifier in the exported predicate environment of the qualifier module. -- If the type of the receiver is the same as the enclosing class, the predicate is resolved by looking up its name and arity in the visible predicate environment of the class. +- If the the call has a receiver and the type of the receiver is the same as the enclosing class, the call is resolved by looking up the predicate name and arity in the visible predicate environment of the enclosing class. -- If the type of the receiver is not the same as the enclosing class, the predicate is resolved by looking up its name and arity in the exported predicate environment of the class or domain type. +- If the the call has a receiver and the type of the receiver is not the same as the enclosing class, the call is resolved by looking up the predicate name and arity in the exported predicate environment of the type of the receiver. If all the predicates that the call resolves to are declared on a primitive type, we then restrict to the set of predicates where each argument of the call is a subtype of the corresponding predicate argument type. Then we find all predicates ``p`` from this new set such that there is not another predicate ``p'`` where each argument of ``p'`` is a subtype of the corresponding argument in ``p``. We then say the call resolves to this set instead. From bfd0a19d85ba8389cbd7728507d4e547b9e982e7 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Wed, 21 Jun 2023 18:36:39 +0100 Subject: [PATCH 716/739] Kotlin: Define DiagnosticTrapWriter, for type safety In some cases, we were writing diagnostics to TRAP files where they shouldn't be written. Such TRAP files don't define #compilation, so TRAP import gave errors. Now we use DiagnosticTrapWriter to get the type system to check that we are writing diagnostics to the right place. --- .../src/main/kotlin/ExternalDeclExtractor.kt | 6 +- .../main/kotlin/KotlinExtractorExtension.kt | 6 +- .../src/main/kotlin/KotlinUsesExtractor.kt | 4 +- .../src/main/kotlin/TrapWriter.kt | 59 +++++++++++++++---- .../src/main/kotlin/utils/Logger.kt | 54 ++++++++--------- 5 files changed, 82 insertions(+), 47 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt b/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt index c45e0a454b7..a426c7bd622 100644 --- a/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt @@ -14,7 +14,7 @@ import java.util.ArrayList import java.util.HashSet import java.util.zip.GZIPOutputStream -class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: String, val sourceFilePath: String, val primitiveTypeMapping: PrimitiveTypeMapping, val pluginContext: IrPluginContext, val globalExtensionState: KotlinExtractorGlobalState, val diagnosticTrapWriter: TrapWriter) { +class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: String, val sourceFilePath: String, val primitiveTypeMapping: PrimitiveTypeMapping, val pluginContext: IrPluginContext, val globalExtensionState: KotlinExtractorGlobalState, val diagnosticTrapWriter: DiagnosticTrapWriter) { val declBinaryNames = HashMap<IrDeclaration, String>() val externalDeclsDone = HashSet<Pair<String, String>>() @@ -95,8 +95,8 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri val binaryPath = getIrClassBinaryPath(containingClass) // We want our comments to be the first thing in the file, - // so start off with a mere TrapWriter - val tw = TrapWriter(logger.loggerBase, TrapLabelManager(), trapFileBW, diagnosticTrapWriter) + // so start off with a PlainTrapWriter + val tw = PlainTrapWriter(logger.loggerBase, TrapLabelManager(), trapFileBW, diagnosticTrapWriter) tw.writeComment("Generated by the CodeQL Kotlin extractor for external dependencies") tw.writeComment("Part of invocation $invocationTrapFile") if (signature != possiblyLongSignature) { diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt index 9bfcabd20fb..c766d70df33 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt @@ -127,7 +127,7 @@ class KotlinExtractorExtension( val lm = TrapLabelManager() val logCounter = LogCounter() val loggerBase = LoggerBase(logCounter) - val tw = TrapWriter(loggerBase, lm, invocationTrapFileBW, null) + val tw = DiagnosticTrapWriter(loggerBase, lm, invocationTrapFileBW) // The interceptor has already defined #compilation = * val compilation: Label<DbCompilation> = StringLabel("compilation") tw.writeCompilation_started(compilation) @@ -324,13 +324,13 @@ private fun doFile( trapFileWriter.getTempWriter().use { trapFileBW -> // We want our comments to be the first thing in the file, // so start off with a mere TrapWriter - val tw = TrapWriter(loggerBase, TrapLabelManager(), trapFileBW, fileTrapWriter) + val tw = PlainTrapWriter(loggerBase, TrapLabelManager(), trapFileBW, fileTrapWriter.getDiagnosticTrapWriter()) tw.writeComment("Generated by the CodeQL Kotlin extractor for kotlin source code") tw.writeComment("Part of invocation $invocationTrapFile") // Now elevate to a SourceFileTrapWriter, and populate the // file information val sftw = tw.makeSourceFileTrapWriter(srcFile, true) - val externalDeclExtractor = ExternalDeclExtractor(logger, invocationTrapFile, srcFilePath, primitiveTypeMapping, pluginContext, globalExtensionState, fileTrapWriter) + val externalDeclExtractor = ExternalDeclExtractor(logger, invocationTrapFile, srcFilePath, primitiveTypeMapping, pluginContext, globalExtensionState, fileTrapWriter.getDiagnosticTrapWriter()) val linesOfCode = LinesOfCode(logger, sftw, srcFile) val fileExtractor = KotlinFileExtractor(logger, sftw, linesOfCode, srcFilePath, null, externalDeclExtractor, primitiveTypeMapping, pluginContext, KotlinFileExtractor.DeclarationStack(), globalExtensionState) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 9c552233158..fdaebe5f1c8 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -139,13 +139,13 @@ open class KotlinUsesExtractor( if (clsFile == null || isExternalDeclaration(cls)) { val filePath = getIrClassBinaryPath(cls) val newTrapWriter = tw.makeFileTrapWriter(filePath, true) - val newLoggerTrapWriter = logger.tw.makeFileTrapWriter(filePath, false) + val newLoggerTrapWriter = logger.dtw.makeFileTrapWriter(filePath, false) val newLogger = FileLogger(logger.loggerBase, newLoggerTrapWriter) return KotlinFileExtractor(newLogger, newTrapWriter, null, filePath, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext, newDeclarationStack, globalExtensionState) } val newTrapWriter = tw.makeSourceFileTrapWriter(clsFile, true) - val newLoggerTrapWriter = logger.tw.makeSourceFileTrapWriter(clsFile, false) + val newLoggerTrapWriter = logger.dtw.makeSourceFileTrapWriter(clsFile, false) val newLogger = FileLogger(logger.loggerBase, newLoggerTrapWriter) return KotlinFileExtractor(newLogger, newTrapWriter, null, clsFile.path, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext, newDeclarationStack, globalExtensionState) } diff --git a/java/kotlin-extractor/src/main/kotlin/TrapWriter.kt b/java/kotlin-extractor/src/main/kotlin/TrapWriter.kt index eb9feeb4559..b27aec9cc52 100644 --- a/java/kotlin-extractor/src/main/kotlin/TrapWriter.kt +++ b/java/kotlin-extractor/src/main/kotlin/TrapWriter.kt @@ -57,7 +57,9 @@ class TrapLabelManager { * share the same `TrapLabelManager` and `BufferedWriter`. */ // TODO lm was `protected` before anonymousTypeMapping and locallyVisibleFunctionLabelMapping moved into it. Should we re-protect it and provide accessors? -open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelManager, private val bw: BufferedWriter, val diagnosticTrapWriter: TrapWriter?) { +abstract class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelManager, private val bw: BufferedWriter) { + abstract fun getDiagnosticTrapWriter(): DiagnosticTrapWriter + /** * Returns the label that is defined to be the given key, if such * a label exists, and `null` otherwise. Most users will want to use @@ -223,7 +225,7 @@ open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelMa val len = str.length val newLen = UTF8Util.encodablePrefixLength(str, MAX_STRLEN) if (newLen < len) { - loggerBase.warn(diagnosticTrapWriter ?: this, + loggerBase.warn(this.getDiagnosticTrapWriter(), "Truncated string of length $len", "Truncated string of length $len, starting '${str.take(100)}', ending '${str.takeLast(100)}'") return str.take(newLen) @@ -237,14 +239,43 @@ open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelMa * writer etc), but using the given `filePath` for locations. */ fun makeFileTrapWriter(filePath: String, populateFileTables: Boolean) = - FileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, filePath, populateFileTables) + FileTrapWriter(loggerBase, lm, bw, this.getDiagnosticTrapWriter(), filePath, populateFileTables) /** * Gets a FileTrapWriter like this one (using the same label manager, * writer etc), but using the given `IrFile` for locations. */ fun makeSourceFileTrapWriter(file: IrFile, populateFileTables: Boolean) = - SourceFileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, file, populateFileTables) + SourceFileTrapWriter(loggerBase, lm, bw, this.getDiagnosticTrapWriter(), file, populateFileTables) +} + +/** + * A `PlainTrapWriter` has no additional context of its own. + */ +class PlainTrapWriter ( + loggerBase: LoggerBase, + lm: TrapLabelManager, + bw: BufferedWriter, + val dtw: DiagnosticTrapWriter +): TrapWriter (loggerBase, lm, bw) { + override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter { + return dtw + } +} + +/** + * A `DiagnosticTrapWriter` is a TrapWriter that diagnostics can be + * written to; i.e. it has the #compilation label defined. In practice, + * this means that it is a TrapWriter for the invocation TRAP file. + */ +class DiagnosticTrapWriter ( + loggerBase: LoggerBase, + lm: TrapLabelManager, + bw: BufferedWriter +): TrapWriter (loggerBase, lm, bw) { + override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter { + return this + } } /** @@ -259,16 +290,20 @@ open class FileTrapWriter ( loggerBase: LoggerBase, lm: TrapLabelManager, bw: BufferedWriter, - diagnosticTrapWriter: TrapWriter?, + val dtw: DiagnosticTrapWriter, val filePath: String, populateFileTables: Boolean -): TrapWriter (loggerBase, lm, bw, diagnosticTrapWriter) { +): TrapWriter (loggerBase, lm, bw) { /** * The ID for the file that we are extracting from. */ val fileId = mkFileId(filePath, populateFileTables) + override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter { + return dtw + } + private fun offsetMinOf(default: Int, vararg options: Int?): Int { if (default == UNDEFINED_OFFSET || default == SYNTHETIC_OFFSET) { return default @@ -349,10 +384,10 @@ class SourceFileTrapWriter ( loggerBase: LoggerBase, lm: TrapLabelManager, bw: BufferedWriter, - diagnosticTrapWriter: TrapWriter?, + dtw: DiagnosticTrapWriter, val irFile: IrFile, populateFileTables: Boolean) : - FileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, irFile.path, populateFileTables) { + FileTrapWriter(loggerBase, lm, bw, dtw, irFile.path, populateFileTables) { /** * The file entry for the file that we are extracting from. @@ -363,14 +398,14 @@ class SourceFileTrapWriter ( override fun getLocation(startOffset: Int, endOffset: Int): Label<DbLocation> { if (startOffset == UNDEFINED_OFFSET || endOffset == UNDEFINED_OFFSET) { if (startOffset != endOffset) { - loggerBase.warn(this, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null) + loggerBase.warn(dtw, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null) } return getWholeFileLocation() } if (startOffset == SYNTHETIC_OFFSET || endOffset == SYNTHETIC_OFFSET) { if (startOffset != endOffset) { - loggerBase.warn(this, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null) + loggerBase.warn(dtw, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null) } return getWholeFileLocation() } @@ -390,14 +425,14 @@ class SourceFileTrapWriter ( override fun getLocationString(e: IrElement): String { if (e.startOffset == UNDEFINED_OFFSET || e.endOffset == UNDEFINED_OFFSET) { if (e.startOffset != e.endOffset) { - loggerBase.warn(this, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null) + loggerBase.warn(dtw, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null) } return "<unknown location while processing $filePath>" } if (e.startOffset == SYNTHETIC_OFFSET || e.endOffset == SYNTHETIC_OFFSET) { if (e.startOffset != e.endOffset) { - loggerBase.warn(this, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null) + loggerBase.warn(dtw, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null) } return "<synthetic location while processing $filePath>" } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt index 3b66e527429..6c9e6f5d64d 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt @@ -107,7 +107,7 @@ open class LoggerBase(val logCounter: LogCounter) { file_number_diagnostic_number = 0 } - fun diagnostic(tw: TrapWriter, severity: Severity, msg: String, extraInfo: String?, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { tw.unknownLocation }) { + fun diagnostic(dtw: DiagnosticTrapWriter, severity: Severity, msg: String, extraInfo: String?, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { dtw.unknownLocation }) { val diagnosticLoc = getDiagnosticLocation() val diagnosticLocStr = if(diagnosticLoc == null) "<unknown location>" else diagnosticLoc val suffix = @@ -121,7 +121,7 @@ open class LoggerBase(val logCounter: LogCounter) { // counting machinery if (verbosity >= 1) { val message = "Severity mismatch ($severity vs ${oldInfo.first}) at $diagnosticLoc" - emitDiagnostic(tw, Severity.Error, "Inconsistency", message, message) + emitDiagnostic(dtw, Severity.Error, "Inconsistency", message, message) } } val newCount = oldInfo.second + 1 @@ -149,18 +149,18 @@ open class LoggerBase(val logCounter: LogCounter) { fullMsgBuilder.append(suffix) val fullMsg = fullMsgBuilder.toString() - emitDiagnostic(tw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId) + emitDiagnostic(dtw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId) } - private fun emitDiagnostic(tw: TrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { tw.unknownLocation }) { + private fun emitDiagnostic(dtw: DiagnosticTrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { dtw.unknownLocation }) { val locStr = if (locationString == null) "" else "At " + locationString + ": " val kind = if (severity <= Severity.WarnHigh) "WARN" else "ERROR" val logMessage = LogMessage(kind, "Diagnostic($diagnosticLocStr): $locStr$fullMsg") // We don't actually make the location until after the `return` above val locationId = mkLocationId() - val diagLabel = tw.getFreshIdLabel<DbDiagnostic>() - tw.writeDiagnostics(diagLabel, "CodeQL Kotlin extractor", severity.sev, "", msg, "${logMessage.timestamp} $fullMsg", locationId) - tw.writeDiagnostic_for(diagLabel, StringLabel("compilation"), file_number, file_number_diagnostic_number++) + val diagLabel = dtw.getFreshIdLabel<DbDiagnostic>() + dtw.writeDiagnostics(diagLabel, "CodeQL Kotlin extractor", severity.sev, "", msg, "${logMessage.timestamp} $fullMsg", locationId) + dtw.writeDiagnostic_for(diagLabel, StringLabel("compilation"), file_number, file_number_diagnostic_number++) logStream.write(logMessage.toJsonLine()) } @@ -188,18 +188,18 @@ open class LoggerBase(val logCounter: LogCounter) { } } - fun warn(tw: TrapWriter, msg: String, extraInfo: String?) { + fun warn(dtw: DiagnosticTrapWriter, msg: String, extraInfo: String?) { if (verbosity >= 2) { - diagnostic(tw, Severity.Warn, msg, extraInfo) + diagnostic(dtw, Severity.Warn, msg, extraInfo) } } - fun error(tw: TrapWriter, msg: String, extraInfo: String?) { + fun error(dtw: DiagnosticTrapWriter, msg: String, extraInfo: String?) { if (verbosity >= 1) { - diagnostic(tw, Severity.Error, msg, extraInfo) + diagnostic(dtw, Severity.Error, msg, extraInfo) } } - fun printLimitedDiagnosticCounts(tw: TrapWriter) { + fun printLimitedDiagnosticCounts(dtw: DiagnosticTrapWriter) { for((caller, info) in logCounter.diagnosticInfo) { val severity = info.first val count = info.second @@ -209,7 +209,7 @@ open class LoggerBase(val logCounter: LogCounter) { // to be an error regardless. val message = "Total of $count diagnostics (reached limit of ${logCounter.diagnosticLimit}) from $caller." if (verbosity >= 1) { - emitDiagnostic(tw, severity, "Limit", message, message) + emitDiagnostic(dtw, severity, "Limit", message, message) } } } @@ -224,28 +224,28 @@ open class LoggerBase(val logCounter: LogCounter) { } } -open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) { +open class Logger(val loggerBase: LoggerBase, open val dtw: DiagnosticTrapWriter) { fun flush() { - tw.flush() + dtw.flush() loggerBase.flush() } fun trace(msg: String) { - loggerBase.trace(tw, msg) + loggerBase.trace(dtw, msg) } fun trace(msg: String, exn: Throwable) { trace(msg + "\n" + exn.stackTraceToString()) } fun debug(msg: String) { - loggerBase.debug(tw, msg) + loggerBase.debug(dtw, msg) } fun info(msg: String) { - loggerBase.info(tw, msg) + loggerBase.info(dtw, msg) } private fun warn(msg: String, extraInfo: String?) { - loggerBase.warn(tw, msg, extraInfo) + loggerBase.warn(dtw, msg, extraInfo) } fun warn(msg: String, exn: Throwable) { warn(msg, exn.stackTraceToString()) @@ -255,7 +255,7 @@ open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) { } private fun error(msg: String, extraInfo: String?) { - loggerBase.error(tw, msg, extraInfo) + loggerBase.error(dtw, msg, extraInfo) } fun error(msg: String) { error(msg, null) @@ -265,16 +265,16 @@ open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) { } } -class FileLogger(loggerBase: LoggerBase, override val tw: FileTrapWriter): Logger(loggerBase, tw) { +class FileLogger(loggerBase: LoggerBase, val ftw: FileTrapWriter): Logger(loggerBase, ftw.getDiagnosticTrapWriter()) { fun warnElement(msg: String, element: IrElement, exn: Throwable? = null) { - val locationString = tw.getLocationString(element) - val mkLocationId = { tw.getLocation(element) } - loggerBase.diagnostic(tw, Severity.Warn, msg, exn?.stackTraceToString(), locationString, mkLocationId) + val locationString = ftw.getLocationString(element) + val mkLocationId = { ftw.getLocation(element) } + loggerBase.diagnostic(ftw.getDiagnosticTrapWriter(), Severity.Warn, msg, exn?.stackTraceToString(), locationString, mkLocationId) } fun errorElement(msg: String, element: IrElement, exn: Throwable? = null) { - val locationString = tw.getLocationString(element) - val mkLocationId = { tw.getLocation(element) } - loggerBase.diagnostic(tw, Severity.Error, msg, exn?.stackTraceToString(), locationString, mkLocationId) + val locationString = ftw.getLocationString(element) + val mkLocationId = { ftw.getLocation(element) } + loggerBase.diagnostic(ftw.getDiagnosticTrapWriter(), Severity.Error, msg, exn?.stackTraceToString(), locationString, mkLocationId) } } From ade4d68793d40d1b4e3daf7bc17bcc0f7a803879 Mon Sep 17 00:00:00 2001 From: Alex Denisov <alexdenisov@github.com> Date: Thu, 22 Jun 2023 09:26:29 +0200 Subject: [PATCH 717/739] Swift: bump C++ version in CMake --- swift/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/CMakeLists.txt b/swift/CMakeLists.txt index ba4a30d5c4a..2b44cc58993 100644 --- a/swift/CMakeLists.txt +++ b/swift/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.21) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_C_COMPILER clang) From 36f980f4bf4096e0005c0099c85edcc69f6f0e26 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 22 Jun 2023 09:46:02 +0100 Subject: [PATCH 718/739] Swift: Hide summarized nodes from paths. --- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index c0f01a67df3..6b830982d6f 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -282,7 +282,7 @@ private predicate hasPatternNode(PatternCfgNode n, Pattern p) { import Cached /** Holds if `n` should be hidden from path explanations. */ -predicate nodeIsHidden(Node n) { none() } +predicate nodeIsHidden(Node n) { n instanceof FlowSummaryNode } private module ParameterNodes { abstract class ParameterNodeImpl extends NodeImpl { From c50a0419e2c9145f40a2ad0de3961b2bee48e183 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 22 Jun 2023 09:46:10 +0100 Subject: [PATCH 719/739] Swift: Accept test changes. --- .../dataflow/dataflow/DataFlow.expected | 16 -------------- .../CWE-079/UnsafeWebViewFetch.expected | 21 ------------------- .../Security/CWE-089/SqlInjection.expected | 10 --------- .../Security/CWE-094/UnsafeJsEval.expected | 20 ------------------ .../StaticInitializationVector.expected | 11 ---------- .../CWE-134/UncontrolledFormatString.expected | 11 ---------- .../CWE-311/CleartextTransmission.expected | 5 ----- .../CWE-321/HardcodedEncryptionKey.expected | 10 --------- .../Security/CWE-760/ConstantSalt.expected | 7 ------- 9 files changed, 111 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index b725e5e7298..bebfd102871 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -1,6 +1,4 @@ edges -| file://:0:0:0:0 | [summary param] this in signum() | file://:0:0:0:0 | [summary] to write: return (return) in signum() | -| file://:0:0:0:0 | [summary param] this in signum() [some:0] | file://:0:0:0:0 | [summary] to write: return (return) in signum() [some:0] | | file://:0:0:0:0 | self [a, x] | file://:0:0:0:0 | .a [x] | | file://:0:0:0:0 | self [str] | file://:0:0:0:0 | .str | | file://:0:0:0:0 | self [x, some:0] | file://:0:0:0:0 | .x [some:0] | @@ -122,9 +120,7 @@ edges | test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:298:11:298:15 | let ...? [some:0] | | test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:306:13:306:24 | .some(...) [some:0] | | test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:314:10:314:21 | .some(...) [some:0] | -| test.swift:270:15:270:22 | call to source() | file://:0:0:0:0 | [summary param] this in signum() | | test.swift:270:15:270:22 | call to source() | test.swift:270:15:270:31 | call to signum() | -| test.swift:271:15:271:16 | ...? | file://:0:0:0:0 | [summary param] this in signum() | | test.swift:271:15:271:16 | ...? | test.swift:271:15:271:25 | call to signum() | | test.swift:271:15:271:25 | call to signum() | test.swift:271:15:271:25 | OptionalEvaluationExpr | | test.swift:280:31:280:38 | call to source() | test.swift:280:15:280:38 | ... ? ... : ... | @@ -133,15 +129,12 @@ edges | test.swift:284:12:284:12 | z | test.swift:285:19:285:19 | z | | test.swift:291:8:291:12 | let ...? [some:0] | test.swift:291:12:291:12 | z | | test.swift:291:12:291:12 | z | test.swift:292:19:292:19 | z | -| test.swift:291:16:291:17 | ...? | file://:0:0:0:0 | [summary param] this in signum() | | test.swift:291:16:291:17 | ...? | test.swift:291:16:291:26 | call to signum() | -| test.swift:291:16:291:17 | ...? [some:0] | file://:0:0:0:0 | [summary param] this in signum() [some:0] | | test.swift:291:16:291:17 | ...? [some:0] | test.swift:291:16:291:26 | call to signum() [some:0] | | test.swift:291:16:291:26 | call to signum() | test.swift:291:16:291:26 | call to signum() [some:0] | | test.swift:291:16:291:26 | call to signum() [some:0] | test.swift:291:8:291:12 | let ...? [some:0] | | test.swift:298:11:298:15 | let ...? [some:0] | test.swift:298:15:298:15 | z1 | | test.swift:298:15:298:15 | z1 | test.swift:300:15:300:15 | z1 | -| test.swift:303:15:303:16 | ...! | file://:0:0:0:0 | [summary param] this in signum() | | test.swift:303:15:303:16 | ...! | test.swift:303:15:303:25 | call to signum() | | test.swift:306:13:306:24 | .some(...) [some:0] | test.swift:306:23:306:23 | z | | test.swift:306:23:306:23 | z | test.swift:307:19:307:19 | z | @@ -283,10 +276,6 @@ nodes | file://:0:0:0:0 | .x [some:0] | semmle.label | .x [some:0] | | file://:0:0:0:0 | [post] self [x, some:0] | semmle.label | [post] self [x, some:0] | | file://:0:0:0:0 | [post] self [x] | semmle.label | [post] self [x] | -| file://:0:0:0:0 | [summary param] this in signum() | semmle.label | [summary param] this in signum() | -| file://:0:0:0:0 | [summary param] this in signum() [some:0] | semmle.label | [summary param] this in signum() [some:0] | -| file://:0:0:0:0 | [summary] to write: return (return) in signum() | semmle.label | [summary] to write: return (return) in signum() | -| file://:0:0:0:0 | [summary] to write: return (return) in signum() [some:0] | semmle.label | [summary] to write: return (return) in signum() [some:0] | | file://:0:0:0:0 | self [a, x] | semmle.label | self [a, x] | | file://:0:0:0:0 | self [str] | semmle.label | self [str] | | file://:0:0:0:0 | self [x, some:0] | semmle.label | self [x, some:0] | @@ -599,11 +588,6 @@ subpaths | test.swift:218:11:218:18 | call to source() | test.swift:169:12:169:22 | value | test.swift:170:5:170:5 | [post] self [x] | test.swift:218:3:218:5 | [post] getter for .a [x] | | test.swift:219:13:219:13 | b [a, x] | test.swift:185:7:185:7 | self [a, x] | file://:0:0:0:0 | .a [x] | test.swift:219:13:219:15 | .a [x] | | test.swift:219:13:219:15 | .a [x] | test.swift:163:7:163:7 | self [x] | file://:0:0:0:0 | .x | test.swift:219:13:219:17 | .x | -| test.swift:270:15:270:22 | call to source() | file://:0:0:0:0 | [summary param] this in signum() | file://:0:0:0:0 | [summary] to write: return (return) in signum() | test.swift:270:15:270:31 | call to signum() | -| test.swift:271:15:271:16 | ...? | file://:0:0:0:0 | [summary param] this in signum() | file://:0:0:0:0 | [summary] to write: return (return) in signum() | test.swift:271:15:271:25 | call to signum() | -| test.swift:291:16:291:17 | ...? | file://:0:0:0:0 | [summary param] this in signum() | file://:0:0:0:0 | [summary] to write: return (return) in signum() | test.swift:291:16:291:26 | call to signum() | -| test.swift:291:16:291:17 | ...? [some:0] | file://:0:0:0:0 | [summary param] this in signum() [some:0] | file://:0:0:0:0 | [summary] to write: return (return) in signum() [some:0] | test.swift:291:16:291:26 | call to signum() [some:0] | -| test.swift:303:15:303:16 | ...! | file://:0:0:0:0 | [summary param] this in signum() | file://:0:0:0:0 | [summary] to write: return (return) in signum() | test.swift:303:15:303:25 | call to signum() | | test.swift:515:12:515:12 | x [some:0] | test.swift:509:9:509:9 | value [some:0] | file://:0:0:0:0 | [post] self [x, some:0] | test.swift:515:5:515:5 | [post] cx [x, some:0] | | test.swift:519:20:519:20 | cx [x, some:0] | test.swift:509:9:509:9 | self [x, some:0] | file://:0:0:0:0 | .x [some:0] | test.swift:519:20:519:23 | .x [some:0] | | test.swift:543:20:543:28 | call to source3() | test.swift:536:10:536:13 | s | test.swift:537:7:537:7 | [post] self [str] | test.swift:543:7:543:7 | [post] self [str] | diff --git a/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected b/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected index b21ed3b030c..e7c8443bfa2 100644 --- a/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected +++ b/swift/ql/test/query-tests/Security/CWE-079/UnsafeWebViewFetch.expected @@ -1,7 +1,4 @@ edges -| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | -| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | -| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:120:25:120:39 | call to getRemoteData() | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() | @@ -25,15 +22,12 @@ edges | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) | UnsafeWebViewFetch.swift:139:48:139:57 | ...! | | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) | UnsafeWebViewFetch.swift:153:85:153:94 | ...! | | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) | UnsafeWebViewFetch.swift:154:86:154:95 | ...! | -| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | | UnsafeWebViewFetch.swift:131:30:131:30 | remoteString | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) | | UnsafeWebViewFetch.swift:132:19:132:61 | call to URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:140:47:140:57 | ...! | | UnsafeWebViewFetch.swift:132:19:132:61 | call to URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:141:48:141:58 | ...! | -| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | | UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL | UnsafeWebViewFetch.swift:132:19:132:61 | call to URL.init(string:relativeTo:) | | UnsafeWebViewFetch.swift:150:19:150:41 | call to Data.init(_:) | UnsafeWebViewFetch.swift:152:15:152:15 | remoteData | | UnsafeWebViewFetch.swift:150:19:150:41 | call to Data.init(_:) | UnsafeWebViewFetch.swift:154:15:154:15 | remoteData | -| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | | UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 | UnsafeWebViewFetch.swift:150:19:150:41 | call to Data.init(_:) | | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() | UnsafeWebViewFetch.swift:168:25:168:25 | remoteString | | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() | UnsafeWebViewFetch.swift:171:25:171:51 | ... .+(_:_:) ... | @@ -49,25 +43,16 @@ edges | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) | UnsafeWebViewFetch.swift:186:48:186:57 | ...! | | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) | UnsafeWebViewFetch.swift:200:90:200:99 | ...! | | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) | UnsafeWebViewFetch.swift:201:91:201:100 | ...! | -| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | | UnsafeWebViewFetch.swift:178:30:178:30 | remoteString | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) | | UnsafeWebViewFetch.swift:179:19:179:61 | call to URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:187:47:187:57 | ...! | | UnsafeWebViewFetch.swift:179:19:179:61 | call to URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:188:48:188:58 | ...! | -| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | | UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL | UnsafeWebViewFetch.swift:179:19:179:61 | call to URL.init(string:relativeTo:) | | UnsafeWebViewFetch.swift:197:19:197:41 | call to Data.init(_:) | UnsafeWebViewFetch.swift:199:15:199:15 | remoteData | | UnsafeWebViewFetch.swift:197:19:197:41 | call to Data.init(_:) | UnsafeWebViewFetch.swift:201:15:201:15 | remoteData | -| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | | UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 | UnsafeWebViewFetch.swift:197:19:197:41 | call to Data.init(_:) | | UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() | UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | | UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() | UnsafeWebViewFetch.swift:211:25:211:25 | htmlData | nodes -| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | semmle.label | [summary param] 0 in URL.init(string:) | -| UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | semmle.label | [summary] to write: return (return) in URL.init(string:) | -| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | semmle.label | [summary param] 1 in URL.init(string:relativeTo:) | -| UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | semmle.label | [summary] to write: return (return) in URL.init(string:relativeTo:) | -| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | -| UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | UnsafeWebViewFetch.swift:94:10:94:37 | try ... | semmle.label | try ... | | UnsafeWebViewFetch.swift:94:14:94:37 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | semmle.label | try! ... | @@ -126,12 +111,6 @@ nodes | UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | semmle.label | htmlData | | UnsafeWebViewFetch.swift:211:25:211:25 | htmlData | semmle.label | htmlData | subpaths -| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) | -| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:132:19:132:61 | call to URL.init(string:relativeTo:) | -| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:150:19:150:41 | call to Data.init(_:) | -| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) | -| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:179:19:179:61 | call to URL.init(string:relativeTo:) | -| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:197:19:197:41 | call to Data.init(_:) | #select | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | UnsafeWebViewFetch.swift:103:30:103:84 | call to String.init(contentsOf:) | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | Tainted data is used in a WebView fetch without restricting the base URL. | | UnsafeWebViewFetch.swift:106:25:106:25 | data | UnsafeWebViewFetch.swift:105:18:105:72 | call to String.init(contentsOf:) | UnsafeWebViewFetch.swift:106:25:106:25 | data | Tainted data is used in a WebView fetch without restricting the base URL. | diff --git a/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 7c5466939f2..a4617e9b811 100644 --- a/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/swift/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -97,8 +97,6 @@ edges | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:117:16:117:16 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:119:16:119:16 | unsafeQuery1 | | SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:132:20:132:20 | remoteString | -| sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) | -| sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 | @@ -106,10 +104,8 @@ edges | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:175:29:175:29 | unsafeQuery3 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:183:29:183:29 | unsafeQuery3 | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | -| sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | | sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | sqlite3_c_api.swift:190:2:190:2 | data | -| sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | | sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:190:21:190:21 | [post] buffer | | sqlite3_c_api.swift:190:21:190:21 | [post] buffer | sqlite3_c_api.swift:194:28:194:28 | buffer | | sqlite3_c_api.swift:190:21:190:21 | [post] buffer | sqlite3_c_api.swift:202:31:202:31 | buffer | @@ -226,10 +222,6 @@ nodes | SQLite.swift:117:16:117:16 | unsafeQuery1 | semmle.label | unsafeQuery1 | | SQLite.swift:119:16:119:16 | unsafeQuery1 | semmle.label | unsafeQuery1 | | SQLite.swift:132:20:132:20 | remoteString | semmle.label | remoteString | -| sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | semmle.label | [summary param] this in copyBytes(to:count:) | -| sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) | semmle.label | [summary] to write: argument 0 in copyBytes(to:count:) | -| sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | semmle.label | [summary param] this in data(using:allowLossyConversion:) | -| sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) | semmle.label | [summary] to write: return (return) in data(using:allowLossyConversion:) | | sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | semmle.label | unsafeQuery1 | | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | semmle.label | unsafeQuery2 | @@ -245,8 +237,6 @@ nodes | sqlite3_c_api.swift:202:31:202:31 | buffer | semmle.label | buffer | | sqlite3_c_api.swift:210:31:210:31 | buffer | semmle.label | buffer | subpaths -| sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) | -| sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) | sqlite3_c_api.swift:190:21:190:21 | [post] buffer | #select | GRDB.swift:106:41:106:41 | remoteString | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | GRDB.swift:106:41:106:41 | remoteString | This query depends on a $@. | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | user-provided value | | GRDB.swift:108:41:108:41 | remoteString | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | GRDB.swift:108:41:108:41 | remoteString | This query depends on a $@. | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | user-provided value | diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index de1c23c52a8..3e810179bcf 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -1,8 +1,5 @@ edges -| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | -| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) | | UnsafeJsEval.swift:165:10:165:37 | try ... | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | | UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | UnsafeJsEval.swift:165:10:165:37 | try ... | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:205:7:205:7 | remoteString | @@ -28,7 +25,6 @@ edges | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | UnsafeJsEval.swift:285:13:285:13 | string | | UnsafeJsEval.swift:208:7:208:39 | ... .+(_:_:) ... | UnsafeJsEval.swift:299:13:299:13 | string | | UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) | UnsafeJsEval.swift:214:24:214:24 | remoteData | -| UnsafeJsEval.swift:211:24:211:37 | .utf8 | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | | UnsafeJsEval.swift:211:24:211:37 | .utf8 | UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) | | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:265:13:265:13 | string | | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:268:13:268:13 | string | @@ -37,12 +33,9 @@ edges | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:285:13:285:13 | string | | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | UnsafeJsEval.swift:299:13:299:13 | string | | UnsafeJsEval.swift:214:24:214:24 | remoteData | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | -| UnsafeJsEval.swift:214:24:214:24 | remoteData | file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | | UnsafeJsEval.swift:265:13:265:13 | string | UnsafeJsEval.swift:266:43:266:43 | string | -| UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | | UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | | UnsafeJsEval.swift:268:13:268:13 | string | UnsafeJsEval.swift:269:43:269:43 | string | -| UnsafeJsEval.swift:269:43:269:43 | string | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:269:43:269:43 | string | UnsafeJsEval.swift:269:22:269:124 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:276:13:276:13 | string | UnsafeJsEval.swift:277:26:277:26 | string | | UnsafeJsEval.swift:279:13:279:13 | string | UnsafeJsEval.swift:280:26:280:26 | string | @@ -63,16 +56,9 @@ edges | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:305:17:305:17 | jsstr | | UnsafeJsEval.swift:318:24:318:87 | call to String.init(contentsOf:) | UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... | -| file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) | nodes -| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | -| UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:124:21:124:42 | string | semmle.label | string | | UnsafeJsEval.swift:124:70:124:70 | string | semmle.label | string | -| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | -| UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | UnsafeJsEval.swift:165:10:165:37 | try ... | semmle.label | try ... | | UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | semmle.label | call to getRemoteData() | @@ -108,13 +94,7 @@ nodes | UnsafeJsEval.swift:305:17:305:17 | jsstr | semmle.label | jsstr | | UnsafeJsEval.swift:318:24:318:87 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | -| file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | semmle.label | [summary param] 0 in String.init(decoding:as:) | -| file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) | semmle.label | [summary] to write: return (return) in String.init(decoding:as:) | subpaths -| UnsafeJsEval.swift:211:24:211:37 | .utf8 | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) | -| UnsafeJsEval.swift:214:24:214:24 | remoteData | file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) | -| UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) | -| UnsafeJsEval.swift:269:43:269:43 | string | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:269:22:269:124 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) | #select diff --git a/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected b/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected index aa6cf49411c..848ce4937ae 100644 --- a/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected +++ b/swift/ql/test/query-tests/Security/CWE-1204/StaticInitializationVector.expected @@ -1,20 +1,15 @@ edges -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | rncryptor.swift:68:104:68:104 | myConstIV1 | | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | rncryptor.swift:77:125:77:125 | myConstIV1 | -| rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | | rncryptor.swift:61:19:61:27 | call to Data.init(_:) | rncryptor.swift:70:104:70:104 | myConstIV2 | | rncryptor.swift:61:19:61:27 | call to Data.init(_:) | rncryptor.swift:79:133:79:133 | myConstIV2 | -| rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:61:19:61:27 | call to Data.init(_:) | | rncryptor.swift:62:19:62:35 | call to Data.init(_:) | rncryptor.swift:72:84:72:84 | myConstIV3 | | rncryptor.swift:62:19:62:35 | call to Data.init(_:) | rncryptor.swift:81:105:81:105 | myConstIV3 | -| rncryptor.swift:62:24:62:34 | [...] | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | rncryptor.swift:62:24:62:34 | [...] | rncryptor.swift:62:19:62:35 | call to Data.init(_:) | | rncryptor.swift:63:19:63:28 | call to Data.init(_:) | rncryptor.swift:74:84:74:84 | myConstIV4 | | rncryptor.swift:63:19:63:28 | call to Data.init(_:) | rncryptor.swift:83:113:83:113 | myConstIV4 | -| rncryptor.swift:63:24:63:24 | iv | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | rncryptor.swift:63:24:63:24 | iv | rncryptor.swift:63:19:63:28 | call to Data.init(_:) | | test.swift:53:19:53:34 | iv | test.swift:54:17:54:17 | iv | | test.swift:85:3:85:3 | this string is constant | test.swift:101:17:101:35 | call to getConstantString() | @@ -40,8 +35,6 @@ edges | test.swift:101:17:101:35 | call to getConstantString() | test.swift:130:39:130:39 | ivString | | test.swift:147:22:147:22 | iv | test.swift:53:19:53:34 | iv | nodes -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | -| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | rncryptor.swift:60:24:60:24 | 0 | semmle.label | 0 | | rncryptor.swift:61:19:61:27 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | @@ -84,10 +77,6 @@ nodes | test.swift:167:22:167:22 | iv | semmle.label | iv | | test.swift:168:22:168:22 | iv | semmle.label | iv | subpaths -| rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:25 | call to Data.init(_:) | -| rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:61:19:61:27 | call to Data.init(_:) | -| rncryptor.swift:62:24:62:34 | [...] | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:62:19:62:35 | call to Data.init(_:) | -| rncryptor.swift:63:24:63:24 | iv | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:63:19:63:28 | call to Data.init(_:) | #select | rncryptor.swift:68:104:68:104 | myConstIV1 | rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:68:104:68:104 | myConstIV1 | The static value '0' is used as an initialization vector for encryption. | | rncryptor.swift:70:104:70:104 | myConstIV2 | rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:70:104:70:104 | myConstIV2 | The static value '123' is used as an initialization vector for encryption. | diff --git a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected index dd2c4f66f74..3a2d4eb80c6 100644 --- a/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected +++ b/swift/ql/test/query-tests/Security/CWE-134/UncontrolledFormatString.expected @@ -1,5 +1,4 @@ edges -| UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:70:28:70:28 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:73:28:73:28 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:74:28:74:28 | tainted | @@ -13,17 +12,11 @@ edges | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:85:72:85:72 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:88:11:88:11 | tainted | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:91:61:91:61 | tainted | -| UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | | UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:81:30:81:54 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | | UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:82:48:82:72 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | | UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:84:37:84:61 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | | UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | nodes -| UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | semmle.label | [summary param] 0 in NSString.init(string:) | -| UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | semmle.label | [summary] to write: return (return) in NSString.init(string:) | | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) | | UncontrolledFormatString.swift:70:28:70:28 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:73:28:73:28 | tainted | semmle.label | tainted | @@ -43,10 +36,6 @@ nodes | UncontrolledFormatString.swift:88:11:88:11 | tainted | semmle.label | tainted | | UncontrolledFormatString.swift:91:61:91:61 | tainted | semmle.label | tainted | subpaths -| UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:81:30:81:54 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:82:48:82:72 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:84:37:84:61 | call to NSString.init(string:) | -| UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) | #select | UncontrolledFormatString.swift:70:28:70:28 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:70:28:70:28 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | | UncontrolledFormatString.swift:73:28:73:28 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:73:28:73:28 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value | diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected index 36c206ed9fd..78ddf30855b 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -2,9 +2,7 @@ edges | testAlamofire.swift:150:45:150:45 | password | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | | testAlamofire.swift:152:51:152:51 | password | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | | testAlamofire.swift:154:38:154:38 | email | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | -| testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | testSend.swift:33:14:33:32 | call to Data.init(_:) | testSend.swift:37:19:37:19 | data2 | -| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:33:14:33:32 | call to Data.init(_:) | | testSend.swift:41:10:41:18 | data | testSend.swift:41:45:41:45 | data | | testSend.swift:52:13:52:13 | password | testSend.swift:59:27:59:27 | str1 | @@ -22,8 +20,6 @@ nodes | testAlamofire.swift:152:51:152:51 | password | semmle.label | password | | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... | | testAlamofire.swift:154:38:154:38 | email | semmle.label | email | -| testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | -| testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | testSend.swift:29:19:29:19 | passwordPlain | semmle.label | passwordPlain | | testSend.swift:33:14:33:32 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | testSend.swift:33:19:33:19 | passwordPlain | semmle.label | passwordPlain | @@ -47,7 +43,6 @@ nodes | testURL.swift:16:55:16:55 | credit_card_no | semmle.label | credit_card_no | | testURL.swift:20:22:20:22 | passwd | semmle.label | passwd | subpaths -| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | testSend.swift:33:14:33:32 | call to Data.init(_:) | | testSend.swift:54:17:54:17 | password | testSend.swift:41:10:41:18 | data | testSend.swift:41:45:41:45 | data | testSend.swift:54:13:54:25 | call to pad(_:) | #select | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | testAlamofire.swift:150:45:150:45 | password | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:150:45:150:45 | password | password | diff --git a/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected b/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected index 380823043c0..f61deac228d 100644 --- a/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected +++ b/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected @@ -22,12 +22,10 @@ edges | file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self | | file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [encryptionKey] | -| misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | value | | misc.swift:46:19:46:38 | call to Data.init(_:) | misc.swift:49:41:49:41 | myConstKey | | misc.swift:46:19:46:38 | call to Data.init(_:) | misc.swift:53:25:53:25 | myConstKey | | misc.swift:46:19:46:38 | call to Data.init(_:) | misc.swift:57:41:57:41 | myConstKey | -| misc.swift:46:24:46:24 | abcdef123456 | misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | misc.swift:46:24:46:24 | abcdef123456 | misc.swift:46:19:46:38 | call to Data.init(_:) | | misc.swift:53:2:53:2 | [post] config [encryptionKey] | misc.swift:53:2:53:2 | [post] config | | misc.swift:53:25:53:25 | myConstKey | misc.swift:30:7:30:7 | value | @@ -37,7 +35,6 @@ edges | misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value | | misc.swift:57:41:57:41 | myConstKey | misc.swift:57:2:57:18 | [post] getter for .config | | misc.swift:57:41:57:41 | myConstKey | misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] | -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:65:73:65:73 | myConstKey | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:66:73:66:73 | myConstKey | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:67:73:67:73 | myConstKey | @@ -53,7 +50,6 @@ edges | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:80:94:80:94 | myConstKey | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:81:102:81:102 | myConstKey | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:83:92:83:92 | myConstKey | -| rncryptor.swift:60:24:60:24 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | rncryptor.swift:60:24:60:24 | abcdef123456 | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | nodes | cryptoswift.swift:76:3:76:3 | this string is constant | semmle.label | this string is constant | @@ -82,8 +78,6 @@ nodes | file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self [encryptionKey] | semmle.label | [post] self [encryptionKey] | | file://:0:0:0:0 | value | semmle.label | value | -| misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | -| misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | misc.swift:30:7:30:7 | value | semmle.label | value | | misc.swift:46:19:46:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | misc.swift:46:24:46:24 | abcdef123456 | semmle.label | abcdef123456 | @@ -94,8 +88,6 @@ nodes | misc.swift:57:2:57:18 | [post] getter for .config | semmle.label | [post] getter for .config | | misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] | semmle.label | [post] getter for .config [encryptionKey] | | misc.swift:57:41:57:41 | myConstKey | semmle.label | myConstKey | -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | -| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | rncryptor.swift:60:24:60:24 | abcdef123456 | semmle.label | abcdef123456 | | rncryptor.swift:65:73:65:73 | myConstKey | semmle.label | myConstKey | @@ -114,12 +106,10 @@ nodes | rncryptor.swift:81:102:81:102 | myConstKey | semmle.label | myConstKey | | rncryptor.swift:83:92:83:92 | myConstKey | semmle.label | myConstKey | subpaths -| misc.swift:46:24:46:24 | abcdef123456 | misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | misc.swift:46:19:46:38 | call to Data.init(_:) | | misc.swift:53:25:53:25 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self | misc.swift:53:2:53:2 | [post] config | | misc.swift:53:25:53:25 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self [encryptionKey] | misc.swift:53:2:53:2 | [post] config [encryptionKey] | | misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self | misc.swift:57:2:57:18 | [post] getter for .config | | misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self [encryptionKey] | misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] | -| rncryptor.swift:60:24:60:24 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:38 | call to Data.init(_:) | #select | cryptoswift.swift:108:21:108:21 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:108:21:108:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | | cryptoswift.swift:109:21:109:21 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:109:21:109:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant | diff --git a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected index 6dd93198451..cd9fda87e19 100644 --- a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected +++ b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected @@ -1,26 +1,21 @@ edges -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:63:57:63:57 | myConstantSalt1 | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:68:106:68:106 | myConstantSalt1 | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:71:106:71:106 | myConstantSalt1 | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:75:127:75:127 | myConstantSalt1 | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:78:135:78:135 | myConstantSalt1 | -| rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | rncryptor.swift:65:55:65:55 | myConstantSalt2 | | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | rncryptor.swift:69:131:69:131 | myConstantSalt2 | | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | rncryptor.swift:72:131:72:131 | myConstantSalt2 | | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | rncryptor.swift:76:152:76:152 | myConstantSalt2 | | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | rncryptor.swift:79:160:79:160 | myConstantSalt2 | -| rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | | rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | | test.swift:43:35:43:130 | [...] | test.swift:51:49:51:49 | constantSalt | | test.swift:43:35:43:130 | [...] | test.swift:56:59:56:59 | constantSalt | | test.swift:43:35:43:130 | [...] | test.swift:62:59:62:59 | constantSalt | | test.swift:43:35:43:130 | [...] | test.swift:67:53:67:53 | constantSalt | nodes -| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) | -| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) | | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | rncryptor.swift:59:29:59:29 | abcdef123456 | semmle.label | abcdef123456 | | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | @@ -41,8 +36,6 @@ nodes | test.swift:62:59:62:59 | constantSalt | semmle.label | constantSalt | | test.swift:67:53:67:53 | constantSalt | semmle.label | constantSalt | subpaths -| rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:59:24:59:43 | call to Data.init(_:) | -| rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:24:60:30 | call to Data.init(_:) | #select | rncryptor.swift:63:57:63:57 | myConstantSalt1 | rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:63:57:63:57 | myConstantSalt1 | The value 'abcdef123456' is used as a constant salt, which is insecure for hashing passwords. | | rncryptor.swift:65:55:65:55 | myConstantSalt2 | rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:65:55:65:55 | myConstantSalt2 | The value '0' is used as a constant salt, which is insecure for hashing passwords. | From 6942925899e0ad7ede5ebde36a0b25d7226c0338 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Thu, 22 Jun 2023 10:53:10 +0200 Subject: [PATCH 720/739] QL: Fix bad join ``` [2023-06-22 10:44:20] (92s) Tuple counts for Predicate#23818b54::Cached::resolveSelfClassCalls#2#ff/2@06fd3bf5 after 1m9s: 30500 ~567% {3} r1 = JOIN Ast#8e1d5bcf::ClassPredicate::getName#0#dispred#ff WITH Ast#8e1d5bcf::PredicateOrBuiltin::getArity#0#dispred#ff ON FIRST 1 OUTPUT Lhs.0 'p', Lhs.1, Rhs.1 26500 ~573% {4} r2 = JOIN r1 WITH Ast#8e1d5bcf::Class::getAClassPredicate#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.2, Lhs.0 'p', Lhs.1, Rhs.1 3059915597 ~605% {4} r3 = JOIN r2 WITH Ast#8e1d5bcf::Call::getNumberOfArguments#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1 'mc', Lhs.2, Lhs.1 'p', Lhs.3 20999389 ~701% {3} r4 = JOIN r3 WITH Ast#8e1d5bcf::MemberCall::getMemberName#0#dispred#ff ON FIRST 2 OUTPUT Lhs.0 'mc', Lhs.2 'p', Lhs.3 20995877 ~711% {4} r5 = JOIN r4 WITH Ast#8e1d5bcf::MemberCall::getBase#0#dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'p', Lhs.2, Lhs.0 'mc' 1240332 ~700% {3} r6 = JOIN r5 WITH Ast#8e1d5bcf::ThisAccess#ff ON FIRST 1 OUTPUT Lhs.3 'mc', Lhs.1 'p', Lhs.2 1236711 ~716% {4} r7 = JOIN r6 WITH Ast#8e1d5bcf::AstNode::getEnclosingPredicate#0#dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.2, Lhs.1 'p', Lhs.0 'mc' 4476 ~347% {2} r8 = JOIN r7 WITH Ast#8e1d5bcf::AstNode::getParent#0#dispred#ff ON FIRST 2 OUTPUT Lhs.3 'mc', Lhs.2 'p' return r8 ``` --- .../src/codeql_ql/ast/internal/Predicate.qll | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll index 46dc86113da..b45eb2166f1 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -90,16 +90,28 @@ private module Cached { ) } + pragma[nomagic] + private ClassPredicate getClassPredicate(Class c, string name, int arity) { + result = c.getClassPredicate(name) and + arity = result.getArity() + } + + pragma[nomagic] + private predicate resolveSelfClassCalls0(Class c, string name, int arity, MemberCall mc) { + mc.getBase() instanceof ThisAccess and + c = mc.getEnclosingPredicate().getParent() and + name = mc.getMemberName() and + arity = mc.getNumberOfArguments() + } + /** * Holds if `mc` is a `this.method()` call to a predicate defined in the same class. * helps avoid spuriously resolving to predicates in super-classes. */ private predicate resolveSelfClassCalls(MemberCall mc, PredicateOrBuiltin p) { - exists(Class c | - mc.getBase() instanceof ThisAccess and - c = mc.getEnclosingPredicate().getParent() and - p = c.getClassPredicate(mc.getMemberName()) and - p.getArity() = mc.getNumberOfArguments() + exists(Class c, string name, int arity | + resolveSelfClassCalls0(c, name, arity, mc) and + p = getClassPredicate(c, name, arity) ) } From d48f7f59c1c62eee5798cbc29c0387de69a343d7 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 22 Jun 2023 09:54:00 +0100 Subject: [PATCH 721/739] Swift: Add change note. --- swift/ql/src/change-notes/2023-06-22-hide-summarized-nodes.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 swift/ql/src/change-notes/2023-06-22-hide-summarized-nodes.md diff --git a/swift/ql/src/change-notes/2023-06-22-hide-summarized-nodes.md b/swift/ql/src/change-notes/2023-06-22-hide-summarized-nodes.md new file mode 100644 index 00000000000..3c192330ee4 --- /dev/null +++ b/swift/ql/src/change-notes/2023-06-22-hide-summarized-nodes.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Functions and methods modeled as flow summaries are no longer shown in the path of `path-problem` queries. This results in more succinct paths for most security queries. From 5816f177c94b024d848a2152053f5472f232dc4a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 9 Jun 2023 15:33:49 +0100 Subject: [PATCH 722/739] C++: Add failing test. --- .../dataflow-consistency.expected | 1 + .../dataflow/dataflow-tests/test.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index acf233ed2ee..55b9a1fe154 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -128,6 +128,7 @@ postWithInFlow | test.cpp:690:3:690:3 | s [post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:694:4:694:6 | buf [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:704:23:704:25 | buf [inner post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:715:25:715:25 | c [inner post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition uniqueParameterNodePosition diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index 915a8421475..ad3257fed9f 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -702,4 +702,21 @@ void call_increment_buf(int** buf) { // $ ast-def=buf void test_conflation_regression(int* source) { // $ ast-def=source int* buf = source; call_increment_buf(&buf); +} + +void write_to_star_star_p(unsigned char **p) // $ ast-def=p ir-def=**p ir-def=*p +{ + **p = 0; +} + +void write_to_star_buf(unsigned char *buf) // $ ast-def=buf +{ + unsigned char *c = buf; + write_to_star_star_p(&c); +} + +void test(unsigned char *source) // $ ast-def=source +{ + write_to_star_buf(source); + sink(*source); // $ SPURIOUS: ir } \ No newline at end of file From 9e9c811eb3c126fae7860700ef95cd46673617b2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 9 Jun 2023 15:20:09 +0100 Subject: [PATCH 723/739] C++: Fix conflation bug in 'getIRRepresentationOfIndirectInstruction'. --- .../semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index d8571b8b74a..55135e180d8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -796,7 +796,7 @@ private module Cached { address.getDef() = instr and isDereference(load, address) and isUseImpl(address, _, indirectionIndex - 1) and - result = instr + result = load ) } From 6034eb07afa037836dfe628ddfb7b1a4695159ab Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 9 Jun 2023 15:16:09 +0100 Subject: [PATCH 724/739] C++: Change the API for indirect operands and indirection instructions to not allow pointer conflation. --- .../ir/dataflow/internal/DataFlowPrivate.qll | 133 +++++++++--------- 1 file changed, 68 insertions(+), 65 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index ef006bbff0a..2e6daad1f84 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -193,86 +193,89 @@ private class SingleUseOperandNode0 extends OperandNode0, TSingleUseOperandNode0 SingleUseOperandNode0() { this = TSingleUseOperandNode0(op) } } -/** - * INTERNAL: Do not use. - * - * A node that represents the indirect value of an operand in the IR - * after `index` number of loads. - * - * Note: Unlike `RawIndirectOperand`, a value of type `IndirectOperand` may - * be an `OperandNode`. - */ -class IndirectOperand extends Node { - Operand operand; - int indirectionIndex; - - IndirectOperand() { - this.(RawIndirectOperand).getOperand() = operand and - this.(RawIndirectOperand).getIndirectionIndex() = indirectionIndex - or - nodeHasOperand(this, Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex), - indirectionIndex - 1) +private module IndirectOperands { + /** + * INTERNAL: Do not use. + * + * A node that represents the indirect value of an operand in the IR + * after `index` number of loads. + * + * Note: Unlike `RawIndirectOperand`, a value of type `IndirectOperand` may + * be an `OperandNode`. + */ + abstract class IndirectOperand extends Node { + /** Gets the underlying operand. */ + abstract predicate hasOperandAndIndirectionIndex(Operand operand, int indirectionIndex); } - /** Gets the underlying operand. */ - Operand getOperand() { result = operand } + private class IndirectOperandFromRaw extends IndirectOperand instanceof RawIndirectOperand { + override predicate hasOperandAndIndirectionIndex(Operand operand, int indirectionIndex) { + operand = RawIndirectOperand.super.getOperand() and + indirectionIndex = RawIndirectOperand.super.getIndirectionIndex() + } + } - /** Gets the underlying indirection index. */ - int getIndirectionIndex() { result = indirectionIndex } + private class IndirectOperandFromIRRepr extends IndirectOperand { + Operand operand; + int indirectionIndex; - /** - * Holds if this `IndirectOperand` is represented directly in the IR instead of - * a `RawIndirectionOperand` with operand `op` and indirection index `index`. - */ - predicate isIRRepresentationOf(Operand op, int index) { - this instanceof OperandNode and - ( - op = operand and - index = indirectionIndex - ) + IndirectOperandFromIRRepr() { + exists(Operand repr | + repr = Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex) and + nodeHasOperand(this, repr, indirectionIndex - 1) + ) + } + + override predicate hasOperandAndIndirectionIndex(Operand op, int index) { + op = operand and index = indirectionIndex + } } } -/** - * INTERNAL: Do not use. - * - * A node that represents the indirect value of an instruction in the IR - * after `index` number of loads. - * - * Note: Unlike `RawIndirectInstruction`, a value of type `IndirectInstruction` may - * be an `InstructionNode`. - */ -class IndirectInstruction extends Node { - Instruction instr; - int indirectionIndex; +import IndirectOperands - IndirectInstruction() { - this.(RawIndirectInstruction).getInstruction() = instr and - this.(RawIndirectInstruction).getIndirectionIndex() = indirectionIndex - or - nodeHasInstruction(this, Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex), - indirectionIndex - 1) +private module IndirectInstructions { + /** + * INTERNAL: Do not use. + * + * A node that represents the indirect value of an instruction in the IR + * after `index` number of loads. + * + * Note: Unlike `RawIndirectInstruction`, a value of type `IndirectInstruction` may + * be an `InstructionNode`. + */ + abstract class IndirectInstruction extends Node { + /** Gets the underlying instruction. */ + abstract predicate hasInstructionAndIndirectionIndex(Instruction instr, int index); } - /** Gets the underlying instruction. */ - Instruction getInstruction() { result = instr } + private class IndirectInstructionFromRaw extends IndirectInstruction instanceof RawIndirectInstruction + { + override predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) { + instr = RawIndirectInstruction.super.getInstruction() and + index = RawIndirectInstruction.super.getIndirectionIndex() + } + } - /** Gets the underlying indirection index. */ - int getIndirectionIndex() { result = indirectionIndex } + private class IndirectInstructionFromIRRepr extends IndirectInstruction { + Instruction instr; + int indirectionIndex; - /** - * Holds if this `IndirectInstruction` is represented directly in the IR instead of - * a `RawIndirectionInstruction` with instruction `i` and indirection index `index`. - */ - predicate isIRRepresentationOf(Instruction i, int index) { - this instanceof InstructionNode and - ( - i = instr and - index = indirectionIndex - ) + IndirectInstructionFromIRRepr() { + exists(Instruction repr | + repr = Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex) and + nodeHasInstruction(this, repr, indirectionIndex - 1) + ) + } + + override predicate hasInstructionAndIndirectionIndex(Instruction i, int index) { + i = instr and index = indirectionIndex + } } } +import IndirectInstructions + /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() } From 3b0a286d8e6bfadf3714758d3a65b9ac76a2ab02 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 9 Jun 2023 15:19:42 +0100 Subject: [PATCH 725/739] C++: Adjust the rest of the library to the new API. --- .../ir/dataflow/internal/DataFlowPrivate.qll | 2 +- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 48 +++++++++++-------- .../dataflow/internal/SsaInternalsCommon.qll | 2 +- .../dataflow/internal/TaintTrackingUtil.qll | 2 +- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 2e6daad1f84..49f61eb0aed 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -323,7 +323,7 @@ private class SideEffectArgumentNode extends ArgumentNode, SideEffectOperandNode override predicate argumentOf(DataFlowCall dfCall, ArgumentPosition pos) { this.getCallInstruction() = dfCall and pos.(IndirectionPosition).getArgumentIndex() = this.getArgumentIndex() and - pos.(IndirectionPosition).getIndirectionIndex() = super.getIndirectionIndex() + super.hasAddressOperandAndIndirectionIndex(_, pos.(IndirectionPosition).getIndirectionIndex()) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 9a3fd679f23..63e49c20c28 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -274,7 +274,7 @@ class Node extends TIRDataFlowNode { * represents the value of `**x` going into `f`. */ Expr asIndirectArgument(int index) { - this.(SideEffectOperandNode).getIndirectionIndex() = index and + this.(SideEffectOperandNode).hasAddressOperandAndIndirectionIndex(_, index) and result = this.(SideEffectOperandNode).getArgument() } @@ -317,7 +317,7 @@ class Node extends TIRDataFlowNode { index = 0 and result = this.(ExplicitParameterNode).getParameter() or - this.(IndirectParameterNode).getIndirectionIndex() = index and + this.(IndirectParameterNode).hasInstructionAndIndirectionIndex(_, index) and result = this.(IndirectParameterNode).getParameter() } @@ -577,15 +577,19 @@ class SsaPhiNode extends Node, TSsaPhiNode { * * A node representing a value after leaving a function. */ -class SideEffectOperandNode extends Node, IndirectOperand { +class SideEffectOperandNode extends Node instanceof IndirectOperand { CallInstruction call; int argumentIndex; - SideEffectOperandNode() { operand = call.getArgumentOperand(argumentIndex) } + SideEffectOperandNode() { + IndirectOperand.super.hasOperandAndIndirectionIndex(call.getArgumentOperand(argumentIndex), _) + } CallInstruction getCallInstruction() { result = call } - Operand getAddressOperand() { result = operand } + predicate hasAddressOperandAndIndirectionIndex(Operand operand, int indirectionIndex) { + IndirectOperand.super.hasOperandAndIndirectionIndex(operand, indirectionIndex) + } int getArgumentIndex() { result = argumentIndex } @@ -665,10 +669,10 @@ class InitialGlobalValue extends Node, TInitialGlobalValue { * * A node representing an indirection of a parameter. */ -class IndirectParameterNode extends Node, IndirectInstruction { +class IndirectParameterNode extends Node instanceof IndirectInstruction { InitializeParameterInstruction init; - IndirectParameterNode() { this.getInstruction() = init } + IndirectParameterNode() { IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _) } int getArgumentIndex() { init.hasIndex(result) } @@ -677,7 +681,12 @@ class IndirectParameterNode extends Node, IndirectInstruction { override Declaration getEnclosingCallable() { result = this.getFunction() } - override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() } + override Declaration getFunction() { result = init.getEnclosingFunction() } + + /** Gets the underlying instruction. */ + predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) { + IndirectInstruction.super.hasInstructionAndIndirectionIndex(instr, index) + } override Location getLocationImpl() { result = this.getParameter().getLocation() } @@ -699,7 +708,8 @@ class IndirectReturnNode extends Node { IndirectReturnNode() { this instanceof FinalParameterNode or - this.(IndirectOperand).getOperand() = any(ReturnValueInstruction ret).getReturnAddressOperand() + this.(IndirectOperand) + .hasOperandAndIndirectionIndex(any(ReturnValueInstruction ret).getReturnAddressOperand(), _) } override Declaration getEnclosingCallable() { result = this.getFunction() } @@ -722,7 +732,7 @@ class IndirectReturnNode extends Node { int getIndirectionIndex() { result = this.(FinalParameterNode).getIndirectionIndex() or - result = this.(IndirectOperand).getIndirectionIndex() + this.(IndirectOperand).hasOperandAndIndirectionIndex(_, result) } } @@ -1106,7 +1116,8 @@ predicate exprNodeShouldBeInstruction(Node node, Expr e) { /** Holds if `node` should be an `IndirectInstruction` that maps `node.asIndirectExpr()` to `e`. */ predicate indirectExprNodeShouldBeIndirectInstruction(IndirectInstruction node, Expr e) { exists(Instruction instr | - instr = node.getInstruction() and not indirectExprNodeShouldBeIndirectOperand(_, e) + node.hasInstructionAndIndirectionIndex(instr, _) and + not indirectExprNodeShouldBeIndirectOperand(_, e) | e = instr.(VariableAddressInstruction).getAst().(Expr).getFullyConverted() or @@ -1307,8 +1318,8 @@ pragma[noinline] private predicate indirectParameterNodeHasArgumentIndexAndIndex( IndirectParameterNode node, int argumentIndex, int indirectionIndex ) { - node.getArgumentIndex() = argumentIndex and - node.getIndirectionIndex() = indirectionIndex + node.hasInstructionAndIndirectionIndex(_, indirectionIndex) and + node.getArgumentIndex() = argumentIndex } /** A synthetic parameter to model the pointed-to object of a pointer parameter. */ @@ -1479,18 +1490,14 @@ VariableNode variableNode(Variable v) { */ Node uninitializedNode(LocalVariable v) { none() } -pragma[noinline] predicate hasOperandAndIndex(IndirectOperand indirectOperand, Operand operand, int indirectionIndex) { - indirectOperand.getOperand() = operand and - indirectOperand.getIndirectionIndex() = indirectionIndex + indirectOperand.hasOperandAndIndirectionIndex(operand, indirectionIndex) } -pragma[noinline] predicate hasInstructionAndIndex( IndirectInstruction indirectInstr, Instruction instr, int indirectionIndex ) { - indirectInstr.getInstruction() = instr and - indirectInstr.getIndirectionIndex() = indirectionIndex + indirectInstr.hasInstructionAndIndirectionIndex(instr, indirectionIndex) } cached @@ -1656,8 +1663,7 @@ module ExprFlowCached { private predicate isIndirectBaseOfArrayAccess(IndirectOperand n, Expr e) { exists(LoadInstruction load, PointerArithmeticInstruction pai | pai = load.getSourceAddress() and - pai.getLeftOperand() = n.getOperand() and - n.getIndirectionIndex() = 1 and + n.hasOperandAndIndirectionIndex(pai.getLeftOperand(), 1) and e = load.getConvertedResultExpression() ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 55135e180d8..b0e092eda62 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -263,7 +263,7 @@ private module IteratorIndirections { // Taint through `operator+=` and `operator-=` on iterators. call.getStaticCallTarget() instanceof Iterator::IteratorAssignArithmeticOperator and node2.(IndirectArgumentOutNode).getPreUpdateNode() = node1 and - node1.(IndirectOperand).getOperand() = call.getArgumentOperand(0) and + node1.(IndirectOperand).hasOperandAndIndirectionIndex(call.getArgumentOperand(0), _) and node1.getType().getUnspecifiedType() = this ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index c3b8765a72a..028f5bad9da 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -160,7 +160,7 @@ predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut) { FunctionInput modelIn, FunctionOutput modelOut | indirectArgument = callInput(call, modelIn) and - indirectArgument.getAddressOperand() = nodeIn.asOperand() and + indirectArgument.hasAddressOperandAndIndirectionIndex(nodeIn.asOperand(), _) and call.getStaticCallTarget() = func and ( func.(DataFlowFunction).hasDataFlow(modelIn, modelOut) From 6543da9990fe0a0d62c05b2bdbdb3b6c755eeb86 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 9 Jun 2023 15:35:22 +0100 Subject: [PATCH 726/739] C++: Accept test changes. --- cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index ad3257fed9f..7a04a53510a 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -718,5 +718,5 @@ void write_to_star_buf(unsigned char *buf) // $ ast-def=buf void test(unsigned char *source) // $ ast-def=source { write_to_star_buf(source); - sink(*source); // $ SPURIOUS: ir + sink(*source); // clean } \ No newline at end of file From 3365ff0d95e49119cffb272b73e682f9482ba759 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 9 Jun 2023 15:46:04 +0100 Subject: [PATCH 727/739] C++: Ensure that 'PrintIR' for dataflow still compiles. --- .../cpp/ir/dataflow/internal/PrintIRFieldFlowSteps.qll | 4 ++-- .../code/cpp/ir/dataflow/internal/PrintIRUtilities.qll | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRFieldFlowSteps.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRFieldFlowSteps.qll index f0286c00cbc..c0976f8c3e9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRFieldFlowSteps.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRFieldFlowSteps.qll @@ -13,7 +13,7 @@ class FieldFlowPropertyProvider extends IRPropertyProvider { override string getOperandProperty(Operand operand, string key) { exists(PostFieldUpdateNode pfun, Content content | key = "store " + content.toString() and - operand = pfun.getPreUpdateNode().(IndirectOperand).getOperand() and + pfun.getPreUpdateNode().(IndirectOperand).hasOperandAndIndirectionIndex(operand, _) and result = strictconcat(string element, Node node | storeStep(node, content, pfun) and @@ -25,7 +25,7 @@ class FieldFlowPropertyProvider extends IRPropertyProvider { or exists(Node node2, Content content | key = "read " + content.toString() and - operand = node2.(IndirectOperand).getOperand() and + node2.(IndirectOperand).hasOperandAndIndirectionIndex(operand, _) and result = strictconcat(string element, Node node1 | readStep(node1, content, node2) and diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll index 5c6cdebf800..5cca78588f0 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll @@ -18,9 +18,12 @@ private string stars(int k) { } string starsForNode(Node node) { - result = stars(node.(IndirectInstruction).getIndirectionIndex()) - or - result = stars(node.(IndirectOperand).getIndirectionIndex()) + exists(int indirectionIndex | + node.(IndirectInstruction).hasInstructionAndIndirectionIndex(_, indirectionIndex) or + node.(IndirectOperand).hasOperandAndIndirectionIndex(_, indirectionIndex) + | + result = stars(indirectionIndex) + ) or not node instanceof IndirectInstruction and not node instanceof IndirectOperand and From c7cff373de79c2fb2c14b5a4d152f98a6dfc52bf Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 9 Jun 2023 15:50:52 +0100 Subject: [PATCH 728/739] C++: Add another testcase with conflation. --- .../dataflow-consistency.expected | 3 +++ .../dataflow/dataflow-tests/test.cpp | 18 ++++++++++++++++-- .../dataflow-tests/uninitialized.expected | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index 55b9a1fe154..6129ed657ac 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -129,6 +129,9 @@ postWithInFlow | test.cpp:694:4:694:6 | buf [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:704:23:704:25 | buf [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:715:25:715:25 | c [inner post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:728:3:728:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:728:4:728:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:734:41:734:41 | x [inner post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition uniqueParameterNodePosition diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index 7a04a53510a..7b6ea0fa718 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -715,8 +715,22 @@ void write_to_star_buf(unsigned char *buf) // $ ast-def=buf write_to_star_star_p(&c); } -void test(unsigned char *source) // $ ast-def=source +void test_write_to_star_buf(unsigned char *source) // $ ast-def=source { write_to_star_buf(source); sink(*source); // clean -} \ No newline at end of file +} + +void does_not_write_source_to_dereference(int *p) // $ ast-def=p ir-def=*p +{ + int x = source(); + p = &x; + *p = 42; +} + +void test_does_not_write_source_to_dereference() +{ + int x; + does_not_write_source_to_dereference(&x); + sink(x); // $ ast,ir=733:7 SPURIOUS: ast,ir=726:11 +} diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected index 0a52d928028..b40148f4950 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected @@ -42,3 +42,5 @@ | test.cpp:551:9:551:9 | y | test.cpp:552:28:552:28 | y | | test.cpp:595:8:595:9 | xs | test.cpp:596:3:596:4 | xs | | test.cpp:595:8:595:9 | xs | test.cpp:597:9:597:10 | xs | +| test.cpp:733:7:733:7 | x | test.cpp:734:41:734:41 | x | +| test.cpp:733:7:733:7 | x | test.cpp:735:8:735:8 | x | From 6528985a2726a97ba3b6144999bb7c693c18e611 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Fri, 9 Jun 2023 15:53:48 +0100 Subject: [PATCH 729/739] C++: Add QLDoc to 'hasAddressOperandAndIndirectionIndex'. --- cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 63e49c20c28..02cca5cdddb 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -587,6 +587,7 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand { CallInstruction getCallInstruction() { result = call } + /** Gets the underlying operand and the underlying indirection index. */ predicate hasAddressOperandAndIndirectionIndex(Operand operand, int indirectionIndex) { IndirectOperand.super.hasOperandAndIndirectionIndex(operand, indirectionIndex) } From a8a04c8588cfbc970736db4c70a6c35e101fcf14 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Sat, 10 Jun 2023 16:12:21 +0100 Subject: [PATCH 730/739] Update cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- .../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 49f61eb0aed..c9331e18ca4 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -204,7 +204,7 @@ private module IndirectOperands { * be an `OperandNode`. */ abstract class IndirectOperand extends Node { - /** Gets the underlying operand. */ + /** Gets the underlying operand and the underlying indirection index. */ abstract predicate hasOperandAndIndirectionIndex(Operand operand, int indirectionIndex); } From 4f1b2c619434ef299f393a8e5aebcd1d061c9870 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Sat, 10 Jun 2023 16:12:28 +0100 Subject: [PATCH 731/739] Update cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- .../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index c9331e18ca4..42a496843d3 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -245,7 +245,7 @@ private module IndirectInstructions { * be an `InstructionNode`. */ abstract class IndirectInstruction extends Node { - /** Gets the underlying instruction. */ + /** Gets the underlying operand and the underlying indirection index. */ abstract predicate hasInstructionAndIndirectionIndex(Instruction instr, int index); } From ff3c76c1faa91a5f671b5644a4d858f67fc1957b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Sat, 10 Jun 2023 16:12:33 +0100 Subject: [PATCH 732/739] Update cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 02cca5cdddb..4cf5cd65fa8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -684,7 +684,7 @@ class IndirectParameterNode extends Node instanceof IndirectInstruction { override Declaration getFunction() { result = init.getEnclosingFunction() } - /** Gets the underlying instruction. */ + /** Gets the underlying operand and the underlying indirection index. */ predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) { IndirectInstruction.super.hasInstructionAndIndirectionIndex(instr, index) } From 273e5bc21feba3c7618a8392f79c4b95ae73fc05 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Sun, 18 Jun 2023 13:12:23 +0100 Subject: [PATCH 733/739] C++: Add testcase demonstrating that the model for 'strncpy' is broken. --- .../dataflow/taint-tests/localTaint.expected | 14 ++++++++++++++ .../library-tests/dataflow/taint-tests/taint.cpp | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index f6a7625b57a..44965a9f2d9 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -6591,6 +6591,20 @@ | taint.cpp:702:4:702:6 | ... ++ | taint.cpp:703:8:703:8 | p | TAINT | | taint.cpp:702:10:702:11 | * ... | taint.cpp:702:3:702:11 | ... = ... | | | taint.cpp:702:11:702:11 | s | taint.cpp:702:10:702:11 | * ... | TAINT | +| taint.cpp:709:25:709:25 | d | taint.cpp:709:25:709:25 | d | | +| taint.cpp:709:25:709:25 | d | taint.cpp:711:10:711:10 | d | | +| taint.cpp:709:25:709:25 | d | taint.cpp:712:7:712:7 | d | | +| taint.cpp:709:34:709:34 | s | taint.cpp:709:34:709:34 | s | | +| taint.cpp:709:34:709:34 | s | taint.cpp:710:18:710:18 | s | | +| taint.cpp:709:34:709:34 | s | taint.cpp:711:13:711:13 | s | | +| taint.cpp:710:18:710:18 | ref arg s | taint.cpp:709:34:709:34 | s | | +| taint.cpp:710:18:710:18 | ref arg s | taint.cpp:711:13:711:13 | s | | +| taint.cpp:711:10:711:10 | d | taint.cpp:711:2:711:8 | call to strncpy | | +| taint.cpp:711:10:711:10 | ref arg d | taint.cpp:709:25:709:25 | d | | +| taint.cpp:711:10:711:10 | ref arg d | taint.cpp:712:7:712:7 | d | | +| taint.cpp:711:13:711:13 | s | taint.cpp:711:2:711:8 | call to strncpy | TAINT | +| taint.cpp:711:13:711:13 | s | taint.cpp:711:10:711:10 | ref arg d | TAINT | +| taint.cpp:712:7:712:7 | ref arg d | taint.cpp:709:25:709:25 | d | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | | | vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index fa6074e44f6..5c582b67cd7 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -702,4 +702,12 @@ namespace strings { *p++ = *s; sink(p); // $ ast ir } +} + +char * strncpy (char *, const char *, unsigned long); + +void test_strncpy(char* d, char* s) { + argument_source(s); + strncpy(d, s, 16); + sink(d); // $ ast MISSING: ir } \ No newline at end of file From fe97572f70175893951a20bc70fd6016b3484919 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Sun, 18 Jun 2023 13:13:28 +0100 Subject: [PATCH 734/739] C++: Fix strncpy model. --- cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll | 2 +- cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll index 10b160dee47..ea371de958a 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll @@ -108,7 +108,7 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid // these may do only a partial copy of the input buffer to the output // buffer exists(this.getParamSize()) and - input.isParameter(this.getParamSrc()) and + input.isParameterDeref(this.getParamSrc()) and ( output.isParameterDeref(this.getParamDest()) or output.isReturnValueDeref() diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 5c582b67cd7..9810418a95e 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -709,5 +709,5 @@ char * strncpy (char *, const char *, unsigned long); void test_strncpy(char* d, char* s) { argument_source(s); strncpy(d, s, 16); - sink(d); // $ ast MISSING: ir + sink(d); // $ ast ir } \ No newline at end of file From 1c1637a886ddda62df8e397d7a90f3baeb088239 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 22 Jun 2023 13:56:06 +0100 Subject: [PATCH 735/739] Ruby: Correct QLDoc for charRange. --- ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll b/ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll index 9160bf60506..d1a39e29fd2 100644 --- a/ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll +++ b/ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll @@ -195,8 +195,8 @@ abstract class RegExp extends Ast::StringlikeLiteral { /** * Holds if the character set starting at `charset_start` contains a character range - * with lower bound found between `start` and `lower_end` - * and upper bound found between `upper_start` and `end`. + * with lower bound found between `start` and `lowerEnd` + * and upper bound found between `upperStart` and `end`. */ predicate charRange(int charsetStart, int start, int lowerEnd, int upperStart, int end) { exists(int index | From d06f4b95676f51d17748bff04a21fc2593c33147 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 22 Jun 2023 13:56:42 +0100 Subject: [PATCH 736/739] Ruby: Correct QLDoc for qualifiedPart. --- ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll b/ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll index d1a39e29fd2..d1f96ec407e 100644 --- a/ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll +++ b/ruby/ql/lib/codeql/ruby/regexp/internal/ParseRegExp.qll @@ -844,11 +844,11 @@ abstract class RegExp extends Ast::StringlikeLiteral { } /** - * Holds if a qualified part is found between `start` and `part_end` and the qualifier is - * found between `part_end` and `end`. + * Holds if a qualified part is found between `start` and `partEnd` and the qualifier is + * found between `partEnd` and `end`. * - * `maybe_empty` is true if the part is optional. - * `may_repeat_forever` is true if the part may be repeated unboundedly. + * `maybeEmpty` is true if the part is optional. + * `mayRepeatForever` is true if the part may be repeated unboundedly. */ predicate qualifiedPart( int start, int partEnd, int end, boolean maybeEmpty, boolean mayRepeatForever From da54751d8506f8e9d8acc91cc560a1e92e170e87 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 22 Jun 2023 17:37:27 +0100 Subject: [PATCH 737/739] C++: Add testcase that demonstrate the need for self-flow out of indirect parameters. --- .../dataflow-consistency.expected | 2 ++ .../dataflow-tests/self_parameter_flow.cpp | 14 ++++++++ .../test_self_parameter_flow.expected | 2 ++ .../test_self_parameter_flow.ql | 34 +++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp create mode 100644 cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.expected create mode 100644 cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.ql diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index 6129ed657ac..eb9e8efb1d2 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -67,6 +67,8 @@ postWithInFlow | ref.cpp:109:9:109:11 | val [post update] | PostUpdateNode should not be the target of local flow. | | ref.cpp:113:11:113:13 | val [post update] | PostUpdateNode should not be the target of local flow. | | ref.cpp:115:11:115:13 | val [post update] | PostUpdateNode should not be the target of local flow. | +| self_parameter_flow.cpp:3:4:3:5 | ps [inner post update] | PostUpdateNode should not be the target of local flow. | +| self_parameter_flow.cpp:8:9:8:9 | s [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:91:3:91:9 | source1 [post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:115:3:115:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:115:4:115:6 | out [inner post update] | PostUpdateNode should not be the target of local flow. | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp new file mode 100644 index 00000000000..1c9d3aebf99 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp @@ -0,0 +1,14 @@ +void incr(unsigned char **ps) // $ ast-def=ps ir-def=*ps ir-def=**ps +{ + *ps += 1; +} + +void callincr(unsigned char *s) // $ ast-def=s +{ + incr(&s); +} + +void test(unsigned char *s) // $ ast-def=s +{ + callincr(s); // $ MISSING: flow +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.expected new file mode 100644 index 00000000000..48de9172b36 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.ql new file mode 100644 index 00000000000..c6ea9c5c96f --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_parameter_flow.ql @@ -0,0 +1,34 @@ +import cpp +import semmle.code.cpp.dataflow.new.DataFlow +import TestUtilities.InlineExpectationsTest + +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + source.getLocation().getFile().getBaseName() = "self_parameter_flow.cpp" and + source.asIndirectArgument() = + any(Call call | call.getTarget().hasName("callincr")).getAnArgument() + } + + predicate isSink(DataFlow::Node sink) { + sink.asDefiningArgument() = + any(Call call | call.getTarget().hasName("callincr")).getAnArgument() + } +} + +import DataFlow::Global<TestConfig> + +module TestSelfParameterFlow implements TestSig { + string getARelevantTag() { result = "flow" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node sink | + flowTo(sink) and + location = sink.getLocation() and + element = sink.toString() and + tag = "flow" and + value = "" + ) + } +} + +import MakeTest<TestSelfParameterFlow> From 0839c1aad1d2312cf066dbfe52c407036a833cd8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 22 Jun 2023 17:38:06 +0100 Subject: [PATCH 738/739] C++: Allow self-flow through indirect parameters. --- .../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 42a496843d3..6715b67c382 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -848,7 +848,7 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves * One example would be to allow flow like `p.foo = p.bar;`, which is disallowed * by default as a heuristic. */ -predicate allowParameterReturnInSelf(ParameterNode p) { none() } +predicate allowParameterReturnInSelf(ParameterNode p) { p instanceof IndirectParameterNode } private predicate fieldHasApproxName(Field f, string s) { s = f.getName().charAt(0) and From 79fb6a6079e60c4275d103dc5be63008e2f47de9 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 22 Jun 2023 17:38:28 +0100 Subject: [PATCH 739/739] C++: Accept test changes. --- .../dataflow/dataflow-tests/self_parameter_flow.cpp | 2 +- .../CWE-119/semmle/tests/OverflowDestination.expected | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp index 1c9d3aebf99..2298e644b05 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp @@ -10,5 +10,5 @@ void callincr(unsigned char *s) // $ ast-def=s void test(unsigned char *s) // $ ast-def=s { - callincr(s); // $ MISSING: flow + callincr(s); // $ flow } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected index 19de8c61578..8d46c8fe99b 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected @@ -8,13 +8,19 @@ edges | overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | | overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection | +| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:9:53:12 | memcpy output argument | | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src indirection | | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src indirection | +| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument | +| overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument | +| overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument | | overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 indirection | | overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 indirection | | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | src indirection | | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | src indirection | +| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | src indirection | | overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | src indirection | +| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | | overflowdestination.cpp:76:30:76:32 | src indirection | overflowdestination.cpp:57:52:57:54 | src indirection | nodes | main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection | @@ -28,15 +34,20 @@ nodes | overflowdestination.cpp:43:8:43:10 | fgets output argument | semmle.label | fgets output argument | | overflowdestination.cpp:46:15:46:17 | src indirection | semmle.label | src indirection | | overflowdestination.cpp:50:52:50:54 | src indirection | semmle.label | src indirection | +| overflowdestination.cpp:53:9:53:12 | memcpy output argument | semmle.label | memcpy output argument | | overflowdestination.cpp:53:15:53:17 | src indirection | semmle.label | src indirection | | overflowdestination.cpp:53:15:53:17 | src indirection | semmle.label | src indirection | +| overflowdestination.cpp:54:9:54:12 | memcpy output argument | semmle.label | memcpy output argument | | overflowdestination.cpp:57:52:57:54 | src indirection | semmle.label | src indirection | | overflowdestination.cpp:64:16:64:19 | src2 indirection | semmle.label | src2 indirection | | overflowdestination.cpp:64:16:64:19 | src2 indirection | semmle.label | src2 indirection | | overflowdestination.cpp:73:8:73:10 | fgets output argument | semmle.label | fgets output argument | +| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | semmle.label | overflowdest_test2 output argument | | overflowdestination.cpp:75:30:75:32 | src indirection | semmle.label | src indirection | | overflowdestination.cpp:76:30:76:32 | src indirection | semmle.label | src indirection | subpaths +| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | +| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | #select | overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | | overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |